1 // vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
3 * This file is part of the libopencm3 project.
5 * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
7 * This library is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library. If not, see <http://www.gnu.org/licenses/>.
23 #include <libopencm3/stm32/rcc.h>
24 #include <libopencm3/stm32/gpio.h>
25 #include <libopencm3/cm3/nvic.h>
26 #include <libopencm3/cm3/systick.h>
27 #include <libopencm3/usb/usbd.h>
28 #include <libopencm3/usb/cdc.h>
30 #include "usb_cdcacm.h"
32 uint32_t n_millis_total = 0;
33 uint32_t n_millis_cur = 0;
34 uint8_t n_millis_loops = 0;
35 usbd_device *usbd_dev;
36 static uint32_t game_time = 14 * 60 * 1000; // 15 minutes of 1ms ticks
38 void sys_tick_handler(void) {
42 if (n_millis_total >= game_time) {
43 gpio_clear(GPIOC, GPIO13); // turn on LED
47 /* calculate remaining seconds to print out on the serial port, only do this every
49 if (n_millis_loops >= 4) {
50 char seconds_remaining[5];
51 sprintf(seconds_remaining, "%d", (int)((game_time - n_millis_total) / 1000));
52 for (int i = 0; i < 4; i++) {
53 cdcacm_putchar(seconds_remaining[i]);
59 if (n_millis_cur >= 250) {
60 gpio_toggle(GPIOC, GPIO13);
69 static void clock_setup(void) {
70 /* Run CPU at 72MHz */
71 rcc_clock_setup_in_hse_8mhz_out_72mhz();
72 rcc_periph_clock_enable(RCC_GPIOA);
73 rcc_periph_clock_enable(RCC_GPIOC);
75 /* 72MHz / 8 => 9000000 counts per second */
76 systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
78 /* 9000000 / 9000 = 1000 overflows per second - every 1ms one interrupt */
79 /* SysTick interrupt every N clock pulses: set reload to N-1 */
80 systick_set_reload(8999); // 1 ms
81 systick_interrupt_enable();
82 systick_counter_enable();
85 static void gpio_setup(void) {
86 // Built-in LED on blue pill board, PC13
87 gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
88 GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
89 gpio_set(GPIOC, GPIO13);
91 // Pull up the USB D+ line for reset
92 gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
93 GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12);
94 gpio_clear(GPIOA, GPIO12);
103 gpio_set(GPIOC, GPIO13);