SPI initialization of NHD-0216AW-SB3
In the forum I have seen samples of bitbanging the initialization but none for standard 8 bit SPI transfer (Mode 3). I am using PIC24F to send the many SPI write commands but the display shows no signs of life after my initialization routine. Scope confirms correct CS operation and data being clocked in to SDI pin of device. Other New Haven LCDs I've used in the past document specific wait times between different operations. This product data sheet doesn't show any required wait times after each command. The clear screen command would normally require some time to process before receiving another command. Initialization code provided in data sheet shows no wait after issuing CLEAR (0x01) command. Any thoughts on how I can get PIC24F SPI transfer up and running would be appreciated.
Init routine attached.
void lcd_init(void)
{
LCD_RST_SetLow();
__delay_ms(500);
LCD_RST_SetHigh();
__delay_ms(500);
lcd_write(0x2A); //function set (extended command set)
lcd_write(0x71); //function selection A
lcd_write(0x00);
// disable internal VDD regulator (2.8V). data(0x5C) = enable regulator (5V)
__delay_ms(10);
lcd_write(0x28); //function set (fundamental command set)
lcd_write(0x08); //display off, cursor off, blink off
lcd_write(0x2A); //function set (extended command set)
lcd_write(0x79); //OLED command set enabled
lcd_write(0xD5); //set display clock divide ratio/oscillator frequency
lcd_write(0x70); //set display clock divide ratio/oscillator frequency
lcd_write(0x78); //OLED command set disabled
lcd_write(0x08); //extended function set (2-lines)
lcd_write(0x06); //COM SEG direction
lcd_write(0x72); //function selection B
lcd_write(0x00);
__delay_ms(10);
lcd_write(0x2A); //function set (extended command set)
lcd_write(0x79); //OLED command set enabled
lcd_write(0xDA); //set SEG pins hardware configuration
lcd_write(0x00); //set SEG pins hardware configuration
lcd_write(0xDC); //function selection C
lcd_write(0x00); //function selection C
lcd_write(0x81); //set contrast control
lcd_write(0x7F); //set contrast control
lcd_write(0xD9); //set phase length
lcd_write(0xF1); //set phase length
lcd_write(0xDB); //set VCOMH deselect level
lcd_write(0x40); //set VCOMH deselect level
lcd_write(0x78); //OLED command set disabled
lcd_write(0x28); //function set (fundamental command set)
lcd_write(0x01); //clear display
lcd_write(0x80); //set DDRAM address to 0x00
lcd_write(0x0C); //display ON
__delay_ms(100);
}
void lcd_write(uint8_t data)
{
LCD_CS_SetLow();
SPI1_Exchange8bit(data); // Data sent.
LCD_CS_SetHigh();
}
-
Hello m_ozzie,
The US2066 controller cannot be run from your typical standard 8-bit SPI transmission, and instead requires manual manipulating of the GPIO states within your software. Please refer to the github below for proper bit-banging implementation of SPI data transmission (Case 2). More details on serial data transfer can be found on pg. 11 of the US2066 controller specs.
Our initialization sequence is also a good indicator of whether any delays are needed between certain commands as our code has been tested and verified.
https://github.com/NewhavenDisplay/NHD_US2066/blob/master/NHD_US2066.cpp
https://support.newhavendisplay.com/hc/en-us/articles/4414485495703--US2066
Hope this is helpful!0 -
Hello Alee_S Thank you for the response. I integrated the bit bang functions (command & data) into my code but there is still no response from OLED. VDD_SEL & VDDIO are tied to 3.3V and jumper SJ1 is open. My micro's SDO pin is connected to OLED "SDI" pin. This conflicts with the wiring diagram but I believe I saw a post stating to do so.
Should I expect the back-light to come on after initialization?
What about the CS? The sample code you pointed me to doesn't address the CS. The timing diagram (fig. 5-5) provided in the US2066 spec. shows a CS transition at beginning and end of the 24 bit transfer. I've tried code with and without CS with same result. Using scope, I've verified the first 3 commands per the data stream shown in fig. 5-5
Are CS commands required?
Thank you for your help.command(0x2A);
command(0x71);
data(0x00);
void lcd_init(void)
{
LCD_RST_SetHigh();
__delay_ms(10);
command(0x2A); //function set (extended command set)
command(0x71); //function selection A
data(0x00); // disable internal VDD regulator (2.8V I/O). data(0x5C) = enable regulator (5V I/O)
command(0x28); //function set (fundamental command set)
command(0x08); //display off, cursor off, blink off
command(0x2A); //function set (extended command set)
command(0x79); //OLED command set enabled
command(0xD5); //set display clock divide ratio/oscillator frequency
command(0x70); //set display clock divide ratio/oscillator frequency
command(0x78); //OLED command set disabled
command(0x08); //extended function set (2-lines)
command(0x06); //COM SEG direction
command(0x72); //function selection B
data(0x00); //ROM CGRAM selection
command(0x2A); //function set (extended command set)
command(0x79); //OLED command set enabled
command(0xDA); //set SEG pins hardware configuration
command(0x00); //set SEG pins hardware configuration
command(0xDC); //function selection C
command(0x00); //function selection C
command(0x81); //set contrast control
command(0x7F); //set contrast control
command(0xD9); //set phase length
command(0xF1); //set phase length
command(0xDB); //set VCOMH deselect level
command(0x40); //set VCOMH deselect level
command(0x78); //OLED command set disabled
command(0x28); //function set (fundamental command set)
command(0x01); //clear display
command(0x80); //set DDRAM address to 0x00
command(0x0C); //display ON
__delay_ms(100);
}
void command(uint8_t c)
{
// LCD_CS_SetLow();
uint8_t temp,i;
temp = 0xF8;
for(i=0;i<8;i++)
{
SCLK_SetLow();
if((temp&0x80)>>7==1)
{
SDO_SetHigh();
}
else
{
SDO_SetLow();
}
temp = temp << 1;
SCLK_SetHigh();
}
for(i=0;i<4;i++)
{
SCLK_SetLow();
if((c&0x01)==1)
{
SDO_SetHigh();
}
else
{
SDO_SetLow();
}
c = c >> 1;
SCLK_SetHigh();
}
for(i=0;i<4;i++)
{
SCLK_SetLow();
SDO_SetLow();
SCLK_SetHigh();
}
for(i=0;i<4;i++)
{
SCLK_SetLow();
if((c&0x01)==1)
{
SDO_SetHigh();
}
else
{
SDO_SetLow();
}
c = c >> 1;
SCLK_SetHigh();
}
for(i=0;i<4;i++)
{
SCLK_SetLow();
SDO_SetLow();
SCLK_SetHigh();
}
// LCD_CS_SetHigh();
}
void data(uint8_t d)
{
// LCD_CS_SetLow();
uint8_t temp,i;
temp = 0xFA;
for(i=0;i<8;i++)
{
SCLK_SetLow();
if((temp&0x80)>>7==1)
{
SDO_SetHigh();
}
else
{
SDO_SetLow();
}
temp = temp << 1;
SCLK_SetHigh();
}
for(i=0;i<4;i++)
{
SCLK_SetLow();
if((d&0x01)==1)
{
SDO_SetHigh();
}
else
{
SDO_SetLow();
}
d = d >> 1;
SCLK_SetHigh();
}
for(i=0;i<4;i++)
{
SCLK_SetLow();
SDO_SetLow();
SCLK_SetHigh();
}
for(i=0;i<4;i++)
{
SCLK_SetLow();
if((d&0x01)==1)
{
SDO_SetHigh();
}
else
{
SDO_SetLow();
}
d = d >> 1;
SCLK_SetHigh();
}
for(i=0;i<4;i++)
{
SCLK_SetLow();
SDO_SetLow();
SCLK_SetHigh();
}
__delay_ms(10);
// LCD_CS_SetHigh();
}0 -
Hello m_ozzie,
OLED displays don't have backlights like LCDs, so there may not be a visual confirmation of the display being initialized properly.
If the OLED display is the only device being communicated too, the /CS pin could be tied LOW for the duration of your code.
The /CS pin must be tied low in order to enable MCU communication.
Best,0
Please sign in to leave a comment.
Comments
3 comments