RMT migration to IDF 5.0

brushlesspower
Posts: 1
Joined: Mon Nov 27, 2023 10:34 am

RMT migration to IDF 5.0

Postby brushlesspower » Mon Nov 27, 2023 10:48 am

Hello,

in the past i used the RMT Peripheral for measuring a Pulse length, change this Value and transmit a new Pulse (with new Length).
All this has to be very fast and in IRAM.

Now i wanted to update everything the the actual IDF Version. But nothing is working any more.

Why i cant register a custom ISR?
Why i have to use queues?
Why i cant acces RMTMEM directly?

here is my Code:

ISR

Code: Select all

void IRAM_ATTR rmt_isr_handler(void* arg) {
  uint32_t intr_st = RMT.int_st.val;                  // get RMT Status -> Interrupt source (kann nur RMT CH1 receive sein)
  RMT.int_clr.val = intr_st;                          // Clear the Int-Flag which is set
  RMT.conf_ch[1].conf1.rx_en = 0;                     // disable receiver
  RMT.conf_ch[1].conf1.mem_owner = RMT_MEM_OWNER_TX;  // sonst wird Servo länge nie geändert

  uint32_t servo_tmp = RMTMEM.chan[1].data32[0].duration0;     // lese die Input Dauer -> 1 = 1µs
  //uint32_t servo_tmp = RMTMEM.chan[1].data32[0].duration1;     // lese die Input Dauer -> 1 = 1µs
  /*if(servo_tmp > throttle){
    RMTMEM.chan[2].data32[0].duration0 = throttle;    // throttle ist der aktuelle Limit wert
    throttle_output = throttle;                       // der neue Output wert
    }
    else{
    RMTMEM.chan[2].data32[0].duration0 = servo_tmp;    // servo_tmp ist der Input wert (kein Limit)
    throttle_output = servo_tmp;                       // der neue Output wert
    }*/

  throttle_input = servo_tmp;                         // last throttle input
  if (servo_tmp > Current_throttle_limit) {
    servo_tmp = Current_throttle_limit;               // neuer Wert für servo_tmp
  }
  if (servo_tmp > Temperature_throttle_limit) {
    servo_tmp = Temperature_throttle_limit;           // neuer Wert für servo_tmp
  }
  if (servo_tmp > Voltage_throttle_limit) {
    servo_tmp = Voltage_throttle_limit;               // neuer Wert für servo_tmp
  }
  if (servo_tmp > RPM_throttle_limit) {
    servo_tmp = RPM_throttle_limit;                   // neuer Wert für servo_tmp
  }
  RMTMEM.chan[2].data32[0].duration0 = servo_tmp;     // servo_tmp ist der Input wert inkl. Limit
  throttle_output = servo_tmp;                        // der neue Output wert

  RMT.conf_ch[2].conf1.mem_rd_rst = 1;                // resette Output
  RMT.conf_ch[2].conf1.mem_rd_rst = 0;                // resette Output
  //RMT.int_clr.ch2_tx_end = 1;                       // Clear Interrupt Flag -> bereits oben erledigt (sollte auch garnicht aktiv sein)
  RMT.conf_ch[2].conf1.tx_start = 1;                  // Starte Output
  //rmt_tx_start(rmt_tx_channel.channel, 1);          // IDF funktion zum resetten und starten

  if (servo_tmp != 0) {
    timerWrite(timer, 0);
    //gptimer_set_raw_count(timer,0);
    //TIMERG0.hw_timer[1].load_high = 0;
    //TIMERG0.hw_timer[1].load_low = 0;
    raw_analog_input = true;
    failsafe_bool = false;
    if (!timerAlarmEnabled(timer)) {
      timerAlarmEnable(timer);
    }
    /*if (TIMERG0.hw_timer[3].config.alarm_en == 0) {
      TIMERG0.hw_timer[3].config.alarm_en = 1;
    }*/
  }

  RMT.conf_ch[1].conf1.mem_wr_rst = 1;                // resette Input
  RMT.conf_ch[1].conf1.mem_owner = RMT_MEM_OWNER_RX;  // sonst wird Servo länge nie geändert
  RMT.conf_ch[1].conf1.rx_en = 1;                     // Enable Input
}
INIT

Code: Select all

#define RMT_CLK_DIV 80
// time before receiver goes idle
#define RMT_RX_MAX_US 2500
#define SERVO_IN 26
  #define SERVO_OUT 18

rmt_config_t rmt_rx_channel;
rmt_config_t rmt_tx_channel;

rmt_rx_channel.channel = RMT_CHANNEL_1;                    // RMT Channel 1
  rmt_rx_channel.gpio_num = (gpio_num_t) SERVO_IN;           // RMT Mapped GPIO
  rmt_rx_channel.clk_div = RMT_CLK_DIV;                      // RMT_Clock auf 1us?
  rmt_rx_channel.mem_block_num = 1;
  rmt_rx_channel.rmt_mode = RMT_MODE_RX;                     // RMT Mode RX
  rmt_rx_channel.rx_config.filter_en = true;                 // Filter aktiv
  rmt_rx_channel.rx_config.filter_ticks_thresh = 250;        // Pulse unter 250 werden ignoriert (0...255)
  rmt_rx_channel.rx_config.idle_threshold = RMT_RX_MAX_US;   // Pulse über 2500 werden ignoriert -> Gleichzeitig die Verzögerung zw. Puls und ausführung der ISR

  rmt_config(&rmt_rx_channel);
  rmt_set_rx_intr_en(rmt_rx_channel.channel, true);
  rmt_rx_start(rmt_rx_channel.channel, 1);

  rmt_tx_channel.channel = RMT_CHANNEL_2;                             // RMT Channel 2
  rmt_tx_channel.gpio_num = (gpio_num_t) SERVO_OUT;                   // RMT Mapped GPIO
  rmt_tx_channel.clk_div = RMT_CLK_DIV;                               // RMT_Clock auf 1us
  rmt_tx_channel.mem_block_num = 1;
  rmt_tx_channel.rmt_mode = RMT_MODE_TX;                              // RMT Mode TX
  rmt_tx_channel.tx_config.loop_en = 0;                               // disable loop
  rmt_tx_channel.tx_config.carrier_en = 0;                            // disable carrier
  rmt_tx_channel.tx_config.idle_output_en = 0;                        // activate output while idle
  //rmt_tx_channel.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;         // output level to 0 when idle
  //rmt_tx_channel.tx_config.carrier_duty_percent = 50;               // must be set to prevent errors - not used
  //rmt_tx_channel.tx_config.carrier_freq_hz = 5000;                  // must be set to prevent errors - not used
  //rmt_tx_channel.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH;  // must be set to prevent errors - not used

  rmt_config(&rmt_tx_channel);                            // set Config
  //rmt_tx_start(rmt_tx_channel.channel, 1);              // Output wird in ISR gestartet
  //rmt_set_tx_intr_en(rmt_tx_channel.channel, true);     // Output Interrupt unnötig

  rmt_isr_register(rmt_isr_handler, NULL, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL2, NULL);  // ESP_INTR_FLAG_IRAM
  RMTMEM.chan[2].data32[0].duration0 = 0;                               // Output Idle/Default value
  RMTMEM.chan[2].data32[0].level0 = 1;                                  // Output Idle/Default value
  RMTMEM.chan[2].data32[0].duration1 = 0;                               // Output Idle/Default value
  RMTMEM.chan[2].data32[0].level1 = 0;                                  // Output Idle/Default value

Who is online

Users browsing this forum: No registered users and 63 guests