Martin Mareš
2 months ago
25 changed files with 676 additions and 0 deletions
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=blink |
||||
|
OBJS=blink.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,23 @@ |
|||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
|
||||
|
for (;;) { |
||||
|
gpio_clear(GPIOC, GPIO13); |
||||
|
|
||||
|
for (int i=0; i<1000000; i++) |
||||
|
asm volatile (""); |
||||
|
|
||||
|
gpio_set(GPIOC, GPIO13); |
||||
|
|
||||
|
for (int i=0; i<2000000; i++) |
||||
|
asm volatile (""); |
||||
|
} |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=blink |
||||
|
OBJS=blink.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,33 @@ |
|||||
|
#include <libopencm3/cm3/systick.h> |
||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
|
||||
|
static void delay_ms(unsigned int ms) |
||||
|
{ |
||||
|
systick_clear(); |
||||
|
for (unsigned int i=0; i<ms; i++) |
||||
|
while (!systick_get_countflag()) |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
|
||||
|
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB); |
||||
|
systick_set_reload(71999); |
||||
|
systick_counter_enable(); |
||||
|
|
||||
|
for (;;) { |
||||
|
gpio_clear(GPIOC, GPIO13); |
||||
|
delay_ms(100); |
||||
|
gpio_set(GPIOC, GPIO13); |
||||
|
delay_ms(500); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=blink |
||||
|
OBJS=blink.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,53 @@ |
|||||
|
#include <libopencm3/cm3/systick.h> |
||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
|
||||
|
static void delay_ms(unsigned int ms) |
||||
|
{ |
||||
|
systick_clear(); |
||||
|
for (unsigned int i=0; i<ms; i++) |
||||
|
while (!systick_get_countflag()) |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOA); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
|
||||
|
// PA0 ... PA2 = LEDs
|
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO0); |
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO1); |
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO2); |
||||
|
gpio_clear(GPIOA, GPIO0); |
||||
|
gpio_clear(GPIOA, GPIO1); |
||||
|
gpio_clear(GPIOA, GPIO2); |
||||
|
|
||||
|
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB); |
||||
|
systick_set_reload(71999); |
||||
|
systick_counter_enable(); |
||||
|
|
||||
|
for (;;) { |
||||
|
gpio_set(GPIOA, GPIO0); |
||||
|
delay_ms(100); |
||||
|
gpio_clear(GPIOA, GPIO0); |
||||
|
|
||||
|
gpio_set(GPIOA, GPIO1); |
||||
|
delay_ms(100); |
||||
|
gpio_clear(GPIOA, GPIO1); |
||||
|
|
||||
|
gpio_set(GPIOA, GPIO2); |
||||
|
delay_ms(100); |
||||
|
gpio_clear(GPIOA, GPIO2); |
||||
|
|
||||
|
gpio_clear(GPIOC, GPIO13); |
||||
|
delay_ms(100); |
||||
|
gpio_set(GPIOC, GPIO13); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=button |
||||
|
OBJS=button.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,30 @@ |
|||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOA); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
|
||||
|
// PA0 ... PA2 = LEDs
|
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO0); |
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO1); |
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO2); |
||||
|
|
||||
|
// PA3 = button (pull-up)
|
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO3); |
||||
|
gpio_set(GPIOA, GPIO3); |
||||
|
|
||||
|
for (;;) { |
||||
|
if (gpio_get(GPIOA, GPIO3)) |
||||
|
gpio_set(GPIOA, GPIO0 | GPIO1 | GPIO2); |
||||
|
else |
||||
|
gpio_clear(GPIOA, GPIO0 | GPIO1 | GPIO2); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
STM32LIB=$(ROOT)/../ucw-stm32lib |
||||
|
OPENCM3_DIR=$(ROOT)/../libopencm3 |
||||
|
|
||||
|
WITH_BOOT_LOADER=1 |
||||
|
WITH_DFU_FLASH=1 |
||||
|
DFU_ARGS=-d 4242:0008 |
||||
|
|
||||
|
include $(STM32LIB)/mk/bluepill.mk |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=matrix |
||||
|
OBJS=matrix.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,167 @@ |
|||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
|
||||
|
#include <string.h> |
||||
|
|
||||
|
typedef unsigned char byte; |
||||
|
|
||||
|
static void wait(void) |
||||
|
{ |
||||
|
for (int i=0; i<7200; i++) |
||||
|
asm volatile (""); |
||||
|
} |
||||
|
|
||||
|
static void set_reg(int reg, int data) |
||||
|
{ |
||||
|
data |= reg << 8; |
||||
|
|
||||
|
gpio_clear(GPIOB, GPIO13); |
||||
|
wait(); |
||||
|
|
||||
|
for (int mask=0x8000; mask; mask >>= 1) { |
||||
|
if (data & mask) |
||||
|
gpio_set(GPIOB, GPIO12); |
||||
|
else |
||||
|
gpio_clear(GPIOB, GPIO12); |
||||
|
wait(); |
||||
|
gpio_set(GPIOB, GPIO14); |
||||
|
wait(); |
||||
|
gpio_clear(GPIOB, GPIO14); |
||||
|
wait(); |
||||
|
} |
||||
|
|
||||
|
gpio_set(GPIOB, GPIO13); |
||||
|
wait(); |
||||
|
} |
||||
|
|
||||
|
byte display[8]; |
||||
|
|
||||
|
#if 0 |
||||
|
static unsigned char smile[8] = { |
||||
|
0x66, /* .##..##. */ |
||||
|
0x66, /* .##..##. */ |
||||
|
0x00, /* ........ */ |
||||
|
0x18, /* ...##... */ |
||||
|
0x00, /* ........ */ |
||||
|
0xc3, /* ##....## */ |
||||
|
0x66, /* .##..##. */ |
||||
|
0x3c, /* ..####.. */ |
||||
|
}; |
||||
|
#endif |
||||
|
|
||||
|
static void refresh_display(void) |
||||
|
{ |
||||
|
for (int i=1; i<=8; i++) |
||||
|
set_reg(i, display[8-i]); |
||||
|
} |
||||
|
|
||||
|
static signed char dirs[4][2] = {{1,0}, {0,-1}, {-1,0}, {0,1}}; |
||||
|
|
||||
|
static byte snake_dir; |
||||
|
#define SNAKE_MAX 65 |
||||
|
static byte snake[SNAKE_MAX][2]; |
||||
|
static byte snake_tail, snake_head; |
||||
|
static byte food[2]; |
||||
|
static unsigned int rng_state = 0xdeadbeef; |
||||
|
|
||||
|
static byte buttons[2]; |
||||
|
|
||||
|
static void gen_food(void) |
||||
|
{ |
||||
|
food[0] = (rng_state >> 28) & 7; |
||||
|
food[1] = (rng_state >> 20) & 7; |
||||
|
rng_state *= 0x3771cadb; |
||||
|
} |
||||
|
|
||||
|
static void snake_init(void) |
||||
|
{ |
||||
|
snake[0][0] = 0; |
||||
|
snake[0][1] = 0; |
||||
|
snake_dir = 3; |
||||
|
snake_tail = 0; |
||||
|
snake_head = 1; |
||||
|
gen_food(); |
||||
|
} |
||||
|
|
||||
|
static void snake_show(void) |
||||
|
{ |
||||
|
memset(display, 0, 8); |
||||
|
for (int i=snake_tail; i != snake_head; i = (i+1) % SNAKE_MAX) |
||||
|
display[snake[i][0]] |= 1 << snake[i][1]; |
||||
|
display[food[0]] |= 1 << food[1]; |
||||
|
refresh_display(); |
||||
|
} |
||||
|
|
||||
|
static void snake_step(void) |
||||
|
{ |
||||
|
if (buttons[0]) |
||||
|
snake_dir = (snake_dir+3) % 4; |
||||
|
else if (buttons[1]) |
||||
|
snake_dir = (snake_dir+1) % 4; |
||||
|
|
||||
|
int hi = (snake_head + SNAKE_MAX - 1) % SNAKE_MAX; |
||||
|
int x = snake[hi][0] + dirs[snake_dir][0]; |
||||
|
int y = snake[hi][1] + dirs[snake_dir][1]; |
||||
|
|
||||
|
if (x < 0 || x > 7 || y < 0 || y > 7) |
||||
|
return; |
||||
|
|
||||
|
snake[snake_head][0] = x; |
||||
|
snake[snake_head][1] = y; |
||||
|
snake_head = (snake_head + 1) % SNAKE_MAX; |
||||
|
|
||||
|
if (x == food[0] && y == food[1]) |
||||
|
gen_food(); |
||||
|
else |
||||
|
snake_tail = (snake_tail + 1) % SNAKE_MAX; |
||||
|
|
||||
|
snake_show(); |
||||
|
} |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOA); |
||||
|
rcc_periph_clock_enable(RCC_GPIOB); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
|
||||
|
// PB12 = display DIN
|
||||
|
// PB13 = display CS*
|
||||
|
// PB14 = display CLK
|
||||
|
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12 | GPIO13 | GPIO14); |
||||
|
gpio_clear(GPIOB, GPIO12); |
||||
|
gpio_set(GPIOB, GPIO13); |
||||
|
gpio_clear(GPIOB, GPIO14); |
||||
|
|
||||
|
// PA0 = left button
|
||||
|
// PA1 = right button
|
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO0 | GPIO1); |
||||
|
gpio_set(GPIOA, GPIO0 | GPIO1); |
||||
|
|
||||
|
refresh_display(); |
||||
|
set_reg(9, 0); |
||||
|
set_reg(10, 0); // intensity
|
||||
|
set_reg(11, 7); |
||||
|
set_reg(13, 0); // test
|
||||
|
set_reg(12, 1); // shutdown
|
||||
|
|
||||
|
snake_init(); |
||||
|
snake_show(); |
||||
|
|
||||
|
for (;;) { |
||||
|
buttons[0] = buttons[1] = 0; |
||||
|
for (int i=0; i<1000000; i++) { |
||||
|
if (!gpio_get(GPIOA, GPIO0)) |
||||
|
buttons[0] = 1; |
||||
|
if (!gpio_get(GPIOA, GPIO1)) |
||||
|
buttons[1] = 1; |
||||
|
asm volatile (""); |
||||
|
} |
||||
|
|
||||
|
gpio_toggle(GPIOC, GPIO13); |
||||
|
snake_step(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=timer |
||||
|
OBJS=timer.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,34 @@ |
|||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
#include <libopencm3/stm32/timer.h> |
||||
|
|
||||
|
static void delay_ms(unsigned int ms) |
||||
|
{ |
||||
|
timer_set_period(TIM3, 2*ms); |
||||
|
timer_enable_counter(TIM3); |
||||
|
while (TIM_CR1(TIM3) & TIM_CR1_CEN) |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
rcc_periph_clock_enable(RCC_TIM3); |
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
|
||||
|
timer_set_prescaler(TIM3, 35999); // 72 MHz / 36000 = 2 kHz
|
||||
|
timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_DOWN); |
||||
|
timer_one_shot_mode(TIM3); |
||||
|
|
||||
|
for (;;) { |
||||
|
gpio_clear(GPIOC, GPIO13); |
||||
|
delay_ms(100); |
||||
|
gpio_set(GPIOC, GPIO13); |
||||
|
delay_ms(500); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=timer |
||||
|
OBJS=timer.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,36 @@ |
|||||
|
#include <libopencm3/cm3/nvic.h> |
||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
#include <libopencm3/stm32/timer.h> |
||||
|
|
||||
|
void tim3_isr(void) |
||||
|
{ |
||||
|
if (TIM_SR(TIM3) & TIM_SR_UIF) { |
||||
|
TIM_SR(TIM3) &= ~TIM_SR_UIF; |
||||
|
gpio_toggle(GPIOC, GPIO13); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
rcc_periph_clock_enable(RCC_TIM3); |
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
|
||||
|
timer_set_prescaler(TIM3, 35999); // 72 MHz / 36000 = 2 kHz
|
||||
|
timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); |
||||
|
timer_set_period(TIM3, 199); // 200 ticks = 100 ms
|
||||
|
timer_update_on_overflow(TIM3); |
||||
|
timer_enable_irq(TIM3, TIM_DIER_UIE); |
||||
|
nvic_enable_irq(NVIC_TIM3_IRQ); |
||||
|
timer_enable_counter(TIM3); |
||||
|
|
||||
|
for (;;) { |
||||
|
asm volatile ("wfi"); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=timer |
||||
|
OBJS=timer.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,37 @@ |
|||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
#include <libopencm3/stm32/timer.h> |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOB); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
rcc_periph_clock_enable(RCC_TIM3); |
||||
|
rcc_periph_reset_pulse(RST_TIM3); // XXX
|
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
gpio_set(GPIOC, GPIO13); |
||||
|
|
||||
|
// PB0 = TIM3_CH3
|
||||
|
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO0); |
||||
|
|
||||
|
timer_set_prescaler(TIM3, 35999); // 72 MHz / 36000 = 2 kHz
|
||||
|
timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); |
||||
|
timer_set_period(TIM3, 1999); |
||||
|
timer_update_on_overflow(TIM3); |
||||
|
|
||||
|
timer_set_oc_mode(TIM3, TIM_OC3, TIM_OCM_PWM1); |
||||
|
timer_set_oc_value(TIM3, TIM_OC3, 500); |
||||
|
timer_set_oc_polarity_high(TIM3, TIM_OC3); |
||||
|
timer_enable_oc_output(TIM3, TIM_OC3); |
||||
|
|
||||
|
timer_enable_counter(TIM3); |
||||
|
|
||||
|
for (;;) { |
||||
|
asm volatile ("wfi"); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=timer |
||||
|
OBJS=timer.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,37 @@ |
|||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
#include <libopencm3/stm32/timer.h> |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOB); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
rcc_periph_clock_enable(RCC_TIM3); |
||||
|
rcc_periph_reset_pulse(RST_TIM3); // XXX
|
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
gpio_set(GPIOC, GPIO13); |
||||
|
|
||||
|
// PB0 = TIM3_CH3
|
||||
|
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO0); |
||||
|
|
||||
|
timer_set_prescaler(TIM3, 1); // 72 MHz / 2 = 36 MHz
|
||||
|
timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); |
||||
|
timer_set_period(TIM3, 999); // 36 MHz / 1000 = 36 kHz
|
||||
|
timer_update_on_overflow(TIM3); |
||||
|
|
||||
|
timer_set_oc_mode(TIM3, TIM_OC3, TIM_OCM_PWM1); |
||||
|
timer_set_oc_value(TIM3, TIM_OC3, 150); |
||||
|
timer_set_oc_polarity_high(TIM3, TIM_OC3); |
||||
|
timer_enable_oc_output(TIM3, TIM_OC3); |
||||
|
|
||||
|
timer_enable_counter(TIM3); |
||||
|
|
||||
|
for (;;) { |
||||
|
asm volatile ("wfi"); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=timer |
||||
|
OBJS=timer.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,72 @@ |
|||||
|
#include <libopencm3/cm3/nvic.h> |
||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
#include <libopencm3/stm32/timer.h> |
||||
|
|
||||
|
int up = 1; |
||||
|
int pwm; |
||||
|
|
||||
|
void tim4_isr(void) |
||||
|
{ |
||||
|
if (TIM_SR(TIM4) & TIM_SR_UIF) { |
||||
|
TIM_SR(TIM4) &= ~TIM_SR_UIF; |
||||
|
if (up) { |
||||
|
pwm += 5; |
||||
|
if (pwm == 1000) { |
||||
|
pwm = 995; |
||||
|
up = 0; |
||||
|
} |
||||
|
} else { |
||||
|
pwm -= 5; |
||||
|
if (pwm < 0) { |
||||
|
pwm = 5; |
||||
|
up = 1; |
||||
|
} |
||||
|
} |
||||
|
timer_set_oc_value(TIM3, TIM_OC3, pwm); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOB); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
rcc_periph_clock_enable(RCC_TIM3); |
||||
|
rcc_periph_clock_enable(RCC_TIM4); |
||||
|
rcc_periph_reset_pulse(RST_TIM3); // XXX
|
||||
|
rcc_periph_reset_pulse(RST_TIM4); // XXX
|
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
gpio_set(GPIOC, GPIO13); |
||||
|
|
||||
|
// PB0 = TIM3_CH3
|
||||
|
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO0); |
||||
|
|
||||
|
timer_set_prescaler(TIM3, 1); // 72 MHz / 2 = 36 MHz
|
||||
|
timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); |
||||
|
timer_set_period(TIM3, 999); // 36 MHz / 1000 = 36 kHz
|
||||
|
timer_update_on_overflow(TIM3); |
||||
|
|
||||
|
timer_set_oc_mode(TIM3, TIM_OC3, TIM_OCM_PWM1); |
||||
|
timer_set_oc_value(TIM3, TIM_OC3, 50); |
||||
|
timer_set_oc_polarity_high(TIM3, TIM_OC3); |
||||
|
timer_enable_oc_output(TIM3, TIM_OC3); |
||||
|
|
||||
|
timer_enable_counter(TIM3); |
||||
|
|
||||
|
timer_set_prescaler(TIM4, 35999); // 72 MHz / 36000 = 2 kHz
|
||||
|
timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); |
||||
|
timer_set_period(TIM4, 2); // 2 kHz / 2 = 1 kHz
|
||||
|
timer_update_on_overflow(TIM4); |
||||
|
timer_enable_irq(TIM4, TIM_DIER_UIE); |
||||
|
nvic_enable_irq(NVIC_TIM4_IRQ); |
||||
|
timer_enable_counter(TIM4); |
||||
|
|
||||
|
for (;;) { |
||||
|
asm volatile ("wfi"); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=usart |
||||
|
OBJS=usart.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,38 @@ |
|||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
#include <libopencm3/stm32/usart.h> |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOA); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
rcc_periph_clock_enable(RCC_USART1); |
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
|
||||
|
// PA10 = RX1, PA9 = TX1
|
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO10); |
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9); |
||||
|
|
||||
|
usart_set_baudrate(USART1, 115200); |
||||
|
usart_set_databits(USART1, 8); |
||||
|
usart_set_stopbits(USART1, USART_STOPBITS_1); |
||||
|
usart_set_mode(USART1, USART_MODE_TX_RX); |
||||
|
usart_set_parity(USART1, USART_PARITY_NONE); |
||||
|
usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE); |
||||
|
usart_enable(USART1); |
||||
|
|
||||
|
int c = 32; |
||||
|
for (;;) { |
||||
|
gpio_toggle(GPIOC, GPIO13); |
||||
|
|
||||
|
usart_send(USART1, c); |
||||
|
usart_wait_send_ready(USART1); |
||||
|
|
||||
|
c++; |
||||
|
if (c == 127) |
||||
|
c = 32; |
||||
|
} |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
ROOT=.. |
||||
|
BINARY=usart |
||||
|
OBJS=usart.o |
||||
|
LIB_OBJS= |
||||
|
|
||||
|
include $(ROOT)/example.mk |
@ -0,0 +1,36 @@ |
|||||
|
#include <libopencm3/stm32/rcc.h> |
||||
|
#include <libopencm3/stm32/gpio.h> |
||||
|
#include <libopencm3/stm32/usart.h> |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); |
||||
|
rcc_periph_clock_enable(RCC_GPIOA); |
||||
|
rcc_periph_clock_enable(RCC_GPIOC); |
||||
|
rcc_periph_clock_enable(RCC_USART1); |
||||
|
|
||||
|
// PC13 = BluePill LED
|
||||
|
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13); |
||||
|
|
||||
|
// PA10 = RX1, PA9 = TX1
|
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO10); |
||||
|
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9); |
||||
|
|
||||
|
usart_set_baudrate(USART1, 115200); |
||||
|
usart_set_databits(USART1, 8); |
||||
|
usart_set_stopbits(USART1, USART_STOPBITS_1); |
||||
|
usart_set_mode(USART1, USART_MODE_TX_RX); |
||||
|
usart_set_parity(USART1, USART_PARITY_NONE); |
||||
|
usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE); |
||||
|
usart_enable(USART1); |
||||
|
|
||||
|
for (;;) { |
||||
|
gpio_toggle(GPIOC, GPIO13); |
||||
|
|
||||
|
usart_wait_recv_ready(USART1); |
||||
|
int c = usart_recv(USART1); |
||||
|
|
||||
|
usart_send(USART1, c); |
||||
|
usart_wait_send_ready(USART1); |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue