Giter VIP home page Giter VIP logo

nrf-hal's People

Contributors

almindor avatar andresovela avatar bjc avatar bors[bot] avatar careyk007 avatar dependabot[bot] avatar dirbaio avatar disasm avatar finomnis avatar fmckeogh avatar hannes-hochreiner avatar hannobraun avatar huntc avatar ia0 avatar ivario123 avatar jamesmunns avatar japaric avatar jonas-schievink avatar kalkyl avatar korken89 avatar kyrne avatar lulf avatar macthestack avatar ninjasource avatar qwandor avatar simonsso avatar thalesfragoso avatar timokroeger avatar wez avatar yatekii avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nrf-hal's Issues

EasyDMA doesn't read from Flash

In general, EasyDMA does not work with items in Flash, e.g. a &'static str. From the datasheet:

EasyDMA is an easy-to-use direct memory acc s module that some peripherals implement to gain direct access to Data RAM.
The EasyDMA is an AHB bus master similar to the CPU and it is connected to the AHB multilayer
interconnect for direct access to the Data RAM. The EasyDMA is not able to access the Flash.

I did this accidentally, and did not receive any visible error when sending via UARTE. I think there would be 3 ways to address this:

  1. if there is some way to detect this error condition and return an Err
  2. debug_assert that the slice ptr is in the RAM region
  3. Do an explicit check, roughly if !( RAM_LOWER <= buf.as_ptr() <= RAM_UPPER ) { return Err(...); }

Investigate implementing embedded-hal traits for UARTE

I looked at implementing embedded-hal Serial traits for UARTE, but it wasn't immediately obvious how we might do that. All of my implementations so far have been with a hardware FIFO and so writing byte by byte makes sense. Sending a string of 100 bytes as 100 single-byte DMA operations would clearly be sub-optimal.

Has anyone given this any thought? Does it need to just wait for the interrupt-driven UARTE driver?

SPIM write sends only logic low

SPIM::transfer_split_uneven seems to send only logic low when the rx_buffer is a Zero Sized Slice. Could it be because the Rust compiler is optimizing out operations on the zero sized type? I'm still new to this but replicating the first part of the transfer_split_uneven function on my desktop compiled to no output.

Full code below (running on a nRF52-DK). If i substitute read() with a zero sized array, for the write() I get the same result:

#![no_std]
#![no_main]

extern crate panic_halt;
extern crate nrf52832_hal;
extern crate embedded_hal_spy;

use cortex_m_rt::entry;
use nrf52832_hal::gpio::{self, *,  p0::*,  Level};
use nrf52832_hal::spim::Spim;


#[entry]
fn main() -> ! {

    let p = nrf52832_hal::pac::Peripherals::take().unwrap();
    let port0 = p0::Parts::new(p.P0);
    
    let cs: P0_12<gpio::Output<PushPull>> = port0.p0_12.into_push_pull_output(Level::High);
    let spiclk = port0.p0_24.into_push_pull_output(Level::Low).degrade();
    let spimosi = port0.p0_23.into_push_pull_output(Level::Low).degrade();
    let spimiso = port0.p0_22.into_floating_input().degrade();

    let pins = nrf52832_hal::spim::Pins {
        sck: spiclk,
        miso: Some(spimiso),
        mosi: Some(spimosi),
    };
    let mut spi = Spim::new(
        p.SPIM1,
        pins,
        nrf52832_hal::spim::Frequency::K500,
        nrf52832_hal::spim::MODE_0,
        0,
    );

    let data: [u8; 1] = [0b1101_0010];
    //let mut readbuf: [u8; 0];
    //spi.write(&mut cs.degrade(), &data).unwrap();
    spi.read(&mut cs.degrade(), &data, &mut [0u8; 0]).unwrap();

    loop {}
}

Current Use of EasyDMA can cause incorrect optimization

Hey, I was doing some work with short EasyDMA TWIM transactions, and noticed that certain operations failed in release (opt level 3), but not in debug (opt level 0). Furthermore, they worked in opt levels 0, 1, or 'z', but not in opt level 2 or 3.

