combine the driver data for digits and matrix
This commit is contained in:
parent
94664bafad
commit
78e2f7bb1c
3
global.h
3
global.h
|
@ -14,6 +14,9 @@
|
||||||
*/
|
*/
|
||||||
/* Copyright (c) 2016 King Kévin <kingkevin@cuvoodoo.info> */
|
/* Copyright (c) 2016 King Kévin <kingkevin@cuvoodoo.info> */
|
||||||
|
|
||||||
|
/* get the length of an array */
|
||||||
|
#define LENGTH(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
/* system clock frequency in Hz */
|
/* system clock frequency in Hz */
|
||||||
#define SYSTEM_CLOCK_FREQ 72000000
|
#define SYSTEM_CLOCK_FREQ 72000000
|
||||||
|
|
||||||
|
|
88
lib/vfd.c
88
lib/vfd.c
|
@ -30,9 +30,6 @@
|
||||||
#include "global.h" // global definitions
|
#include "global.h" // global definitions
|
||||||
#include "vfd.h" // VFD library API
|
#include "vfd.h" // VFD library API
|
||||||
|
|
||||||
/* get the length of an array */
|
|
||||||
#define LENGTH(x) (sizeof(x) / sizeof((x)[0]))
|
|
||||||
|
|
||||||
/* supertex HV518 VFD driver pins */
|
/* supertex HV518 VFD driver pins */
|
||||||
/* port on which the pins to control the supertex HV518 VFD driver are
|
/* port on which the pins to control the supertex HV518 VFD driver are
|
||||||
* we use port A because of the SPI interface */
|
* we use port A because of the SPI interface */
|
||||||
|
@ -304,10 +301,14 @@ static const uint8_t pict5x7[][5] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the 32 bits values to be shifted out to the VFD driver
|
/* the 32 bits values to be shifted out to the VFD driver
|
||||||
* split into 16 bit for SPI transfer */
|
* split into 16 bit for SPI transfer
|
||||||
static uint16_t vfd_spi[VFD_DIGITS+VFD_MATRIX][VFD_DRIVERS*2] = {0};
|
* since the bits for digits and matrix are independant, they can be conbined
|
||||||
static volatile uint8_t vfd_spi_i = 0; // which driver data is being transmitted
|
* 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_mux = 0; // which part to output
|
static volatile uint8_t vfd_mux = 0; // which part to output
|
||||||
|
static const uint32_t digit_mask = 0x00fff0; // the bits used for selecting then digit and 7 segment anodes (for the second driver)
|
||||||
|
|
||||||
/* set digit <nb> to ASCII character <c>
|
/* set digit <nb> to ASCII character <c>
|
||||||
* use the MSB of <c> to enable the dot */
|
* use the MSB of <c> to enable the dot */
|
||||||
|
@ -317,9 +318,9 @@ void vfd_digit(uint8_t nb, char c)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t vfd_data[VFD_DRIVERS] = {0}; // the data to be shifted out for the driver
|
uint32_t digit_data = 0; // the data to be shifted out for the driver (for the second driver)
|
||||||
|
|
||||||
vfd_data[1] = 1<<(4+(9-nb)); // select digit
|
digit_data = 1<<(4+(9-nb)); // select digit
|
||||||
/* encode segment
|
/* encode segment
|
||||||
* here the bit order (classic 7 segment + underline and dot)
|
* here the bit order (classic 7 segment + underline and dot)
|
||||||
* 3_
|
* 3_
|
||||||
|
@ -328,28 +329,27 @@ void vfd_digit(uint8_t nb, char c)
|
||||||
* 0_2,
|
* 0_2,
|
||||||
* */
|
* */
|
||||||
if (false) { // add the underline (not encoded)
|
if (false) { // add the underline (not encoded)
|
||||||
vfd_data[1] |= (1<<(14));
|
digit_data |= (1<<(14));
|
||||||
}
|
}
|
||||||
if (c&0x80) { // add the dot (encoded in the 8th bit)
|
if (c&0x80) { // add the dot (encoded in the 8th bit)
|
||||||
vfd_data[1] |= (1<<(15));
|
digit_data |= (1<<(15));
|
||||||
}
|
}
|
||||||
if (false) { // add the comma (not encoded)
|
if (false) { // add the comma (not encoded)
|
||||||
vfd_data[1] |= (1<<(16));
|
digit_data |= (1<<(16));
|
||||||
}
|
}
|
||||||
|
|
||||||
c &= 0x7f; // only take the ASCII part
|
c &= 0x7f; // only take the ASCII part
|
||||||
if (c>=' ') { // only take printable characters
|
if (c>=' ') { // only take printable characters
|
||||||
uint8_t i = c-' '; // get index for character
|
uint8_t i = c-' '; // get index for character
|
||||||
if (i<LENGTH(ascii_7segments)) {
|
if (i<LENGTH(ascii_7segments)) {
|
||||||
vfd_data[1] |= (ascii_7segments[i]<<(17)); // add encoded segments to memory
|
digit_data |= (ascii_7segments[i]<<(17)); // add encoded segments to memory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare the data for SPI to shift it out
|
digit_data &= digit_mask; // be sure only the bits for the digit are used
|
||||||
for (uint8_t i=0; i<LENGTH(vfd_data); i++) {
|
digit_data |= (driver_data[nb][2]+(driver_data[nb][3]<<16))&~digit_mask; // get the existing data and add the bits for the digit
|
||||||
vfd_spi[nb][i*2] = vfd_data[i];
|
driver_data[nb][2] = digit_data; // write back data (least significant half)
|
||||||
vfd_spi[nb][i*2+1] = vfd_data[i]>>16;
|
driver_data[nb][3] = (digit_data>>16); // write back data (most significant half)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set dot matrix <nb> to ASCII character <c>
|
/* set dot matrix <nb> to ASCII character <c>
|
||||||
|
@ -361,39 +361,41 @@ void vfd_matrix(uint8_t nb, char c)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t vfd_data[VFD_DRIVERS] = {0}; // the data to be shifted out for the driver
|
uint32_t matrix_data[VFD_DRIVERS] = {0}; // the data to be shifted out for the driver
|
||||||
|
|
||||||
// select matrix
|
// select matrix
|
||||||
if (nb<4) {
|
if (nb<4) {
|
||||||
vfd_data[1] = 1<<(3-nb);
|
matrix_data[1] = 1<<(3-nb);
|
||||||
} else {
|
} else {
|
||||||
vfd_data[0] = 1<<(35-nb);
|
matrix_data[0] = 1<<(35-nb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((c<0x80) && (c>=' ')) { // only take printable characters
|
if ((c<0x80) && (c>=' ')) { // only take printable characters
|
||||||
uint8_t i = c-' '; // get index for character
|
uint8_t i = c-' '; // get index for character
|
||||||
if (i<LENGTH(font5x7)) {
|
if (i<LENGTH(font5x7)) {
|
||||||
vfd_data[1] |= font5x7[i][0]<<24;
|
matrix_data[1] |= font5x7[i][0]<<24;
|
||||||
vfd_data[2] |= font5x7[i][1]<<0;
|
matrix_data[2] |= font5x7[i][1]<<0;
|
||||||
vfd_data[2] |= font5x7[i][2]<<8;
|
matrix_data[2] |= font5x7[i][2]<<8;
|
||||||
vfd_data[2] |= font5x7[i][3]<<16;
|
matrix_data[2] |= font5x7[i][3]<<16;
|
||||||
vfd_data[2] |= font5x7[i][4]<<24;
|
matrix_data[2] |= font5x7[i][4]<<24;
|
||||||
}
|
}
|
||||||
} else if (c>0x7f) { // the non ASCII character are used for pictures
|
} else if (c>0x7f) { // the non ASCII character are used for pictures
|
||||||
uint8_t i = c-0x80; // get index for character
|
uint8_t i = c-0x80; // get index for character
|
||||||
if (i<LENGTH(pict5x7)) {
|
if (i<LENGTH(pict5x7)) {
|
||||||
vfd_data[1] |= pict5x7[i][0]<<24;
|
matrix_data[1] |= pict5x7[i][0]<<24;
|
||||||
vfd_data[2] |= pict5x7[i][1]<<0;
|
matrix_data[2] |= pict5x7[i][1]<<0;
|
||||||
vfd_data[2] |= pict5x7[i][2]<<8;
|
matrix_data[2] |= pict5x7[i][2]<<8;
|
||||||
vfd_data[2] |= pict5x7[i][3]<<16;
|
matrix_data[2] |= pict5x7[i][3]<<16;
|
||||||
vfd_data[2] |= pict5x7[i][4]<<24;
|
matrix_data[2] |= pict5x7[i][4]<<24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
matrix_data[1] &= ~digit_mask; // be sure only the bits for the matrix are used
|
||||||
|
matrix_data[1] |= (driver_data[nb][2]+(driver_data[nb][3]<<16))&digit_mask; // get the existing data for the digit
|
||||||
// prepare the data for SPI to shift it out
|
// prepare the data for SPI to shift it out
|
||||||
for (uint8_t i=0; i<LENGTH(vfd_data); i++) {
|
for (uint8_t i=0; i<LENGTH(matrix_data); i++) {
|
||||||
vfd_spi[nb+VFD_DIGITS][i*2] = vfd_data[i];
|
driver_data[nb][i*2] = matrix_data[i];
|
||||||
vfd_spi[nb+VFD_DIGITS][i*2+1] = vfd_data[i]>>16;
|
driver_data[nb][i*2+1] = matrix_data[i]>>16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,9 +403,9 @@ void vfd_matrix(uint8_t nb, char c)
|
||||||
* the data has to be transmitted separately */
|
* the data has to be transmitted separately */
|
||||||
void vfd_clear(void)
|
void vfd_clear(void)
|
||||||
{
|
{
|
||||||
for (uint8_t i=0; i<LENGTH(vfd_spi); i++) {
|
for (uint8_t i=0; i<LENGTH(driver_data); i++) {
|
||||||
for (uint8_t j=0; j<LENGTH(vfd_spi[0]); j++) {
|
for (uint8_t j=0; j<LENGTH(driver_data[0]); j++) {
|
||||||
vfd_spi[i][j] = 0;
|
driver_data[i][j] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,9 +414,9 @@ void vfd_clear(void)
|
||||||
* the data has to be transmitted separately */
|
* the data has to be transmitted separately */
|
||||||
void vfd_test(void)
|
void vfd_test(void)
|
||||||
{
|
{
|
||||||
for (uint8_t i=0; i<LENGTH(vfd_spi); i++) {
|
for (uint8_t i=0; i<LENGTH(driver_data); i++) {
|
||||||
for (uint8_t j=0; j<LENGTH(vfd_spi[0]); j++) {
|
for (uint8_t j=0; j<LENGTH(driver_data[0]); j++) {
|
||||||
vfd_spi[i][j] = ~0;
|
driver_data[i][j] = ~0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -502,9 +504,9 @@ void spi2_isr(void)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (SPI_SR(VFD_SPI) & SPI_SR_TXE) { // transmission buffer empty
|
if (SPI_SR(VFD_SPI) & SPI_SR_TXE) { // transmission buffer empty
|
||||||
if (vfd_spi_i<LENGTH(vfd_spi[0])) { // check if data is available
|
if (spi_i<LENGTH(driver_data[0])) { // check if data is available
|
||||||
gpio_clear(VFD_PORT, VFD_NLE); // slave select to latch data
|
gpio_clear(VFD_PORT, VFD_NLE); // slave select to latch data
|
||||||
spi_send(VFD_SPI, vfd_spi[vfd_mux][vfd_spi_i++]); // send next data
|
spi_send(VFD_SPI, driver_data[vfd_mux][spi_i++]); // send next data
|
||||||
} else { // all data transmitted
|
} else { // all data transmitted
|
||||||
spi_disable_tx_buffer_empty_interrupt(VFD_SPI); // no need to wait for new data
|
spi_disable_tx_buffer_empty_interrupt(VFD_SPI); // no need to wait for new data
|
||||||
while (SPI_SR(VFD_SPI) & SPI_SR_BSY); // wait for data to be shifted out
|
while (SPI_SR(VFD_SPI) & SPI_SR_BSY); // wait for data to be shifted out
|
||||||
|
@ -528,8 +530,8 @@ void tim5_isr(void)
|
||||||
if (timer_get_flag(VFD_TIMER, TIM_SR_UIF)) { // overflow even happened
|
if (timer_get_flag(VFD_TIMER, TIM_SR_UIF)) { // overflow even happened
|
||||||
gpio_toggle(LED_PORT, LED_PIN);
|
gpio_toggle(LED_PORT, LED_PIN);
|
||||||
timer_clear_flag(VFD_TIMER, TIM_SR_UIF); // clear flag
|
timer_clear_flag(VFD_TIMER, TIM_SR_UIF); // clear flag
|
||||||
vfd_spi_i = 0; // set the register to shift out
|
spi_i = 0; // set the register to shift out
|
||||||
spi_enable_tx_buffer_empty_interrupt(VFD_SPI); // enable TX empty interrupt
|
spi_enable_tx_buffer_empty_interrupt(VFD_SPI); // enable TX empty interrupt
|
||||||
vfd_mux = (vfd_mux+1)%LENGTH(vfd_spi); // got to next segment
|
vfd_mux = (vfd_mux+1)%LENGTH(driver_data); // got to next segment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
main.c
3
main.c
|
@ -36,9 +36,6 @@
|
||||||
#include "usb_cdcacm.h" // USB CDC ACM utilities
|
#include "usb_cdcacm.h" // USB CDC ACM utilities
|
||||||
#include "vfd.h" // VFD driver
|
#include "vfd.h" // VFD driver
|
||||||
|
|
||||||
/* get the length of an array */
|
|
||||||
#define LENGTH(x) (sizeof(x) / sizeof((x)[0]))
|
|
||||||
|
|
||||||
/* default output (i.e. for printf) */
|
/* default output (i.e. for printf) */
|
||||||
int _write(int file, char *ptr, int len)
|
int _write(int file, char *ptr, int len)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue