DSHOT on PX4

Has someone started to implement the DSHOT on the PX4 (Nuttx) ?
I’ve implemented the DSHOT protocol on Maple mini (Arduino IDE), but same Timer and DMA initialization sequence don’t work for me on Pixhawk2.

@JulianOes,
I know this two year old thread.
I’m asking, because according to the roadmap, the dshot ability is planned to be released in June.
So, the work has probably started, and i also can help.

Right that would be great. Let’s see if @dagar or @bkueng have pointers for you.

Hey @salex

No, not yet. But would be great if you want to look into that.

Can you show us the code? @david_s5 can also help with timers and DMA.

I’m sorry, i can’t show my exact code, but it mostly based on this, with some timing adjustments it works with DSHOT150 on my Maple mini card.
What is missing here, is building the DSHOT word with the CRC, which is quite simple.
The most challenging part is hardware initialization, which is described in this code, but for STM32F103 CPU.
Now the challenge is to apply this to Pixhawk hardware using existing resources and drivers of NuttX OS.
From this blog, it’s clear that the timers that can work in that way are TIM1 and TIM8, as they are advanced timers, that can trigger the DMA transfer.

@david_s5, @JulianOes

This approach is different from one that used in Ardupilot/Betaflight, (which described in AN4776 of stm32 documentation).
Using the code, i mentioned, on F4/F7 family actually requires to use specific DMA2 streams and one of the two advanced timers TIM1 or TIM8, which are able to trigger DMA with Peripheral address of GPIOx->BSRR register.
The problem is, if the required DMA stream is already in use. Probably that was one of the reasons that Ardupilot implemented DSHOT support on ChibiOS, as it has DMA sharing ability.
Can you guys, answer please, what DMA streams are in use by the PX4 ?
Sometimes It is possible to move some resource to another DMA stream, according to DMA2 mapping.

@salex, @JulianOes, @bkueng

Currently DMA is not used on SPI but will be coming in to master in the near future and that has to be factored in.

Below are the Current assignments on the F4 for FMUv2-FMUv3

USART1 RX* DMA2,DMA_STREAM5,DMA_CHAN4 USART2 RX DMA1,DMA_STREAM5,DMA_CHAN4 USART3 RX DMA1,DMA_STREAM1,DMA_CHAN4 UART4 RX DMA1,DMA_STREAM2,DMA_CHAN4 UART5 RX DMA1,DMA_STREAM0,DMA_CHAN4 USART6 RX* DMA2,DMA_STREAM2,DMA_CHAN5 USART6_TX* DMA2,DMA_STREAM7,DMA_CHAN5 UART7 RX DMA1,DMA_STREAM3,DMA_CHAN5 UART8 RX DMA1,DMA_STREAM6,DMA_CHAN5 SDIO* DMA2,DMA_STREAM3,DMA_CHAN4

The FMU AUX PWM uses is timer 1 Channels 4:1 and timer 3 Channels 2,3

IIRC you need to setup the DMA to do a block of 4 writes to the CCRx using a stride of 4.

To do 4 channels I would look at using
DMA2 DMA_STREAM1 DMA_CHAN6

Just keep in mind SPI 1,2,4 are used on FMUv2-v3 and SPI1 will need RX, TX DMA.

@salex, @JulianOes, @bkueng

I forgot one used by the px4io driver:
USART6_TX* is DMA2,DMA_STREAM7,DMA_CHAN5

So it looks like Stream 4 is free.
I’ll try to implement it in the way i showed in previous posts, when the DMA writes directly to GPIO’s BSRR, not to CCRx.
I can use it with Timer1 Ch4 or Timer8 Ch3, because i need one of the advanced timers.
Timer8 is used for HRT, can be switched with Timer5.
Regarding the telemetry, i want to connect it to Serial 4/5, in case of 4 ESCs, each two should be multiplexed, and the dshot command must be sent periodically to activate /deactivate the telemetry, even if the command not changed. I don’t like this solution, but it is not easy to find free 4 serial ports.

FMI there’s some discussion around that here: https://github.com/betaflight/betaflight/pull/7446.

I suggest we go directly to DShot telemetry via motor signal line: https://github.com/betaflight/betaflight/pull/7264.

1 Like

Signal line telemetry is still in the development.
I started from reading is from serial port and have some problem with it.
I’m trying to read telemetry blocks of 10 bytes from SERIAL4 port.
I see the blocks on oscilloscope are sent at 100Hz.
I configured the port (termios) equivalently to raw mode in Linux:
termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
termios_p->c_cflag &= ~(CSIZE | PARENB);
termios_p->c_cflag |= CS8;

I’m just reading the data to big buffer. but for some reason most of the time the last byte of each block is missing.
When i connect the line to PC, i get all the data correctly.
What can be the reason for that ?

Can you join slack and there the #dshot channel? We found someone (Felix Niessen) working on DShot integration to PX4 who is intimately familiar with the protocol.

Hi guys, is there anything new regarding DShot integration into PX4

Yes, see https://github.com/PX4/Firmware/pull/12634