Initial commit.

This commit is contained in:
Piotr Esden-Tempski
2013-04-19 17:19:32 -07:00
commit 9d5526f773
324 changed files with 22845 additions and 0 deletions

View File

@@ -0,0 +1,168 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
##
## 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 <http://www.gnu.org/licenses/>.
##
PREFIX ?= arm-none-eabi
#PREFIX ?= arm-elf
CC = $(PREFIX)-gcc
LD = $(PREFIX)-gcc
OBJCOPY = $(PREFIX)-objcopy
OBJDUMP = $(PREFIX)-objdump
GDB = $(PREFIX)-gdb
TOOLCHAIN_DIR ?= ../../../../..
ifeq ($(wildcard ../../../../../lib/libopencm3_stm32l1.a),)
ifneq ($(strip $(shell which $(CC))),)
TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX)
endif
else
ifeq ($(V),1)
$(info We seem to be building the example in the source directory. Using local library!)
endif
endif
ARCH_FLAGS = -mthumb -mcpu=cortex-m3 -msoft-float
CFLAGS += -Os -g \
-Wall -Wextra -Wimplicit-function-declaration \
-Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
-Wundef -Wshadow \
-I$(TOOLCHAIN_DIR)/include \
-fno-common $(ARCH_FLAGS) -MD -DSTM32L1
LDSCRIPT ?= $(BINARY).ld
LDFLAGS += --static -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group \
-L$(TOOLCHAIN_DIR)/lib \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \
$(ARCH_FLAGS) -mfix-cortex-m3-ldrd
CFLAGS += -I$(TOOLCHAIN_DIR)/include
LDFLAGS += -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib/stm32/l1
SCRIPT_DIR = $(TOOLCHAIN_DIR)/share
OBJS += $(BINARY).o
OOCD ?= openocd
OOCD_INTERFACE ?= flossjtag
OOCD_BOARD ?= olimex_stm32_h103
# Black magic probe specific variables
# Set the BMP_PORT to a serial port and then BMP is used for flashing
BMP_PORT ?=
# texane/stlink can be used by uncommenting this...
# or defining it in your own makefiles
#STLINK_PORT ?= :4242
# Be silent per default, but 'make V=1' will show all compiler calls.
ifneq ($(V),1)
Q := @
NULL := 2>/dev/null
else
LDFLAGS += -Wl,--print-gc-sections
endif
.SUFFIXES: .elf .bin .hex .srec .list .images
.SECONDEXPANSION:
.SECONDARY:
all: images
images: $(BINARY).images
flash: $(BINARY).flash
%.images: %.bin %.hex %.srec %.list
@#echo "*** $* images generated ***"
%.bin: %.elf
@#printf " OBJCOPY $(*).bin\n"
$(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin
%.hex: %.elf
@#printf " OBJCOPY $(*).hex\n"
$(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex
%.srec: %.elf
@#printf " OBJCOPY $(*).srec\n"
$(Q)$(OBJCOPY) -Osrec $(*).elf $(*).srec
%.list: %.elf
@#printf " OBJDUMP $(*).list\n"
$(Q)$(OBJDUMP) -S $(*).elf > $(*).list
%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_stm32l1.a
@#printf " LD $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(LD) -o $(*).elf $(OBJS) -lopencm3_stm32l1 $(LDFLAGS)
%.o: %.c Makefile
@#printf " CC $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(CC) $(CFLAGS) -o $@ -c $<
clean:
$(Q)rm -f *.o
$(Q)rm -f *.d
$(Q)rm -f *.elf
$(Q)rm -f *.bin
$(Q)rm -f *.hex
$(Q)rm -f *.srec
$(Q)rm -f *.list
ifeq ($(STLINK_PORT),)
ifeq ($(BMP_PORT),)
ifeq ($(OOCD_SERIAL),)
%.flash: %.hex
@printf " FLASH $<\n"
@# IMPORTANT: Don't use "resume", only "reset" will work correctly!
$(Q)$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \
-f board/$(OOCD_BOARD).cfg \
-c "init" -c "reset init" \
-c "stm32l1x mass_erase 0" \
-c "flash write_image $(*).hex" \
-c "reset" \
-c "shutdown" $(NULL)
else
%.flash: %.hex
@printf " FLASH $<\n"
@# IMPORTANT: Don't use "resume", only "reset" will work correctly!
$(Q)$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \
-f board/$(OOCD_BOARD).cfg \
-c "ft2232_serial $(OOCD_SERIAL)" \
-c "init" -c "reset init" \
-c "stm32l1x mass_erase 0" \
-c "flash write_image $(*).hex" \
-c "reset" \
-c "shutdown" $(NULL)
endif
else
%.flash: %.elf
@echo " GDB $(*).elf (flash)"
$(Q)$(GDB) --batch \
-ex 'target extended-remote $(BMP_PORT)' \
-x $(TOOLCHAIN_DIR)/scripts/black_magic_probe_flash.scr \
$(*).elf
endif
else
%.flash: %.elf
@echo " GDB $(*).elf (flash)"
$(Q)$(GDB) --batch \
-ex 'target extended-remote $(STLINK_PORT)' \
-x $(SCRIPT_DIR)/libopencm3/scripts/stlink_flash.scr \
$(*).elf
endif
.PHONY: images clean
-include $(OBJS:.o=.d)

View File

@@ -0,0 +1,24 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
BINARY = main
LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld
include ../../Makefile.include

View File

@@ -0,0 +1,18 @@
This is _functionally_ identical to the "button-irq-printf"
example, but has been modified to use some low power features.
There is a 115200@8n1 console on PA2, which prints a tick count every second,
and when the user push button is pressed, the time it is held down for is
timed (in milliseconds)
Instead of free running timers and busy loops, this version uses the RTC
module and attempts to sleep as much as possible, including while the button
is pressed.
Status
~~~~~~
Only very basic power savings are done!
Current consumption, led off/on, 16Mhz HSI: 2.7mA/5.4mA
Current consumption, led off/on, 4Mhz HSI: 1.4mA/?.?mA
Current consumption, led off/on, 4Mhz MSI: 0.9mA/?.?mA

View File

@@ -0,0 +1,302 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/cm3/scb.h>
#include <libopencm3/stm32/dbgmcu.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/pwr.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/rtc.h>
#include <libopencm3/stm32/l1/rcc.h>
#include <libopencm3/stm32/l1/flash.h>
#include "syscfg.h"
static volatile struct state_t state;
int _write(int file, char *ptr, int len);
__attribute__((always_inline)) static inline void __WFI(void)
{
__asm volatile ("wfi");
}
static void gpio_setup(void)
{
/* green led for ticking, blue for button feedback */
gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_GREEN_PIN);
gpio_mode_setup(LED_DISCO_BLUE_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_BLUE_PIN);
/* Setup GPIO pins for USART2 transmit. */
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2);
/* Setup USART2 TX pin as alternate function. */
gpio_set_af(GPIOA, GPIO_AF7, GPIO2);
}
void BUTTON_DISCO_USER_isr(void)
{
exti_reset_request(BUTTON_DISCO_USER_EXTI);
state.pressed = true;
if (state.falling) {
state.falling = false;
exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING);
state.hold_time = TIM_CNT(TIMER_BUTTON_PRESS);
} else {
state.falling = true;
exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_FALLING);
state.hold_time = TIM_CNT(TIMER_BUTTON_PRESS) = 0;
}
}
static void setup_buttons(void)
{
/* Enable EXTI0 interrupt. */
nvic_enable_irq(BUTTON_DISCO_USER_NVIC);
gpio_mode_setup(BUTTON_DISCO_USER_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, BUTTON_DISCO_USER_PIN);
/* Configure the EXTI subsystem. */
exti_select_source(BUTTON_DISCO_USER_EXTI, BUTTON_DISCO_USER_PORT);
state.falling = false;
exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING);
exti_enable_request(BUTTON_DISCO_USER_EXTI);
}
static void usart_setup(void)
{
usart_set_baudrate(USART_CONSOLE, 115200);
usart_set_databits(USART_CONSOLE, 8);
usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1);
usart_set_mode(USART_CONSOLE, USART_MODE_TX);
usart_set_parity(USART_CONSOLE, USART_PARITY_NONE);
usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE);
/* Finally enable the USART. */
usart_enable(USART_CONSOLE);
}
/**
* Use USART_CONSOLE as a console.
* @param file
* @param ptr
* @param len
* @return
*/
int _write(int file, char *ptr, int len)
{
int i;
if (file == STDOUT_FILENO || file == STDERR_FILENO) {
for (i = 0; i < len; i++) {
if (ptr[i] == '\n') {
usart_send_blocking(USART_CONSOLE, '\r');
}
usart_send_blocking(USART_CONSOLE, ptr[i]);
}
return i;
}
errno = EIO;
return -1;
}
/*
* Free running ms timer.
*/
static void setup_button_press_timer(void)
{
timer_reset(TIMER_BUTTON_PRESS);
timer_set_prescaler(TIMER_BUTTON_PRESS, 3999); // 4Mhz/1000hz - 1
timer_set_period(TIMER_BUTTON_PRESS, 0xffff);
timer_enable_counter(TIMER_BUTTON_PRESS);
}
static int setup_rtc(void)
{
/* turn on power block to enable unlocking */
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_PWREN);
pwr_disable_backup_domain_write_protect();
/* reset rtc */
RCC_CSR |= RCC_CSR_RTCRST;
RCC_CSR &= ~RCC_CSR_RTCRST;
/* We want to use the LSE fitted on the discovery board */
rcc_osc_on(LSE);
rcc_wait_for_osc_ready(LSE);
/* Select the LSE as rtc clock */
rcc_rtc_select_clock(RCC_CSR_RTCSEL_LSE);
/* ?! Stdperiph examples don't turn this on until _afterwards_ which
* simply doesn't work. It must be on at least to be able to configure it */
RCC_CSR |= RCC_CSR_RTCEN;
rtc_unlock();
/* enter init mode */
RTC_ISR |= RTC_ISR_INIT;
while ((RTC_ISR & RTC_ISR_INITF) == 0)
;
/* set synch prescaler, using defaults for 1Hz out */
u32 sync = 255;
u32 async = 127;
rtc_set_prescaler(sync, async);
/* load time and date here if desired, and hour format */
/* exit init mode */
RTC_ISR &= ~(RTC_ISR_INIT);
/* and write protect again */
rtc_lock();
/* and finally enable the clock */
RCC_CSR |= RCC_CSR_RTCEN;
/* And wait for synchro.. */
rtc_wait_for_synchro();
return 0;
}
static int setup_rtc_wakeup(int period)
{
rtc_unlock();
/* ensure wakeup timer is off */
RTC_CR &= ~RTC_CR_WUTE;
/* Wait until we can write */
while ((RTC_ISR & RTC_ISR_WUTWF) == 0)
;
RTC_WUTR = period - 1;
/* Use the 1Hz clock as source */
RTC_CR &= ~(RTC_CR_WUCLKSEL_MASK << RTC_CR_WUCLKSEL_SHIFT);
RTC_CR |= (RTC_CR_WUCLKSEL_SPRE << RTC_CR_WUCLKSEL_SHIFT);
/* Restart WakeUp unit */
RTC_CR |= RTC_CR_WUTE;
/* interrupt configuration */
/* also, let's have an interrupt */
RTC_CR |= RTC_CR_WUTIE;
/* done with rtc registers, lock them again */
rtc_lock();
nvic_enable_irq(NVIC_RTC_WKUP_IRQ);
// EXTI configuration
/* Configure the EXTI subsystem. */
// not needed, this chooses ports exti_select_source(EXTI20, BUTTON_DISCO_USER_PORT);
exti_set_trigger(EXTI20, EXTI_TRIGGER_RISING);
exti_enable_request(EXTI20);
return 0;
}
void rtc_wkup_isr(void)
{
/* clear flag, not write protected */
RTC_ISR &= ~(RTC_ISR_WUTF);
exti_reset_request(EXTI20);
state.rtc_ticked = true;
}
static int process_state(volatile struct state_t *st)
{
if (st->rtc_ticked) {
st->rtc_ticked = 0;
printf("Tick: %x\n", (unsigned int) RTC_TR);
#if defined(FULL_USER_EXPERIENCE)
gpio_toggle(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN);
#else
gpio_clear(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN);
#endif
}
if (st->pressed) {
st->pressed = false;
if (st->falling) {
gpio_set(LED_DISCO_BLUE_PORT, LED_DISCO_BLUE_PIN);
printf("Pushed down!\n");
} else {
gpio_clear(LED_DISCO_BLUE_PORT, LED_DISCO_BLUE_PIN);
printf("held: %u ms\n", st->hold_time);
}
}
return 0;
}
static void reset_clocks(void)
{
/* 4MHz MSI raw range 2*/
clock_scale_t myclock_config = {
.hpre = RCC_CFGR_HPRE_SYSCLK_NODIV,
.ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV,
.ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV,
.voltage_scale = RANGE2,
.flash_config = FLASH_ACR_LATENCY_0WS,
.apb1_frequency = 4194000,
.apb2_frequency = 4194000,
.msi_range = RCC_ICSCR_MSIRANGE_4MHZ,
};
rcc_clock_setup_msi(&myclock_config);
/* buttons and uarts */
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN);
/* user feedback leds */
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN);
/* Enable clocks for USART2. */
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN);
/* And a timers for button presses */
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM7EN);
}
int main(void)
{
reset_clocks();
gpio_setup();
usart_setup();
setup_buttons();
setup_button_press_timer();
printf("we're awake!\n");
setup_rtc();
setup_rtc_wakeup(1);
while (1) {
PWR_CR |= PWR_CR_LPSDSR;
pwr_set_stop_mode();
__WFI();
reset_clocks();
process_state(&state);
}
return 0;
}

