Skip to content

Latest commit

 

History

History
145 lines (104 loc) · 3.9 KB

2020-04-27.md

File metadata and controls

145 lines (104 loc) · 3.9 KB

Office Hours

Post Show Summary:

Planned Topics

Stream Notes

So what are we doing here?

Two contexts:

  • Interrupt Context
  • App context

Additionally, we are going to be doing DMA, which means we need to have packets:

  1. In RAM (nrf52 specific)
  2. Data must be contiguous (because DMA)
  3. Comms between contexts must be thread safe (because interrupts)
  4. Data must have 'static lifetime (mostly)

Quick Primer on Heapless and BBQueue

heapless::Queue<[0u8; 32], U10>

| 32 bytes | 32 bytes | ..... | 32 bytes |

BUT if you have variable packet

bbqueue - really great for variable size chunks of u8 (bytes).

| ONE BIG POOL OF BYTES | | | | | | | | | ] | ][ ]

What is our interface going to look like?

   APP SIDE                IRQ SIDE
   ========                ========
   Some handle            Some Handle
   - send packet          - get outgoing packet
   - receive a packet     - shove incoming packet


         ====================> OUTGOING
         PRODUCER     CONSUMER

         <==================== INCOMING
         CONSUMER     PRODUCER

We need two BBQueues!

// Buffer for ESB, incoming queue is 1024 bytes, outgoing queue is 512 bytes
static BUFFER: EsbBuffer<U1024, U512> = EsbBuffer::new();

fn main() {
    let (mut app_esb, irq_esb) = EsbInterface::new(&BUFFER).unwrap();

    // somehow send `irq_esb` to the interrupt
    something(irq_esb);

    // Enable ESB or something?
    app_esb.init(...).unwrap();

    // TODO: What is a better interface?
    if auto_send { // DO this one
        // start the reception process
        let mut msg = app_esb.start_send().unwrap();

        // Fill the outgoing message
        msg[..8].copy_from_slice(&[10u8; 8]);

        // NOTE: This pends the RADIO interrupt too!
        msg.complete_send();
    } else {
        // start the reception process
        let mut msg = app_esb.start_push().unwrap();

        // Fill the outgoing message
        msg[..8].copy_from_slice(&[10u8; 8]);

        msg.finish_push();

        // Trigger send
        app_esb.start_tx();
    }


    // OR: Do we want

    // Wait for an incoming message
    while !app_esb.msg_ready() {
        continue;
    }

    // now we're not waiting
    let incoming = app_esb.get_incoming().unwrap();

    assert_eq!(&incoming[..8], &[11u8; 8]);
}

#[interrupt]
fn RADIO() {
    static mut STATE = ...;

    let esb_handle = something_get().unwrap();

    // Something with the radio?
    match STATE {
        State::Idle => {
            // check for outgoing?
        }
        State::WaitingForAck => {
            // check for incoming?
            // Maybe also a new outgoing?
            if got_ack() {
                push_into_queue()
                check_for_next()
            }
        }
    }
}