Skip to main content
fancyrat
Associate II
February 13, 2023
Question

SO8N STM32G031C6 USART not working.

  • February 13, 2023
  • 10 replies
  • 5212 views

I'm trying to setup an USART for a very small MCU of the STM32G0 family, the MCU it's theoretically being programmed, but the USART is not responding, I configured the MCU just like I did in other projects (of bigger MCUs), I'm not able to find what I'm doing wrong in this case.

This is what I can see from the USART (theoretically in this image I'm sending "0xFF" all the time, but it does the same whatever I put in the buffer).

0693W00000YAa9tQAD.pngCodewise I'm enabling the USART DMA with LL_USART_EnableDMAReq_TX(USART1), then configuring with LL_DMA_ConfigAddresses.

Some checks with LL_DMA_IsEnabledChannel, and finally sending stuff with both LL_DMA_SetDataLength & LL_DMA_EnableChannel once the buffer has something on it.

Also tried to clear TC1 flag & disable channel every communication, checking it with LL_DMA_IsActiveFlag_TC1.

The USART is configured as Half-duplex (as it need to be) & baudrate, word length, etc...are correct: 0693W00000YAaAhQAL.png

This topic has been closed for replies.

10 replies

KnarfB
Super User
February 13, 2023

And if you don't use DMA but simply write to TXD?

Is is a pin issue or a DMA prog issue?

hth

KnarfB

fancyrat
fancyratAuthor
Associate II
February 13, 2023

Hi,

I've always worked with DMA so I'm not confident in the code I've just wrote, but it seems that the same is happening.

I write this very quickly anyway, so I'll keep investigating in this direction. This is the code I've just written that doesn't use DMA.

void comms_init(void)
{
 // USART clock
 RCC->APBENR2 |= RCC_APBENR2_USART1EN;
 
 // USART baud rate
 USART1->BRR = (uint16_t)(SystemCoreClock / 115200);
 
 // USART data (8 data bits, no parity, 1 stop bit)
 USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
 
 // USART peripheral
 USART1->CR1 |= USART_CR1_UE;
}
 
void USART_SendData(uint8_t data)
{
 // Wait for empty transmit data register 
 while (!(USART1->ISR & USART_ISR_TXFE))
 ;
 
 // Write data to the TDR
 USART1->TDR = data;
 
 // Wait for the transmission
 while (!(USART1->ISR & USART_ISR_TC))
 ;
}
 
void comms_task(void)
{
 
 while (1)
 {
 USART_SendData('H');
 USART_SendData('e');
 USART_SendData('l');
 USART_SendData('l');
 USART_SendData('o');
 USART_SendData('\r');
 USART_SendData('\n');
 }
}

fancyrat
fancyratAuthor
Associate II
February 13, 2023

EDIT: If I remove the watchdog the "spikes" that go to 0 disapear.

KnarfB
Super User
February 13, 2023

Your later code works* if you replace the flag with:

while (!(USART1->ISR & USART_ISR_TXE_TXFNF))

*) have added more init code for the pins, namely the auto-generated MX_USART1_UART_Init() for my STM32G031 Disco..Note that USART1_TX pin is same as BOOT0 and SWCLK, which might be confusing...

hth

KnarfB

Viktor POHORELY
ST Employee
February 13, 2023

Did you tried just simple GPIO toggling, to see if the issue comes from pin or IP ?

There are several pins in paralel on those small packages, thus in case you have other one configured as output it may not work correctly.

fancyrat
fancyratAuthor
Associate II
February 14, 2023

Thank you all,

I built the project from scratch and I manage to sent data both with the DMA & HAL, now the problem I'm having is that the data I'm receiving it's not exactly correct, I'm receiving incorrect characters, I'll try to check if with an oscilloscope, but at a simple glance, everything looks good.

Also I would try again with my old code, as @KnarfB​ confirms that it worked with a very small change.

Edit: Well I just tried with USART_SendData code and I'm still receiving weird stuff.

fancyrat
fancyratAuthor
Associate II
February 14, 2023

Just as a reference, this is what I've got now, it should be saying "HOLA" using the UART with an DMA, I'm receiving other stuff mostly random symbols, I can't seem to find the relation to it:

0693W00000YAhL3QAL.png0693W00000YAgtoQAD.png

fancyrat
fancyratAuthor
Associate II
February 14, 2023

Now I've tried to write "*\n* just to have some other signal to compare like the one in this link: https://hackaday.com/2016/06/22/what-could-go-wrong-asynchronous-serial-edition/

It seems that in my case the message keeps repeating multiple times. But the bits are correct:

