void display_8x0C_lcd_init() {
// next step is needed to have PB3 and PB4 working as GPIO
/* Disable the Serial Wire Jtag Debug Port SWJ-DP */
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = LCD_READ__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_READ__PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_RESET__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_RESET__PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_COMMAND_DATA__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_COMMAND_DATA__PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_CHIP_SELECT__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_CHIP_SELECT__PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LCD_WRITE__PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_WRITE__PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = 0xffff;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_BUS__PORT, &GPIO_InitStructure);
// disable reset
GPIO_SetBits(LCD_RESET__PORT, LCD_RESET__PIN);
// default to write mode
GPIO_SetBits(LCD_READ__PORT, LCD_READ__PIN);
// keep chip select active
GPIO_ResetBits(LCD_CHIP_SELECT__PORT, LCD_CHIP_SELECT__PIN);
lcd_IC_t type = LCD_ST7796;
delay_ms(120);
lcd_write_command(0x11);
delay_ms(120);
lcd_write_command(0x36);
lcd_write_data_8bits(0x48);
lcd_write_command(0x3A);
lcd_write_data_8bits(0x55);
lcd_write_command(0xF0);
lcd_write_data_8bits(0xC3);
lcd_write_command(0xF0);
lcd_write_data_8bits(0x96);
lcd_write_command(0xB4);
lcd_write_data_8bits(0x01);
lcd_write_command(0xB7);
lcd_write_data_8bits(0xC6);
lcd_write_command(0xC0);
lcd_write_data_8bits(0xF0);
lcd_write_data_8bits(0x35);
lcd_write_command(0xC1);
lcd_write_data_8bits(0x15);
lcd_write_command(0xC2);
lcd_write_data_8bits(0xAF);
lcd_write_command(0xC3);
lcd_write_data_8bits(0x09);
lcd_write_command(0xC5); //VCOM
lcd_write_data_8bits(0x06);
lcd_write_command(0xC6);
lcd_write_data_8bits(0x00);
lcd_write_command(0xE8);
lcd_write_data_8bits(0x40);
lcd_write_data_8bits(0x8A);
lcd_write_data_8bits(0x00);
lcd_write_data_8bits(0x00);
lcd_write_data_8bits(0x29);
lcd_write_data_8bits(0x19);
lcd_write_data_8bits(0xA5);
lcd_write_data_8bits(0x33);
lcd_write_command(0xE0);
lcd_write_data_8bits(0x70);
lcd_write_data_8bits(0x00);
lcd_write_data_8bits(0x05);
lcd_write_data_8bits(0x03);
lcd_write_data_8bits(0x02);
lcd_write_data_8bits(0x20);
lcd_write_data_8bits(0x29);
lcd_write_data_8bits(0x01);
lcd_write_data_8bits(0x45);
lcd_write_data_8bits(0x30);
lcd_write_data_8bits(0x09);
lcd_write_data_8bits(0x07);
lcd_write_data_8bits(0x22);
lcd_write_data_8bits(0x29);
lcd_write_command(0xE1);
lcd_write_data_8bits(0x70);
lcd_write_data_8bits(0x0C);
lcd_write_data_8bits(0x10);
lcd_write_data_8bits(0x0F);
lcd_write_data_8bits(0x0E);
lcd_write_data_8bits(0x09);
lcd_write_data_8bits(0x35);
lcd_write_data_8bits(0x64);
lcd_write_data_8bits(0x48);
lcd_write_data_8bits(0x3A);
lcd_write_data_8bits(0x14);
lcd_write_data_8bits(0x13);
lcd_write_data_8bits(0x2E);
lcd_write_data_8bits(0x30);
// lcd_write_command(0x21);
lcd_write_command(0xF0);
lcd_write_data_8bits(0xC3);
lcd_write_command(0xF0);
lcd_write_data_8bits(0x96);
delay_ms(120);
lcd_write_command(0x29);
delay_ms(25);
// End of display configuration
// @geeksville board reads back as 0x2, 0x4, 0x94, 0x81, 0xff - a legit ili9481
write_pulse_duration = 0; // enable fast writes
// Note: if we have some devices still not working, we might need to add a READ command to 0xbf (8.2.39) to read
// the chip id of the failing units - this would allow us to see the vendor code of whoever made the display and
// confirm it is a 9481 (or if different - what it is)
// It is worth noting that the display controller has a small amount of non volatile memory. I bet the mfg of the
// 850C is checking that code in their firmware, and based on that value chosing to flip the display horizontally
// if needed (via command 0x36)
// Initialize global structure and set PSET to this.PSET.
UG_Init(&gui, lcd_pixel_set, DISPLAY_WIDTH, DISPLAY_HEIGHT);
// Register acceleratos.
UG_DriverRegister(DRIVER_FILL_FRAME, (void*) HW_FillFrame);
UG_DriverRegister(DRIVER_DRAW_LINE, (void*) HW_DrawLine);
UG_DriverRegister(DRIVER_FILL_AREA, (void*) HW_FillArea);
//UG_DriverEnable ( DRIVER_FILL_FRAME ) ;
// UG_DriverEnable ( DRIVER_DRAW_LINE ) ;
// UG_DriverEnable ( DRIVER_FILL_AREA ) ;
}