View File

@@ -0,0 +1,61 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef SYSCFG_H
#define SYSCFG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/usart.h>
#define USART_CONSOLE USART2
#define USE_NASTYLOG 1
#define LED_DISCO_GREEN_PORT GPIOB
#define LED_DISCO_GREEN_PIN GPIO7
#define LED_DISCO_BLUE_PORT GPIOB
#define LED_DISCO_BLUE_PIN GPIO6
#define BUTTON_DISCO_USER_PORT GPIOA
#define BUTTON_DISCO_USER_PIN GPIO0
#define BUTTON_DISCO_USER_EXTI EXTI0
#define BUTTON_DISCO_USER_isr exti0_isr
#define BUTTON_DISCO_USER_NVIC NVIC_EXTI0_IRQ
#define TIMER_BUTTON_PRESS TIM7
struct state_t {
bool falling;
bool pressed;
int rtc_ticked;
int hold_time;
};
#ifdef __cplusplus
}
#endif
#endif /* SYSCFG_H */

View File

@@ -0,0 +1,24 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
BINARY = main
LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld
include ../../Makefile.include

View File

@@ -0,0 +1,35 @@
* Prints to the screen when the button is pushed/released (irq driven)
115200@8n1 console on PA2 (tx only)
* uses basic timer 6 with overflows to generate a 1ms counter (not an ideal
use, but shows some api methods and can be demoed on the disco board)
* uses basic timer 7 with the exti interrupts to do ghetto input capture.
Not as fast or precise as the real input capture modes, but can be used
on any gpio pin.
No effort at saving power is made here. Current consumption on the Disco board
is ~7.5mA when the green tick led is off, and about 10.5mA when it is on.
example output:
hi guys!
TICK 0
TICK 1
TICK 2
Pushed down!
held: 443 ms
Pushed down!
TICK 3
held: 217 ms
Pushed down!
held: 99 ms
Pushed down!
TICK 4
held: 73 ms
Pushed down!
held: 60 ms
TICK 5
Pushed down!
held: 98 ms
Pushed down!

