Start documenting firmware
This commit is contained in:
parent
5b21d0fb26
commit
b07f6cabb6
|
@ -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.
|
Loading…
Reference in New Issue