Driving several CCDs

It’s possible to drive and read several TCD1304s with the same MCU with only a slight modification of the source code. Look in downloads for files with the modifications presented here.

Driving more than one CCD is as simple as connecting the extras to the same output-pins on the MCU. The CCDs will then run with identical MCLK, SH and ICG, and as a consequence have identical integration time.¹ In addition to this, the data from each CCD is dumped to the input of the ADC in concert.

Because of this you should consider the following

As the pixels are clocked out at 1/4 rate of the MCLK, each pixel stays on the output of the CCD for:

    tpixel = 4 / MCLK = 4 / 2,0 MHz = 2,0 µs

Driving n CCDs, the MCU’s ADC has 2,0 µs / n to digitize each pixel from all the CCDs ouput. This will limit the number of CCDs that may be connected. The STM32F4 ADCs run with a clock of up to 36 MHz depending on the prescaler. In best case, that means the conversion time for 1 pixel is

    tconv = 12 / 36 MHz = 0,33 µs

In addition to this there’s the ADC sample-time. Its lowest value is 3 ADC clock-cycles

    tsample = 3 / 36 MHz = 0,083 µs

so the total conversion time for one pixel is

    tADC =  tconv + tsample = 0,33 µs + 0,083 µs = 0,417 µs

Giving a maximum number of CCDs that can be read

    n = tpixel / tADC = 2,0 µs / 0,417 µs = 4

Provided that there’s enough RAM on the MCU.

Lowering MCLK will allow for more CCDs. The file main.h provides values for MCLK that will work with the prescalers for the MCU’s timers.

In addition to lowering the sample time, it’s also necessary to configure additional input channels for the ADC, as well as increasing the number of conversions to perform per trigger pulse. Compare the ADC-configuration between the standard CCD firmware to the 3-CCD firmware to see how it’s done.

Data from the STM32F4’s ADC is transferred using DMA. The number of ADC-conversions handled by the DMA-controller for each ICG-pulse, is determined by the value CCDSize, which can be found in the file main.h. Set the value according to the number of CCDs (each CCD contain 3694 pixels). For two CCDs write

    #define CCDSize 7388

This will also take care of the size of the arrays holding the data. Beware that the overhead associated with averaging will be affected!

For an n CCD setup data is arranged as follows:

    aTxBuffer[0] = CCD1[1]
    aTxBuffer[1] = CCD2[1]
    ..
    aTxBuffer[n-1] = CCDn[1]
    aTxBuffer[n]   = CCD1[2]
    aTxBuffer[n+1] = CCD2[2]
    ..
    aTxBuffer[2n-1] = CCDn[2]
    ..
    ..
    aTxBuffer[3694n-1] = CCDn[3694]

The data is transmitted to the computer as is, and it’s the software’s headache to sort it into separate datasets for each CCD. There’s an example for the CLI in downloads.

The modifications presented here can be implemented for all STM32F4 firmwares. Be aware that the linux SPI-buffer will need resizing when using SPI. In principle it should also be possible for the STM32F103 fw, which has a max ADC-clock of 14 MHz.


1. If different driving parameters are required, the easiest is probably to use a separate MCU for each CCD.