I believe this is due to the compiler not "understanding" our use of giving buffers as .ptr()s, and assuming that certain data is never used.

I was able to fix this by placing a compiler fence (compiler_fence(Ordering::AcqRel); after the DMA transaction was completed. It is likely we will need to use this everywhere EasyDMA is used.

Consider changing repository configuration regarding pull request merging

When merging pull requests, the option "Create a merge commit" is currently disabled in this repository. I actually prefer that option, as it documents in the commit history which commits belong to larger pieces of work.

"Squash and merge" is currently enabled. I suggest disabling it, as that makes it easy to accidentally lose valuable history, especially since it's currently the default option. Whenever squashing commits is desirable, it's easy enough to do manually.

I'd also prefer to disable "Rebase and merge", due to my preference for merge commits. I don't feel strongly about this point.

cc @nrf-rs/team, especially @wez

Add nrf52 team as nrf52810-hal owner

CC @hannobraun, could you please add the nrf-rs/nrf52 team as an owner for the nrf52810 crate? Right now you are the only owner.

Edit: On crates.io. You can do this by running the following command from within the crate locally:

cargo owner --add github:nrf-rs:nrf52

Consider renaming repo name

Currently there's nrf52 and nrf9160 crates in this repo, I think it'd be better if that was split up, or if the repo name reflected the contents of the repo. Maybe a generic "nrf-hal"?

SAADC: Multiple channels

The SAADC can have multiple channels, and starting the sample task will result in all channels being read and DMA'd into memory. This is a useful feature and should probably be exposed somehow, but the specifics need to be discussed.

It would most likely interfere with the embedded-hal OneShot trait, so perhaps a MultiShot trait could be proposed?

The SAADC is also dual-rail, so discussion needs to be had regarding how that should be exposed.

Question: I try use set_high() method but not found

I try to compile mi first blink for nrf52840 uC and review your examples for learning and see use directly set_low() after creating Pin instance with into_push_pull_output

follow this example: https://github.com/nrf-rs/nrf-hal/blob/master/examples/spi-demo/src/main.rs#L31

this is my code

#![no_std]
#![no_main]

extern crate panic_halt;
use cortex_m_rt::entry;

extern crate nrf52840_hal;
use nrf52840_hal::gpio;
use nrf52840_hal::gpio::*;
use nrf52840_hal::gpio::p0::*;

use nrf52840_hal::Timer;


#[entry]
fn main() -> ! {
    let p = nrf52840_hal::pac::Peripherals::take().unwrap();
    let p0 = p0::Parts::new(p.P0);
    let mut led1: P0_24<gpio::Output<PushPull>> = p0.p0_24.into_push_pull_output(Level::High);

    let mut timer = Timer::new(p.TIMER0);

    loop {
        led1.set_low();
        timer.delay(2_000_000);
        led1.set_high();
        timer.delay(2_000_000);
    }
}

And this is an error message, both equal for set_low and set_high

error[E0599]: no method named `set_low` found for struct `nrf52840_hal::gpio::p0::P0_24<nrf52840_hal::gpio::Output<nrf52840_hal::gpio::PushPull>>` in the current scope
  --> src/main.rs:26:14
   |
26 |         led1.set_low();
   |              ^^^^^^^ method not found in `nrf52840_hal::gpio::p0::P0_24<nrf52840_hal::gpio::Output<nrf52840_hal::gpio::PushPull>>`

Use this debs

[dependencies]
nrf52840-hal = "0.11.0"
cortex-m-rt = "0.6.12"
panic-halt = "0.2.0"

`Pin`'s public fields let you break `Pin`'s singleton property

For example:

let p0 = p0::Parts(p.P0);
let a = p0.p0_00.degrade();
let mut b = p0.p0_01.degrade();
b.pin = 0;

Lets you create 2 P0.00 pins. I don't think this operation is UB per se but it does break the intended (singleton) semantics and can result in IO misconfiguration, e.g. configuring P0.00 both as serial Tx and Rx if you pass the a and b from above to the Uarte abstraction.

Setting the public pin field to value equal or greater than 32 may result in out of bounds array access though (either a panic or UB if the HAL is using unchecked bounds access).

I think making the fields private and instead providing getter methods for pin and port would be a better fit here.

unresolved import `hal` in ecb-demo

Hi, I'm pretty new to Rust so apologies if this is something obvious on my end. When cloning the repo and running cargo build, I get the error shown below. I am using Ubuntu 19.10 and rustc version 1.44.0.

jason@faraday:/media/jason/e/projects/nrf-hal$ cargo build
   Compiling cortex-m v0.6.2
   Compiling typenum v1.12.0
   Compiling semver-parser v0.7.0
   Compiling stable_deref_trait v1.1.1
   Compiling vcell v0.1.2
   Compiling proc-macro2 v1.0.18
   Compiling unicode-xid v0.2.0
   Compiling syn v1.0.31
   Compiling cortex-m-rt v0.6.12
   Compiling r0 v0.2.2
   Compiling void v1.0.2
   Compiling nb v0.1.2
   Compiling nrf52832-pac v0.9.0
   Compiling nrf52833-pac v0.9.0
   Compiling nrf9160-pac v0.2.1
   Compiling nrf51 v0.9.0
   Compiling nrf52840-pac v0.9.0
   Compiling fpa v0.1.0
   Compiling nrf52810-pac v0.9.0
   Compiling rand_core v0.5.1
   Compiling memchr v2.3.3
   Compiling proc-macro2 v0.4.30
   Compiling nrf52832-hal v0.10.0 (/media/jason/e/projects/nrf-hal/nrf52832-hal)
   Compiling unicode-xid v0.1.0
   Compiling version_check v0.9.2
   Compiling version_check v0.1.5
   Compiling rand_core v0.4.2
   Compiling syn v0.15.44
   Compiling byteorder v1.3.4
   Compiling cortex-m-semihosting v0.3.5
   Compiling nrf9160-hal v0.10.0 (/media/jason/e/projects/nrf-hal/nrf9160-hal)
   Compiling heapless v0.4.4
   Compiling cortex-m v0.5.10
   Compiling panic-halt v0.2.0
   Compiling aligned v0.2.0
   Compiling ufmt-write v0.1.0
   Compiling ssd1306 v0.2.6
   Compiling cortex-m-rtfm v0.4.3
   Compiling nrf52840-hal v0.10.0 (/media/jason/e/projects/nrf-hal/nrf52840-hal)
   Compiling nrf51-hal v0.10.0 (/media/jason/e/projects/nrf-hal/nrf51-hal)
   Compiling adafruit-nrf52-bluefruit-le v0.0.1 (/media/jason/e/projects/nrf-hal/boards/adafruit-nrf52-bluefruit-le)
   Compiling nrf52833-hal v0.10.0 (/media/jason/e/projects/nrf-hal/nrf52833-hal)
   Compiling nrf52810-hal v0.10.0 (/media/jason/e/projects/nrf-hal/nrf52810-hal)
   Compiling volatile-register v0.2.0
   Compiling semver v0.9.0
   Compiling embedded-hal v0.2.3
   Compiling rand_core v0.3.1
   Compiling nom v5.1.2
   Compiling nom v4.2.3
   Compiling embedded-hal-spy v0.0.3
   Compiling rand v0.5.6
   Compiling rustc_version v0.2.3
   Compiling hash32 v0.1.1
   Compiling quote v1.0.7
   Compiling quote v0.6.13
   Compiling bare-metal v0.2.5
   Compiling cast v0.2.3
   Compiling tinytga v0.1.0
   Compiling generic-array v0.13.2
   Compiling generic-array v0.12.3
   Compiling generic-array v0.11.1
   Compiling as-slice v0.1.3
   Compiling aligned v0.3.2
   Compiling rtt-target v0.2.0
   Compiling panic-semihosting v0.5.3
   Compiling tinybmp v0.1.1
   Compiling embedded-graphics v0.4.9
   Compiling owned-singleton-macros v0.1.0
   Compiling cortex-m-rtfm-macros v0.4.3
   Compiling cortex-m-rt-macros v0.1.8
   Compiling owned-singleton v0.1.0
   Compiling ecb-demo v0.0.1 (/media/jason/e/projects/nrf-hal/examples/ecb-demo)
error[E0432]: unresolved import `hal`
  --> examples/ecb-demo/src/main.rs:22:5
   |
22 |     hal::{Clocks, Ecb},
   |     ^^^ use of undeclared type or module `hal`

error[E0433]: failed to resolve: use of undeclared type or module `hal`
  --> examples/ecb-demo/src/main.rs:34:13
   |
34 |     let p = hal::pac::Peripherals::take().unwrap();
   |             ^^^ use of undeclared type or module `hal`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0432, E0433.
For more information about an error, try `rustc --explain E0432`.
error: could not compile `ecb-demo`.

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed

SAADC API?

I'm currently trying to get the SAADC working for a project, and thought that adding it to the HAL would be a nice addition. I think I'd start with just a blocking implementation, does anyone have any rough ideas as to how the API should be structured?

[RFC] Wrap `nrf52::Peripherals` and `nrf52::CorePeripherals`

This issue was first opened in the old nrf52-hal repository. Original discussion: jamesmunns/nrf52-hal#6


The entry points to this crate's API are currently mostly extension traits: For a peripheral that this crate provides an API for, an extension trait is defined and implemented. Extension traits are implemented for the peripheral proxys from the nrf52 crate. An extension trait defines a method like constrain or split, which consumes the raw peripheral proxy and returns the HAL API for that peripheral.

That style of API is popular among HAL APIs (I think mostly because most HAL crates start out by copying other HAL crates), but I believe it is flawed. The critical problem is, that the HAL can't control the initial hardware state, making it impossible to give certain guarantees without significant runtime overhead. If we knew for a fact that no one had been messing with the hardware before initializing the HAL API, we could give much stronger safety guarantees, without the additional runtime overhead.

So far this is a rather general argument, but there is one concrete problem that would be weird to solve with the extension trait style: On the nRF52, several groups of peripherals share the same address space, and only one peripheral in each group can be used at a time (see nRF52832 Product Specification, section 15.2).

If we controlled the initial hardware state, we could statically guarantee that the user can enable only one of the peripherals in a given address space at a time. With the the current architecture, I can only think of solutions that are weird (enabling one peripheral in the group consumes the others) or less efficient (check hardware status at runtime.

I propose the following architecture:

  • We add a new struct, Peripherals, which wraps nrf52::Peripherals and nrf52::CorePeripherals.
  • Peripherals has two methods that can be used to get an instance, take and steal.
  • Under the hood, take and steal use the take and steal methods of nrf52::Peripherals/nrf52::CorePeripherals to provide the same guarantees that those methods provide.
  • Each nRF52 peripheral is available as a field of Peripherals. For peripherals that don't have a HAL API implemented yet, the peripheral proxy from nrf52 is provided directly.
  • Each peripheral API provides a free method that returns the peripheral proxy from nrf52. This allows the user to fall back to the raw register API, if the HAL API doesn't fulfill their needs.
  • This allows us to solve the problem of shared address spaces cleanly: We add singleton structs that represent the shared address spaces to Peripherals. Those are consumed by the HAL APIs of the shared peripherals when enabling them.

Summary: By following this architecture, we know that the user hasn't modified the hardware at the point when the HAL API is initialized (unless they have used unsafe means to do so, at which point all bets are off). This allows us to provide safety guarantees that we otherwise couldn't provide easily, or only with additional runtime overhead.

Further reading: I've been using this technique in lpc82x-hal for a while now, and I'm very happy with it. One major problem it solves is pin function assignment. lpc82x-hal statically guarantees that conflicting pin functions can't be assigned to a single pin. Without control over the initial hardware conditions, this could not be achieved without checking every single function assignment register (nRF52 has the same problem, by the way).

Consider using .chunks() method for sending blocks of data

For sending multiple blocks of data for things like Spim::transfer, this is a handy pattern I came up with. Not sure if it compiles to more code:

fn send(&mut self, buf: &[u8]) -> Result<(), ()> {
    for c in buf.chunks(EASY_DMA_SIZE) {
        self.scratch[..c.len()]
            .copy_from_slice(c);
        self.uart.write(&self.scratch[..c.len()]).map_err(|_| ())?;
    }
    Ok(())
}

Allow larger SPI buffer sizes on nrf52840 in nrf52-hal-common

the maxcnt register in the SPI hardware is 8 bits wide on the nrf52382 but wider on the 52840. The boundary checking code currently constrains the maximum buffer size to 8 bit values which is safe but arbitrarily limiting on the 52840.

Come up with a reasonable way to express this range check that allows taking maximum advantage for the different target devices.

Require 2FA as an organization

I would like to request that we require all members of the organization to use 2FA. Because the teams of this organization have access to push to crates.io, if an attacker can compromise one of our accounts, they can push malicious code to crates.io.

Add gpiote module to nrf52-hal-common

It would be nice to have a safe, ergonomic API to setup events and tasks using the GPIOTE module.

I have an example of how the PAC can be used directly, tested out on the nrf52 dev kit.

I'm up for giving this a go.

I'm guessing it's going to be kind of similar to the gpio module but with more layers. Also I'm wondering about the best way to handle the multiple channels.

It definitely needs a typestate to indicate whether an event pin is configured as pullup or pulldown as a floating pin had me scratching my head for a while.

Does anyone have any hints or implementations they know of in other HAL crates that deal with similar functionality?

Whereabouts of the BPROT register on the nRF52840 should be investigated.

As per @jamesmunns wishes in https://github.com/nrf-rs/nrf52-hal/diffs/4_ this issue should track the open questions about the missing BPROT register on the nRF52840. For now it's just not accessible through the nRF52840-DK BSP as it's apparently also missing in the pac.

We need to find out:

  • Is it really missing?
  • Is there an equivalent?
  • Has it completely been removed?

edit: and ofc the given link by GH does not work. Dunno how to reference the location before the merge. Will relink once it's merged.

Investigate implementing embedded-hal traits for TIMER API

This issue was first opened in the old nrf52-hal repository. Original discussion: jamesmunns/nrf52-hal#10


I didn't initially implement embedded-hal traits for the new TIMER peripheral API, as embedded-hal only has a CountDown trait, while TIMER counts up. Now that I looked into it, I don't think this is a problem, as there's no method to read back the timer value in the CountDown trait.

From the embedded-hal documentation:

Note that the implementer doesn't necessarily have to be a downcounting timer; it could also be an upcounting timer as long as the above contract is upheld.

So it looks like the trait can be implemented.

How do nrf52-hal-common releases work?

I notice that with adafruit-nrf52-bluefruit-le board crate, its built of of much newer abstractions around GPIO pins that are only in the unreleased nrf52-hal-common in git. I'm wondering when the next release of nrf52-hal-common will be so that I can build off newer abstractions without having to use a path dependency.

I'm curious if there's a thought process on when things get released?

Investigate implementing embedded-hal traits for SPIM peripheral

This issue was first opened in the old nrf52-hal repository. Original discussion: jamesmunns/nrf52-hal#11


I didn't do this initially, because I'm not sure whether it's possible, or if it is, if it should be done without modifying embedded-hal first. The problem is that the embedded-hal trait for SPI is very basic, reading and writing only single words. But SPIM supports DMA natively. The most straight-forward way to use it is to actually let it handle the whole SPI transaction.

I now discovered that there are higher-level SPI traits, but those have problems, too. Transfer uses the same buffer for sending and receiving. I'm not sure if this can be implemented for SPIM.

Maybe my doubts are unfounded and there is a reasonable way to implement those traits. Maybe the embedded-hal traits need to be changed. I'm pretty sure there's discussion about SPI somewhere on the embedded-hal issue tracker that might need to be consulted.

Support for nRF52810?

Hello!

If I started work on an nrf52810-hal is it the sort of thing you would like to see merged, or developed as a separate project? I can't see any references to it in this repository so I was just wondering what the plans were.

Thanks :)

Move board support crates out of this repo

This repository should focus on HALs for the microcontrollers, not on providing support for every conceivable devboard that contributors might not have. Board specific crates should be moved to their own repository.

`Rng` is not cryptographically secure

Rng implements CryptoRng without turning on the bias correction. This is a bad idea since its output is not guaranteed to be uniformly distributed without doing that.

v0.9.0 Release Tracking Issue

We're probably due up for a new release, as the Instance changes have not been released yet.

CC #122.

Are there any other changes we would like to land before the next release?

Must do:

  • Update relevant version numbers
  • Update BSP crates

Could do:

  • Rename nrf52-hal/nrf52-hal-common, maybe to nrf-hal and nrf-hal-common, CC #113
  • Land #123 (breaking change)
  • Land #124 (not breaking change)
  • Land #102 (needs feedback from @korken89)
  • Update PAC crates (not breaking change, probably)

Do we have any other (potentially breaking) changes we would like to land soon?

CC @nrf-rs/nrf52 crew

I'd suggest we aim for a release next weekend (I have some time on a train next Saturday, so I'd be up to take the lead on this).

