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