From 80b0f142a7b1abec7c171bef9639a293d856e44e Mon Sep 17 00:00:00 2001 From: Aniket Date: Sat, 26 Jun 2021 22:19:31 +0530 Subject: [PATCH 1/5] Done port.rs but others erased due to some reasons soon will do them --- src/port.rs | 82 +++++++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/src/port.rs b/src/port.rs index 9beb70d..4d89745 100644 --- a/src/port.rs +++ b/src/port.rs @@ -1,55 +1,53 @@ use core; -#[derive(Clone, Copy)] +#[derive(Clone,Copy)] pub enum PortName { - C, + C } -#[repr(C, packed)] -pub struct Port { - // Complete the struct below. See section 11.1.4 of the manual. Note it has continous memory representation of multiple ports but struct should only account for port C i.e. all registers beginning with PORTC_. - pcr: [u32; 32], - gpclr: u32, - gpchr: u32, - reserved_0: [u8; 24], - isfr: u32, +#[repr(C,packed)] +pub struct Port { //registers in port c + pcr : [u32;32], //32 Pin Control Register n + gpclr : u32, // Global Pin Control Low Register (PORTC_GPCLR) + gpchr : u32, // Global Pin Control High Register (PORTC_GPCHR) + isfr : u32, // Interrupt Status Flag Register(PORTC_ISFR) } impl Port { pub unsafe fn new(name: PortName) -> &'static mut Port { - // Complete the function below. Similar to watchdog. But use a matchcase since we should only return when portname is C. See the address in section 11.1.4. &mut *match name { - PortName::C => 0x4004B000 as *mut Port, + PortName::C => 0x4004B000 as *mut Port,// return address only if the port is c } } - pub unsafe fn set_pin_mode(&mut self, p: usize, mut mode: u32) { - // Given the pin mode as a 32 bit value set the register bytes to the same value for the corresponding pin. See the MUX(10-8) bits in section 11.14.1. We need to set only those bits. Again think of appropriate operations using AND,OR,XOR etc.. There are only 8 possible pin models so mode = 0 to 7. Reject if different. - let mut pcr = core::ptr::read_volatile(&self.pcr[p]); - pcr &= 0xFFFFF8FF; - mode &= 0x00000007; - mode <<= 8; - pcr |= mode; - core::ptr::write_volatile(&mut self.pcr[p], pcr); + let mut pcr= core::ptr::read_volatile(&self.pcr[p]); + + pcr &= 0xFFFFF8FF;// to make the value at 8-10 to be 0 + mode &= 0x00000007;//to make all other value except 0-2 in mode to zero + mode <<= 8;//shift mode's value to left by 8 + pcr |= mode;//take or to get the value of mode in pcr + + core::ptr::write_volatile(&mut self.pcr[p],pcr); } } pub struct Pin { port: *mut Port, - pin: usize, + pin: usize } impl Port { pub unsafe fn pin(&mut self, p: usize) -> Pin { - // Complete and return a pin struct - Pin { port: self, pin: p } + Pin{ + port : self, + pin : p + } } } -#[repr(C, packed)] +#[repr(C,packed)] struct GpioBitBand { - // Complete using section 49.2 - pdor: u32, + pdor: u32,// gpio registers for Port C psor: u32, pcor: u32, ptor: u32, @@ -58,17 +56,16 @@ struct GpioBitBand { } pub struct Gpio { - gpio: *mut GpioBitBand, - pin: usize, + gpio: *mut GpioBitband, + pin: usize } impl Port { pub fn name(&self) -> PortName { let addr = (self as *const Port) as u32; match addr { - // Return PortName::C if the address matches the starting address of port C as specified in section 11.1.4. Reject if address is wrong and return error. - 0x4004B000 => PortName::C, - _ => unreachable!(), + 0x4004B000 => PortName::C,//if address matches that of Port C + _ => unreachable!(),//if address does not match that of Port C } } } @@ -76,19 +73,18 @@ impl Port { impl Pin { pub fn make_gpio(self) -> Gpio { unsafe { - // Set pin mode to 1 to enable gpio mode (section 11.14.1 MUX bits). // Consume the pin into a gpio struct i.e. instantitate a gpio struct using the new function below. - let port = &mut *self.port; - port.set_pin_mode(self.pin, 1); - Gpio::new(port.name(), self.pin) + let port: &mut Port=&mut*self.port;//make port to be taken as mutable reference of Port + port.set_pin_mode(self.pin, 1);// to make a pin into gpio mode + Gpio::new(port.name(), self.pin)//making the new Gpio struct for the port given and pin given } } } impl Gpio { - pub unsafe fn new(port: PortName, pin: usize) -> Gpio { + pub unsafe fn new(port: PortName, pin: usize) -> Gpio {-++++ let gpio = match port { - PortName::C => 0x43FE1000 as *mut GpioBitBand, + PortName::C => 0x43FE1000 as *mut GpioBitband }; // Initialize and return a gpio struct. @@ -97,17 +93,15 @@ impl Gpio { pub fn output(&mut self) { unsafe { - // WRITE THE XX register of GPIO to 1 to enable this pin as output type. - // See section 49.2 of the teensy manual to find out what is XX. - core::ptr::write_volatile(&mut (*self.gpio).pddr, 1); + // WRITTEN Port Data Direction Register register of GPIO to 1 to enable this pin as output type. + core::ptr::write_volatile(&mut (*self.gpio).pddr,1); } } pub fn high(&mut self) { unsafe { - // WRITE THE XX register of GPIO to 1 to set this pin as high. - // See section 49.2 of the teensy manual to find out what is XX. Please not that it is not PDOR, since PDOR is never directly written. - core::ptr::write_volatile(&mut (*self.gpio).psor, 1); + // WRITTEN Port Set Output Register register of GPIO to 1 to set this pin as high. + core::ptr::write_volatile(&mut (*self.gpio).psor, 1); } } -} +} \ No newline at end of file From dfcaebb42322637513f2b577569b5fa529dd0fa4 Mon Sep 17 00:00:00 2001 From: Aniket Date: Sat, 26 Jun 2021 22:30:52 +0530 Subject: [PATCH 2/5] #2 completed watchdog --- src/watchdog.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/watchdog.rs b/src/watchdog.rs index d7c0026..b664abb 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -3,7 +3,7 @@ use core::arch::arm::__nop; #[repr(C, packed)] pub struct Watchdog { - stctrlh: u16, + stctrlh: u16,//12 registers for Wacthdog controlling stctrll: u16, tovalh: u16, tovall: u16, @@ -19,22 +19,18 @@ pub struct Watchdog { impl Watchdog { pub unsafe fn new() -> &'static mut Watchdog { - // You can see the starting address in section 23.7 of the manual i.e. 4005_2000. - &mut *(0x40052000 as *mut Watchdog) + &mut *(0x40052000 as *mut Watchdog)//starting register of watchdog } pub fn disable(&mut self) { unsafe { - // Disable the watchdog. This has 2 parts, unlocking the watchdog for modification and then disabling the watchdog. - // See section 23.3.1 for unlocking the watchdog. Ignore point 3 there. - // To disable the watchdog, see section 23.7.1 and scroll down to the last item in the table the 0th bit to understand how to disable the watchdog. This makes it clear that your operation should only change the 0th bit in the 16-bit value, keeping others same. How would you do that? (Think XOR,AND,OR etc.) core::ptr::write_volatile(&mut self.unlock, 0xC520); - core::ptr::write_volatile(&mut self.unlock, 0xD928); + core::ptr::write_volatile(&mut self.unlock, 0xD928);//unlocking the watchdog by writing values for unlock registers can check secction 23.3.1 __nop(); - __nop(); - let mut ctrl = core::ptr::read_volatile(&self.stctrlh); - ctrl &= !(0x00000001); - core::ptr::write_volatile(&mut self.stctrlh, ctrl); + __nop();//waiting for watchdog to unlock takes two cycle delay + let mut ctrl = core::ptr::read_volatile(&self.stctrlh);//take value of stctrlh to disable watchdog see section 23.7.1 + ctrl &= !(0x00000001);//making 0th bit to 0 of WDOG_STCTRLH to disable Watch dog + core::ptr::write_volatile(&mut self.stctrlh, ctrl);//write the ctrl value to finally disable watchdog } } } From c4ed57eb1bd881e736d89c01a8acf93ac07c62ef Mon Sep 17 00:00:00 2001 From: Aniket Date: Sat, 26 Jun 2021 22:43:47 +0530 Subject: [PATCH 3/5] #3 Final updatioon completed with Sim.rs completion --- src/sim.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/sim.rs b/src/sim.rs index 913b2a3..d85c2aa 100644 --- a/src/sim.rs +++ b/src/sim.rs @@ -10,9 +10,9 @@ pub struct Sim { // Complete code here // See section 12.2 of the teensy manual for the register sizes and memory locations and do similar to the watchdog struct. // Note that there are some empty bits between some registers and they are not continous, how do we resolve that ? Padding, eh ? - sopt1: u32, + sopt1: u32,// registers for sim sopt1_cfg: u32, - _pad0: [u32; 1023], + _pad0: [u32; 1023],// we had to introduce padding as the registers are not contigous in memory sopt2: u32, _pad1: u32, sopt4: u32, @@ -38,7 +38,7 @@ pub struct Sim { impl Sim { pub unsafe fn new() -> &'static mut Sim { - // Complete code here (similar to watchdog), see memory location from section 12.2 + // first register address of the register in Sim &mut *(0x40047000 as *mut Sim) } @@ -46,10 +46,9 @@ impl Sim { unsafe { match clock { Clock::PortC => { - // Use the teensy manual to find out which register controls Port C. Then implement this function to enable port C. Scroll through section 12.2 to find which bit of which register needs to be changed to enable clock gate to Port C. Note that all other bits of that register must remain unchanged. - let mut scgc = core::ptr::read_volatile(&self.scgc5); - scgc |= 0x00000800; - core::ptr::write_volatile(&mut self.scgc5, scgc); + let mut scgc = core::ptr::read_volatile(&self.scgc5);//Read value at the "System Clock Gating Control Register 5" also see 12.2 from manual + scgc |= 0x00000800;//make value at the 12th bit to 1 to enable the watch clock for Port C + core::ptr::write_volatile(&mut self.scgc5, scgc);//write value at "ystem Clock Gating Control Register 5" } } } From 17a34ca6b2d71cd52d038c1f6cfe8a43884fcac8 Mon Sep 17 00:00:00 2001 From: Aniket Date: Sat, 26 Jun 2021 22:52:35 +0530 Subject: [PATCH 4/5] #4 updating Sim.rs with more comments --- src/sim.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/sim.rs b/src/sim.rs index d85c2aa..510718c 100644 --- a/src/sim.rs +++ b/src/sim.rs @@ -6,13 +6,10 @@ pub enum Clock { } #[repr(C, packed)] -pub struct Sim { - // Complete code here - // See section 12.2 of the teensy manual for the register sizes and memory locations and do similar to the watchdog struct. - // Note that there are some empty bits between some registers and they are not continous, how do we resolve that ? Padding, eh ? - sopt1: u32,// registers for sim +pub struct Sim { // to understand read section 12.2 of teensy manual + sopt1: u32,// registers for sim sopt1_cfg: u32, - _pad0: [u32; 1023],// we had to introduce padding as the registers are not contigous in memory + _pad0: [u32; 1023],// we had to introduce padding as the registers are not contigous in memory use _padi to introduce padding to skip memory blocks in between the registers for Sim sopt2: u32, _pad1: u32, sopt4: u32, @@ -38,7 +35,7 @@ pub struct Sim { impl Sim { pub unsafe fn new() -> &'static mut Sim { - // first register address of the register in Sim + // first register address of the register in Sim to start giving address in the Sim struct &mut *(0x40047000 as *mut Sim) } @@ -46,9 +43,9 @@ impl Sim { unsafe { match clock { Clock::PortC => { - let mut scgc = core::ptr::read_volatile(&self.scgc5);//Read value at the "System Clock Gating Control Register 5" also see 12.2 from manual - scgc |= 0x00000800;//make value at the 12th bit to 1 to enable the watch clock for Port C - core::ptr::write_volatile(&mut self.scgc5, scgc);//write value at "ystem Clock Gating Control Register 5" + let mut scgc = core::ptr::read_volatile(&self.scgc5);//Read value at the "System Clock Gating Control Register 5" to make changes to enable Watch clock for Port C see 12.2 from manual + scgc |= 0x00000800;//make value at the 12th bit to 1 to enable the watch clock for Port C at scgc_5.... to check read 12.2 teensy manual + core::ptr::write_volatile(&mut self.scgc5, scgc);//write value at "system Clock Gating Control Register 5" to finally enable the watch clock } } } From 548bdab291bad44ef6c9b49d487dc7d9b4e7c462 Mon Sep 17 00:00:00 2001 From: Aniket Date: Sat, 26 Jun 2021 23:02:13 +0530 Subject: [PATCH 5/5] #5 Updating Port.rs with more comments --- src/port.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/port.rs b/src/port.rs index 4d89745..197b989 100644 --- a/src/port.rs +++ b/src/port.rs @@ -6,7 +6,8 @@ pub enum PortName { } #[repr(C,packed)] -pub struct Port { //registers in port c +pub struct Port { // see section 49.2 in Teensy manual for help + //registers in port c pcr : [u32;32], //32 Pin Control Register n gpclr : u32, // Global Pin Control Low Register (PORTC_GPCLR) gpchr : u32, // Global Pin Control High Register (PORTC_GPCHR) @@ -20,10 +21,9 @@ impl Port { } } pub unsafe fn set_pin_mode(&mut self, p: usize, mut mode: u32) { - let mut pcr= core::ptr::read_volatile(&self.pcr[p]); - + let mut pcr= core::ptr::read_volatile(&self.pcr[p]);//Reading value of the pcr of the Pin in Gpio to set pin mode pcr &= 0xFFFFF8FF;// to make the value at 8-10 to be 0 - mode &= 0x00000007;//to make all other value except 0-2 in mode to zero + mode &= 0x00000007;//to make all other value except 0-2 in mode to be zero and values in 0-2 to be 1 mode <<= 8;//shift mode's value to left by 8 pcr |= mode;//take or to get the value of mode in pcr @@ -31,14 +31,14 @@ impl Port { } } -pub struct Pin { - port: *mut Port, - pin: usize +pub struct Pin { // Pin is not stored as a register in port but as a struct in Port + port: *mut Port, // Reference to Port of which we are using the pin + pin: usize // Pin number to be used } impl Port { pub unsafe fn pin(&mut self, p: usize) -> Pin { - Pin{ + Pin{ // assigns Pin and Port to the struct Pin port : self, pin : p } @@ -55,14 +55,14 @@ struct GpioBitBand { pddr: u32, } -pub struct Gpio { +pub struct Gpio { // Gpio is also stored as a struct gpio: *mut GpioBitband, pin: usize } impl Port { pub fn name(&self) -> PortName { - let addr = (self as *const Port) as u32; + let addr = (self as *const Port) as u32;//store address of port passed in addr match addr { 0x4004B000 => PortName::C,//if address matches that of Port C _ => unreachable!(),//if address does not match that of Port C @@ -76,7 +76,7 @@ impl Pin { // Consume the pin into a gpio struct i.e. instantitate a gpio struct using the new function below. let port: &mut Port=&mut*self.port;//make port to be taken as mutable reference of Port port.set_pin_mode(self.pin, 1);// to make a pin into gpio mode - Gpio::new(port.name(), self.pin)//making the new Gpio struct for the port given and pin given + Gpio::new(port.name(), self.pin)//making the Gpio struct for the port given and pin given } } } @@ -84,7 +84,7 @@ impl Pin { impl Gpio { pub unsafe fn new(port: PortName, pin: usize) -> Gpio {-++++ let gpio = match port { - PortName::C => 0x43FE1000 as *mut GpioBitband + PortName::C => 0x43FE1000 as *mut GpioBitband// starting address for the registers in the Gpio }; // Initialize and return a gpio struct.