No 'new' method in gpio::p0::Parts

I am poking around a nRF52840-DK.
I'm trying to implement a blinky for starters, but run into a puzzling compilation error.

error[E0599]: no function or associated item named `new` found for struct `nrf52_hal_common::gpio::p0::Parts` in the current scope
  --> examples/blinky.rs:19:28
   |
19 |     let port0 = p0::Parts::new(peripherals.P0);
   |                            ^^^ function or associated item not found in `nrf52_hal_common::gpio::p0::Parts`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
error: could not compile `nrf52840-dk`.

To learn more, run the command again with --verbose.

Source code:

#![no_main]
#![no_std]

use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;

#[allow(unused_imports)]
use panic_semihosting;

use nrf52840_hal as hal;
use hal::nrf52840_pac as pac;
use hal::gpio::p0;

#[entry]
fn main() -> ! {
	hprintln!("Hello, world!").unwrap();

	let peripherals = pac::Peripherals::take().unwrap();
    let port0 = p0::Parts::new(peripherals.P0);

	loop {}
}

Cargo.toml (packaged info omitted):

[dependencies]
cortex-m = { version = "0.5.4", features = [ "const-fn" ] }
cortex-m-rt = "0.6.12"
embedded-hal = "0.2.3"
nrf52840-hal = "0.8.1"

