Jump to content

DAC

From Ratpack


DataBlock Struct

```
typedef struct {
    int length; // Length in bits
    int current_index; // current position *TO BE READ NEXT* in bits
    uint8_t flags; // an area to communicate between different things accessing this memory
    const int max_length; // maximum length which can be stored in `data` in bits
    const uint8_t* data; // pointer to uint8 array to store data in
} DataBlock_s;
```

FLAGS Data

- 0 for DAC_STOPPED - 1 for DAC_WORKING

Dac Outputting Overview

- Setup handled by DAC_init()
- Tim3 will hold a given frequency, it has an approximately 0.5second period. This is how long the high freq is held for the one bit.
- Once Tim3 finishes, it will call a handler that checks if done, or sets Tim6 ARR depending on the next bit
- Tim6 will at halfway through set the dac's output to 1, and at the end set the dac's output to 0. This has a frequency on the order of 1.2kHz, or 2.4kHz. This will transmit the frequency for the duration of Tim3's output
- From packet_framer() we write the DataBlock_s->length and ->data fields, then call DAC_init()

DAC_init()

- Set current_index to zero
- set flags to 1 to mean the dac is working, external stuff should respect that and not try to write into this block
- Enable Tim6
- Enable radio PTT (once implemented)
- Enable Tim3
- Manually set Tim3 to max value to 'naturally' trigger a reset? Is this possible? We could also just call the handler, but then we get a race condition I think if the timer's going and other interrupts could delay it? We could also just wait 0.5s for it to happen actually naturally

Timer3 Interrupt

The long one that changes the frequency of TIm6

- if current position is less than message length
    - Get the bit stated by current_index and set TIM6's ARR accordingly to hf if it's a 1, or lf it's a 0. Remember that current_index is the bit index
- else (current pos is strictly greater than message length)
    - Disable radio PTT (once implemented)
    - Stop Tim6
    - Stop Tim3
    - Set ->flags to 0 to indicate done transmitting

Timer6 Interrupts

The fast one that sends 0s and 1s to the dac

Halfway interrupt: Write 1 into dac
Fullway interrupt: Write 0 into dac

This could alternately be implemented by xoring 1 with the old value and only having an interrupt at the end of a faster timer, but reading the old value is likely less worth it.