/CS n'est plus force a LOW avant l'impulsion de reset (seul oled_command/ oled_data le pilotent par octet, comme dans le firmware MSP430 de reference qui fonctionnait). Vitesse SPI ramenee a 400kHz et delais de reset alonges a 100ms pour fiabiliser la liaison sur cable ruban IDC. Ajoute aussi l'ancienne lib MSP430 (doc/librairies/) qui a servi de reference pour comparer la sequence d'init SSD1322 octet par octet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01StKu9rqrsdz8CAVt1XMxon
226 lines
5.1 KiB
C
226 lines
5.1 KiB
C
/***************************************************
|
|
//Web: http://www.buydisplay.com
|
|
EastRising Technology Co.,LTD
|
|
****************************************************/
|
|
|
|
//#include "erM032_oled.h"
|
|
|
|
#define HIGH 1 //
|
|
#define LOW 0 //
|
|
|
|
#define OLED_Control P2OUT
|
|
|
|
#define OLED_CS BIT2 // P2.2 chip select
|
|
#define OLED_DC BIT0 // P2.0 Data Command High = Data, Low = Command
|
|
#define OLED_RST BIT1 // P2.0 Data command
|
|
|
|
void send_spi_byte(uint8_t byte)
|
|
{
|
|
// Envoi des données
|
|
UCB0TXBUF = byte;
|
|
|
|
// Attente de la fin de la transmission
|
|
// while (!(UCB0IFG & UCTXIFG));
|
|
while (!(IFG2 & UCB0TXIFG)); // USCI_B0 TX buffer ready?
|
|
// __delay_cycles(35); // 2 MHz
|
|
__delay_cycles(100);
|
|
}
|
|
|
|
void digitalWrite(uint16_t sortie, uint8_t etat)
|
|
{
|
|
if (etat)
|
|
{
|
|
OLED_Control |= sortie;
|
|
}
|
|
else
|
|
{
|
|
OLED_Control &= ~sortie;
|
|
}
|
|
|
|
}
|
|
|
|
void command(uint8_t cmd)
|
|
{
|
|
digitalWrite(OLED_DC, LOW);
|
|
digitalWrite(OLED_CS, LOW);
|
|
send_spi_byte(cmd);
|
|
digitalWrite(OLED_CS, HIGH);
|
|
}
|
|
|
|
void data(uint8_t dat)
|
|
{
|
|
digitalWrite(OLED_DC, HIGH);
|
|
digitalWrite(OLED_CS, LOW );
|
|
send_spi_byte(dat);
|
|
digitalWrite(OLED_CS, HIGH);
|
|
}
|
|
|
|
|
|
void er_oled_begin()
|
|
{ uint16_t k;
|
|
|
|
// digitalWrite(OLED_CS, LOW);
|
|
digitalWrite(OLED_RST, HIGH);
|
|
// delay(10);
|
|
for (k=20; k>0;k--)
|
|
{
|
|
__delay_cycles(100000);
|
|
}
|
|
digitalWrite(OLED_RST, LOW);
|
|
// delay(10);
|
|
for (k=20; k>0;k--)
|
|
{
|
|
__delay_cycles(100000);
|
|
}
|
|
digitalWrite(OLED_RST, HIGH);
|
|
|
|
|
|
command(0xFD); /*SET COMMAND LOCK*/
|
|
data(0x12); /* UNLOCK */
|
|
command(0xAE); /*DISPLAY OFF*/
|
|
command(0xB3);/*DISPLAYDIVIDE CLOCKRADIO/OSCILLATAR FREQUANCY*/
|
|
data(0x91); command(0xCA); /*multiplex ratio*/
|
|
data(0x3F); /*duty = 1/64*/
|
|
command(0xA2); /*set offset*/
|
|
data(0x00);
|
|
command(0xA1); /*start line*/
|
|
data(0x00);
|
|
command(0xA0); /*set remap*/
|
|
data(0x14);
|
|
data(0x11);
|
|
|
|
command(0xAB); /*funtion selection*/
|
|
data(0x01); /* selection external vdd */
|
|
command(0xB4); /* */
|
|
data(0xA0);
|
|
data(0xfd);
|
|
command(0xC1); /*set contrast current */
|
|
data(0x80);
|
|
command(0xC7); /*master contrast current control*/
|
|
data(0x0f);
|
|
|
|
command(0xB1); /*SET PHASE LENGTH*/
|
|
data(0xE2);
|
|
command(0xD1); /**/
|
|
data(0x82);
|
|
data(0x20);
|
|
command(0xBB); /*SET PRE-CHANGE VOLTAGE*/
|
|
data(0x1F);
|
|
command(0xB6); /*SET SECOND PRE-CHARGE PERIOD*/
|
|
data(0x08);
|
|
command(0xBE); /* SET VCOMH */
|
|
data(0x07);
|
|
command(0xA6); /*normal display*/
|
|
command(0xAF); /*display ON*/
|
|
}
|
|
|
|
void er_oled_SetWindow(uint8_t Xstart, uint8_t Ystart, uint8_t Xend, uint8_t Yend)
|
|
{
|
|
command(0x15);
|
|
data(Xstart+0x1c);
|
|
data(Xend+0x1c);
|
|
command(0x75);
|
|
data(Ystart);
|
|
data(Yend);
|
|
command(0x5c);//write ram command
|
|
}
|
|
|
|
void er_oled_clear()
|
|
{int i,row;
|
|
command(0x15);
|
|
data(0x00); //col start
|
|
data(0x77); //col end
|
|
command(0x75);
|
|
data(0x00); //row start
|
|
data(0x7f); //row end
|
|
command(0x5c);
|
|
for (row = 0; row < 128; row++) {
|
|
for(i = 0; i< 240; i++ ) {
|
|
data(0x00);// write data
|
|
}
|
|
}
|
|
}
|
|
|
|
void er_oled_char(uint8_t x, uint8_t y, const char *acsii, uint8_t mode) // void er_oled_char(uint8_t x, uint8_t y, const char *acsii, uint8_t mode)
|
|
{ uint8_t i,str;uint16_t OffSet;
|
|
x=x/4;
|
|
OffSet = (*acsii - 32)*16;
|
|
er_oled_SetWindow(x, y, x+1, y+15);
|
|
for (i=0;i<16;i++)
|
|
{
|
|
str =(AsciiLib[OffSet + i]); //Buydisplay
|
|
// str =(FontLib[OffSet + i]); //FontLib
|
|
if(mode) str=~str;
|
|
Data_processing (str);
|
|
}
|
|
}
|
|
|
|
|
|
void er_oled_string(uint8_t x, uint8_t y, const char *pString, uint8_t Mode)
|
|
{
|
|
while(1)
|
|
{
|
|
if (*pString == 0)
|
|
{
|
|
return;
|
|
}
|
|
er_oled_char(x, y, pString,Mode);
|
|
x += 8;
|
|
pString += 1;
|
|
}
|
|
}
|
|
|
|
|
|
void Data_processing(uint8_t temp) //turns 1byte B/W data to 4 bye gray data with 8 Pixel
|
|
{uint8_t temp1,temp2;
|
|
|
|
if(temp&0x80)temp1=0xf0;
|
|
else temp1=0x00;
|
|
if(temp&0x40)temp2=0x0f;
|
|
else temp2=0x00;
|
|
temp1=temp1|temp2;
|
|
data(temp1); //Pixel1,Pixel2
|
|
if(temp&0x20)temp1=0xf0;
|
|
else temp1=0x00;
|
|
if(temp&0x10)temp2=0x0f;
|
|
else temp2=0x00;
|
|
temp1=temp1|temp2;
|
|
data(temp1); //Pixel3,Pixel4
|
|
if(temp&0x08)temp1=0xf0;
|
|
else temp1=0x00;
|
|
if(temp&0x04)temp2=0x0f;
|
|
else temp2=0x00;
|
|
temp1=temp1|temp2;
|
|
data(temp1); //Pixel5,Pixel6
|
|
if(temp&0x02)temp1=0xf0;
|
|
else temp1=0x00;
|
|
if(temp&0x01)temp2=0x0f;
|
|
else temp2=0x00;
|
|
temp1=temp1|temp2;
|
|
data(temp1); //Pixel7,Pixel8
|
|
}
|
|
|
|
void er_oled_bitmap_mono(const uint8_t *pBuf)
|
|
{ uint8_t row,col,dat;
|
|
er_oled_SetWindow(0, 0, 255/4, 63);
|
|
for (row = 0; row < 64; row++) {
|
|
for(col = 0;col<256/8; col++ ) {
|
|
dat=(*pBuf);
|
|
pBuf++;
|
|
Data_processing(dat);
|
|
}
|
|
}
|
|
}
|
|
|
|
void er_oled_bitmap_gray(const uint8_t * pBuf)
|
|
{ uint8_t row,col;
|
|
er_oled_SetWindow(0, 0, 255/4, 63);
|
|
for (row = 0; row < 64; row++) {
|
|
for(col = 0;col<128; col++ ) {
|
|
data(*pBuf);
|
|
pBuf++;
|
|
}
|
|
}
|
|
}
|
|
|