From 58e77ae6715b399060c074c5cbd8aff4948beed7 Mon Sep 17 00:00:00 2001 From: occheung Date: Sun, 9 Aug 2020 18:46:06 +0800 Subject: [PATCH] cpld: basic switching capability --- .cargo/config | 2 +- migen/fpga_config.py | 6 +-- src/TCA9548ARGER.rs | 112 ------------------------------------------- src/blinky.rs | 76 ----------------------------- src/cpld.rs | 62 ++++++++++++++++++++++++ src/main.rs | 26 +++++----- 6 files changed, 79 insertions(+), 205 deletions(-) delete mode 100644 src/TCA9548ARGER.rs delete mode 100644 src/blinky.rs create mode 100644 src/cpld.rs diff --git a/.cargo/config b/.cargo/config index 6c91033..c0ce242 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,5 +1,5 @@ [target.thumbv7em-none-eabihf] -runner = "gdb -q -x gdb_config/debug.gdb" +runner = "gdb -q -x gdb_config/fpga_config.gdb" rustflags = [ "-C", "link-arg=-Tlink.x", ] diff --git a/migen/fpga_config.py b/migen/fpga_config.py index 2eb8a15..ba08bc5 100644 --- a/migen/fpga_config.py +++ b/migen/fpga_config.py @@ -22,14 +22,14 @@ class UrukulConnector(Module): self.comb += [ eem.p[0].eq(spi.sclk), eem.p[1].eq(spi.mosi), - eem.p[2].eq(spi.miso), + spi.miso.eq(eem.p[2]), eem.p[3].eq(spi.cs[0]), eem.p[4].eq(spi.cs[1]), eem.p[5].eq(spi.cs[2]), ] - # Debug purposes: Tie MISO to MOSI - self.comb += spi.miso.eq(spi.mosi) + # Debug purposes: Tie EEM MISO to EEM MOSI + # self.comb += eem.p[2].eq(eem.n[1]) if __name__ == "__main__": diff --git a/src/TCA9548ARGER.rs b/src/TCA9548ARGER.rs deleted file mode 100644 index 107e271..0000000 --- a/src/TCA9548ARGER.rs +++ /dev/null @@ -1,112 +0,0 @@ -#![no_main] -#![no_std] - -extern crate panic_itm; - -use stm32h7xx_hal::hal::digital::v2::OutputPin; -use stm32h7xx_hal::{pac, prelude::*}; - -use cortex_m_rt::entry; - -use cortex_m_log::println; -use cortex_m_log::{ - destination::Itm, printer::itm::InterruptSync as InterruptSyncItm, -}; - -/* - * I2C Address of the I2C switch (TCA9548ARGER) - */ -const TCA9548ARGER_ADDR :u8 = 0x72; - -/* - * Control register bit masks - */ -const CHANNEL_0 :u8 = 0x01; -const CHANNEL_1 :u8 = 0x02; -const CHANNEL_2 :u8 = 0x04; -const CHANNEL_3 :u8 = 0x08; -const CHANNEL_4 :u8 = 0x10; -const CHANNEL_5 :u8 = 0x20; -const CHANNEL_6 :u8 = 0x40; -const CHANNEL_7 :u8 = 0x80; - -/* - * I2C Address of slaves at different channels - */ -const TEMP_1_ADDR :u8 = 0x48; -const TEMP_PRODUCT_ID_REG :u8 = 0x07; - -#[entry] -fn main() -> ! { - let cp = cortex_m::Peripherals::take().unwrap(); - let dp = pac::Peripherals::take().unwrap(); - let mut log = InterruptSyncItm::new(Itm::new(cp.ITM)); - - // Constrain and Freeze power - // println!(log, "Setup PWR... "); - let pwr = dp.PWR.constrain(); - let vos = pwr.freeze(); - - // Constrain and Freeze clock - // println!(log, "Setup RCC... "); - let rcc = dp.RCC.constrain(); - let ccdr = rcc.sys_ck(100.mhz()).freeze(vos, &dp.SYSCFG); - let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB); - let gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE); - - // Configure the SCL and the SDA pin for our I2C bus - let scl = gpiob.pb8.into_alternate_af4().set_open_drain(); - let sda = gpiob.pb9.into_alternate_af4().set_open_drain(); - - let mut i2c = - dp.I2C1 - .i2c((scl, sda), 100.khz(), ccdr.peripheral.I2C1, &ccdr.clocks); - - // Setup delay - let mut delay = cp.SYST.delay(ccdr.clocks); - - // Configure led - let mut green = gpiob.pb0.into_push_pull_output(); - let mut yellow = gpioe.pe1.into_push_pull_output(); - let mut red = gpiob.pb14.into_push_pull_output(); - - // I2C switch (TCA9548ARGER_ADDR): Only enable channel 5 - let mut tx1 :[u8, 1] = [CHANNEL_5]; - let mut rx1 :[u8; 1] = [0]; - - loop { - i2c.write(TCA9548ARGER_ADDR, &tx1); - delay.delay_ms(10_u16); - } - - // Read back the control value - i2c.read(TCA9548ARGER_ADDR, &mut rx1).unwrap(); - - // Match the control register content with the CHANNEL_5 mask - match rx1[0] { - CHANNEL_5 => yellow.set_high(), - _ => yellow.set_low(), - }.unwrap(); - - loop { - red.set_high().unwrap(); - } - - // delay.delay_ms(100_u16); - - // Temperature sensor (TEMP_1_ADDR): write TEMP_PRODUCT_ID_REG, and read its content (1 byte) - let mut tx2 :[u8, 1] = TEMP_PRODUCT_ID_REG; - let mut rx2 :[u8; 1] = [0]; - // i2c.write_read(TEMP_1_ADDR, &tx1.clone(), &mut rx).unwrap(); - i2c.write_read(TCA9548ARGER_ADDR, &tx2.clone(), &mut rx2).unwrap(); - - // The ID should be 0xA1. - match rx2[0] { - 0xA1 => green.set_high(), - _ => green.set_low(), - }.unwrap(); - - loop { - red.set_high().unwrap(); - } -} diff --git a/src/blinky.rs b/src/blinky.rs deleted file mode 100644 index c7c1157..0000000 --- a/src/blinky.rs +++ /dev/null @@ -1,76 +0,0 @@ -#![deny(warnings)] -#![deny(unsafe_code)] -#![no_main] -#![no_std] - -extern crate panic_itm; - -use cortex_m; -use cortex_m_rt::entry; -use stm32h7xx_hal::hal::digital::v2::OutputPin; -use stm32h7xx_hal::{pac, prelude::*}; - -use cortex_m_log::println; -use cortex_m_log::{ - destination::Itm, printer::itm::InterruptSync as InterruptSyncItm, -}; - -#[entry] -fn main() -> ! { - let cp = cortex_m::Peripherals::take().unwrap(); - let dp = pac::Peripherals::take().unwrap(); - let mut log = InterruptSyncItm::new(Itm::new(cp.ITM)); - - // Constrain and Freeze power - println!(log, "Setup PWR... "); - let pwr = dp.PWR.constrain(); - let vos = pwr.freeze(); - - // Constrain and Freeze clock - println!(log, "Setup RCC... "); - let rcc = dp.RCC.constrain(); - let ccdr = rcc.sys_ck(100.mhz()).freeze(vos, &dp.SYSCFG); - - println!(log, ""); - println!(log, "stm32h7xx-hal example - Blinky"); - println!(log, ""); - - let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB); - let gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE); - - // Configure PE1 as output. - let mut green = gpiob.pb0.into_push_pull_output(); - let mut yellow = gpioe.pe1.into_push_pull_output(); - let mut red = gpiob.pb14.into_push_pull_output(); - - // Get the delay provider. - let mut delay = cp.SYST.delay(ccdr.clocks); - - let mut num = 0; - - loop { - delay.delay_ms(500_u16); - - if num & 4 != 0 { - green.set_high().unwrap(); - } - else { - green.set_low().unwrap(); - } - - if num & 2 != 0 { - yellow.set_high().unwrap(); - } - else { - yellow.set_low().unwrap(); - } - - if num & 1 != 0 { - red.set_high().unwrap(); - } - else { - red.set_low().unwrap(); - } - num = (num + 1) % 8; - } -} diff --git a/src/cpld.rs b/src/cpld.rs new file mode 100644 index 0000000..b2ceece --- /dev/null +++ b/src/cpld.rs @@ -0,0 +1,62 @@ +#![no_std] + +use stm32h7xx_hal::{ + hal::{ + digital::v2::{ + InputPin, + OutputPin, + }, + blocking::spi::Transfer, + }, + pac, + prelude::*, + spi, +}; + +use cortex_m; +use cortex_m::asm::nop; +use cortex_m_semihosting::hprintln; + +use nb::block; + +/* + * Basic structure for CPLD signal multiplexing + */ +pub struct CPLD { + spi: SPI, + chip_select: (CS0, CS1, CS2), +} + +impl CPLD where + SPI: Transfer, + CS0: OutputPin, + CS1: OutputPin, + CS2: OutputPin, +{ + + // Constructor for CPLD + pub fn new(spi: SPI, chip_select: (CS0, CS1, CS2)) -> Self { + + // Init CS to be 0 + let mut obj = Self{spi, chip_select}; + obj.select_chip(0); + return obj + } + + // Select chip + pub fn select_chip(&mut self, channel: u8) { + match channel & (1 << 0) { + 0 => self.chip_select.0.set_low(), + _ => self.chip_select.0.set_high(), + }; + match channel & (1 << 1) { + 0 => self.chip_select.1.set_low(), + _ => self.chip_select.1.set_high(), + }; + match channel & (1 << 2) { + 0 => self.chip_select.2.set_low(), + _ => self.chip_select.2.set_high(), + }; + } + +} diff --git a/src/main.rs b/src/main.rs index 93615b5..b744aac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ use cortex_m_semihosting::hprintln; use core::ptr; use nb::block; +mod cpld; #[entry] fn main() -> ! { @@ -37,6 +38,7 @@ fn main() -> ! { let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA); let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB); + let gpioc = dp.GPIOC.split(ccdr.peripheral.GPIOC); let gpiod = dp.GPIOD.split(ccdr.peripheral.GPIOD); let gpiof = dp.GPIOF.split(ccdr.peripheral.GPIOF); @@ -71,20 +73,18 @@ fn main() -> ! { let mut data :u8 = 0xAD; + let mut switch = cpld::CPLD::new(spi, ( + gpiob.pb12.into_push_pull_output(), + gpioa.pa15.into_push_pull_output(), + gpioc.pc7.into_push_pull_output(), + )); + loop { - hprintln!("Sent {}", data).unwrap(); - block!(spi.send(data)).unwrap(); - data = block!(spi.read()).unwrap(); - hprintln!("Read {}", data).unwrap(); +// hprintln!("Sent {}", data).unwrap(); +// block!(spi.send(data)).unwrap(); +// data = block!(spi.read()).unwrap(); +// hprintln!("Read {}", data).unwrap(); + nop(); } } - - - - - - - - -