diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..fa1cf42 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,25 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/utility/unity/core", + "${workspaceFolder}/utility/unity/fixture", + "${workspaceFolder}/test/oled/helpers/inc", + "${workspaceFolder}/test/oled/", + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE", + "TEST" + ], + "compilerPath": "C:\\Apps\\mingw64\\bin\\gcc.exe", + "cStandard": "gnu17", + "cppStandard": "gnu++17", + "intelliSenseMode": "windows-gcc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e860643..4fdfc88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required(VERSION 3.10) +project(my_libs VERSION 0.1.0) + set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/exe) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra") set(CMAKE_BUILD_TYPE Debug) diff --git a/oled/connection.c b/oled/connection.c new file mode 100644 index 0000000..3c716de --- /dev/null +++ b/oled/connection.c @@ -0,0 +1,12 @@ + +#include "connection.h" + +HAL_StatusTypeDef oled_SendCommand(OLED_HandleTypeDef *hOled, uint8_t *pData, uint16_t Size) +{ + return HAL_I2C_Mem_Write(hOled->hi2c, (hOled->DevAddress) << 1, I2C_COMMAND, 1, pData, Size, I2C_TIMEOUT); +} + +HAL_StatusTypeDef oled_SendData(OLED_HandleTypeDef *hOled, uint8_t *pData, uint16_t Size) +{ + return HAL_I2C_Mem_Write(hOled->hi2c, (hOled->DevAddress) << 1, I2C_DATA, 1, pData, Size, I2C_TIMEOUT); +} diff --git a/oled/connection.h b/oled/connection.h new file mode 100644 index 0000000..7eadf26 --- /dev/null +++ b/oled/connection.h @@ -0,0 +1,7 @@ +#pragma once + +#include "main.h" +#include "oled.h" + +HAL_StatusTypeDef oled_SendCommand(OLED_HandleTypeDef *hOled, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef oled_SendData(OLED_HandleTypeDef *hOled, uint8_t *pData, uint16_t Size); diff --git a/oled/oled.c b/oled/oled.c new file mode 100644 index 0000000..65f4120 --- /dev/null +++ b/oled/oled.c @@ -0,0 +1,59 @@ +#include +#include "oled.h" +#include "ssd1306.h" + +HAL_StatusTypeDef oled_Config(OLED_HandleTypeDef *hOled, uint8_t DevAddress, uint8_t Width, uint8_t Height, OLED_DisplayTypeDef OledType) +{ + if (hOled == NULL || Width == 0 || Height == 0 || OledType == UNKNOWN) + { + return HAL_ERROR; + } + + hOled->DevAddress = DevAddress; + hOled->Width = Width; + hOled->Height = Height; + hOled->OledType = OledType; + hOled->Buffer = (uint8_t *)malloc(Width * ((Height + 7) / 8)); + + if (hOled->Buffer == NULL) + { + return HAL_ERROR; + } + + return HAL_OK; +} + +void oled_init(OLED_HandleTypeDef *hOled, I2C_HandleTypeDef *hi2c) +{ + if (hOled == NULL || hi2c == NULL) + { + return; + } + + if (hOled->Buffer == NULL) + { + return; + } + + hOled->hi2c = hi2c; + + switch (hOled->OledType) + { + case SSD1306: + SSD1306_Init(hOled); + break; + case SH1106: + SH1106_Init(hOled); + break; + + default: + break; + } +} + +int main(void) +{ + + OLED_HandleTypeDef display; + oled_Config(&display, 0x3C, 128, 64, SH1106); +} \ No newline at end of file diff --git a/oled/oled.h b/oled/oled.h new file mode 100644 index 0000000..236fb8b --- /dev/null +++ b/oled/oled.h @@ -0,0 +1,27 @@ +#pragma once + +#include "main.h" + +#define I2C_COMMAND 0x00 +#define I2C_DATA 0x40 +#define I2C_TIMEOUT 100 + +typedef enum +{ + UNKNOWN, + SSD1306, + SH1106 +} OLED_DisplayTypeDef; + +typedef struct +{ + I2C_HandleTypeDef *hi2c; + OLED_DisplayTypeDef OledType; + uint8_t DevAddress; + uint8_t Width; + uint8_t Height; + uint8_t *Buffer; + +} OLED_HandleTypeDef; + +void oled_init(OLED_HandleTypeDef *hOled, I2C_HandleTypeDef *hi2c); \ No newline at end of file diff --git a/oled/sh1106/sh1106.c b/oled/sh1106/sh1106.c new file mode 100644 index 0000000..8ddc31b --- /dev/null +++ b/oled/sh1106/sh1106.c @@ -0,0 +1,7 @@ +#include "sh1106.h" +#include "connection.h" + +void SH1106_Init(OLED_HandleTypeDef *hOled) +{ + +} \ No newline at end of file diff --git a/oled/sh1106/sh1106.h b/oled/sh1106/sh1106.h new file mode 100644 index 0000000..01a589f --- /dev/null +++ b/oled/sh1106/sh1106.h @@ -0,0 +1,23 @@ +#pragma once + +#define LOWCOLADDR 0x00 // 0x00h (0000 XXXX) +#define HIGHCOLADDR 0x10 // 0x10h (0001 XXXX) +#define PUMPVOLTAGE 0x30 // 0x32h (0011 00XX) +#define LINEADDRESS 0x40 // 0x40h (01XX XXXX) +#define CONTRASTMODE 0x81 // (1000 0001) +#define CONTRASTVALUE 0x80 // 0x80h (0x00h - 0xFFh) (XXXX XXXX) +#define SEGMENTREMAP 0xA0 // 0xA0h (1010 000X) right(0), left(1) +#define ENTIREDISPALY 0xA4 // 0xA4h (1010 010X) normal(0), entire(1) +#define NORMALORREVERS 0xA6 // 0xA6h (1010 011X) normal(0), reverse(1) +#define MULTIPLEXMODE 0xA8 // (1010 1000) +#define MILTIPLEXVALUE 0x3F // 0x3Fh (00XX XXXX) (0x00h - 0x3Fh) +#define DCCONTROLMODE 0xAD // (1010 1101) +#define DCCONTROLVALUE 0x8B // 0x8Bh (1000 101X) ON(1), OFF(0) +#define DISPLAYOFF 0xAE +#define DISPLAYON 0xAF // 0xAEh (1010 111X) ON(1), OFF(0) +#define PAGEADDRESS 0xB0 // 0xB0h (1011 XXXX) +#define OUTPUTSCANDIR 0xC0 // 0xC0h (1100 X000) +#define OFFSETMODE 0xD3 // (1101 0011) +#define OFFSETVALUE 0x00 // 0x00h (00XX XXXX) COM0-63 +#define DIVRATIOFREQM 0xD5 // (1101 0101) +#define DIVRATIOFREQV 0x50 // 0x50h (FFFF DDDD) Frequency, Divide \ No newline at end of file diff --git a/oled/ssd1306/ssd1306.c b/oled/ssd1306/ssd1306.c new file mode 100644 index 0000000..4722a3c --- /dev/null +++ b/oled/ssd1306/ssd1306.c @@ -0,0 +1,46 @@ + +#include "ssd1306.h" +#include "connection.h" + +void SSD1306_Init(OLED_HandleTypeDef *hOled) +{ + uint8_t comPins = 0x02; + uint8_t contrast = 0x8F; + + if ((hOled->Width == 128) && (hOled->Height == 32)) { + comPins = 0x02; + contrast = 0x0F; + } else if ((hOled->Width == 128) && (hOled->Height == 64)) { + comPins = 0x12; + contrast = 0xCF; + } else if ((hOled->Width == 96) && (hOled->Height == 16)) { + comPins = 0x02; // ada x12 + contrast = 0xAF; + } + + oled_SendCommand(hOled, SSD1306_DISPLAYOFF, 1); + + const uint8_t config[] = { + SSD1306_SETMULTIPLEX, hOled->Height -1, + SSD1306_SETDISPLAYOFFSET, 0x00, + SSD1306_SETSTARTLINE | 0x00, + SSD1306_SEGREMAP | 0x01, + SSD1306_COMSCANDEC, + SSD1306_SETCOMPINS, comPins, + SSD1306_SETCONTRAST, contrast, + SSD1306_DISPLAYALLON_RESUME, + SSD1306_NORMALDISPLAY, + SSD1306_SETDISPLAYCLOCKDIV, 0x80, + SSD1306_CHARGEPUMP, 0x14, + SSD1306_MEMORYMODE, 0x00, + SSD1306_DEACTIVATE_SCROLL, + SSD1306_SETPRECHARGE, 0xF1, + SSD1306_SETVCOMDETECT, 0x40 + }; + + oled_SendCommand(hOled, config, sizeof(config)); + + oled_SendCommand(hOled, SSD1306_DISPLAYON, 1); + + +} \ No newline at end of file diff --git a/oled/ssd1306/ssd1306.h b/oled/ssd1306/ssd1306.h new file mode 100644 index 0000000..b424783 --- /dev/null +++ b/oled/ssd1306/ssd1306.h @@ -0,0 +1,40 @@ +#pragma once + +#define SSD1306_MEMORYMODE 0x20 ///< See datasheet +#define SSD1306_COLUMNADDR 0x21 ///< See datasheet +#define SSD1306_PAGEADDR 0x22 ///< See datasheet +#define SSD1306_SETCONTRAST 0x81 ///< See datasheet +#define SSD1306_CHARGEPUMP 0x8D ///< See datasheet +#define SSD1306_SEGREMAP 0xA0 ///< See datasheet +#define SSD1306_DISPLAYALLON_RESUME 0xA4 ///< See datasheet +#define SSD1306_DISPLAYALLON 0xA5 ///< Not currently used +#define SSD1306_NORMALDISPLAY 0xA6 ///< See datasheet +#define SSD1306_INVERTDISPLAY 0xA7 ///< See datasheet +#define SSD1306_SETMULTIPLEX 0xA8 ///< See datasheet +#define SSD1306_DISPLAYOFF 0xAE ///< See datasheet +#define SSD1306_DISPLAYON 0xAF ///< See datasheet +#define SSD1306_COMSCANINC 0xC0 ///< Not currently used +#define SSD1306_COMSCANDEC 0xC8 ///< See datasheet +#define SSD1306_SETDISPLAYOFFSET 0xD3 ///< See datasheet +#define SSD1306_SETDISPLAYCLOCKDIV 0xD5 ///< See datasheet +#define SSD1306_SETPRECHARGE 0xD9 ///< See datasheet +#define SSD1306_SETCOMPINS 0xDA ///< See datasheet +#define SSD1306_SETVCOMDETECT 0xDB ///< See datasheet + +#define SSD1306_SETLOWCOLUMN 0x00 ///< Not currently used +#define SSD1306_SETHIGHCOLUMN 0x10 ///< Not currently used +#define SSD1306_SETSTARTLINE 0x40 ///< See datasheet + +#define SSD1306_EXTERNALVCC 0x01 ///< External display voltage source +#define SSD1306_SWITCHCAPVCC 0x02 ///< Gen. display voltage from 3.3V + +#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26 ///< Init rt scroll +#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27 ///< Init left scroll +#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29 ///< Init diag scroll +#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A ///< Init diag scroll +#define SSD1306_DEACTIVATE_SCROLL 0x2E ///< Stop scroll +#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 diff --git a/test/oled/CMakeLists.txt b/test/oled/CMakeLists.txt index 0af9b85..3c0010f 100644 --- a/test/oled/CMakeLists.txt +++ b/test/oled/CMakeLists.txt @@ -8,10 +8,11 @@ set(INCLUDE_DIRS ) set(SRCS - + ../../oled/oled.c + helpers/src/mock_i2c.c ) add_definitions(-DTEST) add_executable(${TEST_NAME} ${SRCS}) -target_include_directories(${TEST_NAME} PUBLIC ${INCLUDE_DIR}) \ No newline at end of file +target_include_directories(${TEST_NAME} PUBLIC ${INCLUDE_DIRS}) \ No newline at end of file diff --git a/test/oled/helpers/inc/main.h b/test/oled/helpers/inc/main.h new file mode 100644 index 0000000..0ad3b41 --- /dev/null +++ b/test/oled/helpers/inc/main.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +typedef struct +{ + uint8_t dummy; +}I2C_HandleTypeDef; + +typedef enum +{ + HAL_OK = 0x00U, + HAL_ERROR = 0x01U, + HAL_BUSY = 0x02U, + HAL_TIMEOUT = 0x03 +} HAL_StatusTypeDef; + +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); diff --git a/test/oled/helpers/src/mock_i2c.c b/test/oled/helpers/src/mock_i2c.c new file mode 100644 index 0000000..b75c552 --- /dev/null +++ b/test/oled/helpers/src/mock_i2c.c @@ -0,0 +1,14 @@ +#include "main.h" + + +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + (void)hi2c; + (void)DevAddress; + (void)MemAddress; + (void)MemAddSize; + (void)pData; + (void)Size; + (void)Timeout; + return HAL_OK; +} \ No newline at end of file