/* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ /* Copyright (c) 2016 King Kévin */ /* standard libraries */ #include // standard integer types #include // standard I/O facilities #include // standard utilities #include // standard streams #include // error number utilities /* STM32 (including CM3) libraries */ #include // real-time control clock library #include // general purpose input output library #include // vector table definition #include // Cortex M3 utilities #include // interrupt utilities #include // external interrupt utilities /* own libraries */ #include "global.h" // board definitions #include "usart.h" // USART utilities #include "usb_cdcacm.h" // USB CDC ACM utilities #include "led_ws2812b.h" // WS2812b LEDs utilities /* flag set in interrupts to be processed in main task */ volatile bool button_flag = false; // button has been pressed // the number of ticks in one second #define TICKS_PER_SECOND 255 /* I can't do the following in define because how defines are stored would cause an integer overflow in the arithmetics */ const uint32_t ticks_second = TICKS_PER_SECOND; // the number of ticks in one second const uint32_t ticks_minute = 60*TICKS_PER_SECOND; // the number of ticks in one minute const uint32_t ticks_hour = 60*60*TICKS_PER_SECOND; // the number of ticks in one hour const uint32_t ticks_midday = 12*60*60*TICKS_PER_SECOND; // the number of ticks in one midday (12 hours) uint8_t clock_leds[WS2812B_LEDS*3] = {0}; // RGB values for the WS2812b clock LEDs /* default output (i.e. for printf) */ 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') { // add carrier return before line feed. this is recommended for most UART terminals usart_putchar_nonblocking('\r'); // a second line feed doesn't break the display cdcacm_putchar('\r'); // a second line feed doesn't break the display } usart_putchar_nonblocking(ptr[i]); // send byte over USART cdcacm_putchar(ptr[i]); // send byte over USB } return i; } errno = EIO; return -1; } /* switch on LED */ void led_on(void) { #ifdef SYSTEM_BOARD gpio_clear(LED_PORT, LED_PIN); #elif MAPLE_MINI gpio_set(LED_PORT, LED_PIN); #endif } /* switch off LED */ void led_off(void) { #ifdef SYSTEM_BOARD gpio_set(LED_PORT, LED_PIN); #elif MAPLE_MINI gpio_clear(LED_PORT, LED_PIN); #endif } /* toggle LED */ void led_toggle(void) { gpio_toggle(LED_PORT, LED_PIN); } /* switch off all clock LEDs */ static void clock_clear(void) { // set all colors of all LEDs to 0 for (uint16_t i=0; i=WS2812B_LEDS*255 || led_minute>=WS2812B_LEDS*255) { // a calculation error occurred return; } // set LEDs for (uint16_t led=0; ledled_minute) { clock_leds[led*3+0] = 0; if (led_minute>=0xff) { // full minutes clock_leds[led*3+1] = 0xff; } else { // running minutes clock_leds[led*3+1] = led_minute; } led_minute -= clock_leds[led*3+1]; if (led_minute!=0) { clock_leds[led*3+2] = 0; led_hour -= 0xff; } else { if (led_hour>=0xff) { // full hours clock_leds[led*3+2] = 0xff; } else { // running hours clock_leds[led*3+2] = led_hour; } led_hour -= clock_leds[led*3+2]; } } else { clock_leds[led*3+0] = 0; if (led_hour!=0) { clock_leds[led*3+1] = 0; led_minute -= 0xff; } else { if (led_minute>=0xff) { // full minutes clock_leds[led*3+1] = 0xff; } else { // running minutes clock_leds[led*3+1] = led_minute; } led_minute -= clock_leds[led*3+1]; } if (led_hour>=0xff) { // full hours clock_leds[led*3+2] = 0xff; } else { // running hours clock_leds[led*3+2] = led_hour; } led_hour -= clock_leds[led*3+2]; } } } /* set the LEDs */ static void leds_set(void) { for (uint16_t i=0; i