main.rs (5551B)
1 #![no_std] 2 #![no_main] 3 #![feature(abi_avr_interrupt)] 4 5 mod kiss; 6 mod rx; 7 mod tx; 8 9 use core::cell::RefCell; 10 use core::hint::spin_loop; 11 12 use arduino_hal::clock::MHz16; 13 use arduino_hal::hal::usart::{Event, Usart0}; 14 use arduino_hal::{pac, Adc}; 15 use avr_device::generic::Periph; 16 use avr_device::interrupt::{self, Mutex}; 17 use kiss::{KissAction, KissTncState}; 18 use panic_halt as _; 19 use rx::Receiver; 20 use tx::Transmitter; 21 22 type TC0 = Periph<pac::tc0::RegisterBlock, 53>; 23 type TC1 = Periph<pac::tc1::RegisterBlock, 54>; 24 25 struct Tnc { 26 state: TncState, 27 serial: Option<Usart0<MHz16>>, 28 receiver: Receiver, 29 transmitter: Transmitter, 30 kiss_state: KissTncState, 31 sample_timer: Option<TC0>, 32 symbol_timer: Option<TC1>, 33 } 34 35 impl Tnc { 36 // 52 * 8 = 416 cycles; at 16 MHz this gives a period of 26 µs (about 38460 Hz) 37 const SAMPLE_TIMER_COMPARE: u8 = 52; 38 // this should theoretically be 13_333 cycles, but in practice we have to go a little faster to 39 // account for overhead; this value seems to work well 40 const SYMBOL_TIMER_COMPARE: u16 = 13_300; 41 42 const fn default() -> Tnc { 43 Tnc { 44 state: TncState::Receiving, 45 serial: None, 46 receiver: Receiver::default(), 47 transmitter: Transmitter::default(), 48 kiss_state: KissTncState::Idle, 49 sample_timer: None, 50 symbol_timer: None, 51 } 52 } 53 pub(crate) fn handle_usart_byte(&mut self, byte: u8) { 54 if let Some(action) = self.kiss_state.update(byte) { 55 match action { 56 KissAction::PushTx(b) => { 57 let _ = self.transmitter.push_message_byte(b); 58 } 59 KissAction::ClearTx => self.transmitter.clear_message(), 60 KissAction::SendTx => { 61 if self.transmitter.has_pending_bytes() { 62 self.state = TncState::Transmitting; 63 self.transmitter.start(); 64 } 65 } 66 KissAction::_SetTxDelay { .. } => todo!(), 67 KissAction::_SetPersistence { .. } => todo!(), 68 KissAction::_SetSlotTime { .. } => todo!(), 69 KissAction::_SetTxTail { .. } => todo!(), 70 KissAction::_SetFullDuplex { .. } => todo!(), 71 KissAction::_SetHardware { .. } => todo!(), 72 KissAction::_Return => todo!(), 73 } 74 }; 75 } 76 } 77 78 enum TncState { 79 Receiving, 80 Transmitting, 81 } 82 83 static TNC: Mutex<RefCell<Tnc>> = Mutex::new(RefCell::new(Tnc::default())); 84 85 #[avr_device::interrupt(atmega328p)] 86 fn TIMER0_COMPA() { 87 interrupt::free(|cs| { 88 let mut tnc = TNC.borrow(cs).borrow_mut(); 89 match tnc.state { 90 TncState::Receiving => { 91 if tnc.receiver.sample_update() { 92 if let Some(ref mut symbol_timer) = tnc.symbol_timer { 93 symbol_timer 94 .tcnt1() 95 .write(|w| w.set(Tnc::SYMBOL_TIMER_COMPARE / 2)); 96 } 97 } 98 if let Some(byte) = tnc.receiver.get_output() { 99 if let Some(ref mut serial) = tnc.serial { 100 let _ = ufmt::uwriteln!(serial, "0x{:02x}", byte); 101 } 102 } 103 } 104 TncState::Transmitting => { 105 tnc.transmitter.sample_update(); 106 if tnc.transmitter.is_done() { 107 tnc.state = TncState::Receiving; 108 } 109 } 110 } 111 }); 112 } 113 114 #[avr_device::interrupt(atmega328p)] 115 fn TIMER1_COMPA() { 116 interrupt::free(|cs| { 117 let mut tnc = TNC.borrow(cs).borrow_mut(); 118 if let TncState::Transmitting = tnc.state { 119 tnc.transmitter.symbol_update(); 120 } 121 }); 122 } 123 124 #[avr_device::interrupt(atmega328p)] 125 fn USART_RX() { 126 interrupt::free(|cs| { 127 let mut tnc = TNC.borrow(cs).borrow_mut(); 128 if let Some(ref mut serial) = tnc.serial { 129 let byte = serial.read_byte(); 130 tnc.handle_usart_byte(byte); 131 } 132 }); 133 } 134 135 #[arduino_hal::entry] 136 fn main() -> ! { 137 let dp = arduino_hal::Peripherals::take().unwrap(); 138 let pins = arduino_hal::pins!(dp); 139 140 let mut serial = arduino_hal::default_serial!(dp, pins, 115200); 141 serial.listen(Event::RxComplete); 142 143 let sample_timer = dp.TC0; 144 sample_timer.tccr0a().write(|w| w.wgm0().ctc()); 145 sample_timer.tccr0b().write(|w| w.cs0().prescale_8()); 146 sample_timer 147 .ocr0a() 148 .write(|w| w.set(Tnc::SAMPLE_TIMER_COMPARE)); 149 sample_timer.timsk0().write(|w| w.ocie0a().set_bit()); 150 151 let symbol_timer = dp.TC1; 152 symbol_timer 153 .tccr1b() 154 .write(|w| w.wgm1().set(0b01).cs1().direct()); 155 symbol_timer 156 .ocr1a() 157 .write(|w| w.set(Tnc::SYMBOL_TIMER_COMPARE)); 158 symbol_timer.timsk1().write(|w| w.ocie1a().set_bit()); 159 160 interrupt::free(|cs| { 161 let mut tnc = TNC.borrow(cs).borrow_mut(); 162 tnc.serial = Some(serial); 163 tnc.sample_timer = Some(sample_timer); 164 tnc.symbol_timer = Some(symbol_timer); 165 tnc.receiver 166 .initialize(Adc::new(dp.ADC, Default::default()), pins.a0); 167 tnc.transmitter.initialize( 168 pins.d2.into_output(), 169 pins.d3.into_output(), 170 pins.d4.into_output(), 171 pins.d5.into_output(), 172 pins.d6.into_output(), 173 ); 174 }); 175 176 unsafe { avr_device::interrupt::enable() }; 177 178 loop { 179 spin_loop(); 180 } 181 }