View File

@@ -0,0 +1,189 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/l1/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/usart.h>
#include "syscfg.h"
static struct state_t state;
int _write(int file, char *ptr, int len);
static void clock_setup(void)
{
rcc_clock_setup_pll(&clock_config[CLOCK_VRANGE1_HSI_PLL_24MHZ]);
/* Lots of things on all ports... */
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN);
/* Enable clocks for USART2. */
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN);
/* And timers. */
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM6EN);
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM7EN);
}
static void gpio_setup(void)
{
/* green led for ticking, blue for button feedback */
gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_GREEN_PIN);
gpio_mode_setup(LED_DISCO_BLUE_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_BLUE_PIN);
/* Setup GPIO pins for USART2 transmit. */
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2);
/* Setup USART2 TX pin as alternate function. */
gpio_set_af(GPIOA, GPIO_AF7, GPIO2);
}
static void usart_setup(void)
{
usart_set_baudrate(USART_CONSOLE, 115200);
usart_set_databits(USART_CONSOLE, 8);
usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1);
usart_set_mode(USART_CONSOLE, USART_MODE_TX);
usart_set_parity(USART_CONSOLE, USART_PARITY_NONE);
usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE);
/* Finally enable the USART. */
usart_enable(USART_CONSOLE);
}
/**
* Use USART_CONSOLE as a console.
* @param file
* @param ptr
* @param len
* @return
*/
int _write(int file, char *ptr, int len)
{
int i;
if (file == STDOUT_FILENO || file == STDERR_FILENO) {
for (i = 0; i < len; i++) {
if (ptr[i] == '\n') {
usart_send_blocking(USART_CONSOLE, '\r');
}
usart_send_blocking(USART_CONSOLE, ptr[i]);
}
return i;
}
errno = EIO;
return -1;
}
void BUTTON_DISCO_USER_isr(void)
{
exti_reset_request(BUTTON_DISCO_USER_EXTI);
if (state.falling) {
gpio_clear(LED_DISCO_BLUE_PORT, LED_DISCO_BLUE_PIN);
state.falling = false;
exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING);
unsigned int x = TIM_CNT(TIM7);
printf("held: %u ms\n", x);
} else {
gpio_set(LED_DISCO_BLUE_PORT, LED_DISCO_BLUE_PIN);
printf("Pushed down!\n");
TIM_CNT(TIM7) = 0;
state.falling = true;
exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_FALLING);
}
}
static volatile int t6ovf = 0;
void tim6_isr(void)
{
TIM_SR(TIM6) &= ~TIM_SR_UIF;
if (t6ovf++ > 1000) {
printf("TICK %d\n", state.tickcount++);
t6ovf = 0;
gpio_toggle(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN);
}
}
/*
* Another ms timer, this one used to generate an overflow interrupt at 1ms
* It is used to toggle leds and write tick counts
*/
static void setup_tim6(void)
{
timer_reset(TIM6);
// 24Mhz / 10khz -1.
timer_set_prescaler(TIM6, 2399); // 24Mhz/10000hz - 1
// 10khz for 10 ticks = 1 khz overflow = 1ms overflow interrupts
timer_set_period(TIM6, 10);
nvic_enable_irq(NVIC_TIM6_IRQ);
timer_enable_update_event(TIM6); // default at reset!
timer_enable_irq(TIM6, TIM_DIER_UIE);
timer_enable_counter(TIM6);
}
/*
* Free running ms timer.
*/
static void setup_tim7(void)
{
timer_reset(TIM7);
timer_set_prescaler(TIM7, 23999); // 24Mhz/1000hz - 1
timer_set_period(TIM7, 0xffff);
timer_enable_counter(TIM7);
}
static void setup_buttons(void)
{
/* Enable EXTI0 interrupt. */
nvic_enable_irq(BUTTON_DISCO_USER_NVIC);
gpio_mode_setup(BUTTON_DISCO_USER_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, BUTTON_DISCO_USER_PIN);
/* Configure the EXTI subsystem. */
exti_select_source(BUTTON_DISCO_USER_EXTI, BUTTON_DISCO_USER_PORT);
state.falling = false;
exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING);
exti_enable_request(BUTTON_DISCO_USER_EXTI);
}
int main(void)
{
clock_setup();
gpio_setup();
usart_setup();
printf("hi guys!\n");
setup_buttons();
setup_tim6();
setup_tim7();
while (1) {
;
}
return 0;
}

