├── .gitignore ├── .gitmodules ├── LICENSE ├── ld.efm32.basic ├── ld.ti.basic ├── ld.nrf52.basic ├── ld.sam.basic ├── ld.stm32.basic ├── template_nrf52.c ├── template_efm32.c ├── template_sam.c ├── template_stm32.c ├── boards.efm32.mk ├── boards.sam.mk ├── boards.nrf.mk ├── template_ti.c ├── boards.ti.mk ├── Makefile ├── README.md ├── cortex-m-generic.ld └── boards.stm32.mk /.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | *.elf 3 | *.hex 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libopencm3"] 2 | path = libopencm3 3 | url = https://github.com/libopencm3/libopencm3.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | To the extent possible, consider the _examples_ in this repository as released 2 | into the Public Domain. 3 | 4 | Where that is not possible, consider the _examples_ released under your choice of the following licenses. 5 | * MIT 6 | * ISC 7 | * Apache2 8 | * X11 9 | * BSD 2 clause 10 | 11 | libopencm3 _itself_ is of course under its own license. (LGPLv3) 12 | -------------------------------------------------------------------------------- /ld.efm32.basic: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic linker script that works for ~all EFM32 3 | * ~all EFM devices have flash at 0x0 and at least 8K 4 | * ~all EFM devices have ram at 0x200000000 and at least 4K 5 | * 6 | * This is enough for miniblink, but if you try and copy this to your own 7 | * projects, "You're gonna have a bad day" 8 | */ 9 | 10 | MEMORY 11 | { 12 | rom (rx) : ORIGIN = 0x00000000, LENGTH = 8K 13 | ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K 14 | } 15 | 16 | INCLUDE ./cortex-m-generic.ld 17 | -------------------------------------------------------------------------------- /ld.ti.basic: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic linker script that works for ~all TI devices 3 | * ~all TI devices have flash at 0x0 and at least 8K 4 | * ~all TI devices have ram at 0x200000000 and at least 4K 5 | * 6 | * This is enough for miniblink, but if you try and copy this to your own 7 | * projects, "You're gonna have a bad day" 8 | */ 9 | 10 | MEMORY 11 | { 12 | rom (rx) : ORIGIN = 0x00000000, LENGTH = 8K 13 | ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K 14 | } 15 | 16 | INCLUDE ./cortex-m-generic.ld 17 | -------------------------------------------------------------------------------- /ld.nrf52.basic: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic linker script that works for ~all NRF52 3 | * ~all NRF52 devices have flash at 0x0 and at least 192K 4 | * ~all NRF52 devices have ram at 0x200000000 and at least 24K 5 | * 6 | * This is enough for miniblink, but if you try and copy this to your own 7 | * projects, "You're gonna have a bad day" 8 | */ 9 | 10 | MEMORY 11 | { 12 | rom (rx) : ORIGIN = 0x00000000, LENGTH = 192K 13 | ram (rwx) : ORIGIN = 0x20000000, LENGTH = 24K 14 | } 15 | 16 | INCLUDE ./cortex-m-generic.ld 17 | -------------------------------------------------------------------------------- /ld.sam.basic: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic linker script that works for ~all Atmel/Microchip SAM devices 3 | * ~all devices have flash at 0x0 and at least 8K 4 | * ~all devices have ram at 0x200000000 and at least 4K 5 | * 6 | * This is enough for miniblink, but if you try and copy this to your own 7 | * projects, "You're gonna have a bad day" 8 | */ 9 | 10 | MEMORY 11 | { 12 | rom (rx) : ORIGIN = 0x00000000, LENGTH = 8K 13 | ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K 14 | } 15 | 16 | INCLUDE ./cortex-m-generic.ld 17 | -------------------------------------------------------------------------------- /ld.stm32.basic: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic linker script that works for ~all STM32 devices 3 | * ~all STM32 devices have flash at 0x08000000 and at least 8K 4 | * ~all STM32 devices have ram at 0x200000000 and at least 2K 5 | * 6 | * This is enough for miniblink, but if you try and copy this to your own 7 | * projects, "You're gonna have a bad day" 8 | */ 9 | 10 | MEMORY 11 | { 12 | rom (rx) : ORIGIN = 0x08000000, LENGTH = 8K 13 | ram (rwx) : ORIGIN = 0x20000000, LENGTH = 2K 14 | } 15 | 16 | INCLUDE ./cortex-m-generic.ld 17 | -------------------------------------------------------------------------------- /template_nrf52.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | gpio_mode_setup(PORT_LED1, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED1); 5 | gpio_set(PORT_LED1, PIN_LED1); 6 | #if defined(PORT_LED2) 7 | gpio_mode_setup(PORT_LED2, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED2); 8 | #endif 9 | while(1) { 10 | /* wait a little bit */ 11 | for (int i = 0; i < LITTLE_BIT; i++) { 12 | __asm__("nop"); 13 | } 14 | gpio_toggle(PORT_LED1, PIN_LED1); 15 | #if defined(PORT_LED2) 16 | gpio_toggle(PORT_LED2, PIN_LED2); 17 | #endif 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /template_efm32.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) { 5 | cmu_periph_clock_enable(CMU_GPIO); 6 | gpio_mode_setup(PORT_LED1, GPIO_MODE_PUSH_PULL, PIN_LED1); 7 | gpio_set(PORT_LED1, PIN_LED1); 8 | #if defined(PORT_LED2) 9 | gpio_mode_setup(PORT_LED2, GPIO_MODE_PUSH_PULL, PIN_LED2); 10 | #endif 11 | while(1) { 12 | /* wait a little bit */ 13 | for (int i = 0; i < LITTLE_BIT; i++) { 14 | __asm__("nop"); 15 | } 16 | gpio_toggle(PORT_LED1, PIN_LED1); 17 | #if defined(PORT_LED2) 18 | gpio_toggle(PORT_LED2, PIN_LED2); 19 | #endif 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /template_sam.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static void gpio_setup(void) 5 | { 6 | PORT_DIR(PORT_LED1) = (1< 2 | #include 3 | 4 | int main(void) { 5 | rcc_periph_clock_enable(RCC_LED1); 6 | #if defined(STM32F1) /* F1 is a precious snowflake */ 7 | gpio_set_mode(PORT_LED1, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, PIN_LED1); 8 | #else /* everyone else is sane */ 9 | gpio_mode_setup(PORT_LED1, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED1); 10 | #endif 11 | gpio_set(PORT_LED1, PIN_LED1); 12 | #if defined(RCC_LED2) 13 | rcc_periph_clock_enable(RCC_LED2); 14 | gpio_mode_setup(PORT_LED2, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED2); 15 | #endif 16 | while(1) { 17 | /* wait a little bit */ 18 | for (int i = 0; i < LITTLE_BIT; i++) { 19 | __asm__("nop"); 20 | } 21 | gpio_toggle(PORT_LED1, PIN_LED1); 22 | #if defined(RCC_LED2) 23 | gpio_toggle(PORT_LED2, PIN_LED2); 24 | #endif 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /boards.efm32.mk: -------------------------------------------------------------------------------- 1 | # Instructions: 2 | # 1) add a rule for your board to the bottom of this file 3 | # 2) profit! 4 | 5 | LFLAGS_EFM32=$(LFLAGS) template_efm32.c -T ld.efm32.basic 6 | 7 | # EFM32HG starts up with HFRCO at 14Mhz 8 | EFM32HG_CFLAGS=$(M0P_FLAGS) -DEFM32HG -DLITTLE_BIT=800000 $(LFLAGS_EFM32) -lopencm3_efm32hg 9 | 10 | define RAWMakeBoard 11 | $(CC) -DPORT_LED1=$(1) -DPIN_LED1=$(2) \ 12 | $(if $(5),-DPORT_LED2=$(5) -DPIN_LED2=$(6),) \ 13 | $(3) -o $(OD)/efm32/$(4) 14 | endef 15 | 16 | 17 | define MakeBoard 18 | BOARDS_ELF+=$(OD)/efm32/$(1).elf 19 | BOARDS_BIN+=$(OD)/efm32/$(1).bin 20 | BOARDS_HEX+=$(OD)/efm32/$(1).hex 21 | $(OD)/efm32/$(1).elf: template_efm32.c libopencm3/lib/libopencm3_$(5).a 22 | @echo " $(5) -> Creating $(OD)/efm32/$(1).elf" 23 | $(call RAWMakeBoard,$(2),$(3),$(4),$(1).elf,$(6),$(7)) 24 | endef 25 | 26 | define efm32hgboard 27 | $(call MakeBoard,$(1),$(2),$(3),$(EFM32HG_CFLAGS),efm32hg,$(4),$(5)) 28 | endef 29 | 30 | # EFM32HG boards 31 | $(eval $(call efm32hgboard,efm32hg-slstk3400a,GPIOF,GPIO4,GPIOF,GPIO5)) 32 | -------------------------------------------------------------------------------- /boards.sam.mk: -------------------------------------------------------------------------------- 1 | # Instructions: 2 | # 1) add a rule for your board, following the style in place. 3 | # This file should cover all the Atmel/Microchip Cortex-M parts 4 | 5 | LFLAGS_SAM=$(LFLAGS) template_sam.c -T ld.sam.basic 6 | 7 | # FIXME what are default clock speeds? 8 | SAMD_CFLAGS=$(M0P_FLAGS) -DSAMD -DLITTLE_BIT=100000 $(LFLAGS_SAM) -lopencm3_samd 9 | 10 | define RAWMakeBoard 11 | $(CC) -DPORT_LED1=$(1) -DPIN_LED1=$(2) \ 12 | $(if $(5),-DPORT_LED2=$(5) -DPIN_LED2=$(6),) \ 13 | $(3) -o $(OD)/sam/$(4) 14 | endef 15 | 16 | define MakeBoard 17 | BOARDS_ELF+=$(OD)/sam/$(1).elf 18 | BOARDS_BIN+=$(OD)/sam/$(1).bin 19 | BOARDS_HEX+=$(OD)/sam/$(1).hex 20 | $(OD)/sam/$(1).elf: template_sam.c libopencm3/lib/libopencm3_$(5).a 21 | @echo " $(5) -> Creating $(OD)/sam/$(1).elf" 22 | $(call RAWMakeBoard,$(2),$(3),$(4),$(1).elf,$(6),$(7)) 23 | endef 24 | 25 | define samdboard 26 | $(call MakeBoard,$(1),$(2),$(3),$(SAMD_CFLAGS),samd) 27 | endef 28 | 29 | $(eval $(call samdboard,samd10-xplained-mini,PORTA,9)) 30 | $(eval $(call samdboard,samd11-xplained-pro,PORTA,16)) 31 | -------------------------------------------------------------------------------- /boards.nrf.mk: -------------------------------------------------------------------------------- 1 | # Instructions: 2 | # 1) add a rule for your board to the bottom of this file 3 | # 2) profit! 4 | 5 | LFLAGS_NRF52=$(LFLAGS) template_nrf52.c -T ld.nrf52.basic 6 | 7 | # NRF52 starts up with HFINT at 64Mhz 8 | NRF52_CFLAGS=$(M4FH_FLAGS) -DNRF52 -DLITTLE_BIT=3200000 $(LFLAGS_NRF52) -lopencm3_nrf52 9 | 10 | define RAWMakeBoard 11 | $(CC) -DPORT_LED1=GPIO -DPIN_LED1=$(1) \ 12 | $(if $(3),-DPORT_LED2=GPIO -DPIN_LED2=$(3),) \ 13 | $(4) -o $(OD)/nrf52/$(2) 14 | endef 15 | 16 | 17 | define MakeBoard 18 | # 1 = board, 2 = pin, 3 = pin, 4 = cflags, 5 = lib 19 | BOARDS_ELF+=$(OD)/nrf52/$(1).elf 20 | BOARDS_BIN+=$(OD)/nrf52/$(1).bin 21 | BOARDS_HEX+=$(OD)/nrf52/$(1).hex 22 | $(OD)/nrf52/$(1).elf: template_nrf52.c libopencm3/lib/libopencm3_$(5).a 23 | @echo " $(5) -> Creating $(OD)/nrf52/$(1).elf" 24 | $(call RAWMakeBoard,$(2),$(1).elf,$(3),$(4)) 25 | endef 26 | 27 | define nrf52board 28 | # 1 = board, 2 = pin, 3=pin 29 | $(call MakeBoard,$(1),$(2),$(3),$(NRF52_CFLAGS),nrf52) 30 | endef 31 | 32 | # NRF52 boards 33 | $(eval $(call nrf52board,nrf52833-dk,GPIO13,GPIO14)) 34 | $(eval $(call nrf52board,pinetime,GPIO13,GPIO14)) 35 | -------------------------------------------------------------------------------- /template_ti.c: -------------------------------------------------------------------------------- 1 | #if defined(LM3S) 2 | #error "LM3S is very poorly supported file a ticket if you actually have this hw" 3 | #include 4 | #include 5 | #elif defined(LM4F) 6 | #include 7 | #include 8 | #else 9 | #error "Unknown TI family!" 10 | #endif 11 | 12 | int main(void) { 13 | gpio_enable_ahb_aperture(); 14 | 15 | periph_clock_enable(RCC_LED1); 16 | /* FIXME - may need to gpio_unlock_commit(port,pin)! */ 17 | gpio_mode_setup(PORT_LED1, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED1); 18 | gpio_set_output_config(PORT_LED1, GPIO_OTYPE_PP, GPIO_DRIVE_2MA, PIN_LED1); 19 | gpio_set(PORT_LED1, PIN_LED1); 20 | 21 | #if defined(RCC_LED2) 22 | periph_clock_enable(RCC_LED2); 23 | gpio_mode_setup(PORT_LED2, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED2); 24 | gpio_set_output_config(PORT_LED2, GPIO_OTYPE_PP, GPIO_DRIVE_2MA, PIN_LED2); 25 | #endif 26 | while(1) { 27 | /* wait a little bit */ 28 | for (int i = 0; i < LITTLE_BIT; i++) { 29 | __asm__("nop"); 30 | } 31 | gpio_toggle(PORT_LED1, PIN_LED1); 32 | #if defined(RCC_LED2) 33 | gpio_toggle(PORT_LED2, PIN_LED2); 34 | #endif 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /boards.ti.mk: -------------------------------------------------------------------------------- 1 | # Instructions: 2 | # 1) add a rule for your board, following the style in place. 3 | # This file should cover all the TI boards, lm3s, lm4f, tiva, msp432 4 | 5 | LFLAGS_TI=$(LFLAGS) template_ti.c -T ld.ti.basic 6 | 7 | # FIXME what are default clock speeds? 8 | LM3S_CFLAGS=$(M3_FLAGS) -DLM3S -DLITTLE_BIT=800000 $(LFLAGS_TI) -lopencm3_lm3s 9 | LM4F_CFLAGS=$(M4FH_FLAGS) -DLM4F -DLITTLE_BIT=800000 $(LFLAGS_TI) -lopencm3_lm4f 10 | 11 | define RAWMakeBoard 12 | $(CC) -DRCC_LED1=RCC_$(1) -DPORT_LED1=$(1) -DPIN_LED1=$(2) \ 13 | $(if $(5),-DRCC_LED2=RCC_$(5) -DPORT_LED2=$(5) -DPIN_LED2=$(6),) \ 14 | $(3) -o $(OD)/ti/$(4) 15 | endef 16 | 17 | define MakeBoard 18 | BOARDS_ELF+=$(OD)/ti/$(1).elf 19 | BOARDS_BIN+=$(OD)/ti/$(1).bin 20 | BOARDS_HEX+=$(OD)/ti/$(1).hex 21 | $(OD)/ti/$(1).elf: template_ti.c libopencm3/lib/libopencm3_$(5).a 22 | @echo " $(5) -> Creating $(OD)/ti/$(1).elf" 23 | $(call RAWMakeBoard,$(2),$(3),$(4),$(1).elf,$(6),$(7)) 24 | endef 25 | 26 | define lm3sboard 27 | $(call MakeBoard,$(1),$(2),$(3),$(LM3S_CFLAGS),lm3s) 28 | endef 29 | define lm4fboard 30 | $(call MakeBoard,$(1),$(2),$(3),$(LM4F_CFLAGS),lm4f) 31 | endef 32 | 33 | # If anyone actually has real lm3s hardware, they can file a bug. 34 | #$(eval $(call lm3sboard,lm3s811-evb,GPIOC,GPIO5)) 35 | $(eval $(call lm4fboard,ek-lm4f120xl,GPIOF,GPIO1,GPIOF,GPIO2)) 36 | # PN1, PN0, PF4, PF0 37 | $(eval $(call lm4fboard,ek-tm4c1294xl,GPION,GPIO0,GPIOF,GPIO4)) 38 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PREFIX?=arm-none-eabi- 2 | CC=$(PREFIX)gcc 3 | OBJCOPY=$(PREFIX)objcopy 4 | OD=bin 5 | 6 | all: realall.really 7 | 8 | SFLAGS= --static -nostartfiles -std=c11 -g3 -Os 9 | SFLAGS+= -fno-common -ffunction-sections -fdata-sections 10 | SFLAGS+= -I./libopencm3/include -L./libopencm3/lib 11 | LFLAGS+=-Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group 12 | 13 | M0_FLAGS= $(SFLAGS) -mcpu=cortex-m0 -mthumb -msoft-float 14 | M0P_FLAGS= $(SFLAGS) -mcpu=cortex-m0plus -mthumb -msoft-float 15 | M3_FLAGS= $(SFLAGS) -mcpu=cortex-m3 -mthumb -msoft-float 16 | M4FH_FLAGS= $(SFLAGS) -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 17 | M7SP_FLAGS= $(SFLAGS) -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 18 | M7DP_FLAGS= $(SFLAGS) -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16 19 | 20 | include boards.efm32.mk 21 | include boards.sam.mk 22 | include boards.stm32.mk 23 | include boards.ti.mk 24 | include boards.nrf.mk 25 | 26 | realall.really: outdir $(BOARDS_ELF) $(BOARDS_BIN) $(BOARDS_HEX) 27 | 28 | libopencm3/Makefile: 29 | @echo "Initializing libopencm3 submodule" 30 | git submodule update --init 31 | 32 | libopencm3/lib/libopencm3_%.a: libopencm3/Makefile 33 | $(MAKE) -C libopencm3 34 | 35 | %.bin: %.elf 36 | @#printf " OBJCOPY $(*).bin\n" 37 | $(OBJCOPY) -Obinary $(*).elf $(*).bin 38 | 39 | %.hex: %.elf 40 | @#printf " OBJCOPY $(*).hex\n" 41 | $(OBJCOPY) -Oihex $(*).elf $(*).hex 42 | 43 | outdir: 44 | mkdir -p $(OD)/efm32 45 | mkdir -p $(OD)/sam 46 | mkdir -p $(OD)/ti 47 | mkdir -p $(OD)/nrf52 48 | 49 | clean: 50 | $(RM) $(BOARDS_ELF) $(BOARDS_BIN) $(BOARDS_HEX) 51 | 52 | .PHONY: realall.really outdir clean all 53 | $(V).SILENT: 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # libopencm3-miniblink 2 | 3 | This repository contains miniblink examples for any and all boards we can find. 4 | 5 | It is intended to be a basic starting point for people who want to test that 6 | their compiler toolchain, flash programming and/or debugger are all working as 7 | expected. 8 | 9 | It contains _only_ basic blinky examples, one for each board. If you are 10 | looking for full examples that setup complicated clocks, or use onboard 11 | peripherals, you are in the *wrong* place. 12 | 13 | # Building 14 | 15 | Just run ```make```. 16 | 17 | If necessary, this will checkout and build the libopencm3 repository, and 18 | then generate a blinky for every known board in the bin directory. 19 | 20 | If you want to see exactly what it did, run ```make V=1``` 21 | 22 | # Flashing 23 | 24 | Unfortunately, flashing these examples is a _very_ openended task. Below are 25 | some examples that might be helpful, but this is not an exhaustive list. 26 | 27 | ## Using [OpenOCD](http://openocd.org/) 28 | OpenOCD can support a multitude of debug interfaces and targets. Unfortunately 29 | this makes it's config more verbose than some tools. 30 | 31 | The general form is 32 | ``` 33 | $ openocd -f interface/.cfg -f target/.cfg \ 34 | -c "program file.elf verify reset exit" 35 | ``` 36 | 37 | For boards with integrated debuggers, you can sometimes shortcut with a "board.cfg" file instead. 38 | 39 | ``` 40 | $ CMD="program ${ELF_FILE} verify reset exit" 41 | $ openocd -f interface/stlink.cfg -f target/stm32f1x.cfg -c "${CMD}" 42 | $ openocd -f board/stm32l4discovery.cfg -c "${CMD}" 43 | ``` 44 | 45 | ## Using [st-flash](https://github.com/texane/stlink) 46 | st-flash or st-util can be used with STM32 targets only, with STLink 47 | debugger hardware. 48 | 49 | ``` 50 | $ st-flash write path/to/yourfile.bin 0x8000000 51 | ``` 52 | 53 | # Next steps 54 | 55 | If you _are_ looking for more complicated examples, the [Original libopencm3-examples](http://github.com/libopencm3/libopencm3-examples) 56 | is still relevant, though it's not well maintained, particularly for newer hardware. 57 | 58 | Other places to look are the [USB Gadget-Zero Tests](https://github.com/libopencm3/libopencm3/tree/master/tests/gadget-zero) are also good at testing your USB hardware. You may also find interesting pieces at https://github.com/karlp/libopencm3-tests and there's also a showcase listed on https://github.com/libopencm3/libopencm3/wiki/Showcase 59 | 60 | 61 | -------------------------------------------------------------------------------- /cortex-m-generic.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the libopencm3 project. 3 | * 4 | * Copyright (C) 2009 Uwe Hermann 5 | * 6 | * This library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this library. If not, see . 18 | */ 19 | 20 | /* Generic linker script for pretty much any cortex-m targets using libopencm3. */ 21 | 22 | /* Memory regions MUST be defined in the ld script which includes this one. */ 23 | 24 | /* Enforce emmition of the vector table. */ 25 | EXTERN (vector_table) 26 | 27 | /* Define the entry point of the output file. */ 28 | ENTRY(reset_handler) 29 | 30 | /* Define sections. */ 31 | SECTIONS 32 | { 33 | .text : { 34 | *(.vectors) /* Vector table */ 35 | *(.text*) /* Program code */ 36 | . = ALIGN(4); 37 | *(.rodata*) /* Read-only data */ 38 | . = ALIGN(4); 39 | } >rom 40 | 41 | /* C++ Static constructors/destructors, also used for __attribute__ 42 | * ((constructor)) and the likes */ 43 | .preinit_array : { 44 | . = ALIGN(4); 45 | __preinit_array_start = .; 46 | KEEP (*(.preinit_array)) 47 | __preinit_array_end = .; 48 | } >rom 49 | .init_array : { 50 | . = ALIGN(4); 51 | __init_array_start = .; 52 | KEEP (*(SORT(.init_array.*))) 53 | KEEP (*(.init_array)) 54 | __init_array_end = .; 55 | } >rom 56 | .fini_array : { 57 | . = ALIGN(4); 58 | __fini_array_start = .; 59 | KEEP (*(.fini_array)) 60 | KEEP (*(SORT(.fini_array.*))) 61 | __fini_array_end = .; 62 | } >rom 63 | 64 | /* 65 | * Another section used by C++ stuff, appears when using newlib with 66 | * 64bit (long long) printf support 67 | */ 68 | .ARM.extab : { 69 | *(.ARM.extab*) 70 | } >rom 71 | .ARM.exidx : { 72 | __exidx_start = .; 73 | *(.ARM.exidx*) 74 | __exidx_end = .; 75 | } >rom 76 | 77 | . = ALIGN(4); 78 | _etext = .; 79 | 80 | /* ram, but not cleared on reset. eg: boot/app comms */ 81 | .noinit (NOLOAD) : { 82 | *(.noinit) 83 | } >ram 84 | . = ALIGN(4); 85 | 86 | .data : { 87 | _data = .; 88 | *(.data*) /* Read-write initialized data */ 89 | . = ALIGN(4); 90 | *(.ramfunctions) /* functions we need/want to run from ram */ 91 | _edata = .; 92 | } >ram AT >rom 93 | _data_loadaddr = LOADADDR(.data); 94 | 95 | .bss : { 96 | *(.bss*) /* Read-write zero initialized data */ 97 | *(COMMON) 98 | . = ALIGN(4); 99 | _ebss = .; 100 | } >ram 101 | 102 | /* 103 | * The .eh_frame section appears to be used for C++ exception handling. 104 | * You may need to fix this if you're using C++. 105 | */ 106 | /DISCARD/ : { *(.eh_frame) } 107 | 108 | . = ALIGN(4); 109 | end = .; 110 | } 111 | 112 | PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); 113 | 114 | -------------------------------------------------------------------------------- /boards.stm32.mk: -------------------------------------------------------------------------------- 1 | # Instructions: 2 | # 1) add a rule for your board to the bottom of this file 3 | # 2) profit! 4 | 5 | LFLAGS_STM32=$(LFLAGS) template_stm32.c -T ld.stm32.basic 6 | 7 | # STM32F0 starts up with HSI at 8Mhz 8 | STM32F0_CFLAGS=$(M0_FLAGS) -DSTM32F0 -DLITTLE_BIT=100000 $(LFLAGS_STM32) -lopencm3_stm32f0 9 | # STM32F1 starts up with HSI at 8Mhz 10 | STM32F1_CFLAGS=$(M3_FLAGS) -DSTM32F1 -DLITTLE_BIT=200000 $(LFLAGS_STM32) -lopencm3_stm32f1 11 | # STM32F2 starts up with HSI at 16MHz 12 | STM32F2_CFLAGS=$(M3_FLAGS) -DSTM32F2 -DLITTLE_BIT=400000 $(LFLAGS_STM32) -lopencm3_stm32f2 13 | # STM32F3 starts up with HSI at 8MHz 14 | STM32F3_CFLAGS=$(M4FH_FLAGS) -DSTM32F3 -DLITTLE_BIT=400000 $(LFLAGS_STM32) -lopencm3_stm32f3 15 | # STM32F4 starts up with HSI at 16MHz 16 | STM32F4_CFLAGS=$(M4FH_FLAGS) -DSTM32F4 -DLITTLE_BIT=800000 $(LFLAGS_STM32) -lopencm3_stm32f4 17 | # STM32F7 starts up with HSI at 16MHz 18 | STM32F7_CFLAGS=$(M7SP_FLAGS) -DSTM32F7 -DLITTLE_BIT=800000 $(LFLAGS_STM32) -lopencm3_stm32f7 19 | # STM32L0 starts up with MSI at 2.1Mhz 20 | STM32L0_CFLAGS=$(M0P_FLAGS) -DSTM32L0 -DLITTLE_BIT=50000 $(LFLAGS_STM32) -lopencm3_stm32l0 21 | # STM32L1 starts up with MSI at 4MHz 22 | STM32L1_CFLAGS=$(M3_FLAGS) -DSTM32L1 -DLITTLE_BIT=100000 $(LFLAGS_STM32) -lopencm3_stm32l1 23 | # STM32L4 starts up with MSI at 4MHz 24 | STM32L4_CFLAGS=$(M4FH_FLAGS) -DSTM32L4 -DLITTLE_BIT=100000 $(LFLAGS_STM32) -lopencm3_stm32l4 25 | # STM32G0 starts up with HSI at 16MHz 26 | STM32G0_CFLAGS=$(M0P_FLAGS) -DSTM32G0 -DLITTLE_BIT=400000 $(LFLAGS_STM32) -lopencm3_stm32g0 27 | # STM32G4 starts up with HSI at 16MHz 28 | STM32G4_CFLAGS=$(M4FH_FLAGS) -DSTM32G4 -DLITTLE_BIT=400000 $(LFLAGS_STM32) -lopencm3_stm32g4 29 | # STM32H7 starts up with HSI at 64MHz 30 | STM32H7_CFLAGS=$(M7DP_FLAGS) -DSTM32H7 -DLITTLE_BIT=3200000 $(LFLAGS_STM32) -lopencm3_stm32h7 31 | 32 | define RAWMakeBoard 33 | mkdir -p $(OD)/$(7) 34 | $(CC) -DRCC_LED1=RCC_$(1) -DPORT_LED1=$(1) -DPIN_LED1=$(2) \ 35 | $(if $(5),-DRCC_LED2=RCC_$(5) -DPORT_LED2=$(5) -DPIN_LED2=$(6),) \ 36 | $(3) -o $(OD)/$(7)/$(4) 37 | endef 38 | 39 | define MakeBoard 40 | BOARDS_ELF+=$(OD)/$(5)/$(1).elf 41 | BOARDS_BIN+=$(OD)/$(5)/$(1).bin 42 | BOARDS_HEX+=$(OD)/$(5)/$(1).hex 43 | $(OD)/$(5)/$(1).elf: template_stm32.c libopencm3/lib/libopencm3_$(5).a 44 | @echo " $(5) -> Creating $(OD)/$(5)/$(1).elf" 45 | $(call RAWMakeBoard,$(2),$(3),$(4),$(1).elf,$(6),$(7),$(5)) 46 | endef 47 | 48 | define stm32f0board 49 | $(call MakeBoard,$(1),$(2),$(3),$(STM32F0_CFLAGS),stm32f0,$(4),$(5)) 50 | endef 51 | define stm32f1board 52 | $(call MakeBoard,$(1),$(2),$(3),$(STM32F1_CFLAGS),stm32f1,$(4),$(5)) 53 | endef 54 | define stm32f2board 55 | $(call MakeBoard,$(1),$(2),$(3),$(STM32F2_CFLAGS),stm32f2,$(4),$(5)) 56 | endef 57 | define stm32f3board 58 | $(call MakeBoard,$(1),$(2),$(3),$(STM32F3_CFLAGS),stm32f3,$(4),$(5)) 59 | endef 60 | define stm32f4board 61 | $(call MakeBoard,$(1),$(2),$(3),$(STM32F4_CFLAGS),stm32f4,$(4),$(5)) 62 | endef 63 | define stm32f7board 64 | $(call MakeBoard,$(1),$(2),$(3),$(STM32F7_CFLAGS),stm32f7,$(4),$(5)) 65 | endef 66 | define stm32l0board 67 | $(call MakeBoard,$(1),$(2),$(3),$(STM32L0_CFLAGS),stm32l0,$(4),$(5)) 68 | endef 69 | define stm32l1board 70 | $(call MakeBoard,$(1),$(2),$(3),$(STM32L1_CFLAGS),stm32l1,$(4),$(5)) 71 | endef 72 | define stm32l4board 73 | $(call MakeBoard,$(1),$(2),$(3),$(STM32L4_CFLAGS),stm32l4,$(4),$(5)) 74 | endef 75 | define stm32g0board 76 | $(call MakeBoard,$(1),$(2),$(3),$(STM32G0_CFLAGS),stm32g0) 77 | endef 78 | define stm32g4board 79 | $(call MakeBoard,$(1),$(2),$(3),$(STM32G4_CFLAGS),stm32g4) 80 | endef 81 | define stm32h7board 82 | $(call MakeBoard,$(1),$(2),$(3),$(STM32H7_CFLAGS),stm32h7,$(4),$(5)) 83 | endef 84 | 85 | # STM32F0 boards 86 | $(eval $(call stm32f0board,stm32f0-discovery,GPIOC,GPIO8)) 87 | $(eval $(call stm32f0board,nucleo-f030r8,GPIOA,GPIO5)) 88 | $(eval $(call stm32f0board,nucleo-f031k6,GPIOB,GPIO3)) 89 | $(eval $(call stm32f0board,nucleo-f042k6,GPIOB,GPIO3)) 90 | $(eval $(call stm32f0board,nucleo-f070rb,GPIOA,GPIO5)) 91 | $(eval $(call stm32f0board,nucleo-f072rb,GPIOA,GPIO5)) 92 | $(eval $(call stm32f0board,nucleo-f091rc,GPIOA,GPIO5)) 93 | 94 | # STM32F1 boards 95 | $(eval $(call stm32f1board,stm32vldiscovery,GPIOC,GPIO8)) 96 | $(eval $(call stm32f1board,olimex-h103,GPIOC,GPIO12)) 97 | $(eval $(call stm32f1board,olimex-h107,GPIOC,GPIO6)) 98 | $(eval $(call stm32f1board,blackpill,GPIOB,GPIO12)) 99 | $(eval $(call stm32f1board,bluepill,GPIOC,GPIO13)) 100 | $(eval $(call stm32f1board,nucleo-f103rb,GPIOA,GPIO5)) 101 | $(eval $(call stm32f1board,lisa-m-1,GPIOC,GPIO13)) 102 | $(eval $(call stm32f1board,lisa-m-2,GPIOA,GPIO8)) 103 | $(eval $(call stm32f1board,st-mb525,GPIOC,GPIO6)) 104 | $(eval $(call stm32f1board,obldc,GPIOA,GPIO6)) 105 | $(eval $(call stm32f1board,obldc-strip,GPIOB,GPIO4)) 106 | $(eval $(call stm32f1board,leaflabs-maple,GPIOA,GPIO5)) 107 | $(eval $(call stm32f1board,waveshare-open103r,GPIOC,GPIO9)) 108 | $(eval $(call stm32f1board,olimex-p103,GPIOC,GPIO12)) 109 | 110 | # STM32F2 boards 111 | $(eval $(call stm32f2board,jobygps,GPIOC,GPIO3)) 112 | 113 | # STM32F3 boards 114 | $(eval $(call stm32f3board,stm32f3-discovery,GPIOE,GPIO8,GPIOE,GPIO10)) 115 | $(eval $(call stm32f3board,nucleo-f302r8,GPIOB,GPIO13)) 116 | $(eval $(call stm32f3board,nucleo-f303k8,GPIOB,GPIO3)) 117 | $(eval $(call stm32f3board,nucleo-f303re,GPIOA,GPIO5)) 118 | $(eval $(call stm32f3board,nucleo-f334r8,GPIOA,GPIO5)) 119 | 120 | # STM32F4 boards 121 | # New product code for original f4 discovery board. 122 | $(eval $(call stm32f4board,stm32f407g-disc1,GPIOD,GPIO12)) 123 | $(eval $(call stm32f4board,stm32f4discover,GPIOD,GPIO12)) 124 | $(eval $(call stm32f4board,nucleo-f411re,GPIOA,GPIO5)) 125 | $(eval $(call stm32f4board,nucleo-f401re,GPIOA,GPIO5)) 126 | $(eval $(call stm32f4board,stm32f429i-disc1,GPIOG,GPIO13)) 127 | $(eval $(call stm32f4board,nucleo-f429zi,GPIOB,GPIO7)) 128 | $(eval $(call stm32f4board,nucleo-f410rb,GPIOA,GPIO5)) 129 | $(eval $(call stm32f4board,nucleo-f446re,GPIOA,GPIO5)) 130 | $(eval $(call stm32f4board,olimex-h405,GPIOC,GPIO12)) 131 | $(eval $(call stm32f4board,olimex-p405,GPIOC,GPIO12)) 132 | $(eval $(call stm32f4board,olimex-e407,GPIOC,GPIO13)) 133 | $(eval $(call stm32f4board,black-stm32f407ve-v2.0,GPIOA,GPIO6)) 134 | $(eval $(call stm32f4board,devebox-stm32f407vgt6,GPIOA,GPIO1)) 135 | $(eval $(call stm32f4board,weact-studio-minif4x1,GPIOC,GPIO13)) 136 | 137 | # STM32F7 boards 138 | $(eval $(call stm32f7board,stm32f746g-disco,GPIOI,GPIO1)) 139 | $(eval $(call stm32f7board,stm32f769i-disco,GPIOJ,GPIO13)) 140 | $(eval $(call stm32f7board,nucleo-f767zi,GPIOB,GPIO0)) 141 | 142 | # STM32L0 boards 143 | $(eval $(call stm32l0board,stm32l0538-disco,GPIOB,GPIO4)) 144 | $(eval $(call stm32l0board,nucleo-l053r8,GPIOA,GPIO5)) 145 | $(eval $(call stm32l0board,nucleo-l073rz,GPIOA,GPIO5)) 146 | $(eval $(call stm32l0board,nucleo-l011k4,GPIOB,GPIO3)) 147 | $(eval $(call stm32l0board,nucleo-l031k6,GPIOB,GPIO3)) 148 | 149 | # STM32L1 boards 150 | # New product code for original l1 discovery 151 | $(eval $(call stm32l1board,32l152cdiscovery,GPIOB,GPIO6)) 152 | $(eval $(call stm32l1board,stm32l-discovery,GPIOB,GPIO6)) 153 | $(eval $(call stm32l1board,nucleo-l152re,GPIOA,GPIO5)) 154 | $(eval $(call stm32l1board,32l100cdiscovery,GPIOC,GPIO8,GPIOC,GPIO9)) 155 | 156 | # STM32L4 boards 157 | $(eval $(call stm32l4board,stm32l476g-disco,GPIOE,GPIO8)) 158 | $(eval $(call stm32l4board,nucleo-stm32l432kc,GPIOB,GPIO3)) 159 | $(eval $(call stm32l4board,nucleo-stm32l452re,GPIOA,GPIO5)) 160 | $(eval $(call stm32l4board,nucleo-stm32l476rg,GPIOA,GPIO5)) 161 | $(eval $(call stm32l4board,nucleo-l4r5zi,GPIOC,GPIO7,GPIOB,GPIO7)) 162 | 163 | # STM32G0 boards 164 | $(eval $(call stm32g0board,nucleo-g071rb,GPIOA,GPIO5)) 165 | $(eval $(call stm32g0board,stm32g0316-disco,GPIOA,GPIO12)) 166 | 167 | # STM32G4 boards 168 | $(eval $(call stm32g4board,nucleo-g431rb,GPIOA,GPIO5)) 169 | $(eval $(call stm32g4board,nucleo-g491re,GPIOA,GPIO5)) 170 | 171 | # STM32H7 boards 172 | $(eval $(call stm32h7board,stm32h743zi,GPIOB,GPIO0,GPIOE,GPIO1)) 173 | $(eval $(call stm32h7board,nucleo-h723zg,GPIOB,GPIO0,GPIOE,GPIO1)) 174 | --------------------------------------------------------------------------------