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.

237 lines
6.1KB

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