Auto generate SPI v2 clock enable
Adds RccPeripheral trait for peripherals implementing clock enable and reset for a given peripheral. Add macro table generting implementations of RccPeripheral for peripherals with clock set, currently restricted to SPI.
This commit is contained in:
		
							parent
							
								
									af0f8082f0
								
							
						
					
					
						commit
						ee3b82b743
					
				| @ -51,3 +51,5 @@ crate::pac::peripheral_pins!( | ||||
|         } | ||||
|     }; | ||||
| ); | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,3 +1,6 @@ | ||||
| #![macro_use] | ||||
| 
 | ||||
| use crate::peripherals; | ||||
| use crate::time::Hertz; | ||||
| use core::mem::MaybeUninit; | ||||
| 
 | ||||
| @ -44,3 +47,38 @@ cfg_if::cfg_if! { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub(crate) mod sealed { | ||||
|     pub trait RccPeripheral { | ||||
|         fn reset(); | ||||
|         fn enable(); | ||||
|         fn disable(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub trait RccPeripheral: sealed::RccPeripheral + 'static {} | ||||
| 
 | ||||
| crate::pac::peripheral_rcc!( | ||||
|     ($inst:ident, $enable:ident, $reset:ident, $perien:ident, $perirst:ident) => { | ||||
|         impl sealed::RccPeripheral for peripherals::$inst { | ||||
|             fn enable() { | ||||
|                 unsafe { | ||||
|                     crate::pac::RCC.$enable().modify(|w| w.$perien(true)); | ||||
|                 } | ||||
|             } | ||||
|             fn disable() { | ||||
|                 unsafe { | ||||
|                     crate::pac::RCC.$enable().modify(|w| w.$perien(false)); | ||||
|                 } | ||||
|             } | ||||
|             fn reset() { | ||||
|                 unsafe { | ||||
|                     crate::pac::RCC.$reset().modify(|w| w.$perirst(true)); | ||||
|                     crate::pac::RCC.$reset().modify(|w| w.$perirst(false)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl RccPeripheral for peripherals::$inst {} | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| @ -4,6 +4,7 @@ use crate::gpio::{AnyPin, Pin}; | ||||
| use crate::pac::gpio::vals::{Afr, Moder}; | ||||
| use crate::pac::gpio::Gpio; | ||||
| use crate::pac::spi; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::spi::{ByteOrder, Config, Error, Instance, MisoPin, MosiPin, SckPin, WordSize}; | ||||
| use crate::time::Hertz; | ||||
| use core::marker::PhantomData; | ||||
| @ -28,14 +29,14 @@ impl WordSize { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct Spi<'d, T: Instance> { | ||||
| pub struct Spi<'d, T: Instance + RccPeripheral> { | ||||
|     sck: AnyPin, | ||||
|     mosi: AnyPin, | ||||
|     miso: AnyPin, | ||||
|     phantom: PhantomData<&'d mut T>, | ||||
| } | ||||
| 
 | ||||
| impl<'d, T: Instance> Spi<'d, T> { | ||||
| impl<'d, T: Instance + RccPeripheral> Spi<'d, T> { | ||||
|     pub fn new<F>( | ||||
|         pclk: Hertz, | ||||
|         _peri: impl Unborrow<Target = T> + 'd, | ||||
| @ -63,6 +64,8 @@ impl<'d, T: Instance> Spi<'d, T> { | ||||
|         let br = Self::compute_baud_rate(pclk, freq.into()); | ||||
| 
 | ||||
|         unsafe { | ||||
|             T::enable(); | ||||
|             T::reset(); | ||||
|             T::regs().cr2().modify(|w| { | ||||
|                 w.set_ssoe(false); | ||||
|             }); | ||||
| @ -140,7 +143,7 @@ impl<'d, T: Instance> Spi<'d, T> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'d, T: Instance> Drop for Spi<'d, T> { | ||||
| impl<'d, T: Instance + RccPeripheral> Drop for Spi<'d, T> { | ||||
|     fn drop(&mut self) { | ||||
|         unsafe { | ||||
|             Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _); | ||||
| @ -198,7 +201,7 @@ fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> { | ||||
| impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> { | ||||
|     type Error = Error; | ||||
| 
 | ||||
|     fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { | ||||
| @ -214,7 +217,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> { | ||||
| impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> { | ||||
|     type Error = Error; | ||||
| 
 | ||||
|     fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { | ||||
| @ -230,7 +233,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> { | ||||
| impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> { | ||||
|     type Error = Error; | ||||
| 
 | ||||
|     fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { | ||||
| @ -246,7 +249,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T> { | ||||
| impl<'d, T: Instance + RccPeripheral> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T> { | ||||
|     type Error = Error; | ||||
| 
 | ||||
|     fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { | ||||
|  | ||||
| @ -136,6 +136,7 @@ fn main() { | ||||
|     let mut interrupt_table: Vec<Vec<String>> = Vec::new(); | ||||
|     let mut peripherals_table: Vec<Vec<String>> = Vec::new(); | ||||
|     let mut peripheral_pins_table: Vec<Vec<String>> = Vec::new(); | ||||
|     let mut peripheral_rcc_table: Vec<Vec<String>> = Vec::new(); | ||||
| 
 | ||||
|     let dma_base = chip | ||||
|         .peripherals | ||||
| @ -216,6 +217,19 @@ fn main() { | ||||
|                     }; | ||||
|                     assert_eq!(p.address, dma_base + dma_stride * dma_num); | ||||
|                 } | ||||
|                 "spi" => { | ||||
|                     if let Some(clock) = &p.clock { | ||||
|                         let reg = clock.to_ascii_lowercase(); | ||||
|                         let field = name.to_ascii_lowercase(); | ||||
|                         peripheral_rcc_table.push(vec![ | ||||
|                             name.clone(), | ||||
|                             format!("{}enr", reg), | ||||
|                             format!("{}rstr", reg), | ||||
|                             format!("set_{}en", field), | ||||
|                             format!("set_{}rst", field), | ||||
|                         ]); | ||||
|                     } | ||||
|                 } | ||||
|                 _ => {} | ||||
|             } | ||||
|         } | ||||
| @ -255,6 +269,7 @@ fn main() { | ||||
|     make_table(&mut extra, "peripherals", &peripherals_table); | ||||
|     make_table(&mut extra, "peripheral_versions", &peripheral_version_table); | ||||
|     make_table(&mut extra, "peripheral_pins", &peripheral_pins_table); | ||||
|     make_table(&mut extra, "peripheral_rcc", &peripheral_rcc_table); | ||||
| 
 | ||||
|     for (module, version) in peripheral_versions { | ||||
|         println!("loading {} {}", module, version); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user