From b9497d9b82803a50559e6f4914e205fb1b4a258d Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Tue, 16 Nov 2021 21:45:52 +0000 Subject: [PATCH] Resolve review comments. Adds same functions to RX FIFO. --- rp2040-hal/src/dma.rs | 84 +++++++++++++++++++++++++++++++++++++++++++ rp2040-hal/src/lib.rs | 1 + rp2040-hal/src/pio.rs | 84 ++++++++++++++++++------------------------- 3 files changed, 119 insertions(+), 50 deletions(-) create mode 100644 rp2040-hal/src/dma.rs diff --git a/rp2040-hal/src/dma.rs b/rp2040-hal/src/dma.rs new file mode 100644 index 0000000..9d16afa --- /dev/null +++ b/rp2040-hal/src/dma.rs @@ -0,0 +1,84 @@ +//! # DMA +//! +//! This is the start of a DMA driver. + +/// The DREQ value for PIO0's TX FIFO 0 +pub const DREQ_PIO0_TX0: u8 = 0; +/// The DREQ value for PIO0's TX FIFO 1 +pub const DREQ_PIO0_TX1: u8 = 1; +/// The DREQ value for PIO0's TX FIFO 2 +pub const DREQ_PIO0_TX2: u8 = 2; +/// The DREQ value for PIO0's TX FIFO 3 +pub const DREQ_PIO0_TX3: u8 = 3; +/// The DREQ value for PIO0's RX FIFO 0 +pub const DREQ_PIO0_RX0: u8 = 4; +/// The DREQ value for PIO0's RX FIFO 1 +pub const DREQ_PIO0_RX1: u8 = 5; +/// The DREQ value for PIO0's RX FIFO 2 +pub const DREQ_PIO0_RX2: u8 = 6; +/// The DREQ value for PIO0's RX FIFO 3 +pub const DREQ_PIO0_RX3: u8 = 7; +/// The DREQ value for PIO1's TX FIFO 0 +pub const DREQ_PIO1_TX0: u8 = 8; +/// The DREQ value for PIO1's TX FIFO 1 +pub const DREQ_PIO1_TX1: u8 = 9; +/// The DREQ value for PIO1's TX FIFO 2 +pub const DREQ_PIO1_TX2: u8 = 10; +/// The DREQ value for PIO1's TX FIFO 3 +pub const DREQ_PIO1_TX3: u8 = 11; +/// The DREQ value for PIO1's RX FIFO 0 +pub const DREQ_PIO1_RX0: u8 = 12; +/// The DREQ value for PIO1's RX FIFO 1 +pub const DREQ_PIO1_RX1: u8 = 13; +/// The DREQ value for PIO1's RX FIFO 2 +pub const DREQ_PIO1_RX2: u8 = 14; +/// The DREQ value for PIO1's RX FIFO 3 +pub const DREQ_PIO1_RX3: u8 = 15; +/// The DREQ value for SPI0's TX FIFO +pub const DREQ_SPI0_TX: u8 = 16; +/// The DREQ value for SPI0's RX FIFO +pub const DREQ_SPI0_RX: u8 = 17; +/// The DREQ value for SPI1's TX FIFO +pub const DREQ_SPI1_TX: u8 = 18; +/// The DREQ value for SPI1's RX FIFO +pub const DREQ_SPI1_RX: u8 = 19; +/// The DREQ value for UART0's TX FIFO +pub const DREQ_UART0_TX: u8 = 20; +/// The DREQ value for UART0's RX FIFO +pub const DREQ_UART0_RX: u8 = 21; +/// The DREQ value for UART1's TX FIFO +pub const DREQ_UART1_TX: u8 = 22; +/// The DREQ value for UART1's RX FIFO +pub const DREQ_UART1_RX: u8 = 23; +/// The DREQ value for PWM Counter 0's Wrap Value +pub const DREQ_PWM_WRAP0: u8 = 24; +/// The DREQ value for PWM Counter 1's Wrap Value +pub const DREQ_PWM_WRAP1: u8 = 25; +/// The DREQ value for PWM Counter 2's Wrap Value +pub const DREQ_PWM_WRAP2: u8 = 26; +/// The DREQ value for PWM Counter 3's Wrap Value +pub const DREQ_PWM_WRAP3: u8 = 27; +/// The DREQ value for PWM Counter 4's Wrap Value +pub const DREQ_PWM_WRAP4: u8 = 28; +/// The DREQ value for PWM Counter 5's Wrap Value +pub const DREQ_PWM_WRAP5: u8 = 29; +/// The DREQ value for PWM Counter 6's Wrap Value +pub const DREQ_PWM_WRAP6: u8 = 30; +/// The DREQ value for PWM Counter 7's Wrap Value +pub const DREQ_PWM_WRAP7: u8 = 31; +/// The DREQ value for I2C0's TX FIFO +pub const DREQ_I2C0_TX: u8 = 32; +/// The DREQ value for I2C0's RX FIFO +pub const DREQ_I2C0_RX: u8 = 33; +/// The DREQ value for I2C1's TX FIFO +pub const DREQ_I2C1_TX: u8 = 34; +/// The DREQ value for I2C1's RX FIFO +pub const DREQ_I2C1_RX: u8 = 35; +/// The DREQ value for the ADC +pub const DREQ_ADC: u8 = 36; +/// The DREQ value for the XIP Streaming FIFO +pub const DREQ_XIP_STREAM: u8 = 37; +/// The DREQ value for the XIP SSI TX FIFO +pub const DREQ_XIP_SSITX: u8 = 38; +/// The DREQ value for the XIP SSI RX FIFO +pub const DREQ_XIP_SSIRX: u8 = 39; diff --git a/rp2040-hal/src/lib.rs b/rp2040-hal/src/lib.rs index 4cf48c9..00cbe83 100644 --- a/rp2040-hal/src/lib.rs +++ b/rp2040-hal/src/lib.rs @@ -18,6 +18,7 @@ pub extern crate rp2040_pac as pac; pub mod adc; pub(crate) mod atomic_register_access; pub mod clocks; +pub mod dma; pub mod gpio; pub mod i2c; pub mod pio; diff --git a/rp2040-hal/src/pio.rs b/rp2040-hal/src/pio.rs index 09c21ce..aa3f7dd 100644 --- a/rp2040-hal/src/pio.rs +++ b/rp2040-hal/src/pio.rs @@ -711,6 +711,28 @@ impl Rx { unsafe { &*self.block } } + /// Gets the FIFO's address. + /// + /// This is useful if you want to DMA from this peripheral. + /// + /// NB: You are responsible for using the pointer correctly and not + /// underflowing the buffer. + pub fn fifo_address(&self) -> *const u32 { + self.register_block().rxf[SM::id()].as_ptr() + } + + /// Gets the FIFO's `DREQ` value. + /// + /// This is a value between 0 and 39. Each FIFO on each state machine on + /// each PIO has a unique value. + pub fn dreq_value(&self) -> u8 { + if self.block as usize == 0x5020_0000usize { + crate::dma::DREQ_PIO0_RX0 + (SM::id() as u8) + } else { + crate::dma::DREQ_PIO1_RX0 + (SM::id() as u8) + } + } + /// Get the next element from RX FIFO. /// /// Returns `None` if the FIFO is empty. @@ -754,63 +776,25 @@ impl Tx { unsafe { &*self.block } } - /// Gets the FIFO's DMA address - pub fn dma_address(&self) -> u32 { - self.register_block().txf[SM::id()].as_ptr() as usize as u32 + /// Gets the FIFO's address. + /// + /// This is useful if you want to DMA to this peripheral. + /// + /// NB: You are responsible for using the pointer correctly and not + /// overflowing the buffer. + pub fn fifo_address(&self) -> *const u32 { + self.register_block().txf[SM::id()].as_ptr() } /// Gets the FIFO's `DREQ` value. /// - /// This is a value between 0 and 39. Each state machine on each PIO has a - /// unique value. - /// - /// | DREQ | DREQ Channel | - /// |------|-----------------| - /// | 0 | DREQ_PIO0_TX0 | - /// | 1 | DREQ_PIO0_TX1 | - /// | 2 | DREQ_PIO0_TX2 | - /// | 3 | DREQ_PIO0_TX3 | - /// | 4 | DREQ_PIO0_RX0 | - /// | 5 | DREQ_PIO0_RX1 | - /// | 6 | DREQ_PIO0_RX2 | - /// | 7 | DREQ_PIO0_RX3 | - /// | 8 | DREQ_PIO1_TX0 | - /// | 9 | DREQ_PIO1_TX1 | - /// | 10 | DREQ_PIO1_TX2 | - /// | 11 | DREQ_PIO1_TX3 | - /// | 12 | DREQ_PIO1_RX0 | - /// | 13 | DREQ_PIO1_RX1 | - /// | 14 | DREQ_PIO1_RX2 | - /// | 15 | DREQ_PIO1_RX3 | - /// | 16 | DREQ_SPI0_TX | - /// | 17 | DREQ_SPI0_RX | - /// | 18 | DREQ_SPI1_TX | - /// | 19 | DREQ_SPI1_RX | - /// | 20 | DREQ_UART0_TX | - /// | 21 | DREQ_UART0_RX | - /// | 22 | DREQ_UART1_TX | - /// | 23 | DREQ_UART1_RX | - /// | 24 | DREQ_PWM_WRAP0 | - /// | 25 | DREQ_PWM_WRAP1 | - /// | 26 | DREQ_PWM_WRAP2 | - /// | 27 | DREQ_PWM_WRAP3 | - /// | 28 | DREQ_PWM_WRAP4 | - /// | 29 | DREQ_PWM_WRAP5 | - /// | 30 | DREQ_PWM_WRAP6 | - /// | 31 | DREQ_PWM_WRAP7 | - /// | 32 | DREQ_I2C0_TX | - /// | 33 | DREQ_I2C0_RX | - /// | 34 | DREQ_I2C1_TX | - /// | 35 | DREQ_I2C1_RX | - /// | 36 | DREQ_ADC | - /// | 37 | DREQ_XIP_STREAM | - /// | 38 | DREQ_XIP_SSITX | - /// | 39 | DREQ_XIP_SSIRX | + /// This is a value between 0 and 39. Each FIFO on each state machine on + /// each PIO has a unique value. pub fn dreq_value(&self) -> u8 { if self.block as usize == 0x5020_0000usize { - SM::id() as u8 + crate::dma::DREQ_PIO0_TX0 + (SM::id() as u8) } else { - (SM::id() as u8) + 8 + crate::dma::DREQ_PIO1_TX0 + (SM::id() as u8) } }