|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
The words the tap's PIO (programmable input/output) program pushes, and the ring a DMA (direct memory access) channel collects them in. More...
Go to the source code of this file.
Data Structures | |
| struct | edge_ring_t |
| Read position of an edge ring. More... | |
Macros | |
| #define | EDGE_COUNT_BITS 31u |
| The counter's bits a word carries. | |
| #define | EDGE_COUNT_MASK 0x7FFFFFFFu |
Functions | |
| uint32_t | edge_word (uint32_t count, bool level) |
The word the program pushes for an edge at counter value count. | |
| uint32_t | edge_word_count (uint32_t word) |
| A word's 31-bit count and level. | |
| bool | edge_word_level (uint32_t word) |
| The word's level after the edge. | |
| uint64_t | edge_tick (uint32_t count, uint64_t est) |
The tick of the counter value count nearest est, with a counter that started at 0 and counts down. | |
| void | edge_ring_init (edge_ring_t *r) |
| Start reading a ring from slot 0, as after the DMA channel restarts. | |
| size_t | edge_ring_take (edge_ring_t *r, const uint32_t *ring, uint32_t size, uint32_t wr, uint64_t est, tone_edge_t *out, size_t max, bool *overrun) |
Take the words in ring ( size words, a power of two) written since the last call, wr being the slot the DMA writes next, as edges stamped against est (the present tick, edge_tick()). | |
The words the tap's PIO (programmable input/output) program pushes, and the ring a DMA (direct memory access) channel collects them in.
Word format. Bits 31 to 1 are the low 31 bits of the state machine's down counter X when the edge was seen; bit 0 is the level after the edge, 1 for a rise. X starts at 0 when the capture starts and counts down once per tick (4 system clocks, 26.7ns at 150MHz), so the ticks elapsed since the start are (0 - count) mod 2^31. The counter wraps every 2^31 ticks, 57.3s.
Extension. A word carries 31 bits of a 64-bit tick count. The rest comes from an estimate of the present tick the caller has from another clock: the word's tick is the one congruent to its count modulo 2^31 nearest the estimate. The estimate has to be within 2^30 ticks (28.6s) of the truth; microseconds are what it is held to. Chaining the differences between words instead would lose a multiple of 57.3s across any silence longer than that.
The ring. The DMA channel writes the words into a ring of a power of two in size, endlessly; the caller reads the channel's write position as a word index. The capture clears the ring before it starts. edge_ring_take() takes the words written since the last call. An overrun, the DMA having lapped the reader, shows as the slot of the last word taken holding another word: counts do not repeat within 57.3s, so a lap always shows. Before the first word is taken that slot is the ring's last one and the word expected is 0, the cleared state; a real word of 0, a fall at tick 0, cannot occur. The reader then discards what is in the ring and starts again after the newest word.
Pure C, no SDK (software development kit). Host-tested in test_edge_ring.
SPDX-License-Identifier: MIT
| void edge_ring_init | ( | edge_ring_t * | r | ) |
Start reading a ring from slot 0, as after the DMA channel restarts.
The ring holds only zero words at that moment, so a lap before the first read shows as a word in its last slot.
| r | Reader state to initialise. |
| size_t edge_ring_take | ( | edge_ring_t * | r, |
| const uint32_t * | ring, | ||
| uint32_t | size, | ||
| uint32_t | wr, | ||
| uint64_t | est, | ||
| tone_edge_t * | out, | ||
| size_t | max, | ||
| bool * | overrun ) |
Take the words in ring ( size words, a power of two) written since the last call, wr being the slot the DMA writes next, as edges stamped against est (the present tick, edge_tick()).
At most max edges go to out; words past that stay in the ring for the next call.
Returns the edges written. *overrun is set when the DMA lapped the reader: nothing is returned, the reader is moved after the newest word, and the caller ends the beep under way (tone_flush()).
| r | Reader state. |
| ring | Ring of edge words. |
| size | Ring size in words, a power of two. |
| wr | Slot the DMA writes next. |
| est | Estimate of the present tick. |
| out | Receives the edges. |
| max | Most edges taken in this call. |
| overrun | Set to true when the DMA lapped the reader; may be NULL. |
out. | uint64_t edge_tick | ( | uint32_t | count, |
| uint64_t | est ) |
The tick of the counter value count nearest est, with a counter that started at 0 and counts down.
Ticks before the start do not exist: the result is at least 0.
| count | Counter value of the edge, 31 bits. |
| est | Estimate of the present tick. |
| uint32_t edge_word | ( | uint32_t | count, |
| bool | level ) |
The word the program pushes for an edge at counter value count.
| count | Counter value at the edge; the low 31 bits are used. |
| level | Level after the edge: true for a rise. |
| uint32_t edge_word_count | ( | uint32_t | word | ) |
A word's 31-bit count and level.
| word | Edge word. |
| bool edge_word_level | ( | uint32_t | word | ) |
The word's level after the edge.
| word | Edge word. |