aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/ospi
diff options
context:
space:
mode:
authorKarun <[email protected]>2024-03-07 12:04:26 -0500
committerKarun <[email protected]>2024-03-07 14:41:26 -0500
commite163572bec221f3367f96ec720d45bc22b985efe (patch)
tree155b0a4b0cb7c88bac152d7745faa2f48927f9d3 /embassy-stm32/src/ospi
parentb86a1f07009dfac8849cdc1beeb621fea348ccd5 (diff)
Add get and set config trait implementations
Diffstat (limited to 'embassy-stm32/src/ospi')
-rw-r--r--embassy-stm32/src/ospi/mod.rs107
1 files changed, 106 insertions, 1 deletions
diff --git a/embassy-stm32/src/ospi/mod.rs b/embassy-stm32/src/ospi/mod.rs
index 48b1ef789..8fb5f06e4 100644
--- a/embassy-stm32/src/ospi/mod.rs
+++ b/embassy-stm32/src/ospi/mod.rs
@@ -8,7 +8,7 @@ pub mod enums;
8use core::ops::Add; 8use core::ops::Add;
9use core::ptr; 9use core::ptr;
10 10
11use embassy_embedded_hal::SetConfig; 11use embassy_embedded_hal::{GetConfig, SetConfig};
12use embassy_futures::join::join; 12use embassy_futures::join::join;
13use embassy_hal_internal::{into_ref, PeripheralRef}; 13use embassy_hal_internal::{into_ref, PeripheralRef};
14// use embedded_hal_02::spi; 14// use embedded_hal_02::spi;
@@ -23,6 +23,7 @@ use crate::rcc::RccPeripheral;
23use crate::{peripherals, Peripheral}; 23use crate::{peripherals, Peripheral};
24 24
25/// OPSI driver config. 25/// OPSI driver config.
26#[derive(Clone, Copy)]
26pub struct Config { 27pub struct Config {
27 /// Fifo threshold used by the peripheral to generate the interrupt indicating data 28 /// Fifo threshold used by the peripheral to generate the interrupt indicating data
28 /// or space is available in the FIFO 29 /// or space is available in the FIFO
@@ -63,6 +64,7 @@ pub struct Config {
63 /// Enables the refresh feature, chip select is released every refresh + 1 clock cycles 64 /// Enables the refresh feature, chip select is released every refresh + 1 clock cycles
64 pub refresh: u32, 65 pub refresh: u32,
65} 66}
67
66impl Default for Config { 68impl Default for Config {
67 fn default() -> Self { 69 fn default() -> Self {
68 Self { 70 Self {
@@ -873,6 +875,83 @@ impl<'d, T: Instance, Dma> Ospi<'d, T, Dma> {
873 875
874 Ok(()) 876 Ok(())
875 } 877 }
878
879 /// Set new bus configuration
880 pub fn set_config(&mut self, config: &Config) -> Result<(), ()> {
881 // Wait for busy flag to clear
882 while T::REGS.sr().read().busy() {}
883
884 // Disable DMA channel while configuring the peripheral
885 T::REGS.cr().modify(|w| {
886 w.set_dmaen(false);
887 });
888
889 // Device configuration
890 T::REGS.dcr1().modify(|w| {
891 w.set_devsize(config.device_size.into());
892 w.set_mtyp(config.memory_type);
893 w.set_csht(config.chip_select_high_time.into());
894 w.set_dlybyp(config.delay_block_bypass);
895 w.set_frck(false);
896 w.set_ckmode(config.clock_mode);
897 });
898
899 T::REGS.dcr2().modify(|w| {
900 w.set_wrapsize(config.wrap_size.into());
901 });
902
903 T::REGS.dcr3().modify(|w| {
904 w.set_csbound(config.chip_select_boundary);
905 w.set_maxtran(config.max_transfer);
906 });
907
908 T::REGS.dcr4().modify(|w| {
909 w.set_refresh(config.refresh);
910 });
911
912 T::REGS.cr().modify(|w| {
913 w.set_fthres(vals::Threshold(config.fifo_threshold.into()));
914 });
915
916 // Wait for busy flag to clear
917 while T::REGS.sr().read().busy() {}
918
919 T::REGS.dcr2().modify(|w| {
920 w.set_prescaler(config.clock_prescaler);
921 });
922
923 T::REGS.cr().modify(|w| {
924 w.set_dmm(config.dual_quad);
925 });
926
927 T::REGS.tcr().modify(|w| {
928 w.set_sshift(match config.sample_shifting {
929 true => vals::SampleShift::HALFCYCLE,
930 false => vals::SampleShift::NONE,
931 });
932 w.set_dhqc(config.delay_hold_quarter_cycle);
933 });
934
935 // Enable peripheral
936 T::REGS.cr().modify(|w| {
937 w.set_en(true);
938 });
939
940 // Free running clock needs to be set after peripheral enable
941 if config.free_running_clock {
942 T::REGS.dcr1().modify(|w| {
943 w.set_frck(config.free_running_clock);
944 });
945 }
946
947 self.config = *config;
948 Ok(())
949 }
950
951 /// Get current configuration
952 pub fn get_config(&self) -> Config {
953 self.config
954 }
876} 955}
877 956
878impl<'d, T: Instance, Dma> Drop for Ospi<'d, T, Dma> { 957impl<'d, T: Instance, Dma> Drop for Ospi<'d, T, Dma> {
@@ -902,6 +981,17 @@ fn finish_dma(regs: Regs) {
902 }); 981 });
903} 982}
904 983
984trait RegsExt {
985 fn dr_ptr<W>(&self) -> *mut W;
986}
987
988impl RegsExt for Regs {
989 fn dr_ptr<W>(&self) -> *mut W {
990 let dr = self.dr();
991 dr.as_ptr() as *mut W
992 }
993}
994
905pub(crate) mod sealed { 995pub(crate) mod sealed {
906 use super::*; 996 use super::*;
907 997
@@ -936,3 +1026,18 @@ foreach_peripheral!(
936 impl Instance for peripherals::$inst {} 1026 impl Instance for peripherals::$inst {}
937 }; 1027 };
938); 1028);
1029
1030impl<'d, T: Instance, Dma> SetConfig for Ospi<'d, T, Dma> {
1031 type Config = Config;
1032 type ConfigError = ();
1033 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
1034 self.set_config(config)
1035 }
1036}
1037
1038impl<'d, T: Instance, Dma> GetConfig for Ospi<'d, T, Dma> {
1039 type Config = Config;
1040 fn get_config(&self) -> Self::Config {
1041 self.get_config()
1042 }
1043}