Commit Graph

1541 Commits

Author SHA1 Message Date
Dario Nieuwenhuis
663141b4e4 nrf: add initial nrf5340 support 2021-10-28 03:36:25 +02:00
Dario Nieuwenhuis
c995a97f20 nrf91: support running in both S and NS mode. 2021-10-26 17:40:07 +02:00
bors[bot]
7cb34760c4
Merge #427
427: New nrf PPI api (with DPPI support for nRF91 & nRF53) r=Dirbaio a=diondokter

- Added _ppi and _dppi features to distinguish between the new and the old peripheral.
- Removed ConfigurableChannel and added capacity numbers to the channels
- Replaced the PPI api with a new one using the DPPI terminology (publish & subscribe)
- Updated all tasks and event registers for DPPI

My proposal for the new API.
Tested on my nRF52840 and nRF9160.

Biggest changes for nRF52 is that there's no longer a distinction made between fork task and normal task. You now subscribe tasks to a channel and at runtime it is checked whether or not there's still room for another subscription.
Same for events.

There are differences between the PPI and DPPI though:
- With the PPI you have a limited amount of tasks and events per channel, but a task or event can be used on multiple channels at the same time.
- With the DPPI you have an unlimited amount of tasks and events per channel, but every task or event can only be used on 1 channel.
This is all checked at runtime.

Currently you need to track which tasks and events are assigned to a channel in order to unassign them. For the PPI this data is stored centrally in the registers, so it would be easy to create e.g. `clear_all` and `get_subscribed_tasks` functions. But for the DPPI that data is stored decentrally and so would need some manual tracking.

If there are requests for tracking functionality, then it should be able to be made relatively easy. But for now this API is fine I think.

Co-authored-by: Dion Dokter <dion@tweedegolf.com>
Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2021-10-26 15:00:46 +00:00
Dario Nieuwenhuis
36d3eda2f9 ppi: simplify driver creation.
Moving `new_*` to the version-specific mod allows doing the correct
register writes right there in `new`, without needing abstractions
like `enable_all`/`disable_all`.
2021-10-26 16:52:51 +02:00
Dion Dokter
c63d747209 Fewer channel traits, more cfg to make the system work 2021-10-26 14:47:34 +02:00
Dion Dokter
4d3341dbb9 Fixed examples 2021-10-26 14:47:33 +02:00
Dion Dokter
6205d6da47 typo 2021-10-26 14:47:33 +02:00
Dion Dokter
a6c84cb915 - Interconnect is now PPI again
- Scary pointer math is now contained in the tasks and events
- ppi now sets the tasks and events immediately and the struct is now zero-sized
- StaticToOne is renamed to ZeroToOne
- Used DPPI tasks and events now panic when enabled twice
2021-10-26 14:47:31 +02:00
Dion Dokter
531dfcffb3 fmt 2021-10-26 14:47:13 +02:00
Dion Dokter
11655af034 Another redo using the feedback.
PPI is now split up into PPI and DPPI under the name 'interconnect'.
The tasks and events are tracked and reset in the drop function.
2021-10-26 14:47:12 +02:00
Dion Dokter
e6ec81b999 Fixed examples and added defmt format to the new error types 2021-10-26 14:46:39 +02:00
Dion Dokter
4950682a50 Some extra docs and better naming 2021-10-26 14:46:39 +02:00
Dion Dokter
65628e1f15 - Added _ppi and _dppi to distinguish between the new and the old peripheral.
- Removed ConfigurableChannel and added capacity numbers to the channels
- Replaced the PPI api with a new one using the DPPI terminology (publish & subscribe)
- Updated all tasks and event registers for DPPI
2021-10-26 14:46:39 +02:00
bors[bot]
01e5376b25
Merge #456
456: Fix L4 clock setup for MSI and PLL to allow RNG operation r=Dirbaio a=lulf

Example is tested on STM32L475VG.

