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.

232 lines
6.6KB

  1. // Copyright 2012 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 "braids/drivers/adc.h"
  34. #include "braids/drivers/display.h"
  35. #include "braids/drivers/encoder.h"
  36. #include "braids/drivers/system.h"
  37. using namespace braids;
  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. Display display;
  47. Encoder encoder;
  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. volatile uint8_t packet_inspector_byte = 0;
  62. volatile bool encoder_released = false;
  63. void SysTick_Handler() {
  64. system_clock.Tick(); // Tick global ms counter.
  65. encoder.Debounce();
  66. encoder_released = encoder_released | encoder.released();
  67. packet_inspector_byte += encoder.increment();
  68. uint32_t ms_clock = system_clock.milliseconds();
  69. if ((ms_clock & 0x3f) == 0 && display.mutable_buffer()[0] >= '\x98') {
  70. display.mutable_buffer()[0] = '\x98' + ((ms_clock >> 6) & 7);
  71. }
  72. display.Refresh();
  73. }
  74. uint16_t discard_samples = 8000;
  75. void TIM1_UP_IRQHandler(void) {
  76. if (TIM_GetITStatus(TIM1, TIM_IT_Update) == RESET) {
  77. return;
  78. }
  79. TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
  80. if (adc.PipelinedRead(3)) {
  81. if (!discard_samples) {
  82. int16_t sample = adc.channel(3);
  83. demodulator.PushSample(sample);
  84. } else {
  85. --discard_samples;
  86. }
  87. }
  88. }
  89. }
  90. static uint32_t current_address;
  91. static uint16_t packet_index;
  92. void ProgramPage(const uint8_t* data, size_t size) {
  93. FLASH_Unlock();
  94. FLASH_ErasePage(current_address);
  95. const uint32_t* words = static_cast<const uint32_t*>(
  96. static_cast<const void*>(data));
  97. for (size_t written = 0; written < size; written += 4) {
  98. FLASH_ProgramWord(current_address, *words++);
  99. current_address += 4;
  100. }
  101. }
  102. void PrintPageNumber(uint16_t page_number, bool error) {
  103. char string[5];
  104. string[0] = '\x98';
  105. string[1] = error ? 'X' : '0' + page_number / 100;
  106. string[2] = '0' + (page_number / 10) % 10;
  107. string[3] = '0' + page_number % 10;
  108. string[4] = '\0';
  109. display.Print(string);
  110. }
  111. const char kHexChar[] = "0123456789ABCDEF";
  112. void PacketInspector() {
  113. while (1) {
  114. char string[5];
  115. string[0] = kHexChar[packet_inspector_byte >> 4];
  116. string[1] = kHexChar[packet_inspector_byte & 0xf];
  117. string[2] = kHexChar[decoder.packet_data()[packet_inspector_byte] >> 4];
  118. string[3] = kHexChar[decoder.packet_data()[packet_inspector_byte] & 0xf];
  119. string[4] = '\0';
  120. display.Print(string);
  121. }
  122. }
  123. void Init() {
  124. sys.Init(F_CPU / (3 * kSampleRate) - 1, false);
  125. system_clock.Init();
  126. adc.Init(3 * kSampleRate > 96000);
  127. encoder.Init();
  128. display.Init();
  129. sys.StartTimers();
  130. }
  131. void InitializeReception() {
  132. decoder.Init();
  133. demodulator.Init(
  134. kModulationRate / kSampleRate * 4294967296.0,
  135. kSampleRate / kModulationRate,
  136. 2.0 * kSampleRate / kBitRate);
  137. demodulator.SyncCarrier(true);
  138. decoder.Reset();
  139. current_address = kStartAddress;
  140. packet_index = 0;
  141. display.Print("\x98RDY");
  142. }
  143. uint8_t rx_buffer[PAGE_SIZE];
  144. const uint16_t kPacketsPerPage = PAGE_SIZE / kPacketSize;
  145. const char* kErrorStrings[2] = { "@SYN", "@CRC", };
  146. int main(void) {
  147. Init();
  148. InitializeReception();
  149. bool exit_updater = !encoder.pressed_immediate();
  150. while (!exit_updater) {
  151. bool error = false;
  152. if (demodulator.state() == DEMODULATOR_STATE_OVERFLOW) {
  153. display.Print("@OVF");
  154. error = true;
  155. } else {
  156. demodulator.ProcessAtLeast(32);
  157. }
  158. while (demodulator.available() && !error && !exit_updater) {
  159. uint8_t symbol = demodulator.NextSymbol();
  160. PacketDecoderState state = decoder.ProcessSymbol(symbol);
  161. switch (state) {
  162. case PACKET_DECODER_STATE_OK:
  163. {
  164. memcpy(
  165. rx_buffer + (packet_index % kPacketsPerPage) * kPacketSize,
  166. decoder.packet_data(),
  167. kPacketSize);
  168. ++packet_index;
  169. if ((packet_index % kPacketsPerPage) == 0) {
  170. PrintPageNumber(packet_index / kPacketsPerPage, false);
  171. ProgramPage(rx_buffer, PAGE_SIZE);
  172. decoder.Reset();
  173. demodulator.SyncCarrier(false);
  174. } else {
  175. decoder.Reset();
  176. demodulator.SyncDecision();
  177. }
  178. }
  179. break;
  180. case PACKET_DECODER_STATE_ERROR_SYNC:
  181. case PACKET_DECODER_STATE_ERROR_CRC:
  182. display.Print(kErrorStrings[state - PACKET_DECODER_STATE_ERROR_SYNC]);
  183. error = true;
  184. break;
  185. case PACKET_DECODER_STATE_END_OF_TRANSMISSION:
  186. exit_updater = true;
  187. break;
  188. default:
  189. break;
  190. }
  191. }
  192. if (error) {
  193. encoder_released = false;
  194. while (!encoder_released); // Polled in ISR
  195. InitializeReception();
  196. }
  197. }
  198. Uninitialize();
  199. JumpTo(kStartAddress);
  200. while (1) { }
  201. }