mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 08:12:30 +00:00
Example and documentation on how to Calculate correct checksum.
+ Include the package format documentation. + Cycle through all three colours in three different speed. - Remove the `write_cmd_bytes()`. Superfluous.
This commit is contained in:
parent
61d0c068ff
commit
66ee0c44d3
@ -1,12 +1,12 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use defmt::info;
|
use defmt::{debug, error, info};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::bind_interrupts;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::peripherals::UART0;
|
use embassy_rp::peripherals::UART0;
|
||||||
use embassy_rp::uart::{Config, DataBits, InterruptHandler as UARTInterruptHandler, Parity, StopBits, Uart};
|
use embassy_rp::uart::{Config, DataBits, InterruptHandler as UARTInterruptHandler, Parity, StopBits, Uart};
|
||||||
use embassy_time::Timer;
|
use embassy_time::{with_timeout, Duration, Timer};
|
||||||
use heapless::Vec;
|
use heapless::Vec;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
@ -14,15 +14,34 @@ bind_interrupts!(pub struct Irqs {
|
|||||||
UART0_IRQ => UARTInterruptHandler<UART0>;
|
UART0_IRQ => UARTInterruptHandler<UART0>;
|
||||||
});
|
});
|
||||||
|
|
||||||
const ADDRESS: u32 = 0xFFFFFFFF;
|
|
||||||
const START: u16 = 0xEF01;
|
const START: u16 = 0xEF01;
|
||||||
|
const ADDRESS: u32 = 0xFFFFFFFF;
|
||||||
|
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
|
|
||||||
fn write_cmd_bytes(buf: &mut Vec<u8, 32>, bytes: &[u8]) {
|
// Data package format
|
||||||
let _ = buf.extend_from_slice(bytes);
|
// Name Length Description
|
||||||
}
|
// ==========================================================================================================
|
||||||
|
// Start 2 bytes Fixed value of 0xEF01; High byte transferred first.
|
||||||
|
// Address 4 bytes Default value is 0xFFFFFFFF, which can be modified by command.
|
||||||
|
// High byte transferred first and at wrong adder value, module
|
||||||
|
// will reject to transfer.
|
||||||
|
// PID 1 byte 01H Command packet;
|
||||||
|
// 02H Data packet; Data packet shall not appear alone in executing
|
||||||
|
// processs, must follow command packet or acknowledge packet.
|
||||||
|
// 07H Acknowledge packet;
|
||||||
|
// 08H End of Data packet.
|
||||||
|
// LENGTH 2 bytes Refers to the length of package content (command packets and data packets)
|
||||||
|
// plus the length of Checksum (2 bytes). Unit is byte. Max length is 256 bytes.
|
||||||
|
// And high byte is transferred first.
|
||||||
|
// DATA - It can be commands, data, command’s parameters, acknowledge result, etc.
|
||||||
|
// (fingerprint character value, template are all deemed as data);
|
||||||
|
// SUM 2 bytes The arithmetic sum of package identifier, package length and all package
|
||||||
|
// contens. Overflowing bits are omitted. high byte is transferred first.
|
||||||
|
|
||||||
|
// ================================================================================
|
||||||
|
|
||||||
|
// Checksum is calculated on 'length (2 bytes) + data (??)'.
|
||||||
fn compute_checksum(buf: Vec<u8, 32>) -> u16 {
|
fn compute_checksum(buf: Vec<u8, 32>) -> u16 {
|
||||||
let mut checksum = 0u16;
|
let mut checksum = 0u16;
|
||||||
|
|
||||||
@ -52,81 +71,88 @@ async fn main(_spawner: Spawner) {
|
|||||||
let (mut tx, mut rx) = uart.split();
|
let (mut tx, mut rx) = uart.split();
|
||||||
|
|
||||||
let mut vec_buf: Vec<u8, 32> = heapless::Vec::new();
|
let mut vec_buf: Vec<u8, 32> = heapless::Vec::new();
|
||||||
|
let mut data: Vec<u8, 32> = heapless::Vec::new();
|
||||||
|
|
||||||
// Cycle through the three colours Red, Blue and Purple.
|
let mut speeds: Vec<u8, 3> = heapless::Vec::new();
|
||||||
for colour in 1..=3 {
|
let _ = speeds.push(0xC8); // Slow
|
||||||
// Clear buffers
|
let _ = speeds.push(0x20); // Medium
|
||||||
vec_buf.clear();
|
let _ = speeds.push(0x02); // Fast
|
||||||
|
|
||||||
// START
|
// Cycle through the three colours Red, Blue and Purple forever.
|
||||||
let _ = write_cmd_bytes(&mut vec_buf, &START.to_be_bytes()[..]);
|
loop {
|
||||||
|
for colour in 1..=3 {
|
||||||
|
for speed in &speeds {
|
||||||
|
// Set the data first, because the length is dependent on that.
|
||||||
|
// However, we write the length bits before we do the data.
|
||||||
|
data.clear();
|
||||||
|
let _ = data.push(0x01); // ctrl=Breathing light
|
||||||
|
let _ = data.push(*speed);
|
||||||
|
let _ = data.push(colour as u8); // colour=Red, Blue, Purple
|
||||||
|
let _ = data.push(0x00); // times=Infinite
|
||||||
|
|
||||||
// ADDRESS
|
// Clear buffers
|
||||||
let _ = write_cmd_bytes(&mut vec_buf, &ADDRESS.to_be_bytes()[..]);
|
vec_buf.clear();
|
||||||
|
|
||||||
// PID
|
// START
|
||||||
let _ = vec_buf.push(0x01);
|
let _ = vec_buf.extend_from_slice(&START.to_be_bytes()[..]);
|
||||||
|
|
||||||
// LENGTH
|
// ADDRESS
|
||||||
let len = <usize as TryInto<u16>>::try_into(vec_buf.len()).unwrap() as u16;
|
let _ = vec_buf.extend_from_slice(&ADDRESS.to_be_bytes()[..]);
|
||||||
let _ = write_cmd_bytes(&mut vec_buf, &len.to_be_bytes()[..]);
|
|
||||||
|
|
||||||
// COMMAND
|
// PID
|
||||||
let _ = vec_buf.push(0x35); // AuraLedConfig
|
let _ = vec_buf.extend_from_slice(&[0x01]);
|
||||||
|
|
||||||
// DATA
|
// LENGTH
|
||||||
let _ = vec_buf.push(0x01); // ctrl=Breathing light
|
let len: u16 = (1 + data.len() + 2).try_into().unwrap();
|
||||||
let _ = vec_buf.push(0x50); // speed=80
|
let _ = vec_buf.extend_from_slice(&len.to_be_bytes()[..]);
|
||||||
let _ = vec_buf.push(colour as u8); // colour=Red, Blue, Purple
|
|
||||||
let _ = vec_buf.push(0x00); // times=Infinite
|
|
||||||
|
|
||||||
// SUM
|
// COMMAND
|
||||||
let chk = compute_checksum(vec_buf.clone());
|
let _ = vec_buf.push(0x35); // Command: AuraLedConfig
|
||||||
let _ = write_cmd_bytes(&mut vec_buf, &chk.to_be_bytes()[..]);
|
|
||||||
|
|
||||||
// =====
|
// DATA
|
||||||
|
let _ = vec_buf.extend_from_slice(&data);
|
||||||
|
|
||||||
// Send command buffer.
|
// SUM
|
||||||
let data_write: [u8; 16] = vec_buf.clone().into_array().unwrap();
|
let chk = compute_checksum(vec_buf.clone());
|
||||||
info!("write ({})='{:?}'", colour, data_write);
|
let _ = vec_buf.extend_from_slice(&chk.to_be_bytes()[..]);
|
||||||
match tx.write(&data_write).await {
|
|
||||||
Ok(..) => info!("Write successful."),
|
|
||||||
Err(e) => info!("Write error: {:?}", e),
|
|
||||||
}
|
|
||||||
|
|
||||||
// =====
|
// =====
|
||||||
|
|
||||||
// Read command buffer.
|
// Send command buffer.
|
||||||
let mut read_buf: [u8; 1] = [0; 1]; // Can only read one byte at a time!
|
let data_write: [u8; 16] = vec_buf.clone().into_array().unwrap();
|
||||||
let mut data_read: Vec<u8, 32> = heapless::Vec::new(); // Return buffer.
|
debug!(" write='{:?}'", data_write[..]);
|
||||||
let mut cnt: u8 = 0; // Keep track of how many packages we've received.
|
match tx.write(&data_write).await {
|
||||||
|
Ok(..) => info!("Write successful."),
|
||||||
|
Err(e) => error!("Write error: {:?}", e),
|
||||||
|
}
|
||||||
|
|
||||||
info!("Attempting read.");
|
// =====
|
||||||
loop {
|
|
||||||
match rx.read(&mut read_buf).await {
|
// Read command buffer.
|
||||||
Ok(..) => (),
|
let mut read_buf: [u8; 1] = [0; 1]; // Can only read one byte at a time!
|
||||||
Err(e) => info!(" Read error: {:?}", e),
|
let mut data_read: Vec<u8, 32> = heapless::Vec::new(); // Save buffer.
|
||||||
|
|
||||||
|
info!("Attempting read.");
|
||||||
|
loop {
|
||||||
|
// Some commands, like `Img2Tz()` needs longer, but we hard-code this to 200ms
|
||||||
|
// for this command.
|
||||||
|
match with_timeout(Duration::from_millis(200), rx.read(&mut read_buf)).await {
|
||||||
|
Ok(..) => {
|
||||||
|
// Extract and save read byte.
|
||||||
|
debug!(" r='{=u8:#04x}H' ({:03}D)", read_buf[0], read_buf[0]);
|
||||||
|
let _ = data_read.push(read_buf[0]).unwrap();
|
||||||
|
}
|
||||||
|
Err(..) => break, // TimeoutError -> Ignore.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info!("Read successful");
|
||||||
|
debug!(" read='{:?}'", data_read[..]);
|
||||||
|
|
||||||
|
Timer::after_secs(3).await;
|
||||||
|
info!("Changing speed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
match cnt {
|
|
||||||
_ => data_read.push(read_buf[0]).unwrap(),
|
|
||||||
}
|
|
||||||
|
|
||||||
if cnt > 10 {
|
|
||||||
info!("read ({})='{:?}'", colour, data_read[..]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cnt = cnt + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =====
|
|
||||||
|
|
||||||
if colour != 3 {
|
|
||||||
Timer::after_secs(2).await;
|
|
||||||
info!("Changing colour.");
|
info!("Changing colour.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("All done..");
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user