Start documenting firmware

This commit is contained in:
Joris van Rantwijk 2024-08-31 21:42:04 +02:00
parent 5b21d0fb26
commit b07f6cabb6
1 changed files with 680 additions and 0 deletions

680
doc/fpga_firmware.md Normal file
View File

@ -0,0 +1,680 @@
# PuzzleFW FPGA firmware
The PuzzleFW firmware provides the following functionality:
* Collect ADC samples at 125 MSa/s with configurable decimation or averaging.
* Trigger on external digital input and collect a configurable number of samples.
* Detect transitions on digital input signals and assign time tags to these events.
* Transfer ADC data and timetagger data to the Zynq PS via DMA.
# Analog acquisition chain
TODO ...
When auto-trigger mode is active, the acquisition chain triggers continuously.
A new trigger occurs as soon as acquisition for the previous trigger has ended, after a dead time controlled by `TRIGGER_DELAY`.
In this mode, the decimation factor must be at least 2 (or at least 4 in 4-channel mode).
If `TRIGGER_DELAY` is zero, sampling continues accross at a fixed pace controlled by the decimation factor.
This makes it possible to set up continuous streaming data acquisition.
When external triggering is active, sampling starts when the specified external trigger condition occurs, after a delay of `TRIGGER_DELAY` samples.
The external trigger event is subject to a jitter of 1 sample (8 ns).
Further trigger events are ignored until acquisition for the previous trigger has ended.
TODO : DMA data format
TODO : LEDs
# Timetagger
TODO ...
TODO : DMA data format
TODO : LEDs
# Registers
The behaviour of the PuzzleFW firmware is controlled via a set of registers.
These registers are accessible from the Zynq PS via memory mapped I/O.
The registers are located in a 2 MB region with address 0x43000000 to 0x431fffff in the PS address map.
Within the register address space, the first 1 MB area is intended for various types of control and status registers that are accessed by user space software.
The second 1 MB area is intended for privileged registers that are only accessed by system software such as the Linux kernel driver.
The difference is that writing incorrect values to privileged registers can corrupt or crash the PS system, while writing to user registers can not.
The complete set of registers is listed below.
Access to undefined addresses within the register area must be avoided.
If such access occurs, the firmware may either ignore it or map it to an existing register in a way that may be unexpected.
## Register list
This list specifies register addresses as offsets within the register address space.
The base address 0x43000000 must be added to obtain the absolute address on the PS memory bus.
**User registers**
| Address | Name | Description |
|----------|-------------------|-------------|
| 0x000000 | INFO | Firmware version information |
| 0x000010 | IRQ_ENABLE | Enable PL-to-PS interrupts |
| 0x000014 | IRQ_PENDING | Mask of pending interrupt conditions |
| 0x000100 | DMA_EN | Enable DMA transfers |
| 0x000104 | DMA_STATUS | Status of DMA engine |
| 0x000108 | DMA_CLEAR | Clear DMA error flags |
| 0x000180 | TIMESTAMP_LO | Low 32 bits of global timestamp |
| 0x000184 | TIMESTAMP_HI | High 16 bits of global timestamp |
| 0x000188 | TIMESTAMP_CLEAR | Reset timestamp counter to zero |
| 0x000200 | ACQ_ADDR_START | Start address of DMA buffer for analog acquisition |
| 0x000204 | ACQ_ADDR_END | End address of DMA buffer for analog acquisition |
| 0x000208 | ACQ_ADDR_LIMIT | Pause DMA when write pointer reaches this point |
| 0x00020C | ACQ_ADDR_INTR | Raise interrupt when write pointer reaches thi point |
| 0x000210 | ACQ_ADDR_PTR | Current DMA write pointer |
| 0x000214 | ACQ_DMA_CTRL | Control DMA write stream for analog acquisition |
| 0x000218 | ACQ_INTR_CTRL | Control DMA interrupts for analog acquisition |
| 0x00021C | ACQ_DMA_STATUS | Status of DMA write stream for analog acquisition |
| 0x000220 | ACQUISITION_EN | Enable analog data acquisition |
| 0x000224 | RECORD_LENGTH | Number of samples per trigger minus 1. |
| 0x000228 | DECIMATION_FACTOR | Sample decimation factor minus 1. |
| 0x00022C | SHIFT_STEPS | Nr of bit steps to shift accumulated value right |
| 0x000230 | AVERAGING_EN | Select averaging or decimation |
| 0x000234 | CH4_MODE | Enable 4-channel sampling (4-channel device only) |
| 0x000238 | SIMULATE_ADC | Simulate ADC samples |
| 0x000240 | TRIGGER_MODE | Trigger configuration |
| 0x000244 | TRIGGER_DELAY | Trigger delay |
| 0x000248 | TRIGGER_STATUS | Trigger status |
| 0x000280 | ADC_SAMPLE | Most recent ADC samples from IN1 and IN2 |
| 0x000284 | ADC23_SAMPLE | Most recent ADC samples from IN3 and IN4 (4-channel device only) |
| 0x00028C | ADC_RANGE_CLEAR | Clear min/max ADC sample values |
| 0x000290 | ADC0_MINMAX | Min/max ADC sample values from IN1 |
| 0x000294 | ADC1_MINMAX | Min/max ADC sample values from IN2 |
| 0x000298 | ADC2_MINMAX | Min/max ADC sample values from IN3 (4-channel device only) |
| 0x00029C | ADC3_MINMAX | Min/max ADC sample values from IN4 (4-channel device only) |
| 0x000300 | TT_ADDR_START | Start address of DMA buffer for timetagger |
| 0x000304 | TT_ADDR_END | End address of DMA buffer for timetagger |
| 0x000308 | TT_ADDR_LIMIT | Pause DMA when write pointer reaches this point |
| 0x00030C | TT_ADDR_INTR | Raise interrupt when write pointer reaches thi point |
| 0x000310 | TT_ADDR_PTR | Current DMA write pointer |
| 0x000314 | TT_DMA_CTRL | Control DMA write stream for timetagger |
| 0x000318 | TT_INTR_CTRL | Control DMA interrupts for timetagger |
| 0x00031C | TT_DMA_STATUS | Status of DMA write stream for timetagger |
| 0x000320 | TIMETAGGER_EN | Mask of enabled timetagger channels |
| 0x000324 | TIMETAGGER_MARK | Emit marker record in timetagger data |
| 0x000404 | LED_STATE | Control LEDs |
**Privileged registers**
| Address | Name | Description |
|----------|-------------------|-------------|
| 0x100000 | DMA_BUF_ADDR | Base address of DMA buffer in RAM |
| 0x100004 | DMA_BUF_SIZE | Size of DMA buffer in RAM |
## Register descriptions
Registers are 32 bits wide, but many registers use only a subset of the bits.
A _field_ is a range of meaningful bits within a register.
Some registers contain multiple fields.
Fields are marked as _RW_ or _RO_ or _WC_.
* RW fields can be modified by writing to the register.
Reading from the register returns the most recent value written to the field.
* RO fields are read-only. Writes to these fields are ignored.
The value of these fields typically changes spontaneously to reflect the status of the firmware.
* WC fields are write-only and auto-clearing.
Writing a 1 bit to the field triggers an action in the firmware.
Writing a 0 bit has no effect.
WC fields are returned as 0 when reading from the register.
Bits that are not part of a field are _reserved_.
Reserved bits must be ignored when reading.
Reserved bits should be written as zero or left unmodified when writing.
### 0x000000: INFO
Firmware version information.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 7 : 0 | version_minor | RO | Firmware minor version |
| 15 : 8 | version_major | RO | Firmware major version |
| 23 : 16 | api_version | RO | Firmware API version, currently 0x01 |
| 31 : 24 | | RO | Fixed value 0x4a |
### 0x000010: IRQ_ENABLE
Enable PL-to-PS interrupts.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | irq_enable | RW | '1' to enable interrupts, '0' to disable |
This register acts as a master switch for interrupts from the firmware.
Specific interrupt conditions can be separately enabled or disabled via other registers.
### 0x000014: IRQ_PENDING
Mask of pending interrupt conditions.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | acq_intr | RO | '1' if an interrupt is pending for analog acquisition DMA |
| 1 | tt_intr | RO | '1' if an interrupt is pending for timetagger DMA |
### 0x000100: DMA_EN
Enable DMA transfers.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | dma_en | RW | '1' to enable DMA transfers, '0' to disable |
This register acts as a master switch for the DMA engine in the PuzzleFW firmware.
Disabling DMA will prevent new bursts from starting, but allows ongoing bursts to complete.
Under normal circumstances, the completion of ongoing bursts can take at most a few microseconds.
### 0x000104: DMA_STATUS
Status of DMA engine.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | dma_busy | RO | '1' if a DMA burst is in progres |
| 1 | err_read | RO | '1' if a DMA read access failed |
| 2 | err_write | RO | '1' if a DMA write access failed |
| 3 | err_address | RO | '1' if access outside the DMA buffer was attempted |
| 4 | err_any | RO | '1' if any DMA error occurred |
If a DMA error occurs, no further DMA bursts will be started until the error is explicitly cleared.
The failed DMA burst will not be acknowledged to the subsystem that initiated it (analog or timetagger).
To recover from this situation, it will typically be necessary to stop and re-initialize all ongoing DMA data streams, clear the error, then restart DMA data streams.
An address error typically occurs when the DMA address range for the analog subsystem or the timetagger exceeds the size of the DMA window specified via `DMA_BUF_SIZE`.
### 0x000108: DMA_CLEAR
Clear DMA error flags.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | dma_clear | WC | Write '1' to clear pending DMA errors |
### 0x000180: TIMESTAMP_LO
Low 32 bits of global timestamp.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 0 | | RO | Least significant 32 bits of the global 8 ns timestamp counter. |
### 0x000184: TIMESTAMP_HI
High 16 bits of global timestamp.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 15 : 0 | | RO | Most significant 16 bits of the global 8 ns timestamp counter. |
When reading both `TIMESTAMP_LO` and `TIMESTAMP_HI`, note that the timestamp will change between the two reads, possibly resulting in an invalid combination of low and high part.
To avoid this, read `TIMESTAMP_HI`, then `TIMESTAMP_LO`, then `TIMESTAMP_HI` again.
Then check that the value of `TIMESTAMP_HI` has not changed during the sequence, otherwise retry.
### 0x000188: TIMESTAMP_CLEAR
Reset timestamp counter to zero.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | timestamp_clear | WC | Write '1' to reset the timestamp counter. |
### 0x000200: ACQ_ADDR_START
Start address of DMA buffer for analog acquisition.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 7 | | RW | Start address as multiple of 128 bytes. |
The address must be aligned to a 128-byte boundary.
The address is interpreted as an offset relative to `DMA_BUF_ADDR`.
### 0x000204: ACQ_ADDR_END
End address of DMA buffer for analog acquisition.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 7 | | RW | End address as multiple of 128 bytes. |
The end address points past the end of the DMA buffer.
When the DMA write pointer reaches `ACQ_ADDR_END`, it immediately wraps back to `ACQ_ADDR_START`.
The address must be aligned to a 128-byte boundary.
The address is interpreted as an offset relative to `DMA_BUF_ADDR`.
### 0x000208: ACQ_ADDR_LIMIT
Pause DMA when write pointer reaches this point.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 7 | | RW | Address as multiple of 128 bytes. |
When the address pointer reaches the limit address, the DMA engine pauses further transfers until software updates the limit.
The address must be aligned to a 128-byte boundary.
The address is interpreted as an offset relative to `DMA_BUF_ADDR`.
### 0x00020C: ACQ_ADDR_INTR
Raise interrupt when write pointer reaches this point.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 3 | | RW | Address as multiple of 8 bytes. |
When the address pointer reaches this address, an interrupt occurs if analog acquisition interrupts are enabled.
The address must be aligned to an 8-byte boundary.
The address is interpreted as an offset relative to `DMA_BUF_ADDR`.
### 0x000210: ACQ_ADDR_PTR
Current DMA write pointer.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 3 | | RO | Address as multiple of 8 bytes. |
This register indicates the address where the next write transfer will start.
Write transfers have completed for locations up to (but excluding) this address.
This indicates that software can read valid data up to (but excluding) the pointer address.
The address will be aligned to an 8-byte boundary.
The address is interpreted as an offset relative to `DMA_BUF_ADDR`.
### 0x000214: ACQ_DMA_CTRL
Control DMA write stream for analog acquisition.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | acq_dma_en | RW | '1' to enable DMA transfers for analog acquisition. |
| 1 | acq_dma_init | WC | Write '1' to initialize the analog acquisition DMA stream |
Initializing the DMA stream resets the write pointer to `ACQ_ADDR_START` and discards pending data from the internal buffer.
Initializing is necessary after setting up the buffer address, and to recover from DMA errors.
### 0x000218: ACQ_INTR_CTRL
Control DMA interrupts for analog acquisition.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | acq_intr_en | RW | '1' to enable interrupt for DMA write pointer. |
| 1 | acq_intr_clear | WC | Write '1' to clear a pending interrupt condition. |
### 0x00021C: ACQ_DMA_STATUS
Status of DMA write stream for analog acquisition.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | acq_dma_busy | RO | '1' if an uncompleted DMA burst is in progress. |
### 0x000220: ACQUISITION_EN
Enable analog data acquisition.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | acquisition_en | RW | '1' to enable analog data acquisition. |
When analog acquisition is enabled, triggers are processed according to the configured trigger mode and samples are collected accordingly.
If analog acquisition is disabled, any ongoing sample collection stops immediately and further triggers are ignored.
### 0x000224: RECORD_LENGTH
Number of samples per trigger minus 1.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 15 : 0 | record_length | RW | Number of samples per trigger minus 1. |
When a trigger condition occurs, the acquisition chain collects (`record_length` + 1) decimated samples.
### 0x000228: DECIMATION_FACTOR
Sample decimation factor minus 1.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 17 : 0 | decimation_factor | RW | Decimation factor minus 1. |
The ADCs sample at a fixed sample rate of 125 MSa/s.
The resulting sample stream is decimated by a factor (`decimation_factor` + 1).
If averaging is enabled, the sum of each group of (`decimation_factor` + 1) ADC samples is collected as a decimated sample.
If averaging is disabled, only the first sample of each group of (`decimation_factor` + 1) ADC samples is collected.
### 0x00022C: SHIFT_STEPS
Number of bit positions to shift accumulated value right.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 3 : 0 | shift_steps | RW | Number of bit positions. |
The accumulated value of each decimated sample is right-shifted by the configured number of bit positions before the value is transferred to DMA.
This is necessary to prevent overflow when a high decimation factor (above 1024) is used in averaging mode.
### 0x000230: AVERAGING_EN
Select averaging or decimation.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | averaging_en | RW | '1' to average samples, '0' to decimate samples. |
### 0x000234: CH4_MODE
Enable 4-channel sampling (only supported on 4-channel devices).
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | ch4_mode | RW | '1' to enable 4-channel sampling. |
When 4-channel sampling is disabled, only channels IN1 and IN2 are active.
One 64-bit word is emitted for each decimated sample, containing the data of these two channels.
When 4-channel sampling is enabled, channels IN3 and IN4 are also active.
Two 64-bit words are emitted for each decimated sample.
The first word contains the data for channels IN1 and IN2.
The second word contains the data for channels IN3 and IN4.
When 4-channel sampling is enabled, the decimation factor **must** be at least 2 (`DECIMATION_FACTOR` at least 1).
### 0x000238: SIMULATE_ADC
Simulate ADC samples.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | simulate_adc | RW | '1' to use simulated ADC samples, '0' to use real ADC samples. |
### 0x000240: TRIGGER_MODE
Trigger configuration.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | trig_auto_en | RW | '1' to enable auto-trigger mode. |
| 1 | trig_ext_en | RW | '1' to enable external triggering. |
| 5 : 4 | trig_ext_select | RW | Select digital input channel to use as external trigger. |
| 7 | trig_ext_falling | RW | '1' to trigger on falling edge, '0' to trigger on rising edge. |
| 8 | trig_force | WC | Write '1' to force a single trigger event. |
Auto-trigger mode takes precedence over external triggering.
If auto-triggering and external triggering are both disabled, no data acquisition takes place unless a trigger is forced by writing to `trig_force`.
### 0x000244: TRIGGER_DELAY
Trigger delay.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 15 : 0 | trigger_delay | RW | Trigger delay in samples (8 ns). |
### 0x000248: TRIGGER_STATUS
Trigger delay.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | trig_waiting | RO | '1' if the acquisition chain is waiting for a trigger. |
### 0x000280: ADC_SAMPLE
Most recent ADC samples from IN1 and IN2.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 13 : 0 | adc0_sample | RO | ADC sample for channel IN1. |
| 29 : 16 | adc1_sample | RO | ADC sample for channel IN2. |
### 0x000284: ADC_SAMPLE
Most recent ADC samples from IN3 and IN4 (only supported on 4-channel devices).
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 13 : 0 | adc2_sample | RO | ADC sample for channel IN3. |
| 29 : 16 | adc3_sample | RO | ADC sample for channel IN4. |
### 0x00028C: ADC_RANGE_CLEAR
Most recent ADC samples from IN3 and IN4 (only supported on 4-channel devices).
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | adc_range_clear | WC | Write '1' to clear min/max ADC sample values. |
### 0x000290: ADC0_MINMAX
Minimum and maximum ADC sample from IN1.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 13 : 0 | adc0_min | RO | Minimum ADC sample from IN1 since range cleared. |
| 29 : 16 | adc0_max | RO | Maximum ADC sample from IN1 since range cleared. |
### 0x000294: ADC1_MINMAX
Minimum and maximum ADC sample from IN2.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 13 : 0 | adc1_min | RO | Minimum ADC sample from IN2 since range cleared. |
| 29 : 16 | adc1_max | RO | Maximum ADC sample from IN2 since range cleared. |
### 0x000298: ADC2_MINMAX
Minimum and maximum ADC sample from IN3 (only supported on 4-channel devices).
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 13 : 0 | adc2_min | RO | Minimum ADC sample from IN3 since range cleared. |
| 29 : 16 | adc2_max | RO | Maximum ADC sample from IN3 since range cleared. |
### 0x00029C: ADC3_MINMAX
Minimum and maximum ADC sample from IN4 (only supported on 4-channel devices).
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 13 : 0 | adc3_min | RO | Minimum ADC sample from IN4 since range cleared. |
| 29 : 16 | adc3_max | RO | Maximum ADC sample from IN4 since range cleared. |
### 0x000300: TT_ADDR_START
Start address of DMA buffer for timetagger.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 7 | | RW | Start address as multiple of 128 bytes. |
The address must be aligned to a 128-byte boundary.
The address is interpreted as an offset relative to `DMA_BUF_ADDR`.
### 0x000304: TT_ADDR_END
End address of DMA buffer for timetagger.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 7 | | RW | End address as multiple of 128 bytes. |
The end address points past the end of the DMA buffer.
When the DMA write pointer reaches `TT_ADDR_END`, it immediately wraps back to `TT_ADDR_START`.
The address must be aligned to a 128-byte boundary.
The address is interpreted as an offset relative to `DMA_BUF_ADDR`.
### 0x000308: TT_ADDR_LIMIT
Pause DMA when write pointer reaches this point.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 7 | | RW | Address as multiple of 128 bytes. |
When the address pointer reaches the limit address, the DMA engine pauses further transfers until software updates the limit.
The address must be aligned to a 128-byte boundary.
The address is interpreted as an offset relative to `DMA_BUF_ADDR`.
### 0x00030C: TT_ADDR_INTR
Raise interrupt when write pointer reaches this point.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 3 | | RW | Address as multiple of 8 bytes. |
When the address pointer reaches this address, an interrupt occurs if analog acquisition interrupts are enabled.
The address must be aligned to an 8-byte boundary.
The address is interpreted as an offset relative to `DMA_BUF_ADDR`.
### 0x000310: TT_ADDR_PTR
Current DMA write pointer.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 3 | | RO | Address as multiple of 8 bytes. |
This register indicates the address where the next write transfer will start.
Write transfers have completed for locations up to (but excluding) this address.
This indicates that software can read valid data up to (but excluding) the pointer address.
The address will be aligned to an 8-byte boundary.
The address is interpreted as an offset relative to `DMA_BUF_ADDR`.
### 0x000314: TT_DMA_CTRL
Control DMA write stream for timetagger.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | tt_dma_en | RW | '1' to enable DMA transfers timetagger. |
| 1 | tt_dma_init | WC | Write '1' to initialize the timetagger DMA stream |
Initializing the DMA stream resets the write pointer to `TT_ADDR_START` and discards pending data from the internal buffer.
Initializing is necessary after setting up the buffer address, and to recover from DMA errors.
### 0x000318: TT_INTR_CTRL
Control DMA interrupts for timetagger.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | tt_intr_en | RW | '1' to enable interrupt for DMA write pointer. |
| 1 | tt_intr_clear | WC | Write '1' to clear a pending interrupt condition. |
### 0x00031C: TT_DMA_STATUS
Status of DMA write stream for timetagger.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | tt_dma_busy | RO | '1' if an uncompleted DMA burst is in progress. |
### 0x000320: TIMETAGGER_EN
Mask of enabled timetagger channels.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | | RW | '1' to enable rising edge events on digital input 0. |
| 1 | | RW | '1' to enable falling edge events on digital input 0. |
| 2 | | RW | '1' to enable rising edge events on digital input 1. |
| 3 | | RW | '1' to enable falling edge events on digital input 1. |
| ... | | RW | ... |
| 7 | | RW | '1' to enable falling edge events on digital input 3. |
### 0x000324: TIMETAGGER_MARK
Emit marker record in timetagger data.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 0 | | WC | Write '1' to emit a marker record in the timetagger data stream. |
### 0x000404: LED_STATE
Control LEDs.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 7 : 4 | | RW | Mask controlling 4 yellow LEDs on the side of the Red Pitaya. |
### 0x100000: DMA_BUF_ADDR
Base address of DMA buffer in RAM.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 12 | | RW | Base address of the DMA buffer in physical RAM. |
This register controls which region of PS RAM may be accessed via DMA.
Typically, the Linux kernel driver must allocate a suitable range of physical memory and initialize these registers accordingly.
The base address must be aligned to a 4 kB boundary.
### 0x100004: DMA_BUF_SIZE
Size of DMA buffer in RAM.
| Bits | Field name | Access | Description |
|---------|---------------|--------|-------------|
| 31 : 12 | | RW | DMA buffer size as number of 4 kB pages. |
# DMA
TODO ...
# Interrupts
The PuzzleFW firmware can send interrupts to the Zynq PS to notify the software of specific conditions.
Interrupts are routed via `IRQ_F2P[0]`, which corresponds to interrupt 61 in the Zynq Generic Interrupt Controller (GIC).
There are two types of conditions that can trigger an interrupt:
* DMA transfers for analog acquisition have progressed to a configurable point.
* DMA transfers for the timetagger have progressed to a configurable point.
Each type of condition has a separate interrupt enable switch, configured via registers `ACQ_INTR_CTRL` and `TT_INTR_CTRL`.
Furthermore, there is a master interrupt enable switch, configured via register `IRQ_ENABLE`.
For example, interrupts may be used to wait for a certain amount of data from the analog acquisition system as follows:
* Write register `ACQ_ADDR_INTR` to specify the amount of progress after which it wants to be notified.
* Write register `ACQ_INTR_CTRL` to clear any pending interrupt and enable interrupts on DMA progress.
* Read register `ACQ_ADDR_PTR` to check whether DMA progress has already passed the configured threshold.
This is necessary to avoid a race condition where software keeps waiting for a condition thas has already happened.
* Write register `IRQ_ENABLE` to enable firmware interrupts.
* Wait for the interrupt or do other stuff in the mean time.
* When the interrupt occurs, the interrupt handler may write register `IRQ_ENABLE` to disable firmware interrupts until the software has time to handle the cause of the interrupt.
* Optionally read register `IRQ_PENDING` to confirm that the interrupt was caused by analog data acquisition.
* Write register `ACQ_INTR_CTRL` to clear the interrupt and disable further interrupts of this type.
* Process the data that arrived in the DMA buffer.
Interrupts can be used to wait for timetagger data in a similar way.