diff --git a/oled/oled.c b/oled/oled.c index 65f4120..65e660d 100644 --- a/oled/oled.c +++ b/oled/oled.c @@ -1,8 +1,9 @@ #include #include "oled.h" #include "ssd1306.h" +#include "sh1106.h" -HAL_StatusTypeDef oled_Config(OLED_HandleTypeDef *hOled, uint8_t DevAddress, uint8_t Width, uint8_t Height, OLED_DisplayTypeDef OledType) +HAL_StatusTypeDef oled_Config(OLED_HandleTypeDef *hOled, uint8_t DevAddress, uint8_t Width, uint8_t Height, OLED_DisplayType_t OledType) { if (hOled == NULL || Width == 0 || Height == 0 || OledType == UNKNOWN) { @@ -13,7 +14,8 @@ HAL_StatusTypeDef oled_Config(OLED_HandleTypeDef *hOled, uint8_t DevAddress, uin hOled->Width = Width; hOled->Height = Height; hOled->OledType = OledType; - hOled->Buffer = (uint8_t *)malloc(Width * ((Height + 7) / 8)); + hOled->BufSize = Width * ((Height + 7) / 8); + hOled->Buffer = (uint8_t *)malloc(hOled->BufSize); if (hOled->Buffer == NULL) { @@ -30,7 +32,7 @@ void oled_init(OLED_HandleTypeDef *hOled, I2C_HandleTypeDef *hi2c) return; } - if (hOled->Buffer == NULL) + if (hOled->Buffer == NULL || hOled->BufSize == 0) { return; } @@ -51,6 +53,50 @@ void oled_init(OLED_HandleTypeDef *hOled, I2C_HandleTypeDef *hi2c) } } +void oled_display_all(OLED_HandleTypeDef *hOled) +{ + if (hOled == NULL) + { + return; + } + + switch (hOled->OledType) + { + case SSD1306: + SSD1306_display_all(hOled); + break; + case SH1106: + SH1106_display_all(hOled); + break; + + default: + break; + } +} + +OLED_SendStatus_t oled_display_page(OLED_HandleTypeDef *hOled) +{ + if (hOled == NULL) + { + return; + } + OLED_SendStatus_t sendStatus; + switch (hOled->OledType) + { + case SSD1306: + sendStatus = SSD1306_display_page(hOled); + break; + case SH1106: + sendStatus = SH1106_display_page(hOled); + break; + + default: + break; + } + + return sendStatus; +} + int main(void) { diff --git a/oled/oled.h b/oled/oled.h index 236fb8b..3ead40e 100644 --- a/oled/oled.h +++ b/oled/oled.h @@ -11,16 +11,22 @@ typedef enum UNKNOWN, SSD1306, SH1106 -} OLED_DisplayTypeDef; +} OLED_DisplayType_t; + +typedef enum{ + SENDPAGE, + SENDALL +} OLED_SendStatus_t; typedef struct { I2C_HandleTypeDef *hi2c; - OLED_DisplayTypeDef OledType; + OLED_DisplayType_t OledType; uint8_t DevAddress; uint8_t Width; uint8_t Height; uint8_t *Buffer; + uint16_t BufSize; } OLED_HandleTypeDef; diff --git a/oled/sh1106/sh1106.c b/oled/sh1106/sh1106.c index 6573d59..b7c1669 100644 --- a/oled/sh1106/sh1106.c +++ b/oled/sh1106/sh1106.c @@ -1,3 +1,4 @@ +#include "oled.h" #include "sh1106.h" #include "connection.h" @@ -7,23 +8,23 @@ void SH1106_Init(OLED_HandleTypeDef *hOled) oled_SendCommand(hOled, &display, 1); uint8_t config[] = { - SH1106_LOWCOLADDR | 0x00, // 0x00h (0000 XXXX) - SH1106_HIGHCOLADDR | 0x00, // 0x10h (0001 XXXX) - SH1106_PUMPVOLTAGE | 0x02, // 0x32h (0011 00XX) - SH1106_LINEADDRESS | 0x00, // 0x40h (01XX XXXX) - SH1106_CONTRASTMODE, SH1106_CONTRASTVALUE, // (1000 0001) // 0x80h (0x00h - 0xFFh) (XXXX XXXX) - SH1106_SEGMENTREMAP | 0x00, // 0xA0h (1010 000X) right(0), left(1) - SH1106_ENTIREDISPALY | 0x00, // 0xA4h (1010 010X) normal(0), entire(1) - SH1106_NORMALORREVERS | 0x00, // 0xA6h (1010 011X) normal(0), reverse(1) - SH1106_MULTIPLEXMODE, SH1106_MILTIPLEXVALUE, // (1010 1000) // 0x3Fh (00XX XXXX) (0x00h - 0x3Fh) - SH1106_DCCONTROLMODE, SH1106_DCCONTROLVALON, // (1010 1101) // 0x8Bh (1000 101X) ON(1), OFF(0) - SH1106_PAGEADDRESS | 0x00, // 0xB0h (1011 XXXX) - SH1106_OUTPUTSCANDIR | 0x00, // 0xC0h (1100 X000) Scan from COM0 to COM [N- 1] (0x00) or Scan from COM [N-1] to COM0 (0x08) - SH1106_OFFSETMODE, SH1106_OFFSETVALUE, // (1101 0011) // 0x00h (00XX XXXX) COM0-63 - SH1106_DIVRATIOFREQM, SH1106_DIVRATIOFREQV, // (1101 0101) // 0x50h (FFFF DDDD) Frequency, Divide - SH1106_CHARGEMODE, SH1106_CHARGEVALUE, // (1101 1001) // 0x22h (DDDD PPPP) Dis-charge Period, Pre-charge Period - SH1106_COMPADSCONFMODE, SH1106_COMPADSCONFVAL, // (1101 1010) // 0x12h (000X 0010) - SH1106_VCOMDESMODE, SH1106_VCOMDESVALUE // (1101 1101) // 0x35h (XXXX XXXX) VCOM (Beta x Vref) + SH1106_LOWCOLADDR | 0x00, // 0x00h (0000 XXXX) + SH1106_HIGHCOLADDR | 0x00, // 0x10h (0001 XXXX) + SH1106_PUMPVOLTAGE | 0x02, // 0x32h (0011 00XX) + SH1106_LINEADDRESS | 0x00, // 0x40h (01XX XXXX) + SH1106_CONTRASTMODE, SH1106_CONTRASTVALUE, // (1000 0001) // 0x80h (0x00h - 0xFFh) (XXXX XXXX) + SH1106_SEGMENTREMAP | 0x00, // 0xA0h (1010 000X) right(0), left(1) + SH1106_ENTIREDISPALY | 0x00, // 0xA4h (1010 010X) normal(0), entire(1) + SH1106_NORMALORREVERS | 0x00, // 0xA6h (1010 011X) normal(0), reverse(1) + SH1106_MULTIPLEXMODE, SH1106_MILTIPLEXVALUE, // (1010 1000) // 0x3Fh (00XX XXXX) (0x00h - 0x3Fh) + SH1106_DCCONTROLMODE, SH1106_DCCONTROLVALON, // (1010 1101) // 0x8Bh (1000 101X) ON(1), OFF(0) + SH1106_PAGEADDRESS | 0x00, // 0xB0h (1011 XXXX) + SH1106_OUTPUTSCANDIR | 0x00, // 0xC0h (1100 X000) Scan from COM0 to COM [N- 1] (0x00) or Scan from COM [N-1] to COM0 (0x08) + SH1106_OFFSETMODE, SH1106_OFFSETVALUE, // (1101 0011) // 0x00h (00XX XXXX) COM0-63 + SH1106_DIVRATIOFREQM, SH1106_DIVRATIOFREQV, // (1101 0101) // 0x50h (FFFF DDDD) Frequency, Divide + SH1106_CHARGEMODE, SH1106_CHARGEVALUE, // (1101 1001) // 0x22h (DDDD PPPP) Dis-charge Period, Pre-charge Period + SH1106_COMPADSCONFMODE, SH1106_COMPADSCONFVAL, // (1101 1010) // 0x12h (000X 0010) + SH1106_VCOMDESMODE, SH1106_VCOMDESVALUE // (1101 1101) // 0x35h (XXXX XXXX) VCOM (Beta x Vref) }; oled_SendCommand(hOled, config, sizeof(config)); @@ -31,3 +32,31 @@ void SH1106_Init(OLED_HandleTypeDef *hOled) oled_SendCommand(hOled, &display, 1); } +void SH1106_display_all(OLED_HandleTypeDef *hOled) +{ + while (SH1106_display_page(hOled) != SENDALL); +} + +OLED_SendStatus_t SH1106_display_page(OLED_HandleTypeDef *hOled) +{ + static uint8_t page = 0; + + uint8_t config[] = { + SH1106_PAGEADDRESS | page, + SH1106_LOWCOLADDR | 0x00, + SH1106_HIGHCOLADDR | 0x00, + }; + oled_SendCommand(hOled, config, sizeof(config)); + + oled_SendData(hOled, hOled->Buffer + (page * hOled->Width), hOled->Width); + + if (++page > 7) + { + page = 0; + return SENDALL; + } + else + { + return SENDPAGE; + } +} \ No newline at end of file diff --git a/oled/sh1106/sh1106.h b/oled/sh1106/sh1106.h index 0a2a3ef..af39efd 100644 --- a/oled/sh1106/sh1106.h +++ b/oled/sh1106/sh1106.h @@ -27,3 +27,7 @@ #define SH1106_COMPADSCONFVAL 0x12 // 0x12h (000X 0010) #define SH1106_VCOMDESMODE 0xDD // (1101 1101) #define SH1106_VCOMDESVALUE 0x35 // 0x35h (XXXX XXXX) VCOM (Beta x Vref) + +void SH1106_Init(OLED_HandleTypeDef *hOled); +void SH1106_display_all(OLED_HandleTypeDef *hOled); +OLED_SendStatus_t SH1106_display_page(OLED_HandleTypeDef *hOled); \ No newline at end of file diff --git a/oled/ssd1306/ssd1306.c b/oled/ssd1306/ssd1306.c index b46874b..906455e 100644 --- a/oled/ssd1306/ssd1306.c +++ b/oled/ssd1306/ssd1306.c @@ -43,6 +43,39 @@ void SSD1306_Init(OLED_HandleTypeDef *hOled) display = SSD1306_DISPLAYOFF; oled_SendCommand(hOled, &display, 1); +} +void SSD1306_display_all(OLED_HandleTypeDef *hOled) +{ + uint8_t config[] = { + SSD1306_PAGEADDR, 0x00, 0x07, //cmd, start_page, end_page + SSD1306_COLUMNADDR, 0x00, hOled->Width - 1 //cmd, start_col, end_col + }; + oled_SendCommand(hOled, config, sizeof(config)); + + oled_SendData(hOled, hOled->Buffer, hOled->BufSize); +} + +OLED_SendStatus_t SSD1306_display_page(OLED_HandleTypeDef *hOled) +{ + static uint8_t page = 0; + + uint8_t config[] = { + SSD1306_PAGEADDR, page, page, + SSD1306_COLUMNADDR, 0x00, hOled->Width - 1 + }; + oled_SendCommand(hOled, config, sizeof(config)); + + SSD1306_SendData(hOled->Buffer + (page * hOled->Width), hOled->Width); + + if (++page > 7) + { + page = 0; + return SENDALL; + } + else + { + return SENDPAGE; + } } \ No newline at end of file diff --git a/oled/ssd1306/ssd1306.h b/oled/ssd1306/ssd1306.h index 4102969..ddf2c0b 100644 --- a/oled/ssd1306/ssd1306.h +++ b/oled/ssd1306/ssd1306.h @@ -38,5 +38,6 @@ #define SSD1306_ACTIVATE_SCROLL 0x2F ///< Start scroll #define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3 ///< Set scroll range - -void SSD1306_Init(OLED_HandleTypeDef *hOled); \ No newline at end of file +void SSD1306_Init(OLED_HandleTypeDef *hOled); +void SSD1306_display_all(OLED_HandleTypeDef *hOled); +OLED_SendStatus_t SSD1306_display_page(OLED_HandleTypeDef *hOled); \ No newline at end of file