]> mj.ucw.cz Git - home-hw.git/commitdiff
SSD1306 display
authorMartin Mares <mj@ucw.cz>
Sun, 17 Jun 2018 13:21:25 +0000 (15:21 +0200)
committerMartin Mares <mj@ucw.cz>
Sun, 17 Jun 2018 13:21:25 +0000 (15:21 +0200)
Src/test.c

index 57d975332a65a394d7821a9b59331e267f17bc64..e28a02fea273c15cbf77e8cb02530bbcd309bd5b 100644 (file)
@@ -5,6 +5,7 @@
 #include <string.h>
 
 typedef unsigned int uint;
+typedef uint8_t byte;
 typedef uint16_t u16;
 typedef int16_t s16;
 
@@ -134,6 +135,8 @@ void debug_printf(const char *fmt, ...)
   va_end(args);
 }
 
+#if 0
+
 static uint bmp_read(uint reg, uint bytes)
 {
   LL_I2C_ClearFlag_STOP(I2C1);
@@ -249,3 +252,123 @@ void run_test(void)
       LL_mDelay(1000);
     }
 }
+
+#else
+
+// Based on https://github.com/adafruit/Adafruit_SSD1306
+
+#define SSD1306_SETLOWCOLUMN 0x00
+#define SSD1306_SETHIGHCOLUMN 0x10
+#define SSD1306_MEMORYMODE 0x20
+#define SSD1306_SETSTARTLINE 0x40
+#define SSD1306_SETCONTRAST 0x81
+#define SSD1306_CHARGEPUMP 0x8D
+#define SSD1306_SEGREMAP 0xA0
+#define SSD1306_DISPLAYALLON_RESUME 0xA4
+#define SSD1306_DISPLAYALLON 0xA5
+#define SSD1306_NORMALDISPLAY 0xA6
+#define SSD1306_INVERTDISPLAY 0xA7
+#define SSD1306_SETMULTIPLEX 0xA8
+#define SSD1306_DISPLAYOFF 0xAE
+#define SSD1306_DISPLAYON 0xAF
+#define SSD1306_SETSTARTPAGE 0xB0
+#define SSD1306_COMSCANINC 0xC0
+#define SSD1306_COMSCANDEC 0xC8
+#define SSD1306_SETDISPLAYOFFSET 0xD3
+#define SSD1306_SETCOMPINS 0xDA
+#define SSD1306_SETVCOMDETECT 0xDB
+#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
+#define SSD1306_SETPRECHARGE 0xD9
+#define SSD1306_NOP 0xE3
+
+static const byte display_init_cmds[] = {
+  SSD1306_DISPLAYOFF,
+  SSD1306_SETDISPLAYCLOCKDIV, 0x80,  // the suggested ratio 0x80
+  SSD1306_SETMULTIPLEX, 0x1F,        // ratio 32
+  SSD1306_SETDISPLAYOFFSET,0x0,      // no offset
+  SSD1306_SETSTARTLINE | 0x0,        // line #0
+  SSD1306_CHARGEPUMP, 0x14,          // internal vcc
+  SSD1306_MEMORYMODE, 0x02,          // page mode
+  SSD1306_SEGREMAP | 0x0,            // column 0 mapped to SEG0
+  SSD1306_COMSCANDEC,                // column scan direction reversed
+  SSD1306_SETCOMPINS, 0x02,          // sequential COM pins, disable remap
+  SSD1306_SETCONTRAST, 0x7F,         // contrast level 127
+  SSD1306_SETPRECHARGE, 0xF1,        // pre-charge period (1, 15)
+  SSD1306_SETVCOMDETECT, 0x40,       // vcomh regulator level-
+  SSD1306_DISPLAYALLON_RESUME,
+  SSD1306_NORMALDISPLAY,
+  SSD1306_DISPLAYON,
+};
+
+static void display_cmd(byte cmd)
+{
+  LL_I2C_ClearFlag_STOP(I2C1);
+  LL_I2C_HandleTransfer(I2C1, 0x79, LL_I2C_ADDRSLAVE_7BIT, 2, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
+  while (!LL_I2C_IsActiveFlag_TXE(I2C1))
+    ;
+  LL_I2C_TransmitData8(I2C1, 0x00);            // Will send a command
+  while (!LL_I2C_IsActiveFlag_TXE(I2C1))
+    ;
+  LL_I2C_TransmitData8(I2C1, cmd);
+  while (!LL_I2C_IsActiveFlag_STOP(I2C1))
+    ;
+}
+
+static void display_data_start(uint cnt)
+{
+  LL_I2C_ClearFlag_STOP(I2C1);
+  LL_I2C_HandleTransfer(I2C1, 0x79, LL_I2C_ADDRSLAVE_7BIT, cnt + 1, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
+  while (!LL_I2C_IsActiveFlag_TXE(I2C1))
+    ;
+  LL_I2C_TransmitData8(I2C1, 0x40);            // Will send data
+}
+
+static void display_data(byte d)
+{
+  while (!LL_I2C_IsActiveFlag_TXE(I2C1))
+    ;
+  LL_I2C_TransmitData8(I2C1, d);
+}
+
+static void display_data_end(void)
+{
+  while (!LL_I2C_IsActiveFlag_STOP(I2C1))
+    ;
+}
+
+static void display_init(void)
+{
+  for (uint i=0; i < sizeof(display_init_cmds); i++)
+    display_cmd(display_init_cmds[i]);
+
+  for (uint p=0; p<4; p++)
+    {
+      display_cmd(SSD1306_SETSTARTPAGE + p);
+      display_cmd(SSD1306_SETHIGHCOLUMN);
+      display_cmd(SSD1306_SETLOWCOLUMN);
+      display_data_start(128);
+      for (uint i=0; i<128; i++)
+       display_data(p == 0 ? 0x80 | i : 0);
+      display_data_end();
+    }
+}
+
+void run_test(void)
+{
+  uint cnt = 0;
+
+  debug_puts("Init\r\n");
+  display_init();
+
+  for (;;)
+    {
+      LL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
+
+      debug_printf("Tick tock: %d\r\n", cnt);
+
+      LL_mDelay(1000);
+      cnt++;
+    }
+}
+
+#endif