1use crate::pio;
6use kernel::utilities::cells::OptionalCell;
7use kernel::utilities::registers::interfaces::{Readable, Writeable};
8use kernel::utilities::registers::{register_bitfields, register_structs, FieldValue, ReadWrite};
9use kernel::utilities::StaticRef;
10
11register_structs! {
12 pub ChannelRegisters {
13 (0x000 => read_addr: ReadWrite<u32, READ_ADDR::Register>),
14 (0x004 => write_addr: ReadWrite<u32, WRITE_ADDR::Register>),
15 (0x008 => trans_count: ReadWrite<u32, TRANS_COUNT::Register>),
16 (0x00C => ctrl_trig: ReadWrite<u32, CTRL_TRIG::Register>),
17 (0x010 => _reserved0),
18 (0x040 => @END),
19 },
20 pub DmaRegisters {
21 (0x000 => channels: [ChannelRegisters; 12]),
22 (0x300 => _reserved),
23
24 (0x400 => intr: ReadWrite<u32, INTR::Register>),
25 (0x404 => inte0: ReadWrite<u32, INTE::Register>),
26 (0x408 => intf0: ReadWrite<u32, INTF::Register>),
27 (0x40C => ints0: ReadWrite<u32, INTS::Register>),
28 (0x410 => _reserved1),
29 (0x414 => inte1: ReadWrite<u32, INTE::Register>),
30 (0x418 => intf1: ReadWrite<u32, INTF::Register>),
31 (0x41C => ints1: ReadWrite<u32, INTS::Register>),
32 (0x420 => timer0: ReadWrite<u32, TIMER0::Register>),
33 (0x424 => timer1: ReadWrite<u32, TIMER1::Register>),
34 (0x428 => timer2: ReadWrite<u32, TIMER2::Register>),
35 (0x42C => timer3: ReadWrite<u32, TIMER3::Register>),
36 (0x430 => multi_chan_trigger: ReadWrite<u32>),
37 (0x434 => sniff_ctrl: ReadWrite<u32, SNIFF_CTRL::Register>),
38 (0x438 => sniff_data: ReadWrite<u32>),
39 (0x43C => _reserved13),
40
41 (0x440 => fifo_levels: ReadWrite<u32, FIFO_LEVELS::Register>),
42 (0x444 => chan_abort: ReadWrite<u32>),
43 (0x448 => n_channels: ReadWrite<u32>),
44 (0x44C => _reserved14),
45
46 (0x800 => ch0_dbg_ctdreq: ReadWrite<u32>),
47 (0x804 => ch0_dbg_tcr: ReadWrite<u32>),
48 (0x808 => _reserved15),
49
50 (0x840 => ch1_dbg_ctdreq: ReadWrite<u32>),
51 (0x844 => ch1_dbg_tcr: ReadWrite<u32>),
52 (0x848 => _reserved16),
53
54 (0x880 => ch2_dbg_ctdreq: ReadWrite<u32>),
55 (0x884 => ch2_dbg_tcr: ReadWrite<u32>),
56 (0x888 => _reserved17),
57
58 (0x8C0 => ch3_dbg_ctdreq: ReadWrite<u32>),
59 (0x8C4 => ch3_dbg_tcr: ReadWrite<u32>),
60 (0x8C8 => _reserved18),
61
62 (0x900 => ch4_dbg_ctdreq: ReadWrite<u32>),
63 (0x904 => ch4_dbg_tcr: ReadWrite<u32>),
64 (0x908 => _reserved19),
65
66 (0x940 => ch5_dbg_ctdreq: ReadWrite<u32>),
67 (0x944 => ch5_dbg_tcr: ReadWrite<u32>),
68 (0x948 => _reserved20),
69
70 (0x980 => ch6_dbg_ctdreq: ReadWrite<u32>),
71 (0x984 => ch6_dbg_tcr: ReadWrite<u32>),
72 (0x988 => _reserved21),
73
74 (0x9C0 => ch7_dbg_ctdreq: ReadWrite<u32>),
75 (0x9C4 => ch7_dbg_tcr: ReadWrite<u32>),
76 (0x9C8 => _reserved22),
77
78 (0xA00 => ch8_dbg_ctdreq: ReadWrite<u32>),
79 (0xA04 => ch8_dbg_tcr: ReadWrite<u32>),
80 (0xA08 => _reserved23),
81
82 (0xA40 => ch9_dbg_ctdreq: ReadWrite<u32>),
83 (0xA44 => ch9_dbg_tcr: ReadWrite<u32>),
84 (0xA48 => _reserved24),
85
86 (0xA80 => ch10_dbg_ctdreq: ReadWrite<u32>),
87 (0xA84 => ch10_dbg_tcr: ReadWrite<u32>),
88 (0xA88 => _reserved25),
89
90 (0xAC0 => ch11_dbg_ctdreq: ReadWrite<u32>),
91 (0xAC4 => ch11_dbg_tcr: ReadWrite<u32>),
92 (0xAC8 => @END),
93 }
94}
95register_bitfields![u32,
96 READ_ADDR [
97 READ_ADDR OFFSET(0) NUMBITS(32) []
98 ],
99 WRITE_ADDR [
100 WRITE_ADDR OFFSET(0) NUMBITS(32) []
101 ],
102 TRANS_COUNT [
103 TRANS_COUNT OFFSET(0) NUMBITS(32) []
104 ],
105 CTRL_TRIG [
106 AHB_ERROR OFFSET(31) NUMBITS(1) [],
107 READ_ERROR OFFSET(30) NUMBITS(1) [],
108 WRITE_ERROR OFFSET(29) NUMBITS(1) [],
109 BUSY OFFSET(24) NUMBITS(1) [],
110 SNIFF_EN OFFSET(23) NUMBITS(1) [],
111 BSWAP OFFSET(22) NUMBITS(1) [],
112 IRQ_QUIET OFFSET(21) NUMBITS(1) [],
113 TREQ_SEL OFFSET(15) NUMBITS(6) [
114 SelectPIO0STXFIFO0AsTREQ = 0,
116 SelectPIO0STXFIFO1AsTREQ = 1,
118 SelectPIO0STXFIFO2AsTREQ = 2,
120 SelectPIO0STXFIFO3AsTREQ = 3,
122 SelectPIO0SRXFIFO0AsTREQ = 4,
124 SelectPIO0SRXFIFO1AsTREQ = 5,
126 SelectPIO0SRXFIFO2AsTREQ = 6,
128 SelectPIO0SRXFIFO3AsTREQ = 7,
130 SelectPIO1STXFIFO0AsTREQ = 8,
132 SelectPIO1STXFIFO1AsTREQ = 9,
134 SelectPIO1STXFIFO2AsTREQ = 10,
136 SelectPIO1STXFIFO3AsTREQ = 11,
138 SelectPIO1SRXFIFO0AsTREQ = 12,
140 SelectPIO1SRXFIFO1AsTREQ = 13,
142 SelectPIO1SRXFIFO2AsTREQ = 14,
144 SelectPIO1SRXFIFO3AsTREQ = 15,
146 SelectSPI0STXFIFOAsTREQ = 16,
148 SelectSPI0SRXFIFOAsTREQ = 17,
150 SelectSPI1STXFIFOAsTREQ = 18,
152 SelectSPI1SRXFIFOAsTREQ = 19,
154 SelectUART0STXFIFOAsTREQ = 20,
156 SelectUART0SRXFIFOAsTREQ = 21,
158 SelectUART1STXFIFOAsTREQ = 22,
160 SelectUART1SRXFIFOAsTREQ = 23,
162 SelectPWMCounter0SWrapValueAsTREQ = 24,
164 SelectPWMCounter1SWrapValueAsTREQ = 25,
166 SelectPWMCounter2SWrapValueAsTREQ = 26,
168 SelectPWMCounter3SWrapValueAsTREQ = 27,
170 SelectPWMCounter4SWrapValueAsTREQ = 28,
172 SelectPWMCounter5SWrapValueAsTREQ = 29,
174 SelectPWMCounter6SWrapValueAsTREQ = 30,
176 SelectPWMCounter7SWrapValueAsTREQ = 31,
178 SelectI2C0STXFIFOAsTREQ = 32,
180 SelectI2C0SRXFIFOAsTREQ = 33,
182 SelectI2C1STXFIFOAsTREQ = 34,
184 SelectI2C1SRXFIFOAsTREQ = 35,
186 SelectTheADCAsTREQ = 36,
188 SelectTheXIPStreamingFIFOAsTREQ = 37,
190 SelectTheXIPSSITXFIFOAsTREQ = 38,
192 SelectTheXIPSSIRXFIFOAsTREQ = 39,
194 SelectTimer0AsTREQ = 59,
196 SelectTimer1AsTREQ = 60,
198 SelectTimer2AsTREQOptional = 61,
200 SelectTimer3AsTREQOptional = 62,
202 PermanentRequestForUnpacedTransfers = 63
204 ],
205 CHAIN_TO OFFSET(11) NUMBITS(4) [],
207 RING_SEL OFFSET(10) NUMBITS(1) [],
210 RING_SIZE OFFSET(6) NUMBITS(4) [
214 RING_NONE = 0
215 ],
216 INCR_WRITE OFFSET(5) NUMBITS(1) [],
217 INCR_READ OFFSET(4) NUMBITS(1) [],
218 DATA_SIZE OFFSET(2) NUMBITS(2) [
219 SIZE_BYTE = 0b00,
220 SIZE_HALFWORD = 0b01,
221 SIZE_WORD = 0b10
222 ],
223 HIGH_PRIORITY OFFSET(1) NUMBITS(1) [],
224 EN OFFSET(0) NUMBITS(1) []
225 ],
226 INTR [
227 INTR OFFSET(0) NUMBITS(16) []
228 ],
229 INTE [
230 CH11 OFFSET(11) NUMBITS(1) [],
231 CH10 OFFSET(10) NUMBITS(1) [],
232 CH9 OFFSET(9) NUMBITS(1) [],
233 CH8 OFFSET(8) NUMBITS(1) [],
234 CH7 OFFSET(7) NUMBITS(1) [],
235 CH6 OFFSET(6) NUMBITS(1) [],
236 CH5 OFFSET(5) NUMBITS(1) [],
237 CH4 OFFSET(4) NUMBITS(1) [],
238 CH3 OFFSET(3) NUMBITS(1) [],
239 CH2 OFFSET(2) NUMBITS(1) [],
240 CH1 OFFSET(1) NUMBITS(1) [],
241 CH0 OFFSET(0) NUMBITS(1) [],
242 ],
243 INTF [
244 CH11 OFFSET(11) NUMBITS(1) [],
245 CH10 OFFSET(10) NUMBITS(1) [],
246 CH9 OFFSET(9) NUMBITS(1) [],
247 CH8 OFFSET(8) NUMBITS(1) [],
248 CH7 OFFSET(7) NUMBITS(1) [],
249 CH6 OFFSET(6) NUMBITS(1) [],
250 CH5 OFFSET(5) NUMBITS(1) [],
251 CH4 OFFSET(4) NUMBITS(1) [],
252 CH3 OFFSET(3) NUMBITS(1) [],
253 CH2 OFFSET(2) NUMBITS(1) [],
254 CH1 OFFSET(1) NUMBITS(1) [],
255 CH0 OFFSET(0) NUMBITS(1) [],
256 ],
257 INTS [
258 CH11 OFFSET(11) NUMBITS(1) [],
261 CH10 OFFSET(10) NUMBITS(1) [],
262 CH9 OFFSET(9) NUMBITS(1) [],
263 CH8 OFFSET(8) NUMBITS(1) [],
264 CH7 OFFSET(7) NUMBITS(1) [],
265 CH6 OFFSET(6) NUMBITS(1) [],
266 CH5 OFFSET(5) NUMBITS(1) [],
267 CH4 OFFSET(4) NUMBITS(1) [],
268 CH3 OFFSET(3) NUMBITS(1) [],
269 CH2 OFFSET(2) NUMBITS(1) [],
270 CH1 OFFSET(1) NUMBITS(1) [],
271 CH0 OFFSET(0) NUMBITS(1) [],
272 ],
273 TIMER0 [
274 X OFFSET(16) NUMBITS(16) [],
276 Y OFFSET(0) NUMBITS(16) []
278 ],
279 TIMER1 [
280 X OFFSET(16) NUMBITS(16) [],
282 Y OFFSET(0) NUMBITS(16) []
284 ],
285 TIMER2 [
286 X OFFSET(16) NUMBITS(16) [],
287 Y OFFSET(0) NUMBITS(16) []
288 ],
289 TIMER3 [
290 X OFFSET(16) NUMBITS(16) [],
291 Y OFFSET(0) NUMBITS(16) []
292 ],
293 MULTI_CHAN_TRIGGER [
294 MULTI_CHAN_TRIGGER OFFSET(0) NUMBITS(16) []
295 ],
296 SNIFF_CTRL [
297 OUT_INV OFFSET(11) NUMBITS(1) [],
298 OUT_REV OFFSET(10) NUMBITS(1) [],
299 BSWAP OFFSET(9) NUMBITS(1) [],
300
301 CALC OFFSET(5) NUMBITS(4) [
302 CalculateACRC32IEEE8023Polynomial = 0,
304 CalculateACRC32IEEE8023PolynomialWithBitReversedData = 1,
306 CalculateACRC16CCITT = 2,
308 CalculateACRC16CCITTWithBitReversedData = 3,
310 XORReductionOverAllData1IfTheTotal1PopulationCountIsOdd = 14,
312 CalculateASimple32BitChecksumAdditionWithA32BitAccumulator = 15
314 ],
315 DMACH OFFSET(1) NUMBITS(4) [],
317 EN OFFSET(0) NUMBITS(1) []
319 ],
320 SNIFF_DATA [
321 SNIFF_DATA OFFSET(0) NUMBITS(32) []
322 ],
323 FIFO_LEVELS [
324 RAF_LVL OFFSET(16) NUMBITS(8) [],
326 WAF_LVL OFFSET(8) NUMBITS(8) [],
328 TDF_LVL OFFSET(0) NUMBITS(8) []
330 ],
331 CHAN_ABORT [
332 CHAN_ABORT OFFSET(0) NUMBITS(16) []
333 ],
334 N_CHANNELS [
335 N_CHANNELS OFFSET(0) NUMBITS(5) []
336 ],
337 DBG_CTDREQ [
338 DBG_CTDREQ OFFSET(0) NUMBITS(6) []
339 ],
340 DBG_TCR [
341 DBG_TCR OFFSET(0) NUMBITS(32) []
342 ]
343];
344
345const DMA_BASE: StaticRef<DmaRegisters> =
346 unsafe { StaticRef::new(0x50000000 as *const DmaRegisters) };
347
348#[derive(Clone, Copy)]
349pub enum Channel {
350 Channel0 = 0,
351 Channel1 = 1,
352 Channel2 = 2,
353 Channel3 = 3,
354 Channel4 = 4,
355 Channel5 = 5,
356 Channel6 = 6,
357 Channel7 = 7,
358 Channel8 = 8,
359 Channel9 = 9,
360 Channel10 = 10,
361 Channel11 = 11,
362}
363
364pub enum Transfer {
365 PeripheralToMemory,
366 MemoryToPeripheral,
367}
368
369pub enum DataSize {
370 Byte = 0x0,
371 HalfWord = 0x1,
372 Word = 0x2,
373}
374
375impl From<DataSize> for FieldValue<u32, CTRL_TRIG::Register> {
376 fn from(value: DataSize) -> Self {
377 match value {
378 DataSize::Byte => CTRL_TRIG::DATA_SIZE::SIZE_BYTE,
379 DataSize::HalfWord => CTRL_TRIG::DATA_SIZE::SIZE_HALFWORD,
380 DataSize::Word => CTRL_TRIG::DATA_SIZE::SIZE_WORD,
381 }
382 }
383}
384
385pub enum DmaPeripheral {
386 PioRxFifo(pio::PIONumber, pio::SMNumber),
387 PioTxFifo(pio::PIONumber, pio::SMNumber),
388}
389
390impl From<DmaPeripheral> for FieldValue<u32, CTRL_TRIG::Register> {
391 fn from(value: DmaPeripheral) -> Self {
392 match value {
393 DmaPeripheral::PioRxFifo(pio::PIONumber::PIO0, pio::SMNumber::SM0) => {
394 CTRL_TRIG::TREQ_SEL::SelectPIO0SRXFIFO0AsTREQ
395 }
396 DmaPeripheral::PioRxFifo(pio::PIONumber::PIO0, pio::SMNumber::SM1) => {
397 CTRL_TRIG::TREQ_SEL::SelectPIO0SRXFIFO1AsTREQ
398 }
399 DmaPeripheral::PioRxFifo(pio::PIONumber::PIO0, pio::SMNumber::SM2) => {
400 CTRL_TRIG::TREQ_SEL::SelectPIO0SRXFIFO2AsTREQ
401 }
402 DmaPeripheral::PioRxFifo(pio::PIONumber::PIO0, pio::SMNumber::SM3) => {
403 CTRL_TRIG::TREQ_SEL::SelectPIO0SRXFIFO3AsTREQ
404 }
405 DmaPeripheral::PioRxFifo(pio::PIONumber::PIO1, pio::SMNumber::SM0) => {
406 CTRL_TRIG::TREQ_SEL::SelectPIO1SRXFIFO0AsTREQ
407 }
408 DmaPeripheral::PioRxFifo(pio::PIONumber::PIO1, pio::SMNumber::SM1) => {
409 CTRL_TRIG::TREQ_SEL::SelectPIO1SRXFIFO1AsTREQ
410 }
411 DmaPeripheral::PioRxFifo(pio::PIONumber::PIO1, pio::SMNumber::SM2) => {
412 CTRL_TRIG::TREQ_SEL::SelectPIO1SRXFIFO2AsTREQ
413 }
414 DmaPeripheral::PioRxFifo(pio::PIONumber::PIO1, pio::SMNumber::SM3) => {
415 CTRL_TRIG::TREQ_SEL::SelectPIO1SRXFIFO3AsTREQ
416 }
417 DmaPeripheral::PioTxFifo(pio::PIONumber::PIO0, pio::SMNumber::SM0) => {
418 CTRL_TRIG::TREQ_SEL::SelectPIO0STXFIFO0AsTREQ
419 }
420 DmaPeripheral::PioTxFifo(pio::PIONumber::PIO0, pio::SMNumber::SM1) => {
421 CTRL_TRIG::TREQ_SEL::SelectPIO0STXFIFO1AsTREQ
422 }
423 DmaPeripheral::PioTxFifo(pio::PIONumber::PIO0, pio::SMNumber::SM2) => {
424 CTRL_TRIG::TREQ_SEL::SelectPIO0STXFIFO2AsTREQ
425 }
426 DmaPeripheral::PioTxFifo(pio::PIONumber::PIO0, pio::SMNumber::SM3) => {
427 CTRL_TRIG::TREQ_SEL::SelectPIO0STXFIFO3AsTREQ
428 }
429 DmaPeripheral::PioTxFifo(pio::PIONumber::PIO1, pio::SMNumber::SM0) => {
430 CTRL_TRIG::TREQ_SEL::SelectPIO1STXFIFO0AsTREQ
431 }
432 DmaPeripheral::PioTxFifo(pio::PIONumber::PIO1, pio::SMNumber::SM1) => {
433 CTRL_TRIG::TREQ_SEL::SelectPIO1STXFIFO1AsTREQ
434 }
435 DmaPeripheral::PioTxFifo(pio::PIONumber::PIO1, pio::SMNumber::SM2) => {
436 CTRL_TRIG::TREQ_SEL::SelectPIO1STXFIFO2AsTREQ
437 }
438 DmaPeripheral::PioTxFifo(pio::PIONumber::PIO1, pio::SMNumber::SM3) => {
439 CTRL_TRIG::TREQ_SEL::SelectPIO1STXFIFO3AsTREQ
440 }
441 }
442 }
443}
444
445pub enum Irq {
446 Irq0,
447 Irq1,
448}
449
450pub trait DmaChannelClient {
451 fn transfer_done(&self);
452}
453
454#[derive(Clone, Copy)]
455pub struct DmaChannel<'a> {
456 dma: &'a Dma<'a>,
457 ch: Channel,
458}
459
460impl<'a> DmaChannel<'a> {
461 pub const fn new(dma: &'a Dma<'a>, ch: Channel) -> Self {
462 Self { dma, ch }
463 }
464 pub fn set_client(&self, client: &'a dyn DmaChannelClient) {
465 self.dma.set_channel_client(self.ch, client);
466 }
467}
468
469pub struct Dma<'a> {
470 registers: StaticRef<DmaRegisters>,
471 clients: [OptionalCell<&'a dyn DmaChannelClient>; 12],
472}
473
474impl<'a> Dma<'a> {
475 pub const fn new() -> Self {
476 Self {
477 registers: DMA_BASE,
478 clients: [const { OptionalCell::empty() }; 12],
479 }
480 }
481
482 pub fn channel(&'a self, ch: Channel) -> DmaChannel<'a> {
483 DmaChannel::new(self, ch)
484 }
485}
486
487impl<'a> Dma<'a> {
488 pub fn handle_interrupt0(&self) {
489 let value = self.registers.ints0.get();
490 self.registers.ints0.set(value);
491
492 self.handle_channels(value);
493 }
494
495 pub fn handle_interrupt1(&self) {
496 let value = self.registers.ints1.get();
497 self.registers.ints1.set(value);
498
499 self.handle_channels(value);
500 }
501
502 #[inline]
503 fn handle_channels(&self, mut ints: u32) {
504 ints &= 0xfff;
505 while ints != 0 {
506 let channel = ints.trailing_zeros();
507 self.clients[channel as usize].map(|client| client.transfer_done());
508 ints ^= 1 << channel;
509 }
510 }
511
512 fn enable_interrupt(&self, channel: Channel, irq: Irq) {
513 let irq = match irq {
514 Irq::Irq0 => &self.registers.inte0,
515 Irq::Irq1 => &self.registers.inte1,
516 };
517 let mut value = irq.get();
518 value |= 1 << (channel as usize);
519 irq.set(value);
520 }
521
522 fn disable_interrupt(&self, channel: Channel, irq: Irq) {
523 let irq = match irq {
524 Irq::Irq0 => &self.registers.inte0,
525 Irq::Irq1 => &self.registers.inte1,
526 };
527 let mut value = irq.get();
528 value &= !(1 << (channel as usize));
529 irq.set(value);
530 }
531
532 fn channel_registers(&self, channel: Channel) -> &ChannelRegisters {
533 &self.registers.channels[channel as usize]
534 }
535
536 fn set_channel_client(&self, channel: Channel, client: &'a dyn DmaChannelClient) {
537 self.clients[channel as usize].set(client)
538 }
539}
540
541impl DmaChannel<'_> {
542 pub fn trans_count(&self) -> u32 {
543 let regs = &self.dma.channel_registers(self.ch);
544 regs.trans_count.get()
545 }
546
547 pub fn busy(&self) -> bool {
548 let regs = &self.dma.channel_registers(self.ch);
549 match regs.ctrl_trig.read(CTRL_TRIG::BUSY) {
550 0 => false,
551 _ => true,
552 }
553 }
554
555 pub fn set_read_addr(&self, addr: u32) {
556 let regs = &self.dma.channel_registers(self.ch);
557 regs.read_addr.write(READ_ADDR::READ_ADDR.val(addr));
558 }
559
560 pub fn set_write_addr(&self, addr: u32) {
561 let regs = &self.dma.channel_registers(self.ch);
562 regs.write_addr.write(WRITE_ADDR::WRITE_ADDR.val(addr));
563 }
564
565 pub fn set_len(&self, len: u32) {
566 let regs = &self.dma.channel_registers(self.ch);
567 regs.trans_count.write(TRANS_COUNT::TRANS_COUNT.val(len));
568 }
569
570 pub fn enable_interrupt(&self, irq: Irq) {
571 self.dma.enable_interrupt(self.ch, irq);
572 }
573
574 pub fn disable_interrupt(&self, irq: Irq) {
575 self.dma.disable_interrupt(self.ch, irq);
576 }
577
578 pub fn enable(
579 &self,
580 treq: DmaPeripheral,
581 data_size: DataSize,
582 transfer: Transfer,
583 bswap: bool,
584 ) {
585 let regs = &self.dma.channel_registers(self.ch);
586
587 let bswap = match bswap {
588 true => CTRL_TRIG::BSWAP::SET,
589 false => CTRL_TRIG::BSWAP::CLEAR,
590 };
591 let (incr_rd, incr_wr) = match transfer {
592 Transfer::MemoryToPeripheral => {
593 (CTRL_TRIG::INCR_READ::SET, CTRL_TRIG::INCR_WRITE::CLEAR)
594 }
595 Transfer::PeripheralToMemory => {
596 (CTRL_TRIG::INCR_READ::CLEAR, CTRL_TRIG::INCR_WRITE::SET)
597 }
598 };
599 let treq = FieldValue::from(treq);
600 let data_size = FieldValue::from(data_size);
601 let chain_to = CTRL_TRIG::CHAIN_TO.val(self.ch as u32);
602
603 let fv = treq + data_size + bswap + incr_rd + incr_wr + chain_to + CTRL_TRIG::EN::SET;
604 regs.ctrl_trig.write(fv);
605 }
606}