Half-Duplex burst mode DMAR

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: barthess, RoccoMarco

andypiper
Posts: 5
Joined: Sat Oct 24, 2020 5:21 pm

Half-Duplex burst mode DMAR

Postby andypiper » Sat Oct 24, 2020 5:32 pm

Hi There,
I am trying to write a driver that uses burst mode DMAR in half duplex mode - so the MCU steps up DMA using DMAR, sends a bunch of data, waits a little and then does the reverse to read the response over DMA from the peripheral (timer).
The documentation on burst mode is extremely thin, and its difficult to understand what the right sequence is - or if this is even possible.
Outbound is working fine, its the incoming response that I am having trouble with. The STM32 documentation indicates that inbound should be exactly the same setup as outbound with the exception of using STM32_DMA_CR_DIR_P2M instead of STM32_DMA_CR_DIR_M2P but I get no data.

Is there anything I should be aware of with trying this setp? Are there any good code samples / documentation of something similar?
In particular I don't understand how the timer clock frequency relates to the pulses being read (hopefully) using burst mode.
Any help greatly appreciated!

User avatar
Giovanni
Site Admin
Posts: 13118
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 767 times
Been thanked: 651 times
Contact:

Re: Half-Duplex burst mode DMAR

Postby Giovanni » Sat Oct 24, 2020 9:59 pm

Hi,

I never tried it, this could be a good question on the ST forums, it is not ChibiOS-specific.

Giovanni

User avatar
FXCoder
Posts: 284
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 117 times
Been thanked: 89 times

Re: Half-Duplex burst mode DMAR

Postby FXCoder » Sun Oct 25, 2020 10:48 am

Hi,
Have you set the DMA transfer size through DMAR to halfword?
Which TIM registers are you writing to/reading from?
--
Bob

andypiper
Posts: 5
Joined: Sat Oct 24, 2020 5:21 pm

Re: Half-Duplex burst mode DMAR

Postby andypiper » Thu Oct 29, 2020 10:49 pm

FXCoder wrote:Hi,
Have you set the DMA transfer size through DMAR to halfword?
Which TIM registers are you writing to/reading from?
--
Bob

Thanks for the suggestions - the main problem was the timer was setup wrong. We are making some progress now but its clear there are many ways to skin this cat which makes things interesting! Will update with more details when I have a better understanding where we have got to.

Maybe you can answer a related question: let's say we get the timer/pins/channel etc all set up correctly and the DMA transaction going - what exactly is it reading? The incoming signal is DShot telemetry so a 21bit serial packet at fixed rate, active low, but transitioning from active high with the first bit always guaranteed to be 0 (so there is always an edge at the start of the packet) and ideally we are reading four of these at once . So what goes into the CCR register? Should it be a string of 1's and 0's or should we try and read the whole packet into two register reads or something different?

User avatar
FXCoder
Posts: 284
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 117 times
Been thanked: 89 times

Re: Half-Duplex burst mode DMAR

Postby FXCoder » Fri Oct 30, 2020 12:07 am

