Skip to content

Commit

Permalink
Merge pull request #42 from gd32-rust/embedded-hal-optional
Browse files Browse the repository at this point in the history
Make embedded-hal 0.2.7 dependency optional
  • Loading branch information
qwandor authored Jan 29, 2024
2 parents e361cfb + 11f30fb commit c31c981
Show file tree
Hide file tree
Showing 19 changed files with 316 additions and 146 deletions.
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 panic_semihosting as _;

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 @@ fn main() -> ! {
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

0 comments on commit c31c981

Please sign in to comment.