document and correct VFD library

This commit is contained in:
King Kévin 2016-08-14 20:18:10 +02:00
parent c68ab36d97
commit 8002255525
2 changed files with 88 additions and 102 deletions

View File

@ -12,10 +12,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* Copyright (c) 2016 King Kévin <kingkevin@cuvoodoo.info> */
/* this library is used to drive the vacuum fluorescent display extracted from a Samsung SER-6500 cash register
* it uses three chained supertex HV518 shift register VFD drivers */
/** 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 <kingkevin@cuvoodoo.info>
* @date 2016
* @note peripherals used: SPI @ref vfd_hv518_spi , GPIO @ref vfd_hv518_gpio , timer @ref vfd_hv518_timer
*/
/* standard libraries */
#include <stdint.h> // standard integer types
#include <stdlib.h> // general utilities
@ -30,53 +33,37 @@
#include "global.h" // global definitions
#include "vfd_hv518.h" // VFD library API
/* supertex HV518 VFD driver pins */
/* port on which the pins to control the supertex HV518 VFD driver are
* we use port A because of the SPI interface */
#define VFD_PORT GPIOA
#define VFD_PORT_RCC RCC_GPIOA
/* SPI port to use */
#define VFD_SPI SPI1
#if (VFD_SPI==SPI1)
#define VFD_SPI_RCC RCC_SPI1
#define VFD_SPI_IRQ NVIC_SPI1_IRQ
#elif (VFD_SPI==SPI2)
#define VFD_SPI_RCC RCC_SPI2
#define VFD_SPI_IRQ NVIC_SPI2_IRQ
#endif
/* strobe pin to enable high voltage output
* high voltage is output on low
* drive using a GPIO PA6 (normally MISO) */
#define VFD_STR GPIO6
/* latch enable pin
* store the shifted data on low
* output the parallel data on high
* use GPIO (PA4) (NSS does not work as SS) */
#define VFD_NLE GPIO4
/* clock signal
* drive using SPI SCK (PA5) */
#define VFD_CLK GPIO_SPI1_SCK
/* data input, where the data is shifted to
* drive using SPI MOSI (PA7) */
#define VFD_DIN GPIO_SPI1_MOSI
/* timer for automatic refresh */
#define VFD_TIMER TIM2
#if (VFD_TIMER==TIM2)
#define VFD_TIMER_RCC RCC_TIM2
#define VFD_TIMER_IRQ NVIC_TIM2_IRQ
#elif (VFD_TIMER==TIM3)
#define VFD_TIMER_RCC RCC_TIM3
#define VFD_TIMER_IRQ NVIC_TIM3_IRQ
#elif (VFD_TIMER==TIM4)
#define VFD_TIMER_RCC RCC_TIM4
#define VFD_TIMER_IRQ NVIC_TIM4_IRQ
#elif (VFD_TIMER==TIM5)
#define VFD_TIMER_RCC RCC_TIM5
#define VFD_TIMER_IRQ NVIC_TIM5_IRQ
#endif
/** @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 */
/** @} */
/* ASCII characters encoded for 7 segments display
* starts with space
/** @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
@ -176,10 +163,9 @@ static const uint8_t ascii_7segments[] = {
0b01000000, // ~
};
/* font for the 5x7 dot matrix display
* from http://sunge.awardspace.com/glcd-sd/node4.html
* first value is left-most line
* LSB is top dot, MSB is not used
/** 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)
@ -279,9 +265,8 @@ static const uint8_t font5x7[][5] = {
{0b00001000, 0b00000100, 0b00001100, 0b00001000, 0b00000100} // ~
};
/* pictures for the 5x7 dot matrix display
* first value is left-most line
* LSB is top dot, MSB is not used
/** 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}, // ->
@ -300,18 +285,23 @@ static const uint8_t pict5x7[][5] = {
{0x00, 0x00, 0x00, 0x00, 0x00} // nothing
};
/* the 32 bits values to be shifted out to the VFD driver
* split into 16 bit for SPI transfer
* since the bits for digits and matrix are independent, they can be combined
* we have more matrix (12) than digits (10)
/** 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};
static volatile uint8_t spi_i = 0; // which driver data is being transmitted
static volatile uint8_t vfd_grid = 0; // which grid/part to activate (single digits and matrix can be combined)
static const uint32_t digit_mask = 0x00fffff0; // the bits used for selecting then digit and 7 segment anodes (for the second driver)
/** 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;
/* set digit <nb> to ASCII character <c>
* use the MSB of <c> to enable the dot */
void vfd_digit(uint8_t nb, char c)
{
if (!(nb<VFD_DIGITS)) { // check the digit exists
@ -352,8 +342,6 @@ void vfd_digit(uint8_t nb, char c)
driver_data[nb][3] = (digit_data>>16); // write back data (most significant half)
}
/* set dot matrix <nb> to ASCII character <c>
* non ASCII characters are used for pictures */
void vfd_matrix(uint8_t nb, char c)
{
// check the matrix exists
@ -399,7 +387,6 @@ void vfd_matrix(uint8_t nb, char c)
}
}
/* clear VFD display */
void vfd_clear(void)
{
for (uint8_t i=0; i<LENGTH(driver_data); i++) {
@ -409,7 +396,6 @@ void vfd_clear(void)
}
}
/* test VFD display (light up all anodes) */
void vfd_test(void)
{
for (uint8_t i=0; i<LENGTH(driver_data); i++) {
@ -419,21 +405,18 @@ void vfd_test(void)
}
}
/* switch VFD display on */
void vfd_on(void)
{
gpio_clear(VFD_PORT, VFD_STR); // enable HV output
timer_enable_counter(VFD_TIMER); // start timer to periodically output that to the parts
}
/* switch VFD display off */
void vfd_off(void)
{
gpio_set(VFD_PORT, VFD_STR); // disable HV output
timer_disable_counter(VFD_TIMER); // stop timer to periodically output that to the parts
}
/* setup VFD */
void vfd_setup(void)
{
/* setup GPIO to control the VFD */
@ -446,8 +429,9 @@ void vfd_setup(void)
/* setup SPI to transmit data */
rcc_periph_clock_enable(VFD_SPI_RCC); // enable SPI clock
gpio_set_mode(VFD_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, VFD_CLK); // set VFD pin to alternative function push-pull
gpio_set_mode(VFD_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, VFD_DIN); // set VFD pin to alternative function push-pull
rcc_periph_clock_enable(VFD_SPI_PORT_RCC); // enable clock for VFD SPI GPIO
gpio_set_mode(VFD_SPI_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, VFD_CLK); // set VFD pin to alternative function push-pull
gpio_set_mode(VFD_SPI_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, VFD_DIN); // set VFD pin to alternative function push-pull
spi_reset(VFD_SPI); // clear SPI values
/* set SPI:
@ -485,11 +469,8 @@ void vfd_setup(void)
vfd_clear(); // initialize values
}
#if (VFD_SPI==SPI1)
void spi1_isr(void)
#elif (VFD_SPI==SPI2)
void spi2_isr(void)
#endif
/** SPI interrupt service routine called when data has been transmitted */
void VFD_SPI_ISR(void)
{
if (SPI_SR(VFD_SPI) & SPI_SR_TXE) { // transmission buffer empty
if (spi_i<LENGTH(driver_data[0])) { // check if data is available
@ -504,15 +485,8 @@ void spi2_isr(void)
}
}
#if (VFD_TIMER==TIM2)
void tim2_isr(void)
#elif (VFD_TIMER==TIM3)
void tim3_isr(void)
#elif (VFD_TIMER==TIM4)
void tim4_isr(void)
#elif (VFD_TIMER==TIM5)
void tim5_isr(void)
#endif
/** timer interrupt service routine called time passed */
void VFD_TIMER_ISR(void)
{
if (timer_get_flag(VFD_TIMER, TIM_SR_UIF)) { // overflow even happened
timer_clear_flag(VFD_TIMER, TIM_SR_UIF); // clear flag

View File

@ -12,28 +12,40 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* Copyright (c) 2016 King Kévin <kingkevin@cuvoodoo.info> */
/* this library is used to drive the vacuum fluorescent display extracted from a Samsung SER-6500 cash register
* it uses three chained supertex HV518 shift register VFD drivers */
/** 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 <kingkevin@cuvoodoo.info>
* @date 2016
* @note peripherals used: USART @ref usart
*/
/* the number of blocks available on the VFD */
/** 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 digit <nb> to ASCII character <c>
* use the MSB of <c> to enable the dot */
/** 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 dot matrix <nb> to ASCII character <c>
* non ASCII characters are used for pictures */
/** 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 */
/** clear VFD display */
void vfd_clear(void);
/* test VFD display (light up all anodes) */
/** test VFD display (light up all segments) */
void vfd_test(void);
/* transmit every digit and matrix */
/** switch VFD on */
void vfd_on(void);
/* switch VFD display off */
/** switch VFD display off */
void vfd_off(void);
/* setup VFD */
/** setup VFD */
void vfd_setup(void);