diff --git a/Cargo.toml b/Cargo.toml index 8acd900..6a0ccc7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,33 @@ edition = "2021" license = "-" [dependencies] -hal = { package = "esp32-hal", version = "0.15.0" } esp-backtrace = { version = "0.8.0", features = ["esp32", "panic-handler", "exception-handler", "print-uart"] } esp-println = { version = "0.6.0", features = ["esp32"] } +atat = { path = "../atat/atat", features = ["log", "async"] } +atat_derive = { path = "../atat/atat_derive" } +serde_at = { path = "../atat/serde_at" } +heapless = "0.7.16" +embassy-time = "0.1.3" +embedded-io-async = "0.5.0" +static_cell = "1.2.0" +embassy-executor = { version = "0.3.0", features = ["nightly"] } + +[dependencies.hal] +package = "esp32-hal" +git = "https://github.com/esp-rs/esp-hal/" +features = [ + "async", + "embassy", + "embassy-executor-thread", + "embassy-time", + "embassy-time-timg0", +] + +[dependencies.esp-hal-common] +package = "esp-hal-common" +git = "https://github.com/esp-rs/esp-hal/" +features = [ + "async", + "esp32", + "esp32_40mhz", +] diff --git a/src/main.rs b/src/main.rs index 8a978bc..def0aa2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,46 +1,90 @@ #![no_std] #![no_main] +#![feature(type_alias_impl_trait)] + +mod modem; use esp_backtrace as _; use esp_println::println; use hal::{ clock::ClockControl, - gpio::{IO}, - peripherals::Peripherals, + embassy::{self, executor::Executor}, + gpio::IO, + interrupt, + peripherals::{Peripherals, Interrupt, UART1}, prelude::*, - prelude::nb::block, - Delay, + timer::TimerGroup, + Uart, uart::{ - TxRxPins, config::{ Config, + DataBits, Parity, StopBits, - DataBits, }, - Uart, - } + TxRxPins, + }, }; +use esp_hal_common::{UartRx, UartTx}; + +use atat::{asynch::AtatClient, AtatIngress, Buffers, DefaultDigester, Ingress}; +use heapless::Vec; +use static_cell::StaticCell; + +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 reader(mut rx: UartRx<'static, UART1>) { + esp_println::println!("reading..."); + // max message size to receive + // leave some extra space for AT-CMD characters + const MAX_BUFFER_SIZE: usize = 10 * READ_BUF_SIZE + 16; + + let mut rbuf: Vec = Vec::new(); + let mut offset = 0; + while let Ok(len) = embedded_io_async::Read::read(&mut rx, &mut rbuf[offset..]).await { + offset += len; + if offset == 0 { + rbuf.truncate(0); + break; + } + // if set_at_cmd is used than stop reading + if len < READ_BUF_SIZE { + rbuf.truncate(offset); + break; + } + } + +} #[entry] fn main() -> ! { let peripherals = Peripherals::take(); let mut system = peripherals.DPORT.split(); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut delay = Delay::new(&clocks); + + let timer_group0 = TimerGroup::new( + peripherals.TIMG0, + &clocks, + &mut system.peripheral_clock_control, + ); + + embassy::init(&clocks, timer_group0.timer0); let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); - // LilyGo A7670E serial pins. - // LilyGo TTGO T-Call sim800l board power / reset pins. + // Power on the LilyGo A7670E module. + let mut power = io.pins.gpio4.into_push_pull_output(); + power.set_high().ok(); + let modem_uart_pins = TxRxPins::new_tx_rx( io.pins.gpio26.into_push_pull_output(), io.pins.gpio27.into_floating_input(), ); - let mut power = io.pins.gpio4.into_push_pull_output(); - power.set_high().ok(); - let config = Config { baudrate: 115200, data_bits: DataBits::DataBits8, @@ -49,20 +93,32 @@ fn main() -> ! { }; // UART interface for the GSM modem - let mut serial = Uart::new_with_config( + let mut uart = Uart::new_with_config( peripherals.UART1, - Some(config), + config, Some(modem_uart_pins), &clocks, &mut system.peripheral_clock_control, ); + uart.set_rx_fifo_full_threshold(READ_BUF_SIZE as u16).unwrap(); - println!("Start"); - loop { - serial.write(0x42).ok(); - let read = block!(serial.read()).unwrap(); - println!("{}", read); + let (tx, rx) = uart.split(); - delay.delay_ms(1000_u32); - } + static BUFFERS: Buffers = + Buffers::::new(); + + let (ingress, client) = BUFFERS.split( + tx, + DefaultDigester::::default(), + atat::Config::default() + ); + + interrupt::enable(Interrupt::UART1, interrupt::Priority::Priority1).unwrap(); + + println!("Starting embassy executor ..."); + let cell = StaticCell::new(); + let executor: &'static mut Executor = cell.init(Executor::new()); + executor.run(|spawner| { + spawner.spawn(reader(rx)).unwrap(); + }); } diff --git a/src/modem/mod.rs b/src/modem/mod.rs new file mode 100644 index 0000000..d56876e --- /dev/null +++ b/src/modem/mod.rs @@ -0,0 +1,57 @@ +use embassy_time::{Instant, Duration}; +use atat::{ + atat_derive::{AtatCmd, AtatResp, AtatUrc}, + asynch::Client, + ResponseChannel, + Config, +}; +use embedded_io_async::Write; +use heapless::String; + +#[derive(Clone, AtatResp)] +pub struct NoResponse; + +#[derive(Clone, AtatCmd)] +#[at_cmd("+CSGT", NoResponse)] +pub struct SetGreetingText<'a> { + #[at_arg(position = 0, len = 32)] + pub text: &'a str, +} + +#[derive(Clone, AtatCmd)] +#[at_cmd("AT", GreetingText)] +pub struct GetGreetingText; + +#[derive(Clone, AtatResp)] +pub struct GreetingText { + #[at_arg(position = 0)] + pub text: String<64>, +} + +#[derive(Clone, AtatCmd)] +#[at_cmd("+CGMI", ManufacturerIdText)] +pub struct GetManufacturerId; + +#[derive(Clone, AtatResp)] +pub struct ManufacturerIdText { + #[at_arg(position = 0)] + pub text: String<32>, +} + +#[derive(Clone, AtatResp)] +pub struct MessageWaitingIndication; + +#[derive(Clone, AtatUrc)] +pub enum Urc { + #[at_urc("+UMWI")] + MessageWaitingIndication(MessageWaitingIndication), +} + +type ModemClient<'a, W> = Client<'a, W, 256>; + +pub fn setup_modem(tx: W, res_channel: &'_ ResponseChannel<256>) -> ModemClient<'_, W> +where W: Write { + let config = Config::new(); + let client: ModemClient = Client::new(tx, res_channel, config); + client +}