#include #include #include #include #include "i2c.h" #include "ssd1306_display_driver.h" #define SSD1306_ADDR 0x3c #define SSD1306_CMD_REG 0x00 #define SSD1306_DATA_REG 0x40 //on the datasheet we have 32 extra rows (4 more pages) of GDRAM that don't fit on the display; we just ignore them everywhere #define SCREEN_PAGE_CNT SCREEN_RES_Y / 8 #define I2C_WRITE 0 #define I2C_READ 1 void screen_init() { #ifdef DEBUG_BUILD printf("initlizing SSD1306 display driver\r\n"); #endif //turn on screen while we configure shit, it might look cooler i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xaf); //don't inverse display i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xa6); //set contrast to 255 (try chainging?) i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0x81, 0xff}); //set lower nibble of column ptr to 0 i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x00); //set upper nibble of column ptr to 0 i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x10); //memory mode is paging i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0x20, 0x02}); //no vertical shift i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0xd3, 0x00}); //page address is at 0 i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xb0); //ram display start register is at 0 i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x40); //column address 0 is mapped to seg0 i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xa0); //a1 i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xc8); //set mux ratio to 32 mux i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0xa8, 0x1f}); //alternative COM hardware mapping (stolen from lib) i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0xda, 0x02}); //volage regulator on i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0x8d, 0x14}); //set clock divider to zero, and oscillator frequency as high as it goes //Maybe we save battery to run slower? i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0xd5, 0xf0}); //TODO look //deactivate scroll i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x2e); } void screen_off() { i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xaf); } void screen_on() { i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xae); } void screen_update() { for(int on_page = 0; on_page < SCREEN_PAGE_CNT; on_page++) { i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xb0 + on_page); i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x00); i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x10); i2c_write_reg_multi(SSD1306_ADDR, SSD1306_DATA_REG, sizeof(screen_buffer), screen_buffer); } } void screen_test() { printf("testing screen\n"); for(int on_pix = 0; on_pix < (SCREEN_RES_X * SCREEN_RES_Y) / 8; on_pix++) screen_buffer[on_pix] = 0b10101010; printf("done testing screen\n"); screen_update(); }