Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New embedded assignment #195

Draft
wants to merge 112 commits into
base: main
Choose a base branch
from
Draft

New embedded assignment #195

wants to merge 112 commits into from

Conversation

Mirabellensaft
Copy link
Contributor

Hi Jonathan, can you check dk_template/src/lib.rs if the button and UARTE implementation are correct so I can write the exercise text?

Notes about the proposed exercise

BSC Exercise

In this exercise you will learn how to write a board support crate.
The bsc template will already contain the led and timer implementation.
The radio and USB/Power implementations will be deleted, because that just takes up unnecessary space and adds to confusion.

Learning goals

  • implement buttons functionality
  • uarte implementation
  • impl blocks, associated functions, methods
  • generate docs!

Steps

Write a button implementation

  • add field in the board struct

  • add struct for all buttons

  • add struct for the single button

  • Read docs, section 8.7 for info about pins and pin configuration

  • add button bring up to board init

  • add doc lines every where!

  • add methods in impl block:

    • detect button push
    • debounce button function? like in knurling session, requires implementation of a second timer, just for this?

Write Uarte implementation

  • add field to the board struct
  • add struct for the instance, how to figure out what the type of the inner field is
  • create instance in init, add baudrate, parity etc.
  • add to instantiation of board struct
  • impl fmt::Write for the Uarte struct, simple write does not work because of dma
  • example code with button is not a good idea for the simple button implementation.

I think this is plenty for an hour.

@Mirabellensaft Mirabellensaft requested review from japaric and jonathanpallant and removed request for japaric February 14, 2023 18:11
@jonathanpallant jonathanpallant self-assigned this Feb 16, 2023
defmt::trace!("blocking for {:?} ...", duration);

// 1 cycle = 1 microsecond
const NANOS_IN_ONE_MICRO: u32 = 1_000;
Copy link
Member

@jonathanpallant jonathanpallant Feb 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be simpler using as_micros.

let mut micros = duration.as_micros();
while micros > u128::from(u32::MAX) {
    self.inner.delay_us(u32::MAX);
    micros -= u128::from(u32::MAX);
}
self.inner.delay_us(micros as u32);

// NOTE this will run at the highest priority, higher priority than RTIC tasks
#[interrupt]
fn RTC0() {
let curr = OVERFLOWS.load(Ordering::Relaxed);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a Cortex-M4, so I think fetch_add is available?

unsafe {
// NOTE volatile is used to order these load operations among themselves
let hi1 = overflows.read_volatile();
let low = core::mem::transmute::<_, RTC0>(())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like how this conjures up an RTC reference. If you don't own the RTC object, I would do a raw pointer read from a literal integer address.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I don't like reading a static AtomicU32 through a *mut u32 pointer. It just seems unnecessarily unsafe.

// the fraction can be reduced to `1953125 / 64`
// which can be further decomposed as `78125 * (5 / 4) * (5 / 4) * (1 / 4)`.
// Doing the operation this way we can stick to 32-bit arithmetic without overflowing the value
// at any stage
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just use a u64 or a u128 and let the compiler figure it out. It'd take me at least 10 minutes to satisfy myself this was correct and use most of a sheet of A4 paper doing it.

.bits();
let hi2 = overflows.read_volatile();

if hi1 == hi2 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This "read it twice, and if before == after, then you're OK" is OK and a common idiom. That can stay.

@@ -0,0 +1,5 @@
MEMORY
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth a note here as to which chip we're running on, and a link to the Manufacturer's data sheet / product page, so you can easily verify that these numbers are correct.


// put memory layout (linker script) in the linker search path
fs::copy("memory.x", out_dir.join("memory.x"))?;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add rerun-if-changed on memory.x?

other-feature = []

# do NOT modify these features
defmt-default = []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need these any more?

See https://defmt.ferrous-systems.com/migration-02-03.html

Mirabellensaft and others added 30 commits March 21, 2023 17:36
Add pyserial and change uarte setup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants