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