Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fbd8412c2
|
||
|
|
ebd576b4e2
|
No files matched your search
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.3.1] - 2026-04-23
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **LilyGo T-Beam (classic) red LED now flashes on TX/RX** instead of
|
||||||
|
dimming off. The red LED under the OLED is wired active-LOW on this
|
||||||
|
board (anode to V+, cathode to GPIO4); v1.3.0 drove it as active-HIGH,
|
||||||
|
so the LED sat lit at idle and briefly dimmed during activity.
|
||||||
|
- Empirically verified on hardware against both T-Beam variants.
|
||||||
|
- Introduces `src/driver/inverted_pin.rs::InvertedPin<P>`, a generic
|
||||||
|
`OutputPin` wrapper that swaps `set_high`/`set_low`. Polarity is
|
||||||
|
expressed at the pin (where the physical wiring lives), so
|
||||||
|
`SimpleLed` stays polarity-agnostic and every other board's code
|
||||||
|
path is byte-for-byte unchanged.
|
||||||
|
- Classic T-Beam now constructs its LED as
|
||||||
|
`SimpleLed(InvertedPin(led_pin))` with pin init at `Level::High`
|
||||||
|
(dark at boot).
|
||||||
|
|
||||||
## [1.3.0] - 2026-04-23
|
## [1.3.0] - 2026-04-23
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
Generated
+1
-1
@@ -486,7 +486,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "donglora"
|
name = "donglora"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cortex-m",
|
"cortex-m",
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ members = ["."]
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "donglora"
|
name = "donglora"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
authors = ["Stephen Waits <steve@waits.net>"]
|
authors = ["Stephen Waits <steve@waits.net>"]
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
//! LoRa ctl: RESET=23, DIO0=26 (primary IRQ — SX127x has no BUSY)
|
//! LoRa ctl: RESET=23, DIO0=26 (primary IRQ — SX127x has no BUSY)
|
||||||
//! OLED I²C: SDA=21, SCL=22, SSD1306 @ 0x3C (shared with AXP192 @ 0x34)
|
//! OLED I²C: SDA=21, SCL=22, SSD1306 @ 0x3C (shared with AXP192 @ 0x34)
|
||||||
//! UART host: TX=1, RX=3 via CP2102 bridge (USB 10c4:ea60)
|
//! UART host: TX=1, RX=3 via CP2102 bridge (USB 10c4:ea60)
|
||||||
//! LED: GPIO4 (active HIGH — reuses MeshCore's P_LORA_TX_LED)
|
//! LED: GPIO4 (active LOW — red LED under the OLED, wrapped in
|
||||||
|
//! InvertedPin so SimpleLed sees normal polarity)
|
||||||
//!
|
//!
|
||||||
//! GPS / battery / IMU / PCF8563 RTC are populated on the board but unused
|
//! GPS / battery / IMU / PCF8563 RTC are populated on the board but unused
|
||||||
//! by this firmware.
|
//! by this firmware.
|
||||||
@@ -24,6 +25,7 @@ use esp_hal::i2c::master::{Config as I2cConfig, I2c};
|
|||||||
use super::esp32;
|
use super::esp32;
|
||||||
use super::traits::{BoardParts, LoRaBoard};
|
use super::traits::{BoardParts, LoRaBoard};
|
||||||
use crate::driver::axp;
|
use crate::driver::axp;
|
||||||
|
use crate::driver::inverted_pin::InvertedPin;
|
||||||
use crate::driver::simple_led::SimpleLed;
|
use crate::driver::simple_led::SimpleLed;
|
||||||
use crate::hal::esp32 as mcu;
|
use crate::hal::esp32 as mcu;
|
||||||
use crate::protocol::RadioChipId;
|
use crate::protocol::RadioChipId;
|
||||||
@@ -33,7 +35,7 @@ pub use super::esp32::{create_display, DisplayDriver, DisplayParts, RadioDriver,
|
|||||||
// ── Concrete peripheral types ───────────────────────────────────────
|
// ── Concrete peripheral types ───────────────────────────────────────
|
||||||
|
|
||||||
pub type UartDriver = esp_hal::uart::Uart<'static, esp_hal::Async>;
|
pub type UartDriver = esp_hal::uart::Uart<'static, esp_hal::Async>;
|
||||||
pub type LedDriver = SimpleLed<Output<'static>>;
|
pub type LedDriver = SimpleLed<InvertedPin<Output<'static>>>;
|
||||||
|
|
||||||
// ── Peripheral bundles ──────────────────────────────────────────────
|
// ── Peripheral bundles ──────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -122,9 +124,10 @@ impl LoRaBoard for Board {
|
|||||||
i2c: i2c_blocking.into_async(),
|
i2c: i2c_blocking.into_async(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// TX activity LED on GPIO4 (active HIGH).
|
// TX activity LED on GPIO4 (active LOW — pin idles HIGH = LED off).
|
||||||
let led_pin = Output::new(p.GPIO4, Level::Low, OutputConfig::default());
|
// InvertedPin flips set_high/set_low so SimpleLed stays polarity-agnostic.
|
||||||
let led = SimpleLed(led_pin);
|
let led_pin = Output::new(p.GPIO4, Level::High, OutputConfig::default());
|
||||||
|
let led = SimpleLed(InvertedPin(led_pin));
|
||||||
|
|
||||||
BoardParts {
|
BoardParts {
|
||||||
radio,
|
radio,
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
//! Generic `OutputPin` wrapper that inverts logic levels.
|
||||||
|
//!
|
||||||
|
//! When a peripheral is wired active-low (LED anode to V+, cathode to GPIO;
|
||||||
|
//! reset line idle-high, etc.) the physical polarity is a property of the
|
||||||
|
//! board, not of the driver. Wrapping the pin in `InvertedPin` lets drivers
|
||||||
|
//! keep "set_high = assert" semantics while the board file expresses the
|
||||||
|
//! wiring reality at construction time.
|
||||||
|
//!
|
||||||
|
//! ```ignore
|
||||||
|
//! let pin = Output::new(p.GPIO4, Level::High, OutputConfig::default()); // off
|
||||||
|
//! let led = SimpleLed(InvertedPin(pin)); // driver sees normal polarity
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
use embedded_hal::digital::{ErrorType, OutputPin};
|
||||||
|
|
||||||
|
pub struct InvertedPin<P>(pub P);
|
||||||
|
|
||||||
|
impl<P: ErrorType> ErrorType for InvertedPin<P> {
|
||||||
|
type Error = P::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: OutputPin> OutputPin for InvertedPin<P> {
|
||||||
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.0.set_high()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.0.set_low()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,9 @@ pub mod sh1106;
|
|||||||
#[cfg(any(feature = "lilygo_tbeam_supreme", feature = "lilygo_tbeam"))]
|
#[cfg(any(feature = "lilygo_tbeam_supreme", feature = "lilygo_tbeam"))]
|
||||||
pub mod axp;
|
pub mod axp;
|
||||||
|
|
||||||
|
#[cfg(feature = "lilygo_tbeam")]
|
||||||
|
pub mod inverted_pin;
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "heltec_v3",
|
feature = "heltec_v3",
|
||||||
feature = "heltec_v3_uart",
|
feature = "heltec_v3_uart",
|
||||||
|
|||||||
Reference in new issue
Block a user