AllenNeuralDynamics / AllenNeuralDynamics/harp.device.quac

"Zero Point" Adjustment Calibration

Aperta
#55 0 commenti 0 reazioni 1 assegnatario Rivendicata da @anjaldoshi Vedi su GitHub
firmware
Lingua principale
C#
Stelle
0
Fork
0
Merge medio
2g 14h
PR unite (30g)
8

Descrizione

By writing 0.0V to the output, the actual output will deviate by a few millivolts. From spot checking a few outputs across boards, we're seeing values on the order of -20 to -45mV. (This value is kinda large, and here's the hardware-related reason: https://github.com/AllenNeuralDynamics/harp.device.quad-dac/issues/56)

To handle any offset, we want a "zero calibration," a settable offset that persists across power resets. This value should be readable upon Harp DUMP.

For storing this calibration data, we could use a dedicated region in flash or even the SD card.

To adjust the output on-the-fly, several options exist:
### ~~A) PIO Driver Calibration~~
~~adjust the PIO code in the LTC264x driver to sum the input value and clamp overflow before outputting the final value over the SPI bus.~~

Unfortunately, the PIO blocks do not have dedicated adders to do this efficiently.

### B) Online Calibration
sum the values in the buffer memory using the CPU as they are being written to the PIO buffers or when they are in the buffers.

This is basically asking us to perform math on literally every sample at 4MHz.

### C) Pre-Calbration
Do the above option in advance and write the calibrated waveforms back to the SD card.

> [!NOTE]
> This issue may not need addressing in software if we can address what may be the root cause of the issue in hardware. See: https://github.com/AllenNeuralDynamics/harp.device.quad-dac/issues/56

## B) Online Calibration Strategy Proposal
This would involve intercepting the data as it goes between SD Card to DAC buffers before the DMA channel writes it to the PIO block.

The calibration needs to happen somewhere in this green boxed region:

Image

In code, this section lives in the `update` loop in [multi_file_player.h](https://github.com/AllenNeuralDynamics/harp.device.quad-dac/blob/dev/firmware/inc/multi_file_player.h#L396). You'd probably want to add an "offset[id]" value right after calling `f_read` to move data from the card to the buffer [here](https://github.com/AllenNeuralDynamics/harp.device.quad-dac/blob/dev/firmware/inc/multi_file_player.h#L435).

### Profiling
To validate that the above strategy works, we would need to profile the SD->Buffer loop to ensure we are still writing to 4 channels at 500KSamples-per-second each. To do this, we can use a built-in hardware "Systick" timer to calculate the elapsed time per loop iteration and ensure we are below a threshold (based on the SD Buffer Size and output sample rate).

The only registers we need to interact with SYSTICK are:
```cpp
#define SYST_CSR (*(volatile uint32_t*)(PPB_BASE + 0xe010))
#define SYST_CVR (*(volatile uint32_t*)(PPB_BASE + 0xe018)) // "current value" register
```

The LicketySplit device does something like this if you add a `PROFILE_CPU` flag to the compilation process. See [core1_lick_detection.cpp](https://github.com/AllenNeuralDynamics/harp.device.lickety-split/blob/main/firmware/src/core1_lick_detection.cpp#L39) for details. Similar code could be "book-ended" to [core1_file_player.cpp](https://github.com/AllenNeuralDynamics/harp.device.quad-dac/blob/dev/firmware/src/core1_file_player.cpp) loop.

> [!WARNING]
> `SYSTICK` is 24-bits and counts _down_. Have a look at the lick detector code for how to turn this into CPU cycles or microseconds--whatever's easiest.

## C) "Pre-Calibration" Strategy Proposal
This would involve writing a pre-calibrated waveform back to the SD card and updating it every time the waveform or calibration value changes.

### Representing/Using Calibration
* Store the calibration constants in non-volatile memory (SD or flash memory)
* Store "pre-calibrated" versions of the waveforms on the SD card that represent the nominal channel data with the offset pre-added.
* Playing a waveform will play the calibrated version of that waveform if it exists.
* Expose calibration constants as read/write-able Harp registers

### Validating/Updating Calibration
* On boot, or before indicating that the system is "ready" (via Harp message, etc), check the following:
* If the system has a pre-computed calibrated waveform. If not, but calibration constants exist, generate the calibrated waveform and write it to the SD card.
* If the the system has a pre-computed calibrated waveform, "spot check" that the calibrated waveform matches the calibration constants
* Upon writing calibration constants, update:
* the calibration constants in non-volatile memory (SD or flash memory)
* the pre-calibrated waveform representations

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.