Add get and set config trait implementations
This commit is contained in:
		
							parent
							
								
									b86a1f0700
								
							
						
					
					
						commit
						e163572bec
					
				@ -8,7 +8,7 @@ pub mod enums;
 | 
				
			|||||||
use core::ops::Add;
 | 
					use core::ops::Add;
 | 
				
			||||||
use core::ptr;
 | 
					use core::ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use embassy_embedded_hal::SetConfig;
 | 
					use embassy_embedded_hal::{GetConfig, SetConfig};
 | 
				
			||||||
use embassy_futures::join::join;
 | 
					use embassy_futures::join::join;
 | 
				
			||||||
use embassy_hal_internal::{into_ref, PeripheralRef};
 | 
					use embassy_hal_internal::{into_ref, PeripheralRef};
 | 
				
			||||||
// use embedded_hal_02::spi;
 | 
					// use embedded_hal_02::spi;
 | 
				
			||||||
@ -23,6 +23,7 @@ use crate::rcc::RccPeripheral;
 | 
				
			|||||||
use crate::{peripherals, Peripheral};
 | 
					use crate::{peripherals, Peripheral};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// OPSI driver config.
 | 
					/// OPSI driver config.
 | 
				
			||||||
 | 
					#[derive(Clone, Copy)]
 | 
				
			||||||
pub struct Config {
 | 
					pub struct Config {
 | 
				
			||||||
    /// Fifo threshold used by the peripheral to generate the interrupt indicating data
 | 
					    /// Fifo threshold used by the peripheral to generate the interrupt indicating data
 | 
				
			||||||
    /// or space is available in the FIFO
 | 
					    /// or space is available in the FIFO
 | 
				
			||||||
@ -63,6 +64,7 @@ pub struct Config {
 | 
				
			|||||||
    /// Enables the refresh feature, chip select is released every refresh + 1 clock cycles
 | 
					    /// Enables the refresh feature, chip select is released every refresh + 1 clock cycles
 | 
				
			||||||
    pub refresh: u32,
 | 
					    pub refresh: u32,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Default for Config {
 | 
					impl Default for Config {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
@ -873,6 +875,83 @@ impl<'d, T: Instance, Dma> Ospi<'d, T, Dma> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Set new bus configuration
 | 
				
			||||||
 | 
					    pub fn set_config(&mut self, config: &Config) -> Result<(), ()> {
 | 
				
			||||||
 | 
					        // Wait for busy flag to clear
 | 
				
			||||||
 | 
					        while T::REGS.sr().read().busy() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Disable DMA channel while configuring the peripheral
 | 
				
			||||||
 | 
					        T::REGS.cr().modify(|w| {
 | 
				
			||||||
 | 
					            w.set_dmaen(false);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Device configuration
 | 
				
			||||||
 | 
					        T::REGS.dcr1().modify(|w| {
 | 
				
			||||||
 | 
					            w.set_devsize(config.device_size.into());
 | 
				
			||||||
 | 
					            w.set_mtyp(config.memory_type);
 | 
				
			||||||
 | 
					            w.set_csht(config.chip_select_high_time.into());
 | 
				
			||||||
 | 
					            w.set_dlybyp(config.delay_block_bypass);
 | 
				
			||||||
 | 
					            w.set_frck(false);
 | 
				
			||||||
 | 
					            w.set_ckmode(config.clock_mode);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        T::REGS.dcr2().modify(|w| {
 | 
				
			||||||
 | 
					            w.set_wrapsize(config.wrap_size.into());
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        T::REGS.dcr3().modify(|w| {
 | 
				
			||||||
 | 
					            w.set_csbound(config.chip_select_boundary);
 | 
				
			||||||
 | 
					            w.set_maxtran(config.max_transfer);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        T::REGS.dcr4().modify(|w| {
 | 
				
			||||||
 | 
					            w.set_refresh(config.refresh);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        T::REGS.cr().modify(|w| {
 | 
				
			||||||
 | 
					            w.set_fthres(vals::Threshold(config.fifo_threshold.into()));
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Wait for busy flag to clear
 | 
				
			||||||
 | 
					        while T::REGS.sr().read().busy() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        T::REGS.dcr2().modify(|w| {
 | 
				
			||||||
 | 
					            w.set_prescaler(config.clock_prescaler);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        T::REGS.cr().modify(|w| {
 | 
				
			||||||
 | 
					            w.set_dmm(config.dual_quad);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        T::REGS.tcr().modify(|w| {
 | 
				
			||||||
 | 
					            w.set_sshift(match config.sample_shifting {
 | 
				
			||||||
 | 
					                true => vals::SampleShift::HALFCYCLE,
 | 
				
			||||||
 | 
					                false => vals::SampleShift::NONE,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            w.set_dhqc(config.delay_hold_quarter_cycle);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Enable peripheral
 | 
				
			||||||
 | 
					        T::REGS.cr().modify(|w| {
 | 
				
			||||||
 | 
					            w.set_en(true);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Free running clock needs to be set after peripheral enable
 | 
				
			||||||
 | 
					        if config.free_running_clock {
 | 
				
			||||||
 | 
					            T::REGS.dcr1().modify(|w| {
 | 
				
			||||||
 | 
					                w.set_frck(config.free_running_clock);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.config = *config;
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Get current configuration
 | 
				
			||||||
 | 
					    pub fn get_config(&self) -> Config {
 | 
				
			||||||
 | 
					        self.config
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Instance, Dma> Drop for Ospi<'d, T, Dma> {
 | 
					impl<'d, T: Instance, Dma> Drop for Ospi<'d, T, Dma> {
 | 
				
			||||||
@ -902,6 +981,17 @@ fn finish_dma(regs: Regs) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					trait RegsExt {
 | 
				
			||||||
 | 
					    fn dr_ptr<W>(&self) -> *mut W;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl RegsExt for Regs {
 | 
				
			||||||
 | 
					    fn dr_ptr<W>(&self) -> *mut W {
 | 
				
			||||||
 | 
					        let dr = self.dr();
 | 
				
			||||||
 | 
					        dr.as_ptr() as *mut W
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) mod sealed {
 | 
					pub(crate) mod sealed {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -936,3 +1026,18 @@ foreach_peripheral!(
 | 
				
			|||||||
        impl Instance for peripherals::$inst {}
 | 
					        impl Instance for peripherals::$inst {}
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'d, T: Instance, Dma> SetConfig for Ospi<'d, T, Dma> {
 | 
				
			||||||
 | 
					    type Config = Config;
 | 
				
			||||||
 | 
					    type ConfigError = ();
 | 
				
			||||||
 | 
					    fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
 | 
				
			||||||
 | 
					        self.set_config(config)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'d, T: Instance, Dma> GetConfig for Ospi<'d, T, Dma> {
 | 
				
			||||||
 | 
					    type Config = Config;
 | 
				
			||||||
 | 
					    fn get_config(&self) -> Self::Config {
 | 
				
			||||||
 | 
					        self.get_config()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user