Compare commits
172 Commits
Author | SHA1 | Date | |
---|---|---|---|
7854328a55 | |||
90ec47d49a | |||
776569d7c1 | |||
f7e0d514dc | |||
7f06533fe7 | |||
dd09112a22 | |||
dcd41db126 | |||
63f7f0ece5 | |||
938e2467a4 | |||
aa1d7b1dde | |||
bbc981fecb | |||
78bc3b97f3 | |||
3f18fef34c | |||
86fa08cb91 | |||
886965ee80 | |||
f335044c77 | |||
af7477d971 | |||
b7670d1e24 | |||
55ac60e080 | |||
8d6d7f315f | |||
1d118ced08 | |||
da57f5ee40 | |||
ac7b075b1c | |||
cfc6c509b7 | |||
ad1aa69180 | |||
ae394561e2 | |||
851c25ffe0 | |||
0e92b46c3e | |||
3f00d36f05 | |||
b0ab623968 | |||
571038023c | |||
b7da249c51 | |||
8bfccb86a0 | |||
9d415ed449 | |||
85fdb1bbac | |||
2dd6e09cd0 | |||
9af8516030 | |||
479a1316c3 | |||
3cd3a869f4 | |||
3c4cabb483 | |||
32aa557a00 | |||
af9d0d685a | |||
02f95f55ee | |||
24cec3850d | |||
462a65cb92 | |||
a8b7726c35 | |||
90dbc57166 | |||
62650bd1b2 | |||
4c1ee2bc26 | |||
0250d81862 | |||
beb6d33f85 | |||
5e688d467d | |||
b0351bcaaf | |||
7675f73d0b | |||
a1da462852 | |||
0e91b71aae | |||
759cfd577e | |||
c73600c91f | |||
34d44c2a88 | |||
884f007d19 | |||
71564dd4f1 | |||
4fba2fd7a4 | |||
d208297aa3 | |||
9d1a4006af | |||
6aa820690e | |||
ea30c7c879 | |||
a2f203a81f | |||
a74539ab4f | |||
9c9893e1da | |||
a716cb10cf | |||
0a18d73197 | |||
8c01cbd918 | |||
019b82d384 | |||
a89d8abb38 | |||
ced5582a1a | |||
4d53d868fe | |||
ce0848343d | |||
863fd744d7 | |||
d85d345ec4 | |||
35a614750d | |||
b3cf0d0302 | |||
3a6a64928d | |||
99d66f4e4e | |||
66521e1981 | |||
210fab8eae | |||
7318d70dcd | |||
0010c5e046 | |||
6b3b55839e | |||
6bed3ab0fb | |||
9a7c51f80e | |||
7a74f9709f | |||
fa29cfc29f | |||
2248ba1762 | |||
ac255816a1 | |||
95b63a06f5 | |||
7656c699bf | |||
c6a4f58b93 | |||
b82520fa9b | |||
25fcf8fe0b | |||
01eaa5cfab | |||
793611d629 | |||
ad52abc26b | |||
b0f5f127f6 | |||
a449b9b7ff | |||
4c6e9a4fda | |||
789b36fc21 | |||
c8861f40c4 | |||
77415cb41f | |||
11f5bc9771 | |||
8526dc084b | |||
fea286914b | |||
cfcc8a1bb6 | |||
510c82d00f | |||
26f6de3015 | |||
a9461b53f5 | |||
d7b6300a50 | |||
d0bd71b266 | |||
a46b6a1630 | |||
b100c4ae13 | |||
a0f9b4a530 | |||
e32e27100d | |||
5b0523f751 | |||
d6cac41b78 | |||
adc62ebb9a | |||
d9a15f2daa | |||
c4af940975 | |||
c58d27cf2e | |||
c3d7711258 | |||
78cb85421a | |||
ff5fbc847d | |||
51e0bfd188 | |||
c411d552a1 | |||
ceff33ea0e | |||
68955ddfec | |||
40ee01ce67 | |||
0b2bbf8c97 | |||
87af738378 | |||
e4ce622f15 | |||
dbd0ea4d27 | |||
a878a1ad9c | |||
aff4275478 | |||
609188d74e | |||
63a2e5e5ff | |||
ac1bea1d45 | |||
7b7f26ee47 | |||
3d00bdf3c0 | |||
319a02d2b4 | |||
cc8be1f278 | |||
e255573b1e | |||
0fe7e1fd39 | |||
2249f460e3 | |||
aae4009fbe | |||
a9284b7154 | |||
777fd7afb9 | |||
31079d95dd | |||
ced714129c | |||
4fcfd29d2b | |||
06de8d0be9 | |||
de36c7f3a2 | |||
8918b97618 | |||
0bb2be3727 | |||
a781fc5b3b | |||
00ef5d9344 | |||
9fbf5b4aad | |||
46083bdf5e | |||
8a165c4d71 | |||
9db9ea9dc1 | |||
4b514c6801 | |||
6a34352914 | |||
35c441355d | |||
9751880813 | |||
e58614002c |
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -1,4 +1,4 @@
|
||||
[submodule "libopencm3"]
|
||||
path = libopencm3
|
||||
url = https://github.com/libopencm3/libopencm3
|
||||
url = https://github.com/libopencm3/libopencm3/
|
||||
ignore = all
|
||||
|
225
README.md
225
README.md
@ -1,4 +1,4 @@
|
||||
This firmware template is designed for development boards based around [STM32 F1 series micro-controller](http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1031).
|
||||
firmware for the Bahn Uhr controller.
|
||||
|
||||
project
|
||||
=======
|
||||
@ -6,49 +6,201 @@ project
|
||||
summary
|
||||
-------
|
||||
|
||||
*describe project purpose*
|
||||
This is the controller for a salvaged and modded Bahnsteig Uhr:
|
||||
|
||||
- the track is made of white translucent ceramic, and RGBW LED strips illuminate it
|
||||
- a motor uses the dial drive to turn the dials (in theory with settable time)
|
||||
- LED panels allow to show text on both sides
|
||||
- controllable over the network using Art-Net
|
||||
|
||||
technology
|
||||
----------
|
||||
|
||||
*described electronic details*
|
||||
controller comprises:
|
||||
|
||||
- a [STM32 F4 series micro-controller](https://www.st.com/en/microcontrollers-microprocessors/stm32f4-series.html)-based black pill
|
||||
- a DRV8825 stepper motor allows turning the dials (hour is linked to minute)
|
||||
- reed switch, to home dial
|
||||
- P1 RGB LED panel (128x64), to display text on front side
|
||||
- WS2812b panel (2x 32x8), to display text
|
||||
- nMOS transistors to control 12V LED strips, to illuminate the track
|
||||
- ESP8266-based ESP-01 to connect to network
|
||||
- power connectors (0,5,12V-4pin and 12V-barrel input, 5V outputs for LED panels, 12V for motor and LED strips)
|
||||
|
||||
Art-Net
|
||||
-------
|
||||
|
||||
The Bahn Uhr controller gets data over the network using Art-Net.
|
||||
The mapping is as follows (universe without offset, channel, target).
|
||||
|
||||
clock illumination color (RGBW LED strip):
|
||||
|
||||
- 0, 0, red high byte
|
||||
- 0, 1, red low byte
|
||||
- 0, 2, green high byte
|
||||
- 0, 3, green low byte
|
||||
- 0, 4, blue high byte
|
||||
- 0, 5, blue low byte
|
||||
- 0, 4, white high byte
|
||||
- 0, 5, white low byte
|
||||
|
||||
dials position:
|
||||
|
||||
- 1, 0, hours (0-11)
|
||||
- 1, 1, minutes (0-59)
|
||||
- 1, 2, seconds (0-59)
|
||||
- 1, 3, direction
|
||||
- 1, 4, speed
|
||||
|
||||
text display:
|
||||
|
||||
font display, line 1:
|
||||
|
||||
- 2, 0, red intensity (0 to use clock illumination color)
|
||||
- 2, 1, green intensity (0 to use clock illumination color)
|
||||
- 2, 2, blue intensity (0 to use clock illumination color)
|
||||
- 2, 3, horizontal position (0 is left), high signed byte
|
||||
- 2, 3, horizontal position (0 is left), low byte
|
||||
- 2, 4+, text (NULL ended)
|
||||
|
||||
font display, line 2:
|
||||
|
||||
- 3, 0, red intensity (0 to use clock illumination color)
|
||||
- 3, 1, green intensity (0 to use clock illumination color)
|
||||
- 3, 2, blue intensity (0 to use clock illumination color)
|
||||
- 3, 3, horizontal position (0 is left), high signed byte
|
||||
- 3, 3, horizontal position (0 is left), low byte
|
||||
- 3, 4+, text (NULL ended)
|
||||
|
||||
font display, line 3:
|
||||
|
||||
- 4, 0, red intensity (0 to use clock illumination color)
|
||||
- 4, 1, green intensity (0 to use clock illumination color)
|
||||
- 4, 2, blue intensity (0 to use clock illumination color)
|
||||
- 4, 3, horizontal position (0 is left), high signed byte
|
||||
- 4, 3, horizontal position (0 is left), low byte
|
||||
- 4, 4+, text (NULL ended)
|
||||
|
||||
back display, line 1:
|
||||
|
||||
- 5, 0, red intensity (0 to use clock illumination color)
|
||||
- 5, 1, green intensity (0 to use clock illumination color)
|
||||
- 5, 2, blue intensity (0 to use clock illumination color)
|
||||
- 5, 3, horizontal position (0 is left), high signed byte
|
||||
- 5, 3, horizontal position (0 is left), low byte
|
||||
- 5, 4+, text (NULL ended)
|
||||
|
||||
back display, line 2:
|
||||
|
||||
- 6, 0, red intensity (0 to use clock illumination color)
|
||||
- 6, 1, green intensity (0 to use clock illumination color)
|
||||
- 6, 2, blue intensity (0 to use clock illumination color)
|
||||
- 6, 3, horizontal position (0 is left), high signed byte
|
||||
- 6, 3, horizontal position (0 is left), low byte
|
||||
- 6, 4+, text (NULL ended)
|
||||
|
||||
board
|
||||
=====
|
||||
|
||||
The current implementation uses a [core board](https://wiki.cuvoodoo.info/doku.php?id=stm32f1xx#core_board).
|
||||
|
||||
The underlying template also supports following board:
|
||||
|
||||
- [Maple Mini](http://leaflabs.com/docs/hardware/maple-mini.html), based on a STM32F103CBT6
|
||||
- [System Board](https://wiki.cuvoodoo.info/doku.php?id=stm32f1xx#system_board), based on a STM32F103C8T6
|
||||
- [blue pill](https://wiki.cuvoodoo.info/doku.php?id=stm32f1xx#blue_pill), based on a STM32F103C8T6
|
||||
- [black pill](https://wiki.cuvoodoo.info/doku.php?id=stm32f1xx#black_pill), based on a STM32F103C8T6
|
||||
- [core board](https://wiki.cuvoodoo.info/doku.php?id=stm32f1xx#core_board), based on a STM32F103C8T6
|
||||
- [ST-LINK V2 mini](https://wiki.cuvoodoo.info/doku.php?id=jtag#mini_st-link_v2), a ST-LINK/V2 clone based on a STM32F101C8T6
|
||||
- [USB-Blaster](https://wiki.cuvoodoo.info/doku.php?id=jtag#armjishu_usb-blaster), an Altera USB-Blaster clone based on a STM32F101C8T6
|
||||
|
||||
**Which board is used is defined in the Makefile**.
|
||||
This is required to map the user LED and button provided on the board
|
||||
|
||||
The ST-LINK V2 mini clone has SWD test points on the board.
|
||||
Because read protection is enabled, you will first need to remove the protection to be able to flash the firmware.
|
||||
To remove the read protection (and erase flash), run `rake remove_protection` while a SWD adapter is connected.
|
||||
|
||||
The Altera USB-Blaster clone has a pin header for SWD and UART1 on the board.
|
||||
SWD is disabled in the main firmware, and it has read protection.
|
||||
To be able to flash using SWD (or the serial port), the BOOT0 pin must be set to 1 to boot the system memory install of the flash memory.
|
||||
To set BOOT0 to 1, apply 3.3 V on R11, between the resistor and the reference designator, when powering the device.
|
||||
The red LED should stay off while the green LED is on.
|
||||
Now you can remove the read protection (and erase flash), run `rake remove_protection` while a SWD adapter is connected.
|
||||
- [WeAct MiniF4](https://github.com/WeActTC/MiniF4-STM32F4x1), based on a STM32F401CCU6
|
||||
|
||||
connections
|
||||
===========
|
||||
|
||||
Connect the peripherals the following way (STM32F10X signal; STM32F10X pin; peripheral pin; peripheral signal; comment):
|
||||
Connect the peripherals the following way (STM32F4xx signal; STM32F4xx pin; peripheral pin; peripheral signal; comment):
|
||||
|
||||
- *list board to peripheral pin connections*
|
||||
|
||||
DRV8825 stepper motor driver (using one timer for PWM output):
|
||||
|
||||
- STEP: PA15/TIM2_CH1
|
||||
- DIRECTION: PB15
|
||||
- nSLEEP: PB14, shorted to nRESET
|
||||
- nRESET: PB14, with external 10kOhm pull-down resistor
|
||||
- nENABLE: PB13, with external 10kOhm pull-up resistor
|
||||
- FAULT: PB12, with external 10kOhm pull-up resistor
|
||||
|
||||
reed switch, to home dial position:
|
||||
|
||||
- 1: GND
|
||||
- 2: PB4
|
||||
|
||||
LED driver (using one timer for PWM outputs):
|
||||
|
||||
- gate 0: PB6/TIM4_CH1
|
||||
- gate 1: PB7/TIM4_CH2
|
||||
- gate 2: PB8/TIM4_CH3
|
||||
- gate 3: PB9/TIM4_CH4
|
||||
|
||||
WS2812b LED matrix:
|
||||
|
||||
- DOUT: PB5 (SPI1_MOSI)
|
||||
|
||||
RGB matrix (using one DMA)
|
||||
|
||||
- DR1: PA2
|
||||
- DG1: PA3
|
||||
- DB1: PA4
|
||||
- DR2: PA5
|
||||
- DG2: PA6
|
||||
- DB2: PA7
|
||||
- CLK: PA0
|
||||
- LAT: PA1
|
||||
- A: PB0
|
||||
- B: PB1
|
||||
- C: PB2
|
||||
- D: PB3
|
||||
- OE: PB10
|
||||
|
||||
ESP8266-based ESP-01 (using one UART):
|
||||
|
||||
- RX: PA9/USART1_TX
|
||||
- TX: PA10/USART1_RX
|
||||
|
||||
EN is pulled to VCC using 10 kOhm for the ESP to start.
|
||||
I replaced the 1 MB flash with a 4MB flash to be sure I won't be annoyed by the space limit.
|
||||
I flashed the AT firmware from ESP8266_NONOS_SDK-3.0.5:
|
||||
|
||||
~~~
|
||||
esptool.py --chip auto --port /dev/ttyUSB0 --baud 115200 erase_flash
|
||||
esptool.py -p /dev/ttyUSB0 --chip esp8266 write_flash -fm dio -ff 26m --flash_size 2MB-c1 0x00000 ./bin/boot_v1.7.bin 0x01000 ./bin/at/1024+1024/user1.2048.new.5.bin 0x1fc000 ./bin/esp_init_data_default_v08.bin 0xfe000 ./bin/blank.bin 0x1fe000 ./bin/blank.bin 0x1fb000 ./bin/blank.bin
|
||||
~~~
|
||||
|
||||
to test the firmware, issue AT commands:
|
||||
|
||||
~~~
|
||||
picocom -b 115200 /dev/ttyUSB0 --omap crcrlf
|
||||
AT
|
||||
|
||||
OK
|
||||
|
||||
AT+GMR
|
||||
version information
|
||||
~~~
|
||||
|
||||
configure the access point in flash:
|
||||
|
||||
~~~
|
||||
# set station mode
|
||||
AT+CWMODE_DEF=1
|
||||
# set AP credentials
|
||||
AT+CWJAP_DEF="essid","password"
|
||||
~~~
|
||||
|
||||
free:
|
||||
|
||||
- PB4, PB5
|
||||
- PA8/TIM1_CH1
|
||||
|
||||
used:
|
||||
|
||||
- PA12: USB DP
|
||||
- PA11: USB DM
|
||||
- PC13: LED
|
||||
- PC14/PC15: 32kHz XTAL
|
||||
|
||||
All pins are configured using `define`s in the corresponding source code.
|
||||
|
||||
code
|
||||
@ -81,15 +233,20 @@ The `bootloader` is started first and immediately jumps to the `application` if
|
||||
The `application` image is the main application and is implemented in `application.c`.
|
||||
It is up to the application to advertise USB DFU support (i.e. as does the provided USB CDC ACM example).
|
||||
|
||||
The `bootloader` image will be flashed using SWD (Serial Wire Debug).
|
||||
The simplest way do flash the `bootloader` image is using the embedded bootloader.
|
||||
By pressing the BOOT0 button (setting the pin low) while powering or resetting the device, the micro-controller boot its embedded UART/USB DFU bootloader.
|
||||
Connect a USB cable and run `rake dfu_bootloader`.
|
||||
|
||||
Once the `bootloader` is flashed, it is possible to flash the `application` over USB using the DFU protocol by running `rake flash` (equivalent to `rake dfu_application`.
|
||||
To force the bootloader to start the DFU mode press the user button or short a pin, depending on the board.
|
||||
Note: I use my own DFU bootloader instead of the embedded bootloader because I was not able to start the embedded USB DFU bootloader from the application.
|
||||
|
||||
The images can also be flash using SWD (Serial Wire Debug) in case the firmware gets stuck and does not provide USB functionalities.
|
||||
For that you need an SWD adapter.
|
||||
The `Makefile` uses a ST-Link V2 programmer along OpenOCD software (default), or Black Magic Probe.
|
||||
To flash the `booltoader` using SWD run `rake flash_booloader`.
|
||||
If the development board uses the CKS32 chip STM32 alternative, use `CPUTAPID=0x2ba01477 rake flash_booloader`.
|
||||
|
||||
Once the `bootloader` is flashed it is possible to flash the `application` over USB using the DFU protocol by running `rake flash`.
|
||||
To force the bootloader to start the DFU mode press the user button or short a pin, depending on the board.
|
||||
It is also possible to flash the `application` image using SWD by running `rake flash_application`.
|
||||
To flash the `bootloader` using SWD run `rake swd_bootloader` (this will also erase the application).
|
||||
To flash the `application` using SWD run `rake swd_application` (or `rake swd`).
|
||||
To erase all memory and unlock read/write protection, run `rake remove_protection`.
|
||||
|
||||
debug
|
||||
-----
|
||||
|
96
Rakefile
96
Rakefile
@ -1,8 +1,8 @@
|
||||
# encoding: utf-8
|
||||
# ruby: 2.4.2
|
||||
=begin
|
||||
Rakefile to manage compile CuVoodoo STM32F1 firmware.
|
||||
the firmware is for development board based around a STM32F1xx micro-controller.
|
||||
Rakefile to manage compiling CuVoodoo STM32F4 firmware.
|
||||
the firmware is for development boards based around a STM32F4xx micro-controller.
|
||||
the firmware uses the libopencm3 library providing support for this micro-controller.
|
||||
=end
|
||||
require 'rake'
|
||||
@ -14,15 +14,27 @@ APPLICATION = "application"
|
||||
FIRMWARES = [BOOTLOADER, APPLICATION]
|
||||
|
||||
# which development board is used
|
||||
# supported are: SYSTEM_BOARD, MAPLE_MINI, BLUE_PILL, BLACK_PILL, CORE_BOARD, STLINKV2, BLASTER, BUSVOODOO
|
||||
BOARD = ENV["BOARD"] || "BLUE_PILL"
|
||||
# supported are: WeAct MiniF4 with STM32F401
|
||||
BOARD = ENV["BOARD"] || "MINIF401"
|
||||
# get MCU from board
|
||||
DEVICE = case BOARD
|
||||
when "MINIF401"
|
||||
# the genuine MINIF401 with stm32f401cc is discontinued and has been replaced with stm32f401ce (just more RAM/flash), but knockoffs with stm32f401cc are still common
|
||||
"stm32f401cc"
|
||||
else
|
||||
raise "unknown MCU for board #{BOARD}"
|
||||
end
|
||||
|
||||
# libopencm3 definitions
|
||||
LIBOPENCM3_DIR = "libopencm3"
|
||||
LIBOPENCM3_INC = LIBOPENCM3_DIR+"/include"
|
||||
LIBOPENCM3_LIB = LIBOPENCM3_DIR+"/lib"
|
||||
# STM32F1 library used for this project provided by libopencm3
|
||||
STM32F1_LIB = "opencm3_stm32f1"
|
||||
LIBOPENCM3_LIBS = LIBOPENCM3_DIR+"/lib"
|
||||
# get libopencm3
|
||||
unless File.file?("./#{LIBOPENCM3_DIR}/scripts/genlink.py") then
|
||||
sh "git submodule init"
|
||||
sh "git submodule update"
|
||||
end
|
||||
LIBOPENCM3_LIB = "opencm3_" + `./#{LIBOPENCM3_DIR}/scripts/genlink.py #{LIBOPENCM3_DIR}/ld/devices.data #{DEVICE} FAMILY`
|
||||
|
||||
# source code used by the firmware
|
||||
SRC_DIRS = [".", "lib"]
|
||||
@ -43,7 +55,7 @@ cflags = [ENV["CFLAGS"]]
|
||||
# optimize for size
|
||||
cflags << "-Os"
|
||||
# add debug symbols (remove for smaller release)
|
||||
cflags << "-ggdb"
|
||||
cflags << "-ggdb3"
|
||||
# use C99 (supported by most an sufficient)
|
||||
cflags << "-std=c99"
|
||||
# have strict warning (for better code)
|
||||
@ -59,7 +71,8 @@ cflags += SRC_DIRS.collect {|srd_dir| "-I #{srd_dir}"}
|
||||
# include libopencm3 library
|
||||
cflags << "-I #{LIBOPENCM3_INC}"
|
||||
# add defines for micro-controller and board
|
||||
cflags << "-DSTM32F1 -D#{BOARD}"
|
||||
cflags << "-D#{BOARD}"
|
||||
cflags << `./#{LIBOPENCM3_DIR}/scripts/genlink.py #{LIBOPENCM3_DIR}/ld/devices.data #{DEVICE} CPPFLAGS`
|
||||
# render cflags
|
||||
cflags = cflags.compact*' '
|
||||
|
||||
@ -76,14 +89,17 @@ ldflags_linker = ["--gc-sections"]
|
||||
# show memory usage
|
||||
ldflags_linker << "--print-memory-usage"
|
||||
# add libopencm3 libraries
|
||||
library_paths = [LIBOPENCM3_LIB]
|
||||
library_paths = [LIBOPENCM3_LIBS]
|
||||
# project libraries
|
||||
ldlibs = [STM32F1_LIB]
|
||||
ldlibs = [LIBOPENCM3_LIB]
|
||||
# general libraries (gcc provides the ARM ABI)
|
||||
ldlibs_linker = ["m", "c", "nosys", "gcc"]
|
||||
|
||||
# target micro-controller information (ARM Cortex-M3 supports thumb and thumb2, but does not include a floating point unit)
|
||||
archflags = "-mthumb -mcpu=cortex-m3 -msoft-float"
|
||||
# target micro-controller information (ARM Cortex-M4 supports thumb and thumb2, but does not include a floating point unit)
|
||||
archflags = "-mthumb"
|
||||
archflags += " -mcpu=" + `./#{LIBOPENCM3_DIR}/scripts/genlink.py #{LIBOPENCM3_DIR}/ld/devices.data #{DEVICE} CPU`
|
||||
archflags += " -mfloat-abi=" + `./#{LIBOPENCM3_DIR}/scripts/genlink.py #{LIBOPENCM3_DIR}/ld/devices.data #{DEVICE} FPU`.split("-")[0]
|
||||
archflags += " -mfpu=" + `./#{LIBOPENCM3_DIR}/scripts/genlink.py #{LIBOPENCM3_DIR}/ld/devices.data #{DEVICE} FPU`.split("-")[1..-1]*"-"
|
||||
|
||||
desc "compile firmwares"
|
||||
task :default => FIRMWARES
|
||||
@ -101,17 +117,17 @@ end
|
||||
|
||||
# get dependencies of a file
|
||||
# done is a list of already known dependencies
|
||||
def dependencies(source, done=[])
|
||||
def dependencies(source, done = [])
|
||||
d_path = source.ext("d") # get the dependency file
|
||||
Rake::Task[d_path].invoke # ensure the dependency file exists
|
||||
d_file = IO.read(d_path) # read the dependencies from dependency file
|
||||
d_file = d_file.split(': ')[1].gsub("\n",'').gsub('\\ ','').gsub(/\s+/,' ').split(' ') # get a list of dependencies
|
||||
d_file = d_file.split(': ')[1].gsub("\n", '').gsub('\\ ', '').gsub(/\s+/, ' ').split(' ') # get a list of dependencies
|
||||
d_list = [] # list of dependencies
|
||||
# only save dependencies which are in our source directories
|
||||
d_file.each do |d|
|
||||
SRC_DIRS.each do |dir|
|
||||
if File.dirname(d)==dir then
|
||||
d_list << d
|
||||
if File.dirname(d) == dir then
|
||||
d_list << d unless d.end_with?(".inc")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -127,14 +143,8 @@ def dependencies(source, done=[])
|
||||
return done
|
||||
end
|
||||
|
||||
desc "get libopencm3"
|
||||
file LIBOPENCM3_DIR+"/Makefile" do
|
||||
sh "git submodule init"
|
||||
sh "git submodule update"
|
||||
end
|
||||
|
||||
desc "compile libopencm3"
|
||||
file "#{LIBOPENCM3_LIB}/lib#{STM32F1_LIB}.a" => LIBOPENCM3_DIR+"/Makefile" do
|
||||
file "#{LIBOPENCM3_LIBS}/lib#{LIBOPENCM3_LIB}.a" do
|
||||
sh "make --directory #{LIBOPENCM3_DIR}"
|
||||
end
|
||||
|
||||
@ -143,17 +153,17 @@ task :doc => ["Doxyfile", "README.md"] do |t|
|
||||
end
|
||||
|
||||
desc "compile source into object"
|
||||
rule '.o' => ['.c', proc{|f| File.file?(f.ext("h")) ? f.ext("h") : []}, proc{|f| dependencies(f).collect{|d| File.file?(d.ext("h")) ? d.ext("h") : []}}, "#{LIBOPENCM3_LIB}/lib#{STM32F1_LIB}.a"] do |t|
|
||||
rule '.o' => ['.c', proc{|f| File.file?(f.ext("h")) ? f.ext("h") : []}, proc{|f| dependencies(f).collect{|d| File.file?(d.ext("h")) ? d.ext("h") : []}}, "#{LIBOPENCM3_LIBS}/lib#{LIBOPENCM3_LIB}.a"] do |t|
|
||||
sh "#{CC} #{cflags} #{archflags} -o #{t.name} -c #{t.prerequisites[0]}"
|
||||
end
|
||||
|
||||
desc "generate dependencies"
|
||||
rule '.d' => ['.c', "#{LIBOPENCM3_LIB}/lib#{STM32F1_LIB}.a"] do |t|
|
||||
rule '.d' => ['.c', "#{LIBOPENCM3_LIBS}/lib#{LIBOPENCM3_LIB}.a"] do |t|
|
||||
sh "#{CC} #{cflags} #{archflags} -MM -MF #{t.name} -c #{t.prerequisites[0]}"
|
||||
end
|
||||
|
||||
desc "link binary"
|
||||
rule '.elf' => ['.o', proc{|f| dependencies(f)}, '.ld', "#{LIBOPENCM3_LIB}/lib#{STM32F1_LIB}.a"] do |t|
|
||||
rule '.elf' => ['.o', proc{|f| dependencies(f)}, '.ld', "#{LIBOPENCM3_LIBS}/lib#{LIBOPENCM3_LIB}.a"] do |t|
|
||||
sh "#{LD} #{archflags} #{ldflags.join(' ')} #{t.prerequisites[0..-3].join(' ')} -T#{t.name.ext('ld')} #{ldflags_linker.collect{|flag| "-Wl,"+flag}.join(' ')} #{library_paths.collect{|path| "-L"+path}.join(' ')} #{ldlibs.collect{|lib| "-l"+lib}.join(' ')} -Wl,--start-group #{ldlibs_linker.collect{|lib| "-l"+lib}.join(' ')} -Wl,--end-group --output #{t.name}"
|
||||
end
|
||||
|
||||
@ -190,42 +200,50 @@ OOCD = ENV["OOCD"] || "openocd"
|
||||
# openOCD adapted name
|
||||
OOCD_INTERFACE = ENV["OOCD_INTERFACE"] || (SWD_ADAPTER=="STLINKV2" ? "stlink" : "")
|
||||
# openOCD target for the micro-controller
|
||||
OOCD_TARGET = "stm32f1x"
|
||||
OOCD_TARGET = "stm32f4x"
|
||||
# Black Magic Probe port
|
||||
BMP_PORT = ENV["BMP_PORT"] || "/dev/ttyACM0"
|
||||
# set CPUTAPID (0x1ba01477 for STM32, 0x2ba01477 for CKS32/APM32)
|
||||
CPUTAPID = ENV["CPUTAPID"] || "0x1ba01477"
|
||||
|
||||
desc "flash application"
|
||||
task :flash => :dfu_application
|
||||
|
||||
desc "flash application using USB DFU"
|
||||
task :flash => APPLICATION+".bin" do |t|
|
||||
task :dfu_application => APPLICATION+".bin" do |t|
|
||||
sh "dfu-util --device 1209:4356 --download #{t.source}"
|
||||
end
|
||||
|
||||
desc "remove STM32F1 protection using SWD"
|
||||
desc "flash application using USB DFU"
|
||||
task :dfu_bootloader => BOOTLOADER+".bin" do |t|
|
||||
sh "dfu-util --device 0483:df11 --cfg 1 --intf 0 --alt 0 --dfuse-address 0x08000000 --download #{t.source} --reset"
|
||||
end
|
||||
|
||||
desc "remove STM32F4 protection using SWD"
|
||||
task :remove_protection do
|
||||
case SWD_ADAPTER
|
||||
when "STLINKV2"
|
||||
sh "#{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --command 'transport select hla_swd' --command 'set CPUTAPID #{CPUTAPID}' --file target/#{OOCD_TARGET}.cfg --command 'init' --command 'halt' --command 'reset init' --command 'stm32f1x unlock 0' --command 'reset init' --command 'flash protect 0 0 last off' --command 'reset init' --command 'stm32f1x options_write 0 SWWDG NORSTSTNDBY NORSTSTOP' --command 'reset init' --command 'stm32f1x mass_erase 0' --command 'shutdown'"
|
||||
sh "#{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --command 'transport select hla_swd' --file target/#{OOCD_TARGET}.cfg --command 'init' --command 'halt' --command 'reset init' --command 'stm32f2x unlock 0' --command 'reset init' --command 'flash protect 0 0 last off' --command 'reset init' --command 'stm32f2x mass_erase 0' --command 'shutdown'"
|
||||
when "BMP"
|
||||
sh "#{GDB} --eval-command='target extended-remote #{BMP_PORT}' --eval-command='set confirm off' --eval-command='monitor swdp_scan' --eval-command='attach 1' --eval-command='monitor option erase' --eval-command='monitor erase_mass' --eval-command='kill' --eval-command='quit'"
|
||||
end
|
||||
end
|
||||
|
||||
desc "flash bootloader using SWD"
|
||||
task :flash_bootloader => BOOTLOADER+".hex" do |t|
|
||||
task :swd_bootloader => BOOTLOADER+".hex" do |t|
|
||||
case SWD_ADAPTER
|
||||
when "STLINKV2"
|
||||
sh "#{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --command 'transport select hla_swd' --command 'set CPUTAPID #{CPUTAPID}' --file target/#{OOCD_TARGET}.cfg --command 'init' --command 'halt' --command 'reset init' --command 'flash erase_sector 0 0 last' --command 'flash write_image erase #{t.source}' --command 'reset' --command 'shutdown'"
|
||||
sh "#{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --command 'transport select hla_swd' --file target/#{OOCD_TARGET}.cfg --command 'init' --command 'halt' --command 'reset init' --command 'flash erase_sector 0 0 last' --command 'flash write_image erase #{t.source}' --command 'reset' --command 'shutdown'"
|
||||
when "BMP"
|
||||
sh "#{GDB} --eval-command='target extended-remote #{BMP_PORT}' --eval-command='set confirm off' --eval-command='monitor swdp_scan' --eval-command='attach 1' --eval-command='monitor erase_mass' --eval-command='load' --eval-command='kill' --eval-command='quit' #{t.source}"
|
||||
end
|
||||
end
|
||||
|
||||
task :swd => :swd_application
|
||||
|
||||
desc "flash application using SWD"
|
||||
task :flash_application => APPLICATION+".hex" do |t|
|
||||
task :swd_application => APPLICATION+".hex" do |t|
|
||||
case SWD_ADAPTER
|
||||
when "STLINKV2"
|
||||
sh "#{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --command 'transport select hla_swd' --command 'set CPUTAPID #{CPUTAPID}' --file target/#{OOCD_TARGET}.cfg --command 'adapter speed 100' --command 'init' --command 'halt' --command 'reset init' --command 'flash write_image erase #{t.source}' --command 'reset' --command 'shutdown'"
|
||||
sh "#{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --command 'transport select hla_swd' --file target/#{OOCD_TARGET}.cfg --command 'adapter speed 100' --command 'init' --command 'halt' --command 'reset init' --command 'flash write_image erase #{t.source}' --command 'reset' --command 'shutdown'"
|
||||
when "BMP"
|
||||
sh "#{GDB} --eval-command='target extended-remote #{BMP_PORT}' --eval-command='set confirm off' --eval-command='monitor swdp_scan' --eval-command='attach 1' --eval-command='load' --eval-command='kill' --eval-command='quit' #{t.source}"
|
||||
end
|
||||
@ -237,7 +255,7 @@ task :debug => APPLICATION+".elf" do |t|
|
||||
case SWD_ADAPTER
|
||||
when "STLINKV2"
|
||||
# for GDB to work with openOCD the firmware needs to be reloaded
|
||||
exec("#{GDB} --eval-command='target remote | #{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --command \"transport select hla_swd\" --command \"set CPUTAPID #{CPUTAPID}\" --file target/#{OOCD_TARGET}.cfg --command \"gdb_port pipe; log_output /dev/null; init\"' #{t.source}")
|
||||
exec("#{GDB} --eval-command='target remote | #{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --command \"transport select hla_swd\" --file target/#{OOCD_TARGET}.cfg --command \"gdb_port pipe; log_output /dev/null; init\"' #{t.source}")
|
||||
when "BMP"
|
||||
exec("#{GDB} --eval-command='target extended-remote #{BMP_PORT}' --eval-command='monitor version' --eval-command='monitor swdp_scan' --eval-command='attach 1' #{t.source}")
|
||||
end
|
||||
@ -249,7 +267,7 @@ task :debug_bootloader => BOOTLOADER+".elf" do |t|
|
||||
case SWD_ADAPTER
|
||||
when "STLINKV2"
|
||||
# for GDB to work with openOCD the firmware needs to be reloaded
|
||||
exec("#{GDB} --eval-command='target remote | #{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --command \"transport select hla_swd\" --command \"set CPUTAPID #{CPUTAPID}\" --file target/#{OOCD_TARGET}.cfg --command \"gdb_port pipe; log_output /dev/null; init\"' --eval-command='monitor reset init' #{t.source}")
|
||||
exec("#{GDB} --eval-command='target remote | #{OOCD} --file interface/#{OOCD_INTERFACE}.cfg --command \"transport select hla_swd\" --file target/#{OOCD_TARGET}.cfg --command \"gdb_port pipe; log_output /dev/null; init\"' --eval-command='monitor reset init' #{t.source}")
|
||||
when "BMP"
|
||||
exec("#{GDB} --eval-command='target extended-remote #{BMP_PORT}' --eval-command='monitor version' --eval-command='monitor swdp_scan' --eval-command='attach 1' #{t.source}")
|
||||
end
|
||||
|
1212
application.c
1212
application.c
File diff suppressed because it is too large
Load Diff
@ -1,30 +1,18 @@
|
||||
/* linker script for application running on STM32F103x8 micro-controller
|
||||
* the STM32F103x8 has 64 KB of flash starting at 0x0800 0000, and 20 KB of RAM starting at 0x2000 0000
|
||||
* the STM32F103xB has 128 KB of flash starting at 0x0800 0000, and 20 KB of RAM starting at 0x2000 0000
|
||||
* STM32F103x8 most often have if fact 128 KB, instead of the specified and advertised 64 KB, like the STM32F103xB
|
||||
* you can define the desired flash size here.
|
||||
* the USB DFU bootloader will take the first 8 KB of flash, followed by the application
|
||||
* the first 4 bytes of the RAM is reserved for the DFU magic word (DFU! to start DFU bootloader)
|
||||
/* linker script for application running on STM32F401xC micro-controller
|
||||
* the STM32F401xC has 256 KB of flash starting at 0x0800 0000, and 64 KB of RAM starting at 0x2000 0000
|
||||
* the USB DFU bootloader will use the first sector, which is 16 KB large.
|
||||
* this is followed by the application.
|
||||
* the first 4 bytes of the RAM are reserved for the DFU magic word (DFU! to start DFU bootloader)
|
||||
*/
|
||||
|
||||
/* define memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
rom (rx) : ORIGIN = 0x08000000 + 8K, LENGTH = 64K - 8K
|
||||
ram (rwx) : ORIGIN = 0x20000000 + 4, LENGTH = 20K - 4
|
||||
rom (rx) : ORIGIN = 0x08000000 + 16K, LENGTH = 256K - 16K
|
||||
ram (rwx) : ORIGIN = 0x20000000 + 4, LENGTH = 64K - 4
|
||||
}
|
||||
PROVIDE(__application_beginning = ORIGIN(rom));
|
||||
/* if you want the firmware to use the flash size advertised by the micro-controller itself, use the following:
|
||||
PROVIDE(__application_end = 0);
|
||||
PROVIDE(__flash_end = 0);
|
||||
if you want to enforce a flash size, because there is more flash than advertized by the micro-controller, use to following:
|
||||
PROVIDE(__application_end = ORIGIN(rom) + LENGTH(rom));
|
||||
PROVIDE(__flash_end = ORIGIN(rom) + LENGTH(rom));
|
||||
*/
|
||||
PROVIDE(__application_end = 0);
|
||||
PROVIDE(__flash_end = 0);
|
||||
/* RAM location reserved so application can talk to bootloader and tell to start DFU */
|
||||
PROVIDE(__dfu_magic = ORIGIN(ram) - 4);
|
||||
|
||||
/* include rest of the definitions for the ARM Cortex-M, including STM32F1 family */
|
||||
/* include rest of the definitions for the ARM Cortex-M, including STM32F4 family */
|
||||
INCLUDE cortex-m-generic.ld
|
||||
|
44
bootloader.c
44
bootloader.c
@ -2,7 +2,7 @@
|
||||
* @file
|
||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @copyright SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @date 2017-2019
|
||||
* @date 2017-2020
|
||||
*/
|
||||
/* standard libraries */
|
||||
#include <stdint.h> // standard integer types
|
||||
@ -17,6 +17,11 @@
|
||||
#include "global.h" // board definitions
|
||||
#include "usb_dfu.h" // USB DFU utilities
|
||||
|
||||
/** symbol for beginning of the application
|
||||
* @note this symbol will be provided by the bootloader linker script
|
||||
*/
|
||||
extern uint32_t __application_beginning;
|
||||
|
||||
/** bootloader entry point */
|
||||
void main(void);
|
||||
void main(void)
|
||||
@ -31,64 +36,41 @@ void main(void)
|
||||
__dfu_magic[1] = 0;
|
||||
__dfu_magic[2] = 0;
|
||||
__dfu_magic[3] = 0;
|
||||
} else if (0 == (RCC_CSR & 0xfc000000)) { // no reset flag present -> this was a soft reset using scb_reset_core() after clearing the flags using RCC_CSR_RMVF, this was the legacy way to start the DFU mode
|
||||
dfu_force = true;
|
||||
} else { // check if the force DFU mode input is set
|
||||
// disable SWJ pin to use as GPIO
|
||||
#if (defined(DFU_FORCE_PIN) && defined(DFU_FORCE_VALUE))
|
||||
#if ((GPIO(B) == GPIO_PORT(DFU_FORCE_PIN)) && (GPIO(4) == GPIO_PIN(DFU_FORCE_PIN)))
|
||||
// JNTRST pin is used as DFU pin
|
||||
rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function domain
|
||||
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST, 0); // keep SWJ enable bit don't use JNTRST
|
||||
#elif ((GPIO(B) == GPIO_PORT(DFU_FORCE_PIN)) && (GPIO(3) == GPIO_PIN(DFU_FORCE_PIN))) || ((GPIO(A) == GPIO_PORT(DFU_FORCE_PIN)) && (GPIO(15) == GPIO_PIN(DFU_FORCE_PIN)))
|
||||
// JTAG but not SWD pin used as DFU pin
|
||||
rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function domain
|
||||
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, 0); // disable JTAG but keep SWD
|
||||
#elif ((GPIO(A) == GPIO_PORT(DFU_FORCE_PIN)) && (GPIO(14) == GPIO_PIN(DFU_FORCE_PIN))) || ((GPIO(A) == GPIO_PORT(DFU_FORCE_PIN)) && (GPIO(13) == GPIO_PIN(DFU_FORCE_PIN)))
|
||||
// JTAG and SWD pin used as DFU pin
|
||||
rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function domain
|
||||
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF, 0); // disable JTAG and SWD
|
||||
#endif // DFU_FORCE_PIN
|
||||
rcc_periph_clock_enable(GPIO_RCC(DFU_FORCE_PIN)); // enable clock for GPIO domain
|
||||
gpio_set_mode(GPIO_PORT(DFU_FORCE_PIN), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_PIN(DFU_FORCE_PIN)); // set GPIO to input
|
||||
// pull on the opposite of the expected value
|
||||
rcc_periph_clock_enable(GPIO_RCC(DFU_FORCE_PIN)); // enable clock for button
|
||||
#if (DFU_FORCE_VALUE == 1)
|
||||
gpio_clear(GPIO_PORT(DFU_FORCE_PIN), GPIO_PIN(DFU_FORCE_PIN)); // pull down to be able to detect when tied to high
|
||||
gpio_mode_setup(GPIO_PORT(DFU_FORCE_PIN), GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN(DFU_FORCE_PIN)); // set GPIO to input
|
||||
if (gpio_get(GPIO_PORT(DFU_FORCE_PIN), GPIO_PIN(DFU_FORCE_PIN))) { // check if output is set to the value to force DFU mode
|
||||
#else
|
||||
gpio_set(GPIO_PORT(DFU_FORCE_PIN), GPIO_PIN(DFU_FORCE_PIN)); // pull up to be able to detect when tied to low
|
||||
gpio_mode_setup(GPIO_PORT(DFU_FORCE_PIN), GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN(DFU_FORCE_PIN)); // set GPIO to input
|
||||
if (0 == gpio_get(GPIO_PORT(DFU_FORCE_PIN), GPIO_PIN(DFU_FORCE_PIN))) { // check if output is set to the value to force DFU mode
|
||||
#endif // DFU_FORCE_VALUE
|
||||
dfu_force = true; // DFU mode forced
|
||||
}
|
||||
#endif // defined(DFU_FORCE_PIN)
|
||||
rcc_periph_clock_disable(RCC_AFIO); // disable alternate function domain to put it back to default
|
||||
rcc_periph_reset_pulse(GPIO_RST(DFU_FORCE_PIN)); // reset pin GPIO domain
|
||||
rcc_periph_clock_disable(GPIO_RCC(DFU_FORCE_PIN)); // disable pin GPIO domain
|
||||
#endif // defined(DFU_FORCE_PIN)
|
||||
}
|
||||
|
||||
// start application if valid
|
||||
/* the application starts with the vector table
|
||||
* the first entry in the vector table is the initial stack pointer (SP) address
|
||||
* the stack will be placed in RAM
|
||||
* on STM32F1xx SRAM begins at 0x2000 0000, and on STM32F103xx there is up to 96 KB of RAM (0x18000).
|
||||
* since the stack grown "downwards" it should start at the end of the RAM: max 0x2001 8000
|
||||
* on STM32F4 SRAM begins at 0x2000 0000, and on STM32F4xx there is up to 384 KiB of RAM (0x60000).
|
||||
* since the stack grown "downwards" it should start at the end of the RAM: max 0x2006 0000
|
||||
* if the SP is not in this range (e.g. flash has been erased) there is no valid application
|
||||
* the second entry in the vector table is the reset address, corresponding to the application start
|
||||
*/
|
||||
volatile uint32_t* application = (uint32_t*)&__application_beginning; // get the value of the application address symbol (use a register instead on the stack since the stack pointer will be changed)
|
||||
if (!dfu_force && (((*application) & 0xFFFE0000) == 0x20000000)) { // application at address seems valid
|
||||
if (!dfu_force && (((*application) & 0xFFF80000) == 0x20000000)) { // application at address seems valid
|
||||
SCB_VTOR = (volatile uint32_t)(application); // set vector table to application vector table (store at the beginning of the application)
|
||||
__asm__ volatile ("MSR msp,%0" : :"r"(*application)); // set stack pointer to address provided in the beginning of the application (loaded into a register first)
|
||||
(*(void(**)(void))((uint32_t)application + 4))(); // start application (by jumping to the reset function which address is stored as second entry of the vector table)
|
||||
}
|
||||
|
||||
rcc_clock_setup_in_hse_8mhz_out_72mhz(); // start main clock
|
||||
board_setup(); // setup board to control LED
|
||||
led_on(); // indicate bootloader started
|
||||
#if defined(BUSVOODOO)
|
||||
led_toggle(); // switch from blue to red LED
|
||||
#endif
|
||||
usb_dfu_setup(); // setup USB DFU for firmware upload
|
||||
usb_dfu_start(); // run DFU mode
|
||||
}
|
||||
|
@ -1,30 +1,20 @@
|
||||
/* linker script for application running on STM32F103x8 micro-controller
|
||||
* the STM32F103x8 has 64 KB of flash starting at 0x0800 0000, and 20 KB of RAM starting at 0x2000 0000
|
||||
* the STM32F103xB has 128 KB of flash starting at 0x0800 0000, and 20 KB of RAM starting at 0x2000 0000
|
||||
* STM32F103x8 most often have if fact 128 KB, instead of the specified and advertised 64 KB, like the STM32F103xB
|
||||
* you can define the desired flash size here.
|
||||
* the USB DFU bootloader will take the first 8 KB of flash, followed by the application
|
||||
* the first 4 bytes of the RAM is reserved for the DFU magic word (DFU! to start DFU bootloader)
|
||||
/* linker script for application running on STM32F401xC micro-controller
|
||||
* the STM32F401xC has 256 KB of flash starting at 0x0800 0000, and 64 KB of RAM starting at 0x2000 0000
|
||||
* the USB DFU bootloader will use the first sector, which is 16 KB large.
|
||||
* this is followed by the application.
|
||||
* the first 4 bytes of the RAM are reserved for the DFU magic word (DFU! to start DFU bootloader)
|
||||
*/
|
||||
|
||||
/* define memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 8K
|
||||
ram (rwx) : ORIGIN = 0x20000000 + 4, LENGTH = 20K - 4
|
||||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||
ram (rwx) : ORIGIN = 0x20000000 + 4, LENGTH = 64K - 4
|
||||
}
|
||||
/* where the main application starts */
|
||||
PROVIDE(__application_beginning = ORIGIN(rom) + LENGTH(rom));
|
||||
/* if you want the firmware to use the flash size advertised by the micro-controller itself, use the following:
|
||||
PROVIDE(__application_end = 0);
|
||||
PROVIDE(__flash_end = 0);
|
||||
if you want to enforce a flash size, because there is more flash than advertized by the micro-controller, use to following:
|
||||
PROVIDE(__application_end = ORIGIN(rom) + LENGTH(rom));
|
||||
PROVIDE(__flash_end = ORIGIN(rom) + LENGTH(rom));
|
||||
*/
|
||||
PROVIDE(__application_end = 0);
|
||||
PROVIDE(__flash_end = 0);
|
||||
/* RAM location reserved so application can talk to bootloader and tell to start DFU */
|
||||
PROVIDE(__dfu_magic = ORIGIN(ram) - 4);
|
||||
|
||||
/* include rest of the definitions for the ARM Cortex-M, including STM32F1 family */
|
||||
/* include rest of the definitions for the ARM Cortex-M, including STM32F4 family */
|
||||
INCLUDE cortex-m-generic.ld
|
||||
|
110
global.c
110
global.c
@ -16,6 +16,8 @@
|
||||
#include <libopencm3/stm32/rcc.h> // real-time control clock library
|
||||
#include <libopencm3/stm32/gpio.h> // general purpose input output library
|
||||
#include <libopencm3/stm32/exti.h> // external interrupt defines
|
||||
#include <libopencm3/stm32/syscfg.h> // system definitions
|
||||
#include <libopencm3/usb/dwc/otg_fs.h> // USB OTG utilities
|
||||
|
||||
#include "global.h" // common methods
|
||||
|
||||
@ -132,9 +134,6 @@ char* b2s(uint64_t binary, uint8_t rjust)
|
||||
inline void led_on(void)
|
||||