27 #include <libopencm3/stm32/rcc.h> 28 #include <libopencm3/stm32/gpio.h> 29 #include <libopencm3/stm32/spi.h> 30 #include <libopencm3/stm32/timer.h> 31 #include <libopencm3/cm3/nvic.h> 39 #define VFD_PORT GPIOA 40 #define VFD_PORT_RCC RCC_GPIOA 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[] = { 171 {0x00, 0x00, 0x00, 0x00, 0x00},
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},
188 {0x00, 0x42, 0x7F, 0x40, 0x00},
189 {0x42, 0x61, 0x51, 0x49, 0x46},
190 {0x21, 0x41, 0x45, 0x4B, 0x31},
191 {0x18, 0x14, 0x12, 0x7F, 0x10},
192 {0x27, 0x45, 0x45, 0x45, 0x39},
193 {0x3C, 0x4A, 0x49, 0x49, 0x30},
194 {0x01, 0x71, 0x09, 0x05, 0x03},
195 {0x36, 0x49, 0x49, 0x49, 0x36},
196 {0x06, 0x49, 0x49, 0x29, 0x1E},
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},
205 {0x7F, 0x49, 0x49, 0x49, 0x36},
206 {0x3E, 0x41, 0x41, 0x41, 0x22},
207 {0x7F, 0x41, 0x41, 0x22, 0x1C},
208 {0x7F, 0x49, 0x49, 0x49, 0x41},
209 {0x7F, 0x09, 0x09, 0x01, 0x01},
210 {0x3E, 0x41, 0x41, 0x51, 0x32},
211 {0x7F, 0x08, 0x08, 0x08, 0x7F},
212 {0x00, 0x41, 0x7F, 0x41, 0x00},
213 {0x20, 0x40, 0x41, 0x3F, 0x01},
214 {0x7F, 0x08, 0x14, 0x22, 0x41},
215 {0x7F, 0x40, 0x40, 0x40, 0x40},
216 {0x7F, 0x02, 0x04, 0x02, 0x7F},
217 {0x7F, 0x04, 0x08, 0x10, 0x7F},
218 {0x3E, 0x41, 0x41, 0x41, 0x3E},
219 {0x7F, 0x09, 0x09, 0x09, 0x06},
220 {0x3E, 0x41, 0x51, 0x21, 0x5E},
221 {0x7F, 0x09, 0x19, 0x29, 0x46},
222 {0x46, 0x49, 0x49, 0x49, 0x31},
223 {0x01, 0x01, 0x7F, 0x01, 0x01},
224 {0x3F, 0x40, 0x40, 0x40, 0x3F},
225 {0x1F, 0x20, 0x40, 0x20, 0x1F},
226 {0x7F, 0x20, 0x18, 0x20, 0x7F},
227 {0x63, 0x14, 0x08, 0x14, 0x63},
228 {0x03, 0x04, 0x78, 0x04, 0x03},
229 {0x61, 0x51, 0x49, 0x45, 0x43},
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},
237 {0x7F, 0x48, 0x44, 0x44, 0x38},
238 {0x38, 0x44, 0x44, 0x44, 0x20},
239 {0x38, 0x44, 0x44, 0x48, 0x7F},
240 {0x38, 0x54, 0x54, 0x54, 0x18},
241 {0x08, 0x7E, 0x09, 0x01, 0x02},
242 {0x08, 0x14, 0x54, 0x54, 0x3C},
243 {0x7F, 0x08, 0x04, 0x04, 0x78},
244 {0x00, 0x44, 0x7D, 0x40, 0x00},
245 {0x20, 0x40, 0x44, 0x3D, 0x00},
246 {0x00, 0x7F, 0x10, 0x28, 0x44},
247 {0x00, 0x41, 0x7F, 0x40, 0x00},
248 {0x7C, 0x04, 0x18, 0x04, 0x78},
249 {0x7C, 0x08, 0x04, 0x04, 0x78},
250 {0x38, 0x44, 0x44, 0x44, 0x38},
251 {0x7C, 0x14, 0x14, 0x14, 0x08},
252 {0x08, 0x14, 0x14, 0x18, 0x7C},
253 {0x7C, 0x08, 0x04, 0x04, 0x08},
254 {0x48, 0x54, 0x54, 0x54, 0x20},
255 {0x04, 0x3F, 0x44, 0x40, 0x20},
256 {0x3C, 0x40, 0x40, 0x20, 0x7C},
257 {0x1C, 0x20, 0x40, 0x20, 0x1C},
258 {0x3C, 0x40, 0x30, 0x40, 0x3C},
259 {0x44, 0x28, 0x10, 0x28, 0x44},
260 {0x0C, 0x50, 0x50, 0x50, 0x3C},
261 {0x44, 0x64, 0x54, 0x4C, 0x44},
262 {0x00, 0x08, 0x36, 0x41, 0x00},
263 {0x00, 0x00, 0x7F, 0x00, 0x00},
264 {0x00, 0x41, 0x36, 0x08, 0x00},
265 {0b00001000, 0b00000100, 0b00001100, 0b00001000, 0b00000100}
272 {0x08, 0x08, 0x2A, 0x1C, 0x08},
273 {0x08, 0x1C, 0x2A, 0x08, 0x08},
274 {0b01110000, 0b01110000, 0b01111010, 0b01111100, 0b01011000},
275 {0b00100000, 0b01110000, 0b01110010, 0b01111100, 0b01011000},
276 {0b00111110, 0b01001001, 0b01010110, 0b01001001, 0b00111110},
277 {0b00111110, 0b01010001, 0b01100110, 0b01010001, 0b00111110},
278 {0b00111000, 0b01010111, 0b01100100, 0b01010111, 0b00111000},
279 {0b00111000, 0b01001111, 0b01010100, 0b01001111, 0b00111000},
280 {0b00111000, 0b01011110, 0b01101000, 0b01011110, 0b00111000},
281 {0b01000001, 0b00110110, 0b00001000, 0b00110110, 0b01000001},
282 {~0b01000001, ~0b00110110, ~0b00001000, ~0b00110110, ~0b01000001},
283 {0b00100010, 0b00010100, 0b00001000, 0b00010100, 0b00100010},
284 {~0b00100010, ~0b00010100, ~0b00001000, ~0b00010100, ~0b00100010},
285 {0x00, 0x00, 0x00, 0x00, 0x00}
311 uint32_t digit_data = 0;
313 digit_data = 1<<(4+(9-nb));
322 digit_data |= (1<<(14));
325 digit_data |= (1<<(15));
328 digit_data |= (1<<(16));
356 matrix_data[1] = 1<<(3-nb);
358 matrix_data[0] = 1<<(35-nb);
361 if ((c<0x80) && (c>=
' ')) {
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;
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;
384 for (uint8_t i=0; i<
LENGTH(matrix_data); i++) {
411 timer_enable_counter(VFD_TIMER);
417 timer_disable_counter(VFD_TIMER);
424 gpio_set_mode(
VFD_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
VFD_STR);
425 gpio_set_mode(
VFD_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
VFD_NLE);
433 gpio_set_mode(
VFD_SPI_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
VFD_CLK);
434 gpio_set_mode(
VFD_SPI_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
VFD_DIN);
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);
447 spi_set_unidirectional_mode(VFD_SPI);
454 spi_enable_software_slave_management(VFD_SPI);
455 spi_set_nss_high(VFD_SPI);
462 timer_reset(VFD_TIMER);
463 timer_set_mode(VFD_TIMER, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
464 timer_set_prescaler(VFD_TIMER, (SYSTEM_CLOCK_FREQ/(1<<16))-1);
466 timer_enable_irq(VFD_TIMER, TIM_DIER_UIE);
475 if (SPI_SR(VFD_SPI) & SPI_SR_TXE) {
480 spi_disable_tx_buffer_empty_interrupt(VFD_SPI);
481 while (SPI_SR(VFD_SPI) & SPI_SR_BSY);
482 spi_disable_tx_buffer_empty_interrupt(VFD_SPI);
491 if (timer_get_flag(VFD_TIMER, TIM_SR_UIF)) {
492 timer_clear_flag(VFD_TIMER, TIM_SR_UIF);
494 spi_enable_tx_buffer_empty_interrupt(VFD_SPI);
static const uint8_t ascii_7segments[]
ASCII characters encoded for the 7 segments digit block.
static volatile uint8_t spi_i
which driver data is being transmitted
void vfd_test(void)
test VFD display (light up all segments)
#define VFD_SPI_PORT_RCC
GPIO port peripheral clock.
#define VFD_DRIVERS
number HV518 VFD drivers
#define VFD_TIMER_IRQ
timer interrupt signal
#define VFD_PORT
GPIO port.
#define VFD_TIMER_RCC
timer peripheral clock
#define VFD_SPI_ISR
SPI interrupt service routine.
void vfd_off(void)
switch VFD display off
#define VFD_MATRIX
number of dot matrix blocks on SER-6500 VFD
global definitions and methods (API)
static const uint8_t font5x7[][5]
font for the 5x7 dot matrix block
#define VFD_DIN
data input, where the data is shifted to
#define VFD_STR
strobe pin to enable high voltage output, high voltage is output on low
static volatile uint8_t vfd_grid
which grid/part to activate
library to drive vacuum fluorescent display using supertex HV518 shift register VFD drivers (API) ...
#define VFD_SPI_RCC
SPI peripheral.
static uint16_t driver_data[VFD_MATRIX][VFD_DRIVERS *2]
the 32 bits values to be shifted out to the VFD driver
static const uint8_t pict5x7[][5]
pictures for the 5x7 dot matrix block
void vfd_digit(uint8_t nb, char c)
set character to digit block
static const uint32_t digit_mask
the bits used for selecting then digit and 7 segment anodes
void vfd_setup(void)
setup VFD
#define VFD_TIMER_ISR
timer interrupt service routine
#define VFD_PORT_RCC
GPIO port peripheral clock.
void vfd_on(void)
switch VFD on
#define VFD_SPI_IRQ
SPI peripheral interrupt signal.
#define VFD_NLE
latch enable pin, stores the shifted data on low, output the parallel data on high ...
void vfd_clear(void)
clear VFD display
#define VFD_CLK
clock signal
#define LENGTH(x)
get the length of an array
#define VFD_DIGITS
number of digits blocks on SER-6500 VFD
#define VFD_SPI_PORT
GPIO port.
void vfd_matrix(uint8_t nb, char c)
set character to matrix block