Add NVM read/write functions
Including adding a wrapper type for NVM addresses to provide validation that the wrong addresses aren't being sent to the device
This commit is contained in:
parent
36bdf9dd16
commit
34dd0902f2
|
@ -12,8 +12,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- `Rn2903::system_factory_reset()`
|
||||
- `Rn2903::system_module_reset()`
|
||||
- `Rn2903::mac_pause()` and `::mac_resume()`
|
||||
- `Rn2903::system_{get, set}_nvm()`
|
||||
- `BadResponse` and `CannotPause` error variants
|
||||
- Examples directory with LED blinky and LoRa packet RX examples
|
||||
- `NvmAddress` newtype for representing values that can be passed to NVM functions
|
||||
- Examples directory:
|
||||
- LED blink
|
||||
- NVM read/write
|
||||
- LoRa packet RX
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
use rn2903::{NvmAddress, Rn2903};
|
||||
use std::env::args;
|
||||
use std::process::exit;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<_> = args().collect();
|
||||
if args.len() <= 1 {
|
||||
eprintln!("rn2903_nvm_set_get <serial port>");
|
||||
eprintln!("\tGet, modify, check, and restore the contents of NVM::0x300.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let mut txvr = Rn2903::new_at(&args[1]).expect("Could not open device. Error");
|
||||
println!(
|
||||
"Successfully connected. Version: {}",
|
||||
txvr.system_version()
|
||||
.expect("Could not read from device. Error:")
|
||||
);
|
||||
|
||||
txvr.system_module_reset().unwrap();
|
||||
txvr.transact(b"mac pause").unwrap();
|
||||
let addr = NvmAddress::new(0x300);
|
||||
|
||||
txvr.transact(b"sys set pindig GPIO10 1").unwrap();
|
||||
let prev = txvr.system_get_nvm(addr).unwrap();
|
||||
println!("Previous value: {:#x}", prev);
|
||||
txvr.transact(b"sys set pindig GPIO10 0").unwrap();
|
||||
|
||||
txvr.transact(b"sys set pindig GPIO11 1").unwrap();
|
||||
txvr.system_set_nvm(addr, 0xAB).unwrap();
|
||||
println!("Wrote new value");
|
||||
txvr.transact(b"sys set pindig GPIO11 0").unwrap();
|
||||
|
||||
txvr.transact(b"sys set pindig GPIO10 1").unwrap();
|
||||
let new = txvr.system_get_nvm(addr).unwrap();
|
||||
println!("New value: {:#x}", new);
|
||||
txvr.transact(b"sys set pindig GPIO10 0").unwrap();
|
||||
|
||||
txvr.transact(b"sys set pindig GPIO11 1").unwrap();
|
||||
txvr.system_set_nvm(addr, prev).unwrap();
|
||||
println!("Restored old value");
|
||||
txvr.transact(b"sys set pindig GPIO11 0").unwrap();
|
||||
}
|
48
src/lib.rs
48
src/lib.rs
|
@ -308,6 +308,34 @@ impl Rn2903 {
|
|||
}
|
||||
}
|
||||
|
||||
/// An address in user-accessible nonvolatile memory. Guaranteed to be between 0x300 and
|
||||
/// 0x3FF.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct NvmAddress(u16);
|
||||
|
||||
impl NvmAddress {
|
||||
/// Create a new `NvmAddress` from a `u16`. The given value must be between 0x300 and
|
||||
/// 0x3FF.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if the given value is not between 0x300 and 0x3FF.
|
||||
pub fn new(value: u16) -> NvmAddress {
|
||||
if value < 0x300 {
|
||||
panic!("Attempted to construct NvmAddress less than 0x300.");
|
||||
}
|
||||
if value > 0x3FF {
|
||||
panic!("Attempted to construct NvmAddress more than 0x3FF.");
|
||||
}
|
||||
NvmAddress(value)
|
||||
}
|
||||
|
||||
/// Return the address to which this NvmAddress refers. Guaranteed to be between
|
||||
/// 0x300 and 0x3FF.
|
||||
pub fn inner(self) -> u16 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// # System API Functions
|
||||
impl Rn2903 {
|
||||
/// Queries the module for its firmware version information.
|
||||
|
@ -340,6 +368,26 @@ impl Rn2903 {
|
|||
pub fn system_factory_reset(&mut self) -> Result<Vec<u8>> {
|
||||
self.transact(b"sys factoryRESET")
|
||||
}
|
||||
|
||||
/// Set the value of the on-MCU nonvolatile memory at the given address to the given
|
||||
/// value.
|
||||
pub fn system_set_nvm(&mut self, address: NvmAddress, value: u8) -> Result<()> {
|
||||
self.transact_expecting(
|
||||
&format!("sys set nvm {:x} {:x}", address.inner(), value).into_bytes(),
|
||||
b"ok",
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the value of the on-MCU nonvolatile memory at the given address.
|
||||
pub fn system_get_nvm(&mut self, address: NvmAddress) -> Result<u8> {
|
||||
let response = bytes_to_string(
|
||||
&self.transact(&format!("sys get nvm {:x}", address.inner()).into_bytes())?,
|
||||
);
|
||||
match u8::from_str_radix(&response, 16) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(_) => Err(Error::bad_response("<integer>", response)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// # MAC API Functions
|
||||
|
|
Loading…
Reference in New Issue