43#define DMA_STAGE_CAP (DETWS_DMA_BUF_SIZE * 3)
50 uint8_t buf[DMA_STAGE_CAP];
59 uint16_t space()
const
61 return (uint16_t)(DMA_STAGE_CAP - len);
64 bool push(
const uint8_t *p, uint16_t n)
68 for (uint16_t i = 0; i < n; i++)
70 buf[(head + len) % DMA_STAGE_CAP] = p[i];
76 uint16_t pop(uint8_t *out, uint16_t max)
78 uint16_t n = (len < max) ? len : max;
79 for (uint16_t i = 0; i < n; i++)
82 head = (head + 1) % DMA_STAGE_CAP;
101 det_dma_periph periph;
115void emit(dma_channel &c, uint8_t
id, det_dma_dir dir,
const uint8_t *data, uint16_t len)
123 ev.periph = c.periph;
134void pump(dma_channel &c, uint8_t
id)
139 c.ingress.push(c.tx_buf, c.tx_len);
140 c.egress.push(c.tx_buf, c.tx_len);
141 uint16_t sent = c.tx_len;
144 emit(c,
id, det_dma_dir::DET_DMA_TX,
nullptr, sent);
147 while (c.ingress.len > 0)
150 uint16_t got = c.ingress.pop(c.rx_buf[c.rx_active] + c.rx_fill, room);
161 emit(c,
id, det_dma_dir::DET_DMA_RX, c.rx_buf[c.rx_active], c.rx_fill);
168bool det_dma_open(
const det_dma_config *cfg)
172 dma_channel &c = s_dma.ch[cfg->channel];
177 c.cb = cfg->on_complete;
183 c.periph = cfg->periph;
184 c.loopback = cfg->loopback;
190bool det_dma_tx_submit(uint8_t ch,
const uint8_t *buf, uint16_t len)
194 dma_channel &c = s_dma.ch[ch];
195 if (!c.open || c.tx_busy)
197 memcpy(c.tx_buf, buf, len);
203void det_dma_close(uint8_t ch)
207 s_dma.ch[ch].open =
false;
210void det_dma_poll(
void)
213 if (s_dma.ch[i].open)
214 pump(s_dma.ch[i], i);
217bool det_dma_sim_feed(uint8_t ch,
const uint8_t *bytes, uint16_t len)
221 dma_channel &c = s_dma.ch[ch];
224 return c.ingress.push(bytes, len);
227uint16_t det_dma_sim_capture(uint8_t ch, uint8_t *out, uint16_t max)
231 dma_channel &c = s_dma.ch[ch];
234 return c.egress.pop(out, max);
241 __attribute__((weak))
bool det_dma_hw_open(
const det_dma_config *cfg)
246 __attribute__((weak))
bool det_dma_hw_tx_submit(uint8_t ch,
const uint8_t *buf, uint16_t len)
253 __attribute__((weak))
void det_dma_hw_close(uint8_t ch)
257 __attribute__((weak))
void det_dma_hw_poll(
void)
262bool det_dma_open(
const det_dma_config *cfg)
266 return det_dma_hw_open(cfg);
269bool det_dma_tx_submit(uint8_t ch,
const uint8_t *buf, uint16_t len)
273 return det_dma_hw_tx_submit(ch, buf, len);
276void det_dma_close(uint8_t ch)
279 det_dma_hw_close(ch);
282void det_dma_poll(
void)
#define DETWS_DMA_BUF_SIZE
Bytes per DMA transfer buffer (RX is double-buffered at this size).
#define DETWS_DMA_CHANNELS
Number of DMA channels (static-allocated; each is one peripheral link).
Pluggable monotonic clock for all library timing.
uint32_t detws_millis(void)
The library's monotonic time at 1000 Hz (milliseconds).
DMA peripheral ingest / egress (DETWS_ENABLE_DMA) - the v5 high-throughput hardware-ingest path.