/* Motenpoche * * (c) 2023 Daniele Lacamera * * * Motenpoche is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Motenpoche is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA * */ #include #include #include "display.h" #include "hardware/i2c.h" #include "bsp/board.h" #define DISPLAY_I2C_ADDR 0x3C static uint8_t contrast = 0xcf; static i2c_inst_t *i2c_inst = NULL; static void display_send_data(const uint8_t *buf, int len) { const uint8_t start_data = 0x40; int i; uint8_t data_buf[200]; data_buf[0] = 0x40; if (len > 199) len = 199; memcpy(data_buf + 1, buf, len); if (!i2c_inst) return; i2c_write_blocking(i2c_inst, DISPLAY_I2C_ADDR, data_buf, len+1, 0); } static void display_send_cmd(uint8_t cmd) { uint8_t buf[2] = {0x00, cmd}; if (!i2c_inst) return; i2c_write_blocking(i2c_inst, DISPLAY_I2C_ADDR, buf, 2, 0); } static void display_send_cmd1(uint8_t cmd, uint8_t arg1) { uint8_t buf[3] = {0x00, cmd, arg1}; if (!i2c_inst) return; i2c_write_blocking(i2c_inst, DISPLAY_I2C_ADDR, buf, 3, 0); } static void display_send_cmd2(uint8_t cmd, uint8_t arg1, uint8_t arg2) { uint8_t buf[4] = {0x00, cmd, arg1, arg2}; if (!i2c_inst) return; i2c_write_blocking(i2c_inst, DISPLAY_I2C_ADDR, buf, 4, 0); } void display_scroll(uint8_t line) { display_send_cmd1(SSD1306_SETSTARTLINE, (line % 0x40) + 0x40); } void display_setcontrast(uint8_t c) { contrast = c; display_send_cmd1(SSD1306_SETCONTRAST, contrast); } uint8_t display_getcontrast(void) { return contrast; } void display_clear(void) { int i,j; uint8_t zeros[8] = {0, 0, 0, 0, 0, 0, 0, 0 }; display_send_cmd(0x00); display_send_cmd(0x10); for (i = 0; i < 8; i++) { display_send_cmd2(SSD1306_PAGEADDR, i, 0xFF); for (j = 0; j < WIDTH; j++) display_send_data(zeros, 8); } } void display_text(int row, const char *text) { int k; display_send_cmd(0x00); display_send_cmd(0x10); display_send_cmd2(SSD1306_PAGEADDR, 7 - row, 0xFF); for(k = 0; k < strlen(text); k++) display_send_data(fb_font[text[k]], 8); } void display_text_inverse(int row, int col, const char *text) { int k, j; uint8_t inv_buf[8]; uint8_t ones[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; int len = strlen(text); if (len > 15) len = 15; display_send_cmd(0x00); display_send_cmd(0x10); sleep_us(1000); display_send_cmd2(SSD1306_PAGEADDR, 7 - row, 0x00); display_send_cmd2(SSD1306_COLUMNADDR, col << 3, WIDTH - 1); for(k = 0; k < len; k++) { for (j = 0; j < 8; j++) inv_buf[j] = ~fb_font[text[k]][j]; display_send_data(inv_buf, 8); } display_send_cmd2(SSD1306_COLUMNADDR, 0, WIDTH - 1); } int display_init(void *priv) { int i; int k = 0; int row = 0; volatile int j; uint8_t dbuf2[64] = {}; int page = 0; int seg = 0; volatile uint32_t now; i2c_inst = (i2c_inst_t *)priv; for (i = 1; i < 64; i++) { dbuf2[i] = 0; } display_send_cmd(SSD1306_DISPLAYOFF); display_send_cmd1(0xD6, 0x01); display_send_cmd(0xA1); display_setcontrast(contrast); display_send_cmd1(SSD1306_CHARGEPUMP, 0x14); display_send_cmd1(SSD1306_MEMORYMODE, 0x00); display_send_cmd1(SSD1306_SETCOMPINS, 0x12); display_send_cmd1(SSD1306_SETDISPLAYOFFSET, 0x00); display_send_cmd1(SSD1306_SETVCOMDETECT, 0x00); display_send_cmd1(SSD1306_SETMULTIPLEX, 63); display_send_cmd(SSD1306_COMSCANINC); display_send_cmd(SSD1306_DISPLAYALLON_RESUME); display_send_cmd(SSD1306_DISPLAYON); display_send_cmd(0x2E); display_send_cmd2(SSD1306_PAGEADDR, 0, 0xFF); display_send_cmd2(SSD1306_COLUMNADDR, 0, WIDTH - 1); display_send_cmd1(SSD1306_SETSTARTLINE, 0); display_send_cmd(0x00); display_send_cmd(0x10); for (page = 0; page < 8; page++) { display_send_cmd2(SSD1306_PAGEADDR, page, 0xFF); for (seg= 0; seg < 32; seg++) { display_send_data(dbuf2, 8); } display_send_cmd1(SSD1306_SETSTARTLINE, row); } return 0; }