Skip to content

Commit

Permalink
Implement RTC (#26)
Browse files Browse the repository at this point in the history
* implement rtc

* fix rtc
  • Loading branch information
bjoernQ authored Jul 23, 2021
1 parent 6e823cc commit a6cb896
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Thal_defaults.x",
]
runner = "cargo blflash --port=/dev/ttyUSB0"
runner = "blash --"

[build]
target = "riscv32imac-unknown-none-elf"
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"rust-analyzer.cargo.target": "riscv32imac-unknown-none-elf",
"rust-analyzer.checkOnSave.allTargets": false
}
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ description = "HAL for the bl602 microcontroller"
[dependencies]
bl602-pac = { git = "https://github.com/sipeed/bl602-pac", branch = "main" }
embedded-hal = "1.0.0-alpha.4"
embedded-time = "0.10"
embedded-time = "0.12.0"
riscv = "0.6.0"
nb = "1.0"
paste = "1.0"
Expand Down
61 changes: 61 additions & 0 deletions examples/rtc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#![no_std]
#![no_main]

use bl602_hal as hal;
use core::{convert::TryFrom, fmt::Write};
use embedded_time::{duration::Seconds, Clock};
use hal::{
clock::{Strict, SysclkFreq, UART_PLL_FREQ},
pac,
prelude::*,
rtc::Rtc,
serial::*,
};
use panic_halt as _;

#[riscv_rt::entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let mut parts = dp.GLB.split();

// Set up all the clocks we need
let clocks = Strict::new()
.use_pll(40_000_000u32.Hz())
.sys_clk(SysclkFreq::Pll160Mhz)
.uart_clk(UART_PLL_FREQ.Hz())
.freeze(&mut parts.clk_cfg);

// Set up uart output. Since this microcontroller has a pin matrix,
// we need to set up both the pins and the muxs
let pin16 = parts.pin16.into_uart_sig0();
let pin7 = parts.pin7.into_uart_sig7();
let mux0 = parts.uart_mux0.into_uart0_tx();
let mux7 = parts.uart_mux7.into_uart0_rx();

// Configure our UART to 115200Baud, and use the pins we configured above
let mut serial = Serial::uart0(
dp.UART,
Config::default().baudrate(115_200.Bd()),
((pin16, mux0), (pin7, mux7)),
clocks,
);

// Create RTC
let rtc = Rtc::rtc(dp.HBN);

loop {
write!(
serial,
"Current millis since start of the rtc: {}\r\n",
rtc.get_millis()
)
.ok();

let seconds =
Seconds::<u64>::try_from(rtc.try_now().unwrap().duration_since_epoch()).unwrap();
write!(serial, "Current instant in seconds: {}\r\n", seconds).ok();

let timer = rtc.new_timer(Seconds(1u32)).into_oneshot();
timer.start().unwrap().wait().ok();
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub mod delay;
pub mod gpio;
pub mod i2c;
pub mod interrupts;
pub mod rtc;
pub mod serial;
pub mod spi;
pub mod timer;
Expand Down
57 changes: 57 additions & 0 deletions src/rtc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*!
# Real Time Clock
A clock that constantly counts up starting at the time of it's creation.
## Initialisation example
```rust
let rtc = Rtc::rtc(dp.HBN);
```
*/

use bl602_pac::HBN;
use embedded_time::Clock;

pub struct Rtc {
hbn: HBN,
}

impl Rtc {
/// Creates and starts the RTC
pub fn rtc(hbn: HBN) -> Rtc {
// clear counter
hbn.hbn_ctl
.modify(|r, w| unsafe { w.rtc_ctl().bits(r.rtc_ctl().bits() & 0xfe) });
// enable counter
hbn.hbn_ctl
.modify(|r, w| unsafe { w.rtc_ctl().bits(r.rtc_ctl().bits() | 1) });

Rtc { hbn }
}

/// Get elapsed milliseconds since the RTC was created
pub fn get_millis(&self) -> u64 {
self.hbn
.rtc_time_h
.modify(|r, w| unsafe { w.bits(r.bits() | 1 << 31) });

let h = self.hbn.rtc_time_h.read().bits();
let l = self.hbn.rtc_time_l.read().bits();
let ts = (h as u64) << 32 | l as u64; // in counter units

// from IOT SDK:
// #define BL_RTC_COUNTER_TO_MS(CNT) (((CNT) >> 5) - ((CNT) >> 11) - ((CNT) >> 12)) // ((CNT)*(1024-16-8)/32768)
// see https://github.com/bouffalolab/bl_iot_sdk/blob/90acb7b46d11343d27db9518c4f86d94572c6629/components/hal_drv/bl602_hal/bl_rtc.c
ts * (1024 - 16 - 8) / 32768
}
}

impl Clock for Rtc {
type T = u64;

const SCALING_FACTOR: embedded_time::fraction::Fraction =
<embedded_time::fraction::Fraction>::new(1, 1_000);

fn try_now(&self) -> Result<embedded_time::Instant<Self>, embedded_time::clock::Error> {
Ok(embedded_time::Instant::new(self.get_millis()))
}
}

0 comments on commit a6cb896

Please sign in to comment.