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

Implement embedded-hal 1.0.0 traits #61

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
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ cast = { version = "0.2.3", default-features = false }
vcell = "0.1.2"
embedded-dma = "0.1.2"

[dependencies.embedded-hal]
version = "0.2.3"
features = ["unproven"]
embedded-hal = { package = "embedded-hal", version = "1.0.0" }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.7", features = [
"unproven",
] }

[features]
rt = ["gd32vf103-pac/rt"]
112 changes: 75 additions & 37 deletions src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use core::sync::atomic::{self, Ordering};

use crate::dma::{dma0::C0, CircBuffer, CircReadDma, Receive, RxDma, Transfer, TransferPayload, W};
use crate::gpio::{gpioa, gpiob, gpioc, Analog};
use crate::hal_02::adc::{Channel, OneShot};
use crate::pac::{ADC0, ADC1};
use crate::rcu::{BaseFrequency, Clocks, Enable, Rcu, Reset};
use embedded_dma::StaticWriteBuffer;
use embedded_hal::adc::{Channel, OneShot};

#[doc(hidden)]
pub trait AdcX {}
Expand Down Expand Up @@ -163,14 +163,14 @@ pub enum ETSRC_A {
impl From<ETSRC_A> for u8 {
fn from(src: ETSRC_A) -> u8 {
match src {
ETSRC_A::TIM0CH0 => 0b000,
ETSRC_A::TIM0CH1 => 0b001,
ETSRC_A::TIM0CH2 => 0b010,
ETSRC_A::TIM1CH1 => 0b011,
ETSRC_A::TIM0CH0 => 0b000,
ETSRC_A::TIM0CH1 => 0b001,
ETSRC_A::TIM0CH2 => 0b010,
ETSRC_A::TIM1CH1 => 0b011,
ETSRC_A::TIM2TRGO => 0b100,
ETSRC_A::TIM3CH3 => 0b101,
ETSRC_A::EXTI11 => 0b110,
ETSRC_A::SWRCST => 0b111,
ETSRC_A::TIM3CH3 => 0b101,
ETSRC_A::EXTI11 => 0b110,
ETSRC_A::SWRCST => 0b111,
}
}
}
Expand Down Expand Up @@ -615,28 +615,52 @@ impl Adc<ADC0> {
self.rb.ctl0.modify(|_, w| w.disrc().clear_bit());
self.rb.ctl1.modify(|_, w| w.dal().bit(self.align.into()));
self.set_channel_sample_time(PIN::channel(), self.sample_time);
self.rb.rsq2.modify(|_, w| unsafe { w.rsq0().bits(PIN::channel()) });
self.rb
.rsq2
.modify(|_, w| unsafe { w.rsq0().bits(PIN::channel()) });
self.rb.ctl1.modify(|_, w| w.dma().set_bit());

RxDma { payload: AdcPayload { adc: self, pins, _mode: PhantomData }, channel: dma_ch }
RxDma {
payload: AdcPayload {
adc: self,
pins,
_mode: PhantomData,
},
channel: dma_ch,
}
}

pub fn with_scan_dma<PINS>(mut self, pins: PINS, dma_ch: C0) -> AdcDma<PINS, Scan>
where
Self: SetChannels<PINS>,
{
self.rb.ctl1.modify(|_, w| w
.adcon().clear_bit()
.dma().clear_bit()
.ctn().clear_bit()
.dal().bit(self.align.into())
);
self.rb.ctl0.modify(|_, w| w.sm().set_bit().disrc().clear_bit());
self.rb.ctl1.modify(|_, w| {
w.adcon()
.clear_bit()
.dma()
.clear_bit()
.ctn()
.clear_bit()
.dal()
.bit(self.align.into())
});
self.rb
.ctl0
.modify(|_, w| w.sm().set_bit().disrc().clear_bit());
self.set_samples();
self.set_sequence();
self.rb.ctl1.modify(|_, w| w.dma().set_bit().adcon().set_bit());

RxDma { payload: AdcPayload { adc: self, pins, _mode: PhantomData }, channel: dma_ch }
self.rb
.ctl1
.modify(|_, w| w.dma().set_bit().adcon().set_bit());

RxDma {
payload: AdcPayload {
adc: self,
pins,
_mode: PhantomData,
},
channel: dma_ch,
}
}
}

Expand All @@ -657,7 +681,7 @@ where

impl<PINS> AdcDma<PINS, Scan>
where
Self: TransferPayload
Self: TransferPayload,
{
pub fn split(mut self) -> (Adc<ADC0>, PINS, C0) {
self.stop();
Expand All @@ -682,19 +706,26 @@ where
// the transfer
let (ptr, len) = unsafe { buffer.static_write_buffer() };
unsafe {
self.channel.set_peripheral_address(&(*ADC0::ptr()).rdata as *const _ as u32, false);
self.channel
.set_peripheral_address(&(*ADC0::ptr()).rdata as *const _ as u32, false);
self.channel.set_memory_address(ptr as u32, true);
}
self.channel.set_transfer_length(len);

atomic::compiler_fence(Ordering::Release);
self.channel.ctl().modify(|_, w| unsafe { w
.m2m().clear_bit()
.prio().bits(0b01) // Medium
.mwidth().bits(0b01) // 16 bits
.pwidth().bits(0b01) // 16 bits
.cmen().set_bit()
.dir().clear_bit()
self.channel.ctl().modify(|_, w| unsafe {
w.m2m()
.clear_bit()
.prio()
.bits(0b01) // Medium
.mwidth()
.bits(0b01) // 16 bits
.pwidth()
.bits(0b01) // 16 bits
.cmen()
.set_bit()
.dir()
.clear_bit()
});
self.start();

Expand All @@ -712,19 +743,26 @@ where
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_write_buffer() };
unsafe {
self.channel.set_peripheral_address(&(*ADC0::ptr()).rdata as *const _ as u32, false);
self.channel
.set_peripheral_address(&(*ADC0::ptr()).rdata as *const _ as u32, false);
self.channel.set_memory_address(ptr as u32, true);
}
self.channel.set_transfer_length(len);

atomic::compiler_fence(Ordering::Release);
self.channel.ctl().modify(|_, w| unsafe { w
.m2m().clear_bit()
.prio().bits(0b01) // Medium
.mwidth().bits(0b01) // 16 bits
.pwidth().bits(0b01) // 16 bits
.cmen().clear_bit()
.dir().clear_bit()
self.channel.ctl().modify(|_, w| unsafe {
w.m2m()
.clear_bit()
.prio()
.bits(0b01) // Medium
.mwidth()
.bits(0b01) // 16 bits
.pwidth()
.bits(0b01) // 16 bits
.cmen()
.clear_bit()
.dir()
.clear_bit()
});
self.start();

Expand Down
71 changes: 43 additions & 28 deletions src/delay.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,47 @@
//! Delays

use crate::timer::Timer;
use crate::time::U32Ext;
use crate::timer::Timer;

use cast::u32;
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal::timer::CountDown;
use gd32vf103_pac::{TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5, TIMER6};
use crate::hal::delay::DelayNs;
use crate::hal_02::blocking::delay::{DelayMs, DelayUs};
use crate::hal_02::timer::CountDown;
use crate::rcu::Clocks;
use gd32vf103_pac::{TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5, TIMER6};

/// Machine mode cycle counter (`mcycle`) as a delay provider
#[derive(Copy, Clone)]
pub struct McycleDelay {
core_frequency: u32
core_frequency: u32,
}

impl McycleDelay {
/// Constructs the delay provider
pub fn new(clocks: &Clocks) -> Self {
Self {
core_frequency: clocks.sysclk().0
core_frequency: clocks.sysclk().0,
}
}
}

impl DelayNs for McycleDelay {
fn delay_ns(&mut self, ns: u32) {
let t0 = riscv::register::mcycle::read64();
let clocks = (ns as u64 * (self.core_frequency as u64)) / 1_000_000_000;
while riscv::register::mcycle::read64().wrapping_sub(t0) <= clocks {}
}
}

impl DelayUs<u64> for McycleDelay {
fn delay_us(&mut self, us: u64) {
let t0 = riscv::register::mcycle::read64();
let clocks = (us * (self.core_frequency as u64)) / 1_000_000;
while riscv::register::mcycle::read64().wrapping_sub(t0) <= clocks { }
self.delay_ns((us * 1_000) as u32);
}
}

impl DelayUs<u32> for McycleDelay {
#[inline(always)]
fn delay_us(&mut self, us: u32) {
self.delay_us(us as u64)
DelayNs::delay_us(self, us);
}
}

Expand All @@ -44,27 +50,27 @@ impl DelayUs<i32> for McycleDelay {
#[inline(always)]
fn delay_us(&mut self, us: i32) {
assert!(us >= 0);
self.delay_us(us as u32);
DelayNs::delay_us(self, us as u32);
}
}

impl DelayUs<u16> for McycleDelay {
#[inline(always)]
fn delay_us(&mut self, us: u16) {
self.delay_us(us as u32)
DelayNs::delay_us(self, us as u32);
}
}

impl DelayUs<u8> for McycleDelay {
#[inline(always)]
fn delay_us(&mut self, us: u8) {
self.delay_us(us as u32)
DelayNs::delay_us(self, us as u32);
}
}

impl DelayMs<u32> for McycleDelay {
fn delay_ms(&mut self, ms: u32) {
self.delay_us((ms as u64) * 1000)
DelayNs::delay_us(self, ms * 1000);
}
}

Expand All @@ -73,26 +79,29 @@ impl DelayMs<i32> for McycleDelay {
#[inline(always)]
fn delay_ms(&mut self, ms: i32) {
assert!(ms >= 0);
self.delay_ms(ms as u32);
DelayNs::delay_ms(self, ms as u32);
}
}

impl DelayMs<u16> for McycleDelay {
#[inline(always)]
fn delay_ms(&mut self, ms: u16) {
self.delay_ms(ms as u32)
DelayNs::delay_ms(self, ms as u32);
}
}

impl DelayMs<u8> for McycleDelay {
#[inline(always)]
fn delay_ms(&mut self, ms: u8) {
self.delay_ms(ms as u32)
DelayNs::delay_ms(self, ms as u32);
}
}

/// TIMER as a delay provider
pub struct Delay<TIMER> where Timer<TIMER>: CountDown {
pub struct Delay<TIMER>
where
Timer<TIMER>: CountDown,
{
timer: Timer<TIMER>,
}

Expand All @@ -112,42 +121,48 @@ macro_rules! delay {
}
}

impl DelayNs for Delay<$TIMER> {
fn delay_ns(&mut self, ns: u32) {
let freq = 1_000_000_000 / ns;
self.timer.start(freq.hz());
while let Err(_) = self.timer.wait() { }
self.timer.tim.ctl0.modify(|_, w| w.cen().clear_bit());
}
}

impl DelayMs<u32> for Delay<$TIMER> {
fn delay_ms(&mut self, ms: u32) {
self.delay_us(ms * 1_000);
DelayNs::delay_ms(self, ms * 1_000);
}
}

impl DelayMs<u16> for Delay<$TIMER> {
fn delay_ms(&mut self, ms: u16) {
self.delay_ms(u32(ms));
DelayNs::delay_ms(self, ms as u32);
}
}

impl DelayMs<u8> for Delay<$TIMER> {
fn delay_ms(&mut self, ms: u8) {
self.delay_ms(u32(ms));
DelayNs::delay_ms(self, ms as u32);
}
}

impl DelayUs<u32> for Delay<$TIMER> {
fn delay_us(&mut self, us: u32) {
let freq = 1_000_000 / us;
self.timer.start(freq.hz());
while let Err(_) = self.timer.wait() { }
self.timer.tim.ctl0.modify(|_, w| w.cen().clear_bit());
DelayNs::delay_us(self, us);
}
}

impl DelayUs<u16> for Delay<$TIMER> {
fn delay_us(&mut self, us: u16) {
self.delay_us(u32(us))
DelayNs::delay_us(self, us as u32);
}
}

impl DelayUs<u8> for Delay<$TIMER> {
fn delay_us(&mut self, us: u8) {
self.delay_us(u32(us))
DelayNs::delay_us(self, us as u32);
}
}
)+
Expand Down
Loading