Remove DMA RegisterAccess::init_channel (#2205)

This commit is contained in:
Dániel Buga 2024-09-23 16:48:20 +02:00 committed by GitHub
parent d971d65c98
commit f2c473d3bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 173 additions and 275 deletions

View File

@ -305,12 +305,10 @@ pub mod dma {
{
fn with_dma(
self,
mut channel: Channel<'d, C, crate::Blocking>,
channel: Channel<'d, C, crate::Blocking>,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> AesDma<'d, C> {
channel.tx.init_channel(); // no need to call this for both, TX and RX
AesDma {
aes: self,
channel,

View File

@ -72,10 +72,6 @@ impl<const N: u8> Channel<N> {
}
impl<const N: u8> RegisterAccess for Channel<N> {
fn init_channel() {
// nothing special to be done here
}
#[cfg(gdma)]
fn set_mem2mem_mode(value: bool) {
Self::ch()
@ -486,15 +482,11 @@ macro_rules! impl_channel {
}
impl ChannelCreator<$num> {
/// Configure the channel for use with blocking APIs
///
/// Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`. I.e., to
/// transfer buffers of size `1..=4092`, you need 1 descriptor.
pub fn configure<'a>(
fn do_configure<'a, M: crate::Mode>(
self,
burst_mode: bool,
priority: DmaPriority,
) -> crate::dma::Channel<'a, [<DmaChannel $num>], crate::Blocking> {
) -> crate::dma::Channel<'a, [<DmaChannel $num>], M> {
let mut tx_impl = ChannelTxImpl {};
tx_impl.init(burst_mode, priority);
@ -508,6 +500,18 @@ macro_rules! impl_channel {
}
}
/// Configure the channel for use with blocking APIs
///
/// Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`. I.e., to
/// transfer buffers of size `1..=4092`, you need 1 descriptor.
pub fn configure<'a>(
self,
burst_mode: bool,
priority: DmaPriority,
) -> crate::dma::Channel<'a, [<DmaChannel $num>], crate::Blocking> {
self.do_configure(burst_mode, priority)
}
/// Configure the channel for use with async APIs
///
/// Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`. I.e., to
@ -517,19 +521,11 @@ macro_rules! impl_channel {
burst_mode: bool,
priority: DmaPriority,
) -> crate::dma::Channel<'a, [<DmaChannel $num>], $crate::Async> {
let mut tx_impl = ChannelTxImpl {};
tx_impl.init(burst_mode, priority);
let mut rx_impl = ChannelRxImpl {};
rx_impl.init(burst_mode, priority);
let this = self.do_configure(burst_mode, priority);
<Channel<$num> as ChannelTypes>::set_isr($async_handler);
crate::dma::Channel {
tx: ChannelTx::new(tx_impl, burst_mode),
rx: ChannelRx::new(rx_impl, burst_mode),
phantom: PhantomData,
}
this
}
}
}
@ -695,7 +691,7 @@ mod m2m {
/// You must ensure that your not using DMA for the same peripheral and
/// that your the only one using the DmaPeripheral.
pub unsafe fn new_unsafe(
mut channel: Channel<'d, C, MODE>,
channel: Channel<'d, C, MODE>,
peripheral: DmaPeripheral,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
@ -707,8 +703,6 @@ mod m2m {
if tx_descriptors.is_empty() || rx_descriptors.is_empty() {
return Err(DmaError::OutOfDescriptors);
}
channel.tx.init_channel();
channel.rx.init_channel();
Ok(Mem2Mem {
channel,
peripheral,

View File

@ -1255,8 +1255,6 @@ pub trait DmaChannel: crate::private::Sealed {
pub trait RxPrivate: crate::private::Sealed {
fn init(&mut self, burst_mode: bool, priority: DmaPriority);
fn init_channel(&mut self);
unsafe fn prepare_transfer_without_start(
&mut self,
peri: DmaPeripheral,
@ -1480,10 +1478,6 @@ where
.contains(DmaRxInterrupt::SuccessfulEof)
}
fn init_channel(&mut self) {
CH::Channel::init_channel();
}
fn clear_interrupts(&self) {
CH::Channel::clear_in_interrupts();
}
@ -1498,8 +1492,6 @@ where
pub trait TxPrivate: crate::private::Sealed {
fn init(&mut self, burst_mode: bool, priority: DmaPriority);
fn init_channel(&mut self);
unsafe fn prepare_transfer_without_start(
&mut self,
peri: DmaPeripheral,
@ -1635,10 +1627,6 @@ where
self.tx_impl.init(burst_mode, priority);
}
fn init_channel(&mut self) {
CH::Channel::init_channel();
}
unsafe fn prepare_transfer_without_start(
&mut self,
peri: DmaPeripheral,
@ -1718,7 +1706,6 @@ where
#[doc(hidden)]
pub trait RegisterAccess: crate::private::Sealed {
fn init_channel();
#[cfg(gdma)]
fn set_mem2mem_mode(value: bool);
#[cfg(esp32s3)]

View File

@ -42,17 +42,6 @@ macro_rules! ImplSpiChannel {
}
impl RegisterAccess for [<Spi $num DmaChannel>] {
fn init_channel() {
// (only) on ESP32 we need to configure DPORT for the SPI DMA channels
#[cfg(esp32)]
{
let dport = unsafe { &*crate::peripherals::DPORT::PTR };
dport
.spi_dma_chan_sel()
.modify(|_, w| unsafe { w.[< spi $num _dma_chan_sel>]().bits($num - 1) });
}
}
fn set_out_burstmode(burst_mode: bool) {
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
spi.dma_conf()
@ -351,15 +340,20 @@ macro_rules! ImplSpiChannel {
pub struct [<Spi $num DmaChannelCreator>] {}
impl [<Spi $num DmaChannelCreator>] {
/// Configure the channel for use with blocking APIs
///
/// Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`. I.e., to
/// transfer buffers of size `1..=4092`, you need 1 descriptor.
pub fn configure<'a>(
fn do_configure<'a, M: $crate::Mode>(
self,
burst_mode: bool,
priority: DmaPriority,
) -> Channel<'a, [<Spi $num DmaChannel>], $crate::Blocking> {
) -> Channel<'a, [<Spi $num DmaChannel>], M> {
#[cfg(esp32)]
{
// (only) on ESP32 we need to configure DPORT for the SPI DMA channels
let dport = unsafe { &*crate::peripherals::DPORT::PTR };
dport
.spi_dma_chan_sel()
.modify(|_, w| unsafe { w.[< spi $num _dma_chan_sel>]().bits($num - 1) });
}
let mut tx_impl = [<Spi $num DmaChannelTxImpl>] {};
tx_impl.init(burst_mode, priority);
@ -373,6 +367,18 @@ macro_rules! ImplSpiChannel {
}
}
/// Configure the channel for use with blocking APIs
///
/// Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`. I.e., to
/// transfer buffers of size `1..=4092`, you need 1 descriptor.
pub fn configure<'a>(
self,
burst_mode: bool,
priority: DmaPriority,
) -> Channel<'a, [<Spi $num DmaChannel>], $crate::Blocking> {
Self::do_configure(self, burst_mode, priority)
}
/// Configure the channel for use with async APIs
///
/// Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`. I.e., to
@ -382,19 +388,11 @@ macro_rules! ImplSpiChannel {
burst_mode: bool,
priority: DmaPriority,
) -> Channel<'a, [<Spi $num DmaChannel>], $crate::Async> {
let mut tx_impl = [<Spi $num DmaChannelTxImpl>] {};
tx_impl.init(burst_mode, priority);
let mut rx_impl = [<Spi $num DmaChannelRxImpl>] {};
rx_impl.init(burst_mode, priority);
let this = Self::do_configure(self, burst_mode, priority);
<[<Spi $num DmaChannel>] as ChannelTypes>::set_isr(super::asynch::interrupt::[< interrupt_handler_spi $num _dma >]);
Channel {
tx: ChannelTx::new(tx_impl, burst_mode),
rx: ChannelRx::new(rx_impl, burst_mode),
phantom: PhantomData,
}
this
}
}
}
@ -425,10 +423,6 @@ macro_rules! ImplI2sChannel {
}
impl RegisterAccess for [<I2s $num DmaChannel>] {
fn init_channel() {
// nothing to do
}
fn set_out_burstmode(burst_mode: bool) {
let reg_block = unsafe { &*crate::peripherals::[<$peripheral>]::PTR };
reg_block.lc_conf()
@ -732,15 +726,11 @@ macro_rules! ImplI2sChannel {
pub struct [<I2s $num DmaChannelCreator>] {}
impl [<I2s $num DmaChannelCreator>] {
/// Configure the channel for use with blocking APIs
///
/// Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`. I.e., to
/// transfer buffers of size `1..=4092`, you need 1 descriptor.
pub fn configure<'a>(
fn do_configure<'a, M: $crate::Mode>(
self,
burst_mode: bool,
priority: DmaPriority,
) -> Channel<'a, [<I2s $num DmaChannel>], $crate::Blocking> {
) -> Channel<'a, [<I2s $num DmaChannel>], M> {
let mut tx_impl = [<I2s $num DmaChannelTxImpl>] {};
tx_impl.init(burst_mode, priority);
@ -754,6 +744,18 @@ macro_rules! ImplI2sChannel {
}
}
/// Configure the channel for use with blocking APIs
///
/// Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`. I.e., to
/// transfer buffers of size `1..=4092`, you need 1 descriptor.
pub fn configure<'a>(
self,
burst_mode: bool,
priority: DmaPriority,
) -> Channel<'a, [<I2s $num DmaChannel>], $crate::Blocking> {
Self::do_configure(self, burst_mode, priority)
}
/// Configure the channel for use with async APIs
///
/// Descriptors should be sized as `(CHUNK_SIZE + 4091) / 4092`. I.e., to
@ -763,19 +765,11 @@ macro_rules! ImplI2sChannel {
burst_mode: bool,
priority: DmaPriority,
) -> Channel<'a, [<I2s $num DmaChannel>], $crate::Async> {
let mut tx_impl = [<I2s $num DmaChannelTxImpl>] {};
tx_impl.init(burst_mode, priority);
let mut rx_impl = [<I2s $num DmaChannelRxImpl>] {};
rx_impl.init(burst_mode, priority);
let this = Self::do_configure(self, burst_mode, priority);
<[<I2s $num DmaChannel>] as ChannelTypes>::set_isr(super::asynch::interrupt::[< interrupt_handler_i2s $num >]);
Channel {
tx: ChannelTx::new(tx_impl, burst_mode),
rx: ChannelRx::new(rx_impl, burst_mode),
phantom: PhantomData,
}
this
}
}
}

View File

@ -345,7 +345,7 @@ where
standard: Standard,
data_format: DataFormat,
sample_rate: impl Into<fugit::HertzU32>,
mut channel: Channel<'d, CH, DmaMode>,
channel: Channel<'d, CH, DmaMode>,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> Self {
@ -353,7 +353,6 @@ where
// could be configured totally independently but for now handle all
// the targets the same and force same configuration for both, TX and RX
channel.tx.init_channel();
PeripheralClockControl::reset(I::get_peripheral());
PeripheralClockControl::enable(I::get_peripheral());
I::set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits()));

View File

@ -141,7 +141,7 @@ where
/// Creates a new `Camera` instance with DMA support.
pub fn new<P: RxPins>(
cam: Cam<'d>,
mut channel: ChannelRx<'d, CH>,
channel: ChannelRx<'d, CH>,
descriptors: &'static mut [DmaDescriptor],
_pins: P,
frequency: HertzU32,
@ -161,43 +161,26 @@ where
lcd_cam.cam_ctrl().write(|w| {
// Force enable the clock for all configuration registers.
unsafe {
w.cam_clk_sel()
.bits((i + 1) as _)
.cam_clkm_div_num()
.bits(divider.div_num as _)
.cam_clkm_div_b()
.bits(divider.div_b as _)
.cam_clkm_div_a()
.bits(divider.div_a as _)
.cam_vsync_filter_thres()
.bits(0)
.cam_vs_eof_en()
.set_bit()
.cam_line_int_en()
.clear_bit()
.cam_stop_en()
.clear_bit()
w.cam_clk_sel().bits((i + 1) as _);
w.cam_clkm_div_num().bits(divider.div_num as _);
w.cam_clkm_div_b().bits(divider.div_b as _);
w.cam_clkm_div_a().bits(divider.div_a as _);
w.cam_vsync_filter_thres().bits(0);
w.cam_vs_eof_en().set_bit();
w.cam_line_int_en().clear_bit();
w.cam_stop_en().clear_bit()
}
});
lcd_cam.cam_ctrl1().write(|w| unsafe {
w.cam_vh_de_mode_en()
.set_bit()
.cam_rec_data_bytelen()
.bits(0)
.cam_line_int_num()
.bits(0)
.cam_vsync_filter_en()
.clear_bit()
.cam_2byte_en()
.clear_bit()
.cam_clk_inv()
.clear_bit()
.cam_de_inv()
.clear_bit()
.cam_hsync_inv()
.clear_bit()
.cam_vsync_inv()
.clear_bit()
w.cam_vh_de_mode_en().set_bit();
w.cam_rec_data_bytelen().bits(0);
w.cam_line_int_num().bits(0);
w.cam_vsync_filter_en().clear_bit();
w.cam_2byte_en().clear_bit();
w.cam_clk_inv().clear_bit();
w.cam_de_inv().clear_bit();
w.cam_hsync_inv().clear_bit();
w.cam_vsync_inv().clear_bit()
});
lcd_cam
@ -206,8 +189,6 @@ where
lcd_cam.cam_ctrl().modify(|_, w| w.cam_update().set_bit());
channel.init_channel();
Self {
lcd_cam,
rx_channel: channel,

View File

@ -105,7 +105,7 @@ where
/// Creates a new instance of the I8080 LCD interface.
pub fn new<P: TxPins>(
lcd: Lcd<'d, DM>,
mut channel: ChannelTx<'d, CH>,
channel: ChannelTx<'d, CH>,
descriptors: &'static mut [DmaDescriptor],
mut pins: P,
frequency: HertzU32,
@ -128,24 +128,16 @@ where
lcd_cam.lcd_clock().write(|w| unsafe {
// Force enable the clock for all configuration registers.
w.clk_en()
.set_bit()
.lcd_clk_sel()
.bits((i + 1) as _)
.lcd_clkm_div_num()
.bits(divider.div_num as _)
.lcd_clkm_div_b()
.bits(divider.div_b as _)
.lcd_clkm_div_a()
.bits(divider.div_a as _)
// LCD_PCLK = LCD_CLK / 2
.lcd_clk_equ_sysclk()
.clear_bit()
.lcd_clkcnt_n()
.bits(2 - 1) // Must not be 0.
.lcd_ck_idle_edge()
.bit(config.clock_mode.polarity == Polarity::IdleHigh)
.lcd_ck_out_edge()
w.clk_en().set_bit();
w.lcd_clk_sel().bits((i + 1) as _);
w.lcd_clkm_div_num().bits(divider.div_num as _);
w.lcd_clkm_div_b().bits(divider.div_b as _);
w.lcd_clkm_div_a().bits(divider.div_a as _); // LCD_PCLK = LCD_CLK / 2
w.lcd_clk_equ_sysclk().clear_bit();
w.lcd_clkcnt_n().bits(2 - 1); // Must not be 0.
w.lcd_ck_idle_edge()
.bit(config.clock_mode.polarity == Polarity::IdleHigh);
w.lcd_ck_out_edge()
.bit(config.clock_mode.phase == Phase::ShiftHigh)
});
@ -157,91 +149,66 @@ where
.write(|w| w.lcd_conv_bypass().clear_bit());
lcd_cam.lcd_user().modify(|_, w| {
w.lcd_8bits_order()
.bit(false)
.lcd_bit_order()
.bit(false)
.lcd_byte_order()
.bit(false)
.lcd_2byte_en()
.bit(false)
w.lcd_8bits_order().bit(false);
w.lcd_bit_order().bit(false);
w.lcd_byte_order().bit(false);
w.lcd_2byte_en().bit(false)
});
lcd_cam.lcd_misc().write(|w| unsafe {
// Set the threshold for Async Tx FIFO full event. (5 bits)
w.lcd_afifo_threshold_num()
.bits(0)
// Configure the setup cycles in LCD non-RGB mode. Setup cycles
// expected = this value + 1. (6 bit)
.lcd_vfk_cyclelen()
.bits(config.setup_cycles.saturating_sub(1) as _)
// Configure the hold time cycles in LCD non-RGB mode. Hold
// cycles expected = this value + 1.
.lcd_vbk_cyclelen()
.bits(config.hold_cycles.saturating_sub(1) as _)
// 1: Send the next frame data when the current frame is sent out.
// 0: LCD stops when the current frame is sent out.
.lcd_next_frame_en()
.clear_bit()
// Enable blank region when LCD sends data out.
.lcd_bk_en()
.set_bit()
// 1: LCD_CD = !LCD_CAM_LCD_CD_IDLE_EDGE when LCD is in DOUT phase.
// 0: LCD_CD = LCD_CAM_LCD_CD_IDLE_EDGE.
.lcd_cd_data_set()
.bit(config.cd_data_edge != config.cd_idle_edge)
// 1: LCD_CD = !LCD_CAM_LCD_CD_IDLE_EDGE when LCD is in DUMMY phase.
// 0: LCD_CD = LCD_CAM_LCD_CD_IDLE_EDGE.
.lcd_cd_dummy_set()
.bit(config.cd_dummy_edge != config.cd_idle_edge)
// 1: LCD_CD = !LCD_CAM_LCD_CD_IDLE_EDGE when LCD is in CMD phase.
// 0: LCD_CD = LCD_CAM_LCD_CD_IDLE_EDGE.
.lcd_cd_cmd_set()
.bit(config.cd_cmd_edge != config.cd_idle_edge)
// The default value of LCD_CD
.lcd_cd_idle_edge()
.bit(config.cd_idle_edge)
w.lcd_afifo_threshold_num().bits(0);
// Configure the setup cycles in LCD non-RGB mode. Setup cycles
// expected = this value + 1. (6 bit)
w.lcd_vfk_cyclelen()
.bits(config.setup_cycles.saturating_sub(1) as _);
// Configure the hold time cycles in LCD non-RGB mode. Hold
// cycles expected = this value + 1.
w.lcd_vbk_cyclelen()
.bits(config.hold_cycles.saturating_sub(1) as _);
// 1: Send the next frame data when the current frame is sent out.
// 0: LCD stops when the current frame is sent out.
w.lcd_next_frame_en().clear_bit();
// Enable blank region when LCD sends data out.
w.lcd_bk_en().set_bit();
// 1: LCD_CD = !LCD_CAM_LCD_CD_IDLE_EDGE when LCD is in DOUT phase.
// 0: LCD_CD = LCD_CAM_LCD_CD_IDLE_EDGE.
w.lcd_cd_data_set()
.bit(config.cd_data_edge != config.cd_idle_edge);
// 1: LCD_CD = !LCD_CAM_LCD_CD_IDLE_EDGE when LCD is in DUMMY phase.
// 0: LCD_CD = LCD_CAM_LCD_CD_IDLE_EDGE.
w.lcd_cd_dummy_set()
.bit(config.cd_dummy_edge != config.cd_idle_edge);
// 1: LCD_CD = !LCD_CAM_LCD_CD_IDLE_EDGE when LCD is in CMD phase.
// 0: LCD_CD = LCD_CAM_LCD_CD_IDLE_EDGE.
w.lcd_cd_cmd_set()
.bit(config.cd_cmd_edge != config.cd_idle_edge);
// The default value of LCD_CD
w.lcd_cd_idle_edge().bit(config.cd_idle_edge)
});
lcd_cam
.lcd_dly_mode()
.write(|w| unsafe { w.lcd_cd_mode().bits(config.cd_mode as u8) });
lcd_cam.lcd_data_dout_mode().write(|w| unsafe {
w.dout0_mode()
.bits(config.output_bit_mode as u8)
.dout1_mode()
.bits(config.output_bit_mode as u8)
.dout2_mode()
.bits(config.output_bit_mode as u8)
.dout3_mode()
.bits(config.output_bit_mode as u8)
.dout4_mode()
.bits(config.output_bit_mode as u8)
.dout5_mode()
.bits(config.output_bit_mode as u8)
.dout6_mode()
.bits(config.output_bit_mode as u8)
.dout7_mode()
.bits(config.output_bit_mode as u8)
.dout8_mode()
.bits(config.output_bit_mode as u8)
.dout9_mode()
.bits(config.output_bit_mode as u8)
.dout10_mode()
.bits(config.output_bit_mode as u8)
.dout11_mode()
.bits(config.output_bit_mode as u8)
.dout12_mode()
.bits(config.output_bit_mode as u8)
.dout13_mode()
.bits(config.output_bit_mode as u8)
.dout14_mode()
.bits(config.output_bit_mode as u8)
.dout15_mode()
.bits(config.output_bit_mode as u8)
w.dout0_mode().bits(config.output_bit_mode as u8);
w.dout1_mode().bits(config.output_bit_mode as u8);
w.dout2_mode().bits(config.output_bit_mode as u8);
w.dout3_mode().bits(config.output_bit_mode as u8);
w.dout4_mode().bits(config.output_bit_mode as u8);
w.dout5_mode().bits(config.output_bit_mode as u8);
w.dout6_mode().bits(config.output_bit_mode as u8);
w.dout7_mode().bits(config.output_bit_mode as u8);
w.dout8_mode().bits(config.output_bit_mode as u8);
w.dout9_mode().bits(config.output_bit_mode as u8);
w.dout10_mode().bits(config.output_bit_mode as u8);
w.dout11_mode().bits(config.output_bit_mode as u8);
w.dout12_mode().bits(config.output_bit_mode as u8);
w.dout13_mode().bits(config.output_bit_mode as u8);
w.dout14_mode().bits(config.output_bit_mode as u8);
w.dout15_mode().bits(config.output_bit_mode as u8)
});
lcd_cam.lcd_user().modify(|_, w| w.lcd_update().set_bit());
channel.init_channel();
pins.configure();
Self {
@ -283,10 +250,8 @@ impl<'d, CH: DmaChannel, DM: Mode> I8080<'d, CH, DM> {
pub fn set_byte_order(&mut self, byte_order: ByteOrder) -> &mut Self {
let is_inverted = byte_order != ByteOrder::default();
self.lcd_cam.lcd_user().modify(|_, w| {
w.lcd_byte_order()
.bit(is_inverted)
.lcd_8bits_order()
.bit(is_inverted)
w.lcd_byte_order().bit(is_inverted);
w.lcd_8bits_order().bit(is_inverted)
});
self
}
@ -432,17 +397,19 @@ impl<'d, CH: DmaChannel, DM: Mode> I8080<'d, CH, DM> {
.modify(|_, w| w.lcd_cmd().clear_bit());
}
Command::One(value) => {
self.lcd_cam
.lcd_user()
.modify(|_, w| w.lcd_cmd().set_bit().lcd_cmd_2_cycle_en().clear_bit());
self.lcd_cam.lcd_user().modify(|_, w| {
w.lcd_cmd().set_bit();
w.lcd_cmd_2_cycle_en().clear_bit()
});
self.lcd_cam
.lcd_cmd_val()
.write(|w| unsafe { w.lcd_cmd_value().bits(value.into() as _) });
}
Command::Two(first, second) => {
self.lcd_cam
.lcd_user()
.modify(|_, w| w.lcd_cmd().set_bit().lcd_cmd_2_cycle_en().set_bit());
self.lcd_cam.lcd_user().modify(|_, w| {
w.lcd_cmd().set_bit();
w.lcd_cmd_2_cycle_en().set_bit()
});
let cmd = first.into() as u32 | (second.into() as u32) << 16;
self.lcd_cam
.lcd_cmd_val()
@ -479,9 +446,10 @@ impl<'d, CH: DmaChannel, DM: Mode> I8080<'d, CH, DM> {
// Otherwise, some garbage data will be sent out
crate::rom::ets_delay_us(1);
self.lcd_cam
.lcd_user()
.modify(|_, w| w.lcd_update().set_bit().lcd_start().set_bit());
self.lcd_cam.lcd_user().modify(|_, w| {
w.lcd_update().set_bit();
w.lcd_start().set_bit()
});
}
fn tear_down_send(&mut self) {
@ -508,9 +476,10 @@ impl<'d, CH: DmaChannel, DM: Mode> I8080<'d, CH, DM> {
// > i. LCD_CAM_LCD_START is cleared;
// > ii. or LCD_CAM_LCD_RESET is set;
// > iii. or all the data in GDMA is sent out.
self.lcd_cam
.lcd_user()
.modify(|_, w| w.lcd_always_out_en().set_bit().lcd_dout().set_bit());
self.lcd_cam.lcd_user().modify(|_, w| {
w.lcd_always_out_en().set_bit();
w.lcd_dout().set_bit()
});
unsafe {
self.tx_chain.fill_for_tx(false, ptr, len)?;

View File

@ -1121,12 +1121,12 @@ where
/// Create a new instance of [ParlIoFullDuplex]
pub fn new(
_parl_io: impl Peripheral<P = peripherals::PARL_IO> + 'd,
mut dma_channel: Channel<'d, CH, DM>,
dma_channel: Channel<'d, CH, DM>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
frequency: HertzU32,
) -> Result<Self, Error> {
internal_init(&mut dma_channel, frequency)?;
internal_init(frequency)?;
Ok(Self {
tx: TxCreatorFullDuplex {
@ -1215,11 +1215,11 @@ where
/// Create a new [ParlIoTxOnly]
pub fn new(
_parl_io: impl Peripheral<P = peripherals::PARL_IO> + 'd,
mut dma_channel: Channel<'d, CH, DM>,
dma_channel: Channel<'d, CH, DM>,
descriptors: &'static mut [DmaDescriptor],
frequency: HertzU32,
) -> Result<Self, Error> {
internal_init(&mut dma_channel, frequency)?;
internal_init(frequency)?;
Ok(Self {
tx: TxCreator {
@ -1303,11 +1303,11 @@ where
/// Create a new [ParlIoRxOnly] instance
pub fn new(
_parl_io: impl Peripheral<P = peripherals::PARL_IO> + 'd,
mut dma_channel: Channel<'d, CH, DM>,
dma_channel: Channel<'d, CH, DM>,
descriptors: &'static mut [DmaDescriptor],
frequency: HertzU32,
) -> Result<Self, Error> {
internal_init(&mut dma_channel, frequency)?;
internal_init(frequency)?;
Ok(Self {
rx: RxCreator {
@ -1370,15 +1370,7 @@ where
}
}
fn internal_init<CH, DM>(
dma_channel: &mut Channel<'_, CH, DM>,
frequency: HertzU32,
) -> Result<(), Error>
where
CH: DmaChannel,
CH::P: ParlIoPeripheral,
DM: Mode,
{
fn internal_init(frequency: HertzU32) -> Result<(), Error> {
if frequency.raw() > 40_000_000 {
return Err(Error::UnreachableClockRate);
}
@ -1395,27 +1387,19 @@ where
let divider = divider as u16;
pcr.parl_clk_tx_conf().modify(|_, w| unsafe {
w.parl_clk_tx_en()
.set_bit()
.parl_clk_tx_sel()
.bits(1) // PLL
.parl_clk_tx_div_num()
.bits(divider)
w.parl_clk_tx_en().set_bit();
w.parl_clk_tx_sel().bits(1); // PLL
w.parl_clk_tx_div_num().bits(divider)
});
pcr.parl_clk_rx_conf().modify(|_, w| unsafe {
w.parl_clk_rx_en()
.set_bit()
.parl_clk_rx_sel()
.bits(1) // PLL
.parl_clk_rx_div_num()
.bits(divider)
w.parl_clk_rx_en().set_bit();
w.parl_clk_rx_sel().bits(1); // PLL
w.parl_clk_rx_div_num().bits(divider)
});
Instance::set_rx_sw_en(true);
Instance::set_rx_sample_mode(SampleMode::InternalSoftwareEnable);
dma_channel.tx.init_channel();
dma_channel.rx.init_channel();
Ok(())
}

View File

@ -113,7 +113,7 @@ pub unsafe extern "C" fn ESP32Reset() -> ! {
}
// continue with default reset handler
xtensa_lx_rt::Reset();
xtensa_lx_rt::Reset()
}
/// The ESP32 has a first stage bootloader that handles loading program data

View File

@ -901,15 +901,13 @@ mod dma {
/// instance of `SpiDma` that supports DMA operations.
pub fn with_dma<C, DmaMode>(
self,
mut channel: Channel<'d, C, DmaMode>,
channel: Channel<'d, C, DmaMode>,
) -> SpiDma<'d, crate::peripherals::SPI2, C, M, DmaMode>
where
C: DmaChannel,
C::P: SpiPeripheral + Spi2Peripheral,
DmaMode: Mode,
{
channel.tx.init_channel(); // no need to call this for both, RX and TX
SpiDma {
spi: self.spi,
channel,
@ -930,15 +928,13 @@ mod dma {
/// operations.
pub fn with_dma<C, DmaMode>(
self,
mut channel: Channel<'d, C, DmaMode>,
channel: Channel<'d, C, DmaMode>,
) -> SpiDma<'d, crate::peripherals::SPI3, C, M, DmaMode>
where
C: DmaChannel,
C::P: SpiPeripheral + Spi3Peripheral,
DmaMode: Mode,
{
channel.tx.init_channel(); // no need to call this for both, RX and TX
SpiDma {
spi: self.spi,
channel,

View File

@ -225,12 +225,10 @@ pub mod dma {
{
fn with_dma(
self,
mut channel: Channel<'d, C, DmaMode>,
channel: Channel<'d, C, DmaMode>,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, crate::peripherals::SPI2, C, DmaMode> {
channel.tx.init_channel(); // no need to call this for both, TX and RX
SpiDma {
spi: self.spi,
channel,
@ -250,12 +248,10 @@ pub mod dma {
{
fn with_dma(
self,
mut channel: Channel<'d, C, DmaMode>,
channel: Channel<'d, C, DmaMode>,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, crate::peripherals::SPI3, C, DmaMode> {
channel.tx.init_channel(); // no need to call this for both, TX and RX
SpiDma {
spi: self.spi,
channel,