Compare commits

...

172 Commits

Author SHA1 Message Date
7854328a55 doc: add brief project description 2022-08-11 14:42:40 +02:00
90ec47d49a app: adjust project name welcome text 2022-08-11 14:42:15 +02:00
776569d7c1 doc: add artnet commands 2022-08-11 14:23:40 +02:00
f7e0d514dc app: fix artnet text display 2022-08-11 14:23:12 +02:00
7f06533fe7 app: add artnet command to set motor speed 2022-08-11 14:22:56 +02:00
dd09112a22 app: minor, remove artnet debug 2022-08-11 14:22:34 +02:00
dcd41db126 app: add code to debug reed trigger 2022-08-11 14:22:08 +02:00
63f7f0ece5 app: set default text displayed 2022-08-11 14:21:45 +02:00
938e2467a4 app: disable homing since reed switch code is buggy 2022-08-11 14:21:19 +02:00
aa1d7b1dde app: minor, fix dial action 2022-08-11 14:20:37 +02:00
bbc981fecb app: verify if ESP is connected 2022-08-11 14:20:12 +02:00
78bc3b97f3 app: fix motor speed 2022-08-11 14:19:23 +02:00
3f18fef34c app: clear pixels between characters 2022-08-11 14:17:56 +02:00
86fa08cb91 app: minor, increase WS2812 matrix brightness 2022-08-11 14:17:19 +02:00
886965ee80 app: minor, add flag to debug reed switch 2022-08-11 14:16:48 +02:00
f335044c77 app: minor, enable watchdog 2022-08-11 14:15:47 +02:00
af7477d971 app: allow setting matrix colors 2022-08-11 14:14:54 +02:00
b7670d1e24 app: minor, calibrate dial steps 2022-08-11 14:13:24 +02:00
55ac60e080 app: fix motor speed and direction 2022-08-11 14:11:13 +02:00
8d6d7f315f app: increase watchdog timeout to allow connecting to network 2022-08-11 14:08:54 +02:00
1d118ced08 esp8266: fix listen in case port is already opened 2022-08-11 14:07:10 +02:00
da57f5ee40 esp8266: add connected function 2022-08-11 14:06:39 +02:00
ac7b075b1c esp8266: add reset function 2022-08-11 14:06:22 +02:00
cfc6c509b7 esp8266: add simple at command function 2022-08-11 14:05:22 +02:00
ad1aa69180 esp8266: allow reading received data 2022-08-11 14:03:15 +02:00
ae394561e2 app: make rgb panel optional 2022-07-27 10:52:39 +02:00
851c25ffe0 app: add dials command 2022-07-27 10:41:36 +02:00
0e92b46c3e app: use offloaded RGB panel library 2022-07-27 10:40:36 +02:00
3f00d36f05 lib: put all RGB panel code in seperate library 2022-07-27 10:39:23 +02:00
b0ab623968 app: parse art-net packets 2022-07-27 10:06:53 +02:00
571038023c usb: adjust product name 2022-07-27 10:04:45 +02:00
b7da249c51 app: add dial target mechanism 2022-07-25 15:42:36 +02:00
8bfccb86a0 app: minor, make line select more secure 2022-07-25 15:41:51 +02:00
9d415ed449 app: remove ununsed code 2022-07-25 15:41:16 +02:00
85fdb1bbac app: fix dial homing 2022-07-25 15:40:56 +02:00
2dd6e09cd0 doc: describe reed switch 2022-07-25 15:39:47 +02:00
9af8516030 app: add test for WS2812b panel 2022-07-21 21:24:54 +02:00
479a1316c3 app: reuse matrix control for WS2812b 2022-07-21 21:24:13 +02:00
3cd3a869f4 ws2812b: set number of LEDs 2022-07-21 21:21:44 +02:00
3c4cabb483 doc: add pinouts and ESP config 2022-07-14 19:01:40 +02:00
32aa557a00 app: add Art-Net receiver 2022-07-14 19:00:46 +02:00
af9d0d685a app: add WS2812B 2022-07-14 19:00:02 +02:00
02f95f55ee app: remove USART printing 2022-07-14 18:58:23 +02:00
24cec3850d esp8266: make received data available 2022-07-14 18:56:56 +02:00
462a65cb92 esp8266: add listening to port 2022-07-14 18:56:36 +02:00
a8b7726c35 esp8266: minor, fix spacing 2022-07-14 18:56:04 +02:00
90dbc57166 lib: port ESP8266 to STM32F4 2022-07-14 18:54:06 +02:00
62650bd1b2 lib: port WS2812B to STM32F4 2022-07-14 14:59:24 +02:00
4c1ee2bc26 global: add TIM_OC macro 2022-06-03 10:10:49 +02:00
0250d81862 add: add RGBW LED strip control 2022-06-03 10:10:16 +02:00
beb6d33f85 app: add scrolling text animation 2022-05-26 10:39:03 +02:00
5e688d467d app: make position on RGB panel more flexibel 2022-05-26 10:38:23 +02:00
b0351bcaaf app: improve a tiny bit the ghosting on RGB panel 2022-05-25 20:21:37 +02:00
7675f73d0b app: remove RGB panel test animation 2022-05-25 20:15:53 +02:00
a1da462852 app: add function to draw text on RGB panel 2022-05-25 20:14:58 +02:00
0e91b71aae app: improve RGB panel refresh rate 2022-05-25 19:58:08 +02:00
759cfd577e app: add function to draw character on RGB panel 2022-05-25 19:57:44 +02:00
c73600c91f app: use timer to update RGB panel lines 2022-05-25 19:37:17 +02:00
34d44c2a88 app: improve/fix RGB panel control 2022-05-25 17:38:34 +02:00
884f007d19 README: fix RGB panel connections 2022-05-25 17:35:54 +02:00
71564dd4f1 app: implement stepper and RGB matrix control 2022-05-24 14:45:56 +02:00
4fba2fd7a4 global: disable button init (pin used by RGB matrix) 2022-05-24 14:17:04 +02:00
d208297aa3 bootloader: fix DFU_FORCE_PIN code 2022-05-24 14:11:19 +02:00
9d1a4006af README: document pin connections 2022-05-24 14:10:05 +02:00
6aa820690e switch back to libopenmc3 repo 2021-09-24 16:01:53 +02:00
ea30c7c879 application: disable VBUS sensing 2021-09-24 16:00:55 +02:00
a2f203a81f lib/usb_dfu: disable VBUS sensing 2021-09-24 16:00:23 +02:00
a74539ab4f bootloader: fix new compiler error 2021-09-24 15:59:47 +02:00
9c9893e1da application: minor, double ensure debug info is only show with DEBUG enabled 2021-05-14 14:50:02 +02:00
a716cb10cf flash_internal: add support for STM32F401CE 2021-05-14 14:30:15 +02:00
0a18d73197 .ld: minor, fix typo 2021-05-14 14:28:48 +02:00
8c01cbd918 sensor_max6675: mark as untested for STM32F4 2021-05-14 13:43:17 +02:00
019b82d384 sensor_max6675: add library for MAX6675 k-type thermocouple reader 2021-05-14 13:42:03 +02:00
a89d8abb38 lib: minor, simplify license 2021-05-14 13:42:03 +02:00
ced5582a1a application: minor, update copyright date 2021-05-14 13:18:20 +02:00
4d53d868fe usart_enhanced: mark STM32F4 compatible (no difference with STM32F1) 2021-05-14 13:14:58 +02:00
ce0848343d usart_enhanced: minor, fix spacing 2021-05-14 13:14:58 +02:00
863fd744d7 README: fix typo 2021-05-14 13:14:58 +02:00
d85d345ec4 application: make some text only output when DEBUG is set 2021-05-14 13:14:53 +02:00
35a614750d application: remove watchdog info (not F4 compatible) 2021-05-14 13:12:46 +02:00
b3cf0d0302 swd: improve documentation 2021-03-23 17:22:48 +01:00
3a6a64928d swd: minor, fix doc 2021-03-23 17:22:48 +01:00
99d66f4e4e swd: improve part number decoding 2021-03-23 17:22:48 +01:00
66521e1981 swd: minor, fix comment, add doc, make reset tiny bit longer for better reliability 2021-03-23 17:22:48 +01:00
210fab8eae swd: expose release pins 2021-03-23 17:22:48 +01:00
7318d70dcd swd: minor, fix space 2021-03-23 17:22:48 +01:00
0010c5e046 swd: provide function to set SWCLK/SWDIO pin 2021-03-23 17:22:48 +01:00
6b3b55839e swd: use variables for pins (for later dynamic change) 2021-03-23 17:22:48 +01:00
6bed3ab0fb Rakefile: ingnore .inc files 2021-03-23 17:22:48 +01:00
9a7c51f80e Rakefile: fix spacing 2021-03-23 17:22:48 +01:00
7a74f9709f add SWD library 2021-03-23 17:22:48 +01:00
fa29cfc29f application: minor, fix typo 2020-12-17 12:51:23 +01:00
2248ba1762 application: fix rtc_to_seconds 2020-12-17 12:51:23 +01:00
ac255816a1 sensor_mlx90614: add library to read from MLX90614 IR-thermometer 2020-12-17 12:51:23 +01:00
95b63a06f5 smbus_master: add SMBus library 2020-12-17 12:51:23 +01:00
7656c699bf i2c_master: fix stop generation 2020-12-17 12:51:23 +01:00
c6a4f58b93 i2c_master: fix wait_stop call 2020-12-17 12:51:23 +01:00
b82520fa9b sensor_sr04: fix shadow counter value issue 2020-12-17 12:51:23 +01:00
25fcf8fe0b global: add ADC macros 2020-12-17 12:51:23 +01:00
01eaa5cfab USB: increase text buffer size for project 2020-12-17 12:51:23 +01:00
793611d629 application: implement uptime 2020-12-17 12:48:37 +01:00
ad52abc26b oled_ssd1306: adapt to ported I²C library 2020-12-17 12:48:37 +01:00
b0f5f127f6 i2c_master: port to STM32F4 2020-12-17 12:48:37 +01:00
a449b9b7ff global: add I²C macros 2020-12-17 12:48:37 +01:00
4c6e9a4fda interrupt: port to STM32F4 2020-12-17 12:48:37 +01:00
789b36fc21 interrupt: minor, fix comment 2020-12-17 12:48:37 +01:00
c8861f40c4 onewire_master: port to STM32F4 2020-12-17 12:48:37 +01:00
77415cb41f onewire_master: minor, fix spacing 2020-12-17 12:48:37 +01:00
11f5bc9771 sensor_sr04: add library for HC-SR04 ultrasonic range sensor 2020-12-17 12:48:37 +01:00
8526dc084b global: add tim irq defines 2020-12-17 12:48:37 +01:00
fea286914b global: improve sleep_us for STM32F4 2020-12-17 12:48:37 +01:00
cfcc8a1bb6 Rakefile: automatically get libopencm3 2020-12-17 12:48:37 +01:00
510c82d00f Merge branch 'stm32f4' of ssh://git.cuvoodoo.info/stm32f1 into stm32f4 2020-12-11 00:03:15 +01:00
26f6de3015 sensor_max1247: STM32F4 incompatible for now 2020-12-11 00:02:44 +01:00
a9461b53f5 README: port to F4 2020-12-11 00:00:25 +01:00
d7b6300a50 rakefile: fix remove protection for F4 2020-12-11 00:00:25 +01:00
d0bd71b266 application: add periodis RTC wakeup 2020-12-11 00:00:25 +01:00
a46b6a1630 Rakefile: add macro debugging information 2020-12-11 00:00:25 +01:00
b100c4ae13 application: RTC + date/time added 2020-12-11 00:00:25 +01:00
a0f9b4a530 application: port to STM32F4 (RTC is not working yet) 2020-12-11 00:00:25 +01:00
e32e27100d USB CDC ACM: fix sending loop (and spacing) 2020-12-11 00:00:25 +01:00
5b0523f751 uart: port to STM32F4 2020-12-11 00:00:25 +01:00
d6cac41b78 USB CDC ACM: minor fix spacing 2020-12-11 00:00:25 +01:00
adc62ebb9a USB CDC ACM: port to STM32F4 2020-12-11 00:00:25 +01:00
d9a15f2daa USB CDC ACM: match serial to STM32 bootloader 2020-12-11 00:00:25 +01:00
c4af940975 dfu: minor, improve disconnect 2020-12-11 00:00:25 +01:00
c58d27cf2e Rakefile: add method to flash bootloader over DFU 2020-12-11 00:00:25 +01:00
c3d7711258 global: add synchronisation barrier commands 2020-12-11 00:00:25 +01:00
78cb85421a global: add common function to start DFU and systeme memory 2020-12-11 00:00:25 +01:00
ff5fbc847d DFU: fix DP pull down 2020-12-11 00:00:25 +01:00
51e0bfd188 DFU: minor, remove unused/duplicate code 2020-12-11 00:00:25 +01:00
c411d552a1 DFU: set serial to match STM32 DFU bootloader 2020-12-11 00:00:25 +01:00
ceff33ea0e Rakefile: use derivated device properties 2020-12-11 00:00:25 +01:00
68955ddfec bootloader: update to work with F4 2020-12-11 00:00:25 +01:00
40ee01ce67 usb_dfu: update to work with F4 2020-12-11 00:00:25 +01:00
0b2bbf8c97 libopencm3: use branch with OTG fix
because the MINIF4 board does not have an optional pull-up resistor on D+, the device is not enumerated without this fix.
this fix is not yet in official libopencm3 master.
2020-12-11 00:00:25 +01:00
87af738378 flash_internal: remove F1 flash utilities, add F4 section utility
compared to the STM32F1, the STM32F4 does not used 1 KB flash pages.
F4 uses variable large (>= 16 KB) flash sections.
this makes using the last page (128 KB instead of 1KB) for EEPROM highly inefficient.
caching such large pages before reprogramming small portion is also no doable (there is not enough RAM).
thus almost all F1 utilities are not applicable anymore.
to help erasing the right section, a utility to get the section from an address is added.
2020-12-11 00:00:25 +01:00
e4ce622f15 terminal: minor, fix doc 2020-12-11 00:00:25 +01:00
dbd0ea4d27 global: remove macro pin definition since on F4 they are not unique 2020-12-11 00:00:25 +01:00
a878a1ad9c global: define MINIF401 button/led pins 2020-12-11 00:00:25 +01:00
aff4275478 lib: disable most libraries since they need tuning to be F4 compatible 2020-12-11 00:00:25 +01:00
609188d74e Rakefile: compile for STM32F4 2020-12-11 00:00:25 +01:00
63a2e5e5ff *.ld: set flash and RAM size for STM32F401xC 2020-12-11 00:00:25 +01:00
ac1bea1d45 README: port to F4 2020-11-30 15:03:32 +01:00
7b7f26ee47 rakefile: fix remove protection for F4 2020-11-30 14:51:06 +01:00
3d00bdf3c0 application: add periodis RTC wakeup 2020-11-30 14:36:33 +01:00
319a02d2b4 Rakefile: add macro debugging information 2020-11-28 15:19:13 +01:00
cc8be1f278 application: RTC + date/time added 2020-11-28 15:17:52 +01:00
e255573b1e application: port to STM32F4 (RTC is not working yet) 2020-11-27 17:07:39 +01:00
0fe7e1fd39 USB CDC ACM: fix sending loop (and spacing) 2020-11-27 17:06:21 +01:00
2249f460e3 uart: port to STM32F4 2020-11-27 16:49:59 +01:00
aae4009fbe USB CDC ACM: minor fix spacing 2020-11-27 16:44:17 +01:00
a9284b7154 USB CDC ACM: port to STM32F4 2020-11-27 16:43:57 +01:00
777fd7afb9 USB CDC ACM: match serial to STM32 bootloader 2020-11-27 16:41:19 +01:00
31079d95dd dfu: minor, improve disconnect 2020-11-27 16:39:51 +01:00
ced714129c Rakefile: add method to flash bootloader over DFU 2020-11-27 16:39:11 +01:00
4fcfd29d2b global: add synchronisation barrier commands 2020-11-27 16:38:32 +01:00
06de8d0be9 global: add common function to start DFU and systeme memory 2020-11-27 16:37:52 +01:00
de36c7f3a2 DFU: fix DP pull down 2020-11-27 16:05:55 +01:00
8918b97618 DFU: minor, remove unused/duplicate code 2020-11-27 16:05:37 +01:00
0bb2be3727 DFU: set serial to match STM32 DFU bootloader 2020-11-27 16:04:07 +01:00
a781fc5b3b Rakefile: use derivated device properties 2020-11-27 15:54:08 +01:00
00ef5d9344 bootloader: update to work with F4 2020-11-24 16:18:17 +01:00
9fbf5b4aad usb_dfu: update to work with F4 2020-11-24 16:17:37 +01:00
46083bdf5e libopencm3: use branch with OTG fix
because the MINIF4 board does not have an optional pull-up resistor on D+, the device is not enumerated without this fix.
this fix is not yet in official libopencm3 master.
2020-11-24 16:11:01 +01:00
8a165c4d71 flash_internal: remove F1 flash utilities, add F4 section utility
compared to the STM32F1, the STM32F4 does not used 1 KB flash pages.
F4 uses variable large (>= 16 KB) flash sections.
this makes using the last page (128 KB instead of 1KB) for EEPROM highly inefficient.
caching such large pages before reprogramming small portion is also no doable (there is not enough RAM).
thus almost all F1 utilities are not applicable anymore.
to help erasing the right section, a utility to get the section from an address is added.
2020-11-24 16:04:42 +01:00
9db9ea9dc1 terminal: minor, fix doc 2020-11-24 16:01:49 +01:00
4b514c6801 global: remove macro pin definition since on F4 they are not unique 2020-11-24 16:01:06 +01:00
6a34352914 global: define MINIF401 button/led pins 2020-11-24 15:59:42 +01:00
35c441355d lib: disable most libraries since they need tuning to be F4 compatible 2020-11-24 15:56:00 +01:00
9751880813 Rakefile: compile for STM32F4 2020-11-24 15:51:03 +01:00
e58614002c *.ld: set flash and RAM size for STM32F401xC 2020-11-24 15:48:25 +01:00
68 changed files with 5635 additions and 1675 deletions

2
.gitmodules vendored
View File

@ -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
View File

@ -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
-----

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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
}

View File

@ -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
View File

@ -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)