[dev-dependencies]
cortex-m-rt = "0.6.12"
cortex-m-semihosting = "~0.3"
panic-semihosting = "~0.5"
nb = "~0.1"

[features]
rt = ["nrf52840-hal/rt"]
default = ["rt"]

I based this on the SPI example.
I took a very quick look a the gpio.rs file and if I correctly read the macro at the bottom, there should be a public method new implemented for p0::Parts

On the other hand, when looking at the HAL's documentation on doc.rs there is no new method implemented for p0::Parts.

From my naive point of view one of the following is happening:

  • I am completely missing something (more than probable, as I am new to rust and even more to embedded rust)
  • There is an error in the documentation (unlikely as it is automatically generated)
  • There is an error in the example / the example is not portable to nRF52840
  • An implementation mistake somehow

Can anyone help me figure that one out ?

Consider moving boards/adafruit_nrf52pro into a separate repository

I'm a big fan of keeping things neat and tidy, and while there's a good argument to be made that all HAL-related crates should remain in this repository, I think we should maintain board support crates in a separate repository. I believe this would have the following advantages:

  • Improve discoverability of the adafruit_nrf52pro crate. Currently it's pretty well-hidden in this repository.
  • Ease maintenance of this repository. #6 is an example where the crate causes build errors. It's no big deal in this case, but I wouldn't want to force contributors to fix errors in a crate they might know nothing about, for a board they might not have available.

Add resources for the two nrf52 chips to the README/repo

I think it would be useful to add resources such as reference manuals to the repo.

Question is if it should be links to the PDFs in the README or even included PDFs in the repo that are omitted in a cargo publish.
I would really welcome that as google et. al always show prelim. versions as first hits, potentially fooling users (e.g the 52840er chip had 255byte wide EDMA transfer buffers for 2/3 peripherals when in fact it really has 2^16 - 1 bytes wide transfer buffers for all peripherals (at least at release (v1.0))).

Adding just a link keeps the storage footprint of the repo low and doesn't clutter it so much, where as committing the actual file would prevent broken links in case nordic moving stuff (which they seem to do some time; didn't happen for the reference manual yet tho; afaik).

What do y'all think about this?

Including [0, 1] would up the repo size about 15 Megs.

[2] http://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.0.pdf
[1] http://infocenter.nordicsemi.com/pdf/nRF52832_PS_v1.4.pdf

GPIO: Add support for tri-state mode

Some use cases require switching a pin between output and floating mode on the fly. This is very inconvenient with the current API. The DWM1001 board support crate has an example that demonstrates this.

I believe the solution for this is to add a tri-state mode that implements the following trait:

pub trait TriStatePin {
    fn set_high(&mut self);
    fn set_low(&mut self);
    fn set_floating(&mut self);
}

