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 time_remaining[6];
51 uint32_t seconds_remaining = (uint32_t)((game_time - n_millis_total) / 1000);
52 int minutes = (int)(seconds_remaining / 60);
53 int seconds = (int)(seconds_remaining % 60);
54 sprintf(time_remaining, "%02d:%02d", minutes, seconds);
55 for (int i = 0; i < 5; i++) {
56 cdcacm_putchar(time_remaining[i]);
62 if (n_millis_cur >= 250) {
63 gpio_toggle(GPIOC, GPIO13);
72 static void clock_setup(void) {
73 /* Run CPU at 72MHz */
74 rcc_clock_setup_in_hse_8mhz_out_72mhz();
75 rcc_periph_clock_enable(RCC_GPIOA);
76 rcc_periph_clock_enable(RCC_GPIOC);
77 rcc_periph_clock_enable(RCC_AFIO);
79 AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
81 /* 72MHz / 8 => 9000000 counts per second */
82 systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
84 /* 9000000 / 9000 = 1000 overflows per second - every 1ms one interrupt */
85 /* SysTick interrupt every N clock pulses: set reload to N-1 */
86 systick_set_reload(8999); // 1 ms
87 systick_interrupt_enable();
88 systick_counter_enable();
91 static void gpio_setup(void) {
92 // Built-in LED on blue pill board, PC13
93 gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
94 GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
95 gpio_set(GPIOC, GPIO13);
104 gpio_set(GPIOC, GPIO13);