The firmware

The previous version of this page


The are two versions of the firmware:

  1. UART-enabled
  2. SPI-enabled

Current UART- and SPI-firmwares differ in the following aspects:

  • UART communication is possible via the built-in ST-link’s USB-connection to any computer with USB. SPI communication requires a raspberry pi
  • UART bitrate is 115.2 kbps so transmission of a full dataset takes 640 ms.
    SPI bitrate is 15.6 Mbps so transmission of a full dataset takes 4.7 ms (the bitrate is actually dependent on the SPI-master, the rpi can handle up to 15.6 Mbps).
  • The UART fw can average up to 15 integrations before sending data.
    The SPI fw can’t do averaging, and with a bitrate of 15.6 Mbps it doesn’t have to.
  • The TCD1304’s MCLK is 2.0 MHz in the UART fw, and 4.0 MHz in the SPI fw (in both firmwares this can easily be changed at compile-time: look in main.h).
  • The maxium frame-rate for the TCD1304 is 1.4 Hz with the UART fw and 125 Hz with the SPI fw.¹
  • There’s Linux (CLI, GUI) and macos (CLI), and a 3rd party Windows (GUI) support for the UART fw. There’s Linux-only support for the SPI fw.

The user LED on the nucleo boards flashes with the ICG-frequency. The feature may be disabled by editing stm32f4xx_it.c but it can be useful for debugging (or simply checking if the upload went well).


Programming the STM32F401RE

Programming the STM32F401RE MCU is as simple as copying the file:

 F401_FW_TCD1304.bin

to the USB-drive that appears, when attaching the nucleo-board to your computer’s (any computer’s) USB-port.


Connections

The CCD should be connected to the nucleo board through the following GPIO’s:

  1. fM connects to PB0
  2. SH connects to PA1
  3. ICG connects to PA0
  4. Output connects to PC0

look at the howto for more details.


Interface (UART)

The UART-enabled firmware can communicate with any  pc over the nucleo’s USB connection. You can use the software presented on this site, or Jens-Ulrich Fröhlich’s java-based GUI.

You can of course also do it your own way, it should be fairly straightforward with something like LabVIEW or MATLAB. Daniele Zannoni wrote a matlab script for the TCD1304 firmware.

Here’s how to communicate with the UART-firmware:

To request a recording with an integration time of t_int, send the following 12 bytes to the nucleo:

0x45 0x52 0xSS 0xTT 0xUU 0xVV 0xKK 0xLL 0xMM 0xNN 0x01 0xYY

The two first are simply a key (the letters ‘ER’) for the nucleo to recognize. The data ends up in a circular buffer, so it’s necessary to know where to start reading.

The next 2x 4 bytes constitute the two 32-bit numbers holding the SH- and ICG-period respectively. The SH-period defines the integration time:

t_int = SH-period / 2.0 MHz

To satisfy the timing requirements of the CCD, make sure the following is obeyed:

ICG-period = n·SH-period ≥ 14776

The 11th byte is the pc ready flag (it’s actually not needed, except for compatibility reasons), and the 12th byte is the number of integrations to average. The firmware can collect and average up to 15 integrations.

Upon completion of UART-reception an interrupt is generated after which the firmware flushes the CCD, reconfigures the timers driving the CCD and collects the desired number of integrations.

When done reading, the nucleo transmits 7388 bytes, which must be combined on the receiving side to 3694 16-bit values.


Interface (SPI)

The SPI-version must be connected to a raspberry pi (or something else with an SPI-controller).

The SPI firmware will only work with a CLI or GUI written specifically for SPI, and similarly for UART. It’s entirely possible to connect a nucleo with the UART-fw to a raspberry pi, but the rpi must then use the programs written for UART.

You can of course also do it your own way, it should be fairly straightforward. Here’s how to communicate with the SPI-firmware:

To request a recording with an integration time of t_int, send 7388 bytes to nucleo of which the first 12 must conform to this format:

0x45 0x52 0xSS 0xTT 0xUU 0xVV 0xKK 0xLL 0xMM 0xNN 0x01 0xYY 0xZZ

The two first are simply a key (the letters ‘ER’) for the nucleo to recognize, whether  the user is requesting a new integration or not.

The next 2x 4 bytes constitute the two 32-bit numbers holding the SH- and ICG-period respectively. The SH-period defines the integration time:

t_int = SH-period / 4.0 MHz

To satisfy the timing requirements of the CCD, make sure the following is obeyed:

ICG-period = n·SH-period ≥ 14 776

To avoid the risc of the ADC overwriting the previous integration, the ICG-period should be longer than 8 ms:

ICG-period = 8 ms · 4.0 MHz = 32 000

The 11th byte is the pc ready flag (it’s actually not needed, except for compatibility reasons).

The 12th and 13th byte is the 16-bit number holding the number of integrations to perform.

Upon completion of SPI-reception an interrupt is generated after which the firmware flushes the CCD, reconfigures the timers driving the CCD and collects the requested number of integrations.

At the end of each integration, the logic state of PB2 is changed, signalling that data is ready to be downloaded. The user must then send another 7388 bytes, to collect the data from the CCD.

Finally the 7388  8-bit values must be combined on the receiving side to 3694 16-bit values.


About the SH-period

For reasons unknown to me, odd SH-periods cause periodic noise, so I recommend you stick with even numbers for the SH-period.


About averaging

When using averaging, one should choose an ICG-period long enough to allow for the firmware to complete the addition the latest integration to the previous ones.

In short, use the CCD in electronic shutter mode, and use an ICG-period of at least 15 ms. It’s a conservative advice, considering collecting and storing the data takes 7.4ms and 3-4 ms respectively

More specfically:

ICG-period = n·SH-period ≥ 30000


¹ This is a conservative estimate based on a minimum ICG-period of 8 ms, roughly the time it takes to complete CCD-readout and SPI-transmission.  SPI-transmission is started by the ADC+DMA transfer-complete interrupt, but since SPI-transmission is slightly slower than CCD-readout the half-transfer-complete could as well be used. The total time would then be
3.7ms / 2 + 4.7 ms = 6.6 ms
The ADC could be restarted even before this without risk of overwriting not-yet transferred data, as the ADC+DMA still would be a few miliseconds behind the SPI+DMA. Unfortunately I don’t have the proper equipment to determine the actual minimum ICG-period.

Advertisements