2020-06-07 11:42 PM
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.
2020-06-08 04:57 AM
> F4 vs. L4
Sorry I've confused this thread with another one I've answered today morning.
Even in 'L433, PB3 is still TIM2_CH2 so you may/should make use of it as I've outlined above. Read the TIM chapter.
DMA in "L4 *can* access AHB2 thus GPIO.
IMO the most straighforward way is again to abandon early the idea that you pull this out by clicking in CubeMX or writing some magic Cube/HAL incantations. I'm sure it can be done in that way, except it's IMO more laborious than to read the RM (TIM and DMA chapter) and experiment. YMMV.
JW
2020-06-08 09:56 PM
For DMA one has to anyways abandon cube and hal libs. I use cube only for reliably initializing and defining all pins and registers. The commenting is also done automatically saving time. I then use the defined variables (which are intuitively named) to setup required registers and peripherals.
I had already read the reference manual before posting the question on this forum. Unlike other MCUs from ST lineup this one has very, very specifically defined peripherals having DMA capability on each APB. Refer the attachment.
Also I tried using TIM7 (which is connected to DMA2 CH5), in this case. I could not get the DMA running.
Also, I started this project trying to use PB3 in TIM2 AF1 input capture mode and figure out a way to sample the digital inputs. However, input capture works only when a transition is detected and does not permit sampling digital values by reading corresponding IDR. The digital value of the pin in IDR register is identically zero even if I had manually connected the power supply to this pin. In EXTI mode, sampling can be done, atleast manually.
2020-06-08 11:37 PM
> However, input capture works only when a transition is detected
> and does not permit sampling digital values by reading corresponding IDR.
You'd still sample upon timer overflow (Update), use the input channel only to start (Trigger) the timer.
JW
2020-06-09 03:24 AM
Done... Finally!!!
As you suggested I used TIM2 AF1 mode. I set the input filter value at 8. I enabled both IC interrupt and regular timer interrupt. Once the Input capture detected a falling edge, I disabled IC by setting the corresponding CCxE bit in the CCER register. The timer count is reset and the timer is allowed to interrupt at twice the baud rate until all 10 bits are received i.e. after 20 cycles.
Thanks a lot for your support.
2020-06-09 04:00 AM
19
As I've said above, you want to start waiting for the next startbit immediately after sampling middle of the stopbit.
JW