2023-02-13 02:10 AM
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).
Codewise 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:
2023-02-14 06:51 AM
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);
}
2023-02-14 07:15 AM
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.
2023-02-15 03:08 AM
yeah, that's for sure
2023-02-15 06:36 AM
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.
2023-02-15 07:00 AM
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.
2023-02-15 07:08 AM
STM32G031C6 has no SO8N in CubeMX.
2023-02-15 11:14 AM
The DMA in your above code is setup for receiving, not transmitting:
dma_init.PeriphOrM2MSrcAddress = (uint32_t)&USART1->RDR;
hth
KnarfB
2023-02-16 01:10 AM
In CubeMX I'm working with STM32G031J6Mx SO8N. I think that both chips are mostly the same.
2023-02-16 03:17 AM
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