This article is to put the recent task into record.
In this project, a GPIO simulated 4-line SPI is used to connect with SSD2828.
Other than the initialization code of SSD2828, HX8394F + BOE6.86 related initialization code is also added. (Note: The initialization code may vary for different panels.)
In addition, although some of the functions are named after SSD2825, they are still valid for SSD2828.
Futhermore, the LCD settings such as VS / VFP / VBP / HS / HBP / HFP and LCD resolution must be set properly in order to get a decent display result.
Finally, users should refer to the latest version of SSD2828 datasheet to better utilize the chip.
The reference codes are listed below:
void S_SPI_Init_8(void) { GPIO_InitTypeDef GPIO_InitStructure; \t RCC_APB2PeriphClockCmd(CS_Clk,ENABLE); GPIO_InitStructure.GPIO_Pin = CS_Pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(CS_Port, & amp;GPIO_InitStructure); GPIO_SetBits(CS_Port,CS_Pin); \t RCC_APB2PeriphClockCmd(SCK_Clk,ENABLE); GPIO_InitStructure.GPIO_Pin = SCK_Pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(SCK_Port, &GPIO_InitStructure); GPIO_ResetBits(SCK_Port,SCK_Pin); RCC_APB2PeriphClockCmd(SDO_Clk,ENABLE); GPIO_InitStructure.GPIO_Pin = SDO_Pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(SDO_Port, & amp;GPIO_InitStructure); RCC_APB2PeriphClockCmd(SDI_Clk,ENABLE); GPIO_InitStructure.GPIO_Pin = SDI_Pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(SDI_Port, & amp;GPIO_InitStructure); GPIO_ResetBits(SDI_Port,SDI_Pin); \t RCC_APB2PeriphClockCmd(A0_Clk,ENABLE); GPIO_InitStructure.GPIO_Pin = A0_Pin; //SDC Pin GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(A0_Port, &GPIO_InitStructure); GPIO_SetBits(A0_Port,SDI_Pin); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //Reset Pin GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, & amp;GPIO_InitStructure); SCK_RESET; SDI_RESET; SDO_RESET; } void SPI_3W_SET_Cmd(unsigned char cmd) { unsigned int kk; \t A0_RESET; //Set DC=0, for writing Command SDI_SET; SCK_RESET; \t for(kk=0;kk<8;kk + + ) { if((cmd & amp;0x80)==0x80) SDI_SET; else SDI_RESET; SCK_SET; SCK_RESET; cmd = cmd<<1; } } void SPI_3W_SET_PAs(unsigned char value) { unsigned int kk; A0_SET; //Set DC=1, for writing Data SDI_SET; SCK_RESET; \t for(kk=0;kk<8;kk + + ) { if((value & amp;0x80)==0x80) SDI_SET; else SDI_RESET; SCK_SET; SCK_RESET; value = value<<1; } } unsigned char SPI_READ_new(void) { unsigned char rdT; unsigned char reValue; unsigned int kk; \t CS_RESET; rdT=0; for(kk=0;kk<8;kk + + ) { rdT = rdT<<1; SCK_SET; if(GPIO_ReadInputDataBit(SDO_Port,SDO_Pin)) rdT |= 0x01; SCK_RESET; } \t reValue = rdT; \t CS_SET; \t return reValue; } void SPI_2825_WrCmd(unsigned char cmd) { CS_RESET; SPI_3W_SET_Cmd(cmd); CS_SET; } void W_C(unsigned char cmd) { CS_RESET; SPI_3W_SET_Cmd(cmd); CS_SET; } void SPI_WriteData(unsigned char value) { CS_RESET; SPI_3W_SET_PAs(value); CS_SET; } void W_D(unsigned char value) { CS_RESET; SPI_3W_SET_PAs(value); CS_SET; } void SPI_2825_WrReg(unsigned char c,unsigned short value) { CS_RESET; SPI_3W_SET_Cmd(c); SPI_3W_SET_PAs(value & amp;0xff); SPI_3W_SET_PAs((value>>8) & amp;0xff); CS_SET; } void GP_COMMAD_PA(unsigned short num) { SPI_2825_WrReg(0xbc, num); SPI_2825_WrCmd(0xbf); \t } void SSD2828_WritePackageSize(unsigned short num) { SPI_2825_WrReg(0xbc, num); SPI_2825_WrCmd(0xbf); \t } unsigned short S_SPI_DataRead_16(void) { unsigned short data; data=SPI_READ_new(); data=(data)|( SPI_READ_new()<<8); return data; } void SSD2828_Reset(void) { GPIO_SetBits(GPIOC, GPIO_Pin_13); delay_ms(100); GPIO_ResetBits(GPIOC,GPIO_Pin_13); delay_ms(200); GPIO_SetBits(GPIOC,GPIO_Pin_13); delay_ms(100); \t } void Delay(int dl) { int ii; \t for(ii=0;ii<dl;ii + + ); } void Init_SSD2828(void) { SSD2828_Reset(); //Set LCD Timing and Resolution - RGB Input Interface Control SPI_2825_WrReg(0xB1, ((LCD_VSPW<<8) + LCD_HSPW)); //Vertical sync and horizontal sync active period SPI_2825_WrReg(0xB2, ((LCD_VBPD<<8) + LCD_HBPD)); //Vertical and horizontal back porch period SPI_2825_WrReg(0xB3, ((LCD_VFPD<<8) + LCD_HFPD)); //Vertical and horizontal front porch period SPI_2825_WrReg(0xB4, LCD_XSIZE_TFT); //Horizontal active period SPI_2825_WrReg(0xB5, LCD_YSIZE_TFT); //Vertical active period SPI_2825_WrReg(0xB6, 0x0003); //Video mode and video pixel format \t //MIPI Lane Configuration SPI_2825_WrCmd(0xDE); SPI_WriteData(0x03); //11=4LANE 10=3LANE 01=2LANE 00=1LANE SPI_WriteData(0x00); delay_ms(10); \t //Check if register setting is done ok -> Read RGB Interface Control Register 0xB5 SPI_2825_WrReg(0xD4,0x00FA); SPI_2825_WrCmd(0xB5); SPI_2825_WrCmd(0xFA); printf("Y resolution:%d\r\ ",S_SPI_DataRead_16()); SPI_2825_WrCmd(0xB7); //B7: Configuration Register SPI_WriteData(0x42); SPI_WriteData(0x02); delay_ms(100); //PLL Configuration //PLL=(TX_CLK/MS)*NS 8228=480M 4428=240M 061E=120M 4214=240M 821E=360M 8219=300M 8225=444M 8224=432M 8220=384M SPI_2825_WrCmd(0xBA); //Fout = Fin * 0x20 / 2 = 24M * 32 /2 = 384M SPI_WriteData(0x20); SPI_WriteData(0x82); \t //VC Control Register SPI_2825_WrCmd(0xB8); SPI_WriteData(0x45); SPI_WriteData(0x00); delay_ms(10); \t //Clock Control Register - For LP clock SPI_2825_WrCmd(0xBB); // 384M / LPD / 8 = 384 / 3 / 8 = 16M SPI_WriteData(0x02); // LPD = 3 SPI_WriteData(0x00); delay_ms(10); \t //PLL Control Register SPI_2825_WrCmd(0xb9); //PLL Enable SPI_WriteData(0x01); SPI_WriteData(0x00); delay_ms(10); /// //Start initialization for HX8394 + BOE6.86 // \t GP_COMMAD_PA(4); //Set EXTC SPI_WriteData(0xB9); SPI_WriteData(0xFF); SPI_WriteData(0x83); SPI_WriteData(0x94); \t GP_COMMAD_PA(11); //Set Power SPI_WriteData(0xB1); SPI_WriteData(0x48); SPI_WriteData(0x0C); SPI_WriteData(0x6C); SPI_WriteData(0x09); SPI_WriteData(0x32); SPI_WriteData(0x24); SPI_WriteData(0x71); SPI_WriteData(0x51); SPI_WriteData(0x2F); SPI_WriteData(0x43); \t GP_COMMAD_PA(7); //Set MIPI SPI_WriteData(0xBA); SPI_WriteData(0x63); SPI_WriteData(0x03); SPI_WriteData(0x68); SPI_WriteData(0x6B); SPI_WriteData(0xB2); SPI_WriteData(0xC0); \t GP_COMMAD_PA(7); //Set Display SPI_WriteData(0xB2); SPI_WriteData(0x40); SPI_WriteData(0xA0); SPI_WriteData(0x64); SPI_WriteData(0x0E); SPI_WriteData(0x0A); SPI_WriteData(0x2F); \t GP_COMMAD_PA(22); //Set Cycles SPI_WriteData(0xB4); SPI_WriteData(0x1C); SPI_WriteData(0x78); SPI_WriteData(0x1C); SPI_WriteData(0x78); SPI_WriteData(0x1C); SPI_WriteData(0x78); SPI_WriteData(0x01); SPI_WriteData(0x0C); SPI_WriteData(0x86); SPI_WriteData(0x55); SPI_WriteData(0x00); SPI_WriteData(0x3F); SPI_WriteData(0x1C); SPI_WriteData(0x78); SPI_WriteData(0x1C); SPI_WriteData(0x78); SPI_WriteData(0x1C); SPI_WriteData(0x78); SPI_WriteData(0x01); SPI_WriteData(0x0C); SPI_WriteData(0x86); \t GP_COMMAD_PA(34); //Set GIP_0 SPI_WriteData(0xD3); SPI_WriteData(0x00); SPI_WriteData(0x00); SPI_WriteData(0x00); SPI_WriteData(0x00); SPI_WriteData(0x64); SPI_WriteData(0x07); SPI_WriteData(0x08); SPI_WriteData(0x08); SPI_WriteData(0x32); SPI_WriteData(0x10); SPI_WriteData(0x07); SPI_WriteData(0x00); SPI_WriteData(0x07); SPI_WriteData(0x32); SPI_WriteData(0x10); SPI_WriteData(0x03); SPI_WriteData(0x00); SPI_WriteData(0x03); SPI_WriteData(0x00); SPI_WriteData(0x32); SPI_WriteData(0x10); SPI_WriteData(0x08); SPI_WriteData(0x00); SPI_WriteData(0x35); SPI_WriteData(0x33); SPI_WriteData(0x09); SPI_WriteData(0x09); SPI_WriteData(0x37); SPI_WriteData(0x0D); SPI_WriteData(0x07); SPI_WriteData(0x37); SPI_WriteData(0x0E); SPI_WriteData(0x40); delay_ms(5); \t GP_COMMAD_PA(45); //Set GIP_Fmaping SPI_WriteData(0xD5); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x24); SPI_WriteData(0x24); SPI_WriteData(0x1A); SPI_WriteData(0x1A); SPI_WriteData(0x1B); SPI_WriteData(0x1B); SPI_WriteData(0x04); SPI_WriteData(0x05); SPI_WriteData(0x06); SPI_WriteData(0x07); SPI_WriteData(0x00); SPI_WriteData(0x01); SPI_WriteData(0x02); SPI_WriteData(0x03); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x19); SPI_WriteData(0x19); SPI_WriteData(0x20); SPI_WriteData(0x21); SPI_WriteData(0x22); SPI_WriteData(0x23); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); delay_ms(5); \t GP_COMMAD_PA(45); //Set GIP_Bmaping SPI_WriteData(0xD6); SPI_WriteData(0x19); SPI_WriteData(0x19); SPI_WriteData(0x24); SPI_WriteData(0x24); SPI_WriteData(0x1A); SPI_WriteData(0x1A); SPI_WriteData(0x1B); SPI_WriteData(0x1B); SPI_WriteData(0x03); SPI_WriteData(0x02); SPI_WriteData(0x01); SPI_WriteData(0x00); SPI_WriteData(0x07); SPI_WriteData(0x06); SPI_WriteData(0x05); SPI_WriteData(0x04); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x23); SPI_WriteData(0x22); SPI_WriteData(0x21); SPI_WriteData(0x20); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); SPI_WriteData(0x18); delay_ms(5); \t GP_COMMAD_PA(3); //Set Vcom SPI_WriteData(0xB6); SPI_WriteData(0x80); SPI_WriteData(0x80); \t GP_COMMAD_PA(59); //Set Gamma SPI_WriteData(0xE0); SPI_WriteData(0x00); SPI_WriteData(0x1E); SPI_WriteData(0x28); SPI_WriteData(0x2F); SPI_WriteData(0x30); SPI_WriteData(0x33); SPI_WriteData(0x37); SPI_WriteData(0x34); SPI_WriteData(0x6B); SPI_WriteData(0x7A); SPI_WriteData(0x88); SPI_WriteData(0x84); SPI_WriteData(0x8B); SPI_WriteData(0x9B); SPI_WriteData(0x9E); SPI_WriteData(0x9F); SPI_WriteData(0xAA); SPI_WriteData(0xAA); SPI_WriteData(0xA4); SPI_WriteData(0xB1); SPI_WriteData(0xC0); SPI_WriteData(0x5F); SPI_WriteData(0x5D); SPI_WriteData(0x61); SPI_WriteData(0x65); SPI_WriteData(0x68); SPI_WriteData(0x70); SPI_WriteData(0x7E); SPI_WriteData(0x7F); SPI_WriteData(0x00); SPI_WriteData(0x1E); SPI_WriteData(0x28); SPI_WriteData(0x2F); SPI_WriteData(0x30); SPI_WriteData(0x33); SPI_WriteData(0x37); SPI_WriteData(0x34); SPI_WriteData(0x6B); SPI_WriteData(0x7A); SPI_WriteData(0x88); SPI_WriteData(0x84); SPI_WriteData(0x8B); SPI_WriteData(0x9B); SPI_WriteData(0x9E); SPI_WriteData(0x9F); SPI_WriteData(0xAA); SPI_WriteData(0xAA); SPI_WriteData(0xA4); SPI_WriteData(0xB1); SPI_WriteData(0xC0); SPI_WriteData(0x5F); SPI_WriteData(0x5D); SPI_WriteData(0x61); SPI_WriteData(0x65); SPI_WriteData(0x68); SPI_WriteData(0x70); SPI_WriteData(0x7E); SPI_WriteData(0x7F); delay_ms(5); \t GP_COMMAD_PA(2); SPI_WriteData(0xCC); //Set Panel SPI_WriteData(0x03); \t GP_COMMAD_PA(3); //Set C0 SPI_WriteData(0xC0); SPI_WriteData(0x1F); SPI_WriteData(0x31); GP_COMMAD_PA(2); SPI_WriteData(0xD4); //Set D4 SPI_WriteData(0x02); \t GP_COMMAD_PA(2); SPI_WriteData(0xBD); //Set Bank SPI_WriteData(0x01); \t GP_COMMAD_PA(1); SPI_WriteData(0xB1); //Set Power1 \t GP_COMMAD_PA(2); SPI_WriteData(0xBD); //Set Bank SPI_WriteData(0x00); \t GP_COMMAD_PA(2); SPI_WriteData(0xC6); //Set C6 SPI_WriteData(0xED); \t GP_COMMAD_PA(1); //Sleep Out SPI_WriteData(0x11); delay_ms(120); \t GP_COMMAD_PA(1); SPI_WriteData(0x29); //Display ON delay_ms(10); /// //End of HX8394 + BOE6.86 Initialization // \t SPI_2825_WrCmd(0xC9); //p1: HS-Data-zero p2: HS-Data-prepare SPI_WriteData(0x02); SPI_WriteData(0x14); delay_ms(100); \t SPI_2825_WrCmd(0xCA); SPI_WriteData(0x03); //Clk Prepare SPI_WriteData(0x28); //Clk Zero SPI_2825_WrCmd(0xCB); //local_write_reg(addr=0xCB,data=0x0510) SPI_WriteData(0x16); //Clk Post SPI_WriteData(0x04); //Clk Per SPI_2825_WrCmd(0xD6); //05=BGR 04=RGB SPI_WriteData(0x04); //D0=0=RGB 1:BGR D1=1=Most significant byte sent first SPI_WriteData(0x00); \t SPI_2825_WrCmd(0xB7); //B7: Configuration Register SPI_WriteData(0x4B); SPI_WriteData(0x02); delay_ms(100); \t SPI_2825_WrCmd(0x2C); printf("Initialization Done\r\ "); } void SSD2828_ID(void) { unsigned short id = 0; SSD2828_Reset(); SPI_2825_WrReg(0xD4,0x00FA); SPI_2825_WrCmd(0xB0); SPI_2825_WrCmd(0xFA); id = S_SPI_DataRead_16(); printf("Device ID :0x%x\r\ ",id); \t }