Add initial center firmware
This commit is contained in:
parent
111b7a6bf3
commit
90038f4378
14 changed files with 1381 additions and 0 deletions
11
fw/.gitignore
vendored
Normal file
11
fw/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
*.elf
|
||||
*.o
|
||||
*.expand
|
||||
*.hex
|
||||
*.lst
|
||||
*.map
|
||||
*.bin
|
||||
sources.c
|
||||
sources.tar.xz
|
||||
sources.tar.xz.zip
|
||||
8b10b_test
|
||||
190
fw/8b10b.c
Normal file
190
fw/8b10b.c
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
|
||||
#include "8b10b.h"
|
||||
|
||||
static const struct entry_5b6b map_5b6b[32] = {
|
||||
{0b100111, 0b011000}, /* D.00 */
|
||||
{0b011101, 0b100010}, /* D.01 */
|
||||
{0b101101, 0b010010}, /* D.02 */
|
||||
{0b110001, 0b110001}, /* D.03 */
|
||||
{0b110101, 0b001010}, /* D.04 */
|
||||
{0b101001, 0b101001}, /* D.05 */
|
||||
{0b011001, 0b011001}, /* D.06 */
|
||||
{0b111000, 0b000111}, /* D.07 */
|
||||
{0b111001, 0b000110}, /* D.08 */
|
||||
{0b100101, 0b100101}, /* D.09 */
|
||||
{0b010101, 0b010101}, /* D.10 */
|
||||
{0b110100, 0b110100}, /* D.11 */
|
||||
{0b001101, 0b001101}, /* D.12 */
|
||||
{0b101100, 0b101100}, /* D.13 */
|
||||
{0b011100, 0b011100}, /* D.14 */
|
||||
{0b010111, 0b101000}, /* D.15 */
|
||||
{0b011011, 0b100100}, /* D.16 */
|
||||
{0b100011, 0b100011}, /* D.17 */
|
||||
{0b010011, 0b010011}, /* D.18 */
|
||||
{0b110010, 0b110010}, /* D.19 */
|
||||
{0b001011, 0b001011}, /* D.20 */
|
||||
{0b101010, 0b101010}, /* D.21 */
|
||||
{0b011010, 0b011010}, /* D.22 */
|
||||
{0b111010, 0b000101}, /* D.23 */
|
||||
{0b110011, 0b001100}, /* D.24 */
|
||||
{0b100110, 0b100110}, /* D.25 */
|
||||
{0b010110, 0b010110}, /* D.26 */
|
||||
{0b110110, 0b001001}, /* D.27 */
|
||||
{0b001110, 0b001110}, /* D.28 */
|
||||
{0b101110, 0b010001}, /* D.29 */
|
||||
{0b011110, 0b100001}, /* D.30 */
|
||||
{0b101011, 0b010100} /* D.31 */
|
||||
};
|
||||
|
||||
static const int8_t map_6b5b[64] = {
|
||||
[0b000101] = 23, /* rd = +1 */
|
||||
[0b000110] = 8, /* rd = +1 */
|
||||
[0b000111] = 7, /* rd = +1 */
|
||||
[0b001001] = 27, /* rd = +1 */
|
||||
[0b001010] = 4, /* rd = +1 */
|
||||
[0b001011] = 20, /* rd = +1 */
|
||||
[0b001100] = 24, /* rd = +1 */
|
||||
[0b001101] = 12, /* rd = +1 */
|
||||
[0b001101] = 12, /* rd = -1 */
|
||||
[0b001110] = 28, /* rd = +1 */
|
||||
[0b010001] = 29, /* rd = +1 */
|
||||
[0b010010] = 2, /* rd = +1 */
|
||||
[0b010011] = 18, /* rd = +1 */
|
||||
[0b010100] = 31, /* rd = +1 */
|
||||
[0b010101] = 10, /* rd = +1 */
|
||||
[0b010101] = 10, /* rd = -1 */
|
||||
[0b010110] = 26, /* rd = +1 */
|
||||
[0b010111] = 15, /* rd = -1 */
|
||||
[0b011000] = -1, /* rd = +1 */
|
||||
[0b011001] = 6, /* rd = +1 */
|
||||
[0b011010] = 22, /* rd = +1 */
|
||||
[0b011011] = 16, /* rd = -1 */
|
||||
[0b011100] = 14, /* rd = -1 */
|
||||
[0b011101] = 1, /* rd = -1 */
|
||||
[0b011110] = 30, /* rd = -1 */
|
||||
[0b100001] = 30, /* rd = +1 */
|
||||
[0b100010] = 1, /* rd = +1 */
|
||||
[0b100011] = 17, /* rd = -1 */
|
||||
[0b100100] = 16, /* rd = +1 */
|
||||
[0b100101] = 9, /* rd = -1 */
|
||||
[0b100110] = 25, /* rd = -1 */
|
||||
[0b100111] = -1, /* rd = -1 */
|
||||
[0b101000] = 15, /* rd = +1 */
|
||||
[0b101001] = 5, /* rd = -1 */
|
||||
[0b101010] = 21, /* rd = -1 */
|
||||
[0b101011] = 31, /* rd = -1 */
|
||||
[0b101100] = 13, /* rd = -1 */
|
||||
[0b101101] = 2, /* rd = -1 */
|
||||
[0b101110] = 29, /* rd = -1 */
|
||||
[0b110001] = 3, /* rd = -1 */
|
||||
[0b110010] = 19, /* rd = -1 */
|
||||
[0b110011] = 24, /* rd = -1 */
|
||||
[0b110100] = 11, /* rd = -1 */
|
||||
[0b110101] = 4, /* rd = -1 */
|
||||
[0b110110] = 27, /* rd = -1 */
|
||||
[0b111000] = 7, /* rd = -1 */
|
||||
[0b111001] = 8, /* rd = -1 */
|
||||
[0b111010] = 23 /* rd = -1 */
|
||||
};
|
||||
|
||||
static const struct entry_5b6b K28 = {0b001111, 0b110000};
|
||||
|
||||
static const struct entry_3b4b map_d_3b4b[7] = {
|
||||
{0b1011, 0b0100}, /* D.x.0 */
|
||||
{0b1001, 0b1001}, /* D.x.1 */
|
||||
{0b0101, 0b0101}, /* D.x.2 */
|
||||
{0b1100, 0b0011}, /* D.x.3 */
|
||||
{0b1101, 0b0010}, /* D.x.4 */
|
||||
{0b1010, 0b1010}, /* D.x.5 */
|
||||
{0b0110, 0b0110} /* D.x.6 */
|
||||
};
|
||||
|
||||
static const struct entry_3b4b Dx_P7 = {0b1110, 0b0001},
|
||||
Dx_A7 = {0b0111, 0b1000};
|
||||
|
||||
static const struct entry_3b4b map_3b4b_k[8] = {
|
||||
{0b1011, 0b0100}, /* K.x.0 */
|
||||
{0b0110, 0b1001}, /* K.x.1 */
|
||||
{0b1010, 0b0101}, /* K.x.2 */
|
||||
{0b1100, 0b0011}, /* K.x.3 */
|
||||
{0b1101, 0b0010}, /* K.x.4 */
|
||||
{0b0101, 0b1010}, /* K.x.5 */
|
||||
{0b1001, 0b0110}, /* K.x.6 */
|
||||
{0b0111, 0b1000} /* K.x.7 */
|
||||
};
|
||||
|
||||
static const int8_t map_4b3b[16] = {
|
||||
[0b0001] = 7, /* DxP7 rd = +1 */
|
||||
[0b0010] = 4, /* rd = +1 */
|
||||
[0b0011] = 3, /* rd = +1 */
|
||||
[0b0100] = -1, /* rd = +1 */
|
||||
[0b0101] = 2, /* rd = -1 */
|
||||
[0b0110] = 6, /* rd = -1 */
|
||||
[0b0111] = 7, /* DxA7 rd = -1 */
|
||||
[0b1000] = 7, /* DxA7 rd = +1 */
|
||||
[0b1001] = 1, /* rd = -1 */
|
||||
[0b1010] = 5, /* rd = -1 */
|
||||
[0b1011] = -1, /* rd = -1 */
|
||||
[0b1100] = 3, /* rd = -1 */
|
||||
[0b1101] = 4, /* rd = -1 */
|
||||
[0b1110] = 7, /* DxP7 rd = -1 */
|
||||
[0b1111] = 0, /* invalid */
|
||||
[0b0000] = 0 /* invalid */
|
||||
};
|
||||
|
||||
static const uint16_t k_sym_map[K_CODES_LAST] = {
|
||||
[K28_0] = 0b0011110100,
|
||||
[K28_1] = 0b0011111001,
|
||||
[K28_2] = 0b0011110101,
|
||||
[K28_3] = 0b0011110011,
|
||||
[K28_4] = 0b0011110010,
|
||||
[K28_5] = 0b0011111010,
|
||||
[K28_6] = 0b0011110110,
|
||||
[K28_7] = 0b0011111000,
|
||||
[K23_7] = 0b1110101000,
|
||||
[K27_7] = 0b1101101000,
|
||||
[K29_7] = 0b1011101000,
|
||||
[K30_7] = 0b0111101000
|
||||
};
|
||||
|
||||
void xfr_8b10b_reset(struct state_8b10b *st) {
|
||||
st->rx = 0;
|
||||
st->bit_ctr = 0; /* unsynchronized */
|
||||
}
|
||||
|
||||
int xfr_8b10b_feed_bit(struct state_8b10b *st, int bit) {
|
||||
uint32_t pattern = st->rx = (st->rx<<1 | !!bit) & 0x3ff;
|
||||
uint16_t comma = k_sym_map[K28_1];
|
||||
if (pattern == comma || pattern == ((~comma)&0x3ff)) {
|
||||
st->bit_ctr = 1;
|
||||
return -K28_1;
|
||||
}
|
||||
|
||||
if (st->bit_ctr == 10) {
|
||||
st->bit_ctr = 1;
|
||||
|
||||
for (int i=1; i<sizeof(k_sym_map)/sizeof(k_sym_map[0]); i++) {
|
||||
if (pattern == k_sym_map[i])
|
||||
return -i;
|
||||
}
|
||||
|
||||
int p3b = map_4b3b[pattern & 0xf];
|
||||
int p5b = map_6b5b[pattern >> 4];
|
||||
|
||||
if (p3b == 0 || p5b == 0)
|
||||
return -DECODING_ERROR;
|
||||
|
||||
p3b = (p3b == -1) ? 0 : p3b;
|
||||
p5b = (p5b == -1) ? 0 : p5b;
|
||||
return p3b<<5 | p5b;
|
||||
|
||||
} else if (st->bit_ctr > 0) {
|
||||
st->bit_ctr++;
|
||||
} /* else we do not have sync yet */
|
||||
return -DECODING_IN_PROGRESS;
|
||||
}
|
||||
|
||||
bool xfr_8b10b_has_sync(struct state_8b10b *st) {
|
||||
return st->bit_ctr != 0;
|
||||
}
|
||||
|
||||
38
fw/8b10b.h
Normal file
38
fw/8b10b.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef __8B10B_H__
|
||||
#define __8B10B_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
enum k_code {
|
||||
K28_0=1, K28_1, K28_2, K28_3,
|
||||
K28_4, K28_5, K28_6, K28_7,
|
||||
K23_7, K27_7, K29_7, K30_7,
|
||||
K_CODES_LAST
|
||||
};
|
||||
|
||||
enum decoder_return_codes {
|
||||
_K_CODES_LAST = K_CODES_LAST,
|
||||
DECODING_ERROR,
|
||||
DECODING_IN_PROGRESS
|
||||
};
|
||||
|
||||
struct entry_3b4b {
|
||||
uint8_t rd_neg, rd_pos;
|
||||
};
|
||||
|
||||
struct entry_5b6b {
|
||||
uint8_t rd_neg, rd_pos;
|
||||
};
|
||||
|
||||
struct state_8b10b {
|
||||
uint32_t rx;
|
||||
int bit_ctr;
|
||||
};
|
||||
|
||||
|
||||
void xfr_8b10b_reset(struct state_8b10b *st);
|
||||
int xfr_8b10b_feed_bit(struct state_8b10b *st, int bit);
|
||||
bool xfr_8b10b_has_sync(struct state_8b10b *st);
|
||||
|
||||
#endif
|
||||
78
fw/8b10b_test.c
Normal file
78
fw/8b10b_test.c
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "8b10b.h"
|
||||
|
||||
static const char * const rc_names[] = {
|
||||
[K28_0] = "K.28.0",
|
||||
[K28_1] = "K.28.1",
|
||||
[K28_2] = "K.28.2",
|
||||
[K28_3] = "K.28.3",
|
||||
[K28_4] = "K.28.4",
|
||||
[K28_5] = "K.28.5",
|
||||
[K28_6] = "K.28.6",
|
||||
[K28_7] = "K.28.7",
|
||||
[K23_7] = "K.23.7",
|
||||
[K27_7] = "K.27.7",
|
||||
[K29_7] = "K.29.7",
|
||||
[K30_7] = "K.30.7",
|
||||
[DECODING_ERROR] = "ERROR",
|
||||
[DECODING_IN_PROGRESS] = "."
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
struct state_8b10b st;
|
||||
|
||||
xfr_8b10b_reset(&st);
|
||||
|
||||
int c;
|
||||
int comment = 0;
|
||||
while ((c=fgetc(stdin)) != EOF) {
|
||||
int bit;
|
||||
|
||||
if (comment) {
|
||||
if (c == '\n')
|
||||
comment = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '\r' || c == ' ' || c == '\t' || c == '\n')
|
||||
continue;
|
||||
|
||||
if (c == '#') {
|
||||
comment = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '0') {
|
||||
bit = 0;
|
||||
} else if (c == '1') {
|
||||
bit = 1;
|
||||
} else {
|
||||
fprintf(stderr, "Parse error: Bit must be 0 or 1, not '%c'. Exiting.\n", c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int read_result = xfr_8b10b_feed_bit(&st, bit);
|
||||
char sync_status = xfr_8b10b_has_sync(&st) ? 'S' : 'U';
|
||||
|
||||
if (read_result >= 0) {
|
||||
fprintf(stdout, "%c%02x ", sync_status, read_result);
|
||||
|
||||
} else {
|
||||
if (-read_result > sizeof(rc_names)/sizeof(rc_names[0])) {
|
||||
fprintf(stderr, "Illegal read result %d. Exiting.\n", read_result);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const char * const msg = rc_names[-read_result];
|
||||
if (!msg) {
|
||||
fprintf(stderr, "Illegal read result %d. Exiting.\n", read_result);
|
||||
return 2;
|
||||
}
|
||||
|
||||
fprintf(stdout, "%c%s ", sync_status, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
101
fw/Makefile
Normal file
101
fw/Makefile
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# Megumin LED display firmware
|
||||
# Copyright (C) 2018 Sebastian Götte <code@jaseg.net>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
CUBE_PATH ?= $(wildcard ~)/resource/STM32CubeF0
|
||||
CMSIS_PATH ?= $(CUBE_PATH)/Drivers/CMSIS
|
||||
CMSIS_DEV_PATH ?= $(CMSIS_PATH)/Device/ST/STM32F0xx
|
||||
HAL_PATH ?= $(CUBE_PATH)/Drivers/STM32F0xx_HAL_Driver
|
||||
|
||||
MAC_ADDR ?= 0xdeadbeef
|
||||
|
||||
CC := arm-none-eabi-gcc
|
||||
LD := arm-none-eabi-ld
|
||||
OBJCOPY := arm-none-eabi-objcopy
|
||||
OBJDUMP := arm-none-eabi-objdump
|
||||
SIZE := arm-none-eabi-size
|
||||
|
||||
CFLAGS = -g -Wall -std=gnu11 -O0 -fdump-rtl-expand -DMAC_ADDR=$(MAC_ADDR)
|
||||
CFLAGS += -mlittle-endian -mcpu=cortex-m0 -march=armv6-m -mthumb
|
||||
#CFLAGS += -ffunction-sections -fdata-sections
|
||||
LDFLAGS = -nostartfiles
|
||||
#LDFLAGS += -specs=rdimon.specs -DSEMIHOSTING
|
||||
LDFLAGS += -Wl,-Map=main.map -nostdlib
|
||||
#LDFLAGS += -Wl,--gc-sections
|
||||
LIBS = -lgcc
|
||||
#LIBS += -lrdimon
|
||||
|
||||
# Technically we're using an STM32F030F4, but apart from the TSSOP20 package that one is largely identical to the
|
||||
# STM32F030*6 and there is no separate device header provided for it, so we're faking a *6 device here. This is
|
||||
# even documented in stm32f0xx.h. Thanks ST!
|
||||
CFLAGS += -DSTM32F030x6 -DHSE_VALUE=8000000
|
||||
|
||||
LDFLAGS += -Tstm32_flash.ld
|
||||
CFLAGS += -I$(CMSIS_DEV_PATH)/Include -I$(CMSIS_PATH)/Include -I$(HAL_PATH)/Inc -Iconfig -Wno-unused
|
||||
LDFLAGS += -L$(CMSIS_PATH)/Lib/GCC -larm_cortexM0l_math
|
||||
|
||||
###################################################
|
||||
|
||||
.PHONY: program clean
|
||||
|
||||
all: main.elf
|
||||
|
||||
cmsis_exports.c: $(CMSIS_DEV_PATH)/Include/stm32f030x6.h $(CMSIS_PATH)/Include/core_cm0.h
|
||||
python3 tools/gen_cmsis_exports.py $^ > $@
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c $(CFLAGS) -o $@ $^
|
||||
# $(CC) -E $(CFLAGS) -o $(@:.o=.pp) $^
|
||||
|
||||
%.o: %.s
|
||||
$(CC) -c $(CFLAGS) -o $@ $^
|
||||
# $(CC) -E $(CFLAGS) -o $(@:.o=.pp) $^
|
||||
|
||||
%.dot: %.elf
|
||||
r2 -a arm -qc 'aa;agC' $< 2>/dev/null >$@
|
||||
|
||||
sources.tar.xz: main.c Makefile
|
||||
tar -caf $@ $^
|
||||
|
||||
# don't ask...
|
||||
sources.tar.xz.zip: sources.tar.xz
|
||||
zip $@ $^
|
||||
|
||||
sources.c: sources.tar.xz.zip
|
||||
xxd -i $< | head -n -1 | sed 's/=/__attribute__((section(".source_tarball"))) =/' > $@
|
||||
|
||||
main.elf: main.o startup_stm32f030x6.o system_stm32f0xx.o $(HAL_PATH)/Src/stm32f0xx_ll_utils.o base.o cmsis_exports.o 8b10b.o sources.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
$(OBJCOPY) -O ihex $@ $(@:.elf=.hex)
|
||||
$(OBJCOPY) -O binary $@ $(@:.elf=.bin)
|
||||
$(OBJDUMP) -St $@ >$(@:.elf=.lst)
|
||||
$(SIZE) $@
|
||||
|
||||
program: main.elf openocd.cfg
|
||||
openocd -f openocd.cfg -c "program $< verify reset exit"
|
||||
|
||||
8b10b_test: 8b10b_test.c 8b10b.c
|
||||
gcc -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f **.o
|
||||
rm -f main.elf main.hex main.bin main.map main.lst
|
||||
rm -f **.expand
|
||||
rm -f cmsis_exports.c
|
||||
rm -f sources.tar.xz
|
||||
rm -f sources.tar.xz.zip
|
||||
rm -f sources.c
|
||||
rm -f *.dot
|
||||
|
||||
21
fw/base.c
Normal file
21
fw/base.c
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
#include <unistd.h>
|
||||
|
||||
int __errno = 0;
|
||||
void *_impure_ptr = NULL;
|
||||
|
||||
void __sinit(void) {
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n) {
|
||||
char *end = (char *)s + n;
|
||||
for (char *p = (char *)s; p < end; p++)
|
||||
*p = (char)c;
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s) {
|
||||
const char *start = s;
|
||||
while (*s++);
|
||||
return s - start - 1;
|
||||
}
|
||||
0
fw/cmsis_exports.c
Normal file
0
fw/cmsis_exports.c
Normal file
48
fw/global.h
Normal file
48
fw/global.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* Megumin LED display firmware
|
||||
* Copyright (C) 2018 Sebastian Götte <code@jaseg.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GLOBAL_H__
|
||||
#define __GLOBAL_H__
|
||||
|
||||
/* Workaround for sub-par ST libraries */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#include <stm32f0xx.h>
|
||||
#include <stm32f0xx_ll_utils.h>
|
||||
#include <stm32f0xx_ll_spi.h>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#include <system_stm32f0xx.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Microcontroller part number: STM32F030F4C6 */
|
||||
|
||||
/* Things used for module status reporting. */
|
||||
#define FIRMWARE_VERSION 2
|
||||
#define HARDWARE_VERSION 4
|
||||
|
||||
#define TS_CAL1 (*(uint16_t *)0x1FFFF7B8)
|
||||
#define VREFINT_CAL (*(uint16_t *)0x1FFFF7BA)
|
||||
|
||||
extern volatile unsigned int sys_time;
|
||||
extern volatile unsigned int sys_time_seconds;
|
||||
|
||||
#endif/*__GLOBAL_H__*/
|
||||
103
fw/main.c
Normal file
103
fw/main.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/* Megumin LED display firmware
|
||||
* Copyright (C) 2018 Sebastian Götte <code@jaseg.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
volatile unsigned int sys_time = 0;
|
||||
volatile unsigned int sys_time_seconds = 0;
|
||||
|
||||
int main(void) {
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while (!(RCC->CR&RCC_CR_HSERDY));
|
||||
RCC->CFGR &= ~RCC_CFGR_PLLMUL_Msk & ~RCC_CFGR_SW_Msk & ~RCC_CFGR_PPRE_Msk & ~RCC_CFGR_HPRE_Msk;
|
||||
RCC->CFGR |= (2<<RCC_CFGR_PLLMUL_Pos) | RCC_CFGR_PLLSRC_HSE_PREDIV; /* PLL x4 -> 32.0MHz */
|
||||
RCC->CFGR2 &= ~RCC_CFGR2_PREDIV_Msk;
|
||||
RCC->CFGR2 |= RCC_CFGR2_PREDIV_DIV2; /* prediv :2 -> 4.0MHz */
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while (!(RCC->CR&RCC_CR_PLLRDY));
|
||||
RCC->CFGR |= (2<<RCC_CFGR_SW_Pos);
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
/* Turn on lots of neat things */
|
||||
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_FLITFEN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_DBGMCUEN | RCC_APB2ENR_TIM1EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||
|
||||
GPIOA->MODER |=
|
||||
(3<<GPIO_MODER_MODER0_Pos) /* PA0 - Vmeas_A */
|
||||
| (3<<GPIO_MODER_MODER1_Pos) /* PA1 - Vmeas_B */
|
||||
| (1<<GPIO_MODER_MODER2_Pos) /* PA2 - LOAD */
|
||||
| (1<<GPIO_MODER_MODER3_Pos) /* PA3 - CH0 */
|
||||
| (1<<GPIO_MODER_MODER4_Pos) /* PA4 - CH3 */
|
||||
| (0<<GPIO_MODER_MODER5_Pos) /* PA5 - TP1 */
|
||||
| (1<<GPIO_MODER_MODER6_Pos) /* PA6 - CH2 */
|
||||
| (1<<GPIO_MODER_MODER7_Pos) /* PA7 - CH1 */
|
||||
| (0<<GPIO_MODER_MODER9_Pos) /* PA9 - TP2 */
|
||||
| (0<<GPIO_MODER_MODER10_Pos);/* PA10 - TP3 */
|
||||
|
||||
/* Set shift register IO GPIO output speed */
|
||||
GPIOA->OSPEEDR |=
|
||||
(2<<GPIO_OSPEEDR_OSPEEDR2_Pos) /* LOAD */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR3_Pos) /* CH0 */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR4_Pos) /* CH3 */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR6_Pos) /* CH2 */
|
||||
| (2<<GPIO_OSPEEDR_OSPEEDR7_Pos); /* CH1 */
|
||||
|
||||
SysTick_Config(SystemCoreClock/1000); /* 1ms interval */
|
||||
|
||||
void set_outputs(uint8_t val) {
|
||||
int a=!!(val&1), b=!!(val&2), c=!!(val&4), d=!!(val&8);
|
||||
GPIOA->ODR &= ~(!a<<3 | !b<<7 | c<<6 | d<<4);
|
||||
GPIOA->ODR |= a<<3 | b<<7 | !c<<6 | !d<<4;
|
||||
}
|
||||
while (42) {
|
||||
#define FOO 500000
|
||||
for (int i=0; i<FOO; i++) ;
|
||||
set_outputs(0x1);
|
||||
for (int i=0; i<FOO; i++) ;
|
||||
set_outputs(0x2);
|
||||
for (int i=0; i<FOO; i++) ;
|
||||
set_outputs(0x4);
|
||||
for (int i=0; i<FOO; i++) ;
|
||||
set_outputs(0x8);
|
||||
}
|
||||
}
|
||||
|
||||
void NMI_Handler(void) {
|
||||
}
|
||||
|
||||
void HardFault_Handler(void) __attribute__((naked));
|
||||
void HardFault_Handler() {
|
||||
asm volatile ("bkpt");
|
||||
}
|
||||
|
||||
void SVC_Handler(void) {
|
||||
}
|
||||
|
||||
|
||||
void PendSV_Handler(void) {
|
||||
}
|
||||
|
||||
void SysTick_Handler(void) {
|
||||
static int n = 0;
|
||||
sys_time++;
|
||||
if (n++ == 1000) {
|
||||
n = 0;
|
||||
sys_time_seconds++;
|
||||
}
|
||||
}
|
||||
|
||||
16
fw/openocd.cfg
Normal file
16
fw/openocd.cfg
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
telnet_port 4444
|
||||
gdb_port 3333
|
||||
|
||||
source [find interface/stlink-v2.cfg]
|
||||
#interface jlink
|
||||
#interface stlink-v2
|
||||
#adapter_khz 10000
|
||||
#transport select swd
|
||||
|
||||
#source /usr/share/openocd/scripts/target/stm32f0x.cfg
|
||||
source [find target/stm32f0x_stlink.cfg]
|
||||
|
||||
init
|
||||
arm semihosting enable
|
||||
|
||||
#flash bank sysflash.alias stm32f0x 0x00000000 0 0 0 $_TARGETNAME
|
||||
273
fw/startup_stm32f030x6.s
Normal file
273
fw/startup_stm32f030x6.s
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file startup_stm32f030x6.s
|
||||
* copied from: STM32Cube/Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/gcc
|
||||
* @author MCD Application Team
|
||||
* @version V2.3.1
|
||||
* @date 04-November-2016
|
||||
* @brief STM32F030x4/STM32F030x6 devices vector table for Atollic TrueSTUDIO toolchain.
|
||||
* This module performs:
|
||||
* - Set the initial SP
|
||||
* - Set the initial PC == Reset_Handler,
|
||||
* - Set the vector table entries with the exceptions ISR address
|
||||
* - Branches to main in the C library (which eventually
|
||||
* calls main()).
|
||||
* After Reset the Cortex-M0 processor is in Thread mode,
|
||||
* priority is Privileged, and the Stack is set to Main.
|
||||
******************************************************************************
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m0
|
||||
.fpu softvfp
|
||||
.thumb
|
||||
|
||||
.global g_pfnVectors
|
||||
.global Default_Handler
|
||||
|
||||
/* start address for the initialization values of the .data section.
|
||||
defined in linker script */
|
||||
.word _sidata
|
||||
/* start address for the .data section. defined in linker script */
|
||||
.word _sdata
|
||||
/* end address for the .data section. defined in linker script */
|
||||
.word _edata
|
||||
/* start address for the .bss section. defined in linker script */
|
||||
.word _sbss
|
||||
/* end address for the .bss section. defined in linker script */
|
||||
.word _ebss
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
ldr r0, =_estack
|
||||
mov sp, r0 /* set stack pointer */
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
movs r1, #0
|
||||
b LoopCopyDataInit
|
||||
|
||||
CopyDataInit:
|
||||
ldr r3, =_sidata
|
||||
ldr r3, [r3, r1]
|
||||
str r3, [r0, r1]
|
||||
adds r1, r1, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
ldr r0, =_sdata
|
||||
ldr r3, =_edata
|
||||
adds r2, r0, r1
|
||||
cmp r2, r3
|
||||
bcc CopyDataInit
|
||||
ldr r2, =_sbss
|
||||
b LoopFillZerobss
|
||||
/* Zero fill the bss segment. */
|
||||
FillZerobss:
|
||||
movs r3, #0
|
||||
str r3, [r2]
|
||||
adds r2, r2, #4
|
||||
|
||||
|
||||
LoopFillZerobss:
|
||||
ldr r3, = _ebss
|
||||
cmp r2, r3
|
||||
bcc FillZerobss
|
||||
|
||||
/* Call the clock system intitialization function.*/
|
||||
bl SystemInit
|
||||
/* Call static constructors */
|
||||
// bl __libc_init_array
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
|
||||
LoopForever:
|
||||
b LoopForever
|
||||
|
||||
|
||||
.size Reset_Handler, .-Reset_Handler
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor receives an
|
||||
* unexpected interrupt. This simply enters an infinite loop, preserving
|
||||
* the system state for examination by a debugger.
|
||||
*
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
.section .text.Default_Handler,"ax",%progbits
|
||||
Default_Handler:
|
||||
Infinite_Loop:
|
||||
b Infinite_Loop
|
||||
.size Default_Handler, .-Default_Handler
|
||||
/******************************************************************************
|
||||
*
|
||||
* The minimal vector table for a Cortex M0. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x0000.0000.
|
||||
*
|
||||
******************************************************************************/
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
|
||||
g_pfnVectors:
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
.word WWDG_IRQHandler /* Window WatchDog */
|
||||
.word 0 /* Reserved */
|
||||
.word RTC_IRQHandler /* RTC through the EXTI line */
|
||||
.word FLASH_IRQHandler /* FLASH */
|
||||
.word RCC_IRQHandler /* RCC */
|
||||
.word EXTI0_1_IRQHandler /* EXTI Line 0 and 1 */
|
||||
.word EXTI2_3_IRQHandler /* EXTI Line 2 and 3 */
|
||||
.word EXTI4_15_IRQHandler /* EXTI Line 4 to 15 */
|
||||
.word 0 /* Reserved */
|
||||
.word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
|
||||
.word DMA1_Channel2_3_IRQHandler /* DMA1 Channel 2 and Channel 3 */
|
||||
.word DMA1_Channel4_5_IRQHandler /* DMA1 Channel 4 and Channel 5 */
|
||||
.word ADC1_IRQHandler /* ADC1 */
|
||||
.word TIM1_BRK_UP_TRG_COM_IRQHandler /* TIM1 Break, Update, Trigger and Commutation */
|
||||
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.word 0 /* Reserved */
|
||||
.word TIM3_IRQHandler /* TIM3 */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word TIM14_IRQHandler /* TIM14 */
|
||||
.word 0 /* Reserved */
|
||||
.word TIM16_IRQHandler /* TIM16 */
|
||||
.word TIM17_IRQHandler /* TIM17 */
|
||||
.word I2C1_IRQHandler /* I2C1 */
|
||||
.word 0 /* Reserved */
|
||||
.word SPI1_IRQHandler /* SPI1 */
|
||||
.word 0 /* Reserved */
|
||||
.word USART1_IRQHandler /* USART1 */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
.weak NMI_Handler
|
||||
.thumb_set NMI_Handler,Default_Handler
|
||||
|
||||
.weak HardFault_Handler
|
||||
.thumb_set HardFault_Handler,Default_Handler
|
||||
|
||||
.weak SVC_Handler
|
||||
.thumb_set SVC_Handler,Default_Handler
|
||||
|
||||
.weak PendSV_Handler
|
||||
.thumb_set PendSV_Handler,Default_Handler
|
||||
|
||||
.weak SysTick_Handler
|
||||
.thumb_set SysTick_Handler,Default_Handler
|
||||
|
||||
.weak WWDG_IRQHandler
|
||||
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_IRQHandler
|
||||
.thumb_set RTC_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_IRQHandler
|
||||
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_IRQHandler
|
||||
.thumb_set RCC_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI0_1_IRQHandler
|
||||
.thumb_set EXTI0_1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI2_3_IRQHandler
|
||||
.thumb_set EXTI2_3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI4_15_IRQHandler
|
||||
.thumb_set EXTI4_15_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel1_IRQHandler
|
||||
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel2_3_IRQHandler
|
||||
.thumb_set DMA1_Channel2_3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel4_5_IRQHandler
|
||||
.thumb_set DMA1_Channel4_5_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC1_IRQHandler
|
||||
.thumb_set ADC1_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_BRK_UP_TRG_COM_IRQHandler
|
||||
.thumb_set TIM1_BRK_UP_TRG_COM_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_CC_IRQHandler
|
||||
.thumb_set TIM1_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM3_IRQHandler
|
||||
.thumb_set TIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM14_IRQHandler
|
||||
.thumb_set TIM14_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM16_IRQHandler
|
||||
.thumb_set TIM16_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM17_IRQHandler
|
||||
.thumb_set TIM17_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_IRQHandler
|
||||
.thumb_set I2C1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI1_IRQHandler
|
||||
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART1_IRQHandler
|
||||
.thumb_set USART1_IRQHandler,Default_Handler
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
136
fw/stm32_flash.ld
Normal file
136
fw/stm32_flash.ld
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
MEMORY {
|
||||
FLASH (rx): ORIGIN = 0x08000000, LENGTH = 0x3C00
|
||||
CONFIGFLASH (rw): ORIGIN = 0x08003C00, LENGTH = 0x400
|
||||
RAM (xrw): ORIGIN = 0x20000000, LENGTH = 4K
|
||||
}
|
||||
|
||||
/* highest address of the user mode stack */
|
||||
_estack = 0x20001000;
|
||||
|
||||
SECTIONS {
|
||||
/* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */
|
||||
.isr_vector : {
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* the program code is stored in the .text section, which goes to Flash */
|
||||
.text : {
|
||||
. = ALIGN(4);
|
||||
|
||||
*(.text) /* normal code */
|
||||
*(.text.*) /* -ffunction-sections code */
|
||||
*(.rodata) /* read-only data (constants) */
|
||||
*(.rodata*) /* -fdata-sections read only data */
|
||||
*(.glue_7) /* TBD - needed ? */
|
||||
*(.glue_7t) /* TBD - needed ? */
|
||||
|
||||
*(.source_tarball)
|
||||
|
||||
/* Necessary KEEP sections (see http://sourceware.org/ml/newlib/2005/msg00255.html) */
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
KEEP (*(.source_tarball))
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
/* This is used by the startup in order to initialize the .data section */
|
||||
_sidata = _etext;
|
||||
} >FLASH
|
||||
|
||||
/*
|
||||
.configflash : {
|
||||
. = ALIGN(0x400);
|
||||
*(.configdata)
|
||||
_econfig = .;
|
||||
} >FLASH
|
||||
*/
|
||||
|
||||
/* This is the initialized data section
|
||||
The program executes knowing that the data is in the RAM
|
||||
but the loader puts the initial values in the FLASH (inidata).
|
||||
It is one task of the startup to copy the initial values from FLASH to RAM. */
|
||||
.data : AT ( _sidata ) {
|
||||
. = ALIGN(4);
|
||||
/* This is used by the startup in order to initialize the .data secion */
|
||||
_sdata = . ;
|
||||
_data = . ;
|
||||
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.RAMtext)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* This is used by the startup in order to initialize the .data secion */
|
||||
_edata = . ;
|
||||
} >RAM
|
||||
|
||||
/* This is the uninitialized data section */
|
||||
.bss : {
|
||||
. = ALIGN(4);
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
_sbss = .;
|
||||
_bss = .;
|
||||
|
||||
*(.bss)
|
||||
*(.bss.*) /* patched by elias - allows the use of -fdata-sections */
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
_ebss = . ;
|
||||
} >RAM
|
||||
|
||||
PROVIDE ( end = _ebss);
|
||||
PROVIDE (_end = _ebss);
|
||||
|
||||
__exidx_start = .;
|
||||
__exidx_end = .;
|
||||
|
||||
/* after that it's only debugging information. */
|
||||
|
||||
/* remove the debugging information from the standard libraries */
|
||||
/* /DISCARD/ : {
|
||||
libc.a ( * )
|
||||
libm.a ( * )
|
||||
libgcc.a ( * )
|
||||
}*/
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
}
|
||||
336
fw/system_stm32f0xx.c
Normal file
336
fw/system_stm32f0xx.c
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f0xx.c
|
||||
* copied from: STM32Cube/Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates
|
||||
* @author MCD Application Team
|
||||
* @version V2.3.1
|
||||
* @date 04-November-2016
|
||||
* @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File.
|
||||
*
|
||||
* 1. This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32f0xx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
|
||||
* by the user application to setup the SysTick
|
||||
* timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
* 2. After each device reset the HSI (8 MHz) is used as system clock source.
|
||||
* Then SystemInit() function is called, in "startup_stm32f0xx.s" file, to
|
||||
* configure the system clock before to branch to main program.
|
||||
*
|
||||
* 3. This file configures the system clock as follows:
|
||||
*=============================================================================
|
||||
* Supported STM32F0xx device
|
||||
*-----------------------------------------------------------------------------
|
||||
* System Clock source | HSI
|
||||
*-----------------------------------------------------------------------------
|
||||
* SYSCLK(Hz) | 8000000
|
||||
*-----------------------------------------------------------------------------
|
||||
* HCLK(Hz) | 8000000
|
||||
*-----------------------------------------------------------------------------
|
||||
* AHB Prescaler | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
* APB1 Prescaler | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
*=============================================================================
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f0xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32f0xx.h"
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
#if !defined (HSI48_VALUE)
|
||||
#define HSI48_VALUE ((uint32_t)48000000) /*!< Default value of the HSI48 Internal oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSI48_VALUE */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock there is no need to
|
||||
call the 2 first functions listed above, since SystemCoreClock variable is
|
||||
updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = 8000000;
|
||||
|
||||
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
* Initialize the default HSI clock source, vector table location and the PLL configuration is reset.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* Reset the RCC clock configuration to the default reset state ------------*/
|
||||
/* Set HSION bit */
|
||||
RCC->CR |= (uint32_t)0x00000001U;
|
||||
|
||||
#if defined (STM32F051x8) || defined (STM32F058x8)
|
||||
/* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE and MCOSEL[2:0] bits */
|
||||
RCC->CFGR &= (uint32_t)0xF8FFB80CU;
|
||||
#else
|
||||
/* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE, MCOSEL[2:0], MCOPRE[2:0] and PLLNODIV bits */
|
||||
RCC->CFGR &= (uint32_t)0x08FFB80CU;
|
||||
#endif /* STM32F051x8 or STM32F058x8 */
|
||||
|
||||
/* Reset HSEON, CSSON and PLLON bits */
|
||||
RCC->CR &= (uint32_t)0xFEF6FFFFU;
|
||||
|
||||
/* Reset HSEBYP bit */
|
||||
RCC->CR &= (uint32_t)0xFFFBFFFFU;
|
||||
|
||||
/* Reset PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
|
||||
RCC->CFGR &= (uint32_t)0xFFC0FFFFU;
|
||||
|
||||
/* Reset PREDIV[3:0] bits */
|
||||
RCC->CFGR2 &= (uint32_t)0xFFFFFFF0U;
|
||||
|
||||
#if defined (STM32F072xB) || defined (STM32F078xx)
|
||||
/* Reset USART2SW[1:0], USART1SW[1:0], I2C1SW, CECSW, USBSW and ADCSW bits */
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFCFE2CU;
|
||||
#elif defined (STM32F071xB)
|
||||
/* Reset USART2SW[1:0], USART1SW[1:0], I2C1SW, CECSW and ADCSW bits */
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFFCEACU;
|
||||
#elif defined (STM32F091xC) || defined (STM32F098xx)
|
||||
/* Reset USART3SW[1:0], USART2SW[1:0], USART1SW[1:0], I2C1SW, CECSW and ADCSW bits */
|
||||
RCC->CFGR3 &= (uint32_t)0xFFF0FEACU;
|
||||
#elif defined (STM32F030x6) || defined (STM32F030x8) || defined (STM32F031x6) || defined (STM32F038xx) || defined (STM32F030xC)
|
||||
/* Reset USART1SW[1:0], I2C1SW and ADCSW bits */
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFFFEECU;
|
||||
#elif defined (STM32F051x8) || defined (STM32F058xx)
|
||||
/* Reset USART1SW[1:0], I2C1SW, CECSW and ADCSW bits */
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFFFEACU;
|
||||
#elif defined (STM32F042x6) || defined (STM32F048xx)
|
||||
/* Reset USART1SW[1:0], I2C1SW, CECSW, USBSW and ADCSW bits */
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFFFE2CU;
|
||||
#elif defined (STM32F070x6) || defined (STM32F070xB)
|
||||
/* Reset USART1SW[1:0], I2C1SW, USBSW and ADCSW bits */
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFFFE6CU;
|
||||
/* Set default USB clock to PLLCLK, since there is no HSI48 */
|
||||
RCC->CFGR3 |= (uint32_t)0x00000080U;
|
||||
#else
|
||||
#warning "No target selected"
|
||||
#endif
|
||||
|
||||
/* Reset HSI14 bit */
|
||||
RCC->CR2 &= (uint32_t)0xFFFFFFFEU;
|
||||
|
||||
/* Disable all interrupts */
|
||||
RCC->CIR = 0x00000000U;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @note - The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32f0xx_hal.h file (default value
|
||||
* 8 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) HSE_VALUE is a constant defined in stm32f0xx_hal.h file (default value
|
||||
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
*
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0;
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case RCC_CFGR_SWS_HSI: /* HSI used as system clock */
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case RCC_CFGR_SWS_HSE: /* HSE used as system clock */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case RCC_CFGR_SWS_PLL: /* PLL used as system clock */
|
||||
/* Get PLL clock source and multiplication factor ----------------------*/
|
||||
pllmull = RCC->CFGR & RCC_CFGR_PLLMUL;
|
||||
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
||||
pllmull = ( pllmull >> 18) + 2;
|
||||
predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;
|
||||
|
||||
if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV)
|
||||
{
|
||||
/* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */
|
||||
SystemCoreClock = (HSE_VALUE/predivfactor) * pllmull;
|
||||
}
|
||||
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx)
|
||||
else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV)
|
||||
{
|
||||
/* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * PLLMUL */
|
||||
SystemCoreClock = (HSI48_VALUE/predivfactor) * pllmull;
|
||||
}
|
||||
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx */
|
||||
else
|
||||
{
|
||||
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) \
|
||||
|| defined(STM32F078xx) || defined(STM32F071xB) || defined(STM32F072xB) \
|
||||
|| defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)
|
||||
/* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */
|
||||
SystemCoreClock = (HSI_VALUE/predivfactor) * pllmull;
|
||||
#else
|
||||
/* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 ||
|
||||
STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB ||
|
||||
STM32F091xC || STM32F098xx || STM32F030xC */
|
||||
}
|
||||
break;
|
||||
default: /* HSI used as system clock */
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
/* Compute HCLK clock frequency ----------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
30
fw/tools/gen_cmsis_exports.py
Normal file
30
fw/tools/gen_cmsis_exports.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env python3
|
||||
import re
|
||||
import os
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('cmsis_device_header', nargs='+', type=argparse.FileType('rb'))
|
||||
args = parser.parse_args()
|
||||
|
||||
print('#ifndef __GENERATED_CMSIS_HEADER_EXPORTS__')
|
||||
print('#define __GENERATED_CMSIS_HEADER_EXPORTS__')
|
||||
print()
|
||||
for header in args.cmsis_device_header:
|
||||
lines = header.readlines()
|
||||
name = os.path.basename(header.name)
|
||||
print('#include <{}>'.format(name))
|
||||
print()
|
||||
|
||||
print('/* {} */'.format(name))
|
||||
for l in lines:
|
||||
match = re.match(b'^#define (\w+)\s+\W*(\w+_TypeDef|\w+_Type).*$', l)
|
||||
if match:
|
||||
inst, typedef = match.groups()
|
||||
inst, typedef = inst.decode(), typedef.decode()
|
||||
print('{} *{} = {};'.format(typedef, inst.lower(), inst))
|
||||
print()
|
||||
print('#endif//__GENERATED_CMSIS_HEADER_EXPORTS__')
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue