diff --git a/.vscode/launch.json b/.vscode/launch.json index 8d4421d..6d0a5a9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,9 +11,11 @@ "chip": "STM32H733VGTx", "coreConfigs": [ { - "programBinary": "${workspaceFolder}/target/thumbv7em-none-eabihf/debug/strain", - } - ] + "programBinary": "${workspaceFolder}/target/thumbv7em-none-eabihf/debug/argus", + }, + ], + "connectUnderReset": true, + "consoleLogLevel": "Info" }, { "type": "probe-rs-debug", @@ -22,9 +24,11 @@ "chip": "STM32H733VGTx", "coreConfigs": [ { - "programBinary": "${workspaceFolder}/target/thumbv7em-none-eabihf/debug/temperature", + "programBinary": "${workspaceFolder}/target/thumbv7em-none-eabihf/debug/argus", } - ] + ], + "connectUnderReset": true, + "consoleLogLevel": "Info" }, { "type": "probe-rs-debug", @@ -33,9 +37,11 @@ "chip": "STM32H733VGTx", "coreConfigs": [ { - "programBinary": "${workspaceFolder}/target/thumbv7em-none-eabihf/debug/pressure", + "programBinary": "${workspaceFolder}/target/thumbv7em-none-eabihf/debug/argus", } - ] + ], + "connectUnderReset": true, + "consoleLogLevel": "Info" }, ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 8b8bd1a..dfa2a00 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ { "rust-analyzer.cargo.target": "thumbv7em-none-eabihf", - "rust-analyzer.cargo.features": ["pressure"] + "rust-analyzer.cargo.features": ["pressure", "temperature", "strain"] } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 2622788..c6405d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,14 +5,15 @@ version = 4 [[package]] name = "ads126x" version = "0.1.0" +source = "git+https://github.com/uorocketry/ads126x#9b87da8f902a4aa90e21a474996191adad19eed4" dependencies = [ "bitflags 2.8.0", "cortex-m", "defmt", "embedded-hal 0.2.7", - "embedded-hal-mock", "heapless 0.7.17", "nb 1.1.0", + "serde", ] [[package]] @@ -40,6 +41,7 @@ dependencies = [ "rtic-sync", "smlang", "stm32h7xx-hal", + "thermocouple-converter", ] [[package]] @@ -130,6 +132,7 @@ checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" name = "common-arm" version = "0.1.0" dependencies = [ + "ads126x", "cortex-m", "defmt", "defmt-rtt", @@ -181,7 +184,7 @@ checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -225,7 +228,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -267,20 +270,20 @@ checksum = "984bc6eca246389726ac2826acc2488ca0fe5fcd6b8d9b48797021951d76a125" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] name = "derive_more" -version = "0.99.18" +version = "0.99.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -338,30 +341,6 @@ dependencies = [ "embedded-hal-async", ] -[[package]] -name = "embedded-hal-mock" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a0f04f8886106faf281c47b6a0e4054a369baedaf63591fdb8da9761f3f379" -dependencies = [ - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-nb", - "embedded-time", - "nb 1.1.0", - "void", -] - -[[package]] -name = "embedded-hal-nb" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" -dependencies = [ - "embedded-hal 1.0.0", - "nb 1.1.0", -] - [[package]] name = "embedded-sdmmc" version = "0.3.0" @@ -380,15 +359,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" -[[package]] -name = "embedded-time" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a4b4d10ac48d08bfe3db7688c402baadb244721f30a77ce360bd24c3dffe58" -dependencies = [ - "num", -] - [[package]] name = "enum_dispatch" version = "0.3.13" @@ -398,7 +368,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -427,6 +397,7 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7" dependencies = [ + "defmt", "gcd", ] @@ -504,15 +475,16 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" dependencies = [ + "defmt", "hash32 0.3.1", "stable_deref_trait", ] [[package]] name = "indexmap" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", "hashbrown", @@ -546,6 +518,12 @@ version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +[[package]] +name = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + [[package]] name = "mavlink" version = "0.13.1" @@ -591,19 +569,18 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "messages" version = "0.1.0" -source = "git+https://github.com/uorocketry/messages?branch=state-refactor#a2110bc7a0a69c02e464523a3623a4e96501fa54" +source = "git+https://github.com/uorocketry/messages?branch=adc-update#2fbb27a73a92ec45a8f4f4be6647abe929268681" dependencies = [ + "ads126x", "bitflags 2.8.0", "chrono", "defmt", "derive_more", - "enum_dispatch", "fugit", "heapless 0.7.17", "mavlink", "messages-proc-macros-lib", "serde", - "smlang", "stm32h7xx-hal", "ublox", ] @@ -611,7 +588,7 @@ dependencies = [ [[package]] name = "messages-proc-macros-lib" version = "0.1.0" -source = "git+https://github.com/uorocketry/messages?branch=state-refactor#a2110bc7a0a69c02e464523a3623a4e96501fa54" +source = "git+https://github.com/uorocketry/messages?branch=adc-update#2fbb27a73a92ec45a8f4f4be6647abe929268681" dependencies = [ "quote", "serde", @@ -632,28 +609,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" -[[package]] -name = "num" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" -dependencies = [ - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" -dependencies = [ - "num-traits", -] - [[package]] name = "num-derive" version = "0.3.3" @@ -665,37 +620,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -776,7 +700,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -845,7 +769,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -930,7 +854,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.24", + "semver 1.0.25", ] [[package]] @@ -950,9 +874,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" +checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" [[package]] name = "semver-parser" @@ -977,7 +901,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1023,6 +947,20 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "smoltcp" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad095989c1533c1c266d9b1e8d70a1329dd3723c3edac6d03bbd67e7bf6f4bb" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "cfg-if", + "defmt", + "heapless 0.8.0", + "managed", +] + [[package]] name = "spin" version = "0.9.8" @@ -1068,7 +1006,7 @@ dependencies = [ [[package]] name = "stm32h7xx-hal" version = "0.16.0" -source = "git+https://github.com/uorocketry/stm32h7xx-hal#28a100a725105714f60a190cce89dbda15cf953e" +source = "git+https://github.com/uorocketry/stm32h7xx-hal#4911af6221101b88aff47915ea5b76c6e60b93e8" dependencies = [ "bare-metal 1.0.0", "cast", @@ -1077,12 +1015,14 @@ dependencies = [ "defmt", "embedded-dma", "embedded-hal 0.2.7", + "embedded-hal 1.0.0", "embedded-storage", "fdcan", "fugit", "nb 1.1.0", "paste", "serde", + "smoltcp", "stm32h7", "void", ] @@ -1106,9 +1046,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.96" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -1145,7 +1085,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1156,7 +1096,7 @@ checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.98", ] [[package]] @@ -1184,9 +1124,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" [[package]] name = "vcell" diff --git a/Cargo.toml b/Cargo.toml index 728d846..39b3176 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,7 +69,7 @@ version = "0.5.0" [workspace.dependencies.messages] git = "https://github.com/uorocketry/messages" -branch = "state-refactor" +branch = "adc-update" [workspace.dependencies.defmt-test] version = "0.3.2" @@ -78,4 +78,7 @@ version = "0.3.2" version = "0.3.11" [workspace.dependencies.smlang] -version = "0.8.0" \ No newline at end of file +version = "0.8.0" + +[workspace.dependencies.ads126x] +git = "https://github.com/uorocketry/ads126x" \ No newline at end of file diff --git a/boards/argus/Cargo.toml b/boards/argus/Cargo.toml index a4491a7..f849d26 100644 --- a/boards/argus/Cargo.toml +++ b/boards/argus/Cargo.toml @@ -23,9 +23,10 @@ panic-probe = { workspace = true } chrono = { workspace = true } enum_dispatch = {workspace = true} messages = {workspace = true} -ads126x = {path = "../../crates/ads126x"} +ads126x = { workspace = true } smlang = {workspace = true} embedded-hal = {workspace = true} +thermocouple-converter = { path = "../../crates/thermocouple-converter" } [dev-dependencies] defmt-test = { workspace = true } @@ -40,6 +41,11 @@ name = "adc" harness = false path = "tests/adc.rs" +[[test]] +name = "simple" +harness = false +path = "tests/simple.rs" + [[bin]] name = "argus" harness = false diff --git a/boards/argus/src/adc_manager.rs b/boards/argus/src/adc_manager.rs index 0ee4e96..c433a39 100644 --- a/boards/argus/src/adc_manager.rs +++ b/boards/argus/src/adc_manager.rs @@ -1,13 +1,14 @@ use ads126x::{ - register::{DataRate, Mode1Register, Mode2Register}, + register::{Mode1Register, Mode2Register, NegativeInpMux, PositiveInpMux}, ADCCommand, Ads126x, }; use defmt::info; use embedded_hal::digital::v2::OutputPin; +use heapless::Vec; +use messages::sensor::AdcSensor; use stm32h7xx_hal::{ - gpio::{Output, Pin, PushPull}, - spi::Spi, + gpio::{Output, Pin, PushPull}, pac::sdmmc1::power, spi::Spi }; // There is an option to use interrupts using the data ready pins, but for now we will poll. @@ -20,6 +21,8 @@ where pub adc2: Ads126x, pub adc1_cs: Pin<'C', 10, Output>, pub adc2_cs: Pin<'D', 2, Output>, + pub adc1_sensors: (u8, Vec), // (index, sensors) + pub adc2_sensors: (u8, Vec), } impl AdcManager @@ -33,98 +36,152 @@ where adc1_cs: Pin<'C', 10, Output>, adc2_cs: Pin<'D', 2, Output>, ) -> Self { + let sensor1 = AdcSensor { + adc: 1, + positive_input: PositiveInpMux::AIN0, + negative_input: NegativeInpMux::AIN1, + }; + + let sensor2 = AdcSensor { + adc: 1, + positive_input: PositiveInpMux::AIN2, + negative_input: NegativeInpMux::AIN3, + }; + + let sensor3 = AdcSensor { + adc: 1, + positive_input: PositiveInpMux::AIN4, + negative_input: NegativeInpMux::AIN5, + }; + + let sensor4 = AdcSensor { + adc: 1, + positive_input: PositiveInpMux::AIN6, + negative_input: NegativeInpMux::AIN7, + }; + + let adc1_temp_sensor = AdcSensor { + adc: 1, + positive_input: PositiveInpMux::TempSensMonPos, + negative_input: NegativeInpMux::TempSensMonNeg, + }; + + let sensor5 = AdcSensor { + adc: 2, + positive_input: PositiveInpMux::AIN0, + negative_input: NegativeInpMux::AIN1, + }; + + let sensor6 = AdcSensor { + adc: 2, + positive_input: PositiveInpMux::AIN2, + negative_input: NegativeInpMux::AIN3, + }; + + let sensor7 = AdcSensor { + adc: 2, + positive_input: PositiveInpMux::AIN4, + negative_input: NegativeInpMux::AIN5, + }; + + let sensor8 = AdcSensor { + adc: 2, + positive_input: PositiveInpMux::AIN6, + negative_input: NegativeInpMux::AIN7, + }; + + // insert the sensors + let adc1_sensors = Vec::from_slice(&[sensor1, sensor2, sensor3, sensor4]) + .expect("Cannot create adc1_sensors vector."); + + // let adc1_sensors = Vec::from_slice(&[sensor4]) + // .expect("Cannot create adc1_sensors vector."); + + let adc2_sensors = Vec::from_slice(&[sensor5, sensor6, sensor7, sensor8]) + .expect("Cannot create adc2_sensors vector."); + Self { spi, adc1: Ads126x::new(adc1_rst), adc2: Ads126x::new(adc2_rst), adc1_cs, adc2_cs, + adc1_sensors: (0, adc1_sensors), + adc2_sensors: (0, adc2_sensors), } } pub fn init_adc1(&mut self) -> Result<(), ads126x::error::ADS126xError> { self.select_adc1(); - self.adc1.set_reset_high()?; - - // 2^16 cycles of delay - cortex_m::asm::delay(65536); - - // stop conversions - self.adc1.send_command(ADCCommand::STOP1, &mut self.spi)?; - self.adc1.send_command(ADCCommand::STOP2, &mut self.spi)?; + self.adc1.set_reset_high().unwrap(); - // setup the Power register - let mut power_cfg = ads126x::register::PowerRegister::default(); - power_cfg.clear_reset(); - self.adc1.set_power(&power_cfg, &mut self.spi)?; + // TODO: move these values to const, or pass in as a parameter (preferably pass as parameter) + cortex_m::asm::delay(65536 * (96_000_000 / 6_000_000)); // delay 2^16 cycles of the ADC - // Verify none custom config works first - // setup mode 1 and mode 2 registers - let mut mode1_cfg = Mode1Register::default(); - mode1_cfg.set_filter(ads126x::register::DigitalFilter::Sinc1); - self.adc1.set_mode1(&mode1_cfg, &mut self.spi)?; + #[cfg(any(feature = "temperature", feature = "pressure"))] + { + // We need to enable vbias + let mut power_cfg = ads126x::register::PowerRegister::default(); + power_cfg.set_vbias(false); + self.adc1.set_power(&power_cfg, &mut self.spi).unwrap(); + // Set gain + let mut mode2_cfg = Mode2Register::default(); + mode2_cfg.set_gain(ads126x::register::PGAGain::VV32); // this needs to be 1 if wanting to read internal temp sensor. let mut mode1_cfg = Mode1Register::default(); - let mut mode2_cfg = Mode2Register::default(); - mode2_cfg.set_dr(DataRate::SPS1200); - self.adc1.set_mode2(&mode2_cfg, &mut self.spi)?; + self.adc1.set_mode2(&mode2_cfg, &mut self.spi).unwrap(); - // read back the mode1 and mode2 registers to verify - let mode1_cfg_real = self.adc1.get_mode1(&mut self.spi)?; - let mode2_cfg_real = self.adc1.get_mode2(&mut self.spi)?; + let mut mode1_cfg = Mode1Register::default(); + mode1_cfg.set_sbmag(ads126x::register::SensorBiasMagnitude::R10MOhm); - // verify - info!("Mode1: {:#010b}", mode1_cfg_real.bits()); - info!("Mode2: {:#010b}", mode2_cfg_real.bits()); - assert!(mode1_cfg.difference(mode1_cfg_real).is_empty()); - assert!(mode2_cfg.difference(mode2_cfg_real).is_empty()); + self.adc1.set_mode1(&mode1_cfg, &mut self.spi).unwrap(); + } // start conversions + self.set_adc1_inpmux(&mut self.adc1_sensors.1[0].clone())?; + self.adc1.send_command(ADCCommand::START1, &mut self.spi)?; + self.adc1.send_command(ADCCommand::START2, &mut self.spi)?; + self.adc1.send_command(ADCCommand::RDATA1, &mut self.spi)?; + Ok(()) } pub fn init_adc2(&mut self) -> Result<(), ads126x::error::ADS126xError> { - self.select_adc1(); - self.adc2.set_reset_high()?; - - // 2^16 cycles of delay - cortex_m::asm::delay(65536); - - // stop conversions - self.adc2.send_command(ADCCommand::STOP1, &mut self.spi)?; - self.adc2.send_command(ADCCommand::STOP2, &mut self.spi)?; + self.select_adc2(); + self.adc2.set_reset_high().unwrap(); - // setup the Power register - let mut power_cfg = ads126x::register::PowerRegister::default(); - power_cfg.clear_reset(); - self.adc2.set_power(&power_cfg, &mut self.spi)?; + // TODO: move these values to const, or pass in as a parameter (preferably pass as parameter) + cortex_m::asm::delay(65536 * (96_000_000 / 6_000_000)); // delay 2^16 cycles of the ADC - // Verify none custom config works first - // setup mode 1 and mode 2 registers - let mut mode1_cfg = Mode1Register::default(); - mode1_cfg.set_filter(ads126x::register::DigitalFilter::Sinc1); - self.adc2.set_mode1(&mode1_cfg, &mut self.spi)?; + #[cfg(any(feature = "temperature", feature = "pressure"))] + { + // We need to enable vbias + let mut power_cfg = ads126x::register::PowerRegister::default(); + power_cfg.set_vbias(false); + self.adc2.set_power(&power_cfg, &mut self.spi).unwrap(); + // Set gain + let mut mode2_cfg = Mode2Register::default(); + mode2_cfg.set_gain(ads126x::register::PGAGain::VV32); // this needs to be 1 if wanting to read internal temp sensor. let mut mode1_cfg = Mode1Register::default(); - let mut mode2_cfg = Mode2Register::default(); - mode2_cfg.set_dr(DataRate::SPS1200); - self.adc2.set_mode2(&mode2_cfg, &mut self.spi)?; + self.adc2.set_mode2(&mode2_cfg, &mut self.spi).unwrap(); - // read back the mode1 and mode2 registers to verify - let mode1_cfg_real = self.adc2.get_mode1(&mut self.spi)?; - let mode2_cfg_real = self.adc2.get_mode2(&mut self.spi)?; + let mut mode1_cfg = Mode1Register::default(); + mode1_cfg.set_sbmag(ads126x::register::SensorBiasMagnitude::R10MOhm); - // verify - info!("Mode1: {:#010b}", mode1_cfg_real.bits()); - info!("Mode2: {:#010b}", mode2_cfg_real.bits()); - assert!(mode1_cfg.difference(mode1_cfg_real).is_empty()); - assert!(mode2_cfg.difference(mode2_cfg_real).is_empty()); + self.adc2.set_mode1(&mode1_cfg, &mut self.spi).unwrap(); + } // start conversions + self.set_adc2_inpmux(&mut self.adc2_sensors.1[0].clone())?; + self.adc2.send_command(ADCCommand::START1, &mut self.spi)?; + self.adc2.send_command(ADCCommand::START2, &mut self.spi)?; + self.adc2.send_command(ADCCommand::RDATA1, &mut self.spi)?; + Ok(()) } @@ -140,25 +197,31 @@ where pub fn set_adc1_inpmux( &mut self, - negative: ads126x::register::NegativeInpMux, - positive: ads126x::register::PositiveInpMux, + sensor: &mut AdcSensor, ) -> Result<(), ads126x::error::ADS126xError> { self.select_adc1(); let mut reg = ads126x::register::InpMuxRegister::default(); - reg.set_muxn(negative); - reg.set_muxp(positive); - self.adc1.set_inpmux(®, &mut self.spi) + reg.set_muxn(&sensor.negative_input); + reg.set_muxp(&sensor.positive_input); + info!("Setting ADC1 InpMux: {:#010b}", reg.bits()); + self.adc1.set_inpmux(®, &mut self.spi)?; + // verify the register + let mut reg_real = self.adc1.get_inpmux(&mut self.spi)?; + + info!("Real ADC1 InpMux: {:#010b}", reg_real.bits()); + + // assert_eq!(reg.bits(), reg_real.bits()); + Ok(()) } pub fn set_adc2_inpmux( &mut self, - negative: ads126x::register::NegativeInpMux, - positive: ads126x::register::PositiveInpMux, + sensor: &mut AdcSensor, ) -> Result<(), ads126x::error::ADS126xError> { self.select_adc2(); let mut reg = ads126x::register::InpMuxRegister::default(); - reg.set_muxn(negative); - reg.set_muxp(positive); + reg.set_muxn(&sensor.negative_input); + reg.set_muxp(&sensor.positive_input); self.adc2.set_inpmux(®, &mut self.spi) } @@ -171,23 +234,59 @@ where */ - pub fn read_adc1_data(&mut self) -> Result { + // abstract these functions + + pub fn read_adc1_data( + &mut self, + ) -> Result<(ads126x::register::StatusRegister, i32, u8), ads126x::error::ADS126xError> { self.select_adc1(); - // ask for data - /* - If no command is intended, keep the DIN pin low during readback. If an input command is - sent during readback, the ADC executes the command, and data interruption may result. - */ self.adc1.read_data1(&mut self.spi) } - pub fn read_adc2_data(&mut self) -> Result { + pub fn read_adc2_data( + &mut self, + ) -> Result<(ads126x::register::StatusRegister, i32, u8), ads126x::error::ADS126xError> { self.select_adc2(); - // ask for data - /* - If no command is intended, keep the DIN pin low during readback. If an input command is - sent during readback, the ADC executes the command, and data interruption may result. - */ self.adc2.read_data1(&mut self.spi) } + + // abstract these functions + + pub fn select_next_adc1_sensor(&mut self) { + self.adc2_cs.set_high(); + self.adc1_cs.set_high(); + self.adc1_cs.set_low(); + // select the next sensor based on round robin + let current_index = (self.adc1_sensors.0 as usize + 1) % self.adc1_sensors.1.len(); + + // set the inputmux + let mut sensor = &mut self.adc1_sensors.1[current_index].clone(); + self.set_adc1_inpmux(&mut sensor).unwrap(); + + // update the index + self.adc1_sensors.0 = current_index as u8; + } + + pub fn select_next_adc2_sensor(&mut self) { + // select the next sensor + } + + // pub fn read_adc1_temperature(&mut self) -> f64 { + // // set gain back to 1 + // let mut mode2_cfg = Mode2Register::default(); + // mode2_cfg.set_gain(ads126x::register::PGAGain::VV1); + // self.adc1.set_mode2(&mode2_cfg, &mut self.spi).unwrap(); + + // let mut sensor = AdcSensor { + // adc: 1, + // positive_input: PositiveInpMux::TempSensMonPos, + // negative_input: NegativeInpMux::TempSensMonNeg, + // }; + + // self.set_adc1_inpmux(&mut sensor).unwrap(); + + // let data = self.read_adc1_data().unwrap(); + + // ((data.1 - 122_400) / 420) as f64 + 25.0 + // } } diff --git a/boards/argus/src/can_manager.rs b/boards/argus/src/can_manager.rs index 20e7839..ff9e879 100644 --- a/boards/argus/src/can_manager.rs +++ b/boards/argus/src/can_manager.rs @@ -17,6 +17,7 @@ use postcard::from_bytes; /// Clock configuration is out of scope for this builder /// easiest way to avoid alloc is to use no generics pub struct CanManager { + // can: fdcan::FdCan, can: fdcan::FdCan, } @@ -69,6 +70,7 @@ impl CanManager { can.apply_config(config); Self { + // can: can.into_internal_loopback(), can: can.into_normal(), } } @@ -78,7 +80,7 @@ impl CanManager { let header = TxFrameHeader { len: payload.len() as u8, // switch to const as this never changes or swtich on message type of known size id: StandardId::new(COM_ID.into()).unwrap().into(), - frame_format: FrameFormat::Standard, + frame_format: FrameFormat::Fdcan, bit_rate_switching: false, marker: None, }; @@ -89,7 +91,8 @@ impl CanManager { let mut buf = [0u8; 64]; while self.can.receive0(&mut buf).is_ok() { if let Ok(data) = from_bytes::(&buf) { - data_manager.handle_command(data)?; + data_manager.handle_command(data.clone())?; + info!("Received: {:?}", data); } else { info!("Error: {:?}", from_bytes::(&buf).unwrap_err()); } diff --git a/boards/argus/src/data_manager.rs b/boards/argus/src/data_manager.rs index 4d3e4f8..540d665 100644 --- a/boards/argus/src/data_manager.rs +++ b/boards/argus/src/data_manager.rs @@ -1,13 +1,13 @@ use common_arm::HydraError; use messages::command::RadioRate; -use messages::state::DeviceState; +use messages::state::State; use messages::CanMessage; use messages::Temperature; use stm32h7xx_hal::rcc::ResetReason; #[derive(Clone)] pub struct DataManager { - pub state: Option, + pub state: Option, pub reset_reason: Option, pub logging_rate: Option, pub recovery_sensing: Option, diff --git a/boards/argus/src/main.rs b/boards/argus/src/main.rs index 2ae599b..1eb0305 100644 --- a/boards/argus/src/main.rs +++ b/boards/argus/src/main.rs @@ -29,21 +29,25 @@ use stm32h7xx_hal::gpio::gpioa::{PA2, PA3}; use stm32h7xx_hal::gpio::PA4; use stm32h7xx_hal::gpio::{Edge, ExtiPin, Pin}; use stm32h7xx_hal::gpio::{Output, PushPull}; -use stm32h7xx_hal::hal::spi; use stm32h7xx_hal::prelude::*; use stm32h7xx_hal::rtc; +use stm32h7xx_hal::spi; use stm32h7xx_hal::{rcc, rcc::rec}; use types::COM_ID; // global logger use crate::types::{ADC2_RST_PIN_ID, ADC2_RST_PIN_PORT}; +use messages::FormattedNaiveDateTime; + +use crate::time_manager::TimeManager; + const DATA_CHANNEL_CAPACITY: usize = 10; -systick_monotonic!(Mono, 500); +systick_monotonic!(Mono); statemachine! { transitions: { - *Init + Start = Idle, + *Initializing + Start = Idle, Idle | Recovery + WantsCollection = Collection, Idle + NoConfig = Calibration, Collection + WantsProcessing = Processing, @@ -61,20 +65,16 @@ fn panic() -> ! { #[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, dispatchers = [EXTI0, EXTI2, SPI3, SPI2])] mod app { - use messages::FormattedNaiveDateTime; - - use crate::time_manager::TimeManager; - use super::*; #[shared] struct SharedResources { data_manager: DataManager, em: ErrorManager, - sd_manager: SdManager< - stm32h7xx_hal::spi::Spi, - PA4>, - >, + // sd_manager: SdManager< + // stm32h7xx_hal::spi::Spi, + // PA4>, + // >, // can_command_manager: CanManager>, // can_data_manager: CanManager>, rtc: rtc::Rtc, @@ -114,26 +114,62 @@ mod app { // RCC let mut rcc = ctx.device.RCC.constrain(); let reset = rcc.get_reset_reason(); - let fdcan_prec_unsafe = unsafe { rcc.steal_peripheral_rec() } - .FDCAN - .kernel_clk_mux(rec::FdcanClkSel::Pll1Q); + // let fdcan_prec_unsafe = unsafe { rcc.steal_peripheral_rec() } + // .FDCAN + // .kernel_clk_mux(rec::FdcanClkSel::Pll1Q); + + // let spi4_unsafe = unsafe { rcc.steal_peripheral_rec() } + // .SPI4.get_kernel_clk_mux(); + // let spi4_clk_mux = spi4_unsafe.unwrap(); + // match spi4_clk_mux { + // SPI45SEL_A::Pll2Q => { + // info!("SPI4: PLL2Q"); + // }, + // SPI45SEL_A::Pll3Q => { + // info!("SPI4: PLL3Q"); + // }, + // SPI45SEL_A::Apb => { + // info!("SPI4: Apb"); + // }, + // SPI45SEL_A::Hse => { + // info!("SPI4: Hse"); + // }, + // SPI45SEL_A::CsiKer => { + // info!("SPI4: Csi"); + // }, + // SPI45SEL_A::HsiKer => { + // info!("SPI4: HSI"); + // }, + // } let ccdr = rcc // .use_hse(48.MHz()) // check the clock hardware - .sys_ck(96.MHz()) + // .sys_ck(96.MHz()) .pll1_strategy(rcc::PllConfigStrategy::Iterative) - .pll1_q_ck(48.MHz()) + .pll1_q_ck(32.MHz()) + .hclk(200.MHz()) + // .pll2_q_ck(48.MHz()) + // .pll2_strategy(rcc::PllConfigStrategy::Iterative) + // .pll3_q_ck(48.MHz()) + // .pll3_strategy(rcc::PllConfigStrategy::Iterative) .pclk1(48.MHz()) .pclk2(48.MHz()) .pclk3(48.MHz()) - .pclk4(48.MHz()) + .pclk4(24.MHz()) + // .per_ck(32.MHz()) .freeze(pwrcfg, &ctx.device.SYSCFG); + + ccdr.clocks.hsi_ck().unwrap(); + // assert_eq!(ccdr.clocks.pclk4().raw(), 24_000_000); + assert_eq!(ccdr.clocks.sys_ck().raw(), 64_000_000); info!("RCC configured"); let fdcan_prec = ccdr .peripheral .FDCAN .kernel_clk_mux(rec::FdcanClkSel::Pll1Q); + assert_eq!(ccdr.clocks.pll1_q_ck().unwrap().raw(), 32_000_000); + // GPIO let gpioa = ctx.device.GPIOA.split(ccdr.peripheral.GPIOA); let gpiod = ctx.device.GPIOD.split(ccdr.peripheral.GPIOD); @@ -153,18 +189,20 @@ mod app { // ctx.device.FDCAN2.fdcan(tx, rx, fdcan_prec) // }; - // let can_data_manager = CanManager::new(can2); - - // let can1: fdcan::FdCan< - // stm32h7xx_hal::can::Can, - // fdcan::ConfigMode, - // > = { - // let rx = gpioa.pa11.into_alternate().speed(Speed::VeryHigh); - // let tx = gpioa.pa12.into_alternate().speed(Speed::VeryHigh); - // ctx.device.FDCAN1.fdcan(tx, rx, fdcan_prec_unsafe) - // }; + let mut data_manager = DataManager::new(); + data_manager.set_reset_reason(reset); - // let can_command_manager = CanManager::new(can1); + // let mut can_data_manager = CanManager::new(can2); + // loop { + // can_data_manager.send_message( + // CanMessage::new( + // FormattedNaiveDateTime(NaiveDate::from_ymd(2021, 1, 1).and_hms(0, 0, 0)), + // COM_ID, + // CanData::Pressure((0, 0.0)), + // ) + // ); + // can_data_manager.process_data(&mut data_manager); + // } let spi_sd: stm32h7xx_hal::spi::Spi< stm32h7xx_hal::stm32::SPI1, @@ -182,31 +220,28 @@ mod app { &ccdr.clocks, ); - let cs_sd = gpioa.pa4.into_push_pull_output(); + let mut cs_sd = gpioa.pa4.into_push_pull_output(); + cs_sd.set_high(); - let sd_manager = SdManager::new(spi_sd, cs_sd); + // let sd_manager = SdManager::new(spi_sd, cs_sd); - // ADC setup - let adc_spi: stm32h7xx_hal::spi::Spi< - stm32h7xx_hal::stm32::SPI4, - stm32h7xx_hal::spi::Enabled, - u8, - > = ctx.device.SPI4.spi( + let mut adc_spi = ctx.device.SPI4.spi( ( - gpioe.pe2.into_alternate(), + gpioe.pe2.into_alternate::<5>(), gpioe.pe5.into_alternate(), gpioe.pe6.into_alternate(), ), - stm32h7xx_hal::spi::Config::new(spi::MODE_1), // datasheet mentioned a mode 1 per datasheet - 8.MHz(), // 125 ns + stm32h7xx_hal::spi::Config::new(spi::MODE_1), + // .inter_word_delay(0.000001), // datasheet mentioned a mode 1 per datasheet + 1.MHz(), // 125 ns ccdr.peripheral.SPI4, &ccdr.clocks, ); - let adc1_cs = gpioc.pc10.into_push_pull_output(); - let adc2_cs = gpiod.pd2.into_push_pull_output(); + let mut adc1_cs = gpioc.pc10.into_push_pull_output(); + let mut adc2_cs = gpiod.pd2.into_push_pull_output(); - let adc1_rst = gpioc.pc11.into_push_pull_output(); + let mut adc1_rst = gpioc.pc11.into_push_pull_output(); #[cfg(feature = "temperature")] let adc2_rst = gpioe.pe0.into_push_pull_output(); @@ -217,8 +252,34 @@ mod app { #[cfg(feature = "strain")] let adc2_rst = gpiob.pb9.into_push_pull_output(); + adc1_rst.set_high(); + adc2_cs.set_high(); + adc1_cs.set_low(); + + // adc_spi.write(&[0x08]); + // adc_spi.write(&[0x46, 0x00, 0b0011_0001]); + // let mut buffer = [0x26, 0x00, 0x26, 0x00]; + // adc_spi.transfer(&mut buffer).unwrap(); + // let data_buffer: [u8; 2] = [buffer[0], buffer[1]]; + // asm::delay(65535 * 5); + // info!("Buffer: {:#010b}", buffer); + // // let mut buffer = [0x26, 0x00]; + // // adc_spi.transfer(&mut buffer).unwrap(); + // // let data_buffer: [u8; 2] = [buffer[0], buffer[1]]; + // // asm::delay(65535); + // // info!("Buffer: {:#010b}", buffer); + // loop { + // // let mut buffer = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x12]; + // // adc1_cs.set_high(); + // // let data_buffer: [u8; 4] = [buffer[1], buffer[2], buffer[3], buffer[4]]; + // // let data: i32 = i32::from_be_bytes(data_buffer); + // // info!("Data: {}", data); + // } + let mut adc_manager = AdcManager::new(adc_spi, adc1_rst, adc2_rst, adc1_cs, adc2_cs); - adc_manager.init_adc1().ok(); + adc_manager.init_adc1().unwrap(); + adc_manager.init_adc2().unwrap(); + // leds let led_red = gpioa.pa2.into_push_pull_output(); @@ -254,24 +315,23 @@ mod app { adc2_int.enable_interrupt(&mut exti); /* Monotonic clock */ - Mono::start(core.SYST, 200_000_000); + Mono::start(core.SYST, ccdr.clocks.sysclk().raw()); - let mut data_manager = DataManager::new(); - data_manager.set_reset_reason(reset); let em = ErrorManager::new(); let state_machine = StateMachine::new(traits::Context {}); blink::spawn().ok(); // send_data_internal::spawn(can_receiver).ok(); + // poll_adc1::spawn().ok(); reset_reason_send::spawn().ok(); - state_send::spawn().ok(); + // state_send::spawn().ok(); info!("Online"); ( SharedResources { data_manager, em, - sd_manager, + // sd_manager, // can_command_manager, // can_data_manager, rtc, @@ -291,43 +351,63 @@ mod app { #[task(priority = 3, binds = EXTI15_10, shared = [adc_manager], local = [adc1_int])] fn adc1_data_ready(mut cx: adc1_data_ready::Context) { - info!("new data available come through"); cx.shared.adc_manager.lock(|adc_manager| { let data = adc_manager.read_adc1_data(); match data { Ok(data) => { - info!("data: {:?}", data); + // data sheet internal temp sensor + // info!("data: {:?}", data.1); + // let celsius = ((data.1 - 122_400) / 420)as f32 + 25.0; + // info!("Celcius: {}", celsius); + + info!("ADC1 reading: {:?}", data.1); + #[cfg(feature = "temperature")] + { + let volts = thermocouple_converter::adc_to_voltage(data.1); + info!("volatage: {}", volts); + + let celsius = thermocouple_converter::adc_to_celsius(data.1); + info!("Celcius: {}", celsius); + } + + #[cfg(feature = "pressure")] + { + let volts = thermocouple_converter::adc_to_voltage(data.1); + info!("volatage: {}", volts); + let pressure: f64 = ((10000.0/((60.0/100.0) * (2.5 / 3.0))) * volts) / 32.0; + info!("Pressure (psi): {}", pressure); + } + + #[cfg(feature = "strain")] + { + let volts = thermocouple_converter::adc_to_voltage(data.1); + info!("volatage: {}", volts); + let strain = data.1 as f32 * 0.0001; + info!("Strain: {}", strain); + } } Err(_) => { info!("Error reading data"); } } - // change the inpmux - adc_manager.set_adc1_inpmux( - ads126x::register::NegativeInpMux::AIN1, - ads126x::register::PositiveInpMux::AIN0, - ); + adc_manager.select_next_adc1_sensor(); // round robin schedules the sensors to be read. }); cx.local.adc1_int.clear_interrupt_pending_bit(); } #[task(priority = 3, binds = EXTI3, shared = [adc_manager], local = [adc2_int])] fn adc2_data_ready(mut cx: adc2_data_ready::Context) { - info!("new data available come through"); cx.shared.adc_manager.lock(|adc_manager| { let data = adc_manager.read_adc2_data(); match data { Ok(data) => { - info!("data: {:?}", data); + info!("Adc 2 reading data: {:?}", data.1); } Err(_) => { info!("Error reading data"); } } - adc_manager.set_adc2_inpmux( - ads126x::register::NegativeInpMux::AIN1, - ads126x::register::PositiveInpMux::AIN0, - ); + adc_manager.select_next_adc2_sensor(); // round robin schedules the sensors to be read. }); cx.local.adc2_int.clear_interrupt_pending_bit(); } @@ -340,18 +420,18 @@ mod app { .lock(|data_manager| data_manager.reset_reason.take()); match reason { Some(reason) => { - let message = messages::CanMessage::new( - cx.shared - .rtc - .lock(|rtc| messages::FormattedNaiveDateTime(rtc.date_time().unwrap())), - COM_ID, - CanData::Common(reason.into()), - ); - - cx.shared.em.run(|| { - spawn!(queue_data_internal, message)?; - Ok(()) - }); + // let message = messages::CanMessage::new( + // cx.shared + // .rtc + // .lock(|rtc| messages::FormattedNaiveDateTime(rtc.date_time().unwrap())), + // COM_ID, + // CanData::Common(reason.into()), + // ); + + // cx.shared.em.run(|| { + // spawn!(queue_data_internal, message)?; + // Ok(()) + // }); } None => return, } @@ -385,7 +465,6 @@ mod app { } // if there is none we still return since we simply don't have data yet. Ok(()) }); - Mono::delay(5.secs()).await; // spawn_after!(state_send, ExtU64::secs(5)).ok(); } @@ -403,14 +482,14 @@ mod app { match sensors { Some(x) => { for sensor in x.iter() { - let message = CanMessage::new( - messages::FormattedNaiveDateTime( - cx.shared.rtc.lock(|rtc| rtc.date_time().unwrap()), - ), - COM_ID, - CanData::Temperature(*sensor), - ); - spawn!(queue_data_internal, message)?; + // let message = CanMessage::new( + // messages::FormattedNaiveDateTime( + // cx.shared.rtc.lock(|rtc| rtc.date_time().unwrap()), + // ), + // COM_ID, + // CanData::Temperature(*sensor), + // ); + // spawn!(queue_data_internal, message)?; } } None => { diff --git a/boards/argus/src/traits.rs b/boards/argus/src/traits.rs index ea53c4d..9839932 100644 --- a/boards/argus/src/traits.rs +++ b/boards/argus/src/traits.rs @@ -1,6 +1,6 @@ //! This module should be refactored out. use crate::States; -use messages::state::DeviceState; +use messages::state::State; use crate::StateMachineContext; @@ -8,16 +8,16 @@ pub struct Context {} impl StateMachineContext for Context {} -impl From for DeviceState { +impl From for State { fn from(value: States) -> Self { match value { - States::Idle => DeviceState::Idle, - States::Calibration => DeviceState::Calibration, - States::Recovery => DeviceState::Recovery, - States::Collection => DeviceState::Collection, - States::Init => DeviceState::Init, - States::Processing => DeviceState::Processing, - States::Fault => DeviceState::Fault, + States::Idle => State::Idle, + States::Calibration => State::Calibration, + States::Recovery => State::Recovery, + States::Collection => State::Collection, + States::Initializing => State::Initializing, + States::Processing => State::Processing, + States::Fault => State::Fault, } } } diff --git a/boards/argus/src/types.rs b/boards/argus/src/types.rs index 06d29ec..c08cf3b 100644 --- a/boards/argus/src/types.rs +++ b/boards/argus/src/types.rs @@ -1,4 +1,8 @@ -use messages::node::{Node, Node::PressureBoard, Node::StrainBoard, Node::TemperatureBoard}; +use ads126x::register::{NegativeInpMux, PositiveInpMux}; +use messages::{ + node::Node::{self, PressureBoard, StrainBoard, TemperatureBoard}, + sensor::AdcSensor, +}; pub enum Feature { Temperature, diff --git a/boards/argus/tests/simple.rs b/boards/argus/tests/simple.rs new file mode 100644 index 0000000..ce520e4 --- /dev/null +++ b/boards/argus/tests/simple.rs @@ -0,0 +1,40 @@ +#![no_std] +#![no_main] + +use defmt::info; +use panic_probe as _; +use stm32h7xx_hal::{pac, rcc}; +use stm32h7xx_hal::prelude::*; + +#[defmt_test::tests] +mod tests { + use super::*; + + #[init] + fn init() { + let _cp = cortex_m::Peripherals::take().unwrap(); + let dp = pac::Peripherals::take().unwrap(); + + let pwr = dp.PWR.constrain(); + let pwrcfg = pwr.freeze(); + + info!("Power enabled"); + // RCC + let mut rcc = dp.RCC.constrain(); + let reset = rcc.get_reset_reason(); + + let ccdr = rcc + // .use_hse(48.MHz()) // check the clock hardware + .sys_ck(200.MHz()) + .pll1_strategy(rcc::PllConfigStrategy::Iterative) + .pll1_q_ck(32.MHz()) + .freeze(pwrcfg, &dp.SYSCFG); + + info!("Reset reason: {:?}", reset); + } + + #[test] + fn simple_test() { + assert!(true == true) + } +} diff --git a/crates/ads126x/Cargo.toml b/crates/ads126x/Cargo.toml deleted file mode 100644 index 9c1e325..0000000 --- a/crates/ads126x/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "ads126x" -version = "0.1.0" -edition = "2021" - -[dependencies] -defmt = {workspace = true} -embedded-hal = {workspace = true} -bitflags = { version = "2.3.1", features = ["serde"] } -nb = "1.1.0" -heapless = {workspace = true} -cortex-m = { workspace = true } - -[dev-dependencies] -embedded-hal-mock = "0.11.1" \ No newline at end of file diff --git a/crates/ads126x/README.md b/crates/ads126x/README.md deleted file mode 100644 index dac2de3..0000000 --- a/crates/ads126x/README.md +++ /dev/null @@ -1 +0,0 @@ -# ADS126x Device Driver diff --git a/crates/ads126x/docs/ads1262.pdf b/crates/ads126x/docs/ads1262.pdf deleted file mode 100644 index cae5756..0000000 Binary files a/crates/ads126x/docs/ads1262.pdf and /dev/null differ diff --git a/crates/ads126x/src/error.rs b/crates/ads126x/src/error.rs deleted file mode 100644 index f2c0bf2..0000000 --- a/crates/ads126x/src/error.rs +++ /dev/null @@ -1,7 +0,0 @@ -use core::fmt::Debug; - -#[derive(Debug)] -pub enum ADS126xError { - IO, - InvalidInputData, -} diff --git a/crates/ads126x/src/lib.rs b/crates/ads126x/src/lib.rs deleted file mode 100644 index cd498a0..0000000 --- a/crates/ads126x/src/lib.rs +++ /dev/null @@ -1,625 +0,0 @@ -#![no_std] -#![no_main] - -pub mod error; -pub mod register; - -use defmt::info; -use error::ADS126xError; -use register::{ - Adc2CfgRegister, Adc2MuxRegister, GpioConRegister, GpioDatRegister, GpioDirRegister, - IdRegister, IdacMagRegister, IdacMuxRegister, InpMuxRegister, InterfaceRegister, Mode0Register, - Mode1Register, Mode2Register, PowerRegister, RefMuxRegister, Register, TdacnRegister, - TdacpRegister, -}; - -use embedded_hal::digital::v2::OutputPin; - -/// The [`Result`] type for ADS126x operations. -pub type Result = core::result::Result; - -pub struct Ads126x -where - GpioPin: OutputPin, -{ - reset_pin: GpioPin, -} - -pub enum ADCCommand { - NOP, - RESET, - START1, - STOP1, - START2, - STOP2, - RDATA1, - RDATA2, - SYOCAL1, - SYGCAL1, - SFOCAL1, - SYOCAL2, - SYGCAL2, - SFOCAL2, - RREG(Register, u8), // (register address, number of registers) - WREG(Register, u8), // (register address, number of registers) -} - -impl Ads126x -where - GpioPin: OutputPin, -{ - pub fn new(reset_pin: GpioPin) -> Self { - Self { reset_pin } - } - - // consolidate this logic to one function. - pub fn set_reset_high(&mut self) -> Result<()> { - self.reset_pin.set_high().map_err(|_| ADS126xError::IO)?; - Ok(()) - } - - pub fn set_reset_low(&mut self) -> Result<()> { - self.reset_pin.set_low().map_err(|_| ADS126xError::IO)?; - Ok(()) - } - - /// to issue read data command call read_data1 or read_data2. - pub fn send_command(&mut self, command: ADCCommand, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let (opcode1, opcode2) = match command { - ADCCommand::NOP => (0x00, None), - ADCCommand::RESET => (0x06, None), - ADCCommand::START1 => (0x08, None), - ADCCommand::STOP1 => (0x0A, None), - ADCCommand::START2 => (0x0C, None), - ADCCommand::STOP2 => (0x0E, None), - ADCCommand::RDATA1 => (0x12, None), - ADCCommand::RDATA2 => (0x14, None), - ADCCommand::SYOCAL1 => (0x16, None), - ADCCommand::SYGCAL1 => (0x17, None), - ADCCommand::SFOCAL1 => (0x19, None), - ADCCommand::SYOCAL2 => (0x1B, None), - ADCCommand::SYGCAL2 => (0x1C, None), - ADCCommand::SFOCAL2 => (0x1E, None), - ADCCommand::RREG(addr, num) => (0x20 | addr as u8, Some(num)), - ADCCommand::WREG(addr, num) => (0x40 | addr as u8, Some(num)), - }; - info!("Sending opcode 1: {:#04x}", opcode1); - - let mut opcodes = [ - opcode1, - if Some(opcode2) != None { - opcode2.unwrap() - } else { - 0x00 - }, - ]; - - spi.transfer(&mut opcodes).map_err(|_| ADS126xError::IO)?; // this ?)?; is weird, why can't I just ? on the block result. - Ok(()) - } - - pub fn read_data1(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - // 0x00 gets interpretted as NOP command - let mut buffer: [u8; 6] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x12]; - spi.transfer(&mut buffer).map_err(|_| ADS126xError::IO)?; - let data_buffer: [u8; 4] = [buffer[1], buffer[2], buffer[3], buffer[4]]; - let data: i32 = i32::from_be_bytes(data_buffer); - Ok(data) - } - - /// Reads data from multiple registers starting at the provided register. - /// To read a single register, see [`ADS126x::read_register`]. - /// - /// Vector returns byte for each register read in order registers were read (increasing address). - pub fn read_multiple_registers( - &mut self, - reg: Register, - num: u8, - spi: &mut SPI, - ) -> Result<[u8; 27]> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - if num > 27 { - return Err(ADS126xError::InvalidInputData); - } - // self.send_command(ADCCommand::RREG(reg, num - 1), spi)?; - let mut buffer: [u8; 27] = [ - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - num, - 0x20 | reg as u8, - ]; - - spi.transfer(&mut buffer).map_err(|_| ADS126xError::IO)?; - - // let mut buffer: Vec = Vec::new(); - // for _ in 0..num { - // buffer - // .push(spi.read().map_err(|_| ADS126xError::IO)?) - // .map_err(|_| ADS126xError::InvalidInputData)?; - // } - Ok(buffer) - } - /// Reads data from only the single provided register. - /// To read multiple registers, see [`ADS126x::read_multiple_registers`]. - pub fn read_register(&mut self, reg: Register, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - // zero since number of registers read - 1, so 1-1=0. - // self.send_command(ADCCommand::RREG(reg, 0), spi)?; - // let data = spi.read().map_err(|_| ADS126xError::IO)?; - let mut buffer = [reg as u8 | 0x20]; - spi.transfer(&mut buffer).map_err(|_| ADS126xError::IO)?; - - Ok(buffer[0]) - } - - /// Writes data to multiple registers starting at the provided register. - /// To write data to a single register, see [`ADS126x::write_register`]. - /// - /// Data has byte for each register in order registers are written to (increasing address). - pub fn write_multiple_registers( - &mut self, - reg: Register, - data: &[u8], - spi: &mut SPI, - ) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - if data.len() > 27 { - return Err(ADS126xError::InvalidInputData); - } - self.send_command(ADCCommand::WREG(reg, data.len() as u8 - 1), spi)?; - for &byte in data { - spi.write(&[byte]).map_err(|_| ADS126xError::IO)?; - } - Ok(()) - } - - /// Writes data to only the single provided register. - /// To write data to multiple registers, see [`ADS126x::write_multiple_registers`]. - pub fn write_register(&mut self, reg: Register, data: u8, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.send_command(ADCCommand::WREG(reg, 0), spi)?; - info!("Writing {:#010b} ", data); - // panic!(); - spi.write(&[data]).map_err(|_| ADS126xError::IO) - } - - pub fn get_id(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::ID, spi)?; - let data = IdRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn get_power(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::POWER, spi)?; - let data = PowerRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_power(&mut self, reg: &PowerRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::POWER, reg.bits(), spi) - } - - pub fn get_interface(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::INTERFACE, spi)?; - let data = InterfaceRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_interface(&mut self, reg: &InterfaceRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::INTERFACE, reg.bits(), spi) - } - - pub fn get_mode0(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::MODE0, spi)?; - let data = Mode0Register::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_mode0(&mut self, reg: &Mode0Register, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::MODE0, reg.bits(), spi) - } - - pub fn get_mode1(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::MODE1, spi)?; - let data = Mode1Register::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_mode1(&mut self, reg: &Mode1Register, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - info!("Setting register to {:#010b}", reg.bits()); - self.write_register(Register::MODE1, reg.bits(), spi) - } - - pub fn get_mode2(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::MODE2, spi)?; - let data = Mode2Register::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_mode2(&mut self, reg: &Mode2Register, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::MODE2, reg.bits(), spi) - } - - pub fn get_inpmux(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::INPMUX, spi)?; - let data = InpMuxRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_inpmux(&mut self, reg: &InpMuxRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::INPMUX, reg.bits(), spi) - } - - pub fn get_ofcal(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bytes = self.read_multiple_registers(Register::OFCAL0, 3, spi)?; // [OFCAL0, OFCAL1, OFCAL2] - let res = (bytes[2] as u32) << 16 | (bytes[1] as u32) << 8 | (bytes[0] as u32); - Ok(res) - } - - pub fn set_ofcal(&mut self, ofcal: u32, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - // Will not panic as & 0xFF ensures values are u8 - let res: [u8; 3] = [ - u8::try_from(ofcal & 0xFF).unwrap(), - u8::try_from((ofcal >> 8) & 0xFF).unwrap(), - u8::try_from((ofcal >> 16) & 0xFF).unwrap(), - ]; - self.write_multiple_registers(Register::OFCAL0, &res, spi) - } - - pub fn get_fscal(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bytes = self.read_multiple_registers(Register::FSCAL0, 3, spi)?; // [FSCAL0, FSCAL1, FSCAL2] - let res = (bytes[2] as u32) << 16 | (bytes[1] as u32) << 8 | (bytes[0] as u32); - Ok(res) - } - - pub fn set_fscal(&mut self, fscal: u32, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - // Will not panic as & 0xFF ensures values are u8 - let res: [u8; 3] = [ - u8::try_from(fscal & 0xFF).unwrap(), - u8::try_from((fscal >> 8) & 0xFF).unwrap(), - u8::try_from((fscal >> 16) & 0xFF).unwrap(), - ]; - self.write_multiple_registers(Register::FSCAL0, &res, spi) - } - - pub fn get_idacmux(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::IDACMUX, spi)?; - let data = IdacMuxRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_idacmux(&mut self, reg: &IdacMuxRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::IDACMUX, reg.bits(), spi) - } - - pub fn get_idacmag(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::IDACMAG, spi)?; - let data = IdacMagRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_idacmag(&mut self, reg: &IdacMagRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::IDACMAG, reg.bits(), spi) - } - - pub fn get_refmux(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::REFMUX, spi)?; - let data = RefMuxRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_refmux(&mut self, reg: &RefMuxRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::REFMUX, reg.bits(), spi) - } - - pub fn get_tdacp(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::TDACP, spi)?; - let data = TdacpRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_tdacp(&mut self, reg: &TdacpRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::TDACP, reg.bits(), spi) - } - - pub fn get_tdacn(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::TDACN, spi)?; - let data = TdacnRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_tdacn(&mut self, reg: &TdacnRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::TDACN, reg.bits(), spi) - } - - pub fn get_gpiocon(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::GPIOCON, spi)?; - let data = GpioConRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_gpiocon(&mut self, reg: &GpioConRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::GPIOCON, reg.bits(), spi) - } - - pub fn get_gpiodir(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::GPIODIR, spi)?; - let data = GpioDirRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_gpiodir(&mut self, reg: &GpioDirRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::GPIODIR, reg.bits(), spi) - } - - pub fn get_gpiodat(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::GPIODAT, spi)?; - let data = GpioDatRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_gpiodat(&mut self, reg: &GpioDatRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::GPIODAT, reg.bits(), spi) - } - - pub fn get_adc2cfg(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::ADC2CFG, spi)?; - let data = Adc2CfgRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_adc2cfg(&mut self, reg: &Adc2CfgRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::ADC2CFG, reg.bits(), spi) - } - - pub fn get_adc2mux(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bits = self.read_register(Register::ADC2MUX, spi)?; - let data = Adc2MuxRegister::from_bits(bits); - match data { - Some(reg) => Ok(reg), - None => Err(ADS126xError::InvalidInputData), - } - } - - pub fn set_adc2mux(&mut self, reg: &Adc2MuxRegister, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - self.write_register(Register::ADC2MUX, reg.bits(), spi) - } - - pub fn get_adc2ofc(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bytes = self.read_multiple_registers(Register::ADC2OFC0, 2, spi)?; // [ADC2OFC0, ADC2OFC1] - let res = (bytes[1] as u16) << 8 | (bytes[0] as u16); - Ok(res) - } - - pub fn set_adc2ofc(&mut self, ofc2: u16, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - // Will not panic as & 0xFF ensures values are u8 - let res: [u8; 2] = [ - u8::try_from(ofc2 & 0xFF).unwrap(), - u8::try_from((ofc2 >> 8) & 0xFF).unwrap(), - ]; - self.write_multiple_registers(Register::ADC2OFC0, &res, spi) - } - - pub fn get_adc2fsc(&mut self, spi: &mut SPI) -> Result - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - let bytes = self.read_multiple_registers(Register::ADC2FSC0, 2, spi)?; // [ADC2FSC0, ADC2FSC1] - let res = (bytes[1] as u16) << 8 | (bytes[0] as u16); - Ok(res) - } - - pub fn set_adc2fsc(&mut self, fsc2: u32, spi: &mut SPI) -> Result<()> - where - SPI: embedded_hal::blocking::spi::Write + embedded_hal::blocking::spi::Transfer, - { - // Will not panic as & 0xFF ensures values are u8 - let res: [u8; 2] = [ - u8::try_from(fsc2 & 0xFF).unwrap(), - u8::try_from((fsc2 >> 8) & 0xFF).unwrap(), - ]; - self.write_multiple_registers(Register::ADC2FSC0, &res, spi) - } -} diff --git a/crates/ads126x/src/register.rs b/crates/ads126x/src/register.rs deleted file mode 100644 index 23f52ae..0000000 --- a/crates/ads126x/src/register.rs +++ /dev/null @@ -1,887 +0,0 @@ -mod enums; - -use bitflags::bitflags; -pub use enums::*; - -#[repr(u8)] -pub enum Register { - ID = 0x00, - POWER = 0x01, - INTERFACE = 0x02, - MODE0 = 0x03, - MODE1 = 0x04, - MODE2 = 0x05, - INPMUX = 0x06, - OFCAL0 = 0x07, - OFCAL1 = 0x08, - OFCAL2 = 0x09, - FSCAL0 = 0x0A, - FSCAL1 = 0x0B, - FSCAL2 = 0x0C, - IDACMUX = 0x0D, - IDACMAG = 0x0E, - REFMUX = 0x0F, - TDACP = 0x10, - TDACN = 0x11, - GPIOCON = 0x12, - GPIODIR = 0x13, - GPIODAT = 0x14, - ADC2CFG = 0x15, - ADC2MUX = 0x16, - ADC2OFC0 = 0x17, - ADC2OFC1 = 0x18, - ADC2FSC0 = 0x19, - ADC2FSC1 = 0x1A, -} - -bitflags! { - pub struct StatusRegister: u8 { - const ADC2 = 0b1000_0000; - const ADC1 = 0b0100_0000; - const EXTCLK = 0b0010_0000; - const REF_ALM = 0b0001_0000; - const PGAL_ALM = 0b0000_1000; - const PGAH_ALM = 0b0000_0100; - const PGAD_ALM = 0b0000_0010; - const RESET = 0b0000_0001; - } -} - -impl StatusRegister { - pub fn get_adc1_new(&self) -> bool { - self.contains(StatusRegister::ADC1) - } - pub fn get_adc2_new(&self) -> bool { - self.contains(StatusRegister::ADC2) - } - pub fn get_extclk(&self) -> bool { - self.contains(StatusRegister::EXTCLK) - } - pub fn get_ref_alarm(&self) -> bool { - self.contains(StatusRegister::REF_ALM) - } - pub fn get_pga_low_alarm(&self) -> bool { - self.contains(StatusRegister::PGAL_ALM) - } - pub fn get_pga_high_alarm(&self) -> bool { - self.contains(StatusRegister::PGAH_ALM) - } - pub fn get_pga_diff_alarm(&self) -> bool { - self.contains(StatusRegister::PGAD_ALM) - } - /// The user needs to clear this byte from the Power register. - pub fn get_reset(&self) -> bool { - self.contains(StatusRegister::RESET) - } -} - -bitflags! { - pub struct IdRegister: u8 { - const _ = !0; // Source may set any bits - } -} - -impl IdRegister { - pub fn get_rev_id(&self) -> u8 { - self.bits() & 0b0001_1111 - } - - pub fn get_dev_id(&self) -> DevId { - match (self.bits() & 0b1110_0000) >> 5 { - 0b000 => DevId::ADS1262, - 0b001 => DevId::ADS1263, - - _ => panic!("Device ID must be 0b000 or 0b001."), - } - } -} - -bitflags! { - pub struct PowerRegister: u8 { - const INTREF = 0b0000_0001; - const VBIAS = 0b0000_0010; - const RESET = 0b0001_0000; - } -} - -impl PowerRegister { - pub fn default() -> Self { - PowerRegister::from_bits_truncate(0b0001_0001) - } - - pub fn set_vbias(&mut self, vbias: bool) { - if vbias { - self.insert(PowerRegister::VBIAS); - } else { - self.remove(PowerRegister::VBIAS); - } - } - - pub fn set_intref(&mut self, intref: bool) { - if intref { - self.insert(PowerRegister::INTREF); - } else { - self.remove(PowerRegister::INTREF); - } - } - - pub fn get_reset(&self) -> bool { - self.contains(PowerRegister::RESET) - } - - // must be cleared if set to detect further resets. - pub fn clear_reset(&mut self) { - self.remove(PowerRegister::RESET); - } -} - -bitflags! { - /// WARNING: If CRC is 0b11 set by ADC, it will reflect as CRC enabled not reserved. - /// CRC only accounts for 0b00 disabled and 0b01 enabled. - pub struct InterfaceRegister: u8 { - const CRC = 0b0000_0001; - const STATUS = 0b0000_0100; - const TIMEOUT = 0b0000_1000; - } -} - -impl InterfaceRegister { - pub fn default() -> Self { - InterfaceRegister::from_bits_truncate(0b0000_0101) - } - - pub fn get_crc(&self) -> CrcMode { - match self.bits() & 0b0000_0001 { - 0b00 => CrcMode::Disabled, - 0b01 => CrcMode::Checksum, - 0b10 => CrcMode::CRC, - _ => unreachable!(), - } - } - - pub fn set_crc(&mut self, crc: CrcMode) { - let bits = crc as u8; - self.insert(InterfaceRegister::from_bits_retain(bits)); - } - - pub fn get_status(&self) -> bool { - self.contains(InterfaceRegister::STATUS) - } - - pub fn set_status(&mut self, status: bool) { - if status { - self.insert(InterfaceRegister::STATUS); - } else { - self.remove(InterfaceRegister::STATUS); - } - } - - pub fn get_timeout(&self) -> bool { - self.contains(InterfaceRegister::TIMEOUT) - } - - pub fn set_timeout(&mut self, timeout: bool) { - if timeout { - self.insert(InterfaceRegister::TIMEOUT); - } else { - self.remove(InterfaceRegister::TIMEOUT); - } - } -} - -bitflags! { - pub struct Mode0Register: u8 { - const RUNMODE = 0b0100_0000; - const REFREV = 0b1000_0000; - - const _ = !0; // Source may set any bits - } -} - -impl Mode0Register { - pub fn default() -> Self { - Mode0Register::from_bits_truncate(0b0000_0000) - } - - pub fn get_delay(&self) -> ConversionDelay { - match self.bits() & 0b0000_1111 { - 0b0000 => ConversionDelay::DNone, - 0b0001 => ConversionDelay::D8_7us, - 0b0010 => ConversionDelay::D17us, - 0b0011 => ConversionDelay::D35us, - 0b0100 => ConversionDelay::D69us, - 0b0101 => ConversionDelay::D139us, - 0b0110 => ConversionDelay::D278us, - 0b0111 => ConversionDelay::D555us, - 0b1000 => ConversionDelay::D1_1ms, - 0b1001 => ConversionDelay::D2_2ms, - 0b1010 => ConversionDelay::D4_4ms, - 0b1011 => ConversionDelay::D8_8ms, - - 0b1100..=0b1111 => panic!("Unknown conversion delay"), - _ => unreachable!(), - } - } - - pub fn set_delay(&mut self, delay: ConversionDelay) { - let bits = delay as u8; - self.insert(Mode0Register::from_bits_retain(bits)); - } - - pub fn get_chop(&self) -> ChopMode { - match (self.bits() & 0b0011_0000) >> 4 { - 0b00 => ChopMode::Disabled, - 0b01 => ChopMode::InChopEnabled, - 0b10 => ChopMode::IdacEnabled, - 0b11 => ChopMode::InChopAndIdacEnabled, - - _ => unreachable!(), - } - } - - pub fn set_chop(&mut self, chop: ChopMode) { - let bits = chop as u8; - self.insert(Mode0Register::from_bits_retain(bits << 4)); - } -} - -bitflags! { - pub struct Mode1Register: u8 { - const SBPOL = 0b0000_1000; - const SBADC = 0b0001_0000; - - const _ = !0; // Source may set any bits - } -} - -impl Mode1Register { - pub fn default() -> Self { - Mode1Register::from_bits_truncate(0b1000_0000) - } - - pub fn get_sbmag(&self) -> SensorBiasMagnitude { - match self.bits() & 0b0000_0111 { - 0b000 => SensorBiasMagnitude::BNone, - 0b001 => SensorBiasMagnitude::B0_5uA, - 0b010 => SensorBiasMagnitude::B2uA, - 0b011 => SensorBiasMagnitude::B10uA, - 0b100 => SensorBiasMagnitude::B50uA, - 0b101 => SensorBiasMagnitude::B200uA, - 0b110 => SensorBiasMagnitude::R10MOhm, - - 0b111 => panic!("Reserved SBMAG"), - _ => unreachable!(), - } - } - - pub fn set_sbmag(&mut self, sbmag: SensorBiasMagnitude) { - let bits = sbmag as u8; - self.insert(Mode1Register::from_bits_retain(bits)); - } - - pub fn get_filter(&self) -> DigitalFilter { - match (self.bits() & 0b1110_0000) >> 5 { - 0b000 => DigitalFilter::Sinc1, - 0b001 => DigitalFilter::Sinc2, - 0b010 => DigitalFilter::Sinc3, - 0b011 => DigitalFilter::Sinc4, - 0b100 => DigitalFilter::FIR, - - 0b101..=0b111 => panic!("Reserved filter"), - _ => unreachable!(), - } - } - - pub fn set_filter(&mut self, filter: DigitalFilter) { - let bits = filter as u8; - self.insert(Mode1Register::from_bits_retain(bits << 5)); - } -} - -bitflags! { - pub struct Mode2Register: u8 { - const BYPASS = 0b1000_0000; - - const _ = !0; // Source may set any bits - } -} - -impl Mode2Register { - pub fn default() -> Self { - Mode2Register::from_bits_truncate(0b0000_0100) - } - - pub fn get_dr(&self) -> DataRate { - match self.bits() & 0b0000_1111 { - 0b0000 => DataRate::SPS2_5, - 0b0001 => DataRate::SPS5, - 0b0010 => DataRate::SPS10, - 0b0011 => DataRate::SPS16_6, - 0b0100 => DataRate::SPS20, - 0b0101 => DataRate::SPS50, - 0b0110 => DataRate::SPS60, - 0b0111 => DataRate::SPS100, - 0b1000 => DataRate::SPS400, - 0b1001 => DataRate::SPS1200, - 0b1010 => DataRate::SPS2400, - 0b1011 => DataRate::SPS4800, - 0b1100 => DataRate::SPS7200, - 0b1101 => DataRate::SPS14400, - 0b1110 => DataRate::SPS19200, - 0b1111 => DataRate::SPS38400, - - _ => unreachable!(), - } - } - - pub fn set_dr(&mut self, rate: DataRate) { - let bits = rate as u8; - self.insert(Mode2Register::from_bits_retain(bits)); - } - - pub fn get_gain(&self) -> PGAGain { - match (self.bits() & 0b0111_0000) >> 4 { - 0b000 => PGAGain::VV1, - 0b001 => PGAGain::VV2, - 0b010 => PGAGain::VV4, - 0b011 => PGAGain::VV8, - 0b100 => PGAGain::VV16, - 0b101 => PGAGain::VV32, - - 0b110 | 0b111 => panic!("Reserved gain"), - _ => unreachable!(), - } - } - - pub fn set_gain(&mut self, gain: PGAGain) { - let bits = gain as u8; - self.insert(Mode2Register::from_bits_retain(bits << 4)); - } -} - -bitflags! { - pub struct InpMuxRegister: u8 { - const _ = !0; // Source may set any bits - } -} - -impl InpMuxRegister { - pub fn default() -> Self { - InpMuxRegister::from_bits_truncate(0b0000_0001) - } - - pub fn get_muxn(&self) -> NegativeInpMux { - match self.bits() & 0b0000_1111 { - 0b0000 => NegativeInpMux::AIN0, - 0b0001 => NegativeInpMux::AIN1, - 0b0010 => NegativeInpMux::AIN2, - 0b0011 => NegativeInpMux::AIN3, - 0b0100 => NegativeInpMux::AIN4, - 0b0101 => NegativeInpMux::AIN5, - 0b0110 => NegativeInpMux::AIN6, - 0b0111 => NegativeInpMux::AIN7, - 0b1000 => NegativeInpMux::AIN8, - 0b1001 => NegativeInpMux::AIN9, - 0b1010 => NegativeInpMux::AINCOM, - 0b1011 => NegativeInpMux::TempSensMonNeg, - 0b1100 => NegativeInpMux::AnlgPwrSupMonNeg, - 0b1101 => NegativeInpMux::DgtlPwrSubMonNeg, - 0b1110 => NegativeInpMux::TDACTestSignalNeg, - 0b1111 => NegativeInpMux::Float, - - _ => unreachable!(), - } - } - - pub fn set_muxn(&mut self, muxn: NegativeInpMux) { - let bits = muxn as u8; - self.insert(InpMuxRegister::from_bits_retain(bits)); - } - - pub fn get_muxp(&self) -> PositiveInpMux { - match (self.bits() & 0b1111_0000) >> 4 { - 0b0000 => PositiveInpMux::AIN0, - 0b0001 => PositiveInpMux::AIN1, - 0b0010 => PositiveInpMux::AIN2, - 0b0011 => PositiveInpMux::AIN3, - 0b0100 => PositiveInpMux::AIN4, - 0b0101 => PositiveInpMux::AIN5, - 0b0110 => PositiveInpMux::AIN6, - 0b0111 => PositiveInpMux::AIN7, - 0b1000 => PositiveInpMux::AIN8, - 0b1001 => PositiveInpMux::AIN9, - 0b1010 => PositiveInpMux::AINCOM, - 0b1011 => PositiveInpMux::TempSensMonPos, - 0b1100 => PositiveInpMux::AnlgPwrSupMonPos, - 0b1101 => PositiveInpMux::DgtlPwrSubMonPos, - 0b1110 => PositiveInpMux::TDACTestSignalPos, - 0b1111 => PositiveInpMux::Float, - - _ => unreachable!(), - } - } - - pub fn set_muxp(&mut self, muxp: PositiveInpMux) { - let bits = muxp as u8; - self.insert(InpMuxRegister::from_bits_retain(bits << 4)); - } -} - -bitflags! { - pub struct IdacMuxRegister: u8 { - const _ = !0; // Source may set any bits - } -} - -impl IdacMuxRegister { - pub fn default() -> Self { - IdacMuxRegister::from_bits_truncate(0b1011_1011) - } - - pub fn get_mux1(&self) -> IdacOutMux { - match self.bits() & 0b0000_1111 { - 0b0000 => IdacOutMux::AIN0, - 0b0001 => IdacOutMux::AIN1, - 0b0010 => IdacOutMux::AIN2, - 0b0011 => IdacOutMux::AIN3, - 0b0100 => IdacOutMux::AIN4, - 0b0101 => IdacOutMux::AIN5, - 0b0110 => IdacOutMux::AIN6, - 0b0111 => IdacOutMux::AIN7, - 0b1000 => IdacOutMux::AIN8, - 0b1001 => IdacOutMux::AIN9, - 0b1010 => IdacOutMux::AINCOM, - 0b1011 => IdacOutMux::NoConnection, - - 0b1100..=0b1111 => panic!("Reserved IDAC Output Multiplexer"), - _ => unreachable!(), - } - } - - pub fn set_mux1(&mut self, mux1: IdacOutMux) { - let bits = mux1 as u8; - self.insert(IdacMuxRegister::from_bits_retain(bits)); - } - - pub fn get_mux2(&self) -> IdacOutMux { - match (self.bits() & 0b1111_0000) >> 4 { - 0b0000 => IdacOutMux::AIN0, - 0b0001 => IdacOutMux::AIN1, - 0b0010 => IdacOutMux::AIN2, - 0b0011 => IdacOutMux::AIN3, - 0b0100 => IdacOutMux::AIN4, - 0b0101 => IdacOutMux::AIN5, - 0b0110 => IdacOutMux::AIN6, - 0b0111 => IdacOutMux::AIN7, - 0b1000 => IdacOutMux::AIN8, - 0b1001 => IdacOutMux::AIN9, - 0b1010 => IdacOutMux::AINCOM, - 0b1011 => IdacOutMux::NoConnection, - - 0b1100..=0b1111 => panic!("Reserved IDAC Output Multiplexer"), - _ => unreachable!(), - } - } - - pub fn set_mux2(&mut self, mux2: IdacOutMux) { - let bits = mux2 as u8; - self.insert(IdacMuxRegister::from_bits_retain(bits << 4)); - } -} - -bitflags! { - pub struct IdacMagRegister: u8 { - const _ = !0; // Source may set any bits - } -} - -impl IdacMagRegister { - pub fn default() -> Self { - IdacMagRegister::from_bits_truncate(0b0000_0000) - } - - pub fn get_mag1(&self) -> IdacCurMag { - match self.bits() & 0b0000_1111 { - 0b0000 => IdacCurMag::I50uA, - 0b0001 => IdacCurMag::I100uA, - 0b0010 => IdacCurMag::I250uA, - 0b0011 => IdacCurMag::I500uA, - 0b0100 => IdacCurMag::I750uA, - 0b0101 => IdacCurMag::I1000uA, - 0b0110 => IdacCurMag::I1500uA, - 0b0111 => IdacCurMag::I2000uA, - 0b1000 => IdacCurMag::I2500uA, - 0b1001 => IdacCurMag::I3000uA, - - 0b1010..=0b1111 => panic!("Reserved IDAC Magnitude Multiplexer"), - _ => unreachable!(), - } - } - - pub fn set_mag1(&mut self, mag1: IdacCurMag) { - let bits = mag1 as u8; - self.insert(IdacMagRegister::from_bits_retain(bits)); - } - - pub fn get_mag2(&self) -> IdacCurMag { - match (self.bits() & 0b1111_0000) >> 4 { - 0b0000 => IdacCurMag::I50uA, - 0b0001 => IdacCurMag::I100uA, - 0b0010 => IdacCurMag::I250uA, - 0b0011 => IdacCurMag::I500uA, - 0b0100 => IdacCurMag::I750uA, - 0b0101 => IdacCurMag::I1000uA, - 0b0110 => IdacCurMag::I1500uA, - 0b0111 => IdacCurMag::I2000uA, - 0b1000 => IdacCurMag::I2500uA, - 0b1001 => IdacCurMag::I3000uA, - - 0b1010..=0b1111 => panic!("Reserved IDAC Output Multiplexer"), - _ => unreachable!(), - } - } - - pub fn set_mag2(&mut self, mag2: IdacCurMag) { - let bits = mag2 as u8; - self.insert(IdacMagRegister::from_bits_retain(bits << 4)); - } -} - -bitflags! { - pub struct RefMuxRegister: u8 { - const _ = 0b0011_1111; - } -} - -impl RefMuxRegister { - pub fn default() -> Self { - RefMuxRegister::from_bits_truncate(0b0000_0000) - } - - pub fn get_rmuxn(&self) -> RefNegativeInp { - match self.bits() & 0b0000_0111 { - 0b000 => RefNegativeInp::Int2_5VRef, - 0b001 => RefNegativeInp::ExtAIN1, - 0b010 => RefNegativeInp::ExtAIN3, - 0b011 => RefNegativeInp::ExtAIN5, - 0b100 => RefNegativeInp::IntAnlgSup, - - 0b101..=0b111 => panic!("Reserved Reference Negative Input"), - _ => unreachable!(), - } - } - - pub fn set_rmuxn(&mut self, rmuxn: RefNegativeInp) { - let bits = rmuxn as u8; - self.insert(RefMuxRegister::from_bits_retain(bits)); - } - - pub fn get_rmuxp(&self) -> RefPositiveInp { - match (self.bits() & 0b0011_1000) >> 3 { - 0b000 => RefPositiveInp::Int2_5VRef, - 0b001 => RefPositiveInp::ExtAIN0, - 0b010 => RefPositiveInp::ExtAIN2, - 0b011 => RefPositiveInp::ExtAIN4, - 0b100 => RefPositiveInp::IntAnlgSup, - - 0b101..=0b111 => panic!("Reserved Reference Positive Input"), - _ => unreachable!(), - } - } - - pub fn set_rmuxp(&mut self, rmuxp: RefPositiveInp) { - let bits = rmuxp as u8; - self.insert(RefMuxRegister::from_bits_retain(bits << 3)); - } -} - -bitflags! { - pub struct TdacpRegister: u8 { - const OUTP = 0b1000_0000; - - const _ = 0b1001_1111; - } -} - -impl TdacpRegister { - // there is no defined default values in the datasheet so just zeros. - pub fn default() -> Self { - TdacpRegister::from_bits_truncate(0b0000_0000) - } - - pub fn get_magp(&self) -> TdacOutMag { - match self.bits() & 0b0001_1111 { - 0b01001 => TdacOutMag::V4_5, - 0b01000 => TdacOutMag::V3_5, - 0b00111 => TdacOutMag::V3, - 0b00110 => TdacOutMag::V2_75, - 0b00101 => TdacOutMag::V2_625, - 0b00100 => TdacOutMag::V2_5625, - 0b00011 => TdacOutMag::V2_53125, - 0b00010 => TdacOutMag::V2_515625, - 0b00001 => TdacOutMag::V2_5078125, - 0b00000 => TdacOutMag::V2_5, - 0b10001 => TdacOutMag::V2_4921875, - 0b10010 => TdacOutMag::V2_484375, - 0b10011 => TdacOutMag::V2_46875, - 0b10100 => TdacOutMag::V2_4375, - 0b10101 => TdacOutMag::V2_375, - 0b10110 => TdacOutMag::V2_25, - 0b10111 => TdacOutMag::V2, - 0b11000 => TdacOutMag::V1_5, - 0b11001 => TdacOutMag::V0_5, - - 0b01010..=0b10000 | 0b11010..=0b11111 => panic!("Reserved MAGP"), - _ => unreachable!(), - } - } - - pub fn set_magp(&mut self, magp: TdacOutMag) { - let bits = magp as u8; - self.insert(TdacpRegister::from_bits_retain(bits)); - } -} - -bitflags! { - pub struct TdacnRegister: u8 { - const OUTN = 0b1000_0000; - - const _ = 0b1001_1111; - } -} - -impl TdacnRegister { - // there is no defined default values in the datasheet so just zeros. - pub fn default() -> Self { - TdacnRegister::from_bits_truncate(0b0000_0000) - } - - pub fn get_magn(&self) -> TdacOutMag { - match self.bits() & 0b0001_1111 { - 0b01001 => TdacOutMag::V4_5, - 0b01000 => TdacOutMag::V3_5, - 0b00111 => TdacOutMag::V3, - 0b00110 => TdacOutMag::V2_75, - 0b00101 => TdacOutMag::V2_625, - 0b00100 => TdacOutMag::V2_5625, - 0b00011 => TdacOutMag::V2_53125, - 0b00010 => TdacOutMag::V2_515625, - 0b00001 => TdacOutMag::V2_5078125, - 0b00000 => TdacOutMag::V2_5, - 0b10001 => TdacOutMag::V2_4921875, - 0b10010 => TdacOutMag::V2_484375, - 0b10011 => TdacOutMag::V2_46875, - 0b10100 => TdacOutMag::V2_4375, - 0b10101 => TdacOutMag::V2_375, - 0b10110 => TdacOutMag::V2_25, - 0b10111 => TdacOutMag::V2, - 0b11000 => TdacOutMag::V1_5, - 0b11001 => TdacOutMag::V0_5, - - 0b01010..=0b10000 | 0b11010..=0b11111 => panic!("Reserved MAGN"), - _ => unreachable!(), - } - } - - pub fn set_magn(&mut self, magn: TdacOutMag) { - let bits = magn as u8; - self.insert(TdacnRegister::from_bits_retain(bits)); - } -} - -bitflags! { - pub struct GpioConRegister: u8 { - const CON0 = 0b0000_0001; // GPIO[0] -> AIN3 - const CON1 = 0b0000_0010; // GPIO[1] -> AIN4 - const CON2 = 0b0000_0100; // GPIO[2] -> AIN5 - const CON3 = 0b0000_1000; // GPIO[3] -> AIN6 - const CON4 = 0b0001_0000; // GPIO[4] -> AIN7 - const CON5 = 0b0010_0000; // GPIO[5] -> AIN8 - const CON6 = 0b0100_0000; // GPIO[6] -> AIN9 - const CON7 = 0b1000_0000; // GPIO[7] -> AINCOM - } -} - -impl GpioConRegister { - pub fn default() -> Self { - GpioConRegister::from_bits_truncate(0b0000_0000) - } -} - -bitflags! { - /// Setting `DIR` to: - /// - 0 = `GPIO` is output - /// - 1 = `GPIO` is input - pub struct GpioDirRegister: u8 { - const DIR0 = 0b0000_0001; - const DIR1 = 0b0000_0010; - const DIR2 = 0b0000_0100; - const DIR3 = 0b0000_1000; - const DIR4 = 0b0001_0000; - const DIR5 = 0b0010_0000; - const DIR6 = 0b0100_0000; - const DIR7 = 0b1000_0000; - } -} - -impl GpioDirRegister { - pub fn default() -> Self { - GpioDirRegister::from_bits_truncate(0b0000_0000) - } -} - -bitflags! { - /// If `GPIO` is output, read returns 0b. - /// If `GPIO` is input, write sets `GPIO` to high (if 1) or low (if 0). - pub struct GpioDatRegister: u8 { - const DAT0 = 0b0000_0001; - const DAT1 = 0b0000_0010; - const DAT2 = 0b0000_0100; - const DAT3 = 0b0000_1000; - const DAT4 = 0b0001_0000; - const DAT5 = 0b0010_0000; - const DAT6 = 0b0100_0000; - const DAT7 = 0b1000_0000; - } -} - -impl GpioDatRegister { - // there is no defined default values in the datasheet so just zeros. - pub fn default() -> Self { - GpioDatRegister::from_bits_truncate(0b0000_0000) - } -} - -bitflags! { - pub struct Adc2CfgRegister: u8 { - const _ = !0; // Source may set any bits - } -} - -impl Adc2CfgRegister { - pub fn default() -> Self { - Adc2CfgRegister::from_bits_truncate(0b0000_0000) - } - - pub fn get_gain2(&self) -> Adc2Gain { - match self.bits() & 0b0000_0111 { - 0b000 => Adc2Gain::VV1, - 0b001 => Adc2Gain::VV2, - 0b010 => Adc2Gain::VV4, - 0b011 => Adc2Gain::VV8, - 0b100 => Adc2Gain::VV16, - 0b101 => Adc2Gain::VV32, - 0b110 => Adc2Gain::VV64, - 0b111 => Adc2Gain::VV128, - - _ => unreachable!(), - } - } - - pub fn set_gain2(&mut self, gain2: Adc2Gain) { - let bits = gain2 as u8; - self.insert(Adc2CfgRegister::from_bits_retain(bits)); - } - - pub fn get_ref2(&self) -> Adc2RefInp { - match (self.bits() & 0b0011_1000) >> 3 { - 0b000 => Adc2RefInp::Int2_5VRef, - 0b001 => Adc2RefInp::ExtAIN0_1, - 0b010 => Adc2RefInp::ExtAIN2_3, - 0b011 => Adc2RefInp::ExtAIN4_5, - 0b100 => Adc2RefInp::IntAnlgSup, - - 0b101..=0b111 => panic!("Reserved ADC2 reference input"), - _ => unreachable!(), - } - } - - pub fn set_ref2(&mut self, ref2: Adc2RefInp) { - let bits = ref2 as u8; - self.insert(Adc2CfgRegister::from_bits_retain(bits << 3)); - } - - pub fn get_dr2(&self) -> Adc2DataRate { - match (self.bits() & 0b1100_0000) >> 6 { - 0b00 => Adc2DataRate::SPS10, - 0b01 => Adc2DataRate::SPS100, - 0b10 => Adc2DataRate::SPS400, - 0b11 => Adc2DataRate::SPS800, - - _ => unreachable!(), - } - } - - pub fn set_dr2(&mut self, dr2: Adc2DataRate) { - let bits = dr2 as u8; - self.insert(Adc2CfgRegister::from_bits_retain(bits << 6)); - } -} - -bitflags! { - pub struct Adc2MuxRegister: u8 { - const _ = !0; // Source may set any bits - } -} - -impl Adc2MuxRegister { - pub fn default() -> Self { - Adc2MuxRegister::from_bits_truncate(0b0000_0001) - } - - pub fn get_muxn2(&self) -> NegativeInpMux { - match self.bits() & 0b0000_1111 { - 0b0000 => NegativeInpMux::AIN0, - 0b0001 => NegativeInpMux::AIN1, - 0b0010 => NegativeInpMux::AIN2, - 0b0011 => NegativeInpMux::AIN3, - 0b0100 => NegativeInpMux::AIN4, - 0b0101 => NegativeInpMux::AIN5, - 0b0110 => NegativeInpMux::AIN6, - 0b0111 => NegativeInpMux::AIN7, - 0b1000 => NegativeInpMux::AIN8, - 0b1001 => NegativeInpMux::AIN9, - 0b1010 => NegativeInpMux::AINCOM, - 0b1011 => NegativeInpMux::TempSensMonNeg, - 0b1100 => NegativeInpMux::AnlgPwrSupMonNeg, - 0b1101 => NegativeInpMux::DgtlPwrSubMonNeg, - 0b1110 => NegativeInpMux::TDACTestSignalNeg, - 0b1111 => NegativeInpMux::Float, - - _ => unreachable!(), - } - } - - pub fn set_muxn2(&mut self, muxn2: NegativeInpMux) { - let bits = muxn2 as u8; - self.insert(Adc2MuxRegister::from_bits_retain(bits)); - } - - pub fn get_muxp2(&self) -> PositiveInpMux { - match (self.bits() & 0b1111_0000) >> 4 { - 0b0000 => PositiveInpMux::AIN0, - 0b0001 => PositiveInpMux::AIN1, - 0b0010 => PositiveInpMux::AIN2, - 0b0011 => PositiveInpMux::AIN3, - 0b0100 => PositiveInpMux::AIN4, - 0b0101 => PositiveInpMux::AIN5, - 0b0110 => PositiveInpMux::AIN6, - 0b0111 => PositiveInpMux::AIN7, - 0b1000 => PositiveInpMux::AIN8, - 0b1001 => PositiveInpMux::AIN9, - 0b1010 => PositiveInpMux::AINCOM, - 0b1011 => PositiveInpMux::TempSensMonPos, - 0b1100 => PositiveInpMux::AnlgPwrSupMonPos, - 0b1101 => PositiveInpMux::DgtlPwrSubMonPos, - 0b1110 => PositiveInpMux::TDACTestSignalPos, - 0b1111 => PositiveInpMux::Float, - - _ => unreachable!(), - } - } - - pub fn set_muxp2(&mut self, muxp2: PositiveInpMux) { - let bits = muxp2 as u8; - self.insert(Adc2MuxRegister::from_bits_retain(bits << 4)); - } -} diff --git a/crates/ads126x/src/register/enums.rs b/crates/ads126x/src/register/enums.rs deleted file mode 100644 index ee319da..0000000 --- a/crates/ads126x/src/register/enums.rs +++ /dev/null @@ -1,271 +0,0 @@ -pub enum DevId { - ADS1262 = 0b000, - ADS1263 = 0b001, -} - -/// Conversion delays follow the pattern `D`. -/// - `len` is the length of time where _ is a substitute for a decimal point. -/// - `units` are the units of time where us is microseconds and ms is milliseconds. -/// -/// D8_7us = delay of 8.7 microseconds. D8_8ms = delay of 8.8 milliseconds. -#[repr(u8)] -pub enum ConversionDelay { - DNone = 0b0000, - D8_7us = 0b0001, - D17us = 0b0010, - D35us = 0b0011, - D69us = 0b0100, - D139us = 0b0101, - D278us = 0b0110, - D555us = 0b0111, - D1_1ms = 0b1000, - D2_2ms = 0b1001, - D4_4ms = 0b1010, - D8_8ms = 0b1011, -} - -impl ConversionDelay { - /// Returns the delay in nanoseconds. - pub fn delay(&self) -> u32 { - match self { - Self::DNone => 0, - Self::D8_7us => 8_700, - Self::D17us => 17_000, - Self::D35us => 35_000, - Self::D69us => 69_000, - Self::D139us => 139_000, - Self::D278us => 278_000, - Self::D555us => 555_000, - Self::D1_1ms => 1_100_000, - Self::D2_2ms => 2_200_000, - Self::D4_4ms => 4_400_000, - Self::D8_8ms => 8_800_000, - } - } -} - -#[repr(u8)] -pub enum ChopMode { - Disabled = 0b00, - InChopEnabled = 0b01, - IdacEnabled = 0b10, - InChopAndIdacEnabled = 0b11, -} - -/// SBMAGs follow the pattern `B` or `R`. -/// - `mag` is the magnitude of current or resistance where _ is a substitute for a decimal point. -/// - `units` are the units of current or resistance where uA is microamperes and MOhm is megaohms. -/// -/// B0_5uA = 0.5 microamps of current. R10MOhm = resistance of 10 megaohms. -#[repr(u8)] -pub enum SensorBiasMagnitude { - BNone = 0b000, - B0_5uA = 0b001, - B2uA = 0b010, - B10uA = 0b011, - B50uA = 0b100, - B200uA = 0b101, - R10MOhm = 0b110, -} - -#[repr(u8)] -pub enum CrcMode { - Disabled = 0b00, - Checksum = 0b01, - CRC = 0b10, -} - -#[repr(u8)] -pub enum DigitalFilter { - Sinc1 = 0b000, - Sinc2 = 0b001, - Sinc3 = 0b010, - Sinc4 = 0b011, - FIR = 0b100, -} - -/// Data rates follow the pattern `SPS`. -/// - `num` is the SPS rate where _ is a substitute for a decimal point. -/// -/// SPS2_5 = 2.5 SPS. -#[repr(u8)] -pub enum DataRate { - SPS2_5 = 0b0000, - SPS5 = 0b0001, - SPS10 = 0b0010, - SPS16_6 = 0b0011, // 16.6666... = 50/3 - SPS20 = 0b0100, - SPS50 = 0b0101, - SPS60 = 0b0110, - SPS100 = 0b0111, - SPS400 = 0b1000, - SPS1200 = 0b1001, - SPS2400 = 0b1010, - SPS4800 = 0b1011, - SPS7200 = 0b1100, - SPS14400 = 0b1101, - SPS19200 = 0b1110, - SPS38400 = 0b1111, -} - -#[repr(u8)] -pub enum PGAGain { - VV1 = 0b000, - VV2 = 0b001, - VV4 = 0b010, - VV8 = 0b011, - VV16 = 0b100, - VV32 = 0b101, -} - -#[repr(u8)] -#[derive(PartialEq)] -pub enum NegativeInpMux { - AIN0 = 0b0000, - AIN1 = 0b0001, - AIN2 = 0b0010, - AIN3 = 0b0011, - AIN4 = 0b0100, - AIN5 = 0b0101, - AIN6 = 0b0110, - AIN7 = 0b0111, - AIN8 = 0b1000, - AIN9 = 0b1001, - AINCOM = 0b1010, - TempSensMonNeg = 0b1011, - AnlgPwrSupMonNeg = 0b1100, - DgtlPwrSubMonNeg = 0b1101, - TDACTestSignalNeg = 0b1110, - Float = 0b1111, -} - -#[repr(u8)] -#[derive(PartialEq)] -pub enum PositiveInpMux { - AIN0 = 0b0000, - AIN1 = 0b0001, - AIN2 = 0b0010, - AIN3 = 0b0011, - AIN4 = 0b0100, - AIN5 = 0b0101, - AIN6 = 0b0110, - AIN7 = 0b0111, - AIN8 = 0b1000, - AIN9 = 0b1001, - AINCOM = 0b1010, - TempSensMonPos = 0b1011, - AnlgPwrSupMonPos = 0b1100, - DgtlPwrSubMonPos = 0b1101, - TDACTestSignalPos = 0b1110, - Float = 0b1111, -} - -#[repr(u8)] -pub enum IdacOutMux { - AIN0 = 0b0000, - AIN1 = 0b0001, - AIN2 = 0b0010, - AIN3 = 0b0011, - AIN4 = 0b0100, - AIN5 = 0b0101, - AIN6 = 0b0110, - AIN7 = 0b0111, - AIN8 = 0b1000, - AIN9 = 0b1001, - AINCOM = 0b1010, - NoConnection = 0b1011, -} - -/// Current magnitudes follow the pattern `I`. -/// - `mag` is the magnitude of current. -/// - `units` are uA meaning microamperes. -/// -/// I50uA = 50 microamps of current. -#[repr(u8)] -pub enum IdacCurMag { - I50uA = 0b0000, - I100uA = 0b0001, - I250uA = 0b0010, - I500uA = 0b0011, - I750uA = 0b0100, - I1000uA = 0b0101, - I1500uA = 0b0110, - I2000uA = 0b0111, - I2500uA = 0b1000, - I3000uA = 0b1001, -} - -#[repr(u8)] -pub enum RefNegativeInp { - Int2_5VRef = 0b000, - ExtAIN1 = 0b001, - ExtAIN3 = 0b010, - ExtAIN5 = 0b011, - IntAnlgSup = 0b100, -} - -#[repr(u8)] -pub enum RefPositiveInp { - Int2_5VRef = 0b000, - ExtAIN0 = 0b001, - ExtAIN2 = 0b010, - ExtAIN4 = 0b011, - IntAnlgSup = 0b100, -} - -/// Voltages are with respect to V_AVSS. -/// Output magnitudes follow the pattern `V`. -/// - `num` is the output magnitude in volts where _ is a substitute for a decimal point. -/// -/// V4_5 = 4.5 V. -#[repr(u8)] -pub enum TdacOutMag { - V4_5 = 0b01001, - V3_5 = 0b01000, - V3 = 0b00111, - V2_75 = 0b00110, - V2_625 = 0b00101, - V2_5625 = 0b00100, - V2_53125 = 0b00011, - V2_515625 = 0b00010, - V2_5078125 = 0b00001, - V2_5 = 0b00000, - V2_4921875 = 0b10001, - V2_484375 = 0b10010, - V2_46875 = 0b10011, - V2_4375 = 0b10100, - V2_375 = 0b10101, - V2_25 = 0b10110, - V2 = 0b10111, - V1_5 = 0b11000, - V0_5 = 0b11001, -} - -#[repr(u8)] -pub enum Adc2Gain { - VV1 = 0b000, - VV2 = 0b001, - VV4 = 0b010, - VV8 = 0b011, - VV16 = 0b100, - VV32 = 0b101, - VV64 = 0b110, - VV128 = 0b111, -} - -#[repr(u8)] -pub enum Adc2RefInp { - Int2_5VRef = 0b000, - ExtAIN0_1 = 0b001, - ExtAIN2_3 = 0b010, - ExtAIN4_5 = 0b011, - IntAnlgSup = 0b100, -} - -#[repr(u8)] -pub enum Adc2DataRate { - SPS10 = 0b00, - SPS100 = 0b01, - SPS400 = 0b10, - SPS800 = 0b11, -} diff --git a/crates/common-arm/Cargo.toml b/crates/common-arm/Cargo.toml index c629dc4..d55c552 100644 --- a/crates/common-arm/Cargo.toml +++ b/crates/common-arm/Cargo.toml @@ -17,6 +17,7 @@ embedded-hal = {workspace = true} nb = {workspace = true} stm32h7xx-hal = { workspace = true } panic-probe = { workspace = true } +ads126x = { workspace = true } [dev-dependencies] defmt-test = { workspace = true } diff --git a/crates/common-arm/src/error/hydra_error.rs b/crates/common-arm/src/error/hydra_error.rs index 85d022b..11599d7 100644 --- a/crates/common-arm/src/error/hydra_error.rs +++ b/crates/common-arm/src/error/hydra_error.rs @@ -1,4 +1,5 @@ // use atsamd_hal::dmac; +use ads126x::error::ADS126xError; use core::convert::Infallible; use defmt::{write, Format}; use derive_more::From; @@ -23,6 +24,7 @@ pub enum HydraErrorType { MavlinkError(messages::mavlink::error::MessageWriteError), MavlinkReadError(messages::mavlink::error::MessageReadError), NbError(NbError), + ADS126xError(ADS126xError), } impl defmt::Format for HydraErrorType { @@ -49,6 +51,9 @@ impl defmt::Format for HydraErrorType { HydraErrorType::NbError(_) => { write!(f, "Nb error!"); } + HydraErrorType::ADS126xError(_) => { + write!(f, "ADS126x error!"); + } } } } diff --git a/crates/thermocouple-converter/src/lib.rs b/crates/thermocouple-converter/src/lib.rs index f2f5889..98d134b 100644 --- a/crates/thermocouple-converter/src/lib.rs +++ b/crates/thermocouple-converter/src/lib.rs @@ -1,117 +1,133 @@ -#![no_std] //! -//! This crate contains code to convert type k thermocouple voltages to temperatures. +//! This crate contains code to convert type K thermocouple voltages to temperatures. //! -///Ranges where polynomial coefficients are for -pub const ENERGY_RANGES: [[f64; 2]; 3] = [[-5.891, 0.0], [0.0, 20.644], [20.644, 54.886]]; +#![no_std] -///Type K thermocouple coefficients for polynomial calculation +/// Type K thermocouple coefficients for polynomial voltage to temperature conversion. /// See https://www.eevblog.com/forum/metrology/a-dive-into-k-type-thermocouple-maths/ pub const TYPE_K_COEF: [[f64; 10]; 3] = [ - [ - 0.0, - 25.173462, - -1.1662878, - -1.0833638, - -0.89773540, - -0.37342377, - -0.086632643, - -0.010450598, - -0.00051920577, - 0.0, + [ // Coefficients for -5.891 <= voltage <= 0.0 + 0.0000000E+00, + 2.5173462E+01, + -1.1662878E+00, + -1.0833638E+00, + -8.9773540E-01, + -3.7342377E-01, + -8.6632643E-02, + -1.0450598E-02, + -5.1920577E-04, + 0.0000000E+00, ], - [ - 0.0, - 25.08355, - 0.07860106, - -0.2503131, - 0.08315270, - -0.01228034, - 0.0009804036, - -0.00004413030, - 0.000001057734, - -0.00000001052755, + [ // Coefficients for 0.0 <= voltage <= 20.644 + 0.000000E+00, + 2.508355E+01, + 7.860106E-02, + -2.503131E-01, + 8.315270E-02, + -1.228034E-02, + 9.804036E-04, + -4.413030E-05, + 1.057734E-06, + -1.052755E-08, ], - [ - -131.8058, - 48.30222, - -1.646031, - 0.05464731, - -0.0009650715, - 0.000008802193, - -0.00000003110810, - 0.0, - 0.0, - 0.0, + [ // Coefficients for 20.644 <= voltage <= 54.886 + -1.318058E+02, + 4.830222E+01, + -1.646031E+00, + 5.464731E-02, + -9.650715E-04, + 8.802193E-06, + -3.110810E-08, + 0.000000E+00, + 0.000000E+00, + 0.000000E+00, ], ]; -///function for power -/// in: base: f64, exp: i32 -/// out: result: f64 -fn pow(base: f64, exp: i32) -> f64 { - let mut result = 1.0; - if exp < 0 { - result = 1.0 / pow(base, -exp); - } else { - for _ in 0..exp { - result *= base; - } +/// Converts a 32-bit ADC reading to a temperature in celsius. +pub fn adc_to_celsius(adc_reading: i32) -> f64 { + voltage_to_celsius(adc_to_voltage(adc_reading)) +} + +/// Converts a 32-bit ADC reading to a voltage. +pub fn adc_to_voltage(adc_reading: i32) -> f64 { + const REFERENCE_VOLTAGE: f64 = 5.0; + const MAX_ADC_VALUE: f64 = 4_294_967_296.0; + // change 32 to be waht the gain is + const V_SCALE: f64 = (REFERENCE_VOLTAGE / MAX_ADC_VALUE) / 32.0; + + adc_reading as f64 * V_SCALE +} + +/// Converts voltage to celsius for type K thermocouples. +pub fn voltage_to_celsius(mut voltage: f64) -> f64 { + voltage *= 1000.0; + return match voltage { + -5.891..=0.0 => calc_temp_exponential(voltage, &TYPE_K_COEF[0]), + 0.0..=20.644 => calc_temp_exponential(voltage, &TYPE_K_COEF[1]), + 20.644..=54.886 => calc_temp_exponential(voltage, &TYPE_K_COEF[2]), + + // Insane temperature ranges that should never be reached. + // Hitting this is a strong indicator of a bug in the Argus system. + _ => panic!("T < -270 or T > 1372 celcius") } - return result; } -///function to calculate the conversion between voltage to celsius from the thermocoupler. -///in: voltage: f64 -///out: celsius: f64 -pub fn voltage_to_celsius(voltage: f64) -> f64 { - //define variables +/// Calculates temperature using the NIST's exponential polynomial. +fn calc_temp_exponential(voltage: f64, coef: &[f64]) -> f64 { let mut result = 0.0; - let mut i = 0; - - //goes through the different ranges - while i < ENERGY_RANGES.len() { - if voltage >= ENERGY_RANGES[i][0] && voltage <= ENERGY_RANGES[i][1] { - //calculates the result - for k in 0..TYPE_K_COEF[i].len() { - result += TYPE_K_COEF[i][k] * pow(voltage, k as i32); - } - return result; - } else { - //if the voltage is not in the range, it goes to the next range - i += 1; - } + for k in 0..coef.len() { + result += coef[k] * pow(voltage, k as i32); } + return result; +} - return -1.0; +/// Floating point exponentiation function. +/// Cannot access std::f64::powi in no_std environment. +fn pow(base: f64, exp: i32) -> f64 { + if exp < 0 { + return 1.0 / pow(base, -exp); + } + + let mut result = 1.0; + for _ in 0..exp { + result *= base; + } + return result; } #[cfg(test)] mod tests { use super::*; - use crate::voltage_to_celsius; #[test] - fn voltage_to_celsius_test1() { - //println!("Test 1: {}", voltage_to_celsius(20.644)); + fn voltage_to_celsius_converts_expected_ranges() { let result: f64 = voltage_to_celsius(20.644); assert!(499.97 <= result && 500.0 >= result); - // println!("Test 2: {}", voltage_to_celsius(6.138)); let result: f64 = voltage_to_celsius(6.138); assert!(150.01 <= result && 150.03 >= result); - // println!("Test 3: {}", voltage_to_celsius(0.039)); let result: f64 = voltage_to_celsius(0.039); assert!(0.97 <= result && 0.98 >= result); - // println!("Test 4: {}", voltage_to_celsius(-0.778)); let result: f64 = voltage_to_celsius(-0.778); assert!(-20.03 <= result && -20.01 >= result); - // println!("Test 5: {}", voltage_to_celsius(10.0)); let result: f64 = voltage_to_celsius(10.0); assert!(246.1 <= result && 246.3 >= result); } + + #[test] + #[should_panic(expected = "T < -270")] + fn voltage_to_celsius_panics_on_temp_too_cold() { + voltage_to_celsius(-6.0); + } + + #[test] + #[should_panic(expected = "T > 1372")] + fn voltage_to_celsius_panics_on_temp_too_hot() { + voltage_to_celsius(-6.0); + } } diff --git a/crates/thermocouple-converter/src/volts_to_celcuis.rs b/crates/thermocouple-converter/src/volts_to_celcuis.rs new file mode 100644 index 0000000..e5adac8 --- /dev/null +++ b/crates/thermocouple-converter/src/volts_to_celcuis.rs @@ -0,0 +1,4 @@ +/// Thermoelectric Voltages in mV for Type K Thermocouples. +/// Index 0 is -270C, index 1 is -269C, etc. +/// Contains voltages for -270C to 1372C. +const K: [f32; 1643] = [-6.458, -6.457, -6.456, -6.455, -6.453, -6.452, -6.450, -6.448, -6.446, -6.444, -6.441, -6.438, -6.435, -6.432, -6.429, -6.425, -6.421, -6.417, -6.413, -6.408, -6.404, -6.399, -6.393, -6.388, -6.382, -6.377, -6.370, -6.364, -6.358, -6.351, -6.344, -6.337, -6.329, -6.322, -6.314, -6.306, -6.297, -6.289, -6.280, -6.271, -6.262, -6.252, -6.243, -6.233, -6.223, -6.213, -6.202, -6.192, -6.181, -6.170, -6.158, -6.147, -6.135, -6.123, -6.111, -6.099, -6.087, -6.074, -6.061, -6.048, -6.035, -6.021, -6.007, -5.994, -5.980, -5.965, -5.951, -5.936, -5.922, -5.907, -5.891, -5.876, -5.861, -5.845, -5.829, -5.813, -5.797, -5.780, -5.763, -5.747, -5.730, -5.713, -5.695, -5.678, -5.660, -5.642, -5.624, -5.606, -5.588, -5.569, -5.550, -5.531, -5.512, -5.493, -5.474, -5.454, -5.435, -5.415, -5.395, -5.374, -5.354, -5.333, -5.313, -5.292, -5.271, -5.250, -5.228, -5.207, -5.185, -5.163, -5.141, -5.119, -5.097, -5.074, -5.052, -5.029, -5.006, -4.983, -4.960, -4.936, -4.913, -4.889, -4.865, -4.841, -4.817, -4.793, -4.768, -4.744, -4.719, -4.694, -4.669, -4.644, -4.618, -4.593, -4.567, -4.542, -4.516, -4.490, -4.463, -4.437, -4.411, -4.384, -4.357, -4.330, -4.303, -4.276, -4.249, -4.221, -4.194, -4.166, -4.138, -4.110, -4.082, -4.054, -4.025, -3.997, -3.968, -3.939, -3.911, -3.882, -3.852, -3.823, -3.794, -3.764, -3.734, -3.705, -3.675, -3.645, -3.614, -3.584, -3.554, -3.523, -3.492, -3.462, -3.431, -3.400, -3.368, -3.337, -3.306, -3.274, -3.243, -3.211, -3.179, -3.147, -3.115, -3.083, -3.050, -3.018, -2.986, -2.953, -2.920, -2.887, -2.854, -2.821, -2.788, -2.755, -2.721, -2.688, -2.654, -2.620, -2.587, -2.553, -2.519, -2.485, -2.450, -2.416, -2.382, -2.347, -2.312, -2.278, -2.243, -2.208, -2.173, -2.138, -2.103, -2.067, -2.032, -1.996, -1.961, -1.925, -1.889, -1.854, -1.818, -1.782, -1.745, -1.709, -1.673, -1.637, -1.600, -1.564, -1.527, -1.490, -1.453, -1.417, -1.380, -1.343, -1.305, -1.268, -1.231, -1.194, -1.156, -1.119, -1.081, -1.043, -1.006, -0.968, -0.930, -0.892, -0.854, -0.816, -0.778, -0.739, -0.701, -0.663, -0.624, -0.586, -0.547, -0.508, -0.470, -0.431, -0.392, -0.353, -0.314, -0.275, -0.236, -0.197, -0.157, -0.118, -0.079, -0.039, 0.000, 0.039, 0.079, 0.119, 0.158, 0.198, 0.238, 0.277, 0.317, 0.357, 0.397, 0.437, 0.477, 0.517, 0.557, 0.597, 0.637, 0.677, 0.718, 0.758, 0.798, 0.838, 0.879, 0.919, 0.960, 1.000, 1.041, 1.081, 1.122, 1.163, 1.203, 1.244, 1.285, 1.326, 1.366, 1.407, 1.448, 1.489, 1.530, 1.571, 1.612, 1.653, 1.694, 1.735, 1.776, 1.817, 1.858, 1.899, 1.941, 1.982, 2.023, 2.064, 2.106, 2.147, 2.188, 2.230, 2.271, 2.312, 2.354, 2.395, 2.436, 2.478, 2.519, 2.561, 2.602, 2.644, 2.685, 2.727, 2.768, 2.810, 2.851, 2.893, 2.934, 2.976, 3.017, 3.059, 3.100, 3.142, 3.184, 3.225, 3.267, 3.308, 3.350, 3.391, 3.433, 3.474, 3.516, 3.557, 3.599, 3.640, 3.682, 3.723, 3.765, 3.806, 3.848, 3.889, 3.931, 3.972, 4.013, 4.055, 4.096, 4.138, 4.179, 4.220, 4.262, 4.303, 4.344, 4.385, 4.427, 4.468, 4.509, 4.550, 4.591, 4.633, 4.674, 4.715, 4.756, 4.797, 4.838, 4.879, 4.920, 4.961, 5.002, 5.043, 5.084, 5.124, 5.165, 5.206, 5.247, 5.288, 5.328, 5.369, 5.410, 5.450, 5.491, 5.532, 5.572, 5.613, 5.653, 5.694, 5.735, 5.775, 5.815, 5.856, 5.896, 5.937, 5.977, 6.017, 6.058, 6.098, 6.138, 6.179, 6.219, 6.259, 6.299, 6.339, 6.380, 6.420, 6.460, 6.500, 6.540, 6.580, 6.620, 6.660, 6.701, 6.741, 6.781, 6.821, 6.861, 6.901, 6.941, 6.981, 7.021, 7.060, 7.100, 7.140, 7.180, 7.220, 7.260, 7.300, 7.340, 7.380, 7.420, 7.460, 7.500, 7.540, 7.579, 7.619, 7.659, 7.699, 7.739, 7.779, 7.819, 7.859, 7.899, 7.939, 7.979, 8.019, 8.059, 8.099, 8.138, 8.178, 8.218, 8.258, 8.298, 8.338, 8.378, 8.418, 8.458, 8.499, 8.539, 8.579, 8.619, 8.659, 8.699, 8.739, 8.779, 8.819, 8.860, 8.900, 8.940, 8.980, 9.020, 9.061, 9.101, 9.141, 9.181, 9.222, 9.262, 9.302, 9.343, 9.383, 9.423, 9.464, 9.504, 9.545, 9.585, 9.626, 9.666, 9.707, 9.747, 9.788, 9.828, 9.869, 9.909, 9.950, 9.991, 10.031, 10.072, 10.113, 10.153, 10.194, 10.235, 10.276, 10.316, 10.357, 10.398, 10.439, 10.480, 10.520, 10.561, 10.602, 10.643, 10.684, 10.725, 10.766, 10.807, 10.848, 10.889, 10.930, 10.971, 11.012, 11.053, 11.094, 11.135, 11.176, 11.217, 11.259, 11.300, 11.341, 11.382, 11.423, 11.465, 11.506, 11.547, 11.588, 11.630, 11.671, 11.712, 11.753, 11.795, 11.836, 11.877, 11.919, 11.960, 12.001, 12.043, 12.084, 12.126, 12.167, 12.209, 12.250, 12.291, 12.333, 12.374, 12.416, 12.457, 12.499, 12.540, 12.582, 12.624, 12.665, 12.707, 12.748, 12.790, 12.831, 12.873, 12.915, 12.956, 12.998, 13.040, 13.081, 13.123, 13.165, 13.206, 13.248, 13.290, 13.331, 13.373, 13.415, 13.457, 13.498, 13.540, 13.582, 13.624, 13.665, 13.707, 13.749, 13.791, 13.833, 13.874, 13.916, 13.958, 14.000, 14.042, 14.084, 14.126, 14.167, 14.209, 14.251, 14.293, 14.335, 14.377, 14.419, 14.461, 14.503, 14.545, 14.587, 14.629, 14.671, 14.713, 14.755, 14.797, 14.839, 14.881, 14.923, 14.965, 15.007, 15.049, 15.091, 15.133, 15.175, 15.217, 15.259, 15.301, 15.343, 15.385, 15.427, 15.469, 15.511, 15.554, 15.596, 15.638, 15.680, 15.722, 15.764, 15.806, 15.849, 15.891, 15.933, 15.975, 16.017, 16.059, 16.102, 16.144, 16.186, 16.228, 16.270, 16.313, 16.355, 16.397, 16.439, 16.482, 16.524, 16.566, 16.608, 16.651, 16.693, 16.735, 16.778, 16.820, 16.862, 16.904, 16.947, 16.989, 17.031, 17.074, 17.116, 17.158, 17.201, 17.243, 17.285, 17.328, 17.370, 17.413, 17.455, 17.497, 17.540, 17.582, 17.624, 17.667, 17.709, 17.752, 17.794, 17.837, 17.879, 17.921, 17.964, 18.006, 18.049, 18.091, 18.134, 18.176, 18.218, 18.261, 18.303, 18.346, 18.388, 18.431, 18.473, 18.516, 18.558, 18.601, 18.643, 18.686, 18.728, 18.771, 18.813, 18.856, 18.898, 18.941, 18.983, 19.026, 19.068, 19.111, 19.154, 19.196, 19.239, 19.281, 19.324, 19.366, 19.409, 19.451, 19.494, 19.537, 19.579, 19.622, 19.664, 19.707, 19.750, 19.792, 19.835, 19.877, 19.920, 19.962, 20.005, 20.048, 20.090, 20.133, 20.175, 20.218, 20.261, 20.303, 20.346, 20.389, 20.431, 20.474, 20.516, 20.559, 20.602, 20.644, 20.687, 20.730, 20.772, 20.815, 20.857, 20.900, 20.943, 20.985, 21.028, 21.071, 21.113, 21.156, 21.199, 21.241, 21.284, 21.326, 21.369, 21.412, 21.454, 21.497, 21.540, 21.582, 21.625, 21.668, 21.710, 21.753, 21.796, 21.838, 21.881, 21.924, 21.966, 22.009, 22.052, 22.094, 22.137, 22.179, 22.222, 22.265, 22.307, 22.350, 22.393, 22.435, 22.478, 22.521, 22.563, 22.606, 22.649, 22.691, 22.734, 22.776, 22.819, 22.862, 22.904, 22.947, 22.990, 23.032, 23.075, 23.117, 23.160, 23.203, 23.245, 23.288, 23.331, 23.373, 23.416, 23.458, 23.501, 23.544, 23.586, 23.629, 23.671, 23.714, 23.757, 23.799, 23.842, 23.884, 23.927, 23.970, 24.012, 24.055, 24.097, 24.140, 24.182, 24.225, 24.267, 24.310, 24.353, 24.395, 24.438, 24.480, 24.523, 24.565, 24.608, 24.650, 24.693, 24.735, 24.778, 24.820, 24.863, 24.905, 24.948, 24.990, 25.033, 25.075, 25.118, 25.160, 25.203, 25.245, 25.288, 25.330, 25.373, 25.415, 25.458, 25.500, 25.543, 25.585, 25.627, 25.670, 25.712, 25.755, 25.797, 25.840, 25.882, 25.924, 25.967, 26.009, 26.052, 26.094, 26.136, 26.179, 26.221, 26.263, 26.306, 26.348, 26.390, 26.433, 26.475, 26.517, 26.560, 26.602, 26.644, 26.687, 26.729, 26.771, 26.814, 26.856, 26.898, 26.940, 26.983, 27.025, 27.067, 27.109, 27.152, 27.194, 27.236, 27.278, 27.320, 27.363, 27.405, 27.447, 27.489, 27.531, 27.574, 27.616, 27.658, 27.700, 27.742, 27.784, 27.826, 27.869, 27.911, 27.953, 27.995, 28.037, 28.079, 28.121, 28.163, 28.205, 28.247, 28.289, 28.332, 28.374, 28.416, 28.458, 28.500, 28.542, 28.584, 28.626, 28.668, 28.710, 28.752, 28.794, 28.835, 28.877, 28.919, 28.961, 29.003, 29.045, 29.087, 29.129, 29.171, 29.213, 29.255, 29.297, 29.338, 29.380, 29.422, 29.464, 29.506, 29.548, 29.589, 29.631, 29.673, 29.715, 29.757, 29.798, 29.840, 29.882, 29.924, 29.965, 30.007, 30.049, 30.090, 30.132, 30.174, 30.216, 30.257, 30.299, 30.341, 30.382, 30.424, 30.466, 30.507, 30.549, 30.590, 30.632, 30.674, 30.715, 30.757, 30.798, 30.840, 30.881, 30.923, 30.964, 31.006, 31.047, 31.089, 31.130, 31.172, 31.213, 31.255, 31.296, 31.338, 31.379, 31.421, 31.462, 31.504, 31.545, 31.586, 31.628, 31.669, 31.710, 31.752, 31.793, 31.834, 31.876, 31.917, 31.958, 32.000, 32.041, 32.082, 32.124, 32.165, 32.206, 32.247, 32.289, 32.330, 32.371, 32.412, 32.453, 32.495, 32.536, 32.577, 32.618, 32.659, 32.700, 32.742, 32.783, 32.824, 32.865, 32.906, 32.947, 32.988, 33.029, 33.070, 33.111, 33.152, 33.193, 33.234, 33.275, 33.316, 33.357, 33.398, 33.439, 33.480, 33.521, 33.562, 33.603, 33.644, 33.685, 33.726, 33.767, 33.808, 33.848, 33.889, 33.930, 33.971, 34.012, 34.053, 34.093, 34.134, 34.175, 34.216, 34.257, 34.297, 34.338, 34.379, 34.420, 34.460, 34.501, 34.542, 34.582, 34.623, 34.664, 34.704, 34.745, 34.786, 34.826, 34.867, 34.908, 34.948, 34.989, 35.029, 35.070, 35.110, 35.151, 35.192, 35.232, 35.273, 35.313, 35.354, 35.394, 35.435, 35.475, 35.516, 35.556, 35.596, 35.637, 35.677, 35.718, 35.758, 35.798, 35.839, 35.879, 35.920, 35.960, 36.000, 36.041, 36.081, 36.121, 36.162, 36.202, 36.242, 36.282, 36.323, 36.363, 36.403, 36.443, 36.484, 36.524, 36.564, 36.604, 36.644, 36.685, 36.725, 36.765, 36.805, 36.845, 36.885, 36.925, 36.965, 37.006, 37.046, 37.086, 37.126, 37.166, 37.206, 37.246, 37.286, 37.326, 37.366, 37.406, 37.446, 37.486, 37.526, 37.566, 37.606, 37.646, 37.686, 37.725, 37.765, 37.805, 37.845, 37.885, 37.925, 37.965, 38.005, 38.044, 38.084, 38.124, 38.164, 38.204, 38.243, 38.283, 38.323, 38.363, 38.402, 38.442, 38.482, 38.522, 38.561, 38.601, 38.641, 38.680, 38.720, 38.760, 38.799, 38.839, 38.878, 38.918, 38.958, 38.997, 39.037, 39.076, 39.116, 39.155, 39.195, 39.235, 39.274, 39.314, 39.353, 39.393, 39.432, 39.471, 39.511, 39.550, 39.590, 39.629, 39.669, 39.708, 39.747, 39.787, 39.826, 39.866, 39.905, 39.944, 39.984, 40.023, 40.062, 40.101, 40.141, 40.180, 40.219, 40.259, 40.298, 40.337, 40.376, 40.415, 40.455, 40.494, 40.533, 40.572, 40.611, 40.651, 40.690, 40.729, 40.768, 40.807, 40.846, 40.885, 40.924, 40.963, 41.002, 41.042, 41.081, 41.120, 41.159, 41.198, 41.237, 41.276, 41.315, 41.354, 41.393, 41.431, 41.470, 41.509, 41.548, 41.587, 41.626, 41.665, 41.704, 41.743, 41.781, 41.820, 41.859, 41.898, 41.937, 41.976, 42.014, 42.053, 42.092, 42.131, 42.169, 42.208, 42.247, 42.286, 42.324, 42.363, 42.402, 42.440, 42.479, 42.518, 42.556, 42.595, 42.633, 42.672, 42.711, 42.749, 42.788, 42.826, 42.865, 42.903, 42.942, 42.980, 43.019, 43.057, 43.096, 43.134, 43.173, 43.211, 43.250, 43.288, 43.327, 43.365, 43.403, 43.442, 43.480, 43.518, 43.557, 43.595, 43.633, 43.672, 43.710, 43.748, 43.787, 43.825, 43.863, 43.901, 43.940, 43.978, 44.016, 44.054, 44.092, 44.130, 44.169, 44.207, 44.245, 44.283, 44.321, 44.359, 44.397, 44.435, 44.473, 44.512, 44.550, 44.588, 44.626, 44.664, 44.702, 44.740, 44.778, 44.816, 44.853, 44.891, 44.929, 44.967, 45.005, 45.043, 45.081, 45.119, 45.157, 45.194, 45.232, 45.270, 45.308, 45.346, 45.383, 45.421, 45.459, 45.497, 45.534, 45.572, 45.610, 45.647, 45.685, 45.723, 45.760, 45.798, 45.836, 45.873, 45.911, 45.948, 45.986, 46.024, 46.061, 46.099, 46.136, 46.174, 46.211, 46.249, 46.286, 46.324, 46.361, 46.398, 46.436, 46.473, 46.511, 46.548, 46.585, 46.623, 46.660, 46.697, 46.735, 46.772, 46.809, 46.847, 46.884, 46.921, 46.958, 46.995, 47.033, 47.070, 47.107, 47.144, 47.181, 47.218, 47.256, 47.293, 47.330, 47.367, 47.404, 47.441, 47.478, 47.515, 47.552, 47.589, 47.626, 47.663, 47.700, 47.737, 47.774, 47.811, 47.848, 47.884, 47.921, 47.958, 47.995, 48.032, 48.069, 48.105, 48.142, 48.179, 48.216, 48.252, 48.289, 48.326, 48.363, 48.399, 48.436, 48.473, 48.509, 48.546, 48.582, 48.619, 48.656, 48.692, 48.729, 48.765, 48.802, 48.838, 48.875, 48.911, 48.948, 48.984, 49.021, 49.057, 49.093, 49.130, 49.166, 49.202, 49.239, 49.275, 49.311, 49.348, 49.384, 49.420, 49.456, 49.493, 49.529, 49.565, 49.601, 49.637, 49.674, 49.710, 49.746, 49.782, 49.818, 49.854, 49.890, 49.926, 49.962, 49.998, 50.034, 50.070, 50.106, 50.142, 50.178, 50.214, 50.250, 50.286, 50.322, 50.358, 50.393, 50.429, 50.465, 50.501, 50.537, 50.572, 50.608, 50.644, 50.680, 50.715, 50.751, 50.787, 50.822, 50.858, 50.894, 50.929, 50.965, 51.000, 51.036, 51.071, 51.107, 51.142, 51.178, 51.213, 51.249, 51.284, 51.320, 51.355, 51.391, 51.426, 51.461, 51.497, 51.532, 51.567, 51.603, 51.638, 51.673, 51.708, 51.744, 51.779, 51.814, 51.849, 51.885, 51.920, 51.955, 51.990, 52.025, 52.060, 52.095, 52.130, 52.165, 52.200, 52.235, 52.270, 52.305, 52.340, 52.375, 52.410, 52.445, 52.480, 52.515, 52.550, 52.585, 52.620, 52.654, 52.689, 52.724, 52.759, 52.794, 52.828, 52.863, 52.898, 52.932, 52.967, 53.002, 53.037, 53.071, 53.106, 53.140, 53.175, 53.210, 53.244, 53.279, 53.313, 53.348, 53.382, 53.417, 53.451, 53.486, 53.520, 53.555, 53.589, 53.623, 53.658, 53.692, 53.727, 53.761, 53.795, 53.830, 53.864, 53.898, 53.932, 53.967, 54.001, 54.035, 54.069, 54.104, 54.138, 54.172, 54.206, 54.240, 54.274, 54.308, 54.343, 54.377, 54.411, 54.445, 54.479, 54.513, 54.547, 54.581, 54.615, 54.649, 54.683, 54.717, 54.751, 54.785, 54.819, 54.852, 54.886]; \ No newline at end of file diff --git a/examples/simple-playground/src/main.rs b/examples/simple-playground/src/main.rs index dacaae4..807ecc0 100644 --- a/examples/simple-playground/src/main.rs +++ b/examples/simple-playground/src/main.rs @@ -16,7 +16,7 @@ fn panic() -> ! { #[entry] fn main() -> ! { - let _cp = cortex_m::Peripherals::take().unwrap(); + let cp = cortex_m::Peripherals::take().unwrap(); let dp = pac::Peripherals::take().unwrap(); let pwr = dp.PWR.constrain(); @@ -29,10 +29,45 @@ fn main() -> ! { info!("Reset reason: {:?}", reset); - let _ccdr = rcc.freeze(pwrcfg, &dp.SYSCFG); + let ccdr = rcc + .pll1_p_ck(32.MHz()) + // .pclk4(32.MHz()) + // .per_ck(32.MHz()) + .freeze(pwrcfg, &dp.SYSCFG); + info!("RCC configured"); + let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA); + let gpiod = dp.GPIOD.split(ccdr.peripheral.GPIOD); + let gpioc = dp.GPIOC.split(ccdr.peripheral.GPIOC); + let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB); + let gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE); + + let mut adc_spi: stm32h7xx_hal::spi::Spi< + stm32h7xx_hal::stm32::SPI4, + stm32h7xx_hal::spi::Enabled, + u8, + > = dp.SPI4.spi( + ( + gpioe.pe2.into_alternate::<5>(), + gpioe.pe5.into_alternate(), + gpioe.pe6.into_alternate(), + ), + stm32h7xx_hal::spi::Config::new(stm32h7xx_hal::spi::MODE_1), // datasheet mentioned a mode 1 per datasheet + 8.MHz(), // 125 ns + ccdr.peripheral.SPI4, + &ccdr.clocks, + ); + + let mut adc1_rst = gpioc.pc11.into_push_pull_output(); + adc1_rst.set_high(); + + let mut adc_cs = gpioc.pc10.into_push_pull_output().internal_pull_up(true); loop { - info!("Hello, world!"); + let mut buffer = [0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + adc_cs.set_low(); + adc_spi.transfer(&mut buffer); + adc_cs.set_high(); + info!("Buffer: {:?}", buffer); } }