diff --git a/Makefile b/Makefile
index 1e986542..a4f3e83d 100644
--- a/Makefile
+++ b/Makefile
@@ -20,8 +20,9 @@
PREFIX ?= arm-none-eabi
#PREFIX ?= arm-elf
-TARGETS := stm32/f0 stm32/f1 stm32/f2 stm32/f3 stm32/f4 stm32/l0 stm32/l1
-TARGETS += lpc/lpc13xx lpc/lpc17xx #lpc/lpc43xx
+TARGETS := stm32/f0 stm32/f1 stm32/f2 stm32/f3 stm32/f4 stm32/f7
+TARGETS += stm32/l0 stm32/l1 stm32/l4
+TARGETS += lpc/lpc13xx lpc/lpc17xx lpc/lpc43xx
TARGETS += tiva/lm3s tiva/lm4f
TARGETS += efm32/efm32tg efm32/efm32g efm32/efm32lg efm32/efm32gg
TARGETS += vf6xx
diff --git a/examples/lpc/lpc43xx/Makefile.include b/examples/lpc/lpc43xx/Makefile.include
index 2f626716..fb2792d2 100644
--- a/examples/lpc/lpc43xx/Makefile.include
+++ b/examples/lpc/lpc43xx/Makefile.include
@@ -22,7 +22,7 @@
LIBNAME = opencm3_lpc43xx
-DEFS += -DLPC43XX
+DEFS += -DLPC43XX -DLPC43XX_M4
FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16
ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS)
diff --git a/examples/lpc/lpc43xx/diolan-lpc-4350-db1/diolan-lpc-4350-db1.ld b/examples/lpc/lpc43xx/diolan-lpc-4350-db1/diolan-lpc-4350-db1.ld
index 92c25aff..f2c89067 100644
--- a/examples/lpc/lpc43xx/diolan-lpc-4350-db1/diolan-lpc-4350-db1.ld
+++ b/examples/lpc/lpc43xx/diolan-lpc-4350-db1/diolan-lpc-4350-db1.ld
@@ -24,9 +24,10 @@ MEMORY
{
/* rom is really the shadow region that points to SPI flash or elsewhere */
rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M
- ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K
+ ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K
/* there are some additional RAM regions */
+ ram_local2 (rw) : ORIGIN = 0x10080000, LENGTH = 72K
}
/* Include the common ld script. */
-INCLUDE libopencm3_lpc43xx.ld
+INCLUDE lpc43xx/m4/libopencm3_lpc43xx.ld
diff --git a/examples/lpc/lpc43xx/hackrf-jellybean/i2c/i2cdemo.c b/examples/lpc/lpc43xx/hackrf-jellybean/i2c/i2cdemo.c
index fd244bef..c025dd39 100644
--- a/examples/lpc/lpc43xx/hackrf-jellybean/i2c/i2cdemo.c
+++ b/examples/lpc/lpc43xx/hackrf-jellybean/i2c/i2cdemo.c
@@ -90,7 +90,7 @@ int main(void)
int i;
gpio_setup();
- i2c0_init();
+ i2c0_init(15);
gpio_set(PORT_EN1V8, PIN_EN1V8); /* 1V8 on */
diff --git a/examples/lpc/lpc43xx/hackrf-jellybean/jellybean-lpc4330.ld b/examples/lpc/lpc43xx/hackrf-jellybean/jellybean-lpc4330.ld
index 29e57004..f6b7a76e 100644
--- a/examples/lpc/lpc43xx/hackrf-jellybean/jellybean-lpc4330.ld
+++ b/examples/lpc/lpc43xx/hackrf-jellybean/jellybean-lpc4330.ld
@@ -24,9 +24,10 @@ MEMORY
{
/* rom is really the shadow region that points to SPI flash or elsewhere */
rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M
- ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K
+ ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K
/* there are some additional RAM regions */
+ ram_local2 (rw) : ORIGIN = 0x10080000, LENGTH = 72K
}
/* Include the common ld script. */
-INCLUDE libopencm3_lpc43xx.ld
+INCLUDE lpc43xx/m4/libopencm3_lpc43xx.ld
diff --git a/examples/lpc/lpc43xx/hackrf-jellybean/jellybean-lpc4330_rom_to_ram.ld b/examples/lpc/lpc43xx/hackrf-jellybean/jellybean-lpc4330_rom_to_ram.ld
index fb3d8f6d..06c50926 100644
--- a/examples/lpc/lpc43xx/hackrf-jellybean/jellybean-lpc4330_rom_to_ram.ld
+++ b/examples/lpc/lpc43xx/hackrf-jellybean/jellybean-lpc4330_rom_to_ram.ld
@@ -27,10 +27,10 @@ MEMORY
rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M
/* rom is really the shadow region that points to SPI flash or elsewhere */
rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M
- ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K
+ ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K
/* there are some additional RAM regions for data */
- ram_data (rw) : ORIGIN = 0x10080000, LENGTH = 72K
+ ram_local2 (rw) : ORIGIN = 0x10080000, LENGTH = 72K
}
/* Include the common ld script. */
-INCLUDE libopencm3_lpc43xx_rom_to_ram.ld
+INCLUDE lpc43xx/m4/libopencm3_lpc43xx_rom_to_ram.ld
diff --git a/examples/lpc/lpc43xx/hackrf-jellybean/ssp/sspdemo.c b/examples/lpc/lpc43xx/hackrf-jellybean/ssp/sspdemo.c
index 554843be..680743a4 100644
--- a/examples/lpc/lpc43xx/hackrf-jellybean/ssp/sspdemo.c
+++ b/examples/lpc/lpc43xx/hackrf-jellybean/ssp/sspdemo.c
@@ -86,7 +86,7 @@ int main(void)
while (1) {
- ssp_write(SSP1_NUM, (uint16_t)ssp_val);
+ ssp_transfer(SSP1_NUM, (uint16_t)ssp_val);
gpio_set(GPIO2, GPIOPIN1); /* LED on */
diff --git a/examples/lpc/lpc43xx/hackrf-jellybean/systick/systickdemo.c b/examples/lpc/lpc43xx/hackrf-jellybean/systick/systickdemo.c
index 58d2d616..28e535f7 100644
--- a/examples/lpc/lpc43xx/hackrf-jellybean/systick/systickdemo.c
+++ b/examples/lpc/lpc43xx/hackrf-jellybean/systick/systickdemo.c
@@ -71,10 +71,10 @@ static void systick_setup(void)
g_ulSysTickCount = 0;
/* Disable IRQ globally */
- asm volatile ("cpsid i");
+ __asm__ __volatile__ ("cpsid i");
/* Set processor Clock as Source Clock */
- systick_set_clocksource(STK_CTRL_CLKSOURCE);
+ systick_set_clocksource(STK_CSR_CLKSOURCE);
/* Get SysTick calibration value to obtain by default 1 tick = 10ms */
systick_reload_val = systick_get_calib();
@@ -97,7 +97,7 @@ static void systick_setup(void)
nvic_set_priority(NVIC_SYSTICK_IRQ, 0xFF);
/* Enable IRQ globally */
- asm volatile ("cpsie i");
+ __asm__ __volatile__ ("cpsie i");
}
static void scs_dwt_cycle_counter_enabled(void)
diff --git a/examples/rules.mk b/examples/rules.mk
index c1a5dade..aeccb10e 100644
--- a/examples/rules.mk
+++ b/examples/rules.mk
@@ -60,7 +60,7 @@ ifeq ($(strip $(OPENCM3_DIR)),)
LIBPATHS := ./libopencm3 ../../../../libopencm3 ../../../../../libopencm3
OPENCM3_DIR := $(wildcard $(LIBPATHS:=/locm3.sublime-project))
-OPENCM3_DIR := $(firstword $(dir $(OPENCM3_DIR)))
+OPENCM3_DIR := $(patsubst %/,%,$(firstword $(dir $(OPENCM3_DIR))))
ifeq ($(strip $(OPENCM3_DIR)),)
$(warning Cannot find libopencm3 library in the standard search paths.)
@@ -84,6 +84,7 @@ ifeq ($(strip $(DEVICE)),)
DEFS += -I$(OPENCM3_DIR)/include
LDFLAGS += -L$(OPENCM3_DIR)/lib
LDLIBS += -l$(LIBNAME)
+LIBDEPS += $(OPENCM3_DIR)/lib/lib$(LIBNAME).a
LDSCRIPT ?= $(BINARY).ld
else
# New style, assume device is provided, and we're generating the rest.
@@ -167,11 +168,26 @@ else
include $(OPENCM3_DIR)/mk/genlink-rules.mk
endif
+# Find libopencm3 library folder
+# this tries to match LIBNAME to manufacturer or manufacturer/series folder in lib/
+# eg. LIBNAME=lm3s LIBFOLDER=lib/lm3s or LIBNAME=stm32f7 LIBFOLDER=lib/stm32/f7
+DIR=$(notdir $(subst /.,,$(wildcard $1/*/.)))
+LIBFOLDER=lib/$(strip \
+ $(foreach M,$(filter-out usb ethernet dispatch,$(call DIR,$(OPENCM3_DIR)/lib)), \
+ $(if $(subst opencm3_$M,,$(LIBNAME)),\
+ $(foreach S,$(call DIR,$(OPENCM3_DIR)/lib/$(M)), \
+ $(if $(subst opencm3_$M$S,,$(LIBNAME)),,$M/$S)), \
+ $M)))
+# exceptions
+ifeq ($(LIBFOLDER),lib/lpc43xx)
+LIBFOLDER=lib/lpc43xx/m4
+endif
+
+# Build libopencm3-lib if it does exists
$(OPENCM3_DIR)/lib/lib$(LIBNAME).a:
-ifeq (,$(wildcard $@))
$(warning $(LIBNAME).a not found, attempting to rebuild in $(OPENCM3_DIR))
- $(MAKE) -C $(OPENCM3_DIR)
-endif
+ $(MAKE) -C $(OPENCM3_DIR) $(LIBFOLDER) $(if $(CFLAGS),CFLAGS="$(CFLAGS)")
+$(OPENCM3_DIR)/include/%.h: $(OPENCM3_DIR)/lib/lib$(LIBNAME).a;
# Define a helper macro for debugging make errors online
# you can type "make print-OPENCM3_DIR" and it will show you
@@ -199,19 +215,19 @@ print-%:
@#printf " OBJDUMP $(*).list\n"
$(Q)$(OBJDUMP) -S $(*).elf > $(*).list
-%.elf %.map: $(OBJS) $(LDSCRIPT) $(OPENCM3_DIR)/lib/lib$(LIBNAME).a
+%.elf %.map: $(OBJS) $(LDSCRIPT) $(LIBDEPS)
@#printf " LD $(*).elf\n"
$(Q)$(LD) $(TGT_LDFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(*).elf
-%.o: %.c
+%.o: %.c $(LIBDEPS)
@#printf " CC $(*).c\n"
$(Q)$(CC) $(TGT_CFLAGS) $(CFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $(*).o -c $(*).c
-%.o: %.cxx
+%.o: %.cxx $(LIBDEPS)
@#printf " CXX $(*).cxx\n"
$(Q)$(CXX) $(TGT_CXXFLAGS) $(CXXFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $(*).o -c $(*).cxx
-%.o: %.cpp
+%.o: %.cpp $(LIBDEPS)
@#printf " CXX $(*).cpp\n"
$(Q)$(CXX) $(TGT_CXXFLAGS) $(CXXFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $(*).o -c $(*).cpp
diff --git a/examples/stm32/f7/Makefile.include b/examples/stm32/f7/Makefile.include
new file mode 100644
index 00000000..ae7a2f0b
--- /dev/null
+++ b/examples/stm32/f7/Makefile.include
@@ -0,0 +1,44 @@
+##
+## This file is part of the libopencm3 project.
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see .
+##
+
+# You should use linker script generation! Specify device!
+ifeq ($(DEVICE),)
+LIBNAME = opencm3_stm32f7
+DEFS += -DSTM32F7
+
+FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv5-sp-d16
+ARCH_FLAGS = -mthumb -mcpu=cortex-m7 $(FP_FLAGS)
+endif
+
+################################################################################
+# OpenOCD specific variables
+
+OOCD ?= openocd
+OOCD_INTERFACE ?= stlink-v2-1
+OOCD_TARGET ?= stm32f7x
+
+################################################################################
+# Black Magic Probe specific variables
+# Set the BMP_PORT to a serial port and then BMP is used for flashing
+BMP_PORT ?=
+
+################################################################################
+# texane/stlink specific variables
+#STLINK_PORT ?= :4242
+
+
+include ../../../../rules.mk
diff --git a/examples/stm32/f7/stm32f769i-discovery/blinkled/Makefile b/examples/stm32/f7/stm32f769i-discovery/blinkled/Makefile
new file mode 100644
index 00000000..62842473
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/blinkled/Makefile
@@ -0,0 +1,9 @@
+OBJS = clock.o
+
+BINARY = application
+
+CFLAGS = -O3
+
+DEVICE = stm32f769nih6
+
+include ../../Makefile.include
diff --git a/examples/stm32/f7/stm32f769i-discovery/blinkled/README.md b/examples/stm32/f7/stm32f769i-discovery/blinkled/README.md
new file mode 100644
index 00000000..0679bea2
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/blinkled/README.md
@@ -0,0 +1,6 @@
+# README
+
+Demo of gpio and exti.
+
+This simple program uses the LEDs LD1-3 to show a grey-counter.
+By pressing the blue button, all the LEDs light up. On release, the counter restarts from 0.
diff --git a/examples/stm32/f7/stm32f769i-discovery/blinkled/application.c b/examples/stm32/f7/stm32f769i-discovery/blinkled/application.c
new file mode 100644
index 00000000..d51eca26
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/blinkled/application.c
@@ -0,0 +1,119 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include "clock.h"
+
+
+/**
+ * Function definitions
+ */
+static void pin_setup(void);
+static void update_led_counter(void);
+
+/**
+ * Setup functions
+ */
+#define LED_LD1 GPIOJ,GPIO13
+#define LED_LD2 GPIOJ,GPIO5
+#define LED_LD3 GPIOA,GPIO12
+#define BUTTON_BLUE GPIOA,GPIO0
+#define BUTTON_BLUE_PRESSED() gpio_get(BUTTON_BLUE)
+void pin_setup()
+{
+ /* pin-clocks */
+ rcc_periph_clock_enable(RCC_GPIOA);
+ rcc_periph_clock_enable(RCC_GPIOJ);
+
+ /* pins */
+ /* outputs (LEDs 1-3) */
+ gpio_mode_setup(GPIOJ, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO5 | GPIO13);
+ gpio_set_output_options(GPIOJ, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO5 | GPIO13);
+ gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO12);
+ gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO12);
+ /* inputs (blue button) */
+ gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO0);
+
+ /* setup blue/user button */
+ exti_select_source(EXTI0, GPIOA);
+ exti_set_trigger(EXTI0, EXTI_TRIGGER_BOTH);
+ exti_enable_request(EXTI0);
+ nvic_enable_irq(NVIC_EXTI0_IRQ);
+}
+
+/**
+ * Interrupts
+ */
+
+/* Blue button interrupt (EXTI makes not too much sense here :)) */
+static bool blue_button_state_changed = false;
+void exti0_isr()
+{
+ exti_reset_request(EXTI0);
+ blue_button_state_changed = true;
+ update_led_counter();
+}
+
+/**
+ * Functions
+ */
+void update_led_counter()
+{
+ /* little grey code blinker */
+ static const uint32_t gcl[] = {0,1,3,2,6,7,5,4};
+ static const uint32_t *gc = gcl;
+ static const uint32_t *gcle = gcl+sizeof(gcl)/sizeof(gcl[0])-1;
+ if (blue_button_state_changed) {
+ blue_button_state_changed = false;
+ gc = gcl;
+ }
+ if (BUTTON_BLUE_PRESSED()) {
+ gpio_set(LED_LD1);
+ gpio_set(LED_LD2);
+ gpio_set(LED_LD3);
+ } else {
+ if (*gc&0b001) gpio_set(LED_LD1);
+ else gpio_clear(LED_LD1);
+ if (*gc&0b010) gpio_set(LED_LD2);
+ else gpio_clear(LED_LD2);
+ if (*gc&0b100) gpio_set(LED_LD3);
+ else gpio_clear(LED_LD3);
+ if (gc==gcle) gc = gcl;
+ else gc++;
+ }
+}
+
+/**
+ * Main loop
+ */
+int main(void)
+{
+ /* init timers. */
+ clock_setup();
+ /* setup pins */
+ pin_setup();
+
+ while (1) {
+ msleep(1000);
+ update_led_counter();
+ }
+}
+
+
diff --git a/examples/stm32/f7/stm32f769i-discovery/blinkled/clock.c b/examples/stm32/f7/stm32f769i-discovery/blinkled/clock.c
new file mode 100644
index 00000000..2a793d49
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/blinkled/clock.c
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2014 Chuck McManis
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+/*
+ * Now this is just the clock setup code from systick-blink as it is the
+ * transferrable part.
+ */
+
+#include
+#include
+
+/* Common function descriptions */
+#include "clock.h"
+
+/* milliseconds since boot */
+static volatile uint64_t system_millis;
+
+/* Called when systick fires */
+void sys_tick_handler(void)
+{
+ system_millis++;
+}
+
+/* simple sleep for delay milliseconds */
+void msleep(uint32_t delay)
+{
+ uint64_t wake = system_millis + delay;
+ while (wake > system_millis) {
+ continue;
+ }
+}
+
+/* Getter function for the current time */
+uint64_t mtime(void)
+{
+ return system_millis;
+}
+
+/*
+ * clock_setup(void)
+ *
+ * This function sets up both the base board clock rate
+ * and a 1khz "system tick" count. The SYSTICK counter is
+ * a standard feature of the Cortex-M series.
+ */
+void clock_setup(void)
+{
+ /* Setup external clock */
+ rcc_clock_setup_hse(&CLOCK_SETUP, 25);
+
+ /* clock rate / CLOCK_SETUP.ahb_frequency * 1000 to get 1mS interrupt rate */
+ systick_set_reload(CLOCK_SETUP.ahb_frequency/1000);
+ systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
+ systick_counter_enable();
+
+ /* this done last */
+ systick_interrupt_enable();
+}
diff --git a/examples/stm32/f7/stm32f769i-discovery/blinkled/clock.h b/examples/stm32/f7/stm32f769i-discovery/blinkled/clock.h
new file mode 100644
index 00000000..5a2b5164
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/blinkled/clock.h
@@ -0,0 +1,38 @@
+/*
+ * This include file describes the functions exported by clock.c and the
+ * CLOCK_SETUP
+ *
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#ifndef __CLOCK_H
+#define __CLOCK_H
+
+#include
+
+#include
+
+#define CLOCK_SETUP rcc_3v3[RCC_CLOCK_3V3_216MHZ]
+
+/*
+ * Definitions for functions being abstracted out
+ */
+void msleep(uint32_t);
+uint64_t mtime(void);
+void clock_setup(void);
+
+#endif /* generic header protector */
+
diff --git a/examples/stm32/f7/stm32f769i-discovery/sdram/Makefile b/examples/stm32/f7/stm32f769i-discovery/sdram/Makefile
new file mode 100644
index 00000000..0bbe438f
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/sdram/Makefile
@@ -0,0 +1,11 @@
+BINARY = application
+
+OBJS = clock.o sdram.o
+OBJS += $(patsubst %.c, %.o, $(wildcard support/*.c))
+
+CFLAGS = -O3
+
+DEVICE = stm32f769nih6
+FP_FLAGS = -mfloat-abi=hard -mfpu=fpv5-d16
+
+include ../../Makefile.include
diff --git a/examples/stm32/f7/stm32f769i-discovery/sdram/README.md b/examples/stm32/f7/stm32f769i-discovery/sdram/README.md
new file mode 100644
index 00000000..c0b3a387
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/sdram/README.md
@@ -0,0 +1,8 @@
+# README
+
+Demo of sdram.
+
+This simple program first fills the whole ram area with consecutive numbers then checks if all the values were correctly set.
+If there were no errors, the green led lights up, otherwise the red LED lights up.
+
+By pressing the blue button, the test is started again.
diff --git a/examples/stm32/f7/stm32f769i-discovery/sdram/application.c b/examples/stm32/f7/stm32f769i-discovery/sdram/application.c
new file mode 100644
index 00000000..d0d17c83
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/sdram/application.c
@@ -0,0 +1,208 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include "clock.h"
+#include "sdram.h"
+
+/**
+ * Function definitions
+ */
+static void pin_setup(void);
+static void ram_test(void);
+
+/***********************************************************************
+ * Setup functions
+ */
+#define LED_LD1 GPIOJ,GPIO13
+#define LED_LD2 GPIOJ,GPIO5
+#define LED_LD3 GPIOA,GPIO12
+#define BUTTON_BLUE GPIOA,GPIO0
+#define BUTTON_BLUE_PRESSED() gpio_get(BUTTON_BLUE)
+void pin_setup()
+{
+ /* pin-clocks */
+ rcc_periph_clock_enable(RCC_GPIOA);
+ rcc_periph_clock_enable(RCC_GPIOJ);
+ /* pins */
+ /* outputs (LEDs 1-3) */
+ gpio_mode_setup(GPIOJ, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO5 | GPIO13);
+ gpio_set_output_options(GPIOJ, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO5 | GPIO13);
+ gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO12);
+ gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO12);
+ /* inputs (blue button) */
+ gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO0);
+ /* setup blue/user button */
+ exti_select_source(EXTI0, GPIOA);
+ exti_set_trigger(EXTI0, EXTI_TRIGGER_BOTH);
+ exti_enable_request(EXTI0);
+ nvic_enable_irq(NVIC_EXTI0_IRQ);
+
+ /* setup sdram clocks */
+ rcc_periph_clock_enable(RCC_FMC);
+ rcc_periph_clock_enable(RCC_GPIOD);
+ rcc_periph_clock_enable(RCC_GPIOE);
+ rcc_periph_clock_enable(RCC_GPIOF);
+ rcc_periph_clock_enable(RCC_GPIOG);
+ rcc_periph_clock_enable(RCC_GPIOH);
+ rcc_periph_clock_enable(RCC_GPIOI);
+
+ /* setup sdram pins */
+ gpio_mode_setup(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE,
+ GPIO0 | GPIO1 | GPIO8 | GPIO9 | GPIO10 | GPIO14 | GPIO15);
+ gpio_set_output_options(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
+ GPIO0 | GPIO1 | GPIO8 | GPIO9 | GPIO10 | GPIO14 | GPIO15);
+ gpio_set_af(GPIOD, GPIO_AF12,
+ GPIO0 | GPIO1 | GPIO8 | GPIO9 | GPIO10 | GPIO14 | GPIO15);
+
+ gpio_mode_setup(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE,
+ GPIO0 | GPIO1 | GPIO7 | GPIO8 | GPIO9 | GPIO10 |
+ GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15);
+ gpio_set_output_options(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
+ GPIO0 | GPIO1 | GPIO7 | GPIO8 | GPIO9 | GPIO10 |
+ GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15);
+ gpio_set_af(GPIOE, GPIO_AF12,
+ GPIO0 | GPIO1 | GPIO7 | GPIO8 | GPIO9 | GPIO10 |
+ GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15);
+
+ gpio_mode_setup(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE,
+ GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 |
+ GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15);
+ gpio_set_output_options(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
+ GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 |
+ GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15);
+ gpio_set_af(GPIOF, GPIO_AF12,
+ GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 |
+ GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15);
+
+ gpio_mode_setup(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE,
+ GPIO0 | GPIO1 | GPIO2 | GPIO4 | GPIO5 | GPIO8 | GPIO15);
+ gpio_set_output_options(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
+ GPIO0 | GPIO1 | GPIO2 | GPIO4 | GPIO5 | GPIO8 | GPIO15);
+ gpio_set_af(GPIOG, GPIO_AF12,
+ GPIO0 | GPIO1 | GPIO2 | GPIO4 | GPIO5 | GPIO8 | GPIO15);
+
+ gpio_mode_setup(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE,
+ GPIO2 | GPIO3 | GPIO5 | GPIO8 | GPIO9 | GPIO10 |
+ GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15);
+ gpio_set_output_options(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
+ GPIO2 | GPIO3 | GPIO5 | GPIO8 | GPIO9 | GPIO10 |
+ GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15);
+ gpio_set_af(GPIOH, GPIO_AF12,
+ GPIO2 | GPIO3 | GPIO5 | GPIO8 | GPIO9 | GPIO10 |
+ GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15);
+
+ gpio_mode_setup(GPIOI, GPIO_MODE_AF, GPIO_PUPD_NONE,
+ GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 |
+ GPIO6 | GPIO7 | GPIO9 | GPIO10);
+ gpio_set_output_options(GPIOI, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,
+ GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 |
+ GPIO6 | GPIO7 | GPIO9 | GPIO10);
+ gpio_set_af(GPIOI, GPIO_AF12,
+ GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 |
+ GPIO6 | GPIO7 | GPIO9 | GPIO10);
+}
+
+/***********************************************************************
+ * Interrupts
+ */
+
+/* Blue button interrupt */
+void exti0_isr()
+{
+ exti_reset_request(EXTI0);
+ /* Re-/start ram_test */
+ ram_test();
+}
+
+/***********************************************************************
+ * Functions
+ */
+
+/**
+ * Very simple ram checker
+ */
+void ram_test()
+{
+ /* Set error and success */
+ gpio_set(LED_LD1);
+ gpio_set(LED_LD2);
+
+ /* Iterate over the whole ram area */
+ uint32_t error_count=0;
+#define SDRAM_SIZE (0x1000000/sizeof(uint32_t))
+ uint32_t *sdram;
+
+ /* Write */
+ sdram = (uint32_t *)SDRAM1_BASE_ADDRESS;
+ for (uint32_t i = 0; i0) {
+ gpio_clear(LED_LD2);
+ } else {
+ gpio_clear(LED_LD1);
+ }
+}
+
+/***********************************************************************
+ * Main loop
+ */
+int main(void)
+{
+ /* Init timers. */
+ clock_setup();
+ /* Setup pins */
+ pin_setup();
+ /* Setup sdram */
+ sdram_init();
+ /* Run initial ram test */
+ ram_test();
+ /* Wait forever */
+ while (1) {}
+}
+
+
diff --git a/examples/stm32/f7/stm32f769i-discovery/sdram/clock.c b/examples/stm32/f7/stm32f769i-discovery/sdram/clock.c
new file mode 100644
index 00000000..2a793d49
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/sdram/clock.c
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2014 Chuck McManis
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+/*
+ * Now this is just the clock setup code from systick-blink as it is the
+ * transferrable part.
+ */
+
+#include
+#include
+
+/* Common function descriptions */
+#include "clock.h"
+
+/* milliseconds since boot */
+static volatile uint64_t system_millis;
+
+/* Called when systick fires */
+void sys_tick_handler(void)
+{
+ system_millis++;
+}
+
+/* simple sleep for delay milliseconds */
+void msleep(uint32_t delay)
+{
+ uint64_t wake = system_millis + delay;
+ while (wake > system_millis) {
+ continue;
+ }
+}
+
+/* Getter function for the current time */
+uint64_t mtime(void)
+{
+ return system_millis;
+}
+
+/*
+ * clock_setup(void)
+ *
+ * This function sets up both the base board clock rate
+ * and a 1khz "system tick" count. The SYSTICK counter is
+ * a standard feature of the Cortex-M series.
+ */
+void clock_setup(void)
+{
+ /* Setup external clock */
+ rcc_clock_setup_hse(&CLOCK_SETUP, 25);
+
+ /* clock rate / CLOCK_SETUP.ahb_frequency * 1000 to get 1mS interrupt rate */
+ systick_set_reload(CLOCK_SETUP.ahb_frequency/1000);
+ systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
+ systick_counter_enable();
+
+ /* this done last */
+ systick_interrupt_enable();
+}
diff --git a/examples/stm32/f7/stm32f769i-discovery/sdram/clock.h b/examples/stm32/f7/stm32f769i-discovery/sdram/clock.h
new file mode 100644
index 00000000..5a2b5164
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/sdram/clock.h
@@ -0,0 +1,38 @@
+/*
+ * This include file describes the functions exported by clock.c and the
+ * CLOCK_SETUP
+ *
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#ifndef __CLOCK_H
+#define __CLOCK_H
+
+#include
+
+#include
+
+#define CLOCK_SETUP rcc_3v3[RCC_CLOCK_3V3_216MHZ]
+
+/*
+ * Definitions for functions being abstracted out
+ */
+void msleep(uint32_t);
+uint64_t mtime(void);
+void clock_setup(void);
+
+#endif /* generic header protector */
+
diff --git a/examples/stm32/f7/stm32f769i-discovery/sdram/sdram.c b/examples/stm32/f7/stm32f769i-discovery/sdram/sdram.c
new file mode 100644
index 00000000..1ee583b1
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/sdram/sdram.c
@@ -0,0 +1,199 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2014 Chuck McManis
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#include "clock.h"
+#include "sdram.h"
+#include
+
+/*
+ * Initialize the SD RAM controller. (with default values)
+ */
+void
+sdram_init(void) {
+ /* Note the 32F769DISCOVERY board has the ram attached to bank 1 */
+ /* Timing parameters computed for a 216Mhz clock */
+ /* These parameters are specific to the SDRAM chip on the board */
+ sdram_init_custom(
+ SDRAM_BANK1,
+ 32,
+ 12,8,
+ (struct sdram_timing) {
+ .trcd = 2, /* RCD Delay */
+ .trp = 2, /* RP Delay */
+ .twr = 2, /* Write Recovery Time */
+ .trc = 7, /* Row Cycle Delay */
+ .tras = 4, /* Self Refresh Time */
+ .txsr = 7, /* Exit Self Refresh Time */
+ .tmrd = 2, /* Load to Active Delay */
+ },
+ 3,
+ false, false,
+ 2
+ );
+}
+void
+sdram_init_custom(
+ enum fmc_sdram_bank sdram_bank,
+ uint32_t memory_width,
+ uint32_t row_count, uint32_t column_count,
+ struct sdram_timing timing,
+ uint32_t cas_latency,
+ bool read_burst, bool write_burst,
+ uint32_t burst_length
+) {
+ uint32_t cr_tmp, tr_tmp; /* control, timing registers */
+ uint32_t cmd_tmp; /* sdram command */
+
+ cr_tmp = cmd_tmp = 0;
+
+ cr_tmp |= FMC_SDCR_RPIPE_1CLK;
+ cr_tmp |= FMC_SDCR_SDCLK_2HCLK;
+ cr_tmp |= FMC_SDCR_NB4; // sdram has 4 internal banks
+ switch (cas_latency) {
+ case 2:
+ cr_tmp |= FMC_SDCR_CAS_2CYC;
+ cmd_tmp |= SDRAM_MODE_CAS_LATENCY_2;
+ break;
+ case 3:
+ cr_tmp |= FMC_SDCR_CAS_3CYC;
+ cmd_tmp |= SDRAM_MODE_CAS_LATENCY_3;
+ break;
+ default:
+ assert("Invalid CAS latency");
+ break;
+ }
+ switch (memory_width) {
+ case 8:
+ cr_tmp |= FMC_SDCR_MWID_8b;
+ break;
+ case 16:
+ cr_tmp |= FMC_SDCR_MWID_16b;
+ break;
+ case 32:
+ cr_tmp |= FMC_SDCR_MWID_32b;
+ break;
+ default:
+ assert("Invalid memory width" && 0);
+ break;
+ }
+ switch (row_count) {
+ case 11:
+ cr_tmp |= FMC_SDCR_NR_11;
+ break;
+ case 12:
+ cr_tmp |= FMC_SDCR_NR_12;
+ break;
+ case 13:
+ cr_tmp |= FMC_SDCR_NR_13;
+ break;
+ default:
+ assert("Invalid row count" && 0);
+ break;
+ }
+ switch (column_count) {
+ case 8:
+ cr_tmp |= FMC_SDCR_NC_8;
+ break;
+ case 9:
+ cr_tmp |= FMC_SDCR_NC_9;
+ break;
+ case 10:
+ cr_tmp |= FMC_SDCR_NC_10;
+ break;
+ case 11:
+ cr_tmp |= FMC_SDCR_NC_11;
+ break;
+ default:
+ assert("Invalid column count" && 0);
+ break;
+ }
+ if (read_burst) {
+ cr_tmp |= FMC_SDCR_RBURST;
+ }
+
+ /* If we're programming BANK 2, but per the manual some of the parameters
+ * only work in CR1 and TR1 so we pull those off and put them in the
+ * right place.
+ */
+ tr_tmp = sdram_timing(&timing);
+ if ((sdram_bank==SDRAM_BANK1)||(sdram_bank==SDRAM_BOTH_BANKS)) {
+ FMC_SDCR1 = cr_tmp;
+ FMC_SDTR1 = tr_tmp;
+ } else
+ if (sdram_bank==SDRAM_BANK2) {
+ FMC_SDCR1 |= (cr_tmp & FMC_SDCR_DNC_MASK);
+ FMC_SDTR1 |= (tr_tmp & FMC_SDTR_DNC_MASK);
+ } else {
+ assert(0);
+ }
+ if ((sdram_bank==SDRAM_BANK2)||(sdram_bank==SDRAM_BOTH_BANKS)) {
+ FMC_SDCR2 = cr_tmp;
+ FMC_SDTR2 = tr_tmp;
+ }
+
+ /* Now start up the Controller per the manual
+ * - Clock config enable
+ * - PALL state
+ * - set auto refresh
+ * - Load the Mode Register
+ */
+ sdram_command(sdram_bank, SDRAM_CLK_CONF, 1, 0);
+ msleep(1); /* sleep at least 200uS */
+ sdram_command(sdram_bank, SDRAM_PALL, 1, 0);
+ msleep(1); /* ? sleep >100uS */
+ sdram_command(sdram_bank, SDRAM_AUTO_REFRESH, 7, 0);
+ msleep(1); /* ?? sleep >100uS */
+
+ cmd_tmp |= SDRAM_MODE_BURST_TYPE_SEQUENTIAL |
+ SDRAM_MODE_OPERATING_MODE_STANDARD;
+ if (write_burst) {
+ cmd_tmp |= SDRAM_MODE_WRITEBURST_MODE_PROGRAMMED;
+ } else {
+ cmd_tmp |= SDRAM_MODE_WRITEBURST_MODE_SINGLE;
+ }
+ switch (burst_length) {
+ case 1:
+ cmd_tmp |= SDRAM_MODE_BURST_LENGTH_1;
+ break;
+ case 2:
+ cmd_tmp |= SDRAM_MODE_BURST_LENGTH_2;
+ break;
+ case 4:
+ cmd_tmp |= SDRAM_MODE_BURST_LENGTH_4;
+ break;
+ case 8:
+ cmd_tmp |= SDRAM_MODE_BURST_LENGTH_8;
+ break;
+ default:
+ assert("Invalid burst length");
+ break;
+ }
+ sdram_command(sdram_bank, SDRAM_LOAD_MODE, 1, cmd_tmp);
+
+
+ msleep(1); /* ?? sleep >100uS */
+ sdram_command(sdram_bank, SDRAM_NORMAL, 0, 0);
+
+ /*
+ * set the refresh counter to insure we kick off an
+ * auto refresh often enough to prevent data loss.
+ */
+ FMC_SDRTR = 683; // 128mbit // 64ms/(1<<13)*216MHz/2-20
+ /* and Poof! a 16 megabytes of ram shows up in the address space */
+}
diff --git a/examples/stm32/f7/stm32f769i-discovery/sdram/sdram.h b/examples/stm32/f7/stm32f769i-discovery/sdram/sdram.h
new file mode 100644
index 00000000..96ac8710
--- /dev/null
+++ b/examples/stm32/f7/stm32f769i-discovery/sdram/sdram.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2014 Chuck McManis
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#ifndef __SDRAM_H
+#define __SDRAM_H
+
+#include
+#include
+#include
+#include
+
+#define SDRAM1_BASE_ADDRESS (0xc0000000U)
+#define SDRAM2_BASE_ADDRESS (0xd0000000U)
+
+/* Initialize the SDRAM chip on the board */
+void sdram_init(void);
+void sdram_init_custom(
+ enum fmc_sdram_bank sdram_bank,
+ uint32_t memory_width,
+ uint32_t row_count, uint32_t column_count,
+ struct sdram_timing timing,
+ uint32_t cas_latency,
+ bool read_burst, bool write_burst,
+ uint32_t burst_length
+);
+
+#ifndef NULL
+#define NULL (void *)(0)
+#endif
+
+#endif
diff --git a/examples/stm32/l4/Makefile.include b/examples/stm32/l4/Makefile.include
new file mode 100644
index 00000000..9faee860
--- /dev/null
+++ b/examples/stm32/l4/Makefile.include
@@ -0,0 +1,44 @@
+##
+## This file is part of the libopencm3 project.
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see .
+##
+
+# You should use linker script generation! Specify device!
+ifeq ($(DEVICE),)
+LIBNAME = opencm3_stm32l4
+DEFS += -DSTM32L4
+
+FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv5-sp-d16
+ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS)
+endif
+
+################################################################################
+# OpenOCD specific variables
+
+OOCD ?= openocd
+OOCD_INTERFACE ?= stlink-v2-1
+OOCD_TARGET ?= stm32l4x
+
+################################################################################
+# Black Magic Probe specific variables
+# Set the BMP_PORT to a serial port and then BMP is used for flashing
+BMP_PORT ?=
+
+################################################################################
+# texane/stlink specific variables
+#STLINK_PORT ?= :4242
+
+
+include ../../../../rules.mk