Skip to content

Commit d7c61cf

Browse files
author
Olivier Gillet
committed
Added Yarns, Tides, Frames
1 parent ae1ca40 commit d7c61cf

File tree

139 files changed

+70167
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+70167
-0
lines changed

frames/__init__.py

Whitespace-only changes.

frames/bootloader/__init__.py

Whitespace-only changes.

frames/bootloader/bootloader.cc

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

frames/bootloader/makefile

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright 2013 Olivier Gillet.
2+
#
3+
# Author: Olivier Gillet ([email protected])
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+
25+
# System specifications
26+
F_CRYSTAL = 8000000L
27+
F_CPU = 72000000L
28+
SYSCLOCK = SYSCLK_FREQ_72MHz
29+
FAMILY = f10x
30+
DENSITY = md
31+
MEMORY_MODE = flash
32+
# USB = enabled
33+
34+
# Preferred upload command
35+
UPLOAD_COMMAND = upload_jtag
36+
37+
# Packages to build
38+
TARGET = frames_bootloader
39+
PACKAGES = frames/bootloader frames/drivers stmlib/utils stmlib/system \
40+
stm_audio_bootloader/qpsk
41+
42+
include stmlib/makefile.inc

0 commit comments

Comments
 (0)