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.

318 lines
8.4KB

  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 "stmlib/system/bootloader_utils.h"
  25. #include "stmlib/system/system_clock.h"
  26. #include "marbles/drivers/adc.h"
  27. #include "marbles/drivers/dac.h"
  28. #include "marbles/drivers/leds.h"
  29. #include "marbles/drivers/switches.h"
  30. #include "marbles/drivers/system.h"
  31. #include "stm_audio_bootloader/qpsk/packet_decoder.h"
  32. #include "stm_audio_bootloader/qpsk/demodulator.h"
  33. #include <cstring>
  34. using namespace marbles;
  35. using namespace stmlib;
  36. using namespace stm_audio_bootloader;
  37. const double kSampleRate = 48000.0;
  38. const double kModulationRate = 6000.0;
  39. const double kBitRate = 12000.0;
  40. const uint32_t kStartAddress = 0x08008000;
  41. Adc adc;
  42. Dac dac;
  43. Leds leds;
  44. Switches switches;
  45. PacketDecoder decoder;
  46. Demodulator demodulator;
  47. int __errno;
  48. void UpdateLeds();
  49. volatile bool switch_released = false;
  50. // Default interrupt handlers.
  51. extern "C" {
  52. void NMI_Handler() { }
  53. void HardFault_Handler() { while (1); }
  54. void MemManage_Handler() { while (1); }
  55. void BusFault_Handler() { while (1); }
  56. void UsageFault_Handler() { while (1); }
  57. void SVC_Handler() { }
  58. void DebugMon_Handler() { }
  59. void PendSV_Handler() { }
  60. void SysTick_Handler() {
  61. IWDG_ReloadCounter();
  62. system_clock.Tick();
  63. switches.Debounce();
  64. if (switches.released(SWITCH_T_DEJA_VU)) {
  65. switch_released = true;
  66. }
  67. UpdateLeds();
  68. }
  69. }
  70. enum UiState {
  71. UI_STATE_WAITING,
  72. UI_STATE_RECEIVING,
  73. UI_STATE_ERROR,
  74. UI_STATE_WRITING
  75. };
  76. volatile UiState ui_state;
  77. volatile int32_t peak;
  78. void UpdateLeds() {
  79. leds.Clear();
  80. switch (ui_state) {
  81. case UI_STATE_WAITING:
  82. leds.set(
  83. LED_T_DEJA_VU,
  84. system_clock.milliseconds() & 128 ? LED_COLOR_GREEN : 0);
  85. leds.set(
  86. LED_X_DEJA_VU,
  87. system_clock.milliseconds() & 128 ? 0 : LED_COLOR_GREEN);
  88. break;
  89. case UI_STATE_RECEIVING:
  90. leds.set(
  91. LED_T_DEJA_VU,
  92. system_clock.milliseconds() & 32 ? LED_COLOR_GREEN : 0);
  93. leds.set(
  94. LED_X_DEJA_VU,
  95. system_clock.milliseconds() & 32 ? 0 : LED_COLOR_GREEN);
  96. break;
  97. case UI_STATE_ERROR:
  98. {
  99. bool on = system_clock.milliseconds() & 256;
  100. for (int i = 0; i < LED_LAST; ++i) {
  101. leds.set(Led(i), on ? LED_COLOR_RED : 0);
  102. }
  103. }
  104. break;
  105. case UI_STATE_WRITING:
  106. {
  107. for (int i = 0; i < LED_LAST; ++i) {
  108. leds.set(Led(i), LED_COLOR_GREEN);
  109. }
  110. }
  111. break;
  112. }
  113. if (ui_state != UI_STATE_WRITING) {
  114. uint8_t pwm = system_clock.milliseconds() & 15;
  115. if (peak < 8192) {
  116. leds.set(
  117. LED_T_RANGE,
  118. (peak >> 9) > pwm ? LED_COLOR_GREEN : 0);
  119. } else if (peak < 16384) {
  120. leds.set(
  121. LED_T_RANGE,
  122. ((peak - 8192) >> 9) >= pwm ? LED_COLOR_YELLOW : LED_COLOR_GREEN);
  123. } else if (peak < 16384 + 8192) {
  124. leds.set(
  125. LED_T_RANGE,
  126. ((peak - 16384 - 8192) >> 9) >= pwm ?
  127. LED_COLOR_RED : LED_COLOR_YELLOW);
  128. } else {
  129. leds.set(LED_T_RANGE, LED_COLOR_RED);
  130. }
  131. }
  132. leds.Write();
  133. }
  134. int32_t dc_offset = 0;
  135. int32_t gain_pot = 16;
  136. size_t discard_samples = 8000;
  137. IOBuffer::Block block;
  138. IOBuffer::Slice FillBuffer(size_t size) {
  139. adc.Convert();
  140. if (!discard_samples) {
  141. // Scan gain pot.
  142. gain_pot = (adc.value(ADC_GROUP_POT) + 4095 * gain_pot) >> 12;
  143. int32_t gain = ((gain_pot >> 1) * gain_pot >> 21) + 128;
  144. // Extract sample. Note: there's a DC offset :/
  145. int32_t sample = 32768 - static_cast<int32_t>(adc.value(ADC_GROUP_CV));
  146. dc_offset += (sample - (dc_offset >> 15));
  147. sample = (sample - (dc_offset >> 15)) * gain >> 8; // 0.5x to 4x
  148. CONSTRAIN(sample, -32768, 32767);
  149. // Update peak-meter
  150. int32_t rect = sample > 0 ? sample : -sample;
  151. peak = rect > peak ? rect : (rect + 32767 * peak) >> 15;
  152. // Write to DAC for monitoring
  153. block.cv_output[0][0] = 32767 - sample;
  154. block.cv_output[1][0] = 32767 - sample;
  155. block.cv_output[2][0] = 32767 - sample;
  156. block.cv_output[3][0] = 32767 - sample;
  157. demodulator.PushSample(2048 + (sample >> 4));
  158. } else {
  159. --discard_samples;
  160. }
  161. IOBuffer::Slice s;
  162. s.block = &block;
  163. s.frame_index = 0;
  164. return s;
  165. }
  166. static size_t current_address;
  167. static uint16_t packet_index;
  168. static uint32_t kSectorBaseAddress[] = {
  169. 0x08000000,
  170. 0x08004000,
  171. 0x08008000,
  172. 0x0800C000,
  173. 0x08010000,
  174. 0x08020000,
  175. 0x08040000,
  176. 0x08060000,
  177. 0x08080000,
  178. 0x080A0000,
  179. 0x080C0000,
  180. 0x080E0000
  181. };
  182. const uint32_t kBlockSize = 16384;
  183. const uint16_t kPacketsPerBlock = ::kBlockSize / kPacketSize;
  184. uint8_t rx_buffer[::kBlockSize];
  185. void ProgramPage(const uint8_t* data, size_t size) {
  186. FLASH_Unlock();
  187. FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
  188. FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
  189. for (int32_t i = 0; i < 12; ++i) {
  190. if (current_address == kSectorBaseAddress[i]) {
  191. FLASH_EraseSector(i * 8, VoltageRange_3);
  192. }
  193. }
  194. const uint32_t* words = static_cast<const uint32_t*>(
  195. static_cast<const void*>(data));
  196. for (size_t written = 0; written < size; written += 4) {
  197. FLASH_ProgramWord(current_address, *words++);
  198. current_address += 4;
  199. }
  200. }
  201. void InitializeReception() {
  202. decoder.Init(20000);
  203. demodulator.Init(
  204. kModulationRate / kSampleRate * 4294967296.0,
  205. kSampleRate / kModulationRate,
  206. 2.0 * kSampleRate / kBitRate);
  207. demodulator.SyncCarrier(true);
  208. decoder.Reset();
  209. current_address = kStartAddress;
  210. packet_index = 0;
  211. ui_state = UI_STATE_WAITING;
  212. }
  213. void Init() {
  214. System sys;
  215. switches.Init();
  216. sys.Init(false);
  217. system_clock.Init();
  218. adc.Init(true);
  219. dac.Init(48000, 1);
  220. leds.Init();
  221. sys.StartTimers();
  222. dac.Start(&FillBuffer);
  223. }
  224. int main(void) {
  225. Init();
  226. InitializeReception();
  227. bool exit_updater = !switches.pressed_immediate(SWITCH_T_DEJA_VU);
  228. while (!exit_updater) {
  229. bool error = false;
  230. if (demodulator.state() == DEMODULATOR_STATE_OVERFLOW) {
  231. error = true;
  232. } else {
  233. demodulator.ProcessAtLeast(32);
  234. }
  235. while (demodulator.available() && !error && !exit_updater) {
  236. uint8_t symbol = demodulator.NextSymbol();
  237. PacketDecoderState state = decoder.ProcessSymbol(symbol);
  238. switch (state) {
  239. case PACKET_DECODER_STATE_OK:
  240. {
  241. ui_state = UI_STATE_RECEIVING;
  242. memcpy(
  243. rx_buffer + (packet_index % kPacketsPerBlock) * kPacketSize,
  244. decoder.packet_data(),
  245. kPacketSize);
  246. ++packet_index;
  247. if ((packet_index % kPacketsPerBlock) == 0) {
  248. ui_state = UI_STATE_WRITING;
  249. ProgramPage(rx_buffer, ::kBlockSize);
  250. decoder.Reset();
  251. demodulator.SyncCarrier(false);
  252. } else {
  253. decoder.Reset();
  254. demodulator.SyncDecision();
  255. }
  256. }
  257. break;
  258. case PACKET_DECODER_STATE_ERROR_SYNC:
  259. case PACKET_DECODER_STATE_ERROR_CRC:
  260. error = true;
  261. break;
  262. case PACKET_DECODER_STATE_END_OF_TRANSMISSION:
  263. exit_updater = true;
  264. break;
  265. default:
  266. break;
  267. }
  268. }
  269. if (error) {
  270. ui_state = UI_STATE_ERROR;
  271. switch_released = false;
  272. while (!switch_released); // Polled in ISR
  273. InitializeReception();
  274. }
  275. }
  276. adc.DeInit();
  277. Uninitialize();
  278. JumpTo(kStartAddress);
  279. while (1) { }
  280. }