cpld: basic switching capability
This commit is contained in:
parent
393138dc9a
commit
58e77ae671
@ -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",
|
||||
]
|
||||
|
@ -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__":
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
62
src/cpld.rs
Normal file
62
src/cpld.rs
Normal file
@ -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, CS0, CS1, CS2> {
|
||||
spi: SPI,
|
||||
chip_select: (CS0, CS1, CS2),
|
||||
}
|
||||
|
||||
impl<SPI, CS0, CS1, CS2> CPLD<SPI, CS0, CS1, CS2> where
|
||||
SPI: Transfer<u8>,
|
||||
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(),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
26
src/main.rs
26
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user