/* PCF2111 LCD driver example code. Used with a dual-chip module (each chip drives 8 digits). Data and Clock lines are shared. The code displays a scrolling message on the 16 digit 7 segment LCD. A hexadecimal font (for this particular segment setup) extended with several characters is included. segment map: A or B indicates A/B register a1 --- | |a3 b1| a2| --- | |a4 b2| | --- __ b4 \/b3 docs: LOCM3 docs: http://libopencm3.org/docs/latest/stm32f1/html/ PCF2111 datasheet: https://www.nxp.com/docs/en/data-sheet/PCF21XXC_FAM.pdf Copyright 2020 polprog.net. Released on 3-clause BSD. See COPYING file for details */ #define STM32F1 #include #include /* PCF2111 module IO */ #define LCD_PORT GPIOA #define LCD_CLK GPIO0 #define LCD_DATA GPIO2 #define LCD_CS1 GPIO3 #define LCD_CS2 GPIO1 /* test font uint8_t font[] = { 0b10000000, 0b01000000, 0b00100000, 0b00010000, 0b00001000, 0b00000100, 0b00000010, 0b00000001, 0b11110000, 0b00001111 };*/ /* real font */ uint8_t font[] = { //b4-b1 a4-a1 0b10111101,//0 0b00001100,//1 0b10100111,//2 0b10001111,//3 0b00011110,//4 0b10011011,//5 0b10111011,//6 0b00001101,//7 0b10111111,//8 0b10011111,//9 0b00111111,//A 10 0b10111010,//b 11 0b10110001,//C 12 0b10101110,//d 13 0b10110011,//E 14 0b00110011,//F 15 // letters 0b00111010,//H 16 0b00111110,//k 17 0b10110010,//t 18 0b00110111,//P 19 0b10110000,//L 20 0b00101010,//N 21 0b00000000,//space 22 0b01000100,//exclam 23 }; /* structure for holding the PCF2111 data */ struct pcf2111 { uint32_t rega, regb; }; void pcf2111_putchar(char c, uint8_t pos, struct pcf2111 *where){ where->rega &= ~(0x0F << (pos*4)); where->rega |= (font[c] & 0x0F) << (pos*4); where->regb &= ~(0x0F << (pos*4)); where->regb |= ((font[c] & 0xF0) >> 4) << (pos*4); } /* PCF2111 module GPIO init routine */ void pcf2111_gpio_init(){ rcc_periph_clock_enable(RCC_GPIOA); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO0 | GPIO1 | GPIO2 | GPIO3); } /* PCF2111 module data tx routine uint32_t data - 32 data bits uint8_t reg - A or B register uint8_t cs - CS1 or CS2 select */ void pcf2111_send(uint32_t data, uint8_t reg, uint8_t cs){ if(cs) gpio_set(LCD_PORT, LCD_CS2); else gpio_set(LCD_PORT, LCD_CS1); //1st clock with data=0 gpio_clear(LCD_PORT, LCD_DATA); gpio_set(LCD_PORT, LCD_CLK); for(int k = 0; k < 100; k++) __asm__("nop"); gpio_clear(LCD_PORT, LCD_CLK); for(int k = 0; k < 100; k++) __asm__("nop"); //32 clocks with data, clks 2-33 for(uint8_t j = 0; j < 32; j++){ gpio_set(LCD_PORT, LCD_CLK); if((data & (1 << j)) == 1<