Remove DMA RegisterAccess::init_channel (#2205)
This commit is contained in:
parent
d971d65c98
commit
f2c473d3bc
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)]
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()));
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)?;
|
||||
|
||||
@ -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(())
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user