2017-05-29 08:55 AM
Hi all,
I'm using USART with DMA to implement a Modbus rtu slave node.
I want to implement this:
- the USART use DMA to store received characters in a buffer
- a contdown-timer count the time between character to recognise the end of the frame.
- the timer is loaded when new characters are loaded by the DMA. I want to recognize them with a 20kHz ISR that I use to do other stuff: Checking the value of the DMA count I know if new bytes has arrived.
I use the DMA as a sort of FIFO, because:
- I don't know the size of the message
- I don't want to use a ISR for each character to avoid loss of information.
Unfortunately, I didn't find any information about getting DMA count!
Does anyone can help me?
Thank you very much.
#stm32-dma #stm32f4 #modbusSolved! Go to Solution.
2017-05-29 11:28 AM
Using the HAL:
huart1.
hdmarx->
Instance->
NDTRDoing it the hard way, look for the NDTR register in the DMA unit.
Andrei
2017-05-29 11:28 AM
Using the HAL:
huart1.
hdmarx->
Instance->
NDTRDoing it the hard way, look for the NDTR register in the DMA unit.
Andrei
2017-05-31 12:46 AM
Hi Andrei,
Using the register you say, my routine works.
Thank you very much for your help!
Francesco
2017-05-31 01:24 AM
as Andrei said,
If you are using HAL library,
You may use the following code.
const uint16_t RX_MAX_SIZE = 64; //some integer which MODBUS RTU would never exceed
static uint16_t receivedBytes = 0;
HAL_UART_Receive_DMA(&huart1, rx_buffer, RX_MAX_SIZE);
....
/*if your timer have detected stop frame */
if(stop_frame_detected)
{
/*check rx receiving bytes*/
receivedBytes = RX_MAX_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx);
/*parse rx cmd*/
}
2017-05-31 11:39 AM
This is a better answer than mine. Thank you.
2017-06-01 05:03 AM
If you can rely on the incoming characters being gapless during a given message, you may find this approach useful:
https://community.st.com/0D50X00009XkhGfSAJ
I use the RX Idle interrupt to detect the end of variable-length RX DMA transactions, hence the (probable) end of messages. In the event of an incomplete message, you can assemble it during successive calls to the idle callback handler.
If you find this approach really useful, you might comment on the feature request so that ST knows that it's wanted by more folks than just one nutcase developer (that being me;-)
2017-06-01 03:30 PM
ST People.
I was trying to figure out why I've never heard of __HAL_DMA_GET_COUNTER before now. I found that it is not in the HAL documentation, like UM1725.
Is there any reason to NOT use this macro?
Andrei
2017-06-01 07:57 PM
Wow, UM1725 is such a huge doc. I always first take a quick view on src and header files, and then move to the manual.
2017-06-02 04:53 PM
I implemented the DMA 'timeout feature', detecting the possible end-of-transmission with USART IDLE interrupts. DMA is used in circular mode (for minimizing the chance of data-loss when receiving bytes from devices that transmit data frequently & periodically), and the newly received message is extracted from the DMA buffer. Here is my source code with explanation:
2017-06-05 03:27 AM
Hi Akos, hi Stephen,
I read your solution and I found them very interesting.
I have only a question regarding the USART IDLE interrupt: this is a specific feature of a micro? In the documentation of the stm32f4 I don't find it.
Anyway, the function I implemented is pretty similar to your solution, but done in a software way. I have a regulation routine that is time-constant and is called in a ISR working at 20kHz. In this routine I implemented the receiving operation. Reading the data count in DMA register (as suggested) I find if there are new data and in this case I reload a timer. If data arrives before the timer end of count they are of the same frame, in the timer reach zero the data are processed. I use half-duplex line, so the receiving is enabled only after the trasmission of the reply.
Ah, my application is a Modbus node.
I see that in recent MCU like stm32f0 there is a specific parameter to set in the USART peripheral to detect timeout after a character. This is very useful, but (unfortunately) is not present on my device!
Francesco