blinky/src/main.rs

334 lines
11 KiB
Rust

//! The following wiring is setup:
//! - TX => GPIO15
//! - RX => GPIO14
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
#![feature(utf8_chunks)]
mod modem;
mod serial;
extern crate alloc;
use core::mem::MaybeUninit;
use esp_backtrace as _;
use esp_println::println;
// use hal::embassy::executor::Executor;
use esp_wifi::{initialize, EspWifiInitFor};
use embassy_time::{Instant, Duration};
use hal::{timer::TimerGroup, Rng};
use embassy_executor::Spawner;
use embassy_sync::{blocking_mutex::raw::NoopRawMutex, signal::Signal};
use hal::{
clock::ClockControl,
embassy,
gpio::IO,
interrupt,
uart::{
config::{Config, DataBits, Parity, StopBits},
TxRxPins,
},
Delay,
peripherals::{Interrupt, Peripherals, UART1},
prelude::*,
Uart,
gpio::GpioPin,
};
use hal::clock::{CpuClock, Clocks};
use esp_hal_common::uart::{config::AtCmdConfig, UartRx, UartTx};
use static_cell::make_static;
use atat::{
asynch::{
AtatClient,
Client,
},
AtatIngress,
Buffers,
DefaultDigester,
Ingress,
AtDigester,
};
#[global_allocator]
static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
fn init_heap() {
const HEAP_SIZE: usize = 32 * 1024;
static mut HEAP: MaybeUninit<[u8; HEAP_SIZE]> = MaybeUninit::uninit();
unsafe {
ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, HEAP_SIZE);
}
}
const AT_CMD: u8 = 0x04;
const READ_BUF_SIZE: usize = 64;
const INGRESS_BUF_SIZE: usize = 1024;
const URC_CAPACITY: usize = 128;
const URC_SUBSCRIBERS: usize = 3;
#[embassy_executor::task]
async fn ingress_task(
mut ingress: Ingress<
'static,
DefaultDigester<modem::Urc>,
modem::Urc,
INGRESS_BUF_SIZE,
URC_CAPACITY,
URC_SUBSCRIBERS,
>,
mut rx: UartRx<'static, UART1>)
{
log::info!("reading in ingress_task...");
ingress.read_from(&mut rx).await;
}
#[embassy_executor::task]
async fn test_send(mut client: Client<'static, UartTx<'static, UART1>, INGRESS_BUF_SIZE>) {
let mut state: u8 = 0;
loop {
match state {
0 => {
match client.send(&modem::GetModelId).await {
Ok(d) => log::info!("GetModelId Sent: {:?}", d),
Err(e) => {
match e {
atat::Error::Timeout => log::error!("[GetModelId] - Timeout Error: {:?}", e),
atat::Error::Parse => log::error!("[GetModelId] - Parse Error: Cound not parse: {:?}", e),
_ => {}
}
},
}
}
1 => {
// println!("sending a single message (GetManufacturerId)");
// log::info!("sending a single message (GetManufacturerId)");
// client.send(&modem::GetManufacturerId).await.unwrap();
// log::info!("(GetManufacturerId) sent");
match client.send(&modem::GetManufacturerId).await {
Ok(d) => log::info!("GetManufacturerId Sent: {:?}", d),
Err(e) => {
match e {
atat::Error::Timeout => log::error!("[GetManufacturerId] - Timeout Error: {:?}", e),
atat::Error::Parse => log::error!("[GetManufacturerId] - Parse Error: Cound not parse: {:?}", e),
_ => {}
}
},
}
}
2 => {
// println!("sending a single message (GetSoftwareVersion)");
// log::info!("sending a single message (GetSoftwareVersion)");
// client.send(&modem::GetSoftwareVersion).await.unwrap();
// log::info!("(GetSoftwareVersion) sent");
match client.send(&modem::GetSoftwareVersion).await {
Ok(d) => log::info!("GetSoftwareVersion Sent: {:?}", d),
Err(e) => {
match e {
atat::Error::Timeout => log::error!("[GetSoftwareVersion] - Timeout Error: {:?}", e),
atat::Error::Parse => log::error!("[GetSoftwareVersion] - Parse Error: Cound not parse: {:?}", e),
_ => {}
}
},
}
}
3 => {
// println!("sending a single message (GetWifiMac)");
// log::info!("sending a single message (GetWifiMac)");
// client.send(&modem::GetWifiMac).await.unwrap();
// log::info!("(GetWifiMac) sent");
match client.send(&modem::GetWifiMac).await {
Ok(d) => log::info!("GetWifiMac Sent: {:?}", d),
Err(e) => {
match e {
atat::Error::Timeout => log::error!("[GetWifiMac] - Timeout Error: {:?}", e),
atat::Error::Parse => log::error!("[GetWifiMac] - Parse Error: Cound not parse: {:?}", e),
_ => {}
}
},
}
}
4 => {
// println!("sending a single message (GetAT)");
// log::info!("sending a single message (GetAT)");
// client.send(&modem::GetAT).await.unwrap();
// log::info!("(GetAT) sent");
match client.send(&modem::GetAT).await {
Ok(d) => log::info!("GetAT Sent: {:?}", d),
Err(e) => {
match e {
atat::Error::Timeout => log::error!("[GetAT] - Timeout Error: {:?}", e),
atat::Error::Parse => log::error!("[GetAT] - Parse Error: Cound not parse: {:?}", e),
_ => {}
}
},
}
// log::info!("AT Command Hit");
}
// _ => state = 0,
_ => break,
}
embassy_time::Timer::after(embassy_time::Duration::from_secs(2)).await;
// log::info!("{}", state);
state += 1;
}
}
pub struct LossyStr<'a>(pub &'a [u8]);
impl<'a> core::fmt::Debug for LossyStr<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match core::str::from_utf8(self.0) {
Ok(s) => write!(f, "{:?}", s),
Err(_) => write!(f, "{:?}", self.0),
}
}
}
#[entry]
fn main() -> ! {
init_heap();
esp_println::logger::init_logger_from_env();
log::info!("Logger is setup");
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock240MHz).freeze();
let mut delay = Delay::new(&clocks);
let timer_group0 = TimerGroup::new(
peripherals.TIMG0,
&clocks,
);
embassy::init(&clocks, timer_group0.timer0);
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
interrupt::enable(Interrupt::UART1, interrupt::Priority::Priority1).unwrap();
let (ingress, client, rx14) =
// let (tx, rx, signal) =
uart_device_setup(
// serial::uart_serial_setup(
delay,
io.pins.gpio15,
io.pins.gpio14,
peripherals.UART1,
&clocks,
);
println!("Starting embassy executor ...");
// let executor = make_static!(embassy_executor::Executor::new());
// let executor = make_static!(hal::embassy::executor::Executor::new());
static CELL: static_cell::StaticCell<hal::embassy::executor::Executor> = static_cell::StaticCell::new();
let executor = CELL.init(hal::embassy::executor::Executor::new());
executor.run(|spawner| {
let _ = spawner.spawn(ingress_task(ingress, rx14));
let _ = spawner.spawn(test_send(client));
})
}
pub fn uart_device_setup(
mut delay: Delay,
gpio15: GpioPin<hal::gpio::Unknown, 15>,
gpio14: GpioPin<hal::gpio::Unknown, 14>,
UART1_per: UART1,
clocks: &Clocks<'static>
) -> (
Ingress<'static, AtDigester<modem::Urc>, modem::Urc, INGRESS_BUF_SIZE, URC_CAPACITY, URC_SUBSCRIBERS>,
atat::asynch::Client<'static, UartTx<'static, hal::peripherals::UART1>, INGRESS_BUF_SIZE>,
UartRx<'static, UART1>
){
let modem_uart_pins = TxRxPins::new_tx_rx(
gpio15.into_push_pull_output(),
gpio14.into_floating_input(),
);
let config = Config {
baudrate: 115200,
data_bits: DataBits::DataBits8,
parity: Parity::ParityNone,
stop_bits: StopBits::STOP1,
};
// UART interface for the GSM modem
let mut uart = Uart::new_with_config(
UART1_per,
config,
Some(modem_uart_pins),
&clocks,
);
uart.set_at_cmd(AtCmdConfig::new(None, None, None, AT_CMD, None));
uart.set_rx_fifo_full_threshold(READ_BUF_SIZE as u16).unwrap();
// uart.set_rx_fifo_full_threshold(1).unwrap();
let (mut tx, mut rx) = uart.split();
static BUFFERS: Buffers<modem::Urc, INGRESS_BUF_SIZE, URC_CAPACITY, URC_SUBSCRIBERS> =
Buffers::<modem::Urc, INGRESS_BUF_SIZE, URC_CAPACITY, URC_SUBSCRIBERS>::new();
let digester = DefaultDigester::<modem::Urc>::default();
// .with_custom_success(|buf| {
// let mut mbuf = buf.to_vec(); // Make a mutable copy
// let filtered_buf = filter_sequence(&mut mbuf);
// let result = core::str::from_utf8(&filtered_buf);//.unwrap_or("Invalid UTF-8");
// match result {
// Ok(data_str) => {
// println!("Valid UTF-8:\n {}", data_str);
// }
// Err(e) => {
// // println!("Invalid UTF-8:\n {:?}", mbuf);
// println!("Invalid UTF-8:\n {:?}", e);
// }
// }
// Ok((buf, buf.len()))
// });
// Atat client
let config = atat::Config::default()
.flush_timeout(Duration::from_millis(2000))
.cmd_cooldown(Duration::from_millis(200))
.tx_timeout(Duration::from_millis(2000));
let (ingress, client) = BUFFERS.split(
tx,
digester,
config,
);
(ingress, client, rx)
}
fn filter_sequence(buf: &mut [u8]) -> &[u8] {
let mut read_idx = 0;
let mut write_idx = 0;
while read_idx < buf.len() {
let byte = buf[read_idx];
if byte != 0 && byte != 202 && byte != 61 && byte != 129 && byte != 37
{
buf[write_idx] = byte;
write_idx += 1;
}
read_idx += 1;
}
&buf[..write_idx]
}
fn replace_newline_with_ctrl_d(input_str: &[u8]) -> alloc::vec::Vec<u8> {
// Byte value for Ctrl+D
let ctrl_d: u8 = 4;
// Replace "\n" with Ctrl+D in the input string
let mut replaced_str = input_str.to_vec();
for byte in replaced_str.iter_mut() {
if *byte == b'\n' {
*byte = ctrl_d;
}
}
replaced_str
}