/* ESP32 reading PWM RC signals 8 CH.
    Based on the code for ATmega 328: https://github.com/TheDIYGuy999/Rc_Engine_Sound
    modified for boat by croky_b for boat
 *  ***** ESP32 CPU frequency must be set to 240MHz! *****

   
*/



#include "driver/rmt.h"

//
// =======================================================================================================
// PIN ASSIGNMENTS & GLOBAL VARIABLES (Do not play around here)
// =======================================================================================================
//
// Pin assignment and wiring instructions

// ------------------------------------------------------------------------------------
// Use a 330Ohm resistor in series with all I/O pins! allows to drive LED directly and
// provides short circuit protection.
// ------------------------------------------------------------------------------------

#define RMT_TICK_PER_US 1
// determines how many clock cycles one "tick" is
// [1..255], source is generally 80MHz APB clk
#define RMT_RX_CLK_DIV (80000000/RMT_TICK_PER_US/1000000)
// time before receiver goes idle
#define RMT_RX_MAX_US 3500

#define RECEIVER_CHANNELS_NUM 8
const uint8_t RECEIVER_CHANNELS[RECEIVER_CHANNELS_NUM] = {0, 1, 2, 3, 4, 5, 6, 7 };
const uint8_t RECEIVER_PINS[RECEIVER_CHANNELS_NUM]  = {13, 12, 14, 27, 33, 35, 39, 34 };

uint32_t  pulseWidth[7];                  // Current RC signal pulse width 

//
// =======================================================================================================
// RMT
// =======================================================================================================
//
// Reference https://esp-idf.readthedocs.io/en/v1.0/api/rmt.html
static void IRAM_ATTR rmt_isr_handler(void* arg) {

  uint32_t intr_st = RMT.int_st.val;

  uint8_t i;
  for (i = 0; i < RECEIVER_CHANNELS_NUM; i++) {
    uint8_t channel = RECEIVER_CHANNELS[i];
    uint32_t channel_mask = BIT(channel * 3 + 1);

    if (!(intr_st & channel_mask)) continue;

    RMT.conf_ch[channel].conf1.rx_en = 0;
    RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_TX;
    volatile rmt_item32_t* item = RMTMEM.chan[channel].data32;
    if (item) {
      pulseWidth[i] = item->duration0;
    }

    RMT.conf_ch[channel].conf1.mem_wr_rst = 1;
    RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_RX;
    RMT.conf_ch[channel].conf1.rx_en = 1;

    //clear RMT interrupt status.
    RMT.int_clr.val = channel_mask;
  }
}

//
// =======================================================================================================
// MAIN ARDUINO SETUP (1x during startup)
// =======================================================================================================
//

void setup()
{
 
  //{13,12,14,27,33,35,34,39 };

  pinMode(13, INPUT_PULLDOWN);
  pinMode(12, INPUT_PULLDOWN);
  pinMode(14, INPUT_PULLDOWN);
  pinMode(27, INPUT_PULLDOWN);
  pinMode(33, INPUT_PULLDOWN);
  pinMode(35, INPUT_PULLDOWN);
  pinMode(34, INPUT_PULLDOWN);
  pinMode(39, INPUT_PULLDOWN); 


  // Communication setup --------------------------------------------

  Serial.begin(115200); // USB serial (for DEBUG)

  
  // PWM ----
  // New: PWM read setup, using rmt
 
  uint8_t i;
  rmt_config_t rmt_channels[RECEIVER_CHANNELS_NUM] = {};

  for (i = 0; i < RECEIVER_CHANNELS_NUM; i++) {
    rmt_channels[i].channel = (rmt_channel_t) RECEIVER_CHANNELS[i];
    rmt_channels[i].gpio_num = (gpio_num_t) RECEIVER_PINS[i];
    rmt_channels[i].clk_div = RMT_RX_CLK_DIV;
    rmt_channels[i].mem_block_num = 1;
    rmt_channels[i].rmt_mode = RMT_MODE_RX;
    rmt_channels[i].rx_config.filter_en = true;
    rmt_channels[i].rx_config.filter_ticks_thresh = 100; // Pulses shorter than this will be filtered out
    rmt_channels[i].rx_config.idle_threshold = RMT_RX_MAX_US * RMT_TICK_PER_US;

    rmt_config(&rmt_channels[i]);
    rmt_set_rx_intr_en(rmt_channels[i].channel, true);
    rmt_rx_start(rmt_channels[i].channel, 1);
  }

  rmt_isr_register(rmt_isr_handler, NULL, 0, NULL); // This is our interrupt



  // wait for RC receiver to initialize

  while (millis() <= 3000) ;

}
// =======================================================================================================
// READ PWM RC SIGNALS
// =======================================================================================================
// CH1=[0] CH2= [1] CH3=[2] CH4=[3] CH5=[4] CH6=[5] CH7=[6] CH8=[7]

void readRcSignals()
{  
   delay(500);
  Serial.print("CH1 :");
  Serial.println(pulseWidth[0]);
  Serial.println("");
  Serial.print("\CH2 :");
  Serial.println(pulseWidth[1]);
  Serial.println("");    
  Serial.print("CH3 :");
  Serial.println(pulseWidth[2]);
  Serial.println("");    
  Serial.print("CH4 :");
  Serial.println(pulseWidth[3]);
  Serial.println("");
  Serial.print("CH5 :");
  Serial.println(pulseWidth[4]);
  Serial.println("");
  Serial.print("CH6 :");
  Serial.println(pulseWidth[5]);
  Serial.println("");
  Serial.print("CH7 :");
  Serial.println(pulseWidth[6]);
  Serial.println("");
  Serial.print("CH8 :");
  Serial.println(pulseWidth[7]); 
} 
//
// =======================================================================================================
// MAIN LOOP
// =======================================================================================================
//


void loop()
{  
  readRcSignals();  
}