0693W00000YAhNYQA1.png0693W00000YAhNEQA1.png

Bob S
Super User
February 14, 2023

Your polarity looks inverted. With TTL/3V level signals a UART should idle high. The start bit is initiated by a high to low transition. These images look like your line is idling low. Unless I am missing something, like you have a TTL-to-RS232 level shifter that isn't able to drive below 0V???? I don't know how that (inverted could happen in the G0, but then I don't know much about the G0 family.

fancyrat
fancyratAuthor
Associate II
February 15, 2023

Now that you said it...yeah, that's weird, There's nothing you're missing, I don't have a TTL-to-RS232 shifter.

I'm taking a look at it, everything is really weird. I managed to receive signals if I sent messages very quickly and it's very inconsistent, if I had a delay to sent messages every second then it's impossible to make it work and the signal you see it's like the one were talking about.

I don't understand anything.

Maybe it's just noise, what I see now looks like a word, but the characters are wrong. Maybe he's interpreting that the start or stop bit or whatever is in the wrong position.

Viktor POHORELY
ST Employee
February 14, 2023

Do you have baud rate set correctly?

fancyrat
fancyratAuthor
Associate II
February 14, 2023

Yes, baud rate is set correctly. I haven't managed to make it work with the DMA (as I want). But the following code is working right now:

void send_uart_data(const uint8_t *data, uint32_t size) {
 for (uint32_t i = 0; i < size; i++) {
 while (!LL_USART_IsActiveFlag_TXE(USART1)); // Wait until TX buffer is empty
 LL_USART_TransmitData8(USART1, data[i]);
 }
}
 
void comms_task(void)
{
 const uint8_t data[] = "Hello, world!";
 send_uart_data(data, sizeof(data)-1);
}

I don't know, I'm probably missing a configuration or initialization in the DMA. This is what I've done in the last try, I've tried more complex stuff, but wasn't working, so I'm trying simpler things now:

/* Define UART Tx DMA buffers */
uint8_t uart_dma_buffer[32] = "Hello, world!";
uint8_t dma_buffer_size = sizeof(uart_dma_buffer);
 
void comms_init(void){
 /* Enable DMA in the USART */
 LL_USART_EnableDMAReq_TX(USART1);
 
 /* Configure DMA for USART Tx */
 LL_DMA_InitTypeDef dma_init = {0};
 dma_init.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
 dma_init.PeriphOrM2MSrcAddress = (uint32_t)&USART1->RDR;
 dma_init.MemoryOrM2MDstAddress = (uint32_t)uart_dma_buffer;
 dma_init.Mode = LL_DMA_MODE_CIRCULAR;
 dma_init.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
 dma_init.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
 dma_init.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
 dma_init.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
 dma_init.NbData = dma_buffer_size;
 
 LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_init);
 
 /* Enable DMA channel */
 LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
}
 
void comms_task(void)
{
 /* Wait for DMA transfer complete */
 while (!LL_DMA_IsActiveFlag_TC1(DMA1)) {}
 
 /* Clear DMA transfer complete flag */
 LL_DMA_ClearFlag_TC1(DMA1);
 
 /* Restart DMA transfer */
 LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, dma_buffer_size);
 LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
}

KnarfB
Super User
February 15, 2023

The DMA in your above code is setup for receiving, not transmitting:

dma_init.PeriphOrM2MSrcAddress = (uint32_t)&USART1->RDR;

hth

KnarfB

fancyrat
fancyratAuthor
Associate II
February 15, 2023

Ok, this is really stupid.

I managed to get a consistent (wrong) message using DMA. If I use my hands as a "resistance" between both Tx wires, I receive the correct messages.

I guess that I'm stuck now working as a wire for the rest of my life.

KnarfB
Super User
February 15, 2023

STM32G031C6 has no SO8N in CubeMX.

fancyrat
fancyratAuthor
Associate II
February 16, 2023

In CubeMX I'm working with STM32G031J6Mx SO8N. I think that both chips are mostly the same.

0693W00000YAtGtQAL.png

KnarfB
Super User
February 16, 2023

Yeah, the disco board? For your above plots: double-check that you have probed the correct pins. On my disco, I have swapped RX and TX pins internally (CubeMX), so PB6 is free for SWD debugging. Make sure that TX is configured as push-pull PP, not OD by CubeMX.

Its also advisable to leave/config PF2 as NRST (option bytes), so you don't lock out yourself like several people here already did.

[Edit]: Have tried it with HAL_UART_Transmit_DMA and .. it worked as expected.

hth

KnarfB