Emulated UART - Timer triggered DMA for reading GPIOB->IDR in STM32L433RBT6
- June 8, 2020
- 14 replies
- 6408 views
Hello,
I am using STM32L433RBT6 for receiving data from NEO6M GPS module. The requirement to add the module was given after the circuit board was delivered. Hence, I need to implement the UART reception using emulated uart (bitbanging technique). I have implemented the uart using the technique described below. However, I am getting lots of junk characters mixed up with the target data.
Description:
I have initialized the pin, PB3, as EXTI and am using TIM2 (in update mode, not capture compare) for timing generation. Timer runs at a frequency twice the baud rate. The timing is calculated as follows:
APB clk=72MHz
Baud Rate=9600bps
Timer CNT=72000000/(2*9600) (for twice baud rate, timer count is divided by 2)
Timer CNT=3750=3749 (actual load value)
When EXTI detects a falling edge, it starts the timer by setting the EN bit of the TIM2->CR register whilst serving its ISR. All interrupts are disabled including the PB3 EXTI itself but not the timer interrupt, until the reception of 10 bits (1 stop bit, 1 start bit, 8 bit data, no parity) is over. When the timer generates an interrupt, a counter is incremented in the timer's ISR.
If the interrupt is generated by an odd count, the digital value of the pin is sampled. Else the ISR just checks whether the count has exceeded the frame length i.e. 19 timer counts. In odd counts, the GPIOB->IDR is stored in a buffer variable unprocessed. Once all bits are received. the data is parsed in the main code's infinite loop by masking the corresponding bit in the stored value of GPIOB->IDR. A screenshot of the received, parsed data is attached.
This issue is not board specific. I also tried this code on Nucleo-F767ZI board and found the exact same problem occurring with it too. The reception using a hardware uart is flawless as expected.
I have tried different optimization techniques but to no avail.
Reading GPIO-IDR through timer triggered DMA is the only route I haven't explored yet. However, I am not able to figure out a way to make this DMA work. I have set up a DMA on timer update event. The DMA configuration is given in the stm32l4xx_hal_msp.c file. Please advice on how to make the DMA work on timer update event for transferring GPIOB->IDR register to a buffer memory location.