Such an abstraction has been proposed before.

If we decide to implement this, we should submit the trait I suggested above to embedded-hal.

Rework 840 SPIM support

While working on the 840, I realized:

  • We don't implement SPIM3
  • SPIM0-SPIM2 only support a max speed of 8MHz. If you use a higher speed, it is oddly slow
  • We don't do implicit copies for embedded-hal

I should be able to submit fixes for this, though I'm not sure if any of the other targets support SPIM3 as well.

[RFC] Change the way pin types are generated

This issue was first opened in the old nrf52-hal repository. Original discussion: jamesmunns/nrf52-hal#8


Most of the code in the GPIO module is generated using a macro, including all the types that represent pins. Through my experience working on lpc82x-hal, I've come to regard this as an anti-pattern.

To be clear, I'm not suggesting that we don't generate code using a macro. I'm suggesting that we minimize the amount of generated code, using it only to feed platform-specific bits into generic, hand-written code.

But more on my suggestion later. First, the reasons on why I regard generating everything (specifically all pin types) as an anti-pattern:

  1. It makes the code hard to read. If you're unfamiliar with the code and need to make sense of something, you constantly have to correlate the code in the macro, to the macro's argument list, to the macro invocation.
  2. The generated pin types represent two different concepts: Which pin this is, and what mode it is in. Combining these two things in the way that is done with the pin types violates the single responsibility principle.