Co-authored-by: Ulf Lilleengen <lulf@redhat.com>
2021-10-26 11:59:14 +00:00
bors[bot]
f8bd9d2b1c
Merge #441
441: Add implementation of async trait for STM32 I2C v2 r=Dirbaio a=lulf

* Add DMA read implementation for I2C v2
* Add example using DMA for I2C

Co-authored-by: Ulf Lilleengen <ulf.lilleengen@gmail.com>
2021-10-26 11:49:45 +00:00
Ulf Lilleengen
e55726964d Fix clock setup for MSI and PLL to allow RNG opereation
Add RNG example using PLL as clock source.
2021-10-26 13:45:53 +02:00
bors[bot]
7729091b39
Merge #450
450: nrf/nvmc: make PAGE_SIZE, FLASH_SIZE public. r=lulf a=Dirbaio



Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2021-10-25 08:05:19 +00:00
bors[bot]
9b59eb3dbe
Merge #448
448: Dummy pin implementation for Saadc internal vdd sampling r=Dirbaio a=jacobrosenthal

For instance, for reading the battery input voltage on the nrf
Api ends up looking like
`let channel_config = saadc::ChannelConfig::single_ended(saadc::VddInput::default());`

I ~haven't confirmed a sane reading yet~, but this compiles so is ready for bikeshedding
Update: It looks like Ive got sane readings

Co-authored-by: Jacob Rosenthal <jacobrosenthal@gmail.com>
2021-10-25 00:56:44 +00:00
Jacob Rosenthal
32850bba79 nrf: saadc dummy pin for vdd sampling 2021-10-24 09:41:51 -07:00
Dario Nieuwenhuis
e7ab979eb8 nrf/nvmc: make PAGE_SIZE, FLASH_SIZE public. 2021-10-24 18:23:22 +02:00
bors[bot]
f3f3858328
Merge #444
444: nrf: add NVMC driver. r=lulf a=Dirbaio

I haven't implemented `embassy_traits::Flash` because I want to change it to match embedded_storage, which is much better designed. 

Either way, NVMC can't do async anyway, so the best we could do is implementing the async trait in a blocking way...

Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2021-10-23 08:28:25 +00:00
bors[bot]
a8797f84f6
Merge #446
446: Use upstream version of rust-lorawan r=lulf a=lulf

The async device has been merged, so dependency can be updated to commit on the upstream master branch.

Co-authored-by: Ulf Lilleengen <ulf.lilleengen@gmail.com>
2021-10-22 18:05:58 +00:00
Ulf Lilleengen
504655d491 Use upstream version of rust-lorawan 2021-10-22 19:33:15 +02:00
bors[bot]
e038834ac3
Merge #445
445: Workaround duplicity of DMA channel declaration when the target chip … r=Dirbaio a=matoushybl

…specifies more than one request, by processing only the first declared request for the channel.

Fixes #443 .

Co-authored-by: Matous Hybl <hyblmatous@gmail.com>
2021-10-22 13:54:24 +00:00
Matous Hybl
4fbac40120 Workaround duplicity of DMA channel declaration when the target chip specifies more than one request, by processing only the first declared request for the channel. 2021-10-22 11:36:47 +02:00
Dario Nieuwenhuis
e78d226acd nrf: add NVMC driver. 2021-10-22 02:14:33 +02:00
Ulf Lilleengen
f8ebc967a9 Add implementation of async trait for STM32 I2C v2
* Add DMA read implementation for I2C v2
* Add example using DMA for I2C
2021-10-21 12:30:02 +02:00
bors[bot]
2b4e2bcbae
Merge #442
442: Configure the correct pin instances r=lulf a=lulf



Co-authored-by: Ulf Lilleengen <lulf@redhat.com>
2021-10-21 10:06:57 +00:00
Ulf Lilleengen
d2a79a46c5 Configure the correct pin instances 2021-10-21 11:57:00 +02:00
bors[bot]
a895b6351f
Merge #439
439: Prevent overflow in std timer driver r=lulf a=lulf

