#include "SSD1306.h" #include "driver/i2c.h" #include "portmacro.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" static char I2C_addr = 0; static int I2CHandle = NULL; static uint8_t SSD1306FrameBuffer[SSD1306BUFFERSIZE]; static uint8_t SSD1306CursorX = 0; static uint8_t SSD1306CursorY = 0; static uint8_t SSD1306OffsetX = 0; static uint8_t SSD1306OffsetY = 0; static uint8_t SSD1306Width = SSD1306_WIDTH; static uint8_t SSD1306Height = SSD1306_HEIGHT; static uint8_t SSD1306Changed = 0; void SSD1306_Init(int i2c_master_port, char address) { I2CHandle = i2c_master_port; I2C_addr = address; if(!I2CHandle) return; SSD1306_Reset(); vTaskDelay(100/portTICK_PERIOD_MS); //init display SSD1306_SetDisplayOn(0); SSD1306_WriteCMD(0x20); //Set Mem Addressing SSD1306_WriteCMD(0x00); SSD1306_WriteCMD(0xB0);//Set Page start SSD1306_WriteCMD(0xC0); //Set COM Output Scan Direction SSD1306_WriteCMD(0x00); //---set low column address SSD1306_WriteCMD(0x10); //---set high column address SSD1306_WriteCMD(0x40); //--set start line address - CHECK SSD1306_SetContrast(0xFF); SSD1306_WriteCMD(0xA1); //--set segment re-map 0 to 127 - CHECK SSD1306_WriteCMD(0xA6); //--set normal color // Set multiplex ratio. SSD1306_WriteCMD(0xA8); SSD1306_WriteCMD(0x1F); // Seems to work for 128px high displays too. SSD1306_WriteCMD(0xA4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content SSD1306_WriteCMD(0xD3); //-set display offset - CHECK SSD1306_WriteCMD(0x00); //-not offset SSD1306_WriteCMD(0xD5); //--set display clock divide ratio/oscillator frequency SSD1306_WriteCMD(0xF0); //--set divide ratio SSD1306_WriteCMD(0xD9); //--set pre-charge period SSD1306_WriteCMD(0x22); // SSD1306_WriteCMD(0xDA); //--set com pins hardware configuration - CHECK SSD1306_WriteCMD(0x02); SSD1306_WriteCMD(0xDB); //--set vcomh SSD1306_WriteCMD(0x20); //0x20,0.77xVcc SSD1306_WriteCMD(0x8D); //--set DC-DC enable SSD1306_WriteCMD(0x14); // SSD1306_SetDisplayOn(1); //--turn on SSD1306 panel //Set buffer to 0; for(uint16_t i =0; i < SSD1306BUFFERSIZE; i++) SSD1306FrameBuffer[i] = 0; } void SSD1306_UpdateScreen() { if(!I2CHandle) return; if(!SSD1306Changed) return; SSD1306Changed = 0; for(uint8_t i = 0; i < SSD1306_HEIGHT/8; i++) { SSD1306_WriteCMD(0xB0 + i); // Set the current RAM page address. SSD1306_WriteCMD(0x00); SSD1306_WriteCMD(0x10); SSD1306_WriteData(&SSD1306FrameBuffer[SSD1306_WIDTH*i],SSD1306_WIDTH); } } void SSD1306_WriteCMD(unsigned char cmd) { if(!I2CHandle) return; i2c_master_write_to_device(I2CHandle,I2C_addr,&cmd,1,100/portTICK_PERIOD_MS); } void SSD1306_WriteData(unsigned char *data,unsigned char len) { if(!I2CHandle) return; i2c_master_write_to_device(I2CHandle,I2C_addr,data,len,100/portTICK_PERIOD_MS); } void SSD1306_WriteChar(char c) { if(!I2CHandle) return; //First check if we have enough space to draw the character //Font size is 8x8 //first we check width //The display is rotated 90* so we this is weird... if((SSD1306CursorX+1)*8 > SSD1306Height-SSD1306OffsetX) { //We do not fit so jump to the next line and set cursor back to 0 SSD1306CursorY ++; SSD1306CursorX = SSD1306OffsetX; } //if we do not fit at the bottom jump to top if((SSD1306CursorY+1)+8 > SSD1306Width-SSD1306OffsetY) { SSD1306CursorX = SSD1306OffsetX; SSD1306CursorY = SSD1306OffsetY; } uint16_t offset = (SSD1306CursorY*8)+(SSD1306CursorX*128); for(uint16_t i =0 ; i < 8;i++) { SSD1306FrameBuffer[i+offset] = Font6x8[(c-32)*8+i]; } SSD1306CursorX++; SSD1306Changed =1; } void SSD1306_WriteString(char *c, char len) { if(!I2CHandle) return; uint8_t i =0; for(i=0;i