Log data to SDCard
This commit is contained in:
parent
d8ff2b7775
commit
ea7e266182
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -125,6 +125,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byte-slice-cast 1.2.2",
|
"byte-slice-cast 1.2.2",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"core2",
|
||||||
"cortex-m",
|
"cortex-m",
|
||||||
"cortex-m-rt",
|
"cortex-m-rt",
|
||||||
"critical-section",
|
"critical-section",
|
||||||
|
@ -176,6 +177,15 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core2"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cortex-m"
|
name = "cortex-m"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
|
|
|
@ -53,7 +53,7 @@ embedded-sdmmc = "0.7.0"
|
||||||
|
|
||||||
# Dependencies of embedded-sdmmc that I need to use directly
|
# Dependencies of embedded-sdmmc that I need to use directly
|
||||||
byteorder = {version = "1", default-features = false}
|
byteorder = {version = "1", default-features = false}
|
||||||
|
core2 = { version = "0.4.0", default-features = false}
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = 2
|
debug = 2
|
||||||
|
|
8
justfile
8
justfile
|
@ -1,6 +1,12 @@
|
||||||
build:
|
build:
|
||||||
cargo build
|
cargo build
|
||||||
|
|
||||||
|
attach:
|
||||||
|
probe-rs attach --chip RP2040 target/thumbv6m-none-eabi/debug/co2_sensing
|
||||||
|
|
||||||
|
run:
|
||||||
|
cargo run
|
||||||
|
|
||||||
rerun:
|
rerun:
|
||||||
probe-rs reset --chip RP2040
|
probe-rs reset --chip RP2040
|
||||||
probe-rs attach --chip RP2040 target/thumbv6m-none-eabi/debug/co2_sensing
|
just attach
|
||||||
|
|
68
src/main.rs
68
src/main.rs
|
@ -9,6 +9,7 @@
|
||||||
mod co2;
|
mod co2;
|
||||||
|
|
||||||
use byteorder::ByteOrder;
|
use byteorder::ByteOrder;
|
||||||
|
use core2::io::{Cursor, Write};
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_embedded_hal::SetConfig;
|
use embassy_embedded_hal::SetConfig;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
|
@ -16,6 +17,8 @@ use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::peripherals::{PIN_10, PIN_11, PIN_12, PIN_16, SPI1};
|
use embassy_rp::peripherals::{PIN_10, PIN_11, PIN_12, PIN_16, SPI1};
|
||||||
use embassy_rp::spi::Spi;
|
use embassy_rp::spi::Spi;
|
||||||
use embassy_rp::{gpio, spi};
|
use embassy_rp::{gpio, spi};
|
||||||
|
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||||
|
use embassy_sync::channel::Channel;
|
||||||
use embedded_hal_bus::spi::ExclusiveDevice;
|
use embedded_hal_bus::spi::ExclusiveDevice;
|
||||||
use embedded_sdmmc::sdcard::{DummyCsPin, SdCard};
|
use embedded_sdmmc::sdcard::{DummyCsPin, SdCard};
|
||||||
use embedded_sdmmc::{Block, BlockDevice, BlockIdx, VolumeIdx};
|
use embedded_sdmmc::{Block, BlockDevice, BlockIdx, VolumeIdx};
|
||||||
|
@ -29,6 +32,8 @@ bind_interrupts!(struct Irqs {
|
||||||
I2C1_IRQ => i2c::InterruptHandler<embassy_rp::peripherals::I2C1>;
|
I2C1_IRQ => i2c::InterruptHandler<embassy_rp::peripherals::I2C1>;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static MEASUREMENT_VALUES: Channel<ThreadModeRawMutex, u16, 8> = Channel::new();
|
||||||
|
|
||||||
struct DummyTimesource();
|
struct DummyTimesource();
|
||||||
|
|
||||||
impl embedded_sdmmc::TimeSource for DummyTimesource {
|
impl embedded_sdmmc::TimeSource for DummyTimesource {
|
||||||
|
@ -49,9 +54,9 @@ async fn main(spawner: Spawner) {
|
||||||
embassy_rp::pac::SIO.spinlock(31).write_value(1);
|
embassy_rp::pac::SIO.spinlock(31).write_value(1);
|
||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
|
|
||||||
// spawner
|
spawner
|
||||||
// .spawn(write_to_sd(p.SPI1, p.PIN_10, p.PIN_11, p.PIN_12, p.PIN_16))
|
.spawn(write_to_sd(p.SPI1, p.PIN_10, p.PIN_11, p.PIN_12, p.PIN_16))
|
||||||
// .unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Wake pin is not required as long as its kept low at all times
|
// Wake pin is not required as long as its kept low at all times
|
||||||
// let mut nWAKE = gpio::Output::new(p.PIN_13, Level::High);
|
// let mut nWAKE = gpio::Output::new(p.PIN_13, Level::High);
|
||||||
|
@ -96,14 +101,14 @@ async fn main(spawner: Spawner) {
|
||||||
status, measured_value
|
status, measured_value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
MEASUREMENT_VALUES.send(measured_value).await;
|
||||||
|
|
||||||
Timer::after(Duration::from_secs(2)).await;
|
Timer::after(Duration::from_secs(2)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn write_to_sd(spi1: SPI1, pin10: PIN_10, pin11: PIN_11, pin12: PIN_12, pin16: PIN_16) {
|
async fn write_to_sd(spi1: SPI1, pin10: PIN_10, pin11: PIN_11, pin12: PIN_12, pin16: PIN_16) {
|
||||||
Timer::after(Duration::from_secs(2)).await;
|
|
||||||
|
|
||||||
// SPI clock needs to be running at <= 400kHz during initialization
|
// SPI clock needs to be running at <= 400kHz during initialization
|
||||||
let mut config = spi::Config::default();
|
let mut config = spi::Config::default();
|
||||||
config.frequency = 400_000;
|
config.frequency = 400_000;
|
||||||
|
@ -127,6 +132,7 @@ async fn write_to_sd(spi1: SPI1, pin10: PIN_10, pin11: PIN_11, pin12: PIN_12, pi
|
||||||
let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, DummyTimesource());
|
let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, DummyTimesource());
|
||||||
{
|
{
|
||||||
let device = volume_mgr.device();
|
let device = volume_mgr.device();
|
||||||
|
info!("Listing devices:");
|
||||||
for (index, label) in valid_volumes(device).into_iter().flatten() {
|
for (index, label) in valid_volumes(device).into_iter().flatten() {
|
||||||
info!(
|
info!(
|
||||||
"Volume {}: name: {:?}",
|
"Volume {}: name: {:?}",
|
||||||
|
@ -141,35 +147,45 @@ async fn write_to_sd(spi1: SPI1, pin10: PIN_10, pin11: PIN_11, pin12: PIN_12, pi
|
||||||
let mut volume0 = volume_mgr
|
let mut volume0 = volume_mgr
|
||||||
.open_volume(embedded_sdmmc::VolumeIdx(0))
|
.open_volume(embedded_sdmmc::VolumeIdx(0))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
info!("Volume 0: {:?}", defmt::Debug2Format(&volume0));
|
|
||||||
|
|
||||||
// Open the root directory (mutably borrows from the volume).
|
// Open the root directory (mutably borrows from the volume).
|
||||||
let mut root_dir = volume0.open_root_dir().unwrap();
|
let mut root_dir = volume0.open_root_dir().unwrap();
|
||||||
|
|
||||||
{
|
let mut file_count: usize = 0;
|
||||||
// Open a file called "MY_FILE.TXT" in the root directory
|
root_dir.iterate_dir(|_| file_count += 1).unwrap();
|
||||||
// This mutably borrows the directory.
|
info!("Found {} files", file_count);
|
||||||
let mut my_file = root_dir
|
|
||||||
.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)
|
// ShortFileName::FILENAME_MAX_LEN == 11. Therefore, we can't go any longer
|
||||||
|
// However, this should be fine as we have 8 chars => 10^8 = 100000000
|
||||||
|
// possible files.
|
||||||
|
let mut file_name_buffer = [0; 11];
|
||||||
|
let mut cursor = Cursor::new(&mut file_name_buffer[..]);
|
||||||
|
core::write!(&mut cursor, "{}.txt", file_count + 1)
|
||||||
|
.expect("File count + extension should definetly fit into 11 bytes");
|
||||||
|
let final_position = cursor.position() as usize;
|
||||||
|
let file_name = core::str::from_utf8(&file_name_buffer[..final_position])
|
||||||
|
.expect("We only put ASCII into the buffer");
|
||||||
|
|
||||||
|
info!("Creating new text file: {}", file_name);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let new_value = MEASUREMENT_VALUES.receive().await;
|
||||||
|
|
||||||
|
let mut file = root_dir
|
||||||
|
.open_file_in_dir(file_name, embedded_sdmmc::Mode::ReadWriteCreateOrAppend)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Print the contents of the file
|
info!("Writing measurement value {} to file", new_value);
|
||||||
while !my_file.is_eof() {
|
|
||||||
let mut buf = [0u8; 32];
|
|
||||||
if let Ok(n) = my_file.read(&mut buf) {
|
|
||||||
info!("{:a}", buf[..n]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// Append some text to the end of the file
|
|
||||||
let mut my_file = root_dir
|
|
||||||
.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadWriteAppend)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
my_file.write(b"Another one\n").unwrap();
|
// Space for five characters to fit numbers up to 65535 + '\n'
|
||||||
|
let mut to_write = [b' '; 6];
|
||||||
|
let mut cursor = Cursor::new(&mut to_write[..]);
|
||||||
|
core::write!(&mut cursor, "{}", new_value)
|
||||||
|
.expect("We have more than enough bytes to fit an u16");
|
||||||
|
to_write[5] = b'\n';
|
||||||
|
file.write(&to_write).unwrap();
|
||||||
|
drop(file);
|
||||||
}
|
}
|
||||||
debug!("TASK ENDED: SdCard")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn valid_volumes<D>(block_device: &mut D) -> [Option<(VolumeIdx, [u8; 11])>; 4]
|
pub fn valid_volumes<D>(block_device: &mut D) -> [Option<(VolumeIdx, [u8; 11])>; 4]
|
||||||
|
|
Loading…
Reference in a new issue