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.

265 lines
7.0KB

  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 <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 "frames/drivers/adc.h"
  34. #include "frames/drivers/switches.h"
  35. #include "frames/drivers/channel_leds.h"
  36. #include "frames/drivers/rgb_led.h"
  37. #include "frames/drivers/system.h"
  38. using namespace frames;
  39. using namespace stmlib;
  40. using namespace stm_audio_bootloader;
  41. const double kSampleRate = 48000.0;
  42. const double kModulationRate = 6000.0;
  43. const double kBitRate = 12000.0;
  44. const uint32_t kStartAddress = 0x08004000;
  45. Adc adc;
  46. System sys;
  47. ChannelLeds leds;
  48. RgbLed rgb;
  49. Switches switches;
  50. PacketDecoder decoder;
  51. Demodulator demodulator;
  52. extern "C" {
  53. void HardFault_Handler(void) { while (1); }
  54. void MemManage_Handler(void) { while (1); }
  55. void BusFault_Handler(void) { while (1); }
  56. void UsageFault_Handler(void) { while (1); }
  57. void NMI_Handler(void) { }
  58. void SVC_Handler(void) { }
  59. void DebugMon_Handler(void) { }
  60. void PendSV_Handler(void) { }
  61. }
  62. extern "C" {
  63. enum UiState {
  64. UI_STATE_WAITING,
  65. UI_STATE_RECEIVING,
  66. UI_STATE_ERROR,
  67. UI_STATE_PACKET_OK
  68. };
  69. volatile bool switch_released = false;
  70. volatile UiState ui_state;
  71. inline void UpdateLeds() {
  72. switch (ui_state) {
  73. case UI_STATE_WAITING:
  74. {
  75. bool on = system_clock.milliseconds() & 256;
  76. rgb.set_color(255, 128, 0);
  77. leds.set_channel(0, on ? 255 : 0);
  78. leds.set_channel(1, on ? 255 : 0);
  79. leds.set_channel(2, on ? 255 : 0);
  80. leds.set_channel(3, on ? 255 : 0);
  81. }
  82. break;
  83. case UI_STATE_RECEIVING:
  84. {
  85. uint8_t stage = (system_clock.milliseconds() >> 7) & 3;
  86. rgb.set_color(0, 255, 0);
  87. leds.set_channel(0, stage == 0 ? 255 : 0);
  88. leds.set_channel(1, stage == 1 ? 255 : 0);
  89. leds.set_channel(2, stage == 2 ? 255 : 0);
  90. leds.set_channel(3, stage == 3 ? 255 : 0);
  91. }
  92. break;
  93. case UI_STATE_ERROR:
  94. {
  95. bool on = system_clock.milliseconds() & 128;
  96. rgb.set_color(255, 0, 0);
  97. leds.set_channel(0, on ? 255 : 0);
  98. leds.set_channel(1, on ? 255 : 0);
  99. leds.set_channel(2, on ? 255 : 0);
  100. leds.set_channel(3, on ? 255 : 0);
  101. }
  102. break;
  103. case UI_STATE_PACKET_OK:
  104. {
  105. rgb.set_color(64, 255, 128);
  106. leds.set_channel(0, 255);
  107. leds.set_channel(1, 255);
  108. leds.set_channel(2, 255);
  109. leds.set_channel(3, 255);
  110. }
  111. break;
  112. }
  113. rgb.Write();
  114. leds.Write();
  115. }
  116. void SysTick_Handler() {
  117. system_clock.Tick(); // Tick global ms counter.
  118. switches.Debounce();
  119. if (switches.released(0)) {
  120. switch_released = true;
  121. }
  122. UpdateLeds();
  123. }
  124. uint16_t discard_samples = 8000;
  125. void TIM1_UP_IRQHandler(void) {
  126. if (TIM_GetITStatus(TIM1, TIM_IT_Update) == RESET) {
  127. return;
  128. }
  129. TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
  130. if (!discard_samples) {
  131. int16_t sample = adc.value(0) >> 4;
  132. demodulator.PushSample(sample);
  133. } else {
  134. --discard_samples;
  135. }
  136. }
  137. }
  138. static uint32_t current_address;
  139. static uint16_t packet_index;
  140. void ProgramPage(const uint8_t* data, size_t size) {
  141. FLASH_Unlock();
  142. FLASH_ErasePage(current_address);
  143. const uint32_t* words = static_cast<const uint32_t*>(
  144. static_cast<const void*>(data));
  145. for (size_t written = 0; written < size; written += 4) {
  146. FLASH_ProgramWord(current_address, *words++);
  147. current_address += 4;
  148. }
  149. }
  150. void Init() {
  151. sys.Init(F_CPU / kSampleRate - 1, false);
  152. system_clock.Init();
  153. adc.Init(true);
  154. switches.Init();
  155. leds.Init();
  156. rgb.Init();
  157. sys.StartTimers();
  158. }
  159. void InitializeReception() {
  160. decoder.Init();
  161. demodulator.Init(
  162. kModulationRate / kSampleRate * 4294967296.0,
  163. kSampleRate / kModulationRate,
  164. 2.0 * kSampleRate / kBitRate);
  165. demodulator.SyncCarrier(true);
  166. decoder.Reset();
  167. current_address = kStartAddress;
  168. packet_index = 0;
  169. ui_state = UI_STATE_WAITING;
  170. }
  171. uint8_t rx_buffer[PAGE_SIZE];
  172. const uint16_t kPacketsPerPage = PAGE_SIZE / kPacketSize;
  173. int main(void) {
  174. Init();
  175. InitializeReception();
  176. bool exit_updater = !switches.pressed_immediate(0);
  177. while (!exit_updater) {
  178. bool error = false;
  179. if (demodulator.state() == DEMODULATOR_STATE_OVERFLOW) {
  180. error = true;
  181. } else {
  182. demodulator.ProcessAtLeast(32);
  183. }
  184. while (demodulator.available() && !error && !exit_updater) {
  185. uint8_t symbol = demodulator.NextSymbol();
  186. PacketDecoderState state = decoder.ProcessSymbol(symbol);
  187. switch (state) {
  188. case PACKET_DECODER_STATE_OK:
  189. {
  190. ui_state = UI_STATE_RECEIVING;
  191. memcpy(
  192. rx_buffer + (packet_index % kPacketsPerPage) * kPacketSize,
  193. decoder.packet_data(),
  194. kPacketSize);
  195. ++packet_index;
  196. if ((packet_index % kPacketsPerPage) == 0) {
  197. ui_state = UI_STATE_PACKET_OK;
  198. ProgramPage(rx_buffer, PAGE_SIZE);
  199. decoder.Reset();
  200. demodulator.SyncCarrier(false);
  201. ui_state = UI_STATE_RECEIVING;
  202. } else {
  203. decoder.Reset();
  204. demodulator.SyncDecision();
  205. }
  206. }
  207. break;
  208. case PACKET_DECODER_STATE_ERROR_SYNC:
  209. case PACKET_DECODER_STATE_ERROR_CRC:
  210. error = true;
  211. break;
  212. case PACKET_DECODER_STATE_END_OF_TRANSMISSION:
  213. exit_updater = true;
  214. break;
  215. default:
  216. break;
  217. }
  218. }
  219. if (error) {
  220. ui_state = UI_STATE_ERROR;
  221. switch_released = false;
  222. while (!switch_released); // Polled in ISR
  223. InitializeReception();
  224. }
  225. }
  226. adc.DeInit();
  227. Uninitialize();
  228. JumpTo(kStartAddress);
  229. while (1) { }
  230. }