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

Timing chart of  the TCD1304

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).

enter image description here

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:

  1. 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.

  2. 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.

  3. 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?

  • I am not familiar with the internals of the ESP32, but if I were doing it on an equivalent PIC32 I'd probably use SPI to generate the clock signal, which I then divide by 2. SPI then generates an interrupt every 8 clocks (or 4 after dividing by 2) which triggers DMA to read from the ADC. Another DMA channel sends out dummy bytes through SPI to keep the clock running and performing enough transactions. I2S relies on an external CODEC chip to do the ADC (and DAC). – Majenko Aug 13 '20 at 11:42
  • @Majenko using SPI for clock generation is a nice idea, I like it! The ESP32's SPI supports 4-bit transmission mode, which seems to be perfect for this. But I still have no idea how I could synchronize the SPI dummy signal with the SH/ICG signals and how I would generate those. Do you think, bitbanging using a timer followed by a call to my dummy SPI transmission (which triggers ADC-DMA) could work? – Sim Son Aug 13 '20 at 12:31
  • The SPI interrupt could be used to manage those pulses I would think. You could also use it to start / stop the ADC reading DMA channel. – Majenko Aug 13 '20 at 12:32
  • @Majenko concerning I2S: do you mean I2S actually requires external hardware? From what I understand, the ESP32's I2S interface is capable of reading the internal ADC to achieve sampling rates of up to ~300kHz, or am I wrong? – Sim Son Aug 13 '20 at 12:33
  • As I mentioned earlier, I am not familiar with the internals. They may have added some loopback to an internal CODEC I guess, but I haven't a clue. I've only ever worked with external CODEC chips. You'd have to consult the TRM datasheet. – Majenko Aug 13 '20 at 12:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.