View File

@@ -0,0 +1,58 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef SYSCFG_H
#define SYSCFG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/usart.h>
#define USART_CONSOLE USART2
#define USE_NASTYLOG 1
#define LED_DISCO_GREEN_PORT GPIOB
#define LED_DISCO_GREEN_PIN GPIO7
#define LED_DISCO_BLUE_PORT GPIOB
#define LED_DISCO_BLUE_PIN GPIO6
#define BUTTON_DISCO_USER_PORT GPIOA
#define BUTTON_DISCO_USER_PIN GPIO0
#define BUTTON_DISCO_USER_EXTI EXTI0
#define BUTTON_DISCO_USER_isr exti0_isr
#define BUTTON_DISCO_USER_NVIC NVIC_EXTI0_IRQ
struct state_t {
bool falling;
int tickcount;
};
#ifdef __cplusplus
}
#endif
#endif /* SYSCFG_H */

View File

@@ -0,0 +1,25 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
BINARY = miniblink
LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld
include ../../Makefile.include

View File

@@ -0,0 +1,9 @@
------------------------------------------------------------------------------
README
------------------------------------------------------------------------------
This is the smallest-possible example program using libopencm3.
It's intended for the ST STM32L-DISCOVERY eval board. It should blink
the blue LED on the board.

