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.

359 lines
9.5KB

  1. // Copyright 2014 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 <stm32f10x_conf.h>
  25. #include <string.h>
  26. #include "stmlib/utils/dsp.h"
  27. #include "stmlib/utils/ring_buffer.h"
  28. #include "stmlib/system/bootloader_utils.h"
  29. #include "stmlib/system/flash_programming.h"
  30. #include "stmlib/system/system_clock.h"
  31. #include "stm_audio_bootloader/qpsk/packet_decoder.h"
  32. #include "stm_audio_bootloader/qpsk/demodulator.h"
  33. #include "streams/drivers/adc.h"
  34. #include "streams/drivers/switches.h"
  35. #include "streams/drivers/leds.h"
  36. #include "streams/drivers/system.h"
  37. using namespace streams;
  38. using namespace stmlib;
  39. using namespace stm_audio_bootloader;
  40. const double kSampleRate = 48000.0;
  41. const double kModulationRate = 6000.0;
  42. const double kBitRate = 12000.0;
  43. const uint32_t kStartAddress = 0x08004000;
  44. Adc adc;
  45. System sys;
  46. Leds leds;
  47. Switches switches;
  48. PacketDecoder decoder;
  49. Demodulator demodulator;
  50. const int16_t wav_db[] = {
  51. -32768, -32768, -24576, -19783,
  52. -16384, -13746, -11591, -9770,
  53. -8192, -6799, -5554, -4428,
  54. -3399, -2453, -1578, -762,
  55. 0, 716, 1392, 2031,
  56. 2637, 3213, 3763, 4289,
  57. 4792, 5274, 5738, 6184,
  58. 6613, 7028, 7429, 7816,
  59. 8192, 8555, 8908, 9251,
  60. 9584, 9907, 10223, 10530,
  61. 10829, 11121, 11405, 11683,
  62. 11955, 12221, 12481, 12735,
  63. 12984, 13227, 13466, 13700,
  64. 13930, 14155, 14376, 14592,
  65. 14805, 15015, 15220, 15422,
  66. 15621, 15816, 16008, 16197,
  67. 16384, 16567, 16747, 16925,
  68. 17100, 17273, 17443, 17610,
  69. 17776, 17939, 18099, 18258,
  70. 18415, 18569, 18722, 18872,
  71. 19021, 19168, 19313, 19456,
  72. 19597, 19737, 19875, 20012,
  73. 20147, 20281, 20413, 20543,
  74. 20673, 20800, 20927, 21052,
  75. 21176, 21298, 21419, 21539,
  76. 21658, 21776, 21892, 22007,
  77. 22122, 22235, 22347, 22458,
  78. 22568, 22676, 22784, 22891,
  79. 22997, 23102, 23207, 23310,
  80. 23412, 23514, 23614, 23714,
  81. 23813, 23911, 24008, 24105,
  82. 24200, 24295, 24389, 24483,
  83. 24576, 24667, 24759, 24849,
  84. 24939, 25028, 25117, 25205,
  85. 25292, 25379, 25465, 25550,
  86. 25635, 25719, 25802, 25885,
  87. 25968, 26049, 26131, 26211,
  88. 26291, 26371, 26450, 26529,
  89. 26607, 26684, 26761, 26838,
  90. 26914, 26989, 27064, 27139,
  91. 27213, 27286, 27360, 27432,
  92. 27505, 27576, 27648, 27719,
  93. 27789, 27860, 27929, 27999,
  94. 28067, 28136, 28204, 28272,
  95. 28339, 28406, 28473, 28539,
  96. 28605, 28670, 28735, 28800,
  97. 28865, 28929, 28992, 29056,
  98. 29119, 29181, 29244, 29306,
  99. 29368, 29429, 29490, 29551,
  100. 29611, 29671, 29731, 29791,
  101. 29850, 29909, 29968, 30026,
  102. 30084, 30142, 30199, 30257,
  103. 30314, 30370, 30427, 30483,
  104. 30539, 30594, 30650, 30705,
  105. 30760, 30814, 30868, 30923,
  106. 30976, 31030, 31083, 31136,
  107. 31189, 31242, 31294, 31347,
  108. 31399, 31450, 31502, 31553,
  109. 31604, 31655, 31706, 31756,
  110. 31806, 31856, 31906, 31955,
  111. 32005, 32054, 32103, 32152,
  112. 32200, 32248, 32297, 32345,
  113. 32392, 32440, 32487, 32534,
  114. 32581, 32628, 32675, 32721,
  115. 32721,
  116. };
  117. extern "C" {
  118. void HardFault_Handler(void) { while (1); }
  119. void MemManage_Handler(void) { while (1); }
  120. void BusFault_Handler(void) { while (1); }
  121. void UsageFault_Handler(void) { while (1); }
  122. void NMI_Handler(void) { }
  123. void SVC_Handler(void) { }
  124. void DebugMon_Handler(void) { }
  125. void PendSV_Handler(void) { }
  126. }
  127. extern "C" {
  128. enum UiState {
  129. UI_STATE_WAITING,
  130. UI_STATE_RECEIVING,
  131. UI_STATE_ERROR,
  132. UI_STATE_PACKET_OK
  133. };
  134. volatile bool switch_released = false;
  135. volatile UiState ui_state;
  136. int32_t peak = 0;
  137. int32_t gain = 0;
  138. inline void UpdateLeds() {
  139. leds.Clear();
  140. // Show vu-meter on right side.
  141. int32_t rectified_sample = adc.cv(0) - 32768;
  142. rectified_sample = rectified_sample * gain >> 4;
  143. if (rectified_sample < 0) {
  144. rectified_sample = -rectified_sample;
  145. }
  146. if (rectified_sample > peak) {
  147. peak = rectified_sample;
  148. } else {
  149. peak += (rectified_sample - peak) * 130 >> 15;
  150. }
  151. leds.PaintPositiveBar(1, wav_db[peak >> 7] + 8192);
  152. // Show status info on left side (or whole display in case of error).
  153. switch (ui_state) {
  154. case UI_STATE_WAITING:
  155. {
  156. bool on = system_clock.milliseconds() & 128;
  157. if (on) {
  158. for (uint8_t i = 0; i < 4; ++i) {
  159. leds.set(i, 255, 255);
  160. }
  161. }
  162. }
  163. break;
  164. case UI_STATE_RECEIVING:
  165. {
  166. uint8_t stage = (system_clock.milliseconds() >> 7) & 3;
  167. leds.set(stage, 0, 255);
  168. }
  169. break;
  170. case UI_STATE_ERROR:
  171. {
  172. bool on = system_clock.milliseconds() & 256;
  173. for (uint8_t i = 0; i < 4; ++i) {
  174. leds.set(i, on ? 255 : 0, 0);
  175. }
  176. }
  177. break;
  178. case UI_STATE_PACKET_OK:
  179. {
  180. for (uint8_t i = 0; i < 4; ++i) {
  181. leds.set(i, 0, 255);
  182. }
  183. }
  184. break;
  185. }
  186. leds.Write();
  187. }
  188. void SysTick_Handler() {
  189. static uint8_t divider = 0;
  190. // SysTick is at 4kHz to get a fast bargraph refresh.
  191. ++divider;
  192. if ((divider & 3) == 0) {
  193. system_clock.Tick();
  194. system_clock.Tick(); // Tick global ms counter.
  195. switches.Debounce();
  196. if (switches.released(0)) {
  197. switch_released = true;
  198. }
  199. adc.ScanPots();
  200. gain = adc.pot(0) >> 11;
  201. UpdateLeds();
  202. }
  203. }
  204. uint16_t discard_samples = 8000;
  205. void TIM2_IRQHandler(void) {
  206. if (TIM_GetITStatus(TIM2, TIM_IT_Update) == RESET) {
  207. return;
  208. }
  209. TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
  210. if (!discard_samples) {
  211. int32_t sample = adc.cv(0);
  212. sample -= 32768;
  213. sample = sample * gain >> 4;
  214. sample = (sample >> 4) + 2048;
  215. if (sample < 0) {
  216. sample = 0;
  217. } else if (sample > 4095) {
  218. sample = 4095;
  219. }
  220. demodulator.PushSample(sample);
  221. } else {
  222. --discard_samples;
  223. }
  224. }
  225. }
  226. static uint32_t current_address;
  227. static uint16_t packet_index;
  228. void ProgramPage(const uint8_t* data, size_t size) {
  229. FLASH_Unlock();
  230. FLASH_ErasePage(current_address);
  231. const uint32_t* words = static_cast<const uint32_t*>(
  232. static_cast<const void*>(data));
  233. for (size_t written = 0; written < size; written += 4) {
  234. FLASH_ProgramWord(current_address, *words++);
  235. current_address += 4;
  236. }
  237. }
  238. void Init() {
  239. sys.Init(false);
  240. system_clock.Init();
  241. adc.Init(true, NULL);
  242. switches.Init();
  243. leds.Init();
  244. sys.StartTimers();
  245. adc.Start();
  246. TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
  247. }
  248. void InitializeReception() {
  249. decoder.Init();
  250. demodulator.Init(
  251. kModulationRate / kSampleRate * 4294967296.0,
  252. kSampleRate / kModulationRate,
  253. 2.0 * kSampleRate / kBitRate);
  254. demodulator.SyncCarrier(true);
  255. decoder.Reset();
  256. current_address = kStartAddress;
  257. packet_index = 0;
  258. ui_state = UI_STATE_WAITING;
  259. }
  260. uint8_t rx_buffer[PAGE_SIZE];
  261. const uint16_t kPacketsPerPage = PAGE_SIZE / kPacketSize;
  262. int main(void) {
  263. Init();
  264. InitializeReception();
  265. bool exit_updater = !switches.pressed_immediate(0);
  266. while (!exit_updater) {
  267. bool error = false;
  268. if (demodulator.state() == DEMODULATOR_STATE_OVERFLOW) {
  269. error = true;
  270. } else {
  271. demodulator.ProcessAtLeast(32);
  272. }
  273. while (demodulator.available() && !error && !exit_updater) {
  274. uint8_t symbol = demodulator.NextSymbol();
  275. PacketDecoderState state = decoder.ProcessSymbol(symbol);
  276. switch (state) {
  277. case PACKET_DECODER_STATE_OK:
  278. {
  279. ui_state = UI_STATE_RECEIVING;
  280. memcpy(
  281. rx_buffer + (packet_index % kPacketsPerPage) * kPacketSize,
  282. decoder.packet_data(),
  283. kPacketSize);
  284. ++packet_index;
  285. if ((packet_index % kPacketsPerPage) == 0) {
  286. ui_state = UI_STATE_PACKET_OK;
  287. ProgramPage(rx_buffer, PAGE_SIZE);
  288. decoder.Reset();
  289. demodulator.SyncCarrier(false);
  290. ui_state = UI_STATE_RECEIVING;
  291. } else {
  292. decoder.Reset();
  293. demodulator.SyncDecision();
  294. }
  295. }
  296. break;
  297. case PACKET_DECODER_STATE_ERROR_SYNC:
  298. case PACKET_DECODER_STATE_ERROR_CRC:
  299. error = true;
  300. break;
  301. case PACKET_DECODER_STATE_END_OF_TRANSMISSION:
  302. exit_updater = true;
  303. break;
  304. default:
  305. break;
  306. }
  307. }
  308. if (error) {
  309. ui_state = UI_STATE_ERROR;
  310. switch_released = false;
  311. while (!switch_released); // Polled in ISR
  312. InitializeReception();
  313. }
  314. }
  315. adc.DeInit();
  316. Uninitialize();
  317. JumpTo(kStartAddress);
  318. while (1) { }
  319. }