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.

258 lines
6.7KB

  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 "tides/drivers/adc.h"
  34. #include "tides/drivers/dac.h"
  35. #include "tides/drivers/switches.h"
  36. #include "tides/drivers/leds.h"
  37. #include "tides/drivers/system.h"
  38. using namespace tides;
  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. Dac dac;
  47. System sys;
  48. Leds leds;
  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() & 128;
  76. leds.set_mode(on, on);
  77. leds.set_value(on ? 65535 : 0);
  78. leds.set_rate(on ? 65535 : 0);
  79. }
  80. break;
  81. case UI_STATE_RECEIVING:
  82. {
  83. uint8_t stage = (system_clock.milliseconds() >> 7) & 3;
  84. leds.set_mode(!stage);
  85. leds.set_value(stage & 1 ? 65535 : 0);
  86. leds.set_rate(stage & 2 ? 65535 : 0);
  87. }
  88. break;
  89. case UI_STATE_ERROR:
  90. {
  91. bool on = system_clock.milliseconds() & 256;
  92. leds.set_mode(on, false);
  93. leds.set_value(on ? 65535 : 0, 0);
  94. leds.set_rate(on ? 65535 : 0, 0);
  95. }
  96. break;
  97. case UI_STATE_PACKET_OK:
  98. {
  99. leds.set_mode(false, true);
  100. leds.set_value(0, 65535);
  101. leds.set_rate(0, 65535);
  102. }
  103. break;
  104. }
  105. leds.Write();
  106. }
  107. void SysTick_Handler() {
  108. system_clock.Tick(); // Tick global ms counter.
  109. switches.Debounce();
  110. if (switches.released(0)) {
  111. switch_released = true;
  112. }
  113. UpdateLeds();
  114. }
  115. uint16_t discard_samples = 8000;
  116. void TIM1_UP_IRQHandler(void) {
  117. if (TIM_GetITStatus(TIM1, TIM_IT_Update) == RESET) {
  118. return;
  119. }
  120. TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
  121. dac.Update(1);
  122. if (!discard_samples) {
  123. int16_t sample = adc.value(0) >> 4;
  124. demodulator.PushSample(sample);
  125. dac.Write(0, adc.value(0));
  126. } else {
  127. --discard_samples;
  128. }
  129. }
  130. }
  131. static uint32_t current_address;
  132. static uint16_t packet_index;
  133. void ProgramPage(const uint8_t* data, size_t size) {
  134. FLASH_Unlock();
  135. FLASH_ErasePage(current_address);
  136. const uint32_t* words = static_cast<const uint32_t*>(
  137. static_cast<const void*>(data));
  138. for (size_t written = 0; written < size; written += 4) {
  139. FLASH_ProgramWord(current_address, *words++);
  140. current_address += 4;
  141. }
  142. }
  143. void Init() {
  144. sys.Init(F_CPU / kSampleRate - 1, false);
  145. system_clock.Init();
  146. adc.Init(true);
  147. dac.Init();
  148. switches.Init();
  149. leds.Init();
  150. sys.StartTimers();
  151. }
  152. void InitializeReception() {
  153. decoder.Init();
  154. demodulator.Init(
  155. kModulationRate / kSampleRate * 4294967296.0,
  156. kSampleRate / kModulationRate,
  157. 2.0 * kSampleRate / kBitRate);
  158. demodulator.SyncCarrier(true);
  159. decoder.Reset();
  160. current_address = kStartAddress;
  161. packet_index = 0;
  162. ui_state = UI_STATE_WAITING;
  163. }
  164. uint8_t rx_buffer[PAGE_SIZE];
  165. const uint16_t kPacketsPerPage = PAGE_SIZE / kPacketSize;
  166. int main(void) {
  167. Init();
  168. InitializeReception();
  169. bool exit_updater = !switches.pressed_immediate(0);
  170. while (!exit_updater) {
  171. bool error = false;
  172. if (demodulator.state() == DEMODULATOR_STATE_OVERFLOW) {
  173. error = true;
  174. } else {
  175. demodulator.ProcessAtLeast(32);
  176. }
  177. while (demodulator.available() && !error && !exit_updater) {
  178. uint8_t symbol = demodulator.NextSymbol();
  179. PacketDecoderState state = decoder.ProcessSymbol(symbol);
  180. switch (state) {
  181. case PACKET_DECODER_STATE_OK:
  182. {
  183. ui_state = UI_STATE_RECEIVING;
  184. memcpy(
  185. rx_buffer + (packet_index % kPacketsPerPage) * kPacketSize,
  186. decoder.packet_data(),
  187. kPacketSize);
  188. ++packet_index;
  189. if ((packet_index % kPacketsPerPage) == 0) {
  190. ui_state = UI_STATE_PACKET_OK;
  191. ProgramPage(rx_buffer, PAGE_SIZE);
  192. decoder.Reset();
  193. demodulator.SyncCarrier(false);
  194. ui_state = UI_STATE_RECEIVING;
  195. } else {
  196. decoder.Reset();
  197. demodulator.SyncDecision();
  198. }
  199. }
  200. break;
  201. case PACKET_DECODER_STATE_ERROR_SYNC:
  202. case PACKET_DECODER_STATE_ERROR_CRC:
  203. error = true;
  204. break;
  205. case PACKET_DECODER_STATE_END_OF_TRANSMISSION:
  206. exit_updater = true;
  207. break;
  208. default:
  209. break;
  210. }
  211. }
  212. if (error) {
  213. ui_state = UI_STATE_ERROR;
  214. switch_released = false;
  215. while (!switch_released); // Polled in ISR
  216. InitializeReception();
  217. }
  218. }
  219. adc.DeInit();
  220. Uninitialize();
  221. JumpTo(kStartAddress);
  222. while (1) { }
  223. }