I am using the ADC read function "esp_adc_cal_get_voltage()".
Testing shows that a single read takes around 42 us. (Doing a raw read takes about the same time)
My question is: Can interrupts be processed during the 42 us? For instance, if a CAN packet arrives, will the CAN ISR fire during the read, or are all interrupts disabled until the 42 us read completes?
If I run a CAN bus at 1 Mbps, 4 CAN frames could arrive and need to be processed during the 42 us.
Thanks!
Can ADC read be interrupted?
Re: Can ADC read be interrupted?
On a hardware level it can, but the current software implementation won't allow it.
If you dig down deeper, you'll see that the function that actually starts the ADC conversion is adc_convert() and this function
essentially just starts the conversion and does a busy-wait while loop until the conversion is done. Therefore on the hardware level, the busy-wait can technically be interrupted by an ISR.
However adc_convert() is called within a critical section (see adc1_get_raw() or adc2_get_raw()). Interrupts (of the calling CPU) are disabled during critical sections, therefore the ISR will not occur.
I see two possible solutions
1) Write a version of adc1_get_raw() or adc2_get_raw() without critical sections. However critical sections are used to protect the ADCs from concurrent access of the ADC (either from other tasks, CPU, ISRs). Therefore removing the critical sections will result in the ADC conversion not being thread safe.
2) Run the ADC conversion and CAN ISR from separate CPUs. When a critical section is entered, only the calling CPU's interrupts are disabled. Therefore if the CAN ISR is run from the opposite CPU, they will not conflict with each other. The CAN driver's ISR is registered when can_driver_install() is called and the ISR is registered to whichever CPU can_driver_install() is called on. Therefore if you call esp_adc_cal_get_voltage() from CPU0, you should register the CAN ISR to CPU1.
If you dig down deeper, you'll see that the function that actually starts the ADC conversion is adc_convert() and this function
essentially just starts the conversion and does a busy-wait while loop until the conversion is done. Therefore on the hardware level, the busy-wait can technically be interrupted by an ISR.
However adc_convert() is called within a critical section (see adc1_get_raw() or adc2_get_raw()). Interrupts (of the calling CPU) are disabled during critical sections, therefore the ISR will not occur.
I see two possible solutions
1) Write a version of adc1_get_raw() or adc2_get_raw() without critical sections. However critical sections are used to protect the ADCs from concurrent access of the ADC (either from other tasks, CPU, ISRs). Therefore removing the critical sections will result in the ADC conversion not being thread safe.
2) Run the ADC conversion and CAN ISR from separate CPUs. When a critical section is entered, only the calling CPU's interrupts are disabled. Therefore if the CAN ISR is run from the opposite CPU, they will not conflict with each other. The CAN driver's ISR is registered when can_driver_install() is called and the ISR is registered to whichever CPU can_driver_install() is called on. Therefore if you call esp_adc_cal_get_voltage() from CPU0, you should register the CAN ISR to CPU1.
Re: Can ADC read be interrupted?
From a single 1M CAN bus I cannot work out how you could get 4 frames in 42us?
Re: Can ADC read be interrupted?
You are correct - my math was faulty. A 1 Mbps bus has a speed of 1 bit every microsecond. So a CAN frame will take approximately 128 us. Seems I was off by a factor of 10.
Who is online
Users browsing this forum: No registered users and 89 guests