SSD2828 Setup – For HX8394F + BOE6.86 MIPI Display

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
}