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);