Creating accurate delay between 2 pulses on different pins.

Voidim
Posts: 1
Joined: Mon Dec 12, 2022 9:06 am

Creating accurate delay between 2 pulses on different pins.

Postby Voidim » Mon Dec 12, 2022 11:53 am

Greetings, i
am new to the esp32. At first glance i though that 240mhz can get me really accurate delays, but turns out it uses 80mhz timer clock, and i have to use divider = 2 so it is 40mhz at the end(25ns each clock), and i cant make my code work.

I have a esp-wroom-32 module(esp32 dev module) and use arduino IDE, my task is to generate 2 pulses on different pins with as much accuracy as possible:
1) make GPIO_NUM_2 and GPIO_NUM_4 go HIGH
2)Generate single shot pulses on a button press with predefined delay:
2.1) Generate negative pulse ~100nS on pin 2 (after that pulse pin2 stays HIGH)
2.2) Wait certain amount of uS: from 3uS to 35uS with precise accuracy.(30nS or less each step i want to increase or decrease delay)
(like to
2.3)Generate another ~100nS pulse on pin4 (after that pulse pin4 stays HIGH)

Currently i came up with the following test code using a timer, but for some reason it does not works as i want:
1)it does not increment delay by 25ns each time (but it starts to work a little better at 22uS or more)
2) minimum delay is ~6.6us, after a while it jumps to 7.7 etc
  1. #include "driver/timer.h"
  2. int i = 0; // value added to match each loop
  3.  
  4. static bool IRAM_ATTR onTimer(void *args) //ISR function
  5. {
  6. //2nd signal pulse
  7.   REG_WRITE(GPIO_OUT_W1TC_REG, BIT4); //GPIO4 LOW(CLEAR)
  8.   __asm__ __volatile__ (
  9.     " nop\n"
  10.     " nop\n"
  11.     " nop\n"
  12.     " nop\n"
  13.     " nop\n"
  14.     " nop\n"
  15.     " nop\n"
  16.     " nop\n"
  17.     " nop\n"
  18.     " nop\n"
  19.     " nop\n"
  20.     " nop\n"
  21.     " nop\n"
  22.     " nop\n"
  23.     " nop\n"
  24.     " nop\n"
  25.     " nop\n"
  26.     " nop\n"
  27.   );
  28.   REG_WRITE(GPIO_OUT_W1TS_REG, BIT4); //GPIO4 HIGH (SET) !!!!!!!!!!!!!!
  29.   timer_pause(TIMER_GROUP_0, TIMER_0);
  30.   return false;
  31. }
  32.  
  33. void setup() {
  34. ////TIMERS SETUP////
  35.   timer_config_t config = {
  36.     .alarm_en = TIMER_ALARM_EN, //ISR on
  37.     .counter_en = TIMER_PAUSE, //timer off after init
  38.     //.intr_type = TIMER_INTR_LEVEL, //can be ignored
  39.     .counter_dir = TIMER_COUNT_UP, //up
  40.     .auto_reload = TIMER_AUTORELOAD_EN, /hardware will load counter value after an alarm event;
  41.     .divider = 2, //from 2 to 65536 if 2  = 40mhz =25ns
  42.   }; //default clock source is APB (80mhz)
  43.  
  44.  timer_init(TIMER_GROUP_0, TIMER_0, &config); //init
  45. timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); //start value
  46. timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 250); //match value
  47. timer_isr_callback_add(TIMER_GROUP_0, TIMER_0, onTimer, NULL, 0); // add isr func
  48.  timer_enable_intr(TIMER_GROUP_0, TIMER_0); // enable isr
  49.  
  50. ////PINS SETUP////
  51. //set it as gpio
  52. gpio_pad_select_gpio( GPIO_NUM_2);
  53.  gpio_pad_select_gpio( GPIO_NUM_4);
  54. //output
  55. gpio_set_direction( GPIO_NUM_2,  GPIO_MODE_OUTPUT);
  56.   gpio_set_direction( GPIO_NUM_4,  GPIO_MODE_OUTPUT);
  57. //pullup to 3.3
  58. gpio_set_pull_mode( GPIO_NUM_2,  GPIO_PULLUP_ONLY);
  59.   gpio_set_pull_mode( GPIO_NUM_4,  GPIO_PULLUP_ONLY);
  60. //out current = 40ma
  61. gpio_set_drive_capability( GPIO_NUM_2,  GPIO_DRIVE_CAP_3);
  62.   gpio_set_drive_capability( GPIO_NUM_4,  GPIO_DRIVE_CAP_3);
  63. //set as high
  64. gpio_set_level( GPIO_NUM_2,  1); //HIGH
  65.   gpio_set_level( GPIO_NUM_4,  1); //HIGH
  66. }
  67.  
  68. void loop() {
  69. delay(500);
  70.  timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 100+i); //set new match value (100 should be ~2.5uS)
  71. timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); //reset starting value to 0
  72. delay(50);
  73.  
  74. //1st signal PULSE
  75.  REG_WRITE(GPIO_OUT_W1TC_REG, BIT2); //GPIO2 LOW(CLEAR)
  76.  __asm__ __volatile__ (
  77.     " nop\n"
  78.     " nop\n"
  79.     " nop\n"
  80.     " nop\n"
  81.     " nop\n"
  82.     " nop\n"
  83.     " nop\n"
  84.     " nop\n"
  85.     " nop\n"
  86.     " nop\n"
  87.     " nop\n"
  88.     " nop\n"
  89.     " nop\n"
  90.     " nop\n"
  91.     " nop\n"
  92.     " nop\n"
  93.     " nop\n"
  94.     " nop\n"
  95.   );
  96.   REG_WRITE(GPIO_OUT_W1TS_REG, BIT2); //GPIO2 HIGH (SET)
  97.  
  98. //start timer
  99.   timer_start(TIMER_GROUP_0, TIMER_0);
  100. }

Maybe there is better peripheral to do that task?
There is so many ways it seems to do that task: with DMA, RTC, LED pwm, creating some assembly code(i am not familiar with it) that can utilize 240mhz so we can get 4.16ns step.
All those ways just overwhelms me.

Who is online

Users browsing this forum: No registered users and 90 guests