Skip to content

Instantly share code, notes, and snippets.

@arrowcircle
Last active October 20, 2020 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arrowcircle/f088340219bf143f1a04a4724feab354 to your computer and use it in GitHub Desktop.
Save arrowcircle/f088340219bf143f1a04a4724feab354 to your computer and use it in GitHub Desktop.
bme280 rtic problem
[package]
authors = ["Oleg Bovykin <oleg.bovykin@gmail.com>"]
edition = "2018"
name = "air"
readme = "README.md"
version = "0.1.0"
[dependencies]
asm-delay = "0.9.0"
# bme280 = "0.2.1"
cortex-m = "0.6.3"
cortex-m-rt = "0.6.13"
cortex-m-rtic = "0.5.5"
cortex-m-semihosting = "0.3.5"
embedded-hal = "0.2.4"
heapless = "0.5.5"
nb = "1.0.0"
panic-halt = "0.2.0"
panic-itm = "0.4.1"
rtt-target = {version = "0.2.0", features = ["cortex-m"]}
[dependencies.bme280]
branch = "borrow_delay"
git = "https://github.com/David-OConnor/bme280-rs"
[dependencies.stm32f1xx-hal]
features = ["rt", "stm32f103", "medium"]
# path = "../stm32f1xx-hal"
branch = "can-high-level"
git = "https://github.com/timokroeger/stm32f1xx-hal"
# optional = true
# package = "bmp280-ehal"
# Uncomment for the panic example.
# panic-itm = "0.4.1"
# Uncomment for the allocator example.
# alloc-cortex-m = "0.3.5"
# Uncomment for the device example.
# Update `memory.x`, set target to `thumbv7em-none-eabihf` in `.cargo/config`,
# and then use `cargo build --examples device` to build it.
# [dependencies.stm32f3]
# features = ["stm32f303", "rt"]
# version = "0.7.1"
# this lets you use `cargo fix`!
[[bin]]
bench = false
name = "air"
test = false
[profile.release]
codegen-units = 1 # better optimizations
debug = true # symbols are nice and they don't increase the size on Flash
lto = true # better optimizations
#![no_main]
#![no_std]
use panic_halt as _;
use rtic::{app, cyccnt::U32Ext};
use rtt_target::{rprintln, rtt_init_print};
use stm32f1xx_hal::{
can::{Can, Filter, Frame, Id, Rx, Tx},
delay, i2c,
pac::CAN1,
prelude::*,
};
use asm_delay::AsmDelay;
use bme280::BME280;
const PERIOD: u32 = 3_000_000;
#[app(device = stm32f1xx_hal::pac, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
const APP: () = {
struct Resources {
can_tx: Tx<CAN1>,
can_rx: Rx<CAN1>,
counter: u16,
}
#[init(schedule = [can_tx_task])]
fn init(cx: init::Context) -> init::LateResources {
rtt_init_print!();
let mut core = cx.core;
core.DCB.enable_trace(); // required for DWT cycle clounter to work when not connected to the debugger
core.DWT.enable_cycle_counter();
unsafe { core.SCB.vtor.write(0x0800_0000) };
let mut flash = cx.device.FLASH.constrain();
let mut rcc = cx.device.RCC.constrain();
let clocks = rcc
.cfgr
.use_hse(8.mhz())
.sysclk(64.mhz())
.hclk(64.mhz())
.pclk1(16.mhz())
.pclk2(64.mhz())
.freeze(&mut flash.acr);
#[cfg(not(feature = "connectivity"))]
let mut can1 = Can::new(cx.device.CAN1, &mut rcc.apb1, cx.device.USB);
#[cfg(feature = "connectivity")]
let mut can1 = Can::new(cx.device.CAN1, &mut rcc.apb1);
// Select pins for CAN1.
let mut gpiob = cx.device.GPIOB.split(&mut rcc.apb2);
let can_rx_pin = gpiob.pb8.into_floating_input(&mut gpiob.crh);
let can_tx_pin = gpiob.pb9.into_alternate_push_pull(&mut gpiob.crh);
let mut afio = cx.device.AFIO.constrain(&mut rcc.apb2);
can1.assign_pins((can_tx_pin, can_rx_pin), &mut afio.mapr);
can1.configure(|config| {
// APB1 (PCLK1): 16MHz, Bit rate: 1000kBit/s, Sample Point 87.5%
// Value was calculated with http://www.bittiming.can-wiki.info/
config.set_bit_timing(0x001c_0000);
});
// Filters are required to use the receiver part of CAN2.
// Because the filter banks are part of CAN1 we first need to enable CAN1
// and split the filters between the peripherals to use them for CAN2.
// let mut can1 = Can::new(cx.device.CAN1, &mut rcc.apb1);
let mut filters = can1.split_filters().unwrap();
// To share load between FIFOs use one filter for standard messages and another
// for extended messages. Accept all IDs by setting the mask to 0. Explicitly
// allow to receive remote frames.
filters
.add(&Filter::new(Id::Standard(0)).with_mask(0).allow_remote())
.unwrap();
filters
.add(&Filter::new(Id::Extended(0)).with_mask(0).allow_remote())
.unwrap();
let can_rx = can1.take_rx(filters).unwrap();
let can_tx = can1.take_tx().unwrap();
// Sync to the bus and start normal operation.
can1.enable().ok();
// I2C
let scl = gpiob.pb6.into_alternate_open_drain(&mut gpiob.crl);
let sda = gpiob.pb7.into_alternate_open_drain(&mut gpiob.crl);
rprintln!("Set I2c Pins");
let i2c = i2c::BlockingI2c::i2c1(
cx.device.I2C1,
(scl, sda),
&mut afio.mapr,
i2c::Mode::Fast {
frequency: 400_000.hz(),
duty_cycle: i2c::DutyCycle::Ratio2to1,
},
clocks,
&mut rcc.apb1,
10,
10,
10,
10,
);
rprintln!("Inited I2c");
rprintln!("Before BME create");
let mut sensor = BME280::new_primary(i2c);
rprintln!("Before BME init");
let mut delay_provider = AsmDelay::new(asm_delay::bitrate::Hertz(64_000_000));
let init_result = sensor.init(&mut delay_provider);
match init_result {
Ok(_result) => {
rprintln!("Init OK");
}
Err(error) => {
rprintln!("Error initializing sensor: {:?}", error);
}
_ => rprintln!("Unknown init error"),
};
rprintln!("After BME init");
// Schedule sender task
cx.schedule.can_tx_task(cx.start + PERIOD.cycles()).unwrap();
let counter = 0;
rprintln!("End of init!");
init::LateResources {
can_tx,
can_rx,
counter,
}
}
#[task(resources = [can_tx, counter], schedule = [can_tx_task])]
fn can_tx_task(cx: can_tx_task::Context) {
let counter: &mut u16 = cx.resources.counter;
let frame_tx = Frame::new(Id::Standard(0x100), &counter.to_be_bytes()).unwrap();
cx.resources.can_tx.transmit(&frame_tx).unwrap();
if *counter > 200 {
rprintln!("Reseting counter");
*counter = 0;
} else {
*counter += 1;
}
cx.schedule
.can_tx_task(cx.scheduled + PERIOD.cycles())
.unwrap();
}
extern "C" {
fn EXTI0();
fn EXTI1();
}
#[idle]
fn idle(_cx: idle::Context) -> ! {
loop {
cortex_m::asm::nop();
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment