From cec0a0885aa9d8f09a4b6751bf5236d2bea1306b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Tue, 19 Jan 2016 12:15:46 +0100 Subject: [PATCH] add 7 segment encoder for VFD --- main.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 340 insertions(+), 39 deletions(-) diff --git a/main.c b/main.c index 3d68511..0fba560 100644 --- a/main.c +++ b/main.c @@ -52,16 +52,12 @@ int _write(int file, char *ptr, int len) return -1; } -static void clock_setup(void) -{ - rcc_clock_setup_in_hse_8mhz_out_72mhz(); // use 8 MHz high speed external clock to generate 72 MHz internal clock - rcc_periph_clock_enable(LED_RCC); //enable clock for LED - rcc_periph_clock_enable(VFD_RCC); //enable clock for VFD -} - static void gpio_setup(void) { + rcc_periph_clock_enable(LED_RCC); //enable clock for LED gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, LED_PIN); // set LED pin to 'output push-pull' + + rcc_periph_clock_enable(VFD_RCC); //enable clock for VFD gpio_set_mode(VFD_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, VFD_STR); // set VFD pin to 'output push-pull' gpio_set_mode(VFD_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, VFD_NLE); // set VFD pin to 'output push-pull' gpio_set_mode(VFD_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, VFD_CLK); // set VFD pin to 'output push-pull' @@ -69,66 +65,371 @@ static void gpio_setup(void) } +/* the ten seven segments + dot displays + * actually they also have a comma and underline, but we want to save space + */ +//static uint8_t digits[10]; +/* the twelve 5x7 dot matrix displays + * the last column dot/bit is not used, making them byte aligned + */ +//static uint8_t dots[12][5]; +/* the three 32 bit to be shifted out to the VFD controller + */ +static uint32_t vfd_data[3]; + +/* shift out the VFD data */ +static void vfd_shift(void) +{ + gpio_clear(VFD_PORT, VFD_NLE); // do not latch data + gpio_set(VFD_PORT, VFD_CLK); // clock is idle high + for (uint8_t i=0; i9) { + return; + } + vfd_data[0] = 0; + vfd_data[1] = 1<<(4+(9-nb)); // select digit + /* encode segment + * here the bit order (classic 7 segment + underline and dot) + * 3_ + * 8|9_|4 + * 7|6_|5.1 + * 0_2, + * */ + if (false) { // add the underline (not encoded) + vfd_data[1] |= (1<<(14)); + } + if (c&0x80) { // add the dot (encoded in the 8th bit) + vfd_data[1] |= (1<<(15)); + } + if (false) { // add the comma (not encoded) + vfd_data[1] |= (1<<(16)); + } + uint8_t segment = 0; + switch (c&0x7f) { + case '0': + segment = 0b00111111; + break; + case '1': + segment = 0b00000110; + break; + case '2': + segment = 0b01011011; + break; + case '3': + segment = 0b01001111; + break; + case '4': + segment = 0b01100110; + break; + case '5': + segment = 0b01101101; + break; + case '6': + segment = 0b01111101; + break; + case '7': + segment = 0b00000111; + break; + case '8': + segment = 0b01111111; + break; + case '9': + segment = 0b01101111; + break; + case 'a': + segment = 0b01011111; + break; + case 'b': + segment = 0b01111100; + break; + case 'c': + segment = 0b01011000; + break; + case 'd': + segment = 0b01011110; + break; + case 'e': + segment = 0b01111011; + break; + case 'f': + segment = 0b01110001; + break; + case 'g': + segment = 0b01101111; + break; + case 'h': + segment = 0b01110100; + break; + case 'i': + segment = 0b00010000; + break; + case 'j': + segment = 0b00001100; + break; + case 'k': + segment = 0b01110110; + break; + case 'l': + segment = 0b00110000; + break; + case 'm': + segment = 0b01010100; + break; + case 'n': + segment = 0b01010100; + break; + case 'o': + segment = 0b01011100; + break; + case 'p': + segment = 0b01110011; + break; + case 'q': + segment = 0b01100111; + break; + case 'r': + segment = 0b01010000; + break; + case 's': + segment = 0b01101101; + break; + case 't': + segment = 0b01111000; + break; + case 'u': + segment = 0b00011100; + break; + case 'v': + segment = 0b00011100; + break; + case 'w': + segment = 0b00011100; + break; + case 'x': + segment = 0b01110110; + break; + case 'y': + segment = 0b01101110; + break; + case 'z': + segment = 0b01011011; + break; + case 'A': + segment = 0b01110111; + break; + case 'B': + segment = 0b01111111; + break; + case 'C': + segment = 0b00111001; + break; + case 'D': + segment = 0b01011110; + break; + case 'E': + segment = 0b01111001; + break; + case 'F': + segment = 0b01110001; + break; + case 'G': + segment = 0b00111101; + break; + case 'H': + segment = 0b01110110; + break; + case 'I': + segment = 0b00110000; + break; + case 'J': + segment = 0b00011110; + break; + case 'K': + segment = 0b01110110; + break; + case 'L': + segment = 0b00111000; + break; + case 'M': + segment = 0b00110111; + break; + case 'N': + segment = 0b00110111; + break; + case 'O': + segment = 0b00111111; + break; + case 'P': + segment = 0b01110011; + break; + case 'Q': + segment = 0b01101011; + break; + case 'R': + segment = 0b00110011; + break; + case 'S': + segment = 0b01101101; + break; + case 'T': + segment = 0b01111000; + break; + case 'U': + segment = 0b00111110; + break; + case 'V': + segment = 0b00111110; + break; + case 'W': + segment = 0b00111110; + break; + case 'X': + segment = 0b01110110; + break; + case 'Y': + segment = 0b01101110; + break; + case 'Z': + segment = 0b01011011; + break; + case '_': + segment = 0b00001000; + break; + case '-': + segment = 0b01000000; + break; + case ' ': + segment = 0b00000000; + break; + case '\'': + segment = 0b00100000; + break; + case '"': + segment = 0b00100010; + break; + case '/': + segment = 0b01010010; + break; + case '\\': + segment = 0b01100100; + break; + case '=': + segment = 0b01001000; + break; + case ',': + segment = 0b00010000; + break; + case '>': + segment = 0b01001100; + break; + case '<': + segment = 0b01011000; + break; + case '(': + case '[': + case '{': + segment = 0b00111001; + break; + case ')': + case ']': + case '}': + segment = 0b00001111; + break; + case '@': + segment = 0b01111011; + break; + case '^': + segment = 0b00100011; + break; + case '`': + segment = 0b00000010; + break; + case '|': + segment = 0b00110000; + break; + case '~': + segment = 0b01000000; + break; + default: + segment = 0x00; + } + vfd_data[1] |= (segment<<(17)); // add the segment to memory + + vfd_data[2] = 0; +} + int main(void) { SCB_VTOR = (uint32_t) 0x08002000; // relocate vector table because of the bootloader + rcc_clock_setup_in_hse_8mhz_out_72mhz(); // use 8 MHz high speed external clock to generate 72 MHz internal clock - clock_setup(); // setup main clock - gpio_setup(); // setup main inputs/ouputs + gpio_setup(); // setup main inputs/outputs usart_setup(); // setup USART (for printing) - cdcacm_setup(); // setup USART (for printing) + cdcacm_setup(); // setup USB CDC ACM (for printing) setbuf(stdout, NULL); // set standard out buffer to NULL to immediately print setbuf(stderr, NULL); // set standard error buffer to NULL to immediately print printf("welcome to the STM32F1 CuVoodoo display driver\n"); - printf("sending VFD data\n"); gpio_set(VFD_PORT, VFD_STR); // disable HV output gpio_clear(VFD_PORT, VFD_NLE); // do not latch data gpio_set(VFD_PORT, VFD_CLK); // clock is idle high bool vfd_transmit = false; - uint32_t vfd_data[3] = {~0,~0,~0}; - uint8_t bit_flip = 0; + uint8_t digit = 0; + uint8_t c = 128; /* blink the LED with every transmitted character */ while (1) { while (usart_received) { // echo every received character - gpio_toggle(LED_PORT, LED_PIN); // toggle LED + //gpio_toggle(LED_PORT, LED_PIN); // toggle LED printf("%c",usart_getchar()); // transmit receive character vfd_transmit = true; } while (cdcacm_received) { // echo every received character - gpio_toggle(LED_PORT, LED_PIN); // toggle LED + //gpio_toggle(LED_PORT, LED_PIN); // toggle LED printf("%c",cdcacm_getchar()); // transmit receive character vfd_transmit = true; } while (vfd_transmit) { vfd_transmit = false; - /* send data to VFD (data valid on clock high) to 3x32 lines */ - gpio_set(VFD_PORT, VFD_STR); // disable HV output - gpio_clear(VFD_PORT, VFD_NLE); // do not latch data - gpio_set(VFD_PORT, VFD_CLK); // clock is idle high - for (uint8_t i=0; i<3; i++) { - printf("%08lx ", vfd_data[i]); - for (uint8_t b=0; b<32; b++) { - gpio_clear(VFD_PORT, VFD_CLK); - if (vfd_data[i]&(1<