Page 1 of 1

Bidirectional Dshot using RMT

Posted: Tue Feb 08, 2022 5:26 pm
by ahalekelly
Hey, I'm trying to implement the bidirectional dshot protocol on the ESP-32 using the RMT peripheral. Basically I need to send a 16 bit packet at 600 kbps, wait for a 16 bit response on the same pin, repeat this at several kHz, and do this on 4 pins concurrently. I'm using the DShotRMT library as a starting point, which has implemented the transmit side of the protocol. ESP-FC seems to have implemented the same thing.

So my question is, is rapidly switching RMT channels back and forth between transmit and receive feasible and the best way to do this? What's the overhead on that? Or should I assign two RMT channels per pin, one for transmit and one for receive?

Re: Bidirectional Dshot using RMT

Posted: Sun Feb 13, 2022 6:43 pm
by ahalekelly
In order to allow the other MCU to respond, I need to switch the RMT output to high-impedance (input) mode. But my signal is default high, so a dip in the voltage results in an error in the signal. This demo code results in a 3us long low signal on the output, 6us before the RMT output is sent:

Code: Select all

	gpio_set_pull_mode(gpio_num, GPIO_PULLUP_ONLY);
	gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
	gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
	rmt_set_gpio(channel, RMT_MODE_TX, gpio_num, false);
	rmt_write_items(channel, dshot_tx_rmt_item, DSHOT_PACKET_LENGTH, false);
If you don't call rmt_set_gpio, rmt_write_items doesn't send anything.

Edit: Using rmt_config instead of rmt_set_gpio doesn't help. The blip in the voltage occurs during the rmt_config or rmt_set_gpio calls. RMT idle_level is set to high. Setting RMT inversion to true doesn't help.

Re: Bidirectional Dshot using RMT

Posted: Wed Feb 16, 2022 8:57 am
by ESP_Sprite
Is bidir Dshot open-drain? If so, couldn't you put both a receiving and a transmitting RMT channel on the same GPIO, then make that GPIO open-drain? If so, there's no need to switch stuff around.

Re: Bidirectional Dshot using RMT

Posted: Thu Feb 17, 2022 3:45 am
by ahalekelly
Oh that's a good idea. The protocol isn't open-drain but I think it's compatible. I didn't know you could put both an RX and a TX RMT channel on one GPIO, that would be helpful in saving me some GPIOs compared to using two per pin. I'll try it out.

Re: Bidirectional Dshot using RMT

Posted: Tue Feb 22, 2022 8:06 am
by ahalekelly
If I configure the RMT output and then call

Code: Select all

gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT_OD);
I don't get any output, how should I do this?

Re: Bidirectional Dshot using RMT

Posted: Wed Feb 23, 2022 3:46 am
by ESP_Sprite
Looking at the GPIO driver code, the bit that makes the GPIO an output also muxes it back to being a plain old GPIO instead of being connected to the RMT. You can either reconnect the GPIO to the RMT using esp_rom_gpio_connect_out_signal(), or use the HAL directly and call gpio_hal_output_enable(), gpio_hal_od_enable() and gpio_hal_input_enable() yourself.