forked from M-Labs/humpback-dds
113 lines
3.1 KiB
Rust
113 lines
3.1 KiB
Rust
#![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();
|
|
}
|
|
}
|