Hi Andy,
If you want to capture high speed PWM (i.e. the ChibiOS ICU driver isn't fast enough) and get the timer counts for each pulse/valley using DMA then for a single channel you'd need to setup two DMA streams and timer configuration as follows:

1. A TIM CH trigger on the edge (trailing in this case) which generates an UP event and DMA transfer.
NOTE: CC is not enabled at this time and the timer should be using slave mode with combined reset + trigger (mode 8).
The UP event DMA is used to transfer a new config (using DMAR) to TIM:CCER which enables the CC of the timer.
The new CCER setting should enable capture on either edge of the input.

2. A CC DMA which will transfer each CC event (the TIM:CNT) to a memory buffer.
You know how many transitions you want to capture and need to set the DMA transfer count accordingly.

Once you get your PWM data in memory then do whatever it is that you need to analyze the counts into pulse widths based on the TIM clock rate.
You should have DMA interrupt handlers to capture errors/TCIF and some state machine management over the whole process.

To add further channels (2,3, 4) is a bit more challenging. I've not had a requirement for a setup like that.
TIM2 would be a candidate for you to try this once you get single channel functional.
--
Bob

User avatar
alex31
Posts: 304
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 28 times
Been thanked: 37 times
Contact:

Re: Half-Duplex burst mode DMAR

Postby alex31 » Fri Oct 30, 2020 10:19 am

andypiper wrote: So what goes into the CCR register? Should it be a string of 1's and 0's or should we try and read the whole packet into two register reads or something different?


Hello,
For the timer part and data representation :

In the DSHOT protocol, each bit is coded with a signal with a fixed period and a positive pulse width which depend on the value of the bit.
I don't remember the exact value, but let's say that the period is 10µs, and positive width is 3µs for a 0 and 7µs for a 1 bit ( **** not actual value of dshot, just for the example ***)
You have to setup the timer predivider so it can count microseconds.
after setting your DMA correctly, you will have in the memory buffer, an array of values which represent the pulse width, so if it's a 3, bit is 0, if it's a 7, bit is 1, and you have to deserialize the data using bitshift in the dma ISR.

For the DMA configuration :
the period if the same for 1 and for 0, so you just need to collect the width, not the period. If you have only one channel, you can directly set the correct CCR register address, no need for DMAR.

If you want to sample multi channels, as far as i know (but i can be wrong since FXCoder thinks it's possible) it's not possible. Input capture on STM32 Timer can be done only on channel 1 or 2 (not 3 and 4) and only one at a time.

I would be happy to be wrong, would be very handy to have multi channel ICU, let me know if this is possible.

If needed, i have example of binding timer in input capture mode and DMA, let me know if you want i send them to you, thay use a DMA driver that i wrote some time ago.

In one of your first post, you mention burst mode. Burst mode is just a way to optimize bandwidth, don't use it for beginning, let's design your driver without burst mode, and when it works without, try to enable it.

what would i do is :
write a driver to emit dshot frame
write a driver to receive dshot telemetry

then start the hard part : make a driver that can switch between emit and receive mode : you will need to know exactly when the last bit of the frame you send has been really sent by the timer, before switching in receive mode. especially when using burst and/or dma fifo, it can be though to know, probably you'll need a busy loop checking on timer state register.

Don't hesitate to post you progress, it's an interesting project.


Alexandre

andypiper
Posts: 5
Joined: Sat Oct 24, 2020 5:21 pm

Re: Half-Duplex burst mode DMAR

Postby andypiper » Fri Oct 30, 2020 2:19 pm

FXCoder wrote:Hi Andy,
If you want to capture high speed PWM (i.e. the ChibiOS ICU driver isn't fast enough) and get the timer counts for each pulse/valley using DMA then for a single channel you'd need to setup two DMA streams and timer configuration as follows:

1. A TIM CH trigger on the edge (trailing in this case) which generates an UP event and DMA transfer.
NOTE: CC is not enabled at this time and the timer should be using slave mode with combined reset + trigger (mode 8).
The UP event DMA is used to transfer a new config (using DMAR) to TIM:CCER which enables the CC of the timer.
The new CCER setting should enable capture on either edge of the input.

2. A CC DMA which will transfer each CC event (the TIM:CNT) to a memory buffer.
You know how many transitions you want to capture and need to set the DMA transfer count accordingly.

Once you get your PWM data in memory then do whatever it is that you need to analyze the counts into pulse widths based on the TIM clock rate.
You should have DMA interrupt handlers to capture errors/TCIF and some state machine management over the whole process.

To add further channels (2,3, 4) is a bit more challenging. I've not had a requirement for a setup like that.
TIM2 would be a candidate for you to try this once you get single channel functional.
--
Bob

Thanks for this. Just to be clear I only need the reverse part of dshot - the telemetry - which is not PWM, it is a fixed width signal. We have the burst mode outbound part (which is PWM) working nicely with DMAR. I'll probably have more questions as we work through this!

andypiper
Posts: 5
Joined: Sat Oct 24, 2020 5:21 pm

Re: Half-Duplex burst mode DMAR

Postby andypiper » Fri Oct 30, 2020 2:22 pm

alex31 wrote:
andypiper wrote: So what goes into the CCR register? Should it be a string of 1's and 0's or should we try and read the whole packet into two register reads or something different?


Hello,
For the timer part and data representation :

In the DSHOT protocol, each bit is coded with a signal with a fixed period and a positive pulse width which depend on the value of the bit.
I don't remember the exact value, but let's say that the period is 10µs, and positive width is 3µs for a 0 and 7µs for a 1 bit ( **** not actual value of dshot, just for the example ***)
You have to setup the timer predivider so it can count microseconds.
after setting your DMA correctly, you will have in the memory buffer, an array of values which represent the pulse width, so if it's a 3, bit is 0, if it's a 7, bit is 1, and you have to deserialize the data using bitshift in the dma ISR.

For the DMA configuration :
the period if the same for 1 and for 0, so you just need to collect the width, not the period. If you have only one channel, you can directly set the correct CCR register address, no need for DMAR.

If you want to sample multi channels, as far as i know (but i can be wrong since FXCoder thinks it's possible) it's not possible. Input capture on STM32 Timer can be done only on channel 1 or 2 (not 3 and 4) and only one at a time.

I would be happy to be wrong, would be very handy to have multi channel ICU, let me know if this is possible.

If needed, i have example of binding timer in input capture mode and DMA, let me know if you want i send them to you, thay use a DMA driver that i wrote some time ago.

In one of your first post, you mention burst mode. Burst mode is just a way to optimize bandwidth, don't use it for beginning, let's design your driver without burst mode, and when it works without, try to enable it.

what would i do is :
write a driver to emit dshot frame
write a driver to receive dshot telemetry

then start the hard part : make a driver that can switch between emit and receive mode : you will need to know exactly when the last bit of the frame you send has been really sent by the timer, before switching in receive mode. especially when using burst and/or dma fifo, it can be though to know, probably you'll need a busy loop checking on timer state register.

Don't hesitate to post you progress, it's an interesting project.


Alexandre


Thanks - we already have the outbound and switch working fine. We are using burst for writing the four channels concurrently using PWM/DMAR. Its the inbound side that is challenging - it's not PWM, its a fixed width signal coming 30us after the end of the dshot frame. Note that you cannot do reading without writing - the code to trigger the telemetry is built into the outbound dshot signal (there is an extra XOR on the CRC and the signal is inverted).

I'd be interested to see your code!

andypiper
Posts: 5
Joined: Sat Oct 24, 2020 5:21 pm

Re: Half-Duplex burst mode DMAR

Postby andypiper » Sun Nov 01, 2020 11:01 pm

FXCoder wrote:Hi Andy,
If you want to capture high speed PWM (i.e. the ChibiOS ICU driver isn't fast enough) and get the timer counts for each pulse/valley using DMA then for a single channel you'd need to setup two DMA streams and timer configuration as follows:

1. A TIM CH trigger on the edge (trailing in this case) which generates an UP event and DMA transfer.
NOTE: CC is not enabled at this time and the timer should be using slave mode with combined reset + trigger (mode 8).
The UP event DMA is used to transfer a new config (using DMAR) to TIM:CCER which enables the CC of the timer.
The new CCER setting should enable capture on either edge of the input.

2. A CC DMA which will transfer each CC event (the TIM:CNT) to a memory buffer.
You know how many transitions you want to capture and need to set the DMA transfer count accordingly.

Once you get your PWM data in memory then do whatever it is that you need to analyze the counts into pulse widths based on the TIM clock rate.
You should have DMA interrupt handlers to capture errors/TCIF and some state machine management over the whole process.

To add further channels (2,3, 4) is a bit more challenging. I've not had a requirement for a setup like that.
TIM2 would be a candidate for you to try this once you get single channel functional.
--
Bob


Hi Bob,

It seems we have a further problem - the outputs are mapped to PB1, PE9, PE11 & PB0 (probably fairly typical for flight controllers) and there are restrictions on what timers can be used with these. It seems Betaflight uses bit-banging to avoid some of these timer allocation issues. Is it possible to bit-band with DMAR given this configuration with reasonable CPU overhead?

Regards

andy

User avatar
FXCoder
Posts: 284
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 117 times
Been thanked: 89 times

Re: Half-Duplex burst mode DMAR

Postby FXCoder » Mon Nov 02, 2020 12:33 pm

Hi Andy,
I think we've gone out of scope of the original question.
For existing hardware then you'll need to work within the constraints of that design.
If it were a new design then the story could be different.
--
Bob


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 2 guests