1 // Copyright 2013 Olivier Gillet. 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // (at your option) any later version. 7 // This program is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 // GNU General Public License for more details. 11 // You should have received a copy of the GNU General Public License 12 // along with this program. If not, see <http://www.gnu.org/licenses/>. 13 // 14 // ----------------------------------------------------------------------------- 15 // 16 // AVR FSK bootloader - inspired by its STM32F counterpart 17 18 #ifndef AVR_AUDIO_BOOTLOADER_FSK_DECODER_H_ 19 #define AVR_AUDIO_BOOTLOADER_FSK_DECODER_H_ 20 21 #include <avr/pgmspace.h> 22 23 namespace avr_audio_bootloader { 24 25 const uint16_t kPause = 16; 26 const uint16_t kOne = 8; 27 const uint16_t kZero = 4; 28 const uint16_t kOneZeroThreshold = (kOne + kZero) >> 1; 29 const uint16_t kPauseOneThreshold = (kPause + kOne) >> 1; 30 31 const uint16_t kMaxSyncDuration = 500; // Symbols 32 const uint8_t kPreambleSize = 32; 33 const uint16_t kPacketSize = SPM_PAGESIZE; 34 35 enum DecoderState { 36 DECODER_STATE_SYNCING, 37 DECODER_STATE_DECODING_PACKET, 38 DECODER_STATE_PACKET_RECEIVED, 39 DECODER_STATE_ERROR_SYNC, 40 DECODER_STATE_END_OF_TRANSMISSION 41 }; 42 43 class Decoder { 44 public: Decoder()45 Decoder() { } ~Decoder()46 ~Decoder() { } 47 Init()48 static inline void Init() { 49 packet_count_ = 0; 50 } 51 Sync()52 static inline void Sync() { 53 previous_sample_ = false; 54 duration_ = 0; 55 swallow_ = 4; 56 57 state_ = DECODER_STATE_SYNCING; 58 sync_blank_size_ = 0; 59 expected_symbols_ = 0xff; 60 preamble_remaining_size_ = kPreambleSize; 61 } 62 set_packet_destination(uint8_t * p)63 static inline void set_packet_destination(uint8_t* p) { 64 packet_ = p; 65 } 66 PushSample(bool sample)67 static inline DecoderState PushSample(bool sample) { 68 if (previous_sample_ == sample) { 69 ++duration_; 70 } else { 71 previous_sample_ = sample; 72 uint8_t symbol = 0; 73 74 if (duration_ >= kPauseOneThreshold) { 75 symbol = 2; 76 } else if (duration_ >= kOneZeroThreshold) { 77 symbol = 1; 78 } else { 79 symbol = 0; 80 } 81 82 if (swallow_) { 83 symbol = 2; 84 --swallow_; 85 } 86 87 PushSymbol(symbol); 88 89 duration_ = 0; 90 } 91 return state_; 92 } 93 ParseSyncHeader(uint8_t symbol)94 static inline void ParseSyncHeader(uint8_t symbol) { 95 if (!((1 << symbol) & expected_symbols_)) { 96 state_ = DECODER_STATE_ERROR_SYNC; 97 return; 98 } 99 100 switch (symbol) { 101 case 2: 102 ++sync_blank_size_; 103 if (sync_blank_size_ >= kMaxSyncDuration && packet_count_) { 104 state_ = DECODER_STATE_END_OF_TRANSMISSION; 105 return; 106 } 107 expected_symbols_ = (1 << 0) | (1 << 1) | (1 << 2); 108 preamble_remaining_size_ = kPreambleSize; 109 break; 110 111 case 1: 112 expected_symbols_ = (1 << 0); 113 --preamble_remaining_size_; 114 break; 115 116 case 0: 117 expected_symbols_ = (1 << 1); 118 --preamble_remaining_size_; 119 break; 120 } 121 122 if (preamble_remaining_size_ == 0) { 123 state_ = DECODER_STATE_DECODING_PACKET; 124 packet_size_ = 0; 125 packet_[packet_size_] = 0; 126 symbol_count_ = 0; 127 } 128 } 129 PushSymbol(uint8_t symbol)130 static void PushSymbol(uint8_t symbol) { 131 switch (state_) { 132 case DECODER_STATE_SYNCING: 133 ParseSyncHeader(symbol); 134 break; 135 136 case DECODER_STATE_DECODING_PACKET: 137 if (symbol == 2) { 138 state_ = DECODER_STATE_ERROR_SYNC; 139 } else { 140 packet_[packet_size_] |= symbol; 141 ++symbol_count_; 142 if (symbol_count_ == 8) { 143 symbol_count_ = 0; 144 ++packet_size_; 145 if (packet_size_ == kPacketSize + 4) { 146 ++packet_count_; 147 state_ = DECODER_STATE_PACKET_RECEIVED; 148 } else { 149 packet_[packet_size_] = 0; 150 } 151 } else { 152 packet_[packet_size_] <<= 1; 153 } 154 } 155 break; 156 157 case DECODER_STATE_PACKET_RECEIVED: 158 case DECODER_STATE_ERROR_SYNC: 159 case DECODER_STATE_END_OF_TRANSMISSION: 160 break; 161 } 162 } 163 164 private: 165 static bool previous_sample_; 166 static uint16_t duration_; 167 static uint8_t swallow_; 168 static DecoderState state_; 169 static uint8_t expected_symbols_; 170 static uint8_t preamble_remaining_size_; 171 static uint16_t sync_blank_size_; 172 static uint8_t symbol_count_; 173 static uint8_t* packet_; 174 static uint16_t packet_size_; 175 static uint16_t packet_count_; 176 }; 177 178 } // namespace avr_audio_bootloader 179 180 #endif // AVR_AUDIO_BOOTLOADER_FSK_DECODER_H_ 181