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

Make embedded-hal 0.2.7 dependency optional #42

Merged
merged 9 commits into from
Jan 29, 2024
Merged
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ jobs:
- gd32f190x4
- gd32f190x6
- gd32f190x8
extra-features:
- rt
- rt,embedded-hal-02
rust:
- stable
include:
Expand All @@ -41,4 +44,4 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: check
args: --features=${{ matrix.mcu }},rt --examples
args: --features=${{ matrix.mcu }},${{ matrix.extra-features }} --examples
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Breaking changes

- Moved `embedded-hal` 0.2 trait implementations behind the `embedded-hal-02` feature flag,
to make the dependency optional.

## [0.8.0]

### Breaking changes
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ embedded-dma = "0.2.0"
embedded-hal = "1.0.0"
embedded-hal-02 = { package = "embedded-hal", version = "0.2.7", features = [
"unproven",
] }
], optional = true }
embedded-io = "0.6.1"
gd32f1 = { version = "0.8.0", features = ["critical-section"] }
nb = "1.1.0"
Expand Down
3 changes: 1 addition & 2 deletions examples/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
use embedded_hal_02::adc::OneShot;
use gd32f1x0_hal::{adc::Adc, pac, prelude::*};

#[entry]
Expand Down Expand Up @@ -34,7 +33,7 @@
let mut ch0 = gpiob.pb0.into_analog(&mut gpiob.config);

loop {
let data: u16 = adc.read(&mut ch0).unwrap();
let data: u16 = adc.read_channel(&mut ch0);

Check warning on line 36 in examples/adc.rs

View workflow job for this annotation

GitHub Actions / clippy

the method `read_channel` doesn't need a mutable reference

warning: the method `read_channel` doesn't need a mutable reference --> examples/adc.rs:36:42 | 36 | let data: u16 = adc.read_channel(&mut ch0); | ^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed = note: `#[warn(clippy::unnecessary_mut_passed)]` on by default
hprintln!("adc1: {}", data);
}
}
12 changes: 7 additions & 5 deletions examples/blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@

use panic_halt as _;

use nb::block;

use core::hint::spin_loop;
use cortex_m_rt::entry;
use embedded_hal::digital::OutputPin;
use embedded_hal_02::timer::CountDown;
use gd32f1x0_hal::{pac, prelude::*, timer::Timer};

#[entry]
Expand Down Expand Up @@ -45,9 +43,13 @@ fn main() -> ! {

// Wait for the timer to trigger an update and change the state of the LED
loop {
block!(timer.wait()).unwrap();
while !timer.has_elapsed() {
spin_loop();
}
led.set_high().unwrap();
block!(timer.wait()).unwrap();
while !timer.has_elapsed() {
spin_loop();
}
led.set_low().unwrap();
}
}
12 changes: 7 additions & 5 deletions examples/blinky_generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@

use panic_halt as _;

use nb::block;

use core::hint::spin_loop;
use cortex_m_rt::entry;
use embedded_hal::digital::OutputPin;
use embedded_hal_02::timer::CountDown;
use gd32f1x0_hal::{pac, prelude::*, timer::Timer};

#[entry]
Expand Down Expand Up @@ -44,11 +42,15 @@ fn main() -> ! {

// Wait for the timer to trigger an update and change the state of the LED
loop {
block!(timer.wait()).unwrap();
while !timer.has_elapsed() {
spin_loop();
}
for led in leds.iter_mut() {
led.set_high().unwrap();
}
block!(timer.wait()).unwrap();
while !timer.has_elapsed() {
spin_loop();
}
for led in leds.iter_mut() {
led.set_low().unwrap();
}
Expand Down
8 changes: 2 additions & 6 deletions examples/blinky_timer_irq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ use panic_halt as _;
use core::cell::RefCell;
use cortex_m::{asm::wfi, interrupt::Mutex};
use cortex_m_rt::entry;
use embedded_hal_02::{
digital::v2::{OutputPin, ToggleableOutputPin},
timer::CountDown,
};
use embedded_hal::digital::{OutputPin, StatefulOutputPin};
use gd32f1x0_hal::{
gpio::{gpioc, Output, PushPull},
pac::{interrupt, Interrupt, Peripherals, TIMER1},
Expand Down Expand Up @@ -57,8 +54,7 @@ fn TIMER1() {
});

let _ = led.toggle();
// TODO: Shouldn't this just return?
let _ = tim.wait();
tim.clear_interrupt_flag(Event::Update);
}

#[entry]
Expand Down
16 changes: 8 additions & 8 deletions examples/pwm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use panic_halt as _;

use cortex_m::asm;
use cortex_m_rt::entry;
use embedded_hal_02::{Pwm, PwmPin};
use embedded_hal::pwm::SetDutyCycle;
use gd32f1x0_hal::{
gpio::{gpioa::PA11, OutputMode, PullMode},
pac,
Expand Down Expand Up @@ -61,41 +61,41 @@ fn main() -> ! {

asm::bkpt();

let max = pwm.get_max_duty();
let max = pwm.max_duty_cycle();

//// Operations affecting single channels can be accessed through
//// the Pwm object or via dereferencing to the pin.

// Use the Pwm object to set C2 to full strength
pwm.set_duty(Channel::C2, max);
pwm.set_duty_cycle(Channel::C2, max);

asm::bkpt();

// Use the Pwm object to set C2 to be dim
pwm.set_duty(Channel::C2, max / 4);
pwm.set_duty_cycle(Channel::C2, max / 4);

asm::bkpt();

// Use the Pwm object to set C2 to be zero
pwm.set_duty(Channel::C2, 0);
pwm.set_duty_cycle(Channel::C2, 0);

asm::bkpt();

// Extract the PwmChannel for C2
let mut pwm_channel = pwm.split().2.unwrap();

// Use the PwmChannel object to set C2 to be full strength
pwm_channel.set_duty(max);
pwm_channel.set_duty_cycle(max).unwrap();

asm::bkpt();

// Use the PwmChannel object to set C2 to be dim
pwm_channel.set_duty(max / 4);
pwm_channel.set_duty_cycle(max / 4).unwrap();

asm::bkpt();

// Use the PwmChannel object to set C2 to be zero
pwm_channel.set_duty(0);
pwm_channel.set_duty_cycle(0).unwrap();

asm::bkpt();

Expand Down
16 changes: 8 additions & 8 deletions examples/pwm_complementary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use panic_halt as _;

use cortex_m::asm;
use cortex_m_rt::entry;
use embedded_hal_02::{Pwm, PwmPin};
use embedded_hal::pwm::SetDutyCycle;
use gd32f1x0_hal::{
gpio::{OutputMode, PullMode},
pac,
Expand Down Expand Up @@ -81,41 +81,41 @@ fn main() -> ! {

asm::bkpt();

let max = pwm.get_max_duty();
let max = pwm.max_duty_cycle();

//// Operations affecting single channels can be accessed through
//// the Pwm object or via dereferencing to the pin.

// Use the Pwm object to set C2 to full strength
pwm.set_duty(Channel::C2, max);
pwm.set_duty_cycle(Channel::C2, max);

asm::bkpt();

// Use the Pwm object to set C2 to be dim
pwm.set_duty(Channel::C2, max / 4);
pwm.set_duty_cycle(Channel::C2, max / 4);

asm::bkpt();

// Use the Pwm object to set C2 to be zero
pwm.set_duty(Channel::C2, 0);
pwm.set_duty_cycle(Channel::C2, 0);

asm::bkpt();

// Extract the PwmChannel for C2
let mut pwm_channel = pwm.split().2.unwrap();

// Use the PwmChannel object to set C2 to be full strength
pwm_channel.set_duty(max);
pwm_channel.set_duty_cycle(max).unwrap();

asm::bkpt();

// Use the PwmChannel object to set C2 to be dim
pwm_channel.set_duty(max / 4);
pwm_channel.set_duty_cycle(max / 4).unwrap();

asm::bkpt();

// Use the PwmChannel object to set C2 to be zero
pwm_channel.set_duty(0);
pwm_channel.set_duty_cycle(0).unwrap();

asm::bkpt();

Expand Down
1 change: 0 additions & 1 deletion examples/timer-interrupt-rtic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use panic_halt as _;
use rtic::app;

use embedded_hal::digital::OutputPin;
use embedded_hal_02::timer::CountDown;
use gd32f1x0_hal::{
gpio::{gpioc::PC13, Output, PushPull},
pac,
Expand Down
41 changes: 30 additions & 11 deletions src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,21 @@ use crate::pac::{
};
use crate::rcu::{Clocks, Enable, Reset, APB2};
use core::{
convert::Infallible,
marker::PhantomData,
sync::atomic::{self, Ordering},
};
use cortex_m::asm::delay;
use embedded_dma::WriteBuffer;
use embedded_hal_02::adc::{Channel, OneShot};
#[cfg(feature = "embedded-hal-02")]
use embedded_hal_02::adc::Channel as _;

#[cfg(feature = "embedded-hal-02")]
pub trait Channel<ADC>: embedded_hal_02::adc::Channel<ADC, ID = u8> {}

#[cfg(not(feature = "embedded-hal-02"))]
pub trait Channel<ADC> {
fn channel() -> u8;
}

/// The number of ADC clock cycles to wait between powering on and starting calibration.
const ADC_CALIBRATION_CYCLES: u32 = 14;
Expand Down Expand Up @@ -293,7 +301,7 @@ impl Adc {

/// Set ADC sampling time for particular channel
#[inline(always)]
pub fn set_sample_time<C: Channel<ADC, ID = u8>>(&mut self, _pin: &C, sample_time: SampleTime) {
pub fn set_sample_time<C: Channel<ADC>>(&mut self, _pin: &C, sample_time: SampleTime) {
self.set_channel_sample_time(C::channel(), sample_time);
}

Expand Down Expand Up @@ -465,10 +473,14 @@ impl Adc {
self.rb.rdata.read().rdata().bits()
}

pub fn read_channel<PIN: Channel<ADC>>(&mut self, _pin: &PIN) -> u16 {
self.convert(PIN::channel())
}

/// Configure the ADC to read from the given pin with DMA.
pub fn with_dma<PIN>(mut self, pins: PIN, dma_ch: C0) -> AdcDma<PIN, Continuous>
where
PIN: Channel<ADC, ID = u8>,
PIN: Channel<ADC>,
{
self.rb.ctl0.modify(|_, w| w.disrc().disabled());
self.rb
Expand All @@ -490,15 +502,16 @@ impl Adc {
}
}

impl<WORD, PIN> OneShot<ADC, WORD, PIN> for Adc
#[cfg(feature = "embedded-hal-02")]
impl<WORD, PIN> embedded_hal_02::adc::OneShot<ADC, WORD, PIN> for Adc
where
WORD: From<u16>,
PIN: Channel<ADC, ID = u8>,
PIN: Channel<ADC>,
{
type Error = Infallible;
type Error = core::convert::Infallible;

fn read(&mut self, _pin: &mut PIN) -> nb::Result<WORD, Self::Error> {
let res = self.convert(PIN::channel());
fn read(&mut self, pin: &mut PIN) -> nb::Result<WORD, Self::Error> {
let res = self.read_channel(pin);
// TODO: Should this also be scaled based on Vref?
Ok(res.into())
}
Expand Down Expand Up @@ -595,7 +608,7 @@ pub struct Sequence {

impl Sequence {
/// Adds the given ADC pin to the list of channels.
pub fn add_pin<PIN: Channel<ADC, ID = u8>>(&mut self, pin: PIN) -> Result<(), PIN> {
pub fn add_pin<PIN: Channel<ADC>>(&mut self, pin: PIN) -> Result<(), PIN> {
if self.length >= self.channels.len() {
return Err(pin);
}
Expand Down Expand Up @@ -634,11 +647,17 @@ pub struct VBat;
macro_rules! adc_pins {
($ADC:ident, $($pin:ty => $chan:expr),+ $(,)*) => {
$(
impl Channel<$ADC> for $pin {
#[cfg(feature = "embedded-hal-02")]
impl embedded_hal_02::adc::Channel<$ADC> for $pin {
type ID = u8;

fn channel() -> u8 { $chan }
}

impl Channel<$ADC> for $pin {
#[cfg(not(feature = "embedded-hal-02"))]
fn channel() -> u8 { $chan }
}
)+
};
}
Expand Down
Loading
Loading