/* 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;
}
// show hours and minutes on LEDs
if (led_hour>led_minute) {
// show hours in blue (and clear other LEDs)
for (uint16_t led=0; led=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];
}
// show minutes in green (override hours)
for (uint16_t led=0; led0; led++) {
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];
clock_leds[led*3+2] = 0;
}
} else {
// show minutes in green (and clear other LEDs)
for (uint16_t led=0; led=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];
clock_leds[led*3+2] = 0;
}
// show hours in blue (override minutes)
for (uint16_t led=0; led0; led++) {
clock_leds[led*3+0] = 0;
clock_leds[led*3+1] = 0;
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