I want to read the TCD1304 linear CCD sensor with an ESP32 and I'm facing some problems. As a first "warm-up" and to get familiar with this sensor I tried to generate the sensors input signals using a timer interrupt and bitbanging, but soon I found out that the resulting signals were way to slow and I didn't get any useful readings.
The signals involved are:
- SH (shift gate): determines the integration time
- ICG (integration clear gate): used to transfer pixel values to the shift register
- ΦM: (master clock): self-explanatory
- OS: output signal
The timing of those signals seems to be quite critical (see diagram below) and need to be quite fast - supported master clock frequency ist 0.8-4MHz and an analog measurement has to be done after every 4th clock pulse (0.2-1MHz).
Right now I'm pretty lost and I believe that this task requires some progamming techniques that I'm not familiar with so far.
Basically, my question is:
What is the best way to generate those signals and how do I read the ADC at that high sampling rate/accurate in timing?
I have some ideas, but - as I said - I probably lack the required skills, so it's hard for me to decide which approach I should take:
Using a single timer and direct port manipulation: This would be easy to implement, but my assumption is that the interrupts will fire much too frequently to handle the ISR (which would be more or less complex, even if I refactorize my current test code). Especially reading the ADC will take too much time, I guess.
using the ESP's I2S-ADC: I have no experience with I2S. From what I understand it is good for reading the ADC with a high frequency, but it is typically used for periodic sampling. In my case I would need the readings to be aligned with the control signals and I don't know if that is possible/convenient with I2S-ADC.
using ADC-DMA: @esben Rossel has a done great work providing a framwork for STM32s and the TCD1304 in which he uses DMA for readout. I have never used direct memory access, but I feel this is a promising approach. Unfortunately, the documentation of the ADC only covers the ADC-RTC mode while there is no information about how to use the ADC-DMA mode. If DMA is the way to go I appreciate any hints on how I can get started with DMA programming on the ESP32.
In the latter cases 2) and 3) I would still need to generate the driving pulses in a "CPU-friendly" manner, probably hardware PWM (?), while the analog reading has to be triggered at every fourth clock pulse.
Would I use one timer for each signal and if yes, how would I ensure that the signals have the correct phase offset? Also, how can I trigger the analog measurement after every 4th clock pulse?