You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

340 lines
11KB

  1. // Copyright 2013 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. #include "stm_audio_bootloader/qpsk/demodulator.h"
  25. #include <cstring>
  26. #define abs(x) (x < 0 ? -x : x)
  27. namespace stm_audio_bootloader {
  28. const uint16_t kObservationWindow = 4096;
  29. const uint32_t kPowerThreshold = 30;
  30. const uint16_t kNumSkippedZeroSymbols = 32;
  31. const uint16_t kNumLockedTemplateSymbols = 4;
  32. int16_t lut_sine[] = {
  33. 0, 50, 100, 150, 200, 250, 300, 350, 399,
  34. 448, 497, 546, 594, 642, 689, 737, 783, 829,
  35. 875, 920, 965, 1009, 1052, 1095, 1137, 1179, 1219,
  36. 1259, 1299, 1337, 1375, 1412, 1448, 1483, 1517, 1550,
  37. 1583, 1614, 1644, 1674, 1702, 1730, 1756, 1781, 1806,
  38. 1829, 1851, 1872, 1892, 1910, 1928, 1944, 1959, 1973,
  39. 1986, 1998, 2008, 2017, 2025, 2032, 2038, 2042, 2045,
  40. 2047, 2048, 2047, 2045, 2042, 2038, 2032, 2025, 2017,
  41. 2008, 1998, 1986, 1973, 1959, 1944, 1928, 1910, 1892,
  42. 1872, 1851, 1829, 1806, 1781, 1756, 1730, 1702, 1674,
  43. 1644, 1614, 1583, 1550, 1517, 1483, 1448, 1412, 1375,
  44. 1337, 1299, 1259, 1219, 1179, 1137, 1095, 1052, 1009,
  45. 965, 920, 875, 829, 783, 737, 689, 642, 594,
  46. 546, 497, 448, 399, 350, 300, 250, 200, 150,
  47. 100, 50, 0, -50, -100, -150, -200, -250, -300,
  48. -350, -399, -448, -497, -546, -594, -642, -689, -737,
  49. -783, -829, -875, -920, -965, -1009, -1052, -1095, -1137,
  50. -1179, -1219, -1259, -1299, -1337, -1375, -1412, -1448, -1483,
  51. -1517, -1550, -1583, -1614, -1644, -1674, -1702, -1730, -1756,
  52. -1781, -1806, -1829, -1851, -1872, -1892, -1910, -1928, -1944,
  53. -1959, -1973, -1986, -1998, -2008, -2017, -2025, -2032, -2038,
  54. -2042, -2045, -2047, -2048, -2047, -2045, -2042, -2038, -2032,
  55. -2025, -2017, -2008, -1998, -1986, -1973, -1959, -1944, -1928,
  56. -1910, -1892, -1872, -1851, -1829, -1806, -1781, -1756, -1730,
  57. -1702, -1674, -1644, -1614, -1583, -1550, -1517, -1483, -1448,
  58. -1412, -1375, -1337, -1299, -1259, -1219, -1179, -1137, -1095,
  59. -1052, -1009, -965, -920, -875, -829, -783, -737, -689,
  60. -642, -594, -546, -497, -448, -399, -350, -300, -250,
  61. -200, -150, -100, -50, 0
  62. };
  63. const int16_t filter_coefficients_3_7[] = {
  64. -20, 40, -55, 64, 255, 64, -55, 40
  65. };
  66. const int16_t filter_coefficients_4_7[] = {
  67. -21, -51, 123, 255, 123, -51, -21
  68. };
  69. const int16_t filter_coefficients_6_7[] = {
  70. -70, 25, 180, 255, 180, 25, -70
  71. };
  72. const int16_t filter_coefficients_8_7[] = {
  73. -35, 85, 205, 255, 205, 85, -35
  74. };
  75. const int16_t filter_coefficients_12_7[] = {
  76. 45, 149, 227, 255, 227, 149, 45
  77. };
  78. const int16_t filter_coefficients_16_7[] = {
  79. 0, 98, 180, 236, 255, 236, 180, 98
  80. };
  81. const int16_t* const cutoff_table[] = {
  82. NULL,
  83. NULL,
  84. NULL,
  85. filter_coefficients_3_7,
  86. filter_coefficients_4_7,
  87. NULL,
  88. filter_coefficients_6_7,
  89. NULL,
  90. filter_coefficients_8_7,
  91. NULL,
  92. NULL,
  93. NULL,
  94. filter_coefficients_12_7,
  95. NULL,
  96. NULL,
  97. NULL,
  98. filter_coefficients_16_7
  99. };
  100. void Demodulator::Init(
  101. uint32_t phase_increment,
  102. uint16_t cutoff_reciprocal,
  103. uint16_t symbol_duration) {
  104. for (uint16_t i = 0; i < kFilterSize; ++i) {
  105. filter_coefficients_[i] = cutoff_table[cutoff_reciprocal][i];
  106. }
  107. symbol_duration_ = symbol_duration;
  108. phase_increment_ = phase_increment;
  109. dc_offset_ = 2048 << 8;
  110. samples_.Init();
  111. symbols_.Init();
  112. Reset();
  113. }
  114. void Demodulator::Reset() {
  115. memset(q_taps_, 0, sizeof(q_taps_));
  116. memset(i_taps_, 0, sizeof(i_taps_));
  117. memset(q_history_, 0, sizeof(q_history_));
  118. memset(i_history_, 0, sizeof(i_history_));
  119. phase_ = 0;
  120. phase_error_ = 0;
  121. decision_counter_ = 0;
  122. history_ptr_ = 0;
  123. decision_counter_ = symbol_duration_;
  124. }
  125. int16_t Demodulator::DecideSymbol(bool adjust_timing) {
  126. int32_t q_acc = 0;
  127. int32_t i_acc = 0;
  128. // Summation sets for decision
  129. //
  130. // Present ---------------------------------------> Past
  131. //
  132. // ========================================= Early
  133. // ========================================= On time
  134. // ========================================= Late
  135. // ===== Head
  136. // ===== Head 2
  137. // ===== Tail
  138. // ===== Tail 2
  139. //
  140. uint16_t now = history_ptr_ + kHistorySize;
  141. for (uint16_t i = 1; i < symbol_duration_ - 1; ++i) {
  142. uint16_t ptr = (now - i) & kHistoryMask;
  143. q_acc += q_history_[ptr];
  144. i_acc += i_history_[ptr];
  145. }
  146. if (adjust_timing) {
  147. uint16_t head_ptr = history_ptr_;
  148. uint16_t head_2_ptr = (now - 1) & kHistoryMask;
  149. uint16_t tail_ptr = (now - symbol_duration_ + 2) & kHistoryMask;
  150. uint16_t tail_2_ptr = (now - symbol_duration_ + 1) & kHistoryMask;
  151. int32_t q_acc_late = q_history_[head_ptr] + q_acc - q_history_[tail_ptr];
  152. int32_t i_acc_late = i_history_[head_ptr] + i_acc - q_history_[tail_ptr];
  153. int32_t q_acc_early = q_acc + q_history_[tail_2_ptr] - q_history_[head_2_ptr];
  154. int32_t i_acc_early = i_acc + i_history_[tail_2_ptr] - i_history_[head_2_ptr];
  155. uint32_t late_strength = abs(q_acc_late) + abs(i_acc_late);
  156. uint32_t on_time_strength = abs(q_acc) + abs(i_acc);
  157. uint32_t early_strength = abs(q_acc_early) + abs(i_acc_early);
  158. if (late_strength > ((5 * on_time_strength) >> 2)) {
  159. q_acc = q_acc_late;
  160. i_acc = i_acc_late;
  161. ++decision_counter_;
  162. } else if (early_strength > ((5 * on_time_strength) >> 2)) {
  163. q_acc = q_acc_early;
  164. i_acc = i_acc_early;
  165. --decision_counter_;
  166. }
  167. }
  168. return (i_acc < 0 ? 0 : 1) + (q_acc < 0 ? 0 : 2);
  169. }
  170. void Demodulator::EstimateDcComponent() {
  171. while (samples_.readable()) {
  172. int32_t sample = samples_.ImmediateRead() - (dc_offset_ >> 8);
  173. dc_offset_ += sample;
  174. ++skipped_samples_;
  175. if (skipped_samples_ >= kObservationWindow) {
  176. skipped_samples_ = 0;
  177. power_ = 0;
  178. state_ = DEMODULATOR_STATE_ESTIMATE_POWER;
  179. break;
  180. }
  181. }
  182. }
  183. void Demodulator::EstimatePower() {
  184. while (samples_.readable()) {
  185. int32_t sample = samples_.ImmediateRead() - (dc_offset_ >> 8);
  186. dc_offset_ += sample;
  187. power_ += sample * sample >> 4;
  188. ++skipped_samples_;
  189. if (skipped_samples_ >= kObservationWindow) {
  190. uint32_t detected_power = power_ / kObservationWindow;
  191. skipped_samples_ = 0;
  192. power_ = 0;
  193. if (detected_power >= kPowerThreshold) {
  194. state_ = DEMODULATOR_STATE_CARRIER_SYNC;
  195. break;
  196. }
  197. }
  198. }
  199. }
  200. void Demodulator::Demodulate() {
  201. while (samples_.readable()) {
  202. // Remove DC offset.
  203. int32_t sample = samples_.ImmediateRead() - (dc_offset_ >> 8);
  204. dc_offset_ += sample;
  205. phase_ += phase_increment_;
  206. // Demodulate.
  207. int32_t i_osc = lut_sine[((phase_ >> 24) + 64) & 0xff];
  208. int32_t q_osc = lut_sine[phase_ >> 24];
  209. i_taps_[0] = (sample * -i_osc) >> 8;
  210. q_taps_[0] = (sample * q_osc) >> 8;
  211. int32_t i = 0;
  212. int32_t q = 0;
  213. // Carrier rejection filter.
  214. for (uint16_t j = 0; j < kFilterSize; ++j) {
  215. i += i_taps_[j] * filter_coefficients_[j];
  216. q += q_taps_[j] * filter_coefficients_[j];
  217. }
  218. for (uint16_t j = kFilterSize - 1; j > 0; --j) {
  219. i_taps_[j] = i_taps_[j - 1];
  220. q_taps_[j] = q_taps_[j - 1];
  221. }
  222. // PLL to lock onto the carrier.
  223. int16_t i_sign = i < 0 ? -1 : 1;
  224. int16_t q_sign = q < 0 ? -1 : 1;
  225. int32_t phase_error = i_sign * q - q_sign * i;
  226. if (state_ == DEMODULATOR_STATE_CARRIER_SYNC) {
  227. phase_error = i - q; // Lock to (-1 -1) during sync phase.
  228. }
  229. phase_error_ = (3 * phase_error_ + phase_error) >> 2;
  230. phase_ += phase_error_ << 3;
  231. phase_increment_ += (phase_error_ >> 1);
  232. // Store in history buffer (for detection).
  233. q_history_[history_ptr_] = q >> 8;
  234. i_history_[history_ptr_] = i >> 8;
  235. history_ptr_ = (history_ptr_ + 1) & kHistoryMask;
  236. --decision_counter_;
  237. if (!decision_counter_) {
  238. decision_counter_ = symbol_duration_;
  239. // In carrier sync mode, we just let the PLL stabilize until we
  240. // consistently decode a string of 0s.
  241. switch (state_) {
  242. case DEMODULATOR_STATE_CARRIER_SYNC:
  243. if (DecideSymbol(false) == 0) {
  244. ++skipped_symbols_;
  245. if (skipped_symbols_ == kNumSkippedZeroSymbols) {
  246. SyncDecision();
  247. }
  248. }
  249. break;
  250. case DEMODULATOR_STATE_DECISION_SYNC:
  251. symbols_.Overwrite(4);
  252. break;
  253. case DEMODULATOR_STATE_OK:
  254. symbols_.Overwrite(DecideSymbol(true));
  255. break;
  256. default:
  257. break;
  258. }
  259. }
  260. if (state_ == DEMODULATOR_STATE_DECISION_SYNC) {
  261. // Match the demodulated Q/I channels with the shape of the alignment
  262. // sequence.
  263. int32_t correlation = 0;
  264. uint16_t ptr = history_ptr_ + kHistorySize;
  265. for (uint16_t k = 0; k < 2 * symbol_duration_; ++k) {
  266. int32_t expected_q = k < symbol_duration_ ? -1 : 1;
  267. int32_t expected_i = -expected_q;
  268. correlation += q_history_[(ptr - k) & kHistoryMask] * expected_q;
  269. correlation += i_history_[(ptr - k) & kHistoryMask] * expected_i;
  270. }
  271. if (correlation > correlation_maximum_) {
  272. correlation_maximum_ = correlation;
  273. }
  274. if (correlation < 0) {
  275. // Reset the peak detector at each valley in the detection function,
  276. // so that we can detect several consecutive peaks.
  277. correlation_maximum_ = 0;
  278. }
  279. // Detect a local maximum in the output of the correlator.
  280. ptr = history_ptr_ + kHistorySize - (symbol_duration_ >> 1);
  281. if (correlation_history_[0] > correlation &&
  282. correlation_history_[0] > correlation_history_[1] &&
  283. correlation_history_[0] == correlation_maximum_ &&
  284. q_history_[ptr & kHistoryMask] < 0 &&
  285. i_history_[ptr & kHistoryMask] > 0) {
  286. ++skipped_symbols_;
  287. if (skipped_symbols_ == kNumLockedTemplateSymbols) {
  288. state_ = DEMODULATOR_STATE_OK;
  289. }
  290. decision_counter_ = symbol_duration_ - 1;
  291. }
  292. correlation_history_[1] = correlation_history_[0];
  293. correlation_history_[0] = correlation;
  294. }
  295. }
  296. }
  297. } // namespace stm_audio_bootloader