/********************************************************************* SSD1306 I2C Library for Raspberry Pi. Based on Adafruit SSD1306 Arduino library. Some functions came from Adafruit GFX lib Modified by Ilia Penev Tested on Raspberry Pi 2 with 0.96 Yellow/Blue OLED *********************************************************************/ /********************************************************************* This is a library for our Monochrome OLEDs based on SSD1306 drivers Pick one up today in the adafruit shop! ------> http://www.adafruit.com/category/63_98 These displays use SPI to communicate, 4 or 5 pins are required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, check license.txt for more information All text above, and the splash screen below must be included in any redistribution *********************************************************************/ #include #include #include "ssd1306_i2c.h" #include "oled_fonts.h" #include "lcd_oled.h" #define true 1 #define false 0 #define rotation 0 int8_t cursor_y = 0; int8_t cursor_x = 0; int16_t i2cd; #define ssd1306_swap(a, b) { int16_t t = a; a = b; b = t; } //Section : 10.1.12 Set Display ON/OFF (AEh/AFh) | Page 37 void ssd1306_i2c_set_display_off(i2c_t *i2c_dev) { ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYOFF); } //Section : 10.1.12 Set Display ON/OFF (AEh/AFh) | Page 37 void ssd1306_i2c_set_display_on(i2c_t *i2c_dev) { ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYON); } // TODO: Find a ferq Calculator // Section : 10.1.16 Set Display Clock Divide Ratio/ Oscillator Frequency (D5h) | Page : 40 void ssd1306_i2c_set_display_clkDiv_oscFreq(i2c_t *i2c_dev, uint8_t clockDivider, uint8_t oscillatorFreq) { uint8_t value = 0; if(oscillatorFreq <= 15) { if(clockDivider <= 16) { value = (oscillatorFreq << 4) | clockDivider; } } ssd1306_i2c_send_command(i2c_dev,SSD1306_SETDISPLAYCLOCKDIV); // 0xD5 ssd1306_i2c_send_command(i2c_dev,value); // the suggested ratio 0x80 } // Section : 10.1.11 Set Multiplex Ratio (A8h) | Page : 37 void ssd1306_i2c_set_multiplex_ratio(i2c_t *i2c_dev, uint8_t ratio) { ssd1306_i2c_send_command(i2c_dev,SSD1306_SETMULTIPLEX); // 0xA8 ssd1306_i2c_send_command(i2c_dev,ratio); } // Section : 10.1.15 Set Display Offset (D3h) | Page : 37 void ssd1306_i2c_set_display_offset(i2c_t *i2c_dev, uint8_t offset) { ssd1306_i2c_send_command(i2c_dev,SSD1306_SETDISPLAYOFFSET); // 0xD3 ssd1306_i2c_send_command(i2c_dev,offset); } // Section : 10.1.13 Set Page Start Address for Page Addressing Mode (B0h~B7h) | Page : 37 void ssd1306_i2c_set_display_start_line(i2c_t *i2c_dev, uint8_t start) { if(start <= 7) { ssd1306_i2c_send_command(i2c_dev,SSD1306_SETSTARTLINE | start); } } // TODO : Some things are not clear What does 0x10 do ? // Section : 2.1 Command Table for Charge Bump Setting | Page : 60 void ssd1306_i2c_set_chage_pump(i2c_t *i2c_dev, uint8_t voltageSource) { ssd1306_i2c_send_command(i2c_dev,SSD1306_CHARGEPUMP); // 0x8D if (voltageSource == SSD1306_EXTERNALVCC) { ssd1306_i2c_send_command(i2c_dev,0x10); } else { ssd1306_i2c_send_command(i2c_dev,SSD1306_ENABLE_CHAGE_PUMP); } } // Section :10.1.3 Set Memory Addressing Mode (20h) | Page : 34 void ssd1306_i2c_set_memory_addressing_mode(i2c_t *i2c_dev, uint8_t mode) { ssd1306_i2c_send_command(i2c_dev,SSD1306_MEMORYMODE); ssd1306_i2c_send_command(i2c_dev,mode); } // TODO : Not very clear what this functionality does :S // Section : 10.1.8 Set Segment Re-map (A0h/A1h) void ssd1306_i2c_set_segment_remap(i2c_t *i2c_dev, uint8_t enable) { if(enable) { ssd1306_i2c_send_command(i2c_dev,SSD1306_SEGREMAP | 0x1); } else { ssd1306_i2c_send_command(i2c_dev,SSD1306_SEGREMAP | 0x0); } } // Section : 10.1.14 Set COM Output Scan Direction (C0h/C8h) | Page 37 void ssd1306_i2c_set_com_scan_direction(i2c_t *i2c_dev, uint8_t incremental) { if(incremental) { ssd1306_i2c_send_command(i2c_dev,SSD1306_COMSCANINC); } else { ssd1306_i2c_send_command(i2c_dev,SSD1306_COMSCANDEC); } } // Section : 10.1.18 Set COM Pins Hardware Configuration (DAh) | Page : 40 void ssd1306_i2c_set_com_pins(i2c_t *i2c_dev, uint8_t alignment) { ssd1306_i2c_send_command(i2c_dev,SSD1306_SETCOMPINS); ssd1306_i2c_send_command(i2c_dev,alignment); } void ssd1306_i2c_set_contrast(i2c_t *i2c_dev, uint8_t contrast) { ssd1306_i2c_send_command(i2c_dev,SSD1306_SETCONTRAST); // 0x81 ssd1306_i2c_send_command(i2c_dev,contrast); } void ssd1306_i2c_set_prechage_period(i2c_t *i2c_dev, uint8_t period) { ssd1306_i2c_send_command(i2c_dev,SSD1306_SETPRECHARGE); // 0xd9 ssd1306_i2c_send_command(i2c_dev,period); } void ssd1306_i2c_set_com_deselect_level(i2c_t *i2c_dev, uint8_t voltageLevel) { ssd1306_i2c_send_command(i2c_dev,SSD1306_SETVCOMDETECT); // 0xDB ssd1306_i2c_send_command(i2c_dev,voltageLevel); } void ssd1306_i2c_set_display_entire_on(i2c_t *i2c_dev, uint8_t resumeOrForce) { if(resumeOrForce == SSD1306_DISPLAYALLON_RESUME) { ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYALLON_RESUME); // 0xA4 } else { ssd1306_i2c_send_command(i2c_dev,SSD1306_DISPLAYALLON); // 0xA4 } } void ssd1306_i2c_set_display_invert_pixel(i2c_t *i2c_dev, uint8_t inverted) { if(inverted) { ssd1306_i2c_send_command(i2c_dev,SSD1306_INVERTDISPLAY); // 0xA6 } else { ssd1306_i2c_send_command(i2c_dev,SSD1306_NORMALDISPLAY); // 0xA6 } } void ssd1306_i2c_set_scroll(i2c_t *i2c_dev, uint8_t onOff) { if(onOff) { ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL); } else { ssd1306_i2c_send_command(i2c_dev,SSD1306_DEACTIVATE_SCROLL); } } void ssd1306_i2c_send_command(i2c_t *i2c_dev,uint8_t c) { // I2C uint8_t control = 0x00; // Co = 0, D/C = 0 uint8_t i2cDataLenght = 1; // Co = 0, D/C = 0 uint16_t address = SSD1306_I2C_ADDRESS; // Co = 0, D/C = 0 i2c_write(i2c_dev, &address, &control, &c, &i2cDataLenght); } // startscrollright // Activate a right handed scroll for rows start through stop // Hint, the display is 16 rows tall. To scroll the whole display, run: // ssd1306_scrollright(0x00, 0x0F) void ssd1306_startscrollright(i2c_t *i2c_dev, uint16_t start, uint16_t stop) { ssd1306_i2c_send_command(i2c_dev,SSD1306_RIGHT_HORIZONTAL_SCROLL); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,start); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,stop); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,0XFF); ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL); } // startscrollleft // Activate a right handed scroll for rows start through stop // Hint, the display is 16 rows tall. To scroll the whole display, run: // ssd1306_scrollright(0x00, 0x0F) void ssd1306_startscrollleft(i2c_t *i2c_dev,uint16_t start, uint16_t stop) { ssd1306_i2c_send_command(i2c_dev,SSD1306_LEFT_HORIZONTAL_SCROLL); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,start); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,stop); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,0XFF); ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL); } // startscrolldiagright // Activate a diagonal scroll for rows start through stop // Hint, the display is 16 rows tall. To scroll the whole display, run: // ssd1306_scrollright(0x00, 0x0F) void ssd1306_startscrolldiagright(i2c_t *i2c_dev, uint16_t start, uint16_t stop) { ssd1306_i2c_send_command(i2c_dev,SSD1306_SET_VERTICAL_SCROLL_AREA); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,SSD1306_LCDHEIGHT); ssd1306_i2c_send_command(i2c_dev,SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,start); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,stop); ssd1306_i2c_send_command(i2c_dev,0X01); ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL); } // startscrolldiagleft // Activate a diagonal scroll for rows start through stop // Hint, the display is 16 rows tall. To scroll the whole display, run: // ssd1306_scrollright(0x00, 0x0F) void ssd1306_startscrolldiagleft(i2c_t *i2c_dev, uint16_t start, uint16_t stop) { ssd1306_i2c_send_command(i2c_dev,SSD1306_SET_VERTICAL_SCROLL_AREA); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,SSD1306_LCDHEIGHT); ssd1306_i2c_send_command(i2c_dev,SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,start); ssd1306_i2c_send_command(i2c_dev,0X00); ssd1306_i2c_send_command(i2c_dev,stop); ssd1306_i2c_send_command(i2c_dev,0X01); ssd1306_i2c_send_command(i2c_dev,SSD1306_ACTIVATE_SCROLL); }