Argument 1. is fairly self-evident, but argument 2. might seem a bit a bit esoteric. It does have real consequences, however. Consider a wrapper type around a pin that is generic over the pin, but specific about the state. Currently, this would require higher-kinded types to express:

struct PinWrapper<T>(T<Output<PushPull>>);

Since higher-kinded types don't exist in Rust, you'd have to use the generic pin type, making the wrapper type less type-safe than it could be:

struct PinWrapper(P0_Pin<Output<PushPull>>);

See dwm1001 for a real-life example of this problem.

I've encountered this same problem with lpc82x-hal and came up with the following solution:

  1. Pull as much code as possible out of the macro, into generic, hand-written types.
  2. Use traits to abstract over the non-generic parts of the implementation.
  3. Use a macro to generate types that implement those traits.

This would look something like this. First, the generic Pin type:

struct Pin<T, Mode> { ... }

Pin relies on traits to do whatever it needs to do:

impl<T> Pin<T, Output> where T: PinTrait {
    pub fn do_stuff(&mut self) {
        T::do_stuff();
    }
}

A code generation macro would still exist, but it would only generate the bare minimum: Types like P0_12 and their trait implementations. lpc82x-hal has several implementations of this pattern: Pin, Function

Now type of pin and mode of pin are cleanly separated, and all combinations can be cleanly expressed:

struct FullyGeneric<T, Mode>(Pin<T, Mode>);
struct TypeGeneric<T>(Pin<T, Output>);
struct ModeGeneric<Mode>(Pin<P0_12, Mode>);
struct FullySpecific(Pin<P0_12, Output);

P0_Pin and degrade would no longer be necessary.

There's one drawback that I never found a good solution for: Whereever you implement this pattern, you end up with a struct, e.g. Thing and a trait that really wants to have the same name. I've been calling these traits ThingTrait instead. This is not pretty, but okay. I'm open to any suggestions!

Add changelogs

The crates in this repository currently don't have a changelog, and therefore no convenient way to check out what changed in new releases.

It's currently not clear to me what the best way to do this would be. Just copy-past the changes from nrf52-hal-common to all nrf528xx-hal changelogs?

Consider supporting extended DMA transfers

This issue was first opened in the old nrf52-hal repository. Original discussion: jamesmunns/nrf52-hal#14


The nRF52832's DMA channels are limited to buffers with a maximum length of 255 bytes. This is very limiting. For example, in the DW1000 driver, I need to support registers that are much longer than that (although there are ways to read/write subsets).

There is a way to use multiple consecutive buffers to circumvent this limitation. The product specification alludes to this (see section 10.1), but doesn't really explain how this works. I found the following discussions that provide a clearer picture:

Since this technique requires additional system resources (PPI, TIMER) and applies to all DMA channels, I think it's probably best to provide this as a separate layer that builds on top of DMA users like SPIM.

`SaadcConfig` can only be default-constructed

It does not have any way of changing its fields, and the only way to create an instance is via Default::default(), so all the Resolution, Oversample, ... settings are impossible to use, unless I'm missing something.

Consider renaming repository to nrf52-hal

This repository contains HAL crates for nRF52 microcontrollers. I think the repository name should reflect that, especially since throughout the ecosystem, repositories that are named after a chip (without the -hal suffix) seem to contain peripheral access crates, not HAL crates.

cc @wez

Product Anomaly Notice (PAN) workaround support

I finally figured out why I have been having issues testing the radio functionality on my nRF51 dongle, the chip on here is old enough to be hit by "PAN 26. System: Manual setup is required to enable use of peripherals".

I wonder if applying workarounds for PAN should be done as part of the rt feature of nrf51? Somehow injecting a before-main function similar to the SystemInit from the SDK.

Support non-blocking serial/SPI/... communication

I'm working on embedded-platform and am targeting nrf52840 devices as the first use-case.

Currently, I'm using this code to support serial writes: https://github.com/dflemstr/embedded-platform/blob/f9ae5e7b686fdbf66ee3f172c755aea543d4c102/platforms/nrf52840/src/serial.rs#L19-L23

I haven't started on SPI/I²C/... mappings but I suspect there will be similar challenges in making the code non-blocking.

The execution model I have chosen is to have the main thread always run wfi when there is nothing happening, and rely on interrupts to wake it up, poll a main future, and do some work, before going back to wfi.

Ideally, the baseline behavior I would like to see is to break apart some of the blocking transactions into multiple steps. Let's look at this section for example:

https://github.com/nrf-rs/nrf52-hal/blob/90a8c3c7dbdb478b49580fd2bf2f89bdb9286cc2/nrf52-hal-common/src/uarte.rs#L145-L154

This could either be modeled as an explicit state machine (e.g. an enum) where during each state transition, there is some sort of polling method instead of a while loop. So imagine a SerialTransaction object with a poll() method that would eventually return a successful status.

If this approach sounds sane, I can make it into a PR.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.