stm32l4: basic uart/exti/led/clock demo
No miniblink, let people interpret a more useful example.
This commit is contained in:
21
examples/stm32/l4/stm32l476g-disco/basics/Makefile
Normal file
21
examples/stm32/l4/stm32l476g-disco/basics/Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
##
|
||||
## 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 <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
BINARY=basics
|
||||
DEVICE=stm32l476vg
|
||||
|
||||
include ../../Makefile.include
|
||||
8
examples/stm32/l4/stm32l476g-disco/basics/README.md
Normal file
8
examples/stm32/l4/stm32l476g-disco/basics/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
This demonstrates some basics on the L476G disco board.
|
||||
|
||||
* printf via usart2 to the attached stlink virtual com port. 115200@8n1
|
||||
* pll configuration from hsi
|
||||
* flash wait state configuration
|
||||
* basic led blinking
|
||||
* exti interrupts for buttons
|
||||
* simple timer usage.
|
||||
199
examples/stm32/l4/stm32l476g-disco/basics/basics.c
Normal file
199
examples/stm32/l4/stm32l476g-disco/basics/basics.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* This file is part of the libopencm3 project.
|
||||
*
|
||||
* Copyright (C) 2018 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/exti.h>
|
||||
#include <libopencm3/stm32/flash.h>
|
||||
#include <libopencm3/stm32/gpio.h>
|
||||
#include <libopencm3/stm32/rcc.h>
|
||||
#include <libopencm3/stm32/timer.h>
|
||||
#include <libopencm3/stm32/usart.h>
|
||||
|
||||
#define LED_GREEN_PORT GPIOE
|
||||
#define LED_GREEN_PIN GPIO8
|
||||
#define LED_RED_PORT GPIOB
|
||||
#define LED_RED_PIN GPIO2
|
||||
|
||||
/* joysticks are on PA0,1,2,3,5 (center, left, right, up, down) */
|
||||
#define JOY_PORT GPIOA
|
||||
#define JOYC_EXTI EXTI0
|
||||
#define JOYC_PIN GPIO0
|
||||
#define JOYC_NVIC NVIC_EXTI0_IRQ
|
||||
|
||||
#define USART_CONSOLE USART2 /* PD5/6 , af7 */
|
||||
|
||||
int _write(int file, char *ptr, int len);
|
||||
|
||||
struct state_t {
|
||||
bool falling;
|
||||
int last_hold;
|
||||
//int tickcount;
|
||||
};
|
||||
|
||||
static struct state_t state;
|
||||
|
||||
|
||||
static void clock_setup(void)
|
||||
{
|
||||
/* FIXME - this should eventually become a clock struct helper setup */
|
||||
rcc_osc_on(RCC_HSI16);
|
||||
|
||||
flash_prefetch_enable();
|
||||
flash_set_ws(4);
|
||||
flash_dcache_enable();
|
||||
flash_icache_enable();
|
||||
/* 16MHz / 4 = > 4 * 40 = 160MHz VCO => 80MHz main pll */
|
||||
rcc_set_main_pll(RCC_PLLCFGR_PLLSRC_HSI16, 4, 40,
|
||||
0, 0, RCC_PLLCFGR_PLLR_DIV2);
|
||||
rcc_osc_on(RCC_PLL);
|
||||
/* either rcc_wait_for_osc_ready() or do other things */
|
||||
|
||||
/* Enable clocks for the ports we need */
|
||||
rcc_periph_clock_enable(RCC_GPIOA);
|
||||
rcc_periph_clock_enable(RCC_GPIOB);
|
||||
rcc_periph_clock_enable(RCC_GPIOD);
|
||||
rcc_periph_clock_enable(RCC_GPIOE);
|
||||
|
||||
/* Enable clocks for peripherals we need */
|
||||
rcc_periph_clock_enable(RCC_USART2);
|
||||
rcc_periph_clock_enable(RCC_TIM7);
|
||||
rcc_periph_clock_enable(RCC_SYSCFG);
|
||||
|
||||
rcc_set_sysclk_source(RCC_CFGR_SW_PLL); /* careful with the param here! */
|
||||
rcc_wait_for_sysclk_status(RCC_PLL);
|
||||
/* FIXME - eventually handled internally */
|
||||
rcc_ahb_frequency = 80e6;
|
||||
rcc_apb1_frequency = 80e6;
|
||||
rcc_apb2_frequency = 80e6;
|
||||
}
|
||||
|
||||
static void usart_setup(void)
|
||||
{
|
||||
/* Setup GPIO pins for USART2 transmit. */
|
||||
gpio_mode_setup(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO5|GPIO6);
|
||||
|
||||
/* Setup USART2 TX pin as alternate function. */
|
||||
gpio_set_af(GPIOD, GPIO_AF7, GPIO5);
|
||||
|
||||
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.
|
||||
* This is a syscall for newlib
|
||||
* @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 exti0_isr(void)
|
||||
{
|
||||
exti_reset_request(JOYC_EXTI);
|
||||
if (state.falling) {
|
||||
gpio_clear(LED_RED_PORT, LED_RED_PIN);
|
||||
state.falling = false;
|
||||
state.last_hold = TIM_CNT(TIM7);
|
||||
exti_set_trigger(JOYC_EXTI, EXTI_TRIGGER_RISING);
|
||||
} else {
|
||||
/* pushed */
|
||||
gpio_set(LED_RED_PORT, LED_RED_PIN);
|
||||
state.falling = true;
|
||||
TIM_CNT(TIM7) = 0;
|
||||
state.last_hold = 0;
|
||||
exti_set_trigger(JOYC_EXTI, EXTI_TRIGGER_FALLING);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free running ms timer.
|
||||
*/
|
||||
static void setup_tim7(void)
|
||||
{
|
||||
rcc_periph_reset_pulse(RST_TIM7);
|
||||
timer_set_prescaler(TIM7, rcc_apb1_frequency / 1e3 - 1);
|
||||
timer_set_period(TIM7, 0xffff);
|
||||
timer_enable_counter(TIM7);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int j = 0;
|
||||
clock_setup();
|
||||
usart_setup();
|
||||
printf("hi guys!\n");
|
||||
|
||||
/* green led for ticking */
|
||||
gpio_mode_setup(LED_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,
|
||||
LED_GREEN_PIN);
|
||||
/* red led for buttons */
|
||||
gpio_mode_setup(LED_RED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,
|
||||
LED_RED_PIN);
|
||||
|
||||
setup_tim7();
|
||||
gpio_mode_setup(JOY_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, JOYC_PIN);
|
||||
nvic_enable_irq(JOYC_NVIC);
|
||||
exti_select_source(JOYC_EXTI, JOY_PORT);
|
||||
state.falling = false;
|
||||
exti_set_trigger(JOYC_EXTI, EXTI_TRIGGER_RISING);
|
||||
exti_enable_request(JOYC_EXTI);
|
||||
|
||||
while (1) {
|
||||
printf("tick: %d\n", j++);
|
||||
if (state.last_hold) {
|
||||
printf("button was held for %d ms\n", state.last_hold);
|
||||
state.last_hold = 0;
|
||||
}
|
||||
gpio_toggle(LED_GREEN_PORT, LED_GREEN_PIN);
|
||||
|
||||
for (int i = 0; i < 4000000; i++) { /* Wait a bit. */
|
||||
__asm__("NOP");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user