Aruna
ESP32_RMT_Dshot.cpp
Go to the documentation of this file.
1 //
2 // Created by noeel on 08-11-20.
3 //
4 
6 
7 using namespace aruna;
8 using namespace aruna::driver;
9 ESP32_RMT_Dshot::ESP32_RMT_Dshot(rmt_channel_t channel, gpio_num_t gpio_port) {
10  const static uint32_t PERF_CLK_HZ = 80000000;
11 // TODO get the clock speed dynamicly
12  const static uint8_t clk_div = 1;
13 
14 // config driver
15  driver_config.channel = channel;
16  driver_config.gpio_num = gpio_port;
17  driver_config.rmt_mode = RMT_MODE_TX;
18  driver_config.clk_div = clk_div;
19  driver_config.mem_block_num = 1;
20  driver_config.tx_config.loop_en = false;
21  driver_config.tx_config.carrier_en = false;
22  driver_config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
23  driver_config.tx_config.idle_output_en = false;
24 
25 // calculate ticks
26  const static float ticks_per_second_in_nanosecond = ((float) PERF_CLK_HZ / (float) clk_div) / 1000000000;
27 
28  T0H_ticks = ticks_per_second_in_nanosecond * T0H_ns;
29  T1H_ticks = ticks_per_second_in_nanosecond * T1H_ns;
30  T0L_ticks = ticks_per_second_in_nanosecond * T0L_ns;
31  T1L_ticks = ticks_per_second_in_nanosecond * T1L_ns;
32 
33  err_t rval;
34  esp_err_t eerr;
35  ESP_ERROR_CHECK(rmt_config(&driver_config));
36  eerr = rmt_driver_install(driver_config.channel, 0, 0);
37 // TODO make generic esp_err_t to aruna::err_t function?
38  switch (eerr) {
39  case ESP_OK:
40  rval = err_t::OK;
41  break;
42  case ESP_ERR_INVALID_ARG:
44  break;
45  case ESP_FAIL:
46  default:
47  rval = err_t::FAIL;
48  break;
49  }
50  // start thread
51  int p_mut, p_cre = 0;
52  p_mut = pthread_mutex_init(&dshot_frame_lock, NULL);
53  p_cre = pthread_create(&update_handler, NULL, _update_task, this);
54  if (p_mut || p_cre)
55  rval = err_t::TASK_FAILED;
56  startup_error = rval;
57 }
58 
60  rmt_driver_uninstall(driver_config.channel);
61  pthread_cancel(update_handler);
62  pthread_mutex_destroy(&dshot_frame_lock);
63 }
64 
66 
67  while (true) {
68  pthread_mutex_lock(&dshot_frame_lock);
70  pthread_mutex_unlock(&dshot_frame_lock);
71  usleep(1);
72  }
73 
74 }
75 
76 void *ESP32_RMT_Dshot::_update_task(void *_this) {
77  static_cast<ESP32_RMT_Dshot *>(_this)->update_task();
78  return 0;
79 }
80 
82  pthread_mutex_lock(&dshot_frame_lock);
83  this->dshot_frame = dshot_frame;
84  pthread_mutex_unlock(&dshot_frame_lock);
85  return err_t::OK;
86 }
87 
89  const static size_t rmt_size = 17;
90  static rmt_item32_t rmt_frame[rmt_size];
91 
92  for (uint8_t i = 0; i < rmt_size - 1; ++i) {
93  uint16_t i_bit = (dshot_frame >> (rmt_size - 2 - i)) & 0b1;
94  uint16_t on_time = i_bit ? T1H_ticks : T0H_ticks;
95  uint16_t off_time = i_bit ? T1L_ticks : T0L_ticks;
96 
97  rmt_frame[i] = {{{on_time, 1, off_time, 0}}};
98  }
99 // clear at the end
100  rmt_frame[rmt_size - 1] = {{{0, 1, 0, 0}}};
101 
102  ESP_ERROR_CHECK(rmt_write_items(driver_config.channel, rmt_frame, rmt_size, true));
103 // TODO return error.
104  return err_t::OK;
105 }
static void * _update_task(void *_this)
static function to help pthead
Definition: comm.cpp:14
err_t single_write(uint16_t dshot_frame)
Write a single Dshot frame to the bus.
uint16_t T1H_ns
Definition: Dshot.h:58
void update_task()
updates ESC with current dshot buffer, blocks CPU
uint16_t T0L_ns
Definition: Dshot.h:59
uint16_t T1L_ns
Definition: Dshot.h:60
uint16_t T0H_ns
Definition: Dshot.h:57
err_t startup_error
error when constructing gets put here, read before usage.
Definition: Actuator.h:45
ESP32_RMT_Dshot(rmt_channel_t channel, gpio_num_t gpio_port)
Dshot150 using RMT hardware.
err_t _write_frame_continuous(uint16_t dshot_frame) override
Write set Dshot frame continuously on the bus.