Jens-Ulrich Fröhlich built my OtterVIS-LGL spectrophotometer and he reported that changing the pulse counter in the interrupt handler from 2 to 3 improved stability of the readings.
This is correct, so I decided to figure out why, after all I don’t want to wait one integration too long (or too short) for getting a proper reading.
The situation with a pulse counter of 2 looks like this:
The blue trace is the ICG pulse, which determines when the pixels are dumped into the TCD1304’s shift registers and read by the ADC. The ICG timer runs with a certain period (the first four pulses) until the MCU receives the new settings (pulse #5) somewhere after the fourth pulse. Then follows 2 pulses with a short period to clear the CCD, and then the ADC is started.
Of course this is undesirable, and with a pulse counter of 3 the new trace looks like:
The ADC start trace (red) is actually a GPIO that’s set high at ADC-DMA Half-Transfer interrupt and set low again at ADC-DMA Transfer-Complete, in case your wondering why it doesn’t start right when ICG goes high.
Here is a close-up of TIM4 (that paces the ADC) tied to a GPIO together with ICG:
fM (not shown) is 2.0 MHz and TIM4 is fM/4 ie. 0.50 MHz. The timer starts with a negligible delay¹ after ICG goes high, and is turned off 7.4 ms later, just as expected (3964 / 0.50 MHz = 7.4 ms).
I’ve also checked if the DMA_SxNDTR is counting properly, and at 3.7 ms after ICG it’s 1848 and at 7.4 ms it’s 3693 (the DMA is circular and NDTR is reset at the end).
In short I’m fairly certain the timers and their interrupts are behaving consistently and as expected.²
Now comes the puzzling part. Spending the entire weekend looking at the output, I’ve realized that someting odd is going on:
When new settings are received, the MCU is supposed to wait for the ADC-DMA Transfer-Complete interrupt before transmitting the collected pixel values back to the PC. However this is apparently not the case. There are owles in the marsh (as we say in Denmark).
- For long ICG-periods the consequence is that the MCU transmits the contents of aTxBuffer before it’s updated, ie. you get the previous reading. For some applications this is not a problem. You just collect twice, but if your sample is changing with time this is of not very desirable.
- For shorter ICG-periods you will see part of a new read and part of the old, and the frame shifts at pixel number: ICG/170. Again you can just collect twice and the problems goes away – if you can collect twice..
The behaviour is of course unacceptable and will be fixed. For now you know it exists!
¹ There are 32 dummy pixels, so with fM = 2.0 MHz theres 16 µs to eat at, but enabling and disabling TIM4 by manipulating directly with the TIM_CR1 register is fast enough that TIM4 is running even before ICG goes low.
² The timer update interrupt appears to also be called when the timer settings are changed. I’ve not looked into the reference manual, but the answer is most certainly there.