Issues with UART DmaTransmit and DmaReceive

**** ORIGNAL POST CAN BE IGNORED. SEE NEXT REPLY FOR UPDATE ****

I’m having some difficulty setting up a UART connection on the Daisy Patch Submodule. Ultimately I would like to communicate between a Daisy Patch Submodule and a Rasberry Pi, but for now I am just attempting to transmit messages to a USB serial converter.

So far I’ve been able to Transmit messages from Daisy only about 10% of the time. Seemingly at random, the USB serial converter will begin receiving transmitted messages, but usually nothing happens at all. When the serial usb does receive my transmitted messages and I print them in a PD patch, they are not as expected. I’m not sure if the error is how I send them on the Daisy side or how I decode them.

I should add though that every time I make a DmaTransmit() call on the Daisy PatchSm, it returns result of OK, even if the serial usb converter does not appear to receive anything

Below is all of my code related to the UartHandler and DmaTransmit/DmaReceive calls. Is there something in my config that may be causing issues or am I not properly setting up my transmit and receive buffers? I’m new to hardware and UART and any help is greatly appreciated.

/** UART Communication */
UartHandler uart_handler;
uint8_t uart_receive_buffer;
size_t uart_buffer_size = 512;
uint8_t uart_transmit_buffer[512];

int main(void)
{
    /** UART communication config */
    UartHandler::Config       uart_config;
    uart_config.baudrate      = 9600;
    uart_config.periph        = UartHandler::Config::Peripheral::USART_1;
    uart_config.stopbits      = UartHandler::Config::StopBits::BITS_1;
    uart_config.parity        = UartHandler::Config::Parity::NONE;
    uart_config.mode          = UartHandler::Config::Mode::TX_RX;
    uart_config.wordlength    = UartHandler::Config::WordLength::BITS_8;
    uart_config.pin_config.rx = {DSY_GPIOB, 15};  // (USART_1 RX) PatchSM pin A9
    uart_config.pin_config.tx = {DSY_GPIOB, 14};  // (USART_1 TX) PatchSM pin A8

    /** UART communication initialization */
    uart_handler.Init(uart_config);
    uart_handler.DmaReceive(&uart_receive_buffer, uart_buffer_size, NULL, NULL, NULL);
    uart_handler.DmaReceiveFifo();

  while(1) {
        std::string transmit_message = "gr/107/0.5/15\n";  // test message
        std::vector<uint8_t> transmit_vector(transmit_message.begin(), transmit_message.end()); // copy test message to uint8_t vector

        UartHandler::Result result = uart_handler.DmaTransmit(&transmit_vector[0], transmit_message.length(), NULL, NULL, NULL);
        if (result == UartHandler::Result::OK) {
            hw.PrintLine("OK TRANSMIT");
        } else {
            hw.PrintLine("ERROR TRANSMIT");
        }

        hw.Delay(2000);
  }
}

I’ve discovered the UART examples in libdaisy and now I’m trying use the UART Tx example for the PatchSM. So far I’ve only made minor adjustments to the original example. I think what I’m most unclear on is if I’m correctly initializing the Pins for the config. I’m attempting to assign pin A3 on the PatchSM for UART TX. The PatchSM csv that shows the STM32 Pin is PB6 so my code assigns it like this:

uart_conf.pin_config.tx = Pin(PORTB, 6);

Am I interpreting the csv correctly? Is this the correct way to initialize a Pin on PatchSM? Also, baudrate on my serial monitor is 4800 which I believe is the default for Daisy. I’m using Pin A5 for GND. Full code is below:

#include "daisy_patch_sm.h"

using namespace daisy;
using namespace patch_sm;

DaisyPatchSM hw;
UartHandler uart;

#define BUFF_SIZE 256

// buffer to be dma transmitted
static uint8_t DMA_BUFFER_MEM_SECTION buff[BUFF_SIZE];

void RestartUart(void* state, UartHandler::Result res);

// dma end callback, will start a new DMA transfer
void RestartUart(void* state, UartHandler::Result res)
{
    if(res != UartHandler::Result::ERR)
    {
        uart.DmaTransmit(buff, BUFF_SIZE, NULL, RestartUart, NULL);
    }
}

int main(void)
{
    // Initialize the daisy hardware
    hw.Init();

    // initilize the buffer
    for(int i = 0; i < BUFF_SIZE; i++)
    {
        buff[i] = i;
    }

    // Configure the Uart Peripheral
    UartHandler::Config uart_conf;
    uart_conf.periph        = UartHandler::Config::Peripheral::USART_1;
    uart_conf.mode          = UartHandler::Config::Mode::TX;
    uart_conf.pin_config.tx = Pin(PORTB, 6);
    uart_conf.pin_config.rx = Pin(PORTB, 7);

    // Initialize the uart peripheral and start the DMA transmit
    uart.Init(uart_conf);

    // loop forever
    while(1) {
      uart.DmaTransmit(buff, BUFF_SIZE, NULL, RestartUart, NULL);
      hw.Delay(2000);
   }
}

Hello zyxy398!

Pin configuration for uart looks good to me. PB6 = UART TX = Pin A3 for Patch SM.

Before we move forward, I do want to clarify with you that Pin A5 is not GND as it is for +12V In. Could you try pin A4 or A7 for GND?

Thanks, you’re correct. I think I just mistyped it. I’m now connected to A3 for Tx and A4 for GND and still nothing printing in my serial monitor and no led indication on my serial usb device.

What you need to use are the USART1 pins.

Please check out page 3 of the Patch SM datasheet.
As you can see, pin A2 and A3 are for UART4.
Therefore, you need to instead use pins A8 and A9 for USART1 on the Patch SM.

This should work.

uart_conf.pin_config.tx = DaisyPatchSM::A8;
uart_conf.pin_config.rx = DaisyPatchSM::A9;

Also, you should move

uart.DmaTransmit(buff, BUFF_SIZE, NULL, RestartUart, NULL);

back to its original place since the DMA callback RestartUart will take care of that.

Thank you for bringing this up since it looks like .csv file needs some update.
We hope this helps!!

@Takumi_Ogata thank you!! Rx and Tx both working now.

1 Like