CuVoodoo STM32F1 firmware template
vfd_hv518.c
Go to the documentation of this file.
1 /* This program is free software: you can redistribute it and/or modify
2  * it under the terms of the GNU General Public License as published by
3  * the Free Software Foundation, either version 3 of the License, or
4  * (at your option) any later version.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program. If not, see <http://www.gnu.org/licenses/>.
13  *
14  */
22 /* standard libraries */
23 #include <stdint.h> // standard integer types
24 #include <stdlib.h> // general utilities
25 
26 /* STM32 (including CM3) libraries */
27 #include <libopencm3/stm32/rcc.h> // real-time control clock library
28 #include <libopencm3/stm32/gpio.h> // general purpose input output library
29 #include <libopencm3/stm32/spi.h> // SPI library
30 #include <libopencm3/stm32/timer.h> // timer library
31 #include <libopencm3/cm3/nvic.h> // interrupt handler
32 
33 #include "global.h" // global definitions
34 #include "vfd_hv518.h" // VFD library API
35 
39 #define VFD_PORT GPIOA
40 #define VFD_PORT_RCC RCC_GPIOA
41 #define VFD_STR GPIO6
42 #define VFD_NLE GPIO4
48 #define VFD_SPI_RCC RCC_SPI1
49 #define VFD_SPI_PORT GPIOA
50 #define VFD_SPI_PORT_RCC RCC_GPIOA
51 #define VFD_SPI_IRQ NVIC_SPI1_IRQ
52 #define VFD_SPI_ISR spi1_isr
53 #define VFD_CLK GPIO_SPI1_SCK
54 #define VFD_DIN GPIO_SPI1_MOSI
60 #define VFD_TIMER_RCC RCC_TIM2
61 #define VFD_TIMER_IRQ NVIC_TIM2_IRQ
62 #define VFD_TIMER_ISR tim2_isr
68 static const uint8_t ascii_7segments[] = {
69  0b00000000, // space
70  0b00110000, // ! (I)
71  0b00100010, // "
72  0b01011100, // # (o)
73  0b01101101, // $ (s)
74  0b01010010, // % (/)
75  0b01111101, // & (6)
76  0b00100000, // '
77  0b00111001, // ( ([)
78  0b00001111, // )
79  0b01110000, // *
80  0b01000110, // +
81  0b00010000, // ,
82  0b01000000, // -
83  0b00010000, // . (,)
84  0b01010010, // /
85  0b00111111, // 0
86  0b00000110, // 1
87  0b01011011, // 2
88  0b01001111, // 3
89  0b01100110, // 4
90  0b01101101, // 5
91  0b01111101, // 6
92  0b00000111, // 7
93  0b01111111, // 8
94  0b01101111, // 9
95  0b01001000, // : (=)
96  0b01001000, // ; (=)
97  0b01011000, // <
98  0b01001000, // =
99  0b01001100, // >
100  0b01010011, // ?
101  0b01111011, // @
102  0b01110111, // A
103  0b01111111, // B
104  0b00111001, // C
105  0b01011110, // D
106  0b01111001, // E
107  0b01110001, // F
108  0b00111101, // G
109  0b01110110, // H
110  0b00110000, // I
111  0b00011110, // J
112  0b01110110, // K
113  0b00111000, // L
114  0b00110111, // M
115  0b00110111, // N
116  0b00111111, // O
117  0b01110011, // P
118  0b01101011, // Q
119  0b00110011, // R
120  0b01101101, // S
121  0b01111000, // T
122  0b00111110, // U
123  0b00111110, // V (U)
124  0b00111110, // W (U)
125  0b01110110, // X (H)
126  0b01101110, // Y
127  0b01011011, // Z
128  0b00111001, // [
129  0b01100100, // '\'
130  0b00001111, // /
131  0b00100011, // ^
132  0b00001000, // _
133  0b00000010, // `
134  0b01011111, // a
135  0b01111100, // b
136  0b01011000, // c
137  0b01011110, // d
138  0b01111011, // e
139  0b01110001, // f
140  0b01101111, // g
141  0b01110100, // h
142  0b00010000, // i
143  0b00001100, // j
144  0b01110110, // k
145  0b00110000, // l
146  0b01010100, // m
147  0b01010100, // n
148  0b01011100, // o
149  0b01110011, // p
150  0b01100111, // q
151  0b01010000, // r
152  0b01101101, // s
153  0b01111000, // t
154  0b00011100, // u
155  0b00011100, // v (u)
156  0b00011100, // w (u)
157  0b01110110, // x
158  0b01101110, // y
159  0b01011011, // z
160  0b00111001, // { ([)
161  0b00110000, // |
162  0b00001111, // } ([)
163  0b01000000, // ~
164 };
165 
170 static const uint8_t font5x7[][5] = {
171  {0x00, 0x00, 0x00, 0x00, 0x00}, // (space)
172  {0x00, 0x00, 0x5F, 0x00, 0x00}, // !
173  {0x00, 0x07, 0x00, 0x07, 0x00}, // "
174  {0x14, 0x7F, 0x14, 0x7F, 0x14}, // #
175  {0x24, 0x2A, 0x7F, 0x2A, 0x12}, // $
176  {0x23, 0x13, 0x08, 0x64, 0x62}, // %
177  {0x36, 0x49, 0x55, 0x22, 0x50}, // &
178  {0x00, 0x05, 0x03, 0x00, 0x00}, // '
179  {0x00, 0x1C, 0x22, 0x41, 0x00}, // (
180  {0x00, 0x41, 0x22, 0x1C, 0x00}, // )
181  {0x08, 0x2A, 0x1C, 0x2A, 0x08}, // *
182  {0x08, 0x08, 0x3E, 0x08, 0x08}, // +
183  {0x00, 0x50, 0x30, 0x00, 0x00}, // ,
184  {0x08, 0x08, 0x08, 0x08, 0x08}, // -
185  {0x00, 0x60, 0x60, 0x00, 0x00}, // .
186  {0x20, 0x10, 0x08, 0x04, 0x02}, // /
187  {0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0
188  {0x00, 0x42, 0x7F, 0x40, 0x00}, // 1
189  {0x42, 0x61, 0x51, 0x49, 0x46}, // 2
190  {0x21, 0x41, 0x45, 0x4B, 0x31}, // 3
191  {0x18, 0x14, 0x12, 0x7F, 0x10}, // 4
192  {0x27, 0x45, 0x45, 0x45, 0x39}, // 5
193  {0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6
194  {0x01, 0x71, 0x09, 0x05, 0x03}, // 7
195  {0x36, 0x49, 0x49, 0x49, 0x36}, // 8
196  {0x06, 0x49, 0x49, 0x29, 0x1E}, // 9
197  {0x00, 0x36, 0x36, 0x00, 0x00}, // :
198  {0x00, 0x56, 0x36, 0x00, 0x00}, // ;
199  {0x00, 0x08, 0x14, 0x22, 0x41}, // <
200  {0x14, 0x14, 0x14, 0x14, 0x14}, // =
201  {0x41, 0x22, 0x14, 0x08, 0x00}, // >
202  {0x02, 0x01, 0x51, 0x09, 0x06}, // ?
203  {0x32, 0x49, 0x79, 0x41, 0x3E}, // @
204  {0x7E, 0x11, 0x11, 0x11, 0x7E}, // A
205  {0x7F, 0x49, 0x49, 0x49, 0x36}, // B
206  {0x3E, 0x41, 0x41, 0x41, 0x22}, // C
207  {0x7F, 0x41, 0x41, 0x22, 0x1C}, // D
208  {0x7F, 0x49, 0x49, 0x49, 0x41}, // E
209  {0x7F, 0x09, 0x09, 0x01, 0x01}, // F
210  {0x3E, 0x41, 0x41, 0x51, 0x32}, // G
211  {0x7F, 0x08, 0x08, 0x08, 0x7F}, // H
212  {0x00, 0x41, 0x7F, 0x41, 0x00}, // I
213  {0x20, 0x40, 0x41, 0x3F, 0x01}, // J
214  {0x7F, 0x08, 0x14, 0x22, 0x41}, // K
215  {0x7F, 0x40, 0x40, 0x40, 0x40}, // L
216  {0x7F, 0x02, 0x04, 0x02, 0x7F}, // M
217  {0x7F, 0x04, 0x08, 0x10, 0x7F}, // N
218  {0x3E, 0x41, 0x41, 0x41, 0x3E}, // O
219  {0x7F, 0x09, 0x09, 0x09, 0x06}, // P
220  {0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q
221  {0x7F, 0x09, 0x19, 0x29, 0x46}, // R
222  {0x46, 0x49, 0x49, 0x49, 0x31}, // S
223  {0x01, 0x01, 0x7F, 0x01, 0x01}, // T
224  {0x3F, 0x40, 0x40, 0x40, 0x3F}, // U
225  {0x1F, 0x20, 0x40, 0x20, 0x1F}, // V
226  {0x7F, 0x20, 0x18, 0x20, 0x7F}, // W
227  {0x63, 0x14, 0x08, 0x14, 0x63}, // X
228  {0x03, 0x04, 0x78, 0x04, 0x03}, // Y
229  {0x61, 0x51, 0x49, 0x45, 0x43}, // Z
230  {0x00, 0x00, 0x7F, 0x41, 0x41}, // [
231  {0x02, 0x04, 0x08, 0x10, 0x20}, // '\'
232  {0x41, 0x41, 0x7F, 0x00, 0x00}, // ]
233  {0x04, 0x02, 0x01, 0x02, 0x04}, // ^
234  {0x40, 0x40, 0x40, 0x40, 0x40}, // _
235  {0x00, 0x01, 0x02, 0x04, 0x00}, // `
236  {0x20, 0x54, 0x54, 0x54, 0x78}, // a
237  {0x7F, 0x48, 0x44, 0x44, 0x38}, // b
238  {0x38, 0x44, 0x44, 0x44, 0x20}, // c
239  {0x38, 0x44, 0x44, 0x48, 0x7F}, // d
240  {0x38, 0x54, 0x54, 0x54, 0x18}, // e
241  {0x08, 0x7E, 0x09, 0x01, 0x02}, // f
242  {0x08, 0x14, 0x54, 0x54, 0x3C}, // g
243  {0x7F, 0x08, 0x04, 0x04, 0x78}, // h
244  {0x00, 0x44, 0x7D, 0x40, 0x00}, // i
245  {0x20, 0x40, 0x44, 0x3D, 0x00}, // j
246  {0x00, 0x7F, 0x10, 0x28, 0x44}, // k
247  {0x00, 0x41, 0x7F, 0x40, 0x00}, // l
248  {0x7C, 0x04, 0x18, 0x04, 0x78}, // m
249  {0x7C, 0x08, 0x04, 0x04, 0x78}, // n
250  {0x38, 0x44, 0x44, 0x44, 0x38}, // o
251  {0x7C, 0x14, 0x14, 0x14, 0x08}, // p
252  {0x08, 0x14, 0x14, 0x18, 0x7C}, // q
253  {0x7C, 0x08, 0x04, 0x04, 0x08}, // r
254  {0x48, 0x54, 0x54, 0x54, 0x20}, // s
255  {0x04, 0x3F, 0x44, 0x40, 0x20}, // t
256  {0x3C, 0x40, 0x40, 0x20, 0x7C}, // u
257  {0x1C, 0x20, 0x40, 0x20, 0x1C}, // v
258  {0x3C, 0x40, 0x30, 0x40, 0x3C}, // w
259  {0x44, 0x28, 0x10, 0x28, 0x44}, // x
260  {0x0C, 0x50, 0x50, 0x50, 0x3C}, // y
261  {0x44, 0x64, 0x54, 0x4C, 0x44}, // z
262  {0x00, 0x08, 0x36, 0x41, 0x00}, // {
263  {0x00, 0x00, 0x7F, 0x00, 0x00}, // |
264  {0x00, 0x41, 0x36, 0x08, 0x00}, // }
265  {0b00001000, 0b00000100, 0b00001100, 0b00001000, 0b00000100} // ~
266 };
267 
271 static const uint8_t pict5x7[][5] = {
272  {0x08, 0x08, 0x2A, 0x1C, 0x08}, // ->
273  {0x08, 0x1C, 0x2A, 0x08, 0x08}, // <-
274  {0b01110000, 0b01110000, 0b01111010, 0b01111100, 0b01011000}, // bunny side 1
275  {0b00100000, 0b01110000, 0b01110010, 0b01111100, 0b01011000}, // bunny side 2
276  {0b00111110, 0b01001001, 0b01010110, 0b01001001, 0b00111110}, // bunny face 1
277  {0b00111110, 0b01010001, 0b01100110, 0b01010001, 0b00111110}, // bunny face 2
278  {0b00111000, 0b01010111, 0b01100100, 0b01010111, 0b00111000}, // bunny face 3
279  {0b00111000, 0b01001111, 0b01010100, 0b01001111, 0b00111000}, // bunny face 4
280  {0b00111000, 0b01011110, 0b01101000, 0b01011110, 0b00111000}, // bunny face 5
281  {0b01000001, 0b00110110, 0b00001000, 0b00110110, 0b01000001}, // cross 1
282  {~0b01000001, ~0b00110110, ~0b00001000, ~0b00110110, ~0b01000001}, // cross 1 negated
283  {0b00100010, 0b00010100, 0b00001000, 0b00010100, 0b00100010}, // cross 2
284  {~0b00100010, ~0b00010100, ~0b00001000, ~0b00010100, ~0b00100010}, // cross 2 negated
285  {0x00, 0x00, 0x00, 0x00, 0x00} // nothing
286 };
287 
293 static uint16_t driver_data[VFD_MATRIX][VFD_DRIVERS*2] = {0};
295 static volatile uint8_t spi_i = 0;
299 static volatile uint8_t vfd_grid = 0;
303 static const uint32_t digit_mask = 0x00fffff0;
304 
305 void vfd_digit(uint8_t nb, char c)
306 {
307  if (!(nb<VFD_DIGITS)) { // check the digit exists
308  return;
309  }
310 
311  uint32_t digit_data = 0; // the data to be shifted out for the driver (for the second driver)
312 
313  digit_data = 1<<(4+(9-nb)); // select digit
314  /* encode segment
315  * here the bit order (classic 7 segment + underline and dot)
316  * 3_
317  * 8|9_|4
318  * 7|6_|5.1
319  * 0_2,
320  * */
321  if (false) { // add the underline (not encoded)
322  digit_data |= (1<<(14));
323  }
324  if (c&0x80) { // add the dot (encoded in the 8th bit)
325  digit_data |= (1<<(15));
326  }
327  if (false) { // add the comma (not encoded)
328  digit_data |= (1<<(16));
329  }
330 
331  c &= 0x7f; // only take the ASCII part
332  if (c>=' ') { // only take printable characters
333  uint8_t i = c-' '; // get index for character
334  if (i<LENGTH(ascii_7segments)) {
335  digit_data |= (ascii_7segments[i]<<(17)); // add encoded segments to memory
336  }
337  }
338 
339  digit_data &= digit_mask; // be sure only the bits for the digit are used
340  digit_data |= (driver_data[nb][2]+(driver_data[nb][3]<<16))&~digit_mask; // get the existing data and add the bits for the digit
341  driver_data[nb][2] = digit_data; // write back data (least significant half)
342  driver_data[nb][3] = (digit_data>>16); // write back data (most significant half)
343 }
344 
345 void vfd_matrix(uint8_t nb, char c)
346 {
347  // check the matrix exists
348  if (!(nb<VFD_MATRIX)) {
349  return;
350  }
351 
352  uint32_t matrix_data[VFD_DRIVERS] = {0}; // the data to be shifted out for the driver
353 
354  // select matrix
355  if (nb<4) {
356  matrix_data[1] = 1<<(3-nb);
357  } else {
358  matrix_data[0] = 1<<(35-nb);
359  }
360 
361  if ((c<0x80) && (c>=' ')) { // only take printable characters
362  uint8_t i = c-' '; // get index for character
363  if (i<LENGTH(font5x7)) {
364  matrix_data[1] |= font5x7[i][0]<<24;
365  matrix_data[2] |= font5x7[i][1]<<0;
366  matrix_data[2] |= font5x7[i][2]<<8;
367  matrix_data[2] |= font5x7[i][3]<<16;
368  matrix_data[2] |= font5x7[i][4]<<24;
369  }
370  } else if (c>0x7f) { // the non ASCII character are used for pictures
371  uint8_t i = c-0x80; // get index for character
372  if (i<LENGTH(pict5x7)) {
373  matrix_data[1] |= pict5x7[i][0]<<24;
374  matrix_data[2] |= pict5x7[i][1]<<0;
375  matrix_data[2] |= pict5x7[i][2]<<8;
376  matrix_data[2] |= pict5x7[i][3]<<16;
377  matrix_data[2] |= pict5x7[i][4]<<24;
378  }
379  }
380 
381  matrix_data[1] &= ~digit_mask; // be sure only the bits for the matrix are used
382  matrix_data[1] |= (driver_data[nb][2]+(driver_data[nb][3]<<16))&digit_mask; // get the existing data for the digit
383  // prepare the data for SPI to shift it out
384  for (uint8_t i=0; i<LENGTH(matrix_data); i++) {
385  driver_data[nb][i*2] = matrix_data[i];
386  driver_data[nb][i*2+1] = matrix_data[i]>>16;
387  }
388 }
389 
390 void vfd_clear(void)
391 {
392  for (uint8_t i=0; i<LENGTH(driver_data); i++) {
393  for (uint8_t j=0; j<LENGTH(driver_data[0]); j++) {
394  driver_data[i][j] = 0;
395  }
396  }
397 }
398 
399 void vfd_test(void)
400 {
401  for (uint8_t i=0; i<LENGTH(driver_data); i++) {
402  for (uint8_t j=0; j<LENGTH(driver_data[0]); j++) {
403  driver_data[i][j] = ~0;
404  }
405  }
406 }
407 
408 void vfd_on(void)
409 {
410  gpio_clear(VFD_PORT, VFD_STR); // enable HV output
411  timer_enable_counter(VFD_TIMER); // start timer to periodically output that to the parts
412 }
413 
414 void vfd_off(void)
415 {
416  gpio_set(VFD_PORT, VFD_STR); // disable HV output
417  timer_disable_counter(VFD_TIMER); // stop timer to periodically output that to the parts
418 }
419 
420 void vfd_setup(void)
421 {
422  /* setup GPIO to control the VFD */
423  rcc_periph_clock_enable(VFD_PORT_RCC); // enable clock for VFD GPIO
424  gpio_set_mode(VFD_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, VFD_STR); // set VFD pin to output push-pull
425  gpio_set_mode(VFD_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, VFD_NLE); // set VFD pin to output push-pull
426 
427  gpio_set(VFD_PORT, VFD_STR); // disable HV output
428  gpio_clear(VFD_PORT, VFD_NLE); // do not output latched data
429 
430  /* setup SPI to transmit data */
431  rcc_periph_clock_enable(VFD_SPI_RCC); // enable SPI clock
432  rcc_periph_clock_enable(VFD_SPI_PORT_RCC); // enable clock for VFD SPI GPIO
433  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
434  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
435 
436  spi_reset(VFD_SPI); // clear SPI values
437  /* set SPI:
438  * - use VFD_SPI port
439  * - divide clock by 8 for generating the baudrate (F_PCLK1 is 36MHz, max HV518 is 6MHz)
440  * - clock idle high polarity
441  * - data is valid on rising edge (second clock phase)
442  * - send 16 bits at a time
443  * - send least significant bit first (that's how I coded the data)
444  */
445  spi_init_master(VFD_SPI, SPI_CR1_BAUDRATE_FPCLK_DIV_8, SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_2, SPI_CR1_DFF_16BIT, SPI_CR1_LSBFIRST);
446  //spi_set_bidirectional_transmit_only_mode(VFD_SPI); // only use MOSI to transmit
447  spi_set_unidirectional_mode(VFD_SPI); // MISO is unused
448  /* set NSS high to enable transmission
449  * the NSS in STM32 can not be used as hardware slave select
450  * RM0008 reference manual 25.3.1 is misleading
451  * when hardware NSS is used and output is enabled NSS never goes up after transmission, even if SPI is disabled
452  * when software NSS is used, NSS can not be set high again, even when writing to the register
453  * the slave select must be done manually using GPIO */
454  spi_enable_software_slave_management(VFD_SPI);
455  spi_set_nss_high(VFD_SPI); // set NSS high
456 
457  nvic_enable_irq(VFD_SPI_IRQ); // enable SPI interrupt
458  spi_enable(VFD_SPI); // enable SPI (the tx empty interrupt will trigger)
459 
460  /* setup timer to refresh display */
461  rcc_periph_clock_enable(VFD_TIMER_RCC); // enable clock for timer block
462  timer_reset(VFD_TIMER); // reset timer state
463  timer_set_mode(VFD_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
464  timer_set_prescaler(VFD_TIMER, (SYSTEM_CLOCK_FREQ/(1<<16))-1); // set the prescaler so this 16 bits timer overflows at 1Hz
465  timer_set_period(VFD_TIMER, 0xffff/LENGTH(driver_data)/100); // set the refresh frequency
466  timer_enable_irq(VFD_TIMER, TIM_DIER_UIE); // enable interrupt for timer
467  nvic_enable_irq(VFD_TIMER_IRQ); // allow interrupt for timer
468 
469  vfd_clear(); // initialize values
470 }
471 
473 void VFD_SPI_ISR(void)
474 {
475  if (SPI_SR(VFD_SPI) & SPI_SR_TXE) { // transmission buffer empty
476  if (spi_i<LENGTH(driver_data[0])) { // check if data is available
477  gpio_clear(VFD_PORT, VFD_NLE); // slave select to latch data
478  spi_send(VFD_SPI, driver_data[vfd_grid][spi_i++]); // send next data
479  } else { // all data transmitted
480  spi_disable_tx_buffer_empty_interrupt(VFD_SPI); // no need to wait for new data
481  while (SPI_SR(VFD_SPI) & SPI_SR_BSY); // wait for data to be shifted out
482  spi_disable_tx_buffer_empty_interrupt(VFD_SPI); // no need to wait for new data
483  gpio_set(VFD_PORT, VFD_NLE); // output latched data
484  }
485  }
486 }
487 
489 void VFD_TIMER_ISR(void)
490 {
491  if (timer_get_flag(VFD_TIMER, TIM_SR_UIF)) { // overflow even happened
492  timer_clear_flag(VFD_TIMER, TIM_SR_UIF); // clear flag
493  spi_i = 0; // set the register to shift out
494  spi_enable_tx_buffer_empty_interrupt(VFD_SPI); // enable TX empty interrupt
495  vfd_grid = (vfd_grid+1)%LENGTH(driver_data); // got to next segment
496  }
497 }
static const uint8_t ascii_7segments[]
ASCII characters encoded for the 7 segments digit block.
Definition: vfd_hv518.c:68
static volatile uint8_t spi_i
which driver data is being transmitted
Definition: vfd_hv518.c:295
void vfd_test(void)
test VFD display (light up all segments)
Definition: vfd_hv518.c:399
#define VFD_SPI_PORT_RCC
GPIO port peripheral clock.
Definition: vfd_hv518.c:50
#define VFD_DRIVERS
number HV518 VFD drivers
Definition: vfd_hv518.h:24
#define VFD_TIMER_IRQ
timer interrupt signal
Definition: vfd_hv518.c:61
#define VFD_PORT
GPIO port.
Definition: vfd_hv518.c:39
#define VFD_TIMER_RCC
timer peripheral clock
Definition: vfd_hv518.c:60
#define VFD_SPI_ISR
SPI interrupt service routine.
Definition: vfd_hv518.c:52
void vfd_off(void)
switch VFD display off
Definition: vfd_hv518.c:414
#define VFD_MATRIX
number of dot matrix blocks on SER-6500 VFD
Definition: vfd_hv518.h:28
global definitions and methods (API)
static const uint8_t font5x7[][5]
font for the 5x7 dot matrix block
Definition: vfd_hv518.c:170
#define VFD_DIN
data input, where the data is shifted to
Definition: vfd_hv518.c:54
#define VFD_STR
strobe pin to enable high voltage output, high voltage is output on low
Definition: vfd_hv518.c:41
static volatile uint8_t vfd_grid
which grid/part to activate
Definition: vfd_hv518.c:299
library to drive vacuum fluorescent display using supertex HV518 shift register VFD drivers (API) ...
#define VFD_SPI_RCC
SPI peripheral.
Definition: vfd_hv518.c:48
static uint16_t driver_data[VFD_MATRIX][VFD_DRIVERS *2]
the 32 bits values to be shifted out to the VFD driver
Definition: vfd_hv518.c:293
static const uint8_t pict5x7[][5]
pictures for the 5x7 dot matrix block
Definition: vfd_hv518.c:271
void vfd_digit(uint8_t nb, char c)
set character to digit block
Definition: vfd_hv518.c:305
static const uint32_t digit_mask
the bits used for selecting then digit and 7 segment anodes
Definition: vfd_hv518.c:303
void vfd_setup(void)
setup VFD
Definition: vfd_hv518.c:420
#define VFD_TIMER_ISR
timer interrupt service routine
Definition: vfd_hv518.c:62
#define VFD_PORT_RCC
GPIO port peripheral clock.
Definition: vfd_hv518.c:40
void vfd_on(void)
switch VFD on
Definition: vfd_hv518.c:408
#define VFD_SPI_IRQ
SPI peripheral interrupt signal.
Definition: vfd_hv518.c:51
#define VFD_NLE
latch enable pin, stores the shifted data on low, output the parallel data on high ...
Definition: vfd_hv518.c:42
void vfd_clear(void)
clear VFD display
Definition: vfd_hv518.c:390
#define VFD_CLK
clock signal
Definition: vfd_hv518.c:53
#define LENGTH(x)
get the length of an array
Definition: global.h:26
#define VFD_DIGITS
number of digits blocks on SER-6500 VFD
Definition: vfd_hv518.h:26
#define VFD_SPI_PORT
GPIO port.
Definition: vfd_hv518.c:49
void vfd_matrix(uint8_t nb, char c)
set character to matrix block
Definition: vfd_hv518.c:345