Skip to content
Snippets Groups Projects
Commit 36b53972 authored by Marvin Gudel's avatar Marvin Gudel
Browse files

Merge branch 'feature/embedded-hal-1.0' into 'main'

Update to embedded-hal 1.0

See merge request silicon-economy/libraries/serum/quectel-bg77!9
parents 6ccab199 471333e1
No related branches found
Tags v0.3.0
No related merge requests found
Pipeline #6072 failed
......@@ -7,8 +7,13 @@ build:
script:
- nix-shell --pure --run 'cargo build --features bg77'
- nix-shell --pure --run 'cargo build --features bg770'
build-examples:
stage: build
script:
- nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo build --examples --features sensing_puck --target thumbv7em-none-eabihf'
- nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo build --examples --features motion2se --target thumbv7em-none-eabihf'
allow_failure: true
check-formatting:
stage: lint
......@@ -23,18 +28,25 @@ cargo-readme:
clippy:
stage: lint
script:
- nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo clippy --examples --features sensing_puck --target thumbv7em-none-eabihf' # automatically tests the lib
- nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo clippy --examples --features motion2se --target thumbv7em-none-eabihf' # automatically tests the lib
# - nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo clippy --examples --features sensing_puck --target thumbv7em-none-eabihf' # automatically tests the lib
# - nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo clippy --examples --features motion2se --target thumbv7em-none-eabihf' # automatically tests the lib
- nix-shell --pure --run 'cargo clippy --tests --features bg77'
- nix-shell --pure --run 'cargo clippy --tests --features bg77 --message-format=json > clippy.out'
# The same three steps with --message-format=json for gitlab-clippy
- nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo clippy --examples --features sensing_puck --target thumbv7em-none-eabihf --message-format=json > clippy.out'
- nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo clippy --examples --features motion2se --target thumbv7em-none-eabihf --message-format=json >> clippy.out'
- nix-shell --pure --run 'cargo clippy --tests --features bg77 --message-format=json >> clippy.out'
# - nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo clippy --examples --features sensing_puck --target thumbv7em-none-eabihf --message-format=json >> clippy.out'
# - nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo clippy --examples --features motion2se --target thumbv7em-none-eabihf --message-format=json >> clippy.out'
- nix-shell --pure --run 'cat clippy.out | gitlab-clippy > gl-code-quality-report.json'
artifacts:
reports:
codequality: gl-code-quality-report.json
clippy-examples:
stage: lint
script:
- nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo clippy --examples --features sensing_puck --target thumbv7em-none-eabihf' # automatically tests the lib
- nix-shell --pure --arg example true --run 'BG77_REMOTE=127.0.0.1:12345 cargo clippy --examples --features motion2se --target thumbv7em-none-eabihf' # automatically tests the lib
allow_failure: true
check-licenses:
stage: lint
script:
......
# Changelog
## Current Development
## v.0.3.0
- Update to _Rust_ 1.82.0 and _nixpkgs_ 24.05
- Update to _embedded-hal_ 1.0
- Use of embedded-timers and embedded-hal-nb
- Improve logging
- Exchange timer fields of `Bg77Hal` for single clock reference
- Add constructor function for `Bg77Hal`
- Clarify behaviour of _PWRKEY_
## v0.2.3 - 2024-10-31
- Configure `bg77` feature in `package.metadata.docs.rs` to build documentation on docs.rs
......
[package]
name = "quectel-bg77"
description = "Driver for Quectel's BG77 and BG770 eMTC and NB-IoT Modems"
version = "0.2.3"
version = "0.3.0"
authors = [ "Fraunhofer IML Embedded Rust Group <embedded-rust@iml.fraunhofer.de>" ]
repository = "https://git.openlogisticsfoundation.org/silicon-economy/libraries/serum/quectel-bg77"
edition = "2018"
license = "OLFL-1.3"
keywords = ["bg77", "quectel", "no_std"]
categories = ["embedded", "hardware-support", "no-std"]
resolver = "2"
[package.metadata.docs.rs]
features = ["bg77"]
......@@ -23,7 +24,9 @@ motion2se = ["bg770"]
direct-serial-access = []
[dependencies]
embedded-hal = "0.2.4"
embedded-hal = "1"
embedded-hal-nb = "1"
embedded-timers = "0.4.0"
heapless = "0.7.3"
log = "0.4.14"
nb = "1.0.0"
......@@ -36,11 +39,12 @@ void = { version = "1.0.2", default-features = false }
inverted-pin = "0.2.0"
# dependencies for tests and doc tests (exclude from examples)
[target.'cfg(any(windows, unix))'.dev-dependencies]
[target.'cfg(not(target_os="none"))'.dev-dependencies]
embedded-hal-mock = "0.8"
embedded-timers = { version = "0.4.0", features = ["std"]}
# dev-dependencies for running the examples on an stm32l4x2 MCU (exclude from tests)
[target.'cfg(not(any(windows, unix)))'.dev-dependencies]
[target.thumbv7em-none-eabihf.dev-dependencies]
stm32l4xx-hal = { git = "https://github.com/stm32-rs/stm32l4xx-hal", rev = "bf2ded1fcabe782168d132500d95f9bd1acf48c1", features = ["stm32l452", "rt"] }
cortex-m = "0.7.2"
cortex-m-rt = "0.6.13"
......
......@@ -28,15 +28,14 @@ use embedded_nal::TcpClientStack;
// The hardware abstraction used for the Bg77Hal must implement the respective embedded-hal
// traits
let bg77_hal = quectel_bg77::Bg77Hal {
pin_enable: bg77_enable,
pin_reset_n: bg77_reset_n,
pin_pwrkey: bg77_pwrkey,
tx: bg77_tx,
rx: bg77_rx,
at_timer,
modem_timer,
};
let bg77_hal = quectel_bg77::Bg77Hal::new(
bg77_enable,
bg77_reset_n,
bg77_pwrkey,
bg77_tx,
bg77_rx,
&Clock,
);
// choose which radio technologies and bands to use
let radio_config = quectel_bg77::RadioConfig::OnlyNbiot {
bands: quectel_bg77::NbiotBand::B8.into(),
......@@ -64,6 +63,9 @@ bg77.close(socket).unwrap();
```
## Examples
> ❗ __Note:__ Examples are currently broken.
> The used stm32 HAL does not support _embedded-hal_ `1.0` and needs to be replaced.
There are a few examples which can be run on appropriate hardware. This driver was initially
developed alongside the
[Sensing Puck](https://www.silicon-economy.com/neue-open-source-hardware-sensing-puck-laesst-sich-einfach-integrieren/)
......@@ -88,7 +90,7 @@ the `--lib` flag: `cargo test --lib`
- `bg77` / `bg770` selects the modem in use
- `sensing_puck` / `motion2se` selects the board for the examples
- `direct-serial-access` Enables direct access to the underlying serial port. This should be
used for development/debugging only.
used for development/debugging only.
## License
Open Logistics Foundation License\
......
......@@ -5,9 +5,9 @@ let
# additional targets like shown below.
rust_overlay = import
(builtins.fetchTarball {
name = "rust-overlay-2024-01-15";
url = "https://github.com/oxalica/rust-overlay/archive/d681ac8a92a1cce066df1d3a5a7f7c909688f4be.tar.gz";
sha256 = "1mrcbw14dlch89hnncs7pnm7lh4isqx7xywha6i97d8xs24spfvv";
name = "rust-overlay-2024-11-19";
url = "https://github.com/oxalica/rust-overlay/archive/71287228d96e9568e1e70c6bbfa3f992d145947b.tar.gz";
sha256 = "1sg1myrnrfyv7jn5srinrfinvbz8qzly5mmd3rshz9dl0039lh14";
});
# Our own overlay with additional build environment tools
......@@ -20,10 +20,10 @@ let
# Pinned nixpkgs
nixpkgsBase = import (builtins.fetchTarball {
name = "nixpkgs-stable-23.11";
url = "https://github.com/NixOS/nixpkgs/archive/refs/tags/23.11.tar.gz";
name = "nixpkgs-stable-24.05";
url = "https://github.com/NixOS/nixpkgs/archive/refs/tags/24.05.tar.gz";
# sha256 = "0000000000000000000000000000000000000000000000000000";
sha256 = "1ndiv385w1qyb3b18vw13991fzb9wg4cl21wglk89grsfsnra41k";
sha256 = "1lr1h35prqkd1mkmzriwlpvxcb34kmhc9dnr48gkm8hh089hifmx";
});
nixpkgs = nixpkgsBase {
......@@ -34,8 +34,8 @@ let
# For nightly, we use a specific one so we do not download a new compiler every day
rustChannel = (
if nightly
then nixpkgs.rust-bin.nightly."2024-01-15"
else nixpkgs.rust-bin.stable."1.73.0"
then nixpkgs.rust-bin.nightly."2024-11-19"
else nixpkgs.rust-bin.stable."1.82.0"
).default;
rust = if example
......
......@@ -5,38 +5,39 @@
// SPDX-License-Identifier: OLFL-1.3
use core::time::Duration;
use embedded_hal_nb::serial::{Read, Write};
use embedded_timers::{clock::Clock, timer::Timer};
use heapless::Vec;
use try_ascii::try_ascii;
use crate::error::Bg77Error;
use crate::util::wait;
use crate::{error::Bg77Error, util::*};
/// Helper type to assist in running AT commands, especially in parsing the responses
pub struct AtHelper<TX, RX, E, TIMER>
pub struct AtHelper<'a, TX, RX, E, CLOCK>
where
TX: embedded_hal::serial::Write<u8, Error = E>,
RX: embedded_hal::serial::Read<u8, Error = E>,
TIMER: embedded_hal::timer::CountDown<Time = Duration>,
TX: Write<u8, Error = E>,
RX: Read<u8, Error = E>,
CLOCK: Clock,
{
tx: TX,
rx: RX,
timer: TIMER,
timer: Timer<'a, CLOCK>,
tx_rx_cooldown: Duration,
input: Vec<u8, 2048>, // TODO generic size
}
impl<TX, RX, E, TIMER> AtHelper<TX, RX, E, TIMER>
impl<'a, TX, RX, E, CLOCK> AtHelper<'a, TX, RX, E, CLOCK>
where
E: core::fmt::Debug,
TX: embedded_hal::serial::Write<u8, Error = E>,
RX: embedded_hal::serial::Read<u8, Error = E>,
TIMER: embedded_hal::timer::CountDown<Time = Duration>,
TX: Write<u8, Error = E>,
RX: Read<u8, Error = E>,
CLOCK: Clock,
{
pub fn new(tx: TX, rx: RX, timer: TIMER, tx_rx_cooldown: Duration) -> Self {
pub fn new(tx: TX, rx: RX, clock: &'a CLOCK, tx_rx_cooldown: Duration) -> Self {
AtHelper {
tx,
rx,
timer,
timer: Timer::new(clock),
tx_rx_cooldown,
input: Vec::new(),
}
......@@ -58,15 +59,26 @@ where
// beginning of the answer, extract the data length and then just
// read the raw data into the target buffer.
// TODO Nicer error handling for rx errors, e.g. Overflows?
while let Ok(byte) = self.rx.read() {
self.input.push(byte).map_err(|_| {
log::trace!("RxBytes {:?}", try_ascii(&self.input[oldlen..]));
log::warn!("Input buffer overflow. Use a bigger input buffer to prevent this kind of error.");
Bg77Error::BufferOverflow
})?;
loop {
match self.rx.read() {
Ok(byte) => {
self.input.push(byte).map_err(|_| {
log::debug!("RxBytes {:?}", try_ascii(&self.input[oldlen..]));
log::warn!("Input buffer overflow. Use a bigger input buffer to prevent this kind of error.");
Bg77Error::BufferOverflow
})?;
}
Err(nb::Error::WouldBlock) => break,
Err(nb::Error::Other(e)) => {
log::error!("rx read error: {:?}", e);
break;
}
}
}
if self.input.len() != oldlen {
log::trace!("RxBytes {:?}", try_ascii(&self.input[oldlen..]));
log::debug!("RxBytes {:?}", try_ascii(&self.input[oldlen..]));
}
Ok(())
}
......
......@@ -6,6 +6,7 @@
use core::fmt::Write;
use core::time::Duration;
use embedded_timers::{clock::Clock, timer::Timer};
use enumflags2::{bitflags, BitFlags};
use heapless::String;
......@@ -174,21 +175,21 @@ fn format_bands(bands: BitFlags<Band>) -> String<22> {
///
/// The methods should only be called if the modem is in the right state, i.e. this should be
/// wrapped by a type taking care of the internal modem state.
pub struct Bg77CmdFlows<P0, P1, P2, TX, RX, UE, TIMER>
pub struct Bg77CmdFlows<'a, P0, P1, P2, TX, RX, UE, CLOCK>
where
P0: embedded_hal::digital::v2::OutputPin,
P1: embedded_hal::digital::v2::OutputPin,
P2: embedded_hal::digital::v2::OutputPin,
P0: embedded_hal::digital::OutputPin,
P1: embedded_hal::digital::OutputPin,
P2: embedded_hal::digital::OutputPin,
UE: core::fmt::Debug,
TX: embedded_hal::serial::Write<u8, Error = UE>,
RX: embedded_hal::serial::Read<u8, Error = UE>,
TIMER: embedded_hal::timer::CountDown<Time = Duration>,
TX: embedded_hal_nb::serial::Write<u8, Error = UE>,
RX: embedded_hal_nb::serial::Read<u8, Error = UE>,
CLOCK: Clock,
{
pin_enable: P0,
pin_reset_n: P1,
pin_pwrkey: P2,
timer: TIMER,
at: atst_commands::AtHelper<TX, RX, UE, TIMER>,
timer: Timer<'a, CLOCK>,
at: atst_commands::AtHelper<'a, TX, RX, UE, CLOCK>,
radio_config: RadioConfig,
apn: Option<String<32>>,
operator: Option<String<8>>,
......@@ -196,15 +197,15 @@ where
delay_before_attach: Duration,
}
impl<P0, P1, P2, TX, RX, UE, TIMER> Bg77CmdFlows<P0, P1, P2, TX, RX, UE, TIMER>
impl<'a, P0, P1, P2, TX, RX, UE, CLOCK> Bg77CmdFlows<'a, P0, P1, P2, TX, RX, UE, CLOCK>
where
P0: embedded_hal::digital::v2::OutputPin,
P1: embedded_hal::digital::v2::OutputPin,
P2: embedded_hal::digital::v2::OutputPin,
P0: embedded_hal::digital::OutputPin,
P1: embedded_hal::digital::OutputPin,
P2: embedded_hal::digital::OutputPin,
UE: core::fmt::Debug,
TX: embedded_hal::serial::Write<u8, Error = UE>,
RX: embedded_hal::serial::Read<u8, Error = UE>,
TIMER: embedded_hal::timer::CountDown<Time = Duration>,
TX: embedded_hal_nb::serial::Write<u8, Error = UE>,
RX: embedded_hal_nb::serial::Read<u8, Error = UE>,
CLOCK: Clock,
{
/// Creates a new Bg77CmdFlows instance
///
......@@ -213,7 +214,7 @@ where
/// experienced connection issues on a low-power device when doing this too fast. This delay
/// helped but could/should be avoided on devices where it is not necessary.
pub fn new(
hal: Bg77Hal<P0, P1, P2, TX, RX, UE, TIMER>,
hal: Bg77Hal<'a, P0, P1, P2, TX, RX, CLOCK>,
radio_config: RadioConfig,
apn: Option<&str>,
operator: Option<&str>,
......@@ -225,8 +226,8 @@ where
pin_enable: hal.pin_enable,
pin_reset_n: hal.pin_reset_n,
pin_pwrkey: hal.pin_pwrkey,
timer: hal.modem_timer,
at: atst_commands::AtHelper::new(hal.tx, hal.rx, hal.at_timer, tx_rx_cooldown),
timer: Timer::new(hal.clock),
at: atst_commands::AtHelper::new(hal.tx, hal.rx, hal.clock, tx_rx_cooldown),
radio_config,
apn: apn.map(|a| a.into()),
operator: operator.map(|o| o.into()),
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment