diff options
| author | Karun <[email protected]> | 2024-03-07 12:04:26 -0500 |
|---|---|---|
| committer | Karun <[email protected]> | 2024-03-07 14:41:26 -0500 |
| commit | e163572bec221f3367f96ec720d45bc22b985efe (patch) | |
| tree | 155b0a4b0cb7c88bac152d7745faa2f48927f9d3 /embassy-stm32/src/ospi | |
| parent | b86a1f07009dfac8849cdc1beeb621fea348ccd5 (diff) | |
Add get and set config trait implementations
Diffstat (limited to 'embassy-stm32/src/ospi')
| -rw-r--r-- | embassy-stm32/src/ospi/mod.rs | 107 |
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; | |||
| 8 | use core::ops::Add; | 8 | use core::ops::Add; |
| 9 | use core::ptr; | 9 | use core::ptr; |
| 10 | 10 | ||
| 11 | use embassy_embedded_hal::SetConfig; | 11 | use embassy_embedded_hal::{GetConfig, SetConfig}; |
| 12 | use embassy_futures::join::join; | 12 | use embassy_futures::join::join; |
| 13 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 13 | use 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; | |||
| 23 | use crate::{peripherals, Peripheral}; | 23 | use crate::{peripherals, Peripheral}; |
| 24 | 24 | ||
| 25 | /// OPSI driver config. | 25 | /// OPSI driver config. |
| 26 | #[derive(Clone, Copy)] | ||
| 26 | pub struct Config { | 27 | pub 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 | |||
| 66 | impl Default for Config { | 68 | impl 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 | ||
| 878 | impl<'d, T: Instance, Dma> Drop for Ospi<'d, T, Dma> { | 957 | impl<'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 | ||
| 984 | trait RegsExt { | ||
| 985 | fn dr_ptr<W>(&self) -> *mut W; | ||
| 986 | } | ||
| 987 | |||
| 988 | impl 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 | |||
| 905 | pub(crate) mod sealed { | 995 | pub(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 | |||
| 1030 | impl<'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 | |||
| 1038 | impl<'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 | } | ||
