Enable nvic and exti support for L1

And include an example that uses it.
This commit is contained in:
Karl Palsson 2012-10-22 23:32:42 +00:00
parent b860504fed
commit ce8f47e7df
12 changed files with 215 additions and 197 deletions

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,4 @@
* Counts how long the user button was held down (in ms)
* Uses one free running counter plus EXTI as an ugly input capture
115200@8n1 console on PA2 (tx only)

View File

@ -0,0 +1,117 @@
/*
* Karl Palsson, 2012 <karlp@tweak.net.au
*/
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/l1/rcc.h>
#include <libopencm3/stm32/l1/gpio.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/usart.h>
#include "syscfg.h"
static struct state_t state;
void clock_setup(void) {
/* 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);
}
void gpio_setup(void) {
gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_GREEN_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 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) {
state.falling = false;
exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING);
// ILOG("fell: %d\n", TIM_CNT(TIM7));
puts("fell!\n");
} else {
puts("Rose!\n");
// TIM_CNT(TIM7) = 0;
state.falling = true;
exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_FALLING);
}
}
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) {
int i;
int j = 0;
clock_setup();
gpio_setup();
usart_setup();
puts("hi guys!\n");
setup_buttons();
while (1) {
puts("tick:");
putchar('a' + (j++ % 26));
gpio_toggle(GPIOB, GPIO7); /* LED on/off */
for (i = 0; i < 100000; i++) /* Wait a bit. */
__asm__("NOP");
}
return 0;
}

View File

@ -0,0 +1,45 @@
/*
* General configuration of the device
*
* Karl Palsson <karlp@tweak.net.au> 2012
*/
#ifndef SYSCFG_H
#define SYSCFG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <libopencm3/stm32/l1/gpio.h>
#include <libopencm3/stm32/nvic.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;
};
#ifdef __cplusplus
}
#endif
#endif /* SYSCFG_H */

View File

@ -1,46 +0,0 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
*
* 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 LIBOPENCM3_SYSCFG_H
#define LIBOPENCM3_SYSCFG_H
#include <libopencm3/stm32/memorymap.h>
/* --- SYSCFG registers ------------------------------------------------------ */
#define SYSCFG_MEMRM MMIO32(SYSCFG_BASE + 0x00)
#define SYSCFG_PMC MMIO32(SYSCFG_BASE + 0x04)
/* External interrupt configuration register 1 (SYSCFG_EXTICR1) */
#define SYSCFG_EXTICR1 MMIO32(SYSCFG_BASE + 0x08)
/* External interrupt configuration register 2 (SYSCFG_EXTICR2) */
#define SYSCFG_EXTICR2 MMIO32(SYSCFG_BASE + 0x0c)
/* External interrupt configuration register 3 (SYSCFG_EXTICR3) */
#define SYSCFG_EXTICR3 MMIO32(SYSCFG_BASE + 0x10)
/* External interrupt configuration register 4 (SYSCFG_EXTICR4) */
#define SYSCFG_EXTICR4 MMIO32(SYSCFG_BASE + 0x14)
#define SYSCFG_CMPCR MMIO32(SYSCFG_BASE + 0x20)
#endif

View File

@ -4,6 +4,8 @@
# include "../stm32/f2/vector_nvic.c"
#elif defined(STM32F4)
# include "../stm32/f4/vector_nvic.c"
#elif defined(STM32L1)
# include "../stm32/l1/vector_nvic.c"
#elif defined(EFM32TG)
# include "../efm32/efm32tg/vector_nvic.c"

View File

@ -2,6 +2,7 @@
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz>
* 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
@ -15,11 +16,22 @@
*
* 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/>.
*
* This provides the code for the "next gen" EXTI block provided in F2/F4/L1
* devices. (differences only in the source selection)
*/
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/f4/syscfg.h>
#include <libopencm3/stm32/syscfg.h>
#if defined(STM32F2)
#include <libopencm3/stm32/f2/gpio.h>
#elif defined(STM32F4)
#include <libopencm3/stm32/f4/gpio.h>
#elif defined(STM32L1)
#include <libopencm3/stm32/l1/gpio.h>
#else
#error "invalid/unknown stm32 family for this code"
#endif
void exti_set_trigger(u32 extis, exti_trigger_type trig)
{
@ -121,18 +133,24 @@ void exti_select_source(u32 exti, u32 gpioport)
case GPIOE:
bits = 0xb;
break;
#if defined(STM32L1)
#else
case GPIOF:
bits = 0xa;
break;
case GPIOG:
bits = 0x9;
break;
#endif
case GPIOH:
bits = 0x8;
break;
#if defined(STM32L1)
#else
case GPIOI:
bits = 0x7;
break;
#endif
}
/* Ensure that only valid EXTI lines are used. */

