Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP Modem #469

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[build]
target = "riscv32imc-esp-espidf"
# target = "riscv32imc-esp-espidf"
#target = "xtensa-esp32-espidf"
target = "xtensa-esp32s3-espidf"

[target.xtensa-esp32-espidf]
linker = "ldproxy"
Expand Down
6 changes: 6 additions & 0 deletions .github/configs/sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ CONFIG_ETH_SPI_ETHERNET_DM9051=y
CONFIG_ETH_SPI_ETHERNET_W5500=y
CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL=y

# GSM
CONFIG_LWIP_PPP_SUPPORT=y
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=2048
CONFIG_LWIP_PPP_ENABLE_IPV6=n


# We don't have an example for classic BT - yet - we need to enable class BT
# specifically to workaround this bug in ESP IDF v5.2 (fixed in ESP IDF v5.2.1+):
# https://github.com/espressif/esp-idf/issues/13113
Expand Down
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,13 @@ uncased = { version = "0.9.7", default-features = false }
embedded-hal-async = { version = "1", default-features = false }
embedded-svc = { version = "0.28", default-features = false }
esp-idf-hal = { version = "0.44", default-features = false }
embassy-time-driver = { version = "0.1", optional = true, features = ["tick-hz-1_000_000"] }
# esp-idf-hal = { path = "../esp-idf-hal" }
embassy-time-driver = { version = "0.1", optional = true, features = [
"tick-hz-1_000_000",
] }
embassy-futures = "0.1"
futures-io = { version = "0.3", optional = true }
at-commands = "0.5.4"

[build-dependencies]
embuild = "0.32"
Expand Down
8 changes: 8 additions & 0 deletions espflash.toml
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
partition_table = "partitions.csv"

[connection]

[[usb_device]]
vid = "303a"
pid = "1001"

[flash]
147 changes: 147 additions & 0 deletions examples/lte_modem.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
//! Example of using blocking wifi.
//!
//! Add your own ssid and password

use std::{thread::ScopedJoinHandle, time::Duration};

use embedded_svc::{
http::{client::Client as HttpClient, Method},
utils::io,
};

use esp_idf_hal::uart::UartDriver;
use esp_idf_hal::units::Hertz;
use esp_idf_hal::{
delay,
gpio::{self, PinDriver},
};
use esp_idf_svc::modem::sim::sim7600::SIM7600;
use esp_idf_svc::modem::sim::SimModem;
use esp_idf_svc::modem::EspModem;
use esp_idf_svc::{eventloop::EspSystemEventLoop, modem::BufferedRead};
use esp_idf_svc::{hal::prelude::Peripherals, http::client::EspHttpConnection};
use esp_idf_svc::{log::EspLogger, modem::ModemPhaseStatus};

use log::{error, info};

// const SSID: &str = env!("WIFI_SSID");
// const PASSWORD: &str = env!("WIFI_PASS");

fn main() -> anyhow::Result<()> {
esp_idf_svc::sys::link_patches();
EspLogger::initialize_default();

let peripherals = Peripherals::take()?;
let sys_loop = EspSystemEventLoop::take()?;

let serial = peripherals.uart2;
let tx = peripherals.pins.gpio17;
let rx = peripherals.pins.gpio18;

let mut lte_reset = PinDriver::output(peripherals.pins.gpio42).unwrap();
lte_reset.set_low().unwrap();

let mut lte_power = PinDriver::output(peripherals.pins.gpio41).unwrap();
let mut lte_on = PinDriver::output(peripherals.pins.gpio40).unwrap();
// turn lte device on
log::info!("Reset GSM Device");
lte_power.set_high().unwrap();
let delay = delay::Delay::new_default();
delay.delay_ms(100);
lte_on.set_high().unwrap();
delay.delay_ms(100);
lte_on.set_low().unwrap();
delay.delay_ms(10000);
log::info!("Reset Complete");

let mut serial = UartDriver::new(
serial,
tx,
rx,
Option::<gpio::Gpio0>::None,
Option::<gpio::Gpio0>::None,
&esp_idf_hal::uart::UartConfig {
baudrate: Hertz(115200),
..Default::default()
},
)?;

let mut buff = [0u8; 1024];

let (mut tx, rx) = serial.split();

let mut buf_reader = BufferedRead::new(rx, &mut buff);

let mut sim_device = SIM7600::new();

match sim_device.negotiate(&mut tx, &mut buf_reader) {
Err(x) => log::error!("Error = {}", x),
Ok(()) => log::info!("Device in PPP mode"),
}

let modem = EspModem::new(&mut tx, &mut buf_reader, sys_loop)?;

let _scope = std::thread::scope::<_, anyhow::Result<()>>(|s| {
let my_thread: ScopedJoinHandle<anyhow::Result<()>> = s.spawn(|| {
let mut buff = [0u8; 64];

match modem.run(&mut buff) {
Err(x) => log::error!("Error: {:?}", x),
Ok(_x) => (),
};
Ok(())
});
std::thread::sleep(Duration::from_secs(10));

let mut client = HttpClient::wrap(EspHttpConnection::new(&Default::default())?);

// GET
loop {
std::thread::sleep(Duration::from_secs(10));
match get_request(&mut client) {
Err(x) => log::error!("Failed, reason = {}", x),
Ok(_) => break,
}
}
my_thread.join().unwrap()?;
Ok(())
});

std::thread::sleep(core::time::Duration::from_secs(5));

Ok(())
}

/// Send an HTTP GET request.
fn get_request(client: &mut HttpClient<EspHttpConnection>) -> anyhow::Result<()> {
// Prepare headers and URL
let headers = [("accept", "text/plain")];
let url = "http://ifconfig.net/";

// Send request
//
// Note: If you don't want to pass in any headers, you can also use `client.get(url, headers)`.
let request = client.request(Method::Get, url, &headers)?;
info!("-> GET {}", url);
let mut response = request.submit()?;

// Process response
let status = response.status();
info!("<- {}", status);
let mut buf = [0u8; 1024];
let bytes_read = io::try_read_full(&mut response, &mut buf).map_err(|e| e.0)?;
info!("Read {} bytes", bytes_read);
match std::str::from_utf8(&buf[0..bytes_read]) {
Ok(body_string) => info!(
"Response body (truncated to {} bytes): {:?}",
buf.len(),
body_string
),
Err(e) => error!("Error decoding response body: {}", e),
};

// Drain the remaining response bytes
while response.read(&mut buf)? > 0 {}

Ok(())
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub mod mdns;
esp_idf_comp_mqtt_enabled,
esp_idf_comp_esp_event_enabled
))]
pub mod modem;
pub mod mqtt;
#[cfg(esp_idf_lwip_ipv4_napt)]
pub mod napt;
Expand Down
Loading
Loading