Commit Graph

1809 Commits

Author SHA1 Message Date
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
bors[bot]
fdef047741
Merge #433
433: Update nightly r=Dirbaio a=Dirbaio



Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2021-10-17 23:46:32 +00:00
Dario Nieuwenhuis
d7b768992e examples/std: fix warning 2021-10-18 01:37:35 +02:00
huntc
785030df96 Use types to strengthen the buffer dimensioning 2021-10-18 10:26:11 +11:00
huntc
0c317a64f6 As suggested, use the const param to declare the internal sample for one channel only 2021-10-18 10:26:11 +11:00
huntc
cb56f52b99 Removed the Mode enum and factored out into two functions so that we can assert channel limits 2021-10-18 10:26:11 +11:00
huntc
a020b1a404 Combine intenset calls 2021-10-18 10:26:11 +11:00
huntc
b6cacb98db Compact expression 2021-10-18 10:26:11 +11:00
huntc
e37a10ae99 Hangover - should have set this to internal for a previous PR 2021-10-18 10:26:11 +11:00
huntc
fa82913bc3 We have to reduce the buffer size to cater for the number of channels to scan 2021-10-18 10:26:11 +11:00
huntc
3be274dc2a We must allow the run handler to mutate state
The handler may well need to close over and mutate state
2021-10-18 10:26:11 +11:00
huntc
34e9e85819 We can kick start the internal timer outside of the main loop 2021-10-18 10:26:11 +11:00
huntc
16b6c78332 Removed debugging logs 2021-10-18 10:26:11 +11:00
huntc
103a3305e2 Implements continuous sampling for the nRF SAADC
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 wlll be swapped once sampling has taken place.

A sample frequency is provided and will set the internal timer of the SAADC when there is just the one channel being sampled. Otherwise, PPI will be used to hook up the TIMER peripheral to drive the sampling task.
2021-10-18 10:26:11 +11:00
Dario Nieuwenhuis
00d67dc21a Update nightly 2021-10-18 01:26:06 +02:00
bors[bot]
90f6b56cba
Merge #434
434: Clippy fixes r=Dirbaio a=Dirbaio

Fixes most clippy lints. 

Added `#![allow(clippy::new_without_default)]` because I really, really don't agree with `new()` being the same as `default()`...


Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2021-10-17 23:19:45 +00:00
Dario Nieuwenhuis
f5e251fc81 Update clap 2021-10-18 01:19:01 +02:00
Dario Nieuwenhuis
a2e7c24e00 Clippy fixes 2021-10-18 01:05:29 +02:00
bors[bot]
d81a203ee2
Merge #429 #431
429: nrf/uarte: do not use WFE on drop. r=Dirbaio a=Dirbaio

- It disturbs other stuff that uses WFE/SEV in the system. I ran into issues with this.
- It needs the irq handler to check for RXTO/TXSTOPPED errors, which makes it slower.

431: interrupt: transmute instead of steal. r=Dirbaio a=Dirbaio

That steal method has a TAKEN=true write [here](6b013138b7/src/peripheral/mod.rs (L180)).
This is not zero cost, we don't want it. Transmute instead, which is zero cost.

Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2021-10-16 14:21:36 +00:00
Dario Nieuwenhuis
4c0fa03c14 interrupt: transmute instead of steal.
That steal method has a TAKEN=true write [here](6b013138b7/src/peripheral/mod.rs (L180)).
This is not zero cost, we don't want it. Transmute instead, which is zero cost.
2021-10-16 04:11:19 +02:00
Dario Nieuwenhuis
66d70cd146 nrf/uarte: do not use WFE on drop.
- It disturbs other stuff that uses WFE/SEV in the system. I ran into
  issues with this.
- It needs the irq handler to check for RXTO/TXSTOPPED errors, which makes
  it slower.
2021-10-16 03:14:47 +02:00
Dario Nieuwenhuis
d32477f5a1 executor: Inline enqueue fns 2021-10-16 01:50:10 +02:00
Dario Nieuwenhuis
39e5677621 executor: Use critical sections instead of atomic CAS loops 2021-10-16 01:49:54 +02:00
bors[bot]
05bc4d198e
Merge #423
423: nRF9160 support r=Dirbaio a=diondokter

- Created a chip file with all the peripherals, interrupts and peripheral implementations.
- All peripherals now use an alias for the NS (non-secure) version of the nRF9160 version.
- Implementations of peripherals that don't exist are ignored.
- Most PPI functionality has been stubbed out because the nRF91 has the newer DPPI which is not compatible with the current API. (The channels are also set to not configurable, so they are kinda useless now, but in principle the stubs should never be called)


Co-authored-by: Dion Dokter <dion@tweedegolf.com>
2021-10-13 21:11:41 +00:00
bors[bot]
7318fc026e
Merge #426
426: nrf/saadc: API improvements r=Dirbaio a=Dirbaio



Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2021-10-13 20:14:03 +00:00
Dario Nieuwenhuis
c675fb1036 nrf/saadc: make InputChannel private. 2021-10-13 22:13:30 +02:00
Dario Nieuwenhuis
d8c3365d6a nrf/saadc: make Input trait sealed. 2021-10-13 22:13:26 +02:00
Dario Nieuwenhuis
0d709fa5c8 nrf/saadc: require unborrow for Input.
This allows using borrowed pins in ChannelConfig.
2021-10-13 22:06:09 +02:00
Dion Dokter
c1c704bfc8 - Removed the enable assert from UARTE.
- Added nRF9160 to CI.
2021-10-13 15:00:08 +02:00
Dion Dokter
ddcee446c1 Added anomaly workaround from the HAL to improve the UARTE 2021-10-12 13:35:08 +02:00
Dion Dokter
2c2c284482 Undoing unnecessary changes 2021-10-12 11:55:38 +02:00
bors[bot]
bc76a24eaf
Merge #424
424: Add bors r=Dirbaio a=Dirbaio



Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2021-10-11 23:52:53 +00:00
Dario Nieuwenhuis
db289d6d5e Add bors 2021-10-12 01:52:26 +02:00