View File

@@ -0,0 +1,72 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
* Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com>
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/stm32/l1/rcc.h>
#include <libopencm3/stm32/l1/gpio.h>
#define PORT_LED GPIOB
#define PIN_LED GPIO6
static void gpio_setup(void)
{
/* Enable GPIOB clock. */
/* Manually: */
//RCC_AHBENR |= RCC_AHBENR_GPIOBEN;
/* Using API functions: */
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN);
/* Set GPIO6 (in GPIO port B) to 'output push-pull'. */
/* Using API functions: */
gpio_mode_setup(PORT_LED, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED);
}
int main(void)
{
int i;
gpio_setup();
/* Blink the LED (PC8) on the board. */
while (1) {
/* Manually: */
// GPIOD_BSRR = GPIO12; /* LED off */
// for (i = 0; i < 1000000; i++) /* Wait a bit. */
// __asm__("nop");
// GPIOD_BRR = GPIO12; /* LED on */
// for (i = 0; i < 1000000; i++) /* Wait a bit. */
// __asm__("nop");
/* Using API functions gpio_set()/gpio_clear(): */
// gpio_set(GPIOD, GPIO12); /* LED off */
// for (i = 0; i < 1000000; i++) /* Wait a bit. */
// __asm__("nop");
// gpio_clear(GPIOD, GPIO12); /* LED on */
// for (i = 0; i < 1000000; i++) /* Wait a bit. */
// __asm__("nop");
/* Using API function gpio_toggle(): */
gpio_toggle(PORT_LED, PIN_LED); /* LED on/off */
for (i = 0; i < 1000000; i++) /* Wait a bit. */
__asm__("nop");
}
return 0;
}

View File

@@ -0,0 +1,25 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
##
## 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 <http://www.gnu.org/licenses/>.
##
BINARY = usart
LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld
include ../../Makefile.include

View File

@@ -0,0 +1,12 @@
------------------------------------------------------------------------------
README
------------------------------------------------------------------------------
This example program sends some characters on USART2 on the
ST STM32L DISCOVERY eval board. (USART2 TX on PA2)
The terminal settings for the receiving device/PC are 38400 8n1.
The sending is done in a blocking way in the code, see the usart_irq example
for a more elaborate USART example.

View File

@@ -0,0 +1,84 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
* Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/stm32/l1/rcc.h>
#include <libopencm3/stm32/l1/gpio.h>
#include <libopencm3/stm32/usart.h>
static void clock_setup(void)
{
/* We are running on MSI after boot. */
/* Enable GPIOD clock for LED & USARTs. */
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN);
/* Enable clocks for USART2. */
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN);
}
static void usart_setup(void)
{
/* Setup USART2 parameters. */
usart_set_baudrate(USART2, 38400);
usart_set_databits(USART2, 8);
usart_set_stopbits(USART2, USART_STOPBITS_1);
usart_set_mode(USART2, USART_MODE_TX);
usart_set_parity(USART2, USART_PARITY_NONE);
usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
/* Finally enable the USART. */
usart_enable(USART2);
}
static void gpio_setup(void)
{
/* Setup GPIO pin GPIO7 on GPIO port B for Green LED. */
gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO7);
/* Setup GPIO pins for USART2 transmit. */
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2);
/* Setup USART2 TX pin as alternate function. */
gpio_set_af(GPIOA, GPIO_AF7, GPIO2);
}
int main(void)
{
int i, j = 0, c = 0;
clock_setup();
gpio_setup();
usart_setup();
/* Blink the LED (PD12) on the board with every transmitted byte. */
while (1) {
gpio_toggle(GPIOB, GPIO7); /* LED on/off */
usart_send_blocking(USART2, c + '0'); /* USART2: Send byte. */
c = (c == 9) ? 0 : c + 1; /* Increment c. */
if ((j++ % 80) == 0) { /* Newline after line full. */
usart_send_blocking(USART2, '\r');
usart_send_blocking(USART2, '\n');
}
for (i = 0; i < 100000; i++) /* Wait a bit. */
__asm__("NOP");
}
return 0;
}