This prevents the std time driver from overflowing when setting the next
wakeup time. If an overflow occurs, default to sleeping up to 1 second.

Fixes #438

Co-authored-by: Ulf Lilleengen <ulf.lilleengen@gmail.com>
2021-10-20 13:16:25 +00:00
Ulf Lilleengen
5e6ee59ecd Fix time calculation
Use unwrap_or_get to avoid checking time when not necessary
2021-10-20 14:36:16 +02:00
Ulf Lilleengen
3c2daf0d32 Remove unused import 2021-10-20 14:36:16 +02:00
Ulf Lilleengen
6c9420978b Prevent overflow in std timer driver
This prevents the std time driver from overflowing when setting the next
wakeup time. If an overflow occurs, default to sleeping up to 1 second.

Fixes #438
2021-10-20 14:36:16 +02:00
bors[bot]
acce0f1d25
Merge #440
440: Add i2c example for L4 r=Dirbaio a=lulf

Tested to work on STM32 IOT01A  (STM32L475VG) board.

Co-authored-by: Ulf Lilleengen <ulf.lilleengen@gmail.com>
2021-10-20 11:34:18 +00:00
Ulf Lilleengen
9e461b771a Add i2c example for L4 2021-10-20 10:11:34 +02:00
bors[bot]
675172f981
Merge #436
436: Add support for temperature sensor peripheral r=lulf a=lulf

* Add TEMP peripheral to all nRF52 chips
* Add async HAL for reading temperature values
* Add example application reading temperature values

Co-authored-by: Ulf Lilleengen <lulf@redhat.com>
Co-authored-by: Ulf Lilleengen <ulf.lilleengen@gmail.com>
2021-10-19 18:50:37 +00:00
Ulf Lilleengen
69953a78f1 Use async fn instead of impl Future 2021-10-19 20:48:46 +02:00
Ulf Lilleengen
e807a9eaec Specify unit in log output 2021-10-19 15:32:16 +02:00
Ulf Lilleengen
c777b6aae1 Use AtomicWaker instead of Signal 2021-10-19 15:31:28 +02:00
Ulf Lilleengen
db3b315f94 Cargo fmt 2021-10-19 08:37:19 +02:00
Ulf Lilleengen
2ef4a45fa0 Add support for temperature sensor peripheral
* Add TEMP peripheral to all nRF52 chips
* Add async HAL for reading temperature values
* Add example application reading temperature values
2021-10-19 07:18:56 +02:00
bors[bot]
729b17bc25
Merge #428
428: executor: Use critical sections instead of atomic CAS loops r=lulf a=Dirbaio

Optimize executor wakes.

CAS loops (either `fetch_update`, or manual `load + compare_exchange_weak`) generate surprisingly horrible code: https://godbolt.org/z/zhscnM1cb

This switches to using critical sections, which makes it faster. On thumbv6 (Cortex-M0) it should make it even faster, as it is currently using `atomic-polyfill`, which will make many critical sections for each `compare_exchange_weak` anyway.

```
            opt-level=3   opt-level=s
   atmics:  105 cycles    101 cycles
       CS:   76 cycles     72 cycles
CS+inline:   72 cycles     64 cycles
```

Measured in nrf52 with icache disabled, with this code:

```rust


    poll_fn(|cx| {
        let task = unsafe { task_from_waker(cx.waker()) };

        compiler_fence(Ordering::SeqCst);
        let a = cortex_m::peripheral::DWT::get_cycle_count();
        compiler_fence(Ordering::SeqCst);

        unsafe { wake_task(task) }

        compiler_fence(Ordering::SeqCst);
        let b = cortex_m::peripheral::DWT::get_cycle_count();
        compiler_fence(Ordering::SeqCst);

        defmt::info!("cycles: {=u32}", b.wrapping_sub(a));

        Poll::Ready(())
    })
    .await;
````

Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2021-10-18 12:05:43 +00:00
bors[bot]
b22c472af3
Merge #435
435: Optimises the buffer passing for nRF SAADC r=huntc a=huntc

The buffer will always have been filled and we never explicitly stop the task outside of this code. Thus, we can assume the number of bytes in the slice.

Co-authored-by: huntc <huntchr@gmail.com>
2021-10-18 01:31:45 +00:00
huntc
3f31774674 Formatting 2021-10-18 12:29:31 +11:00
huntc
8dcc41c7f0 Optimises the buffer passing for nRF SAADC
The buffer will always have been filled and we never explicitly stop the task outside of this code. Thus, we can assume the number of bytes in the slice.
2021-10-18 12:23:13 +11:00
bors[bot]
a5c11b1a80
Merge #425
425: Implements continuous sampling for the nRF SAADC r=huntc a=huntc

Implements continuous sampling for the nRF SAADC and also renames `OneShot` to `Saadc`. The one-shot behaviour is retained with the `sample` method and a new `run_sampler` method is provided for efficiently (i.e. zero copying) sampler processing. A double buffer is used for continuously sampling, which is swapped appropriately.

A sample frequency is provided and will set the internal timer of the SAADC when there is just one channel being sampled. Otherwise, PPI will be used to hook up the TIMER peripheral to drive the sampling task. Two methods are provided for this: `run_task_sampler` and `run_task_sampler` with the latter available where the compiler sees that just one channel is configured. Note that we set up the PPI and timer behaviour outside of the `Saadc` for maximum flexibility.

A callback is provided to the `run_sampler` method. This is a synchronous callback that should return in a reasonably short space of time. The SAADC could stall if it does not. A reasonable practice is to perform a small amount of processing within the callback to yield a signal, perhaps via `mpsc`. In the case of `mpsc`, the `try_send` method becomes useful.

A new example has been provided to illustrate continuous sampling, along with multiple channels and external timing:

```rust
#[embassy::main]
async fn main(_spawner: Spawner, mut p: Peripherals) {
    let config = Config::default();
    let channel_1_config = ChannelConfig::single_ended(&mut p.P0_02);
    let channel_2_config = ChannelConfig::single_ended(&mut p.P0_03);
    let channel_3_config = ChannelConfig::single_ended(&mut p.P0_04);
    let mut saadc = Saadc::new(
        p.SAADC,
        interrupt::take!(SAADC),
        config,
        [channel_1_config, channel_2_config, channel_3_config],
    );

    let mut timer = Timer::new(p.TIMER0);
    timer.set_frequency(Frequency::F1MHz);
    timer.cc(0).write(100); // We want to sample at 10KHz
    timer.cc(0).short_compare_clear();

    let mut ppi = Ppi::new(p.PPI_CH0);
    ppi.set_event(timer.cc(0).event_compare());
    ppi.set_task(saadc.task_sample());
    ppi.enable();

    timer.start();

    let mut bufs = [[[0; 3]; 50]; 2];

    let mut c = 0;
    let mut a: i32 = 0;

    saadc
        .run_task_sampler(&mut bufs, move |buf| {
            for b in buf {
                a += b[0] as i32;
            }
            c += buf.len();
            if c > 10000 {
                a = a / c as i32;
                info!("channel 1: {=i32}", a);
                c = 0;
                a = 0;
            }
            SamplerState::Sampled
        })
        .await;
}
```

Co-authored-by: huntc <huntchr@gmail.com>
2021-10-18 00:51:19 +00:00
huntc
a94d44a689 Comments corrected 2021-10-18 11:45:23 +11:00
huntc
6dc0ed53ff Renamed sample rate to what it actually is 2021-10-18 11:42:30 +11:00
huntc
93407ed5e2 Remove unneeded stop 2021-10-18 11:31:06 +11:00
huntc
c7e426655d Ensure the compiler doesn't reorder things before calling the sampler 2021-10-18 11:28:43 +11:00