View File

@ -29,7 +29,7 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = rcc.o gpio.o usart.o spi.o flash.o \
i2c.o exti.o timer.o
i2c.o exti2.o timer.o
VPATH += ../../usb:../:../../cm3

View File

@ -1,146 +0,0 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz>
*
* 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/exti.h>
#include <libopencm3/stm32/f2/syscfg.h>
#include <libopencm3/stm32/f2/gpio.h>
void exti_set_trigger(u32 extis, exti_trigger_type trig)
{
switch (trig) {
case EXTI_TRIGGER_RISING:
EXTI_RTSR |= extis;
EXTI_FTSR &= ~extis;
break;
case EXTI_TRIGGER_FALLING:
EXTI_RTSR &= ~extis;
EXTI_FTSR |= extis;
break;
case EXTI_TRIGGER_BOTH:
EXTI_RTSR |= extis;
EXTI_FTSR |= extis;
break;
}
}
void exti_enable_request(u32 extis)
{
/* Enable interrupts. */
EXTI_IMR |= extis;
/* Enable events. */
EXTI_EMR |= extis;
}
void exti_disable_request(u32 extis)
{
/* Disable interrupts. */
EXTI_IMR &= ~extis;
/* Disable events. */
EXTI_EMR &= ~extis;
}
/*
* Reset the interrupt request by writing a 1 to the corresponding
* pending bit register.
*/
void exti_reset_request(u32 extis)
{
EXTI_PR = extis;
}
/*
* Remap an external interrupt line to the corresponding pin on the
* specified GPIO port.
*
* TODO: This could be rewritten in fewer lines of code.
*/
void exti_select_source(u32 exti, u32 gpioport)
{
u8 shift, bits;
shift = bits = 0;
switch (exti) {
case EXTI0:
case EXTI4:
case EXTI8:
case EXTI12:
shift = 0;
break;
case EXTI1:
case EXTI5:
case EXTI9:
case EXTI13:
shift = 4;
break;
case EXTI2:
case EXTI6:
case EXTI10:
case EXTI14:
shift = 8;
break;
case EXTI3:
case EXTI7:
case EXTI11:
case EXTI15:
shift = 12;
break;
}
switch (gpioport) {
case GPIOA:
bits = 0xf;
break;
case GPIOB:
bits = 0xe;
break;
case GPIOC:
bits = 0xd;
break;
case GPIOD:
bits = 0xc;
break;
case GPIOE:
bits = 0xb;
break;
case GPIOF:
bits = 0xa;
break;
case GPIOG:
bits = 0x9;
break;
}
/* Ensure that only valid EXTI lines are used. */
if (exti < EXTI4) {
SYSCFG_EXTICR1 &= ~(0x000F << shift);
SYSCFG_EXTICR1 |= (~bits << shift);
} else if (exti < EXTI8) {
SYSCFG_EXTICR2 &= ~(0x000F << shift);
SYSCFG_EXTICR2 |= (~bits << shift);
} else if (exti < EXTI12) {
SYSCFG_EXTICR3 &= ~(0x000F << shift);
SYSCFG_EXTICR3 |= (~bits << shift);
} else if (exti < EXTI16) {
SYSCFG_EXTICR4 &= ~(0x000F << shift);
SYSCFG_EXTICR4 |= (~bits << shift);
}
}

View File

@ -30,7 +30,7 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = rcc.o gpio.o usart.o spi.o flash.o \
i2c.o exti.o pwr.o timer.o \
i2c.o exti2.o pwr.o timer.o \
usb.o usb_standard.o usb_control.o usb_fx07_common.o usb_f107.o \
usb_f207.o adc.o

View File

@ -25,10 +25,10 @@ CC = $(PREFIX)-gcc
AR = $(PREFIX)-ar
CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
-mcpu=cortex-m3 -mthumb -Wstrict-prototypes \
-ffunction-sections -fdata-sections -MD -DSTM32F1
-ffunction-sections -fdata-sections -MD -DSTM32L1
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = rcc.o gpio.o desig.o crc.o usart.o
OBJS = rcc.o gpio.o desig.o crc.o usart.o exti2.o
VPATH += ../../usb:../:../../cm3