cancel
Showing results for 
Search instead for 
Did you mean: 

Problems on RX data on stm32f091 using uart and dma

Hi. After many hours my stm32f091 board does not receive what I send to it using uart.

Please could someone confirm that I'm using uart, rx and dma correctly?

So this is my sequence:

CubeMX -> usart1 -> DMA Settings -> add

(on RX, circular, memory)

Usart1 global interrupt: checked

main.c

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
 
bool ReadyRead0= false;
std::vector<unsigned char> VBufferSerial0Read;
unsigned char MicroBufferSerial0Read[2];
unsigned long LastByteIn0;
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
	if (huart->Instance== USART1) {
		VBufferSerial0Read.push_back(MicroBufferSerial0Read[0]);
		LastByteIn0= HAL_GetTick();
		ReadyRead0= true;
	}
}
 
/* USER CODE END PFP */
 
int main(void)
{
	HAL_UART_Receive_DMA(&huart1, (uint8_t*)&MicroBufferSerial0Read, 1);
    for(;;) {
        if (ReadyRead0) {
            ......
            ......
            ......
            ReadyRead0= false;
        }
    }
}

6 REPLIES 6
randy2
Associate II

There should be an example in your device firmware package. You are not checking what the HAL returns. whats happening in your debug...

in mozbek we trust
Associate II

Yes you should as @randy2​ says you should check what happening in your debug

Is my code ok? Is there a better way to use dma on rx channel, without to know how many bytes are coming?

Hi there,

Yes you can use IDLE interrupts in normal mode, not circular. The was a good example of code if you google "Efficiently receive UART data using DMA"

T J
Lead

Excellent work, Tick, Tick Tick....

my sequence:
 
CubeMX -> usart1 -> DMA Settings -> add
(on RX, circular, memory)
Usart1 global interrupt: checked

this is the Polling method..

In your process, are you waiting for a byte or a length ?

either way, you can Peek inside the RxDMAbuffer without reading it..

that is, if you are waiting for a length or sequence set.. You can Peek without touching

Usually a buffer has PtrIN and PtrOUT

on startup

PtrIN =0; // not needed

PtrOUT =0; // needed

if PtrIN - PtrOUT =0, there is no data in the buffer...

If the DMA receives a byte, PtrIN is calculated from the DMAbufferPointer.

U1RxBufferPtrIN =  U1RxBufSize - huart2.hdmarx->Instance->CNDTR;

used here to check the UNread length of the buffer

char readableU1(void) {
    U1RxBufferPtrIN =  U1RxBufSize - huart2.hdmarx->Instance->CNDTR;
    return U1RxBufferPtrIN - U1RxBufferPtrOUT;  //UNread length
}

I had to initialise the Rx interrupt, but I dont use the callback.

char readU1(void) {
    char readByte = Usart1RxDMABuffer[U1RxBufferPtrOUT++];
    if (U1RxBufferPtrOUT >= U1RxBufSize) U1RxBufferPtrOUT = 0;
    return readByte;
}

Your approach is very interesting.

I have just applied it and started to test.

I hope my demo board will work correctly till monday.

Have a nice weekend.