mirror of
https://github.com/italicsjenga/rp-hal-boards.git
synced 2025-01-11 13:01:30 +11:00
Merge pull request #38 from anall/bugfix/pll-uart-reset
Have the `pll` and `uart` HAL modules bring the hardware out of reset
This commit is contained in:
commit
9bef0821d9
|
@ -77,18 +77,15 @@ macro_rules! gpio {
|
|||
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
|
||||
use super::*;
|
||||
|
||||
use crate::resets::SubsystemReset;
|
||||
|
||||
impl GpioExt<pac::$PADSX, sio::$siotoken> for pac::$GPIOX {
|
||||
type Parts = Parts;
|
||||
|
||||
fn split(self, pads: pac::$PADSX, sio: sio::$siotoken, resets: &mut pac::RESETS) -> Parts {
|
||||
resets.reset.modify(|_, w| w.$gpiox().clear_bit().$padsx().clear_bit());
|
||||
// TODO: Implement Resets in the HAL
|
||||
while resets.reset_done.read().$gpiox().bit_is_clear() {
|
||||
cortex_m::asm::delay(10);
|
||||
}
|
||||
while resets.reset_done.read().$padsx().bit_is_clear() {
|
||||
cortex_m::asm::delay(10);
|
||||
}
|
||||
// FIXME: bring both of these up at the same time
|
||||
self.reset_bring_up(resets);
|
||||
pads.reset_bring_up(resets);
|
||||
Parts {
|
||||
_pads: pads,
|
||||
_sio: sio,
|
||||
|
|
|
@ -19,6 +19,7 @@ pub mod i2c;
|
|||
pub mod pll;
|
||||
pub mod prelude;
|
||||
pub mod pwm;
|
||||
pub mod resets;
|
||||
pub mod rom_data;
|
||||
pub mod rtc;
|
||||
pub mod sio;
|
||||
|
|
|
@ -14,6 +14,8 @@ use embedded_time::{
|
|||
|
||||
use nb::Error::WouldBlock;
|
||||
|
||||
use crate::resets::SubsystemReset;
|
||||
|
||||
/// State of the PLL
|
||||
pub trait State {}
|
||||
|
||||
|
@ -39,7 +41,10 @@ impl State for Locked {}
|
|||
impl State for Locking {}
|
||||
|
||||
/// Trait to handle both underlying devices from the PAC (PLL_SYS & PLL_USB)
|
||||
pub trait PhaseLockedLoopDevice: Deref<Target = rp2040_pac::pll_sys::RegisterBlock> {}
|
||||
pub trait PhaseLockedLoopDevice:
|
||||
Deref<Target = rp2040_pac::pll_sys::RegisterBlock> + SubsystemReset
|
||||
{
|
||||
}
|
||||
|
||||
impl PhaseLockedLoopDevice for rp2040_pac::PLL_SYS {}
|
||||
impl PhaseLockedLoopDevice for rp2040_pac::PLL_USB {}
|
||||
|
@ -190,7 +195,9 @@ impl<D: PhaseLockedLoopDevice> PhaseLockedLoop<Disabled, D> {
|
|||
}
|
||||
|
||||
/// Configures and starts the PLL : it switches to Locking state.
|
||||
pub fn initialize(self) -> PhaseLockedLoop<Locking, D> {
|
||||
pub fn initialize(self, resets: &mut rp2040_pac::RESETS) -> PhaseLockedLoop<Locking, D> {
|
||||
self.device.reset_bring_up(resets);
|
||||
|
||||
// Turn off PLL in case it is already running
|
||||
self.device.pwr.reset();
|
||||
self.device.fbdiv_int.reset();
|
||||
|
|
49
rp2040-hal/src/resets.rs
Normal file
49
rp2040-hal/src/resets.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
//! Subsystem Resets
|
||||
// See [Chapter 2 Section 14](https://datasheets.raspberrypi.org/rp2040/rp2040_datasheet.pdf) for more details
|
||||
use rp2040_pac as pac;
|
||||
|
||||
mod private {
|
||||
pub trait SubsystemReset {
|
||||
fn reset_bring_up(&self, resets: &mut pac::RESETS);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use private::SubsystemReset;
|
||||
|
||||
macro_rules! generate_reset {
|
||||
($MODULE:ident, $module:ident) => {
|
||||
impl SubsystemReset for pac::$MODULE {
|
||||
fn reset_bring_up(&self, resets: &mut pac::RESETS) {
|
||||
resets.reset.modify(|_, w| w.$module().clear_bit());
|
||||
while resets.reset_done.read().$module().bit_is_clear() {}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// In datasheet order
|
||||
generate_reset!(USBCTRL_REGS, usbctrl);
|
||||
generate_reset!(UART1, uart1);
|
||||
generate_reset!(UART0, uart0);
|
||||
generate_reset!(TIMER, timer);
|
||||
generate_reset!(TBMAN, tbman);
|
||||
generate_reset!(SYSINFO, sysinfo);
|
||||
generate_reset!(SYSCFG, syscfg);
|
||||
generate_reset!(SPI1, spi1);
|
||||
generate_reset!(SPI0, spi0);
|
||||
generate_reset!(RTC, rtc);
|
||||
generate_reset!(PWM, pwm);
|
||||
generate_reset!(PLL_USB, pll_usb);
|
||||
generate_reset!(PLL_SYS, pll_sys);
|
||||
generate_reset!(PIO1, pio1);
|
||||
generate_reset!(PIO0, pio0);
|
||||
generate_reset!(PADS_QSPI, pads_qspi);
|
||||
generate_reset!(PADS_BANK0, pads_bank0);
|
||||
//generate_reset!(JTAG,jtag); // This doesn't seem to have an item in the pac
|
||||
generate_reset!(IO_QSPI, io_qspi);
|
||||
generate_reset!(IO_BANK0, io_bank0);
|
||||
generate_reset!(I2C1, i2c1);
|
||||
generate_reset!(I2C0, i2c0);
|
||||
generate_reset!(DMA, dma);
|
||||
generate_reset!(BUSCTRL, busctrl);
|
||||
generate_reset!(ADC, adc);
|
|
@ -16,6 +16,8 @@ use crate::pac::{
|
|||
UART0, UART1,
|
||||
};
|
||||
|
||||
use crate::resets::SubsystemReset;
|
||||
|
||||
/// Error type for UART operations.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
@ -51,7 +53,7 @@ pub enum ReadErrorType {
|
|||
pub trait State {}
|
||||
|
||||
/// Trait to handle both underlying devices (UART0 & UART1)
|
||||
pub trait UartDevice: Deref<Target = RegisterBlock> {}
|
||||
pub trait UartDevice: Deref<Target = RegisterBlock> + SubsystemReset {}
|
||||
|
||||
impl UartDevice for UART0 {}
|
||||
impl UartDevice for UART1 {}
|
||||
|
@ -178,9 +180,12 @@ impl<D: UartDevice> UartPeripheral<Disabled, D> {
|
|||
/// Enables the provided UART device with the given configuration.
|
||||
pub fn enable(
|
||||
mut device: D,
|
||||
resets: &mut pac::RESETS,
|
||||
config: UartConfig,
|
||||
frequency: Hertz,
|
||||
) -> Result<UartPeripheral<Enabled, D>, Error> {
|
||||
device.reset_bring_up(resets);
|
||||
|
||||
let effective_baudrate = configure_baudrate(&mut device, &config.baudrate, &frequency)?;
|
||||
|
||||
// Enable the UART, both TX and RX
|
||||
|
|
Loading…
Reference in a new issue