diff --git a/lib/flash_internal.c b/lib/flash_internal.c
deleted file mode 100644
index cf4dedf..0000000
--- a/lib/flash_internal.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* 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 .
- *
- */
-/** library to read/write internal flash (code)
- * @file flash_internal.c
- * @author King Kévin
- * @date 2016
- * @note peripherals used: none
- */
-/* standard libraries */
-#include // standard integer types
-#include // general utilities
-
-/* STM32 (including CM3) libraries */
-#include // device signature utilities
-#include // flash utilities
-
-#include "flash_internal.h" // flash storage library API
-#include "global.h" // global definitions
-
-/** the flash page size (medium-density devices have 1KiB page size) */
-#define PAGE_SIZE 1024
-
-bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size)
-{
- // verify it's in the storage area
- if (addressSTORAGE_END) {
- return false;
- }
- if (buffer==NULL || size==0) {
- return false;
- }
-
- // copy data byte per byte
- // a more efficient way would be to copy words, than the remaining bytes
- for (size_t i=0; iSTORAGE_END) {
- return false;
- }
- if (buffer==NULL || size==0) {
- return false;
- }
-
- uint8_t page[PAGE_SIZE]; // the complete page to write
-
- flash_unlock(); // unlock flash to be able to write it
- // go through memory
- while (size) {
- uint32_t page_pre = address%PAGE_SIZE; // the beginning data size in the page
- address -= page_pre; // go to beginning of the page
- storage_read(address, &page[0], page_pre); // copy existing data
- if (size>=PAGE_SIZE-page_pre) { // no need to read tailing page data
- for (uint16_t i=0; i.
- *
- */
-/** library to read/write internal flash (API)
- * @file flash_internal.h
- * @author King Kévin
- * @date 2016
- * @note peripherals used: none
- */
-#pragma once
-
-#include // device signature utilities
-
-/** how much data (in bytes) should we be able to store (be sure it's available and does not overlap the firmware) */
-#define STORAGE_SIZE 2048
-/** the end of the flash area where to store data */
-#define STORAGE_END FLASH_BASE+DESIG_FLASH_SIZE
-/** the start of the flash area where to store data (be sure it's after the firmware data) */
-#define STORAGE_START STORAGE_END-STORAGE_SIZE
-
-/** read data from internal flash
- * @param[in] address start address of the data to read
- * @param[out] buffer where to store the read data
- * @param[in] size how much data to read, in bytes
- * @return if read succeeded
- */
-bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size);
-/** write data to internal flash
- * @param[in] address start address where to write data to
- * @param[in] buffer data to be written
- * @param[in] size how much data to write, in bytes
- * @return if write succeeded
- */
-bool flash_internal_write(uint32_t address, uint8_t *buffer, size_t size);
diff --git a/lib/led_ws2812b.c b/lib/led_ws2812b.c
deleted file mode 100644
index 2d9c759..0000000
--- a/lib/led_ws2812b.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/* 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 .
- *
- */
-/** library to drive a WS2812B LED chain (code)
- * @file led_ws2812b.c
- * @author King Kévin
- * @date 2016
- * @note peripherals used: SPI @ref led_ws2812b_spi, timer @ref led_ws2812b_timer, DMA @ref led_ws2812b_dma
- */
-
-/* standard libraries */
-#include // standard integer types
-#include // general utilities
-
-/* STM32 (including CM3) libraries */
-#include // real-time control clock library
-#include // general purpose input output library
-#include // SPI library
-#include // timer library
-#include // DMA library
-#include // interrupt handler
-#include // Cortex M3 utilities
-
-#include "led_ws2812b.h" // LED WS2812B library API
-#include "global.h" // common methods
-
-/** bit template to encode one byte to be shifted out by SPI to the WS2812B LEDs
- * @details For each WS2812B bit which needs to be transfered we require to transfer 3 SPI bits.
- * The first SPI bit is the high start of the WS2812B bit frame.
- * The second SPI bit determines if the WS2812B bit is a 0 or 1.
- * The third SPI bit is the last part of the WS2812B bit frame, which is always low.
- * The binary pattern is 0b100100100100100100100100
- */
-#define LED_WS2812B_SPI_TEMPLATE 0x924924
-
-uint8_t led_ws2812b_data[LED_WS2812B_LEDS*3*3+40*3/8+1] = {0}; /**< data encoded to be shifted out by SPI for the WS2812B, plus the 50us reset (~40 data bits) */
-static volatile bool transmit_flag = false; /**< flag set in software when transmission started, clear by interrupt when transmission completed */
-
-void led_ws2812b_set_rgb(uint16_t led, uint8_t red, uint8_t green, uint8_t blue)
-{
- // verify the led exists
- if (led>=LED_WS2812B_LEDS) {
- return;
- }
- // wait for transmission to complete before changing the color
- while (transmit_flag) {
- __WFI();
- }
-
- const uint8_t colors[] = {green, red, blue}; // color order for the WS2812B
- const uint8_t pattern_bit[] = {0x02, 0x10, 0x80, 0x04, 0x20, 0x01, 0x08, 0x40}; // which bit to change in the pattern
- const uint8_t pattern_byte[] = {2,2,2,1,1,0,0,0}; // in which byte in the pattern to write the pattern bit
- for (uint8_t color=0; color>16);
- led_ws2812b_data[i*3+1] = (uint8_t)(LED_WS2812B_SPI_TEMPLATE>>8);
- led_ws2812b_data[i*3+2] = (uint8_t)(LED_WS2812B_SPI_TEMPLATE>>0);
- }
- // fill remaining with with 0 to encode the reset code
- for (uint16_t i=LED_WS2812B_LEDS*3*3; i.
- *
- */
-/** library to drive a WS2812B LED chain (API)
- * @file led_ws2812b.h
- * @author King Kévin
- * @date 2016
- * @note peripherals used: SPI @ref led_ws2812b_spi, timer @ref led_ws2812b_timer, DMA @ref led_ws2812b_dma
- */
-#pragma once
-
-/** number of LEDs on the WS2812B strip */
-#define LED_WS2812B_LEDS 48
-
-/** peripheral configuration */
-/** @defgroup led_ws2812b_spi SPI peripheral used to control the WS2812B LEDs
- * @{
- */
-#define LED_WS2812B_SPI SPI1 /**< SPI peripheral */
-#define LED_WS2812B_SPI_DR SPI1_DR /**< SPI data register for the DMA */
-#define LED_WS2812B_SPI_RCC RCC_SPI1 /**< SPI peripheral clock */
-#define LED_WS2812B_SPI_PORT_RCC RCC_GPIOA /**< SPI I/O peripheral clock */
-#define LED_WS2812B_SPI_PORT GPIOA /**< SPI port */
-#define LED_WS2812B_SPI_CLK GPIO_SPI1_SCK /**< SPI clock pin (PA5), connect to PWM output */
-#define LED_WS2812B_SPI_DOUT GPIO_SPI1_MISO /**< SPI data pin (PA6), connect to WS2812B DIN */
-/** @} */
-/** @defgroup led_ws2812b_timer timer peripheral used to generate SPI clock
- * @{
- */
-#define LED_WS2812B_TIMER TIM3 /**< timer peripheral */
-#define LED_WS2812B_TIMER_RCC RCC_TIM3 /**< timer peripheral clock */
-#define LED_WS2812B_TIMER_OC TIM_OC3 /**< timer output compare used to set PWM frequency */
-#define LED_WS2812B_CLK_RCC RCC_GPIOB /**< timer port peripheral clock */
-#define LED_WS2812B_CLK_PORT GPIOB /**< timer port */
-#define LED_WS2812B_CLK_PIN GPIO_TIM3_CH3 /**< timer pin to output PWM (PB0), connect to SPI clock input */
-/** @} */
-/** @defgroup led_ws2812b_dma DMA peripheral used to send the data
- * @{
- */
-#define LED_WS2812B_DMA DMA1 /**< DMA peripheral to put data for WS2812B LED in SPI queue (only DMA1 supports SPI1_TX interrupt) */
-#define LED_WS2812B_DMA_RCC RCC_DMA1 /**< DMA peripheral clock */
-#define LED_WS2812B_DMA_CH DMA_CHANNEL3 /**< DMA channel (only DMA1 channel 3 supports SPI1_TX interrupt) */
-#define LED_WS2812B_DMA_IRQ NVIC_DMA1_CHANNEL3_IRQ /**< DMA channel interrupt signal */
-#define LED_WS2812B_DMA_ISR dma1_channel3_isr /**< DMA channel interrupt service routine */
-/** @} */
-
-/** setup WS2812B LED driver */
-void led_ws2812b_setup(void);
-/** set color of a single LED
- * @param[in] led the LED number to set the color
- * @param[in] red the red color value to set on the LED
- * @param[in] green the green color value to set on the LED
- * @param[in] blue the blue color value to set on the LED
- * @note transmission needs to be done separately
- */
-void led_ws2812b_set_rgb(uint16_t led, uint8_t red, uint8_t green, uint8_t blue);
-/** transmit color values to WS2812B LEDs
- * @return true if transmission started, false if another transmission is already ongoing
- */
-bool led_ws2812b_transmit(void);
diff --git a/lib/rtc_dcf77.c b/lib/rtc_dcf77.c
deleted file mode 100644
index 3e0fdd2..0000000
--- a/lib/rtc_dcf77.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/* 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 .
- *
- */
-/** library to get time from a DCF77 module (code)
- * @file rtc_dcf77.c
- * @author King Kévin
- * @date 2016
- * @note peripherals used: GPIO @ref rtc_dcf77_gpio, timer @ref rtc_dcf77_timer
- */
-
-/* standard libraries */
-#include // standard integer types
-#include // general utilities
-
-/* STM32 (including CM3) libraries */
-#include // real-time control clock library
-#include // general purpose input output library
-#include // SPI library
-#include // timer library
-#include // interrupt handler
-#include // Cortex M3 utilities
-
-#include "rtc_dcf77.h" // RTC DCF77 library API
-#include "global.h" // common methods
-
-volatile bool rtc_dcf77_time_flag = false;
-volatile uint64_t rtc_dcf77_frame = 0; /**< the received DCF77 frame bits */
-
-void rtc_dcf77_setup(void)
-{
- // setup enable output
- rcc_periph_clock_enable(RTC_DCF77_ENABLE_RCC); // enable clock GPIO peripheral
- gpio_set_mode(RTC_DCF77_ENABLE_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, RTC_DCF77_ENABLE_PIN); // set pin to output push-pull to be able to enable the module
- rtc_dcf77_off(); // disable module at start
-
- // setup signal input
- rcc_periph_clock_enable(RTC_DCF77_SIGNAL_RCC); // enable clock for signal input peripheral
- gpio_set_mode(RTC_DCF77_SIGNAL_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, RTC_DCF77_SIGNAL_PIN); // set signal pin to input
- rcc_periph_clock_enable(RCC_AFIO); // enable alternate function clock for external interrupt
- exti_select_source(RTC_DCF77_SIGNAL_EXTI, RTC_DCF77_SIGNAL_PORT); // mask external interrupt of this pin only for this port
- exti_set_trigger(RTC_DCF77_SIGNAL_EXTI, EXTI_TRIGGER_BOTH); // trigger on both edges
- exti_enable_request(RTC_DCF77_SIGNAL_EXTI); // enable external interrupt
- nvic_enable_irq(RTC_DCF77_SIGNAL_IRQ); // enable interrupt
-
- // setup timer to measure pulses
- rcc_periph_clock_enable(RTC_DCF77_TIMER_RCC); // enable clock for timer peripheral
- timer_reset(RTC_DCF77_TIMER); // reset timer state
- timer_set_mode(RTC_DCF77_TIMER, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up
- timer_set_prescaler(RTC_DCF77_TIMER, RTC_DCF77_TIMER_MAX_TIME*(rcc_ahb_frequency/1000)/(1<<16)); // set prescaler to count up to the maximum time
- timer_enable_counter(RTC_DCF77_TIMER); // start timer to measure time
-}
-
-void rtc_dcf77_on(void)
-{
- gpio_clear(RTC_DCF77_ENABLE_PORT, RTC_DCF77_ENABLE_PIN); // enable module by pull pin low
-}
-
-void rtc_dcf77_off(void)
-{
- gpio_set(RTC_DCF77_ENABLE_PORT, RTC_DCF77_ENABLE_PIN); // disable module by pull pin high
-}
-
-uint8_t* rtc_dcf77_time(void)
-{
- static uint8_t to_return[6] = {0}; // arrays with date values to return
- uint8_t parity = 0; // to check parity
- if (rtc_dcf77_frame==0) { // no time received yet
- return NULL;
- }
- if (!(rtc_dcf77_frame&((uint64_t)1<<20))) { // start of encode time should always be 1
- return NULL;
- }
- // check minute parity
- parity = 0;
- for (uint8_t bit=21; bit<=28; bit++) {
- if (rtc_dcf77_frame&((uint64_t)1<>21)&(0x1))+2*((rtc_dcf77_frame>>22)&(0x1))+4*((rtc_dcf77_frame>>23)&(0x1))+8*((rtc_dcf77_frame>>24)&(0x1))+10*((rtc_dcf77_frame>>25)&(0x1))+20*((rtc_dcf77_frame>>26)&(0x1))+40*((rtc_dcf77_frame>>27)&(0x1)); // read minute (00-59)
- if (to_return[0]>59) { // minutes should not be more than 59
- return NULL;
- }
- // check hour parity
- parity = 0;
- for (uint8_t bit=29; bit<=35; bit++) {
- if (rtc_dcf77_frame&((uint64_t)1<>29)&(0x1))+2*((rtc_dcf77_frame>>30)&(0x1))+4*((rtc_dcf77_frame>>31)&(0x1))+8*((rtc_dcf77_frame>>32)&(0x1))+10*((rtc_dcf77_frame>>33)&(0x1))+20*((rtc_dcf77_frame>>34)&(0x1)); // read hour (00-23)
- if (to_return[1]>23) { // hours should not be more than 23
- return NULL;
- }
- // check date parity
- parity = 0;
- for (uint8_t bit=36; bit<=58; bit++) {
- if (rtc_dcf77_frame&((uint64_t)1<>36)&(0x1))+2*((rtc_dcf77_frame>>37)&(0x1))+4*((rtc_dcf77_frame>>38)&(0x1))+8*((rtc_dcf77_frame>>39)&(0x1))+10*((rtc_dcf77_frame>>40)&(0x1))+20*((rtc_dcf77_frame>>41)&(0x1)); // read day of the month (01-31)
- if (to_return[2]==0 || to_return[2]>31) { // day of the month should be 1-31
- return NULL;
- }
- to_return[3] = 1*((rtc_dcf77_frame>>42)&(0x1))+2*((rtc_dcf77_frame>>43)&(0x1))+4*((rtc_dcf77_frame>>44)&(0x1)); // read day of the week (1=Monday - 7=Sunday)
- if (to_return[3]==0 || to_return[3]>7) { // day of the week should be 1-7
- return NULL;
- }
- to_return[4] = 1*((rtc_dcf77_frame>>45)&(0x1))+2*((rtc_dcf77_frame>>46)&(0x1))+4*((rtc_dcf77_frame>>47)&(0x1))+8*((rtc_dcf77_frame>>48)&(0x1))+10*((rtc_dcf77_frame>>49)&(0x1)); // read month of the year (01-12)
- if (to_return[4]==0 || to_return[4]>12) { // month of the year should be 1-12
- return NULL;
- }
- to_return[5] = 1*((rtc_dcf77_frame>>50)&(0x1))+2*((rtc_dcf77_frame>>51)&(0x1))+4*((rtc_dcf77_frame>>52)&(0x1))+8*((rtc_dcf77_frame>>53)&(0x1))+10*((rtc_dcf77_frame>>54)&(0x1))+20*((rtc_dcf77_frame>>55)&(0x1))+40*((rtc_dcf77_frame>>56)&(0x1))+80*((rtc_dcf77_frame>>57)&(0x1)); // read year of the century (00-99)
- if (to_return[5]>99) { // year should be <100
- return NULL;
- }
- return to_return;
-}
-
-/** interrupt service routine called when signal edge is detected, decoding the received DCF77 frame (composed by high pulses) */
-void RTC_DCF77_SIGNAL_ISR(void)
-{
- exti_reset_request(RTC_DCF77_SIGNAL_EXTI); // reset interrupt
- static uint16_t old_state = 0; // save last port state to detect difference
- static uint8_t pulse = 0; // next pulse number in the DCF77 frame
- static uint16_t pulse_edge = 0; // time on when the last pulse (rising edge) has been detected
- static uint64_t rtc_dcf77_frame_tmp = 0; // the DCF77 frame bits as they get filled
- uint16_t time = timer_get_counter(RTC_DCF77_TIMER); // get timer value
-
- uint16_t new_state = gpio_get(RTC_DCF77_SIGNAL_PORT, RTC_DCF77_SIGNAL_PIN); // save last port state to detect difference
- if (old_state!=new_state) { // pulse edge detected
- time = (uint32_t)(time-pulse_edge)*RTC_DCF77_TIMER_MAX_TIME/(1<<16); // get time since last rising edge (integer underflow possible)
- if (new_state) { // rising edge
- if (time < 980) { // glitch
- goto end; // ignore glitch
- } else if (time < 1030) { // a normal pulse
- pulse++; // go to next pulse
- if (pulse>58) { // something wrong happened
- pulse = 0; // restart
- }
- } else if (time < 1980) { // glitch
- goto end; // ignore glitch
- } else if (time < 2130) { // first pulse of a frame
- if (pulse==58) { // full frame received
- rtc_dcf77_frame = rtc_dcf77_frame_tmp; // save received complete frame
- rtc_dcf77_time_flag = true; // notify user
- }
- pulse = 0;
- } else { // something is wrong, restart
- pulse = 0;
- }
- pulse_edge = 0; // save new edge
- timer_set_counter(RTC_DCF77_TIMER, 0); // reset timer to count
- } else { // falling edge
- if (time < 90) { // glitch
- goto end; // ignore glitch
- } else if (time < 120) { // 0 received
- rtc_dcf77_frame_tmp &= ~((uint64_t)1<.
- *
- */
-/** library to get time from a DCF77 module (API)
- * @file rtc_dcf77.h
- * @author King Kévin
- * @date 2016
- * @note peripherals used: GPIO @ref rtc_dcf77_gpio, timer @ref rtc_dcf77_timer
- */
-#pragma once
-
-/** @defgroup rtc_dcf77_gpio output to enable DCF module and input to capture DCF signal
- * @{
- */
-#define RTC_DCF77_ENABLE_RCC RCC_GPIOA /**< GPIO peripheral clock to enable the module */
-#define RTC_DCF77_ENABLE_PORT GPIOA /**< GPIO port to enable the module */
-#define RTC_DCF77_ENABLE_PIN GPIO2 /**< GPIO pinto enable the module */
-#define RTC_DCF77_SIGNAL_RCC RCC_GPIOA /**< GPIO peripheral clock to capture the DCF signal */
-#define RTC_DCF77_SIGNAL_PORT GPIOA /**< GPIO port to capture the DCF signal */
-#define RTC_DCF77_SIGNAL_PIN GPIO3 /**< GPIO pin to capture the DCF signal */
-#define RTC_DCF77_SIGNAL_EXTI EXTI3 /**< GPIO external interrupt to capture the DCF signal */
-#define RTC_DCF77_SIGNAL_IRQ NVIC_EXTI3_IRQ /**< GPIO line interrupt */
-#define RTC_DCF77_SIGNAL_ISR exti3_isr /**< GPIO line interrupt service routine */
-/** @} */
-
-/** @defgroup rtc_dcf77_timer timer to measure signal puls
- * @{
- */
-#define RTC_DCF77_TIMER TIM4 /**< timer peripheral */
-#define RTC_DCF77_TIMER_RCC RCC_TIM4 /**< timer peripheral clock */
-#define RTC_DCF77_TIMER_MAX_TIME 2200 /**< the maximum time in ms the timer can count. DCF77 have pulses < 2s */
-/** @} */
-
-/** set when time information has been received */
-extern volatile bool rtc_dcf77_time_flag;
-
-/** setup DCF77 time receiver module */
-void rtc_dcf77_setup(void);
-/** switch on DCF77 time receiver module */
-void rtc_dcf77_on(void);
-/** switch off DCF77 time receiver module */
-void rtc_dcf77_off(void);
-/** get last received DCF77 time
- * @return array of {minutes (00-49), hours (00-23), date (01-31), day of the week (1-7=Monday-Sunday), month (01-12), year of the century (00-99)} if received time is valid, NULL else
- */
-uint8_t* rtc_dcf77_time(void);
diff --git a/lib/rtc_ds1307.c b/lib/rtc_ds1307.c
deleted file mode 100644
index 4044b2e..0000000
--- a/lib/rtc_ds1307.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/* 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 .
- *
- */
-/** library to communicate with the Maxim DS1307 I2C RTC IC (code)
- * @file rtc_ds1307.c
- * @author King Kévin
- * @date 2016
- * @note user RAM is not handled
- * @note peripherals used: I2C @ref rtc_ds1307_i2c, GPIO & timer @ref rtc_ds1307_square_wave_timer
- */
-
-/* standard libraries */
-#include // standard integer types
-#include // standard I/O facilities
-#include // general utilities
-
-/* STM32 (including CM3) libraries */
-#include // real-time control clock library
-#include // general purpose input output library
-#include // I2C library
-#include // interrupt handler
-#include // Cortex M3 utilities
-#include // timer utilities
-
-#include "global.h" // global utilities
-#include "rtc_ds1307.h" // RTC header and definitions
-
-#if defined(RTC_DS1307_SQUARE_WAVE_TICKS)
-volatile uint32_t rtc_ds1307_ticks = 0;
-volatile bool rtc_ds1307_tick_flag = false;
-#endif
-
-void rtc_ds1307_setup(void)
-{
- // configure I2C peripheral (see RM008 26.3.3, I2C master)
- rcc_periph_clock_enable(RTC_DS1307_I2C_PORT_RCC); // enable clock for I2C I/O peripheral
- gpio_set_mode(RTC_DS1307_I2C_PORT, GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, RTC_DS1307_I2C_PIN_SDA | RTC_DS1307_I2C_PIN_SCL); // setup I2C I/O pins
- rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function
- rcc_periph_clock_enable(RTC_DS1307_I2C_RCC); // enable clock for I2C peripheral
- i2c_reset(RTC_DS1307_I2C); // reset configuration
- i2c_peripheral_disable(RTC_DS1307_I2C); // I2C needs to be disable to be configured
- i2c_set_clock_frequency(RTC_DS1307_I2C, rcc_apb1_frequency/1E6); // configure the peripheral clock to the APB1 freq (where it is connected to)
- i2c_set_standard_mode(RTC_DS1307_I2C); // the DS1307 has a maximum I2C SCL freq if 100 kHz (corresponding to the standard mode)
- i2c_set_ccr(RTC_DS1307_I2C, rcc_apb1_frequency/(100E3*2)); // set Thigh/Tlow to generate frequency of 100 kHz
- i2c_set_trise(RTC_DS1307_I2C, rcc_apb1_frequency/1E6); // max rise time for 100 kHz is 1000 ns (~1 MHz)
- i2c_peripheral_enable(RTC_DS1307_I2C); // enable I2C after configuration completed
-
-#if defined(RTC_DS1307_SQUARE_WAVE_TICKS)
- // setup timer to generate tick from square wave output
- rcc_periph_clock_enable(RTC_DS1307_SQUARE_WAVE_GPIO_RCC); // enable clock for GPIO peripheral
- gpio_set_mode(RTC_DS1307_SQUARE_WAVE_GPIO_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, RTC_DS1307_SQUARE_WAVE_GPIO_PIN); // set pin as input
- gpio_set(RTC_DS1307_SQUARE_WAVE_GPIO_PORT, RTC_DS1307_SQUARE_WAVE_GPIO_PIN); // enable pull-up
- rcc_periph_clock_enable(RTC_DS1307_SQUARE_WAVE_TIMER_RCC); // enable clock for timer peripheral
- timer_reset(RTC_DS1307_SQUARE_WAVE_TIMER); // reset timer state
- timer_ic_set_input(RTC_DS1307_SQUARE_WAVE_TIMER, RTC_DS1307_SQUARE_WAVE_TIMER_IC, RTC_DS1307_SQUARE_WAVE_TIMER_IN); // configure channel as input capture
- timer_ic_set_filter(RTC_DS1307_SQUARE_WAVE_TIMER, RTC_DS1307_SQUARE_WAVE_TIMER_IC, TIM_IC_OFF); // use no input capture filter
- timer_ic_set_polarity(RTC_DS1307_SQUARE_WAVE_TIMER, RTC_DS1307_SQUARE_WAVE_TIMER_IC, TIM_IC_FALLING); //capture on falling edge
- timer_slave_set_trigger(RTC_DS1307_SQUARE_WAVE_TIMER, RTC_DS1307_SQUARE_WAVE_TIMER_TS); // select trigger
- timer_slave_set_mode(RTC_DS1307_SQUARE_WAVE_TIMER, TIM_SMCR_SMS_ECM1); // select external clock more 1 as input
- timer_ic_enable(RTC_DS1307_SQUARE_WAVE_TIMER, RTC_DS1307_SQUARE_WAVE_TIMER_IC); // enable input capture
- timer_set_mode(RTC_DS1307_SQUARE_WAVE_TIMER, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up
- timer_set_prescaler(RTC_DS1307_SQUARE_WAVE_TIMER, 0); // no need to prescale
- timer_set_period(RTC_DS1307_SQUARE_WAVE_TIMER, RTC_DS1307_SQUARE_WAVE_TICKS-1); // set the tick period
- timer_enable_irq(RTC_DS1307_SQUARE_WAVE_TIMER, TIM_DIER_UIE); // enable interrupt for timer
- nvic_enable_irq(RTC_DS1307_SQUARE_WAVE_TIMER_IRQ); // allow interrupt for timer
- rtc_ds1307_tick_flag = false; // reset RTC tick flag
- timer_enable_counter(RTC_DS1307_SQUARE_WAVE_TIMER); // enable timer to count ticks
- rtc_ds1307_write_square_wave(RTC_DS1307_SQUARE_WAVE_FREQUENCY); // set square wave output frequency
-#endif
-}
-
-/** read memory from RTC IC
- * @param[in] addr start address for memory to read
- * @param[out] data buffer to store read memory
- * @param[in] len number of byte to read from the memory
- * @return if read succeeded
- */
-static bool rtc_ds1307_read_memory(uint8_t addr, uint8_t* data, size_t len)
-{
- bool to_return = false; // return if read succeeded
- if (data==NULL || len==0) { // verify there it data to be read
- goto error;
- }
- i2c_send_start(RTC_DS1307_I2C); // send start condition to start transaction
- while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_SB)); // wait until start condition is transmitted
- if (!(I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_MSL)) { // verify if in master mode
- goto error;
- }
- i2c_send_7bit_address(RTC_DS1307_I2C, RTC_DS1307_I2C_ADDR, I2C_WRITE); // select slave
- while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_ADDR)); // wait until address is transmitted
- if (!((I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR)
- goto error;
- }
- i2c_send_data(RTC_DS1307_I2C, addr); // send memory address we want to read
- while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_TxE)); // wait until byte has been transmitted
- i2c_send_start(RTC_DS1307_I2C); // send restart condition to switch from write to read mode
- while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_SB)); // wait until start condition is transmitted
- i2c_send_7bit_address(RTC_DS1307_I2C, RTC_DS1307_I2C_ADDR, I2C_READ); // select slave
- while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_ADDR)); // wait until address is transmitted
- if ((I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_TRA)) { // verify we are in read mode (and read SR2 to clear ADDR)
- goto error;
- }
- for (size_t i=0; i>4)*10+(data[0]&0x0f); // convert BCD coding into seconds
- return to_return;
-}
-
-uint8_t rtc_ds1307_read_minutes(void)
-{
- uint8_t to_return = 0; // minutes to return
- uint8_t data[1] = {0}; // to read data over I2C
- rtc_ds1307_read_memory(1, data, LENGTH(data)); // read a single byte containing minutes value
- to_return = (data[0]>>4)*10+(data[0]&0x0f); // convert BCD coding into minutes
- return to_return;
-}
-
-uint8_t rtc_ds1307_read_hours(void)
-{
- uint8_t to_return = 0; // hours to return
- uint8_t data[1] = {0}; // to read data over I2C
- rtc_ds1307_read_memory(2, data, LENGTH(data)); // read a single byte containing hours value
- if (data[0]&0x40) { // 12 hour mode
- if (data[0]&0x02) { // PM
- to_return += 12; // add the 12 hours
- }
- to_return += ((data[0]&0x10)>>4)*10; // convert BCD coding into hours (first digit)
- } else {
- to_return = ((data[0]&0x30)>>4)*10; // convert BCD coding into hours (first digit)
- }
- to_return += (data[0]&0x0f); // convert BCD coding into hours (second digit)
- return to_return;
-}
-
-uint8_t rtc_ds1307_read_day(void)
-{
- uint8_t to_return = 0; // day to return
- uint8_t data[1] = {0}; // to read data over I2C
- rtc_ds1307_read_memory(3, data, LENGTH(data)); // read a single byte containing day value
- to_return = (data[0]&0x07); // convert BCD coding into days
- return to_return;
-}
-
-uint8_t rtc_ds1307_read_date(void)
-{
- uint8_t to_return = 0; // date to return
- uint8_t data[1] = {0}; // to read data over I2C
- rtc_ds1307_read_memory(4, data, LENGTH(data)); // read a single byte containing date value
- to_return = ((data[0]&0x30)>>4)*10+(data[0]&0x0f); // convert BCD coding into date
- return to_return;
-}
-
-uint8_t rtc_ds1307_read_month(void)
-{
- uint8_t to_return = 0; // month to return
- uint8_t data[1] = {0}; // to read data over I2C
- rtc_ds1307_read_memory(5, data, LENGTH(data)); // read a single byte containing month value
- to_return = ((data[0]&0x10)>>4)*10+(data[0]&0x0f); // convert BCD coding into month
- return to_return;
-}
-
-uint8_t rtc_ds1307_read_year(void)
-{
- uint8_t data[1] = {0}; // to read data over I2C
- rtc_ds1307_read_memory(6, data, LENGTH(data)); // read a single byte containing year value
- uint8_t to_return = ((data[0]&0xf0)>>4)*10+(data[0]&0x0f); // convert BCD coding into year
- return to_return;
-}
-
-uint8_t* rtc_ds1307_read_time(void)
-{
- static uint8_t time[7] = {0}; // store time {seconds, minutes, hours, day, date, month, year}
- uint8_t data[7] = {0}; // to read data over I2C
- rtc_ds1307_read_memory(0, data, LENGTH(data)); // read all time bytes
- time[0] = ((data[0]&0x70)>>4)*10+(data[0]&0x0f); // convert seconds from BCD
- time[1] = (data[1]>>4)*10+(data[1]&0x0f); // convert minutes from BCD
- time[2] = 0; // re-initialize hours
- if (data[2]&0x40) { // 12 hour mode
- if (data[2]&0x02) { // PM
- time[2] += 12; // add the 12 hours
- }
- time[2] += ((data[2]&0x10)>>4)*10; // convert BCD coding into hours (first digit)
- } else {
- time[2] = ((data[2]&0x30)>>4)*10; // convert BCD coding into hours (first digit)
- }
- time[2] += (data[2]&0x0f); // convert BCD coding into hours (second digit)
- time[3] = (data[3]&0x07); // convert BCD coding into days
- time[4] = ((data[4]&0x30)>>4)*10+(data[4]&0x0f); // convert BCD coding into date
- time[5] = ((data[5]&0x10)>>4)*10+(data[5]&0x0f); // convert BCD coding into month
- time[6] = ((data[6]&0xf0)>>4)*10+(data[6]&0x0f); // convert BCD coding into year
- return time;
-}
-
-/** write memory into RTC IC
- * @param[in] addr start address for memory to be written
- * @param[in] data buffer to for memory to be written
- * @param[in] len number of byte to write into the memory
- * @return if write succeeded
- */
-static bool rtc_ds1307_write_memory(uint8_t addr, uint8_t* data, size_t len)
-{
- bool to_return = false; // return if read succeeded
- if (data==NULL || len==0) { // verify there it data to be read
- goto error;
- }
- i2c_send_start(RTC_DS1307_I2C); // send start condition to start transaction
- while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_SB)); // wait until start condition is transmitted
- if (!(I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_MSL)) { // verify if in master mode
- goto error;
- }
- i2c_send_7bit_address(RTC_DS1307_I2C, RTC_DS1307_I2C_ADDR, I2C_WRITE); // select slave
- while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_ADDR)); // wait until address is transmitted
- if (!((I2C_SR2(RTC_DS1307_I2C) & I2C_SR2_TRA))) { // verify we are in transmit mode (and read SR2 to clear ADDR)
- goto error;
- }
- i2c_send_data(RTC_DS1307_I2C, addr); // send memory address we want to read
- while (!(I2C_SR1(RTC_DS1307_I2C) & I2C_SR1_TxE)); // wait until byte has been transmitted
- for (size_t i=0; i59) {
- return false;
- }
- uint8_t data[1] = {0}; // to read CH value data and write seconds value over I2C
- if (!rtc_ds1307_read_memory(0, data, LENGTH(data))) { // read seconds with CH value
- return false;
- }
- data[0] &= 0x80; // only keep CH flag
- data[0] |= (((seconds/10)%6)<<4)+(seconds%10); // encode seconds in BCD format
- return rtc_ds1307_write_memory(0, data, LENGTH(data)); // write current seconds with previous CH value
-}
-
-bool rtc_ds1307_write_minutes(uint8_t minutes)
-{
- if (minutes>59) {
- return false;
- }
- uint8_t data[1] = {0}; // to write time value
- data[0] = (((minutes/10)%6)<<4)+(minutes%10); // encode minutes in BCD format
- return rtc_ds1307_write_memory(1, data, LENGTH(data)); // write time value on RTC
-}
-
-bool rtc_ds1307_write_hours(uint8_t hours)
-{
- if (hours>24) {
- return false;
- }
- uint8_t data[1] = {0}; // to write time value
- data[0] = (((hours/10)%3)<<4)+(hours%10); // encode hours in BCD 24h format
- return rtc_ds1307_write_memory(2, data, LENGTH(data)); // write time value on RTC
-}
-
-bool rtc_ds1307_write_day(uint8_t day)
-{
- if (day<1 || day>7) {
- return false;
- }
- uint8_t data[1] = {0}; // to write time value
- data[0] = (day%8); // encode day in BCD format
- return rtc_ds1307_write_memory(3, data, LENGTH(data)); // write time value on RTC
-}
-
-bool rtc_ds1307_write_date(uint8_t date)
-{
- if (date<1 || date>31) {
- return false;
- }
- uint8_t data[1] = {0}; // to write time value
- data[0] = (((date/10)%4)<<4)+(date%10); // encode date in BCD format
- return rtc_ds1307_write_memory(4, data, LENGTH(data)); // write time value on RTC
-}
-
-bool rtc_ds1307_write_month(uint8_t month)
-{
- if (month<1 || month>12) {
- return false;
- }
- uint8_t data[1] = {0}; // to write time value
- data[0] = (((month/10)%2)<<4)+(month%10); // encode month in BCD format
- return rtc_ds1307_write_memory(5, data, LENGTH(data)); // write time value on RTC
-}
-
-bool rtc_ds1307_write_year(uint8_t year)
-{
- if (year>99) {
- return false;
- }
- uint8_t data[1] = {0}; // to write time value
- data[0] = (((year/10)%10)<<4)+(year%10); // encode year in BCD format
- return rtc_ds1307_write_memory(6, data, LENGTH(data)); // write time value on RTC
-}
-
-bool rtc_ds1307_write_time(uint8_t seconds, uint8_t minutes, uint8_t hours, uint8_t day, uint8_t date, uint8_t month, uint8_t year)
-{
- uint8_t data[7] = {0}; // to write all time values
- // seconds
- if (seconds>59) {
- return false;
- }
- if (!rtc_ds1307_read_memory(0, data, 1)) { // read seconds with CH value
- return false;
- }
- data[0] &= 0x80; // only keep CH flag
- data[0] |= (((seconds/10)%6)<<4)+(seconds%10); // encode seconds in BCD format
- // minutes
- if (minutes>59) {
- return false;
- }
- data[1] = (((minutes/10)%6)<<4)+(minutes%10); // encode minutes in BCD format
- // hours
- if (hours>24) {
- return false;
- }
- data[2] = (((hours/10)%3)<<4)+(hours%10); // encode hours in BCD 24h format
- // day
- if (day<1 || day>7) {
- return false;
- }
- data[3] = (day%8); // encode day in BCD format
- // date
- if (date<1 || date>31) {
- return false;
- }
- data[4] = (((date/10)%4)<<4)+(date%10); // encode date in BCD format
- // month
- if (month<1 || month>12) {
- return false;
- }
- data[5] = (((month/10)%2)<<4)+(month%10); // encode month in BCD format
- // year
- if (year>99) {
- return false;
- }
- data[6] = (((year/10)%10)<<4)+(year%10); // encode year in BCD format
-
- return rtc_ds1307_write_memory(0, data, LENGTH(data)); // write time values on RTC
-}
-
-#if defined(RTC_DS1307_SQUARE_WAVE_TICKS)
-/** timer interrupt service routine called when number of ticks have been received */
-void RTC_DS1307_SQUARE_WAVE_TIMER_ISR(void)
-{
- if (timer_get_flag(RTC_DS1307_SQUARE_WAVE_TIMER, TIM_SR_UIF)) { // overflow even happened
- timer_clear_flag(RTC_DS1307_SQUARE_WAVE_TIMER, TIM_SR_UIF); // clear flag
- rtc_ds1307_ticks++; // increment count
- rtc_ds1307_tick_flag = true; // update flag
- }
-}
-#endif
-
diff --git a/lib/rtc_ds1307.h b/lib/rtc_ds1307.h
deleted file mode 100644
index 2b8a98b..0000000
--- a/lib/rtc_ds1307.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* 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 .
- *
- */
-/** library to communicate with the Maxim DS1307 I2C RTC IC (API)
- * @file rtc_ds1307.h
- * @author King Kévin
- * @date 2016
- * @note user RAM is not handled
- * @note peripherals used: I2C @ref rtc_ds1307_i2c, GPIO & timer @ref rtc_ds1307_square_wave_timer
- */
-#pragma once
-
-/** @defgroup rtc_ds1307_i2c I2C peripheral used to communication with the DS1307 RTC IC
- * @{
- */
-/** I2C peripheral */
-#define RTC_DS1307_I2C I2C1 /**< I2C peripheral */
-#define RTC_DS1307_I2C_RCC RCC_I2C1 /**< I2C peripheral clock */
-#define RTC_DS1307_I2C_PORT_RCC RCC_GPIOB /**< I2C I/O peripheral clock */
-#define RTC_DS1307_I2C_PORT GPIOB /**< I2C I/O peripheral port */
-#define RTC_DS1307_I2C_PIN_SDA GPIO_I2C1_SDA /**< I2C peripheral data pin (PB7) */
-#define RTC_DS1307_I2C_PIN_SCL GPIO_I2C1_SCL /**< I2C peripheral clock pin (PB6) */
-#define RTC_DS1307_I2C_ADDR 0x68 /**< DS1307 I2C address (fixed to 0b1101000) */
-/** @} */
-
-/** @defgroup rtc_ds1307_square_wave_timer timer peripheral used to count timer based on RTC IC square wave output
- * @note comment out SQUARE_WAVE_TICS to not disable feature
- * @{
- */
-#define RTC_DS1307_SQUARE_WAVE_TICKS (RTC_DS1307_SQUARE_WAVE_FREQUENCY/256) /**< number of square wave tics before setting rtc_ds1307_tic_flag */
-#define RTC_DS1307_SQUARE_WAVE_FREQUENCY 4096 /**< square wave output frequency from the RTC IC */
-#define RTC_DS1307_SQUARE_WAVE_TIMER TIM2 /**< timer peripheral */
-#define RTC_DS1307_SQUARE_WAVE_TIMER_RCC RCC_TIM2 /**< timer peripheral clock */
-#define RTC_DS1307_SQUARE_WAVE_TIMER_IC TIM_IC1 /**< input capture channel (for TIM2_CH1) */
-#define RTC_DS1307_SQUARE_WAVE_TIMER_IN TIM_IC_IN_TI1 /**< input capture input source (TIM2_CH1 becomes TI1, then TI1F, then TI1FP1) */
-#define RTC_DS1307_SQUARE_WAVE_TIMER_TS TIM_SMCR_TS_IT1FP1 /**< input capture trigger (actually TI1FP1) */
-#define RTC_DS1307_SQUARE_WAVE_TIMER_IRQ NVIC_TIM2_IRQ /**< timer interrupt */
-#define RTC_DS1307_SQUARE_WAVE_TIMER_ISR tim2_isr /**< timer interrupt service routine */
-#define RTC_DS1307_SQUARE_WAVE_GPIO_RCC RCC_GPIOA /**< timer port peripheral clock (TIM2_CH1 on PA0)*/
-#define RTC_DS1307_SQUARE_WAVE_GPIO_PORT GPIOA /**< timer port (TIM2_CH1 on PA0) */
-#define RTC_DS1307_SQUARE_WAVE_GPIO_PIN GPIO_TIM2_CH1_ETR /**< timer pin input, connect to RTC IC square wave output (TIM2_CH1 on PA0) */
-/** @} */
-
-#if defined(RTC_DS1307_SQUARE_WAVE_TICKS)
-extern volatile uint32_t rtc_ds1307_ticks; /**< increment on SQUARE_WAVE_TICS square wave ticks */
-extern volatile bool rtc_ds1307_tick_flag; /**< set on SQUARE_WAVE_TICS square wave ticks */
-#endif
-
-/** setup communication with RTC IC
- * configure the I2C port defined in the sources
- */
-void rtc_ds1307_setup(void);
-/** verify if oscillator is disabled
- * @return if oscillator is disabled
- */
-bool rtc_ds1307_oscillator_disabled(void);
-/** read square wave output frequency (in Hz)
- * @return square wave output frequency in Hz, 0 if disabled
- */
-uint16_t rtc_ds1307_read_square_wave(void);
-/** read seconds from RTC IC
- * @return number of seconds (0-59) of the current time
- */
-uint8_t rtc_ds1307_read_seconds(void);
-/** read minutes from RTC IC
- * @return number of minutes (0-59) of the current time
- */
-uint8_t rtc_ds1307_read_minutes(void);
-/** read hours from RTC IC
- * @return number of hours (0-23) of the current time
- */
-uint8_t rtc_ds1307_read_hours(void);
-/** read day from RTC IC
- * @return day of the week (1-7, 1 is Sunday) of the current time, 1 being Sunday
- */
-uint8_t rtc_ds1307_read_day(void);
-/** read date from RTC IC
- * @return day of the month (1-31) of the current time
- */
-uint8_t rtc_ds1307_read_date(void);
-/** read month from RTC IC
- * @return month of the year (1-12) of the current time
- */
-uint8_t rtc_ds1307_read_month(void);
-/** read year from RTC IC
- * @return year of the century (00-99) of the current time
- */
-uint8_t rtc_ds1307_read_year(void);
-/** read time from RTC IC
- * @return array of {seconds, minutes, hours, day, date, month, year} as defined above
- */
-uint8_t* rtc_ds1307_read_time(void);
-/** disable RTC IC oscillator
- * @return if disabling oscillator succeeded
- */
-bool rtc_ds1307_oscillator_disable(void);
-/** enable RTC IC oscillator
- * @return if enabling oscillator succeeded
- */
-bool rtc_ds1307_oscillator_enable(void);
-/** write square wave output frequency (in Hz)
- * @param[in] frequency square wave output frequency in Hz (0 to disable, 1, 4096, 8192, 32768)
- * @return if write succeeded
- */
-bool rtc_ds1307_write_square_wave(uint16_t frequency);
-/** write seconds into RTC IC
- * @param[in] seconds number of seconds (0-59)
- * @return if write succeeded
- */
-bool rtc_ds1307_write_seconds(uint8_t seconds);
-/** write minutes into RTC IC
- * @param[in] minutes number of minutes (0-59)
- * @return if write succeeded
- */
-bool rtc_ds1307_write_minutes(uint8_t minutes);
-/** write hours into RTC IC
- * @param[in] hours number of hours (0-23)
- * @return if write succeeded
- */
-bool rtc_ds1307_write_hours(uint8_t hours);
-/** write day into RTC IC
- * @param[in] day day of the week (1-7, 1 is Sunday)
- * @return if write succeeded
- */
-bool rtc_ds1307_write_day(uint8_t day);
-/** write date into RTC IC
- * @param[in] date day of the month (1-31)
- * @return if write succeeded
- */
-bool rtc_ds1307_write_date(uint8_t date);
-/** write month into RTC IC
- * @param[in] month month of the year (1-12)
- * @return if write succeeded
- */
-bool rtc_ds1307_write_month(uint8_t month);
-/** write year into RTC IC
- * @param[in] year year of the century (00-99)
- * @return if write succeeded
- */
-bool rtc_ds1307_write_year(uint8_t year);
-/** write time into RTC IC
- * @param[in] seconds number of seconds (0-59)
- * @param[in] minutes number of minutes (0-59)
- * @param[in] hours number of hours (0-23)
- * @param[in] day day of the week (1-7, 1 is Sunday)
- * @param[in] date day of the month (1-31)
- * @param[in] month month of the year (1-12)
- * @param[in] year year of the century (00-99)
- * @return if write succeeded
- */
-bool rtc_ds1307_write_time(uint8_t seconds, uint8_t minutes, uint8_t hours, uint8_t day, uint8_t date, uint8_t month, uint8_t year);
diff --git a/lib/uart_soft.c b/lib/uart_soft.c
deleted file mode 100644
index 105d811..0000000
--- a/lib/uart_soft.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/* 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 .
- *
- */
-/** library to control up to 4 independent receive and transmit software UART ports (code)
- * @file uart_soft.c
- * @author King Kévin
- * @date 2016
- * @note peripherals used: GPIO @ref uart_soft_gpio, timer @ref uart_soft_timer
- */
-
-/* standard libraries */
-#include // standard integer types
-#include // general utilities
-
-/* STM32 (including CM3) libraries */
-#include // real-time control clock library
-#include // general purpose input output library
-#include // timer library
-#include // interrupt handler
-#include // external interrupt defines
-#include // Cortex M3 utilities
-
-#include "uart_soft.h" // software UART library API
-#include "global.h" // common methods
-
-/** @defgroup uart_soft_gpio GPIO used for the software 4 UART ports
- * @note comment if unused
- * @warning only one port must be used per line (pin number)
- * @{
- */
-#define UART_SOFT_RX_PORT0 B /**< port for receive signal for UART port 0 */
-#define UART_SOFT_RX_PIN0 9 /**< pin for receive signal for UART port 0 */
-//#define UART_SOFT_RX_PORT1 A /**< port for receive signal for UART port 0 */
-//#define UART_SOFT_RX_PIN1 0 /**< pin for receive signal for UART port 0 */
-//#define UART_SOFT_RX_PORT2 A /**< port for receive signal for UART port 0 */
-//#define UART_SOFT_RX_PIN2 0 /**< pin for receive signal for UART port 0 */
-//#define UART_SOFT_RX_PORT3 A /**< port for receive signal for UART port 0 */
-//#define UART_SOFT_RX_PIN3 0 /**< pin for receive signal for UART port 0 */
-#define UART_SOFT_TX_PORT0 B /**< port for transmit signal for UART port 0 */
-#define UART_SOFT_TX_PIN0 8 /**< pin for transmit signal for UART port 0 */
-//#define UART_SOFT_TX_PORT1 A /**< port for transmit signal for UART port 0 */
-//#define UART_SOFT_TX_PIN1 0 /**< pin for transmit signal for UART port 0 */
-//#define UART_SOFT_TX_PORT2 A /**< port for transmit signal for UART port 0 */
-//#define UART_SOFT_TX_PIN2 0 /**< pin for transmit signal for UART port 0 */
-//#define UART_SOFT_TX_PORT3 A /**< port for transmit signal for UART port 0 */
-//#define UART_SOFT_TX_PIN3 0 /**< pin for transmit signal for UART port 0 */
-/** @} */
-
-/** buffer size for receive and transmit buffers */
-#define UART_SOFT_BUFFER 128
-/** UART receive state definition */
-struct soft_uart_rx_state {
- uint32_t port; /**< UART receive port */
- uint16_t pin; /**< UART receive pin */
- uint32_t rcc; /**< UART receive port peripheral clock */
- uint32_t exti; /**< UART receive external interrupt */
- uint32_t irq; /**< UART receive interrupt request */
- uint32_t baudrate; /**< UART receive baud rate */
- volatile uint16_t state; /**< GPIO state for receive pin */
- volatile uint8_t bit; /**< next UART frame bit to receive */
- volatile uint8_t byte; /**< byte being received */
- volatile uint8_t buffer[UART_SOFT_BUFFER]; /**< receive buffer */
- volatile uint8_t buffer_i; /**< index of current data to be read out */
- volatile uint8_t buffer_used; /**< how much data is available */
- volatile bool lock; /**< put lock when changing buffer_i or buffer_used */
- volatile uint8_t buffer_byte; /**< to temporary store byte while locked */
- volatile bool buffer_byte_used; /**< signal a byte has been stored in temporary buffer */
-
-};
-/** UART transmit state definition */
-struct soft_uart_tx_state {
- uint32_t port; /**< UART receive port */
- uint16_t pin; /**< UART receive pin */
- uint32_t rcc; /**< UART receive port peripheral clock */
- uint32_t baudrate; /**< UART receive baud rate */
- volatile uint8_t bit; /**< next UART frame bit to transmit */
- volatile uint8_t byte; /**< byte being transmitted */
- volatile uint8_t buffer[UART_SOFT_BUFFER]; /**< receive buffer */
- volatile uint8_t buffer_i; /**< index of current data to be read out */
- volatile uint8_t buffer_used; /**< how much data is available */
- volatile bool transmit; /**< flag to know it transmission is ongoing */
-};
-
-static struct soft_uart_rx_state* uart_soft_rx_states[4] = {NULL}; /**< states of UART receive ports (up to 4) */
-static struct soft_uart_tx_state* uart_soft_tx_states[4] = {NULL}; /**< states of UART transmit ports (up to 4) */
-
-volatile bool uart_soft_received[4] = {false, false, false, false};
-
-/** @defgroup uart_soft_timer timer used to sample UART signals
- * @{
- */
-#if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0)) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1)) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2)) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN0))
- #define UART_SOFT_RX_TIMER 3 /**< timer peripheral for receive signals */
-#endif
-#if (defined(UART_SOFT_TX_PORT0) && defined(UART_SOFT_TX_PIN0)) || (defined(UART_SOFT_TX_PORT1) && defined(UART_SOFT_TX_PIN1)) || (defined(UART_SOFT_TX_PORT2) && defined(UART_SOFT_TX_PIN2)) || (defined(UART_SOFT_TX_PORT3) && defined(UART_SOFT_TX_PIN0))
- #define UART_SOFT_TX_TIMER 4 /**< timer peripheral for transmit signals */
-#endif
-/** @} */
-
-static const uint32_t timer_flags[4] = {TIM_SR_CC1IF,TIM_SR_CC2IF,TIM_SR_CC3IF,TIM_SR_CC4IF}; /**< the interrupt flags for the compare units */
-static const uint32_t timer_interrupt[4] = {TIM_DIER_CC1IE,TIM_DIER_CC2IE,TIM_DIER_CC3IE,TIM_DIER_CC4IE}; /**< the interrupt enable for the compare units */
-static const enum tim_oc_id timer_oc[4] = {TIM_OC1,TIM_OC2,TIM_OC3,TIM_OC4}; /**< the output compares for the compare units */
-
-bool uart_soft_setup(uint32_t *rx_baudrates, uint32_t *tx_baudrates)
-{
- (void)rx_baudrates; // ensure compile does no complain even if no receive port is used
- (void)tx_baudrates; // ensure compile does no complain even if no transmit port is used
-
- // save UART receive definition
-#if defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0)
- uart_soft_rx_states[0] = calloc(1,sizeof(struct soft_uart_rx_state)); // create state definition
- uart_soft_rx_states[0]->port = GPIO(UART_SOFT_RX_PORT0); // save receive port
- uart_soft_rx_states[0]->pin = GPIO(UART_SOFT_RX_PIN0); // save receive pin
- uart_soft_rx_states[0]->rcc = RCC_GPIO(UART_SOFT_RX_PORT0); // save receive port peripheral clock
- uart_soft_rx_states[0]->exti = EXTI(UART_SOFT_RX_PIN0); // save receive external interrupt
- uart_soft_rx_states[0]->irq = NVIC_EXTI_IRQ(UART_SOFT_RX_PIN0); // save receive interrupt request
-#endif
-
- // setup UART receive GPIO
- for (uint8_t rx=0; rx<4; rx++) {
- if (!uart_soft_rx_states[rx]) { // verify is receive UART is defined
- continue; // skip configuration if not defined
- }
- if (!rx_baudrates || rx_baudrates[rx]==0) { // verify if receive baud rate has been defined
- return false;
- }
- uart_soft_rx_states[rx]->baudrate = rx_baudrates[rx]; // save baud rate
- rcc_periph_clock_enable(uart_soft_rx_states[rx]->rcc); // enable clock for GPIO peripheral
- gpio_set_mode(uart_soft_rx_states[rx]->port, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, uart_soft_rx_states[rx]->pin); // setup GPIO pin UART receive
- gpio_set(uart_soft_rx_states[rx]->port, uart_soft_rx_states[rx]->pin); // pull up to avoid noise when not connected
- rcc_periph_clock_enable(RCC_AFIO); // enable alternate function clock for external interrupt
- exti_select_source(uart_soft_rx_states[rx]->exti, uart_soft_rx_states[rx]->port); // mask external interrupt of this pin only for this port
- exti_enable_request(uart_soft_rx_states[rx]->exti); // enable external interrupt
- exti_set_trigger(uart_soft_rx_states[rx]->exti, EXTI_TRIGGER_BOTH); // trigger when button is pressed
- nvic_enable_irq(uart_soft_rx_states[rx]->irq); // enable interrupt
- uart_soft_rx_states[rx]->state = gpio_get(uart_soft_rx_states[rx]->port, uart_soft_rx_states[rx]->pin); // save state of GPIO
- uart_soft_rx_states[rx]->bit = 0; // reset bits received
- }
-
- // save UART transmit definition
-#if defined(UART_SOFT_TX_PORT0) && defined(UART_SOFT_TX_PIN0)
- uart_soft_tx_states[0] = calloc(1,sizeof(struct soft_uart_tx_state)); // create state definition
- uart_soft_tx_states[0]->port = GPIO(UART_SOFT_TX_PORT0); // save receive port
- uart_soft_tx_states[0]->pin = GPIO(UART_SOFT_TX_PIN0); // save receive pin
- uart_soft_tx_states[0]->rcc = RCC_GPIO(UART_SOFT_TX_PORT0); // save receive port peripheral clock
-#endif
-
- // setup UART transmit GPIO
- for (uint8_t tx=0; tx<4; tx++) {
- if (!uart_soft_tx_states[tx]) { // verify is transmit UART is defined
- continue; // skip configuration if not defined
- }
- if (!tx_baudrates || tx_baudrates[tx]==0) { // verify if transmit baud rate has been defined
- return false;
- }
- uart_soft_tx_states[tx]->baudrate = tx_baudrates[tx]; // save baud rate
- rcc_periph_clock_enable(uart_soft_tx_states[tx]->rcc); // enable clock for GPIO peripheral
- gpio_set_mode(uart_soft_tx_states[tx]->port, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, uart_soft_tx_states[tx]->pin); // setup GPIO UART transmit pin
- gpio_set(uart_soft_tx_states[tx]->port, uart_soft_tx_states[tx]->pin); // idle high
- }
-
- // setup timer
-#if defined(UART_SOFT_RX_TIMER)
- rcc_periph_clock_enable(RCC_TIM(UART_SOFT_RX_TIMER)); // enable clock for timer peripheral
- timer_reset(TIM(UART_SOFT_RX_TIMER)); // reset timer state
- timer_set_mode(TIM(UART_SOFT_RX_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up
- timer_set_prescaler(TIM(UART_SOFT_RX_TIMER), 0); // prescaler to be able to sample 2400-115200 bps (72MHz/2^16=1099<2400bps)
- nvic_enable_irq(NVIC_TIM_IRQ(UART_SOFT_RX_TIMER)); // allow interrupt for timer
- timer_enable_counter(TIM(UART_SOFT_RX_TIMER)); // start timer to generate interrupts for the receive pins
-#endif
-#if defined(UART_SOFT_TX_TIMER)
- rcc_periph_clock_enable(RCC_TIM(UART_SOFT_TX_TIMER)); // enable clock for timer peripheral
- timer_reset(TIM(UART_SOFT_TX_TIMER)); // reset timer state
- timer_set_mode(TIM(UART_SOFT_TX_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up
- timer_set_prescaler(TIM(UART_SOFT_TX_TIMER), 0); // prescaler to be able to output 2400-115200 bps (72MHz/2^16=1099<2400bps)
- nvic_enable_irq(NVIC_TIM_IRQ(UART_SOFT_TX_TIMER)); // allow interrupt for timer
- timer_enable_counter(TIM(UART_SOFT_TX_TIMER)); // start timer to generate interrupts for the transmit pins
-#endif
-
- return true; // setup completed
-}
-
-#if defined(UART_SOFT_RX_TIMER)
-uint8_t uart_soft_getbyte(uint8_t uart)
-{
- if (uart>=4 || !uart_soft_rx_states[uart]) { // ensure receive UART port is defined
- return 0; // return
- }
- while (!uart_soft_rx_states[uart]->buffer_used) { // idle until data is available
- __WFI(); // sleep until interrupt
- }
- uart_soft_rx_states[uart]->lock = true; // set lock
- uint8_t to_return = uart_soft_rx_states[uart]->buffer[uart_soft_rx_states[uart]->buffer_i]; // get the next available character
- uart_soft_rx_states[uart]->buffer_i = (uart_soft_rx_states[uart]->buffer_i+1)%LENGTH(uart_soft_rx_states[uart]->buffer); // update used buffer
- uart_soft_rx_states[uart]->buffer_used--; // update used buffer
- uart_soft_rx_states[uart]->lock = false; // free lock
- if (uart_soft_rx_states[uart]->buffer_byte_used) { // temporary byte has been stored
- uart_soft_rx_states[uart]->buffer[(uart_soft_rx_states[uart]->buffer_i+uart_soft_rx_states[uart]->buffer_used)%LENGTH(uart_soft_rx_states[uart]->buffer)] = uart_soft_rx_states[uart]->buffer_byte; // put byte in buffer
- uart_soft_rx_states[uart]->buffer_used++; // update used buffer
- uart_soft_rx_states[uart]->buffer_byte_used = false; // buffer byte is now in buffer
- }
- uart_soft_received[uart] = (uart_soft_rx_states[uart]->buffer_used!=0); // notify user if data is available
- uart_soft_rx_states[uart]->lock = false; // free lock
- return to_return;
-}
-
-/** timer interrupt service routine to generate UART transmit signals */
-void TIM_ISR(UART_SOFT_RX_TIMER)(void)
-{
- for (uint8_t rx=0; rx<4; rx++) {
- if (timer_interrupt_source(TIM(UART_SOFT_RX_TIMER),timer_flags[rx])) { // got a match on compare for receive pin
- timer_clear_flag(TIM(UART_SOFT_RX_TIMER),timer_flags[rx]); // clear flag
- if (!uart_soft_rx_states[rx]) { // verify if RX exists
- continue; // skip if receive port is not defined it
- }
- uart_soft_rx_states[rx]->byte += ((gpio_get(uart_soft_rx_states[rx]->port, uart_soft_rx_states[rx]->pin)==0 ? 0 : 1)<<(uart_soft_rx_states[rx]->bit-1)); // save bit value
- if (uart_soft_rx_states[rx]->bit<8) { // not the last bit received
- timer_set_oc_value(TIM(UART_SOFT_RX_TIMER),timer_oc[rx],timer_get_counter(TIM(UART_SOFT_RX_TIMER))+rcc_ahb_frequency/uart_soft_rx_states[rx]->baudrate); // set timer to next bit
- uart_soft_rx_states[rx]->bit++; // wait for next bit
- } else { // last bit received
- if (uart_soft_rx_states[rx]->lock) { // someone is already reading data
- uart_soft_rx_states[rx]->buffer_byte = uart_soft_rx_states[rx]->byte; // save byte
- uart_soft_rx_states[rx]->buffer_byte_used = true; // notify reader there is a temporary byte
- } else { // buffer can be updated
- if (uart_soft_rx_states[rx]->buffer_used>=LENGTH(uart_soft_rx_states[rx]->buffer)) { // buffer is full
- uart_soft_rx_states[rx]->buffer_i = (uart_soft_rx_states[rx]->buffer_i+1)%LENGTH(uart_soft_rx_states[rx]->buffer); // drop oldest byte
- uart_soft_rx_states[rx]->buffer_used--; // update buffer usage
- }
- uart_soft_rx_states[rx]->buffer[(uart_soft_rx_states[rx]->buffer_i+uart_soft_rx_states[rx]->buffer_used)%LENGTH(uart_soft_rx_states[rx]->buffer)] = uart_soft_rx_states[rx]->byte; // put byte in buffer
- uart_soft_rx_states[rx]->buffer_used++; // update used buffer
- uart_soft_received[rx] = true; // notify user data is available
- }
- timer_disable_irq(TIM(UART_SOFT_RX_TIMER),timer_interrupt[rx]); // stop_interrupting
- uart_soft_rx_states[rx]->bit = 0; // next bit should be first bit of next byte
- }
- }
- }
-}
-#endif
-
-#if defined(UART_SOFT_TX_TIMER)
-void uart_soft_flush(uint8_t uart)
-{
- if (uart>=4 || !uart_soft_tx_states[uart]) { // ensure transmit UART port is defined
- return; // return
- }
- while (uart_soft_tx_states[uart]->buffer_used) { // idle until buffer is empty
- __WFI(); // sleep until interrupt
- }
- while (uart_soft_tx_states[uart]->transmit) { // idle until transmission is complete
- __WFI(); // sleep until interrupt
- }
-}
-
-/** start transmitting a byte from the buffer
- * @param[in] uart UART port used for transmission
- */
-static void uart_soft_transmit(uint8_t uart) {
- if (uart>=4 || !uart_soft_tx_states[uart]) { // ensure transmit UART port is defined
- return; // UART transmit port not defined
- }
- if (uart_soft_tx_states[uart]->transmit) { // already transmitting
- return; // transmission is already ongoing
- }
- if (!uart_soft_tx_states[uart]->buffer_used) { // no buffered data to transmit
- return; // nothing to transmit
- }
- uart_soft_tx_states[uart]->byte = uart_soft_tx_states[uart]->buffer[uart_soft_tx_states[uart]->buffer_i]; // get byte
- uart_soft_tx_states[uart]->buffer_i = (uart_soft_tx_states[uart]->buffer_i+1)%LENGTH(uart_soft_tx_states[uart]->buffer); // update index
- uart_soft_tx_states[uart]->buffer_used--; // update used buffer
- uart_soft_tx_states[uart]->bit = 0; // LSb is transmitted first
- uart_soft_tx_states[uart]->transmit = true; // start transmission
- gpio_clear(uart_soft_tx_states[uart]->port, uart_soft_tx_states[uart]->pin); // output start bit
- timer_set_oc_value(TIM(UART_SOFT_TX_TIMER), timer_oc[uart], timer_get_counter(TIM(UART_SOFT_TX_TIMER))+(rcc_ahb_frequency/uart_soft_tx_states[uart]->baudrate)); // set timer to output UART frame 1 (data bit 0) in 1 bit
- timer_clear_flag(TIM(UART_SOFT_TX_TIMER), timer_flags[uart]); // clear flag before enabling interrupt
- timer_enable_irq(TIM(UART_SOFT_TX_TIMER), timer_interrupt[uart]);// enable timer IRQ for TX for this UART
-}
-
-void uart_soft_putbyte_nonblocking(uint8_t uart, uint8_t byte)
-{
- if (uart>=4 || !uart_soft_tx_states[uart]) { // ensure transmit UART port is defined
- return; // return
- }
- while (uart_soft_tx_states[uart]->buffer_used>=LENGTH(uart_soft_tx_states[uart]->buffer)) { // idle until there is place in the buffer
- __WFI(); // sleep until something happened
- }
- uart_soft_tx_states[uart]->buffer[(uart_soft_tx_states[uart]->buffer_i+uart_soft_tx_states[uart]->buffer_used)%LENGTH(uart_soft_tx_states[uart]->buffer)] = byte; // save byte to be transmitted
- uart_soft_tx_states[uart]->buffer_used++; // update used buffer
- uart_soft_transmit(uart); // start transmission
-}
-
-void uart_soft_putbyte_blocking(uint8_t uart, uint8_t byte)
-{
- uart_soft_putbyte_nonblocking(uart, byte); // put byte in queue
- uart_soft_flush(uart); // wait for all byte to be transmitted
-}
-
-/** timer interrupt service routine to sample UART receive signals */
-void TIM_ISR(UART_SOFT_TX_TIMER)(void)
-{
- for (uint8_t tx=0; tx<4; tx++) {
- if (timer_interrupt_source(TIM(UART_SOFT_TX_TIMER),timer_flags[tx])) { // got a match on compare for transmit pin
- timer_clear_flag(TIM(UART_SOFT_TX_TIMER),timer_flags[tx]); // clear flag
- if (!uart_soft_tx_states[tx]) { // verify if transmit is defined
- continue; // skip if transmit port is not defined it
- }
- if (uart_soft_tx_states[tx]->bit<8) { // there is a data bit to transmit
- if ((uart_soft_tx_states[tx]->byte>>uart_soft_tx_states[tx]->bit)&0x01) { // bit to transmit is a 1
- gpio_set(uart_soft_tx_states[tx]->port, uart_soft_tx_states[tx]->pin); // set output to high
- } else { // bit to transmit is a 0
- gpio_clear(uart_soft_tx_states[tx]->port, uart_soft_tx_states[tx]->pin); // set output to low
- }
- timer_set_oc_value(TIM(UART_SOFT_TX_TIMER), timer_oc[tx], timer_get_counter(TIM(UART_SOFT_TX_TIMER))+(rcc_ahb_frequency/uart_soft_tx_states[tx]->baudrate)); // wait for the next frame bit
- uart_soft_tx_states[tx]->bit++; // go to next bit
- } else if (uart_soft_tx_states[tx]->bit==8) { // transmit stop bit
- gpio_set(uart_soft_tx_states[tx]->port, uart_soft_tx_states[tx]->pin); // go idle high
- timer_set_oc_value(TIM(UART_SOFT_TX_TIMER), timer_oc[tx], timer_get_counter(TIM(UART_SOFT_TX_TIMER))+(rcc_ahb_frequency/uart_soft_tx_states[tx]->baudrate)); // wait for 1 stop bit
- uart_soft_tx_states[tx]->bit++; // go to next bit
- } else { // UART frame is complete
- timer_disable_irq(TIM(UART_SOFT_TX_TIMER), timer_interrupt[tx]);// enable timer IRQ for TX for this UART
- uart_soft_tx_states[tx]->transmit = false; // transmission finished
- uart_soft_transmit(tx); // start next transmission (if there is)
- }
- } // compare match
- } // go through UARTs
-}
-#endif
-
-/** central function handling receive signal activity */
-static void uart_soft_receive_activity(void)
-{
- for (uint8_t rx=0; rx<4; rx++) {
- if (!uart_soft_rx_states[rx]) { // verify if receive port is not configured
- continue; // skip if receive port is not defined it
- }
- if (uart_soft_rx_states[rx]->state!=gpio_get(uart_soft_rx_states[rx]->port, uart_soft_rx_states[rx]->pin)) { // only do something if state changed
- uart_soft_rx_states[rx]->state = gpio_get(uart_soft_rx_states[rx]->port, uart_soft_rx_states[rx]->pin); // save new state
- if (uart_soft_rx_states[rx]->bit==0) { // start bit edge detected
- if (uart_soft_rx_states[rx]->state==0) { // start bit has to be low
- timer_set_oc_value(TIM(UART_SOFT_RX_TIMER), timer_oc[rx], timer_get_counter(TIM(UART_SOFT_RX_TIMER))+(rcc_ahb_frequency/uart_soft_rx_states[rx]->baudrate)*1.5); // set timer to sample data bit 0 in 1.5 bits
- timer_clear_flag(TIM(UART_SOFT_RX_TIMER), timer_flags[rx]); // clear flag before enabling interrupt
- timer_enable_irq(TIM(UART_SOFT_RX_TIMER), timer_interrupt[rx]);// enable timer IRQ for RX for this UART
- uart_soft_rx_states[rx]->byte = 0; // reset byte value
- uart_soft_rx_states[rx]->bit++; // wait for first bit
- }
- } else { // data bit detected
- timer_set_oc_value(TIM(UART_SOFT_RX_TIMER), timer_oc[rx], timer_get_counter(TIM(UART_SOFT_RX_TIMER))+(rcc_ahb_frequency/uart_soft_rx_states[rx]->baudrate)/2); // resync timer to half a bit (good for drifting transmission, bad if the line is noisy)
- }
- }
- }
-}
-
-/** GPIO interrupt service routine to detect UART receive activity */
-#if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && UART_SOFT_RX_PIN0==0) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && UART_SOFT_RX_PIN1==0) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && UART_SOFT_RX_PIN2==0) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && UART_SOFT_RX_PIN3==0)
-void exti0_isr(void)
-{
- exti_reset_request(EXTI0); // clear interrupt flag for pin triggers this ISR (pin state will be checked independently)
- uart_soft_receive_activity(); // check which GPIO changed
-}
-#endif
-#if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && UART_SOFT_RX_PIN0==1) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && UART_SOFT_RX_PIN1==1) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && UART_SOFT_RX_PIN2==1) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && UART_SOFT_RX_PIN3==1)
-void exti1_isr(void)
-{
- exti_reset_request(EXTI1); // clear interrupt flag for pin triggers this ISR (pin state will be checked independently)
- uart_soft_receive_activity(); // check which GPIO changed
-}
-#endif
-#if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && UART_SOFT_RX_PIN0==2) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && UART_SOFT_RX_PIN1==2) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && UART_SOFT_RX_PIN2==2) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && UART_SOFT_RX_PIN3==2)
-void exti2_isr(void)
-{
- exti_reset_request(EXTI2); // clear interrupt flag for pin triggers this ISR (pin state will be checked independently)
- uart_soft_receive_activity(); // check which GPIO changed
-}
-#endif
-#if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && UART_SOFT_RX_PIN0==3) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && UART_SOFT_RX_PIN1==3) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && UART_SOFT_RX_PIN2==3) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && UART_SOFT_RX_PIN3==3)
-void exti3_isr(void)
-{
- exti_reset_request(EXTI3); // clear interrupt flag for pin triggers this ISR (pin state will be checked independently)
- uart_soft_receive_activity(); // check which GPIO changed
-}
-#endif
-#if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && UART_SOFT_RX_PIN0==4) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && UART_SOFT_RX_PIN1==4) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && UART_SOFT_RX_PIN2==4) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && UART_SOFT_RX_PIN3==4)
-void exti4_isr(void)
-{
- exti_reset_request(EXTI4); // clear interrupt flag for pin triggers this ISR (pin state will be checked independently)
- uart_soft_receive_activity(); // check which GPIO changed
-}
-#endif
-#if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && (UART_SOFT_RX_PIN0==5 || UART_SOFT_RX_PIN0==6 || UART_SOFT_RX_PIN0==7 || UART_SOFT_RX_PIN0==8 || UART_SOFT_RX_PIN0==9)) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && (UART_SOFT_RX_PIN1==5 || UART_SOFT_RX_PIN1==6 || UART_SOFT_RX_PIN1==7 || UART_SOFT_RX_PIN1==8 || UART_SOFT_RX_PIN1==9)) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && (UART_SOFT_RX_PIN2==5 || UART_SOFT_RX_PIN2==6 || UART_SOFT_RX_PIN2==7 || UART_SOFT_RX_PIN2==8 || UART_SOFT_RX_PIN2==9)) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && (UART_SOFT_RX_PIN3==5 || UART_SOFT_RX_PIN3==6 || UART_SOFT_RX_PIN3==7 || UART_SOFT_RX_PIN3==8 || UART_SOFT_RX_PIN3==9))
-void exti9_5_isr(void)
-{
- exti_reset_request(EXTI5|EXTI6|EXTI7|EXTI8|EXTI9); // clear interrupt flag for pin triggers this ISR (pin state will be checked independently)
- uart_soft_receive_activity(); // check which GPIO changed
-}
-#endif
-#if (defined(UART_SOFT_RX_PORT0) && defined(UART_SOFT_RX_PIN0) && (UART_SOFT_RX_PIN0==10 || UART_SOFT_RX_PIN0==11 || UART_SOFT_RX_PIN0==12 || UART_SOFT_RX_PIN0==13 || UART_SOFT_RX_PIN0==14 || UART_SOFT_RX_PIN0==15)) || (defined(UART_SOFT_RX_PORT1) && defined(UART_SOFT_RX_PIN1) && (UART_SOFT_RX_PIN1==10 || UART_SOFT_RX_PIN1==11 || UART_SOFT_RX_PIN1==12 || UART_SOFT_RX_PIN1==13 || UART_SOFT_RX_PIN1==14 || UART_SOFT_RX_PIN1==15)) || (defined(UART_SOFT_RX_PORT2) && defined(UART_SOFT_RX_PIN2) && (UART_SOFT_RX_PIN2==10 || UART_SOFT_RX_PIN2==11 || UART_SOFT_RX_PIN2==12 || UART_SOFT_RX_PIN2==13 || UART_SOFT_RX_PIN2==14 || UART_SOFT_RX_PIN2==15)) || (defined(UART_SOFT_RX_PORT3) && defined(UART_SOFT_RX_PIN3) && (UART_SOFT_RX_PIN3==10 || UART_SOFT_RX_PIN3==11 || UART_SOFT_RX_PIN3==12 || UART_SOFT_RX_PIN3==13 || UART_SOFT_RX_PIN3==14 || UART_SOFT_RX_PIN3==15))
-void exti15_10_isr(void)
-{
- exti_reset_request(EXTI10|EXTI11|EXTI12|EXTI13|EXTI14|EXTI15); // clear interrupt flag for pin triggers this ISR (pin state will be checked independently)
- uart_soft_receive_activity(); // check which GPIO changed
-}
-#endif
-
diff --git a/lib/uart_soft.h b/lib/uart_soft.h
deleted file mode 100644
index 677ea8c..0000000
--- a/lib/uart_soft.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* 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 .
- *
- */
-/** library to control up to 4 independent receive and transmit software UART ports (API)
- * @file uart_soft.h
- * @author King Kévin
- * @date 2016
- * @note peripherals used: GPIO @ref uart_soft_gpio, timer @ref uart_soft_timer
- */
-
-/** if data has been received from UART port and is available to be read */
-extern volatile bool uart_soft_received[4];
-
-/** setup software UART ports
- * @param[in] rx_baudrates baud rates of the 4 UART RX ports (0 if unused)
- * @param[in] tx_baudrates baud rates of the 4 UART TX ports (0 if unused)
- * @return is setup succeeded, else the configuration is wrong
- */
-bool uart_soft_setup(uint32_t *rx_baudrates, uint32_t *tx_baudrates);
-/** get received byte from UART port
- * @param[in] uart UART receive port to read byte from
- * @return received byte (0 if no byte is available)
- */
-uint8_t uart_soft_getbyte(uint8_t uart);
-/** ensure all bytes are transmitted for the UART
- * @param[in] uart UART port to flush
- */
-void uart_soft_flush(uint8_t uart);
-/** put byte in buffer to be transmitted on UART port
- * @note blocking if buffer is full
- * @param[in] uart UART port to transmit the byte from
- * @param[in] byte byte to put in transmit buffer
- */
-void uart_soft_putbyte_nonblocking(uint8_t uart, uint8_t byte);
-/** transmit byte on UART port
- * @note blocks until all buffered byte and this byte are transmitted
- * @param[in] uart UART port to transmit the byte from
- * @param[in] byte byte to transmit
- */
-void uart_soft_putbyte_blocking(uint8_t uart, uint8_t byte);
-
diff --git a/lib/usart.c b/lib/usart.c
deleted file mode 100644
index ca9f827..0000000
--- a/lib/usart.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/* 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 .
- *
- */
-/** library for USART communication (code)
- * @file usart.c
- * @author King Kévin
- * @date 2016
- * @note peripherals used: USART @ref usart
- */
-
-/* standard libraries */
-#include // standard integer types
-#include // standard I/O facilities
-#include // general utilities
-
-/* STM32 (including CM3) libraries */
-#include // real-time control clock library
-#include // general purpose input output library
-#include // universal synchronous asynchronous receiver transmitter library
-#include // interrupt handler
-#include // Cortex M3 utilities
-
-#include "usart.h" // USART header and definitions
-#include "global.h" // common methods
-
-/** @defgroup usart USART peripheral used for UART communication
- * @{
- */
-#define USART_ID 1 /**< USART peripheral */
-/** @} */
-
-#define USART_BAUDRATE 115200 /**< serial baudrate, in bits per second (with 8N1 8 bits, no parity bit, 1 stop bit settings) */
-
-/* input and output ring buffer, indexes, and available memory */
-static uint8_t rx_buffer[USART_BUFFER] = {0}; /**< ring buffer for received data */
-static volatile uint8_t rx_i = 0; /**< current position of read received data */
-static volatile uint8_t rx_used = 0; /**< how much data has been received and not red */
-static uint8_t tx_buffer[USART_BUFFER] = {0}; /**< ring buffer for data to transmit */
-static volatile uint8_t tx_i = 0; /**< current position of transmitted data */
-static volatile uint8_t tx_used = 0; /**< how much data needs to be transmitted */
-
-volatile bool usart_received = false;
-
-void usart_setup(void)
-{
- /* enable USART I/O peripheral */
- rcc_periph_clock_enable(USART_PORT_RCC(USART_ID)); // enable clock for USART port peripheral
- rcc_periph_clock_enable(USART_RCC(USART_ID)); // enable clock for USART peripheral
- rcc_periph_clock_enable(RCC_AFIO); // enable pin alternate function (USART)
- gpio_set_mode(USART_PORT(USART_ID), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, USART_PIN_TX(USART_ID)); // setup GPIO pin USART transmit
- gpio_set_mode(USART_PORT(USART_ID), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, USART_PIN_RX(USART_ID)); // setup GPIO pin USART receive
- gpio_set(USART_PORT(USART_ID), USART_PIN_RX(USART_ID)); // pull up to avoid noise when not connected
-
- /* setup USART parameters */
- usart_set_baudrate(USART(USART_ID), USART_BAUDRATE);
- usart_set_databits(USART(USART_ID), 8);
- usart_set_stopbits(USART(USART_ID), USART_STOPBITS_1);
- usart_set_mode(USART(USART_ID), USART_MODE_TX_RX);
- usart_set_parity(USART(USART_ID), USART_PARITY_NONE);
- usart_set_flow_control(USART(USART_ID), USART_FLOWCONTROL_NONE);
-
- nvic_enable_irq(USART_IRQ(USART_ID)); // enable the USART interrupt
- usart_enable_rx_interrupt(USART(USART_ID)); // enable receive interrupt
- usart_enable(USART(USART_ID)); // enable USART
-
- /* reset buffer states */
- tx_i = 0;
- tx_used = 0;
- rx_i = 0;
- rx_used = 0;
- usart_received = false;
-}
-
-void usart_putchar_blocking(char c)
-{
- usart_flush(); // empty buffer first
- usart_send_blocking(USART(USART_ID), c); // send character
-}
-
-void usart_flush(void)
-{
- while (tx_used) { // idle until buffer is empty
- __WFI(); // sleep until interrupt
- }
- usart_wait_send_ready(USART(USART_ID)); // wait until transmit register is empty (transmission might not be complete)
-}
-
-char usart_getchar(void)
-{
- while (!rx_used) { // idle until data is available
- __WFI(); // sleep until interrupt
- }
- char to_return = rx_buffer[rx_i]; // get the next available character
- usart_disable_rx_interrupt(USART(USART_ID)); // disable receive interrupt to prevent index corruption
- rx_i = (rx_i+1)%LENGTH(rx_buffer); // update used buffer
- rx_used--; // update used buffer
- usart_received = (rx_used!=0); // update available data
- usart_enable_rx_interrupt(USART(USART_ID)); // enable receive interrupt
- return to_return;
-}
-
-void usart_putchar_nonblocking(char c)
-{
- while (tx_used>=LENGTH(tx_buffer)) { // idle until buffer has some space
- usart_enable_tx_interrupt(USART(USART_ID)); // enable transmit interrupt
- __WFI(); // sleep until something happened
- }
- usart_disable_tx_interrupt(USART(USART_ID)); // disable transmit interrupt to prevent index corruption
- tx_buffer[(tx_i+tx_used)%LENGTH(tx_buffer)] = c; // put character in buffer
- tx_used++; // update used buffer
- usart_enable_tx_interrupt(USART(USART_ID)); // enable transmit interrupt
-}
-
-/** USART interrupt service routine called when data has been transmitted or received */
-void USART_ISR(USART_ID)(void)
-{
- if (usart_get_interrupt_source(USART(USART_ID), USART_SR_TXE)) { // data has been transmitted
- if (!tx_used) { // no data in the buffer to transmit
- usart_disable_tx_interrupt(USART(USART_ID)); // disable transmit interrupt
- } else {
- usart_send(USART(USART_ID),tx_buffer[tx_i]); // put data in transmit register
- tx_i = (tx_i+1)%LENGTH(rx_buffer); // update location on buffer
- tx_used--; // update used size
- }
- }
- if (usart_get_interrupt_source(USART(USART_ID), USART_SR_RXNE)) { // data has been received
- // only save data if there is space in the buffer
- while (rx_used>=LENGTH(rx_buffer)) { // if buffer is full
- rx_i = (rx_i+1)%LENGTH(rx_buffer); // drop oldest data
- rx_used--; // update used buffer information
- }
- rx_buffer[(rx_i+rx_used)%LENGTH(rx_buffer)] = usart_recv(USART(USART_ID)); // put character in buffer
- rx_used++; // update used buffer
- usart_received = (rx_used!=0); // update available data
- }
-}
diff --git a/lib/usart.h b/lib/usart.h
deleted file mode 100644
index dddcadb..0000000
--- a/lib/usart.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* 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 .
- *
- */
-/** library for USART communication (API)
- * @file usart.h
- * @author King Kévin
- * @date 2016
- * @note peripherals used: USART @ref usart
- */
-#pragma once
-
-/** transmit and receive buffer sizes */
-#define USART_BUFFER 128
-/** how many bytes available in the received buffer since last read */
-extern volatile bool usart_received;
-
-/** setup USART peripheral */
-void usart_setup(void);
-/** send character over USART (blocking)
- * @param[in] c character to send
- * @note blocks until character transmission started */
-void usart_putchar_blocking(char c);
-/** ensure all data has been transmitted (blocking)
- * @note block until all data has been transmitted
- */
-void usart_flush(void);
-/** get character received over USART (blocking)
- * @return character received over USART
- * @note blocks until character is received over USART when received buffer is empty
- */
-char usart_getchar(void);
-/** send character over USART (non-blocking)
- * @param[in] c character to send
- * @note blocks if transmit buffer is full, else puts in buffer and returns
- */
-void usart_putchar_nonblocking(char c);
diff --git a/lib/vfd_hv518.c b/lib/vfd_hv518.c
deleted file mode 100644
index 371ca8f..0000000
--- a/lib/vfd_hv518.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/* 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 .
- *
- */
-/** library to drive vacuum fluorescent display using supertex HV518 shift register VFD drivers (code)
- * @details the current configuration is for a VFD extracted from a Samsung SER-6500 cash register
- * @file vfd_hv518.c
- * @author King Kévin
- * @date 2016
- * @note peripherals used: SPI @ref vfd_hv518_spi , GPIO @ref vfd_hv518_gpio , timer @ref vfd_hv518_timer
- */
-/* standard libraries */
-#include // standard integer types
-#include // general utilities
-
-/* STM32 (including CM3) libraries */
-#include // real-time control clock library
-#include // general purpose input output library
-#include // SPI library
-#include // timer library
-#include // interrupt handler
-
-#include "global.h" // global definitions
-#include "vfd_hv518.h" // VFD library API
-
-/** @defgroup vfd_hv518_gpio GPIO to control supertex HV518 VFD drivers
- * @{
- */
-#define VFD_PORT GPIOA /**< GPIO port */
-#define VFD_PORT_RCC RCC_GPIOA /**< GPIO port peripheral clock */
-#define VFD_STR GPIO6 /**< strobe pin to enable high voltage output, high voltage is output on low */
-#define VFD_NLE GPIO4 /**< latch enable pin, stores the shifted data on low, output the parallel data on high */
-/** @} */
-
-/** @defgroup vfd_hv518_spi SPI to send data to supertex HV518 VFD drivers
- * @{
- */
-#define VFD_SPI_RCC RCC_SPI1 /**< SPI peripheral */
-#define VFD_SPI_PORT GPIOA /**< GPIO port */
-#define VFD_SPI_PORT_RCC RCC_GPIOA /**< GPIO port peripheral clock */
-#define VFD_SPI_IRQ NVIC_SPI1_IRQ /**< SPI peripheral interrupt signal */
-#define VFD_SPI_ISR spi1_isr /**< SPI interrupt service routine */
-#define VFD_CLK GPIO_SPI1_SCK /**< clock signal */
-#define VFD_DIN GPIO_SPI1_MOSI /**< data input, where the data is shifted to */
-/** @} */
-
-/** @defgroup vfd_hv518_timer timer for automatic display blocks refresh
- * @{
- */
-#define VFD_TIMER_RCC RCC_TIM2 /**< timer peripheral clock */
-#define VFD_TIMER_IRQ NVIC_TIM2_IRQ /**< timer interrupt signal */
-#define VFD_TIMER_ISR tim2_isr /**< timer interrupt service routine */
-/** @} */
-
-/** ASCII characters encoded for the 7 segments digit block
- * @note starts with space
- */
-static const uint8_t ascii_7segments[] = {
- 0b00000000, // space
- 0b00110000, // ! (I)
- 0b00100010, // "
- 0b01011100, // # (o)
- 0b01101101, // $ (s)
- 0b01010010, // % (/)
- 0b01111101, // & (6)
- 0b00100000, // '
- 0b00111001, // ( ([)
- 0b00001111, // )
- 0b01110000, // *
- 0b01000110, // +
- 0b00010000, // ,
- 0b01000000, // -
- 0b00010000, // . (,)
- 0b01010010, // /
- 0b00111111, // 0
- 0b00000110, // 1
- 0b01011011, // 2
- 0b01001111, // 3
- 0b01100110, // 4
- 0b01101101, // 5
- 0b01111101, // 6
- 0b00000111, // 7
- 0b01111111, // 8
- 0b01101111, // 9
- 0b01001000, // : (=)
- 0b01001000, // ; (=)
- 0b01011000, // <
- 0b01001000, // =
- 0b01001100, // >
- 0b01010011, // ?
- 0b01111011, // @
- 0b01110111, // A
- 0b01111111, // B
- 0b00111001, // C
- 0b01011110, // D
- 0b01111001, // E
- 0b01110001, // F
- 0b00111101, // G
- 0b01110110, // H
- 0b00110000, // I
- 0b00011110, // J
- 0b01110110, // K
- 0b00111000, // L
- 0b00110111, // M
- 0b00110111, // N
- 0b00111111, // O
- 0b01110011, // P
- 0b01101011, // Q
- 0b00110011, // R
- 0b01101101, // S
- 0b01111000, // T
- 0b00111110, // U
- 0b00111110, // V (U)
- 0b00111110, // W (U)
- 0b01110110, // X (H)
- 0b01101110, // Y
- 0b01011011, // Z
- 0b00111001, // [
- 0b01100100, // '\'
- 0b00001111, // /
- 0b00100011, // ^
- 0b00001000, // _
- 0b00000010, // `
- 0b01011111, // a
- 0b01111100, // b
- 0b01011000, // c
- 0b01011110, // d
- 0b01111011, // e
- 0b01110001, // f
- 0b01101111, // g
- 0b01110100, // h
- 0b00010000, // i
- 0b00001100, // j
- 0b01110110, // k
- 0b00110000, // l
- 0b01010100, // m
- 0b01010100, // n
- 0b01011100, // o
- 0b01110011, // p
- 0b01100111, // q
- 0b01010000, // r
- 0b01101101, // s
- 0b01111000, // t
- 0b00011100, // u
- 0b00011100, // v (u)
- 0b00011100, // w (u)
- 0b01110110, // x
- 0b01101110, // y
- 0b01011011, // z
- 0b00111001, // { ([)
- 0b00110000, // |
- 0b00001111, // } ([)
- 0b01000000, // ~
-};
-
-/** font for the 5x7 dot matrix block
- * @details first value is left-most line, LSB is top dot, MSB is not used
- * @note from http://sunge.awardspace.com/glcd-sd/node4.html
- */
-static const uint8_t font5x7[][5] = {
- {0x00, 0x00, 0x00, 0x00, 0x00}, // (space)
- {0x00, 0x00, 0x5F, 0x00, 0x00}, // !
- {0x00, 0x07, 0x00, 0x07, 0x00}, // "
- {0x14, 0x7F, 0x14, 0x7F, 0x14}, // #
- {0x24, 0x2A, 0x7F, 0x2A, 0x12}, // $
- {0x23, 0x13, 0x08, 0x64, 0x62}, // %
- {0x36, 0x49, 0x55, 0x22, 0x50}, // &
- {0x00, 0x05, 0x03, 0x00, 0x00}, // '
- {0x00, 0x1C, 0x22, 0x41, 0x00}, // (
- {0x00, 0x41, 0x22, 0x1C, 0x00}, // )
- {0x08, 0x2A, 0x1C, 0x2A, 0x08}, // *
- {0x08, 0x08, 0x3E, 0x08, 0x08}, // +
- {0x00, 0x50, 0x30, 0x00, 0x00}, // ,
- {0x08, 0x08, 0x08, 0x08, 0x08}, // -
- {0x00, 0x60, 0x60, 0x00, 0x00}, // .
- {0x20, 0x10, 0x08, 0x04, 0x02}, // /
- {0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0
- {0x00, 0x42, 0x7F, 0x40, 0x00}, // 1
- {0x42, 0x61, 0x51, 0x49, 0x46}, // 2
- {0x21, 0x41, 0x45, 0x4B, 0x31}, // 3
- {0x18, 0x14, 0x12, 0x7F, 0x10}, // 4
- {0x27, 0x45, 0x45, 0x45, 0x39}, // 5
- {0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6
- {0x01, 0x71, 0x09, 0x05, 0x03}, // 7
- {0x36, 0x49, 0x49, 0x49, 0x36}, // 8
- {0x06, 0x49, 0x49, 0x29, 0x1E}, // 9
- {0x00, 0x36, 0x36, 0x00, 0x00}, // :
- {0x00, 0x56, 0x36, 0x00, 0x00}, // ;
- {0x00, 0x08, 0x14, 0x22, 0x41}, // <
- {0x14, 0x14, 0x14, 0x14, 0x14}, // =
- {0x41, 0x22, 0x14, 0x08, 0x00}, // >
- {0x02, 0x01, 0x51, 0x09, 0x06}, // ?
- {0x32, 0x49, 0x79, 0x41, 0x3E}, // @
- {0x7E, 0x11, 0x11, 0x11, 0x7E}, // A
- {0x7F, 0x49, 0x49, 0x49, 0x36}, // B
- {0x3E, 0x41, 0x41, 0x41, 0x22}, // C
- {0x7F, 0x41, 0x41, 0x22, 0x1C}, // D
- {0x7F, 0x49, 0x49, 0x49, 0x41}, // E
- {0x7F, 0x09, 0x09, 0x01, 0x01}, // F
- {0x3E, 0x41, 0x41, 0x51, 0x32}, // G
- {0x7F, 0x08, 0x08, 0x08, 0x7F}, // H
- {0x00, 0x41, 0x7F, 0x41, 0x00}, // I
- {0x20, 0x40, 0x41, 0x3F, 0x01}, // J
- {0x7F, 0x08, 0x14, 0x22, 0x41}, // K
- {0x7F, 0x40, 0x40, 0x40, 0x40}, // L
- {0x7F, 0x02, 0x04, 0x02, 0x7F}, // M
- {0x7F, 0x04, 0x08, 0x10, 0x7F}, // N
- {0x3E, 0x41, 0x41, 0x41, 0x3E}, // O
- {0x7F, 0x09, 0x09, 0x09, 0x06}, // P
- {0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q
- {0x7F, 0x09, 0x19, 0x29, 0x46}, // R
- {0x46, 0x49, 0x49, 0x49, 0x31}, // S
- {0x01, 0x01, 0x7F, 0x01, 0x01}, // T
- {0x3F, 0x40, 0x40, 0x40, 0x3F}, // U
- {0x1F, 0x20, 0x40, 0x20, 0x1F}, // V
- {0x7F, 0x20, 0x18, 0x20, 0x7F}, // W
- {0x63, 0x14, 0x08, 0x14, 0x63}, // X
- {0x03, 0x04, 0x78, 0x04, 0x03}, // Y
- {0x61, 0x51, 0x49, 0x45, 0x43}, // Z
- {0x00, 0x00, 0x7F, 0x41, 0x41}, // [
- {0x02, 0x04, 0x08, 0x10, 0x20}, // '\'
- {0x41, 0x41, 0x7F, 0x00, 0x00}, // ]
- {0x04, 0x02, 0x01, 0x02, 0x04}, // ^
- {0x40, 0x40, 0x40, 0x40, 0x40}, // _
- {0x00, 0x01, 0x02, 0x04, 0x00}, // `
- {0x20, 0x54, 0x54, 0x54, 0x78}, // a
- {0x7F, 0x48, 0x44, 0x44, 0x38}, // b
- {0x38, 0x44, 0x44, 0x44, 0x20}, // c
- {0x38, 0x44, 0x44, 0x48, 0x7F}, // d
- {0x38, 0x54, 0x54, 0x54, 0x18}, // e
- {0x08, 0x7E, 0x09, 0x01, 0x02}, // f
- {0x08, 0x14, 0x54, 0x54, 0x3C}, // g
- {0x7F, 0x08, 0x04, 0x04, 0x78}, // h
- {0x00, 0x44, 0x7D, 0x40, 0x00}, // i
- {0x20, 0x40, 0x44, 0x3D, 0x00}, // j
- {0x00, 0x7F, 0x10, 0x28, 0x44}, // k
- {0x00, 0x41, 0x7F, 0x40, 0x00}, // l
- {0x7C, 0x04, 0x18, 0x04, 0x78}, // m
- {0x7C, 0x08, 0x04, 0x04, 0x78}, // n
- {0x38, 0x44, 0x44, 0x44, 0x38}, // o
- {0x7C, 0x14, 0x14, 0x14, 0x08}, // p
- {0x08, 0x14, 0x14, 0x18, 0x7C}, // q
- {0x7C, 0x08, 0x04, 0x04, 0x08}, // r
- {0x48, 0x54, 0x54, 0x54, 0x20}, // s
- {0x04, 0x3F, 0x44, 0x40, 0x20}, // t
- {0x3C, 0x40, 0x40, 0x20, 0x7C}, // u
- {0x1C, 0x20, 0x40, 0x20, 0x1C}, // v
- {0x3C, 0x40, 0x30, 0x40, 0x3C}, // w
- {0x44, 0x28, 0x10, 0x28, 0x44}, // x
- {0x0C, 0x50, 0x50, 0x50, 0x3C}, // y
- {0x44, 0x64, 0x54, 0x4C, 0x44}, // z
- {0x00, 0x08, 0x36, 0x41, 0x00}, // {
- {0x00, 0x00, 0x7F, 0x00, 0x00}, // |
- {0x00, 0x41, 0x36, 0x08, 0x00}, // }
- {0b00001000, 0b00000100, 0b00001100, 0b00001000, 0b00000100} // ~
-};
-
-/** pictures for the 5x7 dot matrix block
- * @details first value is left-most line, LSB is top dot, MSB is not used
- */
-static const uint8_t pict5x7[][5] = {
- {0x08, 0x08, 0x2A, 0x1C, 0x08}, // ->
- {0x08, 0x1C, 0x2A, 0x08, 0x08}, // <-
- {0b01110000, 0b01110000, 0b01111010, 0b01111100, 0b01011000}, // bunny side 1
- {0b00100000, 0b01110000, 0b01110010, 0b01111100, 0b01011000}, // bunny side 2
- {0b00111110, 0b01001001, 0b01010110, 0b01001001, 0b00111110}, // bunny face 1
- {0b00111110, 0b01010001, 0b01100110, 0b01010001, 0b00111110}, // bunny face 2
- {0b00111000, 0b01010111, 0b01100100, 0b01010111, 0b00111000}, // bunny face 3
- {0b00111000, 0b01001111, 0b01010100, 0b01001111, 0b00111000}, // bunny face 4
- {0b00111000, 0b01011110, 0b01101000, 0b01011110, 0b00111000}, // bunny face 5
- {0b01000001, 0b00110110, 0b00001000, 0b00110110, 0b01000001}, // cross 1
- {~0b01000001, ~0b00110110, ~0b00001000, ~0b00110110, ~0b01000001}, // cross 1 negated
- {0b00100010, 0b00010100, 0b00001000, 0b00010100, 0b00100010}, // cross 2
- {~0b00100010, ~0b00010100, ~0b00001000, ~0b00010100, ~0b00100010}, // cross 2 negated
- {0x00, 0x00, 0x00, 0x00, 0x00} // nothing
-};
-
-/** the 32 bits values to be shifted out to the VFD driver
- * @note split into 16 bit for SPI transfer
- * @note since the bits for digits and matrix are independent, they can be combined
- * @note we have more matrix (12) than digits (10)
- */
-static uint16_t driver_data[VFD_MATRIX][VFD_DRIVERS*2] = {0};
-/** which driver data is being transmitted */
-static volatile uint8_t spi_i = 0;
-/** which grid/part to activate
- * @note digits and matrix can be combined
- */
-static volatile uint8_t vfd_grid = 0;
-/** the bits used for selecting then digit and 7 segment anodes
- * @note for the second driver
- */
-static const uint32_t digit_mask = 0x00fffff0;
-
-void vfd_digit(uint8_t nb, char c)
-{
- if (!(nb=' ') { // only take printable characters
- uint8_t i = c-' '; // get index for character
- if (i>16); // write back data (most significant half)
-}
-
-void vfd_matrix(uint8_t nb, char c)
-{
- // check the matrix exists
- if (!(nb=' ')) { // only take printable characters
- uint8_t i = c-' '; // get index for character
- if (i0x7f) { // the non ASCII character are used for pictures
- uint8_t i = c-0x80; // get index for character
- if (i>16;
- }
-}
-
-void vfd_clear(void)
-{
- for (uint8_t i=0; i.
- *
- */
-/** library to drive vacuum fluorescent display using supertex HV518 shift register VFD drivers (API)
- * @details the current configuration is for a VFD extracted from a Samsung SER-6500 cash register
- * @file vfd_hv518.h
- * @author King Kévin
- * @date 2016
- * @note peripherals used: USART @ref usart
- */
-
-/** number HV518 VFD drivers */
-#define VFD_DRIVERS 3
-/** number of digits blocks on SER-6500 VFD */
-#define VFD_DIGITS 10
-/** number of dot matrix blocks on SER-6500 VFD */
-#define VFD_MATRIX 12
-
-/** set character to digit block
- * @param[in] nb digit block to set
- * @param[in] c ASCII character to set
- * @note use the MSB of @p nb to enable the dot
- */
-void vfd_digit(uint8_t nb, char c);
-/** set character to matrix block
- * @param[in] nb matrix block to set
- * @param[in] c ASCII character to set
- * @note on ASCII characters are used for pictures
- */
-void vfd_matrix(uint8_t nb, char c);
-/** clear VFD display */
-void vfd_clear(void);
-/** test VFD display (light up all segments) */
-void vfd_test(void);
-/** switch VFD on */
-void vfd_on(void);
-/** switch VFD display off */
-void vfd_off(void);
-/** setup VFD */
-void vfd_setup(void);