cancel
Showing results for 
Search instead for 
Did you mean: 

OLED SSD1322 don't Work

William Warnots
Associate III
Posted on August 03, 2017 at 09:44

Hi everyone,

ì'm trying to use te OLED MCOT256064BA-WM with the SSD1322 Driver.

Is so frustrating to be in the situation that the code seems really correct at least , but the OLED don't still Work.

I need Help!

i'm using the STM32F412ZGTx, the OLED is a 256x64

The code is Here, i Think the problem is the initialization of the driver , at the Oscilloscope the SPI Communication seems ok !

Thank you very much for every incoming help!!

void Oled_setupSSD1233(void)

{

//Si esegue procedura di accensione riportata sul datasheet del SSD1322

//1) Power on STM32 e quindi VCI,VDDIO (MCU 3,3v)

HAL_GPIO_WritePin(Oled_NSS_Port, Oled_NSS_Pin, 1); // trasmissione non attiva

HAL_Delay(5); //5ms da datasheet bisogna aspettare almeno 1ms che la 3.3 V dal micro diventi stabile //2) Delay Minimum 1 ms

HAL_GPIO_WritePin(Oled_RST_Port, Oled_RST_Pin, 1); //non attivo

HAL_Delay(200);

HAL_GPIO_WritePin(Oled_RST_Port, Oled_RST_Pin, 0); // Reset SSD1322

// 3) // Display Off

//128MUX

// column and address normals , Display start line is set at display ram address 0

// Normal scan direction COm Outputs

// contrast control register set at 7Fh

HAL_Delay(50); //4) 100micros datasheet

HAL_GPIO_WritePin(Oled_RST_Port, Oled_RST_Pin, 1); // 5) Reset off

HAL_Delay(200); //50m //

HAL_GPIO_WritePin(OLED_PWR_EN_GPIO_Port, OLED_PWR_EN_Pin, 1); // 6) Power on Vcc (12V) da Switch

HAL_Delay(500); //6) wait at least 200mS and than 300, Vcc become stable

Reset_Device(); //7) inizializzazione

HAL_Delay(300);

}

void Reset_Device(void)

{

// Lots of reset/tweaking commands follow

displaySend(SEND_CMD, 0xFD); // Set Command Lock (MCU protection status) ok

displaySend(SEND_CMD, 0xAE); // Sleep On (DisplayOFF) ok,

displaySend(SEND_DAT, 0x12); // = Reset Unlocked Oled driver , se Locked accetta solo il Comando FDh

displaySend(SEND_CMD, 0xB3); // Set Front Clock Divider / Oscillator Frequency

displaySend(SEND_DAT, 0x91); // = reset / 1100b (0xD0) divide per due , selezionata frequenza che non so , boh!!!

//displaySend(SEND_DAT, 0xC0); // frequenza oscillatore a quella di reset e divisore 0, PROVARE

//displaySend(SEND_DAT, 0xD0) prova anche questo

displaySend(SEND_CMD, 0xCA); // Set MUX Ratio

displaySend(SEND_DAT, 0x3F); // = 63dec = 64MUX da 0 a 63 , numero di Righe attive (settate) che verranno eseguite in un unico frame.

displaySend(SEND_CMD, 0xA2); // Set Display Offset ok

displaySend(SEND_DAT, 0x00); // = RESET

displaySend(SEND_CMD, 0xA1); // Set Display Start Line ok

displaySend(SEND_DAT, 0x00); // = register 00h

displaySend(SEND_CMD, 0xA0); // Set Re-map and Dual COM Line mode

//displaySend2(SEND_DAT, 0x14,0x11); // = Reset except Enable Nibble Re-map, Scan from COM[N-1] to COM0, where N is the Multiplex ratio

displaySend(SEND_DAT, 0x14);

displaySend(SEND_DAT, 0x11);

displaySend(SEND_CMD, 0xB5); // Set GPIO

displaySend(SEND_DAT, 0x00); // = GPIO0, GPIO1 = HiZ alta impedenza, Input Disabled //ok, ma capire cos'è!!!

displaySend(SEND_CMD, 0xAB); // Function Selection

displaySend(SEND_DAT, 0x01); // = reset = Enable internal VDD regulator ok

displaySend(SEND_CMD, 0xB4); // Display Enhancement A

//displaySend2(SEND_DAT, 0xA0,0xFD); // = Enable external VSL (OK)

displaySend(SEND_DAT, 0xA0); // = Low GS display quality, for Normal (reset) send 0xB5 //ok

displaySend(SEND_DAT, 0xFD);

displaySend(SEND_CMD, 0xC1); // Set Contrast Current //ok, ma capire cos'è

displaySend(SEND_DAT, 0x9F); // = reset (0x7F) // 0xff

displaySend(SEND_CMD, 0xC7); // Master Contrast Current Control// ok

displaySend(SEND_DAT, 0x0F); // = no change

displaySend(SEND_CMD, 0xB9); // Select Default Linear Gray Scale table//ok

displaySend(SEND_CMD, 0xB1); // Set Phase Length //ok

displaySend(SEND_DAT, 0xE2); // = Phase 1 period (reset phase length) = 5 DCLKs, Phase 2 period (first pre- charge phase length) = 14 DCLKs

displaySend(SEND_CMD, 0xD1); // Display Enhancement B //ok

//displaySend2(SEND_DAT, 0x82,0x20); // = Normal (reset) (0xA2)

displaySend(SEND_DAT, 0x82); // n/a

displaySend(SEND_DAT, 0x20);

displaySend(SEND_CMD, 0xBB); // Set Pre-charge voltage

displaySend(SEND_DAT, 0x1F); // = 0.60 x VCC //ok

displaySend(SEND_CMD, 0xB6); // Set Second Precharge Period //ok

displaySend(SEND_DAT, 0x08); // = 8 dclks [reset]

displaySend(SEND_CMD, 0xBE); // Set VCOMH

displaySend(SEND_DAT, 0x07); // = 0.86 x VCC //ok

displaySend(SEND_CMD, 0xA6); // Set Display Mode = Normal Display //ok

displaySend(SEND_CMD, 0xA9); // Exit Partial Display //ok

Clear_RAM();

// ClearDisplay();

//displaySend(SEND_CMD, 0xA4); // spegne solo tutti i pixels dello schermo , serve una funzione clear che setti anche le dimensioni dello schermo e abiliti la RAM

displaySend(SEND_CMD, 0xAF); // Set Sleep mode OFF (Display ON) //

HAL_Delay(10); //0.01s

}

void Clear_RAM(void){

unsigned char x,y;

Set_Column_Address(0x00, 0x77); // ci sono 120 colonne comprendenti ognuna 4 SEG ( pixels) , 25674 = 64 (3Fh) (63 dec da 0 a 63)

Set_Row_Address(0x00,0x7F); // 128max, 63 dec , 0 a 63 sono 64 righe, dovrebbe essere impostata la dimensione dell'OLED 256x

Set_Write_RAM();

for(y=0;y<128;y++)

{ for(x=0;x<120;x++) // 119 cicli

{

displaySend(SEND_DAT, 0x00);

}

}

}

void displaySend(uint8_t sendType, unsigned char v)

{

displaySendStart(sendType); // controlla sendType(comando o dato) e setta CD di conseguenza , attiva sempre CS

displaySendData(v); // v trasmesso da SPI

displaySendEnd(); //Chip Select alto

}

void displaySendData(unsigned char v)

{

//SPI.transfer(v);

uint8_t aTxBuffer[] = {0x00}, aRxBuffer[] = {0x00};

aTxBuffer[0] = v;

HAL_SPI_TransmitReceive(&OLEDspi2, (uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer, 1, 250);

}

void displaySendStart(uint8_t sendType)

{

HAL_GPIO_WritePin(Oled_NSS_Port, Oled_NSS_Pin, 0); // se non funziona OLED, Spostare in fondo alla funzione

if (sendType == SEND_DAT)

{

HAL_GPIO_WritePin(Oled_CD_Port, Oled_CD_Pin, 1);

}

else if (sendType == SEND_CMD)

{

HAL_GPIO_WritePin(Oled_CD_Port, Oled_CD_Pin, 0);

}

}

void displaySendEnd(void)

{

HAL_GPIO_WritePin(Oled_NSS_Port, Oled_NSS_Pin, 1);

}

void Oled_Loop(void)

{

displaySend(SEND_CMD, 0xA5); // Entire Display ON, all pixels turns ON in GS level 15

HAL_Delay(1000);

}

#oled #stm32-f

Note: this post was migrated and contained many threaded conversations, some content may be missing.
20 REPLIES 20
Posted on August 08, 2017 at 11:22

With CMD B9 i just set the default grey scale!

Checking my code about SPI and ecc... you see substantial differences? The fact that you've used a parallel communication suggest me  that could be the SPI Protocol the wrong part.

Posted on August 08, 2017 at 17:18

Hi again..

Your second question is the answer for your problem

0690X00000607hzQAA.png

you interpret the commands as bytes.(not as words, tripletes.. and so on)

for example the second initialisation command itself is not a valid command.

each command unity (one or  more bytes with params) must be under one cs low pulse.

not send individualy.

You can't keep steady low the cs pin.

CS pin

participate

s in timing and  gives the ''trigger for transaction.

Also remember that SPI clck must not exceed 10 MHZ

Posted on August 09, 2017 at 10:02

Hi,

Thanks for your precious Support,

Maybe i understand , yesterday i've redone the program and seeing the same image that have you posted from the datasheet, so  i change Chip Select use m( my Nss Pin).

But for ''each command unity'' , what do you mean exactly?

we have Commands and datas, in the new protocol i've designed i put before low and high the chip slect ( NSS)  for the command , and another single Nss cycle for all Datas.

Example setting ReMapDualCOMLineMode(CMD  0xB3, Data1 0x14,Data2 0x11)

Nss = 0 SPI Chip Select Enabled

CD = 0 Command

send Command

Nss = 1 Nss Disabled

Nss = 0 

CD=1 Data

Send Data 1

Send Data 2

Nss=1

Below i show you the functions

void Set_ReMapDualCOMLineMode(unsigned char dat1,unsigned char dat2){

    displaySendCMD(0xB3);

    displaySendData2(dat1,dat2);

}

void displaySendCMD(unsigned char v){

SPI_START();

HAL_GPIO_WritePin(Oled_CD_Port, Oled_CD_Pin, 0);

uint8_t aTxBuffer[] = {0x00}, aRxBuffer[] = {0x00};

aTxBuffer[0] = v;

HAL_SPI_TransmitReceive(&hspi2OLED, (uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer, 1, 250);

SPI_STOP();

}

void displaySendData2(unsigned char v1,unsigned char v2){

    SPI_START();

    HAL_GPIO_WritePin(Oled_CD_Port, Oled_CD_Pin, 1);

    //SPI.transfer(v);

    uint8_t aTxBuffer[] = {0x00}, aRxBuffer[] = {0x00};

    aTxBuffer[0] = v1;

    aTxBuffer[1] = v2;

    HAL_SPI_TransmitReceive(&hspi2OLED, (uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer, 2, 250);

    SPI_STOP();

}

There is a Oscilloscope Picture taken yesterday exactly of this Command, is ok??

CLOCK ( 3,15 MHz)

     MOSI  

CHIP SELECT 

DATA/COMMAND

0690X00000602R0QAI.bmp

Is now ok the communication?? or i must do an unic NSS cycle??

Posted on August 09, 2017 at 14:52

Hello!!

First of all , lets begin with Datasheet we have and how to translate it.

Data transfer pause is never mentioned in this dartasheet. This means that we haven't any knowledge about ''What if pull CS_hi after first  byte, in a double or triple byte command? Or what if pull CS_hi in the midle of tranfering a byte?''

or ''Is it mandatory or optional to keep CS at low state between of any kind of sequential or singe writing?.''

or ''In case we omit a single clock pulse (by some reason) , is CS_HI reseting with someway the internal shift register counting circuitry to correct this anomaly, or we need a general reset?''

We dont have theese answers but we have this display working. !

By a ''logic'' way of thinking, and the only fact we have,  ( the above ''spi writing diagram'' )

IMHO must divide your data in unities  to send to chip. As unity i mean, Under contously CS_LO state,

0690X00000607Z8QAI.png

the one byte command, the two bytes command, the three bytes command, etc and any length of data bytes alone,

just to cover the worst case scennario (not the fastest ) of the above ingnorance.

I forgot to mention that BS pins must be grounded in your case.

0690X00000607eZQAQ.png

In your code you can use HAL_SPI_Transmit(), its faster than HAL_SPI_TransmitReceive();

Make some macros to have clearer code view ..

Posted on August 11, 2017 at 08:54

Hi William

I used the Midas MCOT128064H1V-GM which is 128 x 64 in a design last year and it works fine in SPI mode. I assume that its controller is either the same or similar. I have never had a chance to get into using HAL drivers and in my driver uses bit-banging instead of an SPI (though I have since got to grips with SPI, the STM32F205 that I used has issues with NSS so fully automatic SPI would not be possible on that STM32F2xx).

Anyway, looking at my code just now, I cycle CS/NSS for each single byte that I send. Sending a command sequence means a CS for every byte in the sequence.

Do you have the data sheet for the controller chip? Midas will send you this if you ask. You should also try emailing Midas with your questions.

Hope that helps

Simon Morrison

Posted on August 21, 2017 at 08:54

Hi,

Thank you so much for the help,

You don't known which driver you've used? i work with SSD1322, so i used its datasheet and also i have the Midas datasheet.

The initalization code is taken from a MIDAS example.

If the SPI works like your way for every byte, the SPI is correct from the beginning, i had changed mode hoping in an SPI bug.

For me would be great you show me here, or sending by email , the initialization code you have used and the vcc power up sequence.....

Also contact Midas asking technical support is a great idea.

Thanks for all,

William

Posted on August 21, 2017 at 10:07

Hi

I can tell you right now that the supply voltage start-up is not critical so long as you apply the reset line as recommended in the data sheet. My display did not work without a reset pulse.

I am not using anybody's driver. As I said, I am bit-banging the SPI port.

I can't send you code right now because I am debugging another product and I will need to extract the parts that you need. I would strongly suggest you send Midas your code and connection information. They do have technical support people and they did help me to resolve my issues. Some of the constants that set up the contrast etc that tech support recommended are not the same for all displays using the same controller and the ones I ended up using are different to the display's manual.

Simon

Posted on August 21, 2017 at 10:10

Also, it would be a good idea to use another piece of equipment to verify that your SPI transmission is working. For example a logic analyser or scope that has SPI decoding.

Posted on August 29, 2017 at 10:31

I don't know if we've asked this already: is the 'high voltage' OK?

JW

Posted on August 30, 2017 at 09:30

sure