arduino-tnc

git clone https://git.bradleygannon.com/arduino-tnc.git
Log | Files | Refs

tx.rs (7601B)


      1 use arduino_hal::{
      2     hal::port::{PD2, PD3, PD4, PD5, PD6},
      3     port::{mode::Output, Pin},
      4 };
      5 use crc::{Crc, CRC_16_IBM_SDLC};
      6 use embedded_hal::digital::OutputPin;
      7 use heapless::Vec;
      8 
      9 static SINE_TABLE: [u8; 32] = [
     10     16, 19, 22, 24, 27, 29, 30, 31, 31, 31, 30, 29, 27, 24, 22, 19, 16, 12, 9, 7, 4, 2, 1, 0, 0, 0,
     11     1, 2, 4, 7, 9, 12,
     12 ];
     13 
     14 pub(crate) struct Transmitter {
     15     counter: u16,
     16     increment: u16,
     17     state: TransmitterState,
     18     dac_0: Option<Pin<Output, PD2>>,
     19     dac_1: Option<Pin<Output, PD3>>,
     20     dac_2: Option<Pin<Output, PD4>>,
     21     dac_3: Option<Pin<Output, PD5>>,
     22     dac_4: Option<Pin<Output, PD6>>,
     23     message: Vec<u8, 256>,
     24 }
     25 
     26 #[derive(PartialEq)]
     27 pub(crate) enum TransmitterState {
     28     Off,
     29     StartFlag {
     30         bit_index: u8,
     31         count: usize,
     32     },
     33     Payload {
     34         byte_index: usize,
     35         bit_index: u8,
     36         ones_count: usize,
     37         stuff_bit: bool,
     38     },
     39     EndFlag {
     40         bit_index: u8,
     41         count: usize,
     42     },
     43 }
     44 
     45 impl Transmitter {
     46     const START_FLAG_BYTES: usize = 45;
     47     const END_FLAG_BYTES: usize = 15;
     48 
     49     const MARK_INCREMENT: u16 = 2100;
     50     const SPACE_INCREMENT: u16 = 3838;
     51 
     52     pub(crate) const fn default() -> Transmitter {
     53         Transmitter {
     54             counter: 0,
     55             increment: 0,
     56             state: TransmitterState::Off,
     57             dac_0: None,
     58             dac_1: None,
     59             dac_2: None,
     60             dac_3: None,
     61             dac_4: None,
     62             message: Vec::new(),
     63         }
     64     }
     65     pub(crate) fn initialize(
     66         &mut self,
     67         dac_0: Pin<Output, PD2>,
     68         dac_1: Pin<Output, PD3>,
     69         dac_2: Pin<Output, PD4>,
     70         dac_3: Pin<Output, PD5>,
     71         dac_4: Pin<Output, PD6>,
     72     ) {
     73         self.dac_0 = Some(dac_0);
     74         self.dac_1 = Some(dac_1);
     75         self.dac_2 = Some(dac_2);
     76         self.dac_3 = Some(dac_3);
     77         self.dac_4 = Some(dac_4);
     78     }
     79     fn u8_index_msb(byte: u8, bit_index: u8) -> bool {
     80         (byte >> (7 - bit_index)) & 1 != 0
     81     }
     82     pub(crate) fn start(&mut self) {
     83         let crc = Crc::<u16>::new(&CRC_16_IBM_SDLC);
     84         let mut digest = crc.digest();
     85         digest.update(self.message.as_slice());
     86         let crc_bytes = digest.finalize().to_le_bytes();
     87 
     88         for byte in self.message.iter_mut() {
     89             *byte = byte.reverse_bits();
     90         }
     91         let _ = self.message.push(crc_bytes[0].reverse_bits());
     92         let _ = self.message.push(crc_bytes[1].reverse_bits());
     93 
     94         self.state = TransmitterState::StartFlag {
     95             bit_index: 0,
     96             count: 0,
     97         };
     98     }
     99     pub(crate) fn push_message_byte(&mut self, byte: u8) -> Result<(), u8> {
    100         self.message.push(byte)
    101     }
    102     pub(crate) fn clear_message(&mut self) {
    103         self.message.clear();
    104     }
    105     pub(crate) fn has_pending_bytes(&self) -> bool {
    106         !self.message.is_empty()
    107     }
    108     pub(crate) fn is_done(&self) -> bool {
    109         self.state == TransmitterState::Off
    110     }
    111     pub(crate) fn sample_update(&mut self) {
    112         self.counter = self.counter.wrapping_add(self.increment);
    113         let sine_index = ((self.counter >> 11) as usize).clamp(0, SINE_TABLE.len());
    114         if let Some(sine_value) = SINE_TABLE.get(sine_index) {
    115             if let Some(ref mut dac_0) = self.dac_0 {
    116                 let _ = dac_0.set_state((sine_value & 0b10000 != 0).into());
    117             };
    118             if let Some(ref mut dac_1) = self.dac_1 {
    119                 let _ = dac_1.set_state((sine_value & 0b01000 != 0).into());
    120             };
    121             if let Some(ref mut dac_2) = self.dac_2 {
    122                 let _ = dac_2.set_state((sine_value & 0b00100 != 0).into());
    123             };
    124             if let Some(ref mut dac_3) = self.dac_3 {
    125                 let _ = dac_3.set_state((sine_value & 0b00010 != 0).into());
    126             };
    127             if let Some(ref mut dac_4) = self.dac_4 {
    128                 let _ = dac_4.set_state((sine_value & 0b00001 != 0).into());
    129             };
    130         }
    131     }
    132     pub(crate) fn symbol_update(&mut self) {
    133         let new_symbol = match self.state {
    134             TransmitterState::Off => None,
    135             TransmitterState::StartFlag {
    136                 bit_index,
    137                 count: _,
    138             }
    139             | TransmitterState::EndFlag {
    140                 bit_index,
    141                 count: _,
    142             } => Some(Self::u8_index_msb(0x7e, bit_index)),
    143             TransmitterState::Payload {
    144                 byte_index,
    145                 bit_index,
    146                 ref mut ones_count,
    147                 ref mut stuff_bit,
    148             } => {
    149                 if *stuff_bit {
    150                     *stuff_bit = false;
    151                     Some(false)
    152                 } else {
    153                     let maybe_byte = self.message.get(byte_index);
    154                     if let Some(byte) = maybe_byte {
    155                         let bit = Self::u8_index_msb(*byte, bit_index);
    156                         if bit {
    157                             *ones_count += 1;
    158                         } else {
    159                             *ones_count = 0;
    160                         }
    161                         Some(bit)
    162                     } else {
    163                         Some(false)
    164                     }
    165                 }
    166             }
    167         };
    168         self.increment = match new_symbol {
    169             Some(true) => self.increment,
    170             Some(false) => {
    171                 if self.increment == Self::MARK_INCREMENT {
    172                     Self::SPACE_INCREMENT
    173                 } else {
    174                     Self::MARK_INCREMENT
    175                 }
    176             }
    177             None => 0,
    178         };
    179         match self.state {
    180             TransmitterState::Off => (),
    181             TransmitterState::StartFlag {
    182                 ref mut bit_index,
    183                 ref mut count,
    184             } => {
    185                 *bit_index += 1;
    186                 if *bit_index >= 8 {
    187                     *count += 1;
    188                     *bit_index = 0;
    189                     if *count > Self::START_FLAG_BYTES {
    190                         self.state = TransmitterState::Payload {
    191                             byte_index: 0,
    192                             bit_index: 0,
    193                             ones_count: 0,
    194                             stuff_bit: false,
    195                         };
    196                     }
    197                 }
    198             }
    199             TransmitterState::Payload {
    200                 ref mut byte_index,
    201                 ref mut bit_index,
    202                 ref mut ones_count,
    203                 ref mut stuff_bit,
    204             } => {
    205                 if *ones_count >= 5 {
    206                     *stuff_bit = true;
    207                     *ones_count = 0;
    208                 } else {
    209                     *bit_index += 1;
    210                     if *bit_index >= 8 {
    211                         *byte_index += 1;
    212                         *bit_index = 0;
    213                         if *byte_index >= self.message.len() {
    214                             self.state = TransmitterState::EndFlag {
    215                                 bit_index: 0,
    216                                 count: 0,
    217                             };
    218                         }
    219                     }
    220                 }
    221             }
    222             TransmitterState::EndFlag {
    223                 ref mut bit_index,
    224                 ref mut count,
    225             } => {
    226                 *bit_index += 1;
    227                 if *bit_index >= 8 {
    228                     *count += 1;
    229                     *bit_index = 0;
    230                     if *count > Self::END_FLAG_BYTES {
    231                         self.state = TransmitterState::Off;
    232                         self.message.clear();
    233                     }
    234                 }
    235             }
    236         }
    237     }
    238 }