From e6445491bb34ec1cd54ee9cdedbe863936fd374a Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sun, 20 Sep 2020 16:09:59 +1000 Subject: [PATCH] Move OLED to use bulk setup --- .../TS100/Core/BSP/Pine64/I2C_Wrapper.cpp | 46 +++------- workspace/TS100/Core/BSP/Pine64/postRTOS.cpp | 1 - workspace/TS100/Core/BSP/Pine64/preRTOS.cpp | 5 +- workspace/TS100/Core/Drivers/I2C_Wrapper.hpp | 15 ++-- workspace/TS100/Core/Drivers/OLED.cpp | 89 +++++++++---------- 5 files changed, 62 insertions(+), 94 deletions(-) diff --git a/workspace/TS100/Core/BSP/Pine64/I2C_Wrapper.cpp b/workspace/TS100/Core/BSP/Pine64/I2C_Wrapper.cpp index 2588c008..a407f21e 100644 --- a/workspace/TS100/Core/BSP/Pine64/I2C_Wrapper.cpp +++ b/workspace/TS100/Core/BSP/Pine64/I2C_Wrapper.cpp @@ -9,8 +9,6 @@ #include SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr; StaticSemaphore_t FRToSI2C::xSemaphoreBuffer; -SemaphoreHandle_t FRToSI2C::I2CSemaphore2 = nullptr; -StaticSemaphore_t FRToSI2C::xSemaphoreBuffer2; #define FLAG_TIMEOUT 1000 void FRToSI2C::CpltCallback() { @@ -28,8 +26,7 @@ int i2c_start() { i2c_flag_clear(I2C0, I2C_FLAG_AERR); /* wait until I2C_FLAG_I2CBSY flag is reset */ - timeout = FLAG_TIMEOUT - ; + timeout = FLAG_TIMEOUT; while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) { if ((timeout--) == 0) { @@ -38,8 +35,7 @@ int i2c_start() { } /* ensure the i2c has been stopped */ - timeout = FLAG_TIMEOUT - ; + timeout = FLAG_TIMEOUT; while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) == I2C_CTL0_STOP) { if ((timeout--) == 0) { return (int) -1; @@ -50,8 +46,7 @@ int i2c_start() { i2c_start_on_bus(I2C0); /* ensure the i2c has been started successfully */ - timeout = FLAG_TIMEOUT - ; + timeout = FLAG_TIMEOUT; while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) { if ((timeout--) == 0) { return (int) -1; @@ -154,8 +149,7 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData i2c_start_on_bus(I2C0); /* ensure the i2c has been started successfully */ - timeout = FLAG_TIMEOUT - ; + timeout = FLAG_TIMEOUT; while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) { if ((timeout--) == 0) { i2c_stop(); @@ -200,8 +194,7 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData i2c_start_on_bus(I2C0); /* ensure the i2c has been started successfully */ - timeout = FLAG_TIMEOUT - ; + timeout = FLAG_TIMEOUT; while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) { if ((timeout--) == 0) { i2c_stop(); @@ -259,8 +252,7 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pDat int timeout = 0; /* wait until I2C_FLAG_I2CBSY flag is reset */ - timeout = FLAG_TIMEOUT - ; + timeout = FLAG_TIMEOUT; while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) { if ((timeout--) == 0) { i2c_stop(); @@ -276,8 +268,7 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pDat i2c_start_on_bus(I2C0); /* ensure the i2c has been started successfully */ - timeout = FLAG_TIMEOUT - ; + timeout = FLAG_TIMEOUT; while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) { if ((timeout--) == 0) { i2c_stop(); @@ -342,8 +333,7 @@ bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { i2c_start_on_bus(I2C0); /* ensure the i2c has been started successfully */ - timeout = FLAG_TIMEOUT - ; + timeout = FLAG_TIMEOUT; while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) { if ((timeout--) == 0) { i2c_stop(); @@ -426,8 +416,10 @@ void FRToSI2C::I2C_Unstick() { } bool FRToSI2C::lock() { - if (I2CSemaphore == nullptr) - return true; + if (I2CSemaphore == nullptr) { + for (;;) { // + } + } return xSemaphoreTake(I2CSemaphore,1000) == pdTRUE; } @@ -436,25 +428,15 @@ void FRToSI2C::unlock() { return; xSemaphoreGive(I2CSemaphore); } -bool FRToSI2C::lock2() { - if (I2CSemaphore2 == nullptr) - return true; - return xSemaphoreTake(I2CSemaphore2,1000) == pdTRUE; -} - -void FRToSI2C::unlock2() { - if (I2CSemaphore2 == nullptr) - return; - xSemaphoreGive(I2CSemaphore2); -} bool FRToSI2C::writeRegistersBulk(const uint8_t address, const I2C_REG* registers, const uint8_t registersLength) { for (int index = 0; index < registersLength; index++) { if (!I2C_RegisterWrite(address, registers[index].reg, registers[index].val)) { return false; } - if (registers[index].pause_ms) + if (registers[index].pause_ms) { delay_ms(registers[index].pause_ms); + } } return true; } diff --git a/workspace/TS100/Core/BSP/Pine64/postRTOS.cpp b/workspace/TS100/Core/BSP/Pine64/postRTOS.cpp index fa55ab11..d0022011 100644 --- a/workspace/TS100/Core/BSP/Pine64/postRTOS.cpp +++ b/workspace/TS100/Core/BSP/Pine64/postRTOS.cpp @@ -11,7 +11,6 @@ #include "fusbpd.h" void postRToSInit() { // Any after RTos setup - FRToSI2C::FRToSInit(); #ifdef POW_PD //Spawn all of the USB-C processors fusb302_start_processing(); diff --git a/workspace/TS100/Core/BSP/Pine64/preRTOS.cpp b/workspace/TS100/Core/BSP/Pine64/preRTOS.cpp index 222cc096..e2ddee6a 100644 --- a/workspace/TS100/Core/BSP/Pine64/preRTOS.cpp +++ b/workspace/TS100/Core/BSP/Pine64/preRTOS.cpp @@ -11,11 +11,10 @@ #include void preRToSInit() { //Normal system bringup -- GPIO etc - eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL4_PRIO0); - eclic_global_interrupt_enable(); + hardware_init(); - FRToSI2C::FRToSInit(); gpio_bit_reset(OLED_RESET_GPIO_Port, OLED_RESET_Pin); + FRToSI2C::FRToSInit(); delay_ms(50); gpio_bit_set(OLED_RESET_GPIO_Port, OLED_RESET_Pin); } diff --git a/workspace/TS100/Core/Drivers/I2C_Wrapper.hpp b/workspace/TS100/Core/Drivers/I2C_Wrapper.hpp index 88be5e62..ca4a50a4 100644 --- a/workspace/TS100/Core/Drivers/I2C_Wrapper.hpp +++ b/workspace/TS100/Core/Drivers/I2C_Wrapper.hpp @@ -22,10 +22,10 @@ class FRToSI2C { public: static void FRToSInit() { - I2CSemaphore = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer); - xSemaphoreGive(I2CSemaphore); - I2CSemaphore2 = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer2); - xSemaphoreGive(I2CSemaphore2); + if (I2CSemaphore == nullptr) { + I2CSemaphore = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer); + xSemaphoreGive(I2CSemaphore); + } } static void CpltCallback(); //Normal Tx Callback @@ -41,12 +41,9 @@ public: static bool I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data); static uint8_t I2C_RegisterRead(uint8_t address, uint8_t reg); - static void unlock2(); - static bool lock2(); - typedef struct { const uint8_t reg; // The register to write to - const uint8_t val; // The value to write to this register + uint8_t val; // The value to write to this register const uint8_t pause_ms; //How many ms to pause _after_ writing this reg } I2C_REG; static bool writeRegistersBulk(const uint8_t address, const I2C_REG* registers, const uint8_t registersLength); @@ -56,8 +53,6 @@ private: static void I2C_Unstick(); static SemaphoreHandle_t I2CSemaphore; static StaticSemaphore_t xSemaphoreBuffer; - static SemaphoreHandle_t I2CSemaphore2; - static StaticSemaphore_t xSemaphoreBuffer2; }; #endif /* FRTOSI2C_HPP_ */ diff --git a/workspace/TS100/Core/Drivers/OLED.cpp b/workspace/TS100/Core/Drivers/OLED.cpp index 7d5eb0b2..4a8906df 100644 --- a/workspace/TS100/Core/Drivers/OLED.cpp +++ b/workspace/TS100/Core/Drivers/OLED.cpp @@ -30,38 +30,37 @@ uint8_t OLED::secondFrameBuffer[OLED_WIDTH * 2]; /*http://www.displayfuture.com/Display/datasheet/controller/SSD1307.pdf*/ /*All commands are prefixed with 0x80*/ /*Data packets are prefixed with 0x40*/ -uint8_t OLED_Setup_Array[] = { +FRToSI2C::I2C_REG OLED_Setup_Array[] = { /**/ -0x80, 0xAE, /*Display off*/ -0x80, 0xD5, /*Set display clock divide ratio / osc freq*/ -0x80, 0x52, /*Divide ratios*/ -0x80, 0xA8, /*Set Multiplex Ratio*/ -0x80, 0x0F, /*16 == max brightness,39==dimmest*/ -0x80, 0xC0, /*Set COM Scan direction*/ -0x80, 0xD3, /*Set vertical Display offset*/ -0x80, 0x00, /*0 Offset*/ -0x80, 0x40, /*Set Display start line to 0*/ -0x80, 0xA0, /*Set Segment remap to normal*/ -0x80, 0x8D, /*Charge Pump*/ -0x80, 0x14, /*Charge Pump settings*/ -0x80, 0xDA, /*Set VCOM Pins hardware config*/ -0x80, 0x02, /*Combination 2*/ -0x80, 0x81, /*Contrast*/ -0x80, 0x33, /*^51*/ -0x80, 0xD9, /*Set pre-charge period*/ -0x80, 0xF1, /*Pre charge period*/ -0x80, 0xDB, /*Adjust VCOMH regulator ouput*/ -0x80, 0x30, /*VCOM level*/ -0x80, 0xA4, /*Enable the display GDDR*/ -0x80, 0XA6, /*Normal display*/ -0x80, 0x20, /*Memory Mode*/ -0x80, 0x00, /*Wrap memory*/ -0x80, 0xAF /*Display on*/ +{ 0x80, 0xAE, 0 }, /*Display off*/ +{ 0x80, 0xD5, 0 }, /*Set display clock divide ratio / osc freq*/ +{ 0x80, 0x52, 0 }, /*Divide ratios*/ +{ 0x80, 0xA8, 0 }, /*Set Multiplex Ratio*/ +{ 0x80, 0x0F, 0 }, /*16 == max brightness,39==dimmest*/ +{ 0x80, 0xC0, 0 }, /*Set COM Scan direction*/ +{ 0x80, 0xD3, 0 }, /*Set vertical Display offset*/ +{ 0x80, 0x00, 0 }, /*0 Offset*/ +{ 0x80, 0x40, 0 }, /*Set Display start line to 0*/ +{ 0x80, 0xA0, 0 }, /*Set Segment remap to normal*/ +{ 0x80, 0x8D, 0 }, /*Charge Pump*/ +{ 0x80, 0x14, 0 }, /*Charge Pump settings*/ +{ 0x80, 0xDA, 0 }, /*Set VCOM Pins hardware config*/ +{ 0x80, 0x02, 0 }, /*Combination 2*/ +{ 0x80, 0x81, 0 }, /*Contrast*/ +{ 0x80, 0x33, 0 }, /*^51*/ +{ 0x80, 0xD9, 0 }, /*Set pre-charge period*/ +{ 0x80, 0xF1, 0 }, /*Pre charge period*/ +{ 0x80, 0xDB, 0 }, /*Adjust VCOMH regulator ouput*/ +{ 0x80, 0x30, 0 }, /*VCOM level*/ +{ 0x80, 0xA4, 0 }, /*Enable the display GDDR*/ +{ 0x80, 0XA6, 0 }, /*Normal display*/ +{ 0x80, 0x20, 0 }, /*Memory Mode*/ +{ 0x80, 0x00, 0 }, /*Wrap memory*/ +{ 0x80, 0xAF, 0 }, /*Display on*/ }; // Setup based on the SSD1307 and modified for the SSD1306 -const uint8_t REFRESH_COMMANDS[17] = { 0x80, 0xAF, 0x80, 0x21, 0x80, 0x20, 0x80, - 0x7F, 0x80, 0xC0, 0x80, 0x22, 0x80, 0x00, 0x80, 0x01, 0x40 }; +const uint8_t REFRESH_COMMANDS[17] = { 0x80, 0xAF, 0x80, 0x21, 0x80, 0x20, 0x80, 0x7F, 0x80, 0xC0, 0x80, 0x22, 0x80, 0x00, 0x80, 0x01, 0x40 }; /* * Animation timing function that follows a bezier curve. @@ -98,8 +97,8 @@ void OLED::initialize() { // initialisation data to the OLED. setDisplayState(DisplayState::ON); - FRToSI2C::Transmit(DEVICEADDR_OLED, &OLED_Setup_Array[0], - sizeof(OLED_Setup_Array)); + FRToSI2C::writeRegistersBulk(DEVICEADDR_OLED, OLED_Setup_Array, sizeof(OLED_Setup_Array) / sizeof(OLED_Setup_Array[0])); + } void OLED::setFramebuffer(uint8_t *buffer) { @@ -128,8 +127,7 @@ void OLED::drawChar(char c) { } uint16_t index = c - 2; //First index is \x02 uint8_t *charPointer; - charPointer = ((uint8_t*) currentFont) - + ((fontWidth * (fontHeight / 8)) * index); + charPointer = ((uint8_t*) currentFont) + ((fontWidth * (fontHeight / 8)) * index); drawArea(cursor_x, cursor_y, fontWidth, fontHeight, charPointer); cursor_x += fontWidth; } @@ -196,8 +194,7 @@ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) { OLED_WIDTH - progress); memmove(&firstStripPtr[newStart], &firstBackStripPtr[newEnd], progress); - memmove(&secondStripPtr[newStart], &secondBackStripPtr[newEnd], - progress); + memmove(&secondStripPtr[newStart], &secondBackStripPtr[newEnd], progress); refresh(); osDelay(40); @@ -222,14 +219,14 @@ void OLED::setRotation(bool leftHanded) { // send command struct again with changes if (leftHanded) { - OLED_Setup_Array[11] = 0xC8; // c1? - OLED_Setup_Array[19] = 0xA1; + OLED_Setup_Array[5].val = 0xC8; // c1? + OLED_Setup_Array[9].val = 0xA1; } else { - OLED_Setup_Array[11] = 0xC0; - OLED_Setup_Array[19] = 0xA0; + OLED_Setup_Array[5].val = 0xC0; + OLED_Setup_Array[9].val = 0xA0; } - FRToSI2C::Transmit(DEVICEADDR_OLED, (uint8_t*) OLED_Setup_Array, - sizeof(OLED_Setup_Array)); + FRToSI2C::writeRegistersBulk(DEVICEADDR_OLED, OLED_Setup_Array, sizeof(OLED_Setup_Array) / sizeof(OLED_Setup_Array[0])); + inLeftHandedMode = leftHanded; screenBuffer[5] = inLeftHandedMode ? 0 : 32; // display is shifted by 32 in left handed @@ -337,8 +334,7 @@ void OLED::drawSymbol(uint8_t symbolID) { } // Draw an area, but y must be aligned on 0/8 offset -void OLED::drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, - const uint8_t *ptr) { +void OLED::drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t *ptr) { // Splat this from x->x+wide in two strides if (x <= -wide) return; // cutoffleft @@ -372,8 +368,7 @@ void OLED::drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, // Draw an area, but y must be aligned on 0/8 offset // For data which has octets swapped in a 16-bit word. -void OLED::drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height, - const uint8_t *ptr) { +void OLED::drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t *ptr) { // Splat this from x->x+wide in two strides if (x <= -wide) return; // cutoffleft @@ -407,8 +402,7 @@ void OLED::drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height, } } -void OLED::fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, - const uint8_t value) { +void OLED::fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t value) { // Splat this from x->x+wide in two strides if (x <= -wide) return; // cutoffleft @@ -440,8 +434,7 @@ void OLED::fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, } } -void OLED::drawFilledRect(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, - bool clear) { +void OLED::drawFilledRect(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, bool clear) { // Draw this in 3 sections // This is basically a N wide version of vertical line