diff --git a/source/Core/BSP/Miniware/BSP.cpp b/source/Core/BSP/Miniware/BSP.cpp index fed937e3..f1461258 100644 --- a/source/Core/BSP/Miniware/BSP.cpp +++ b/source/Core/BSP/Miniware/BSP.cpp @@ -379,20 +379,32 @@ uint8_t preStartChecksDone() { } uint8_t getTipResistanceX10() { +#ifdef TIP_RESISTANCE_SENSE_Pin // Return tip resistance in x10 ohms // We can measure this using the op-amp return lastTipResistance; +#else + return TIP_RESISTANCE; +#endif } uint8_t getTipThermalMass() { +#ifdef TIP_RESISTANCE_SENSE_Pin if (lastTipResistance >= 80) { return TIP_THERMAL_MASS; } return 45; +#else + return TIP_THERMAL_MASS; +#endif } uint8_t getTipInertia() { +#ifdef TIP_RESISTANCE_SENSE_Pin if (lastTipResistance >= 80) { return TIP_THERMAL_MASS; } return 10; +#else + return TIP_THERMAL_MASS; +#endif } \ No newline at end of file diff --git a/source/Core/BSP/Miniware/Power.cpp b/source/Core/BSP/Miniware/Power.cpp index 423fe528..4e48b2a2 100644 --- a/source/Core/BSP/Miniware/Power.cpp +++ b/source/Core/BSP/Miniware/Power.cpp @@ -5,7 +5,7 @@ #include "Settings.h" #include "USBPD.h" #include "configuration.h" - +#include "stm32f1xx_hal.h" void power_check() { #ifdef POW_PD // Cant start QC until either PD works or fails @@ -27,7 +27,7 @@ bool getIsPoweredByDCIN() { #endif #ifdef MODEL_TS101 // TODO have to check what we are using - return false; + return HAL_GPIO_ReadPin(DC_SELECT_GPIO_Port, DC_SELECT_Pin) == GPIO_PIN_SET; #endif #ifdef MODEL_TS100 return true; diff --git a/source/Core/BSP/Miniware/Setup.cpp b/source/Core/BSP/Miniware/Setup.cpp index 2bdc7a89..27b3b1e8 100644 --- a/source/Core/BSP/Miniware/Setup.cpp +++ b/source/Core/BSP/Miniware/Setup.cpp @@ -113,7 +113,7 @@ uint16_t getADCVin(uint8_t sample) { latestADC += hadc2.Instance->JDR2; latestADC += hadc2.Instance->JDR3; latestADC += hadc2.Instance->JDR4; - latestADC <<= 3; + latestADC <<= 1; filter.update(latestADC); } return filter.average(); @@ -333,7 +333,7 @@ static void MX_TIP_CONTROL_TIMER_Init(void) { #ifdef TIP_HAS_DIRECT_PWM sConfigOC.Pulse = 0; // PWM is direct to tip #else - sConfigOC.Pulse = 127; // 50% duty cycle, that is AC coupled through the cap to provide an on signal (This does not do tip at 50% duty cycle) + sConfigOC.Pulse = 127; // 50% duty cycle, that is AC coupled through the cap to provide an on signal (This does not do tip at 50% duty cycle) #endif sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_ENABLE; @@ -352,7 +352,7 @@ static void MX_TIP_CONTROL_TIMER_Init(void) { // Remap TIM3_CH1 to be on PB4 __HAL_AFIO_REMAP_TIM3_PARTIAL(); #else - // No re-map required + // No re-map required #endif HAL_TIM_PWM_Start(&htimTip, PWM_Out_CHANNEL); } @@ -496,8 +496,8 @@ static void MX_GPIO_Init(void) { HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); #endif #else - /* TS80 */ - /* Leave USB lines open circuit*/ + /* TS80 */ + /* Leave USB lines open circuit*/ #endif diff --git a/source/Core/BSP/Miniware/configuration.h b/source/Core/BSP/Miniware/configuration.h index 9be7918b..8c4145d0 100644 --- a/source/Core/BSP/Miniware/configuration.h +++ b/source/Core/BSP/Miniware/configuration.h @@ -224,10 +224,10 @@ #ifdef MODEL_TS80 #define VOLTAGE_DIV 780 // Default divider from schematic #define CALIBRATION_OFFSET 900 // the adc offset in uV -#define PID_POWER_LIMIT 24 // Sets the max pwm power limit -#define POWER_LIMIT 24 // 24 watts default power limit +#define PID_POWER_LIMIT 35 // Sets the max pwm power limit +#define POWER_LIMIT 32 // 24 watts default power limit -#define HARDWARE_MAX_WATTAGE_X10 180 +#define HARDWARE_MAX_WATTAGE_X10 320 #define POW_QC @@ -238,9 +238,9 @@ #define VOLTAGE_DIV 650 // Default for TS80P with slightly different resistors #define CALIBRATION_OFFSET 1500 // the adc offset in uV #define PID_POWER_LIMIT 35 // Sets the max pwm power limit -#define POWER_LIMIT 30 // 30 watts default power limit +#define POWER_LIMIT 32 // 30 watts default power limit -#define HARDWARE_MAX_WATTAGE_X10 300 +#define HARDWARE_MAX_WATTAGE_X10 320 #define POW_PD 1 #define POW_QC 1 diff --git a/source/Core/BSP/Sequre_S60/configuration.h b/source/Core/BSP/Sequre_S60/configuration.h index 50ea3d86..8c5f574f 100644 --- a/source/Core/BSP/Sequre_S60/configuration.h +++ b/source/Core/BSP/Sequre_S60/configuration.h @@ -160,12 +160,12 @@ #define HAS_POWER_DEBUG_MENU #define TEMP_NTC #define I2C_SOFT_BUS_2 // For now we are doing software I2C to get around hardware chip issues -#define OLED_I2CBB +#define OLED_I2CBB2 #define MODEL_HAS_DCDC // We dont have DC/DC but have reallly fast PWM that gets us roughly the same place #endif #endif -#define FLASH_LOGOADDR (0x08000000 + (62 * 1024)) +#define FLASH_LOGOADDR (0x08000000 + (62 * 1024)) #define SETTINGS_START_PAGE (0x08000000 + (63 * 1024)) diff --git a/source/Core/Drivers/OLED.cpp b/source/Core/Drivers/OLED.cpp index 32f075c9..05dd6777 100644 --- a/source/Core/Drivers/OLED.cpp +++ b/source/Core/Drivers/OLED.cpp @@ -14,17 +14,16 @@ #include // rendering to the buffer -uint8_t *OLED::firstStripPtr; // Pointers to the strips to allow for buffer -// having extra content -uint8_t *OLED::secondStripPtr; // Pointers to the strips -bool OLED::inLeftHandedMode; // Whether the screen is in left or not (used for +uint8_t *OLED::stripPointers[4]; // Pointers to the strips to allow for buffer having extra content + +bool OLED::inLeftHandedMode; // Whether the screen is in left or not (used for // offsets in GRAM) OLED::DisplayState OLED::displayState; int16_t OLED::cursor_x, OLED::cursor_y; bool OLED::initDone = false; uint8_t OLED::displayOffset; uint8_t OLED::screenBuffer[16 + (OLED_WIDTH * (OLED_HEIGHT / 8)) + 10]; // The data buffer -uint8_t OLED::secondFrameBuffer[OLED_WIDTH * 2]; +uint8_t OLED::secondFrameBuffer[16 + (OLED_WIDTH * (OLED_HEIGHT / 8)) + 10]; uint32_t OLED::displayChecksum; /*Setup params for the OLED screen*/ /*http://www.displayfuture.com/Display/datasheet/controller/SSD1307.pdf*/ @@ -32,20 +31,20 @@ uint32_t OLED::displayChecksum; /*Data packets are prefixed with 0x40*/ I2C_CLASS::I2C_REG OLED_Setup_Array[] = { /**/ - {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, OLED_HEIGHT - 1, 0}, /*Multiplex ratio adjusts how far down the matrix it scans*/ - {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*/ - #ifdef OLED_SEGMENT_MAP_REVERSED - {0x80, 0xA1, 0}, /*Set Segment remap to normal*/ - #else - {0x80, 0xA0, 0}, /*Set Segment remap to normal*/ - #endif + {0x80, 0xAE, 0}, /*Display off*/ + {0x80, 0xD3, 0}, /*Set display clock divide ratio / osc freq*/ + {0x80, 0x52, 0}, /*Divide ratios*/ + {0x80, 0xA8, 0}, /*Set Multiplex Ratio*/ + {0x80, OLED_HEIGHT - 1, 0}, /*Multiplex ratio adjusts how far down the matrix it scans*/ + {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*/ +#ifdef OLED_SEGMENT_MAP_REVERSED + {0x80, 0xA1, 0}, /*Set Segment remap to normal*/ +#else + {0x80, 0xA0, 0}, /*Set Segment remap to normal*/ +#endif {0x80, 0x8D, 0}, /*Charge Pump*/ {0x80, 0x14, 0}, /*Charge Pump settings*/ {0x80, 0xDA, 0}, /*Set VCOM Pins hardware config*/ @@ -111,14 +110,22 @@ static uint8_t easeInOutTiming(uint8_t t) { return t * t * (300 - 2 * t) / 10000 * @param b The value associated with 100% * @param t The percentage [0..<100] */ -static uint8_t lerp(uint8_t a, uint8_t b, uint8_t t) { return a + t * (b - a) / 100; } +static uint16_t lerp(uint16_t a, uint16_t b, uint16_t t) { return a + t * (b - a) / 100; } void OLED::initialize() { cursor_x = cursor_y = 0; inLeftHandedMode = false; - firstStripPtr = &screenBuffer[FRAMEBUFFER_START]; - secondStripPtr = &screenBuffer[FRAMEBUFFER_START + OLED_WIDTH]; - displayOffset = 0; +#ifdef OLED_128x32 + stripPointers[0] = &screenBuffer[FRAMEBUFFER_START]; + stripPointers[1] = &screenBuffer[FRAMEBUFFER_START + OLED_WIDTH]; + stripPointers[2] = &screenBuffer[FRAMEBUFFER_START + 2 * OLED_WIDTH]; + stripPointers[3] = &screenBuffer[FRAMEBUFFER_START + 3 * OLED_WIDTH]; + +#else + stripPointers[0] = &screenBuffer[FRAMEBUFFER_START]; + stripPointers[1] = &screenBuffer[FRAMEBUFFER_START + OLED_WIDTH]; +#endif + displayOffset = 0; memcpy(&screenBuffer[0], &REFRESH_COMMANDS[0], sizeof(REFRESH_COMMANDS)); // Set the display to be ON once the settings block is sent and send the @@ -133,14 +140,13 @@ void OLED::initialize() { initDone = true; } void OLED::setFramebuffer(uint8_t *buffer) { - if (buffer == NULL) { - firstStripPtr = &screenBuffer[FRAMEBUFFER_START]; - secondStripPtr = &screenBuffer[FRAMEBUFFER_START + OLED_WIDTH]; - return; - } + stripPointers[0] = &buffer[FRAMEBUFFER_START]; + stripPointers[1] = &buffer[FRAMEBUFFER_START + OLED_WIDTH]; - firstStripPtr = &buffer[0]; - secondStripPtr = &buffer[OLED_WIDTH]; +#ifdef OLED_128x32 + stripPointers[2] = &buffer[FRAMEBUFFER_START + (2 * OLED_WIDTH)]; + stripPointers[3] = &buffer[FRAMEBUFFER_START + (3 * OLED_WIDTH)]; +#endif } /* @@ -233,7 +239,10 @@ void OLED::maskScrollIndicatorOnOLED() { // Start of data 0x40, - +#ifdef OLED_128x32 + 0x00, + 0x00, +#endif // Clears two 8px strips 0x00, 0x00, @@ -249,8 +258,14 @@ void OLED::maskScrollIndicatorOnOLED() { * Otherwise a rewinding navigation animation is shown to the second framebuffer contents. */ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) { - uint8_t *firstBackStripPtr = &secondFrameBuffer[0]; - uint8_t *secondBackStripPtr = &secondFrameBuffer[OLED_WIDTH]; + uint8_t *stripBackPointers[4]; + stripBackPointers[0] = &secondFrameBuffer[0]; + stripBackPointers[1] = &secondFrameBuffer[OLED_WIDTH]; + +#ifdef OLED_128x32 + stripBackPointers[2] = &secondFrameBuffer[OLED_WIDTH * 2]; + stripBackPointers[3] = &secondFrameBuffer[OLED_WIDTH * 3]; +#endif TickType_t totalDuration = TICKS_100MS * 5; // 500ms TickType_t duration = 0; @@ -262,6 +277,7 @@ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) { uint8_t progress = ((duration * 100) / totalDuration); // Percentage of the period we are through for animation progress = easeInOutTiming(progress); progress = lerp(0, OLED_WIDTH, progress); + // Constrain if (progress > OLED_WIDTH) { progress = OLED_WIDTH; } @@ -278,11 +294,19 @@ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) { offset = progress; - memmove(&firstStripPtr[oldStart], &firstStripPtr[oldPrevious], OLED_WIDTH - progress); - memmove(&secondStripPtr[oldStart], &secondStripPtr[oldPrevious], OLED_WIDTH - progress); + memmove(&stripPointers[0][oldStart], &stripPointers[0][oldPrevious], OLED_WIDTH - progress); + memmove(&stripPointers[1][oldStart], &stripPointers[1][oldPrevious], OLED_WIDTH - progress); +#ifdef OLED_128x32 + memmove(&stripPointers[2][oldStart], &stripPointers[2][oldPrevious], OLED_WIDTH - progress); + memmove(&stripPointers[3][oldStart], &stripPointers[3][oldPrevious], OLED_WIDTH - progress); +#endif - memmove(&firstStripPtr[newStart], &firstBackStripPtr[newEnd], progress); - memmove(&secondStripPtr[newStart], &secondBackStripPtr[newEnd], progress); + memmove(&stripPointers[0][newStart], &stripBackPointers[0][newEnd], progress); + memmove(&stripPointers[1][newStart], &stripBackPointers[1][newEnd], progress); +#ifdef OLED_128x32 + memmove(&stripPointers[2][newStart], &stripBackPointers[2][newEnd], progress); + memmove(&stripPointers[3][newStart], &stripBackPointers[3][newEnd], progress); +#endif refresh(); osDelay(TICKS_100MS / 7); @@ -296,60 +320,62 @@ void OLED::useSecondaryFramebuffer(bool useSecondary) { if (useSecondary) { setFramebuffer(secondFrameBuffer); } else { - setFramebuffer(NULL); + setFramebuffer(screenBuffer); } } /** - * Plays a transition animation of scrolling downward. Note this does *not* - * use the secondary framebuffer. - * - * This transition relies on the previous screen data already in the OLED - * RAM. The caller shall not call `OLED::refresh()` before calling this - * method, as doing so will overwrite the previous screen data. The caller - * does not need to call `OLED::refresh()` after this function returns. + * This assumes that the current display output buffer has the current on screen contents + * Then the secondary buffer has the "new" contents to be slid up onto the screen + * Sadly we cant use the hardware scroll as some devices with the 128x32 screens dont have the GRAM for holding both screens at once * * **This function blocks until the transition has completed or user presses button** */ void OLED::transitionScrollDown() { - // We want to draw the updated framebuffer to the next page downward. - uint8_t const pageStart = screenBuffer[13]; - uint8_t const nextPage = (pageStart + (OLED_HEIGHT / 8)) % 8; - // Change page start address: - screenBuffer[13] = nextPage; - // Change page end address: - screenBuffer[15] = (nextPage + 1) % 8; - refresh(); // Now refresh to write out the contents to the new page - osDelay(TICKS_100MS / 5); + for (uint8_t heightPos = 0; heightPos < OLED_HEIGHT; heightPos++) { + // For each line, we shuffle all bits up a row + for (uint8_t xPos = 0; xPos < OLED_WIDTH; xPos++) { + const uint16_t firstStripPos = FRAMEBUFFER_START + xPos; + const uint16_t secondStripPos = firstStripPos + OLED_WIDTH; +#ifdef OLED_128x32 + // For 32 pixel high OLED's we have four strips to tailchain + const uint16_t thirdStripPos = secondStripPos + OLED_WIDTH; + const uint16_t fourthStripPos = thirdStripPos + OLED_WIDTH; + // Move the MSB off the first strip, and pop MSB from second strip onto the first strip + screenBuffer[firstStripPos] = (screenBuffer[firstStripPos] >> 1) | ((screenBuffer[secondStripPos] & 0x01) << 7); + // Now shuffle off the second strip + screenBuffer[secondStripPos] = (screenBuffer[secondStripPos] >> 1) | ((screenBuffer[thirdStripPos] & 0x01) << 7); + // Now shuffle off the third strip + screenBuffer[thirdStripPos] = (screenBuffer[thirdStripPos] >> 1) | ((screenBuffer[fourthStripPos] & 0x01) << 7); + // Now forth strip gets the start of the new buffer + screenBuffer[fourthStripPos] = (screenBuffer[fourthStripPos] >> 1) | ((secondFrameBuffer[firstStripPos] & 0x01) << 7); + // Now cycle all the secondary buffers - uint8_t startLine = (pageStart * 8) + 1; - - uint8_t scrollTo = (pageStart + (OLED_HEIGHT / 8)) * 8; - - // Scroll the screen by changing display start line. - // This effectively scrolls off the bottom of the current page and into the next one - for (uint8_t current = startLine; current <= scrollTo; current++) { - if (getButtonState() != BUTTON_NONE) { - current = scrollTo; + secondFrameBuffer[firstStripPos] = (secondFrameBuffer[firstStripPos] >> 1) | ((secondFrameBuffer[secondStripPos] & 0x01) << 7); + secondFrameBuffer[secondStripPos] = (secondFrameBuffer[secondStripPos] >> 1) | ((secondFrameBuffer[thirdStripPos] & 0x01) << 7); + secondFrameBuffer[thirdStripPos] = (secondFrameBuffer[thirdStripPos] >> 1) | ((secondFrameBuffer[fourthStripPos] & 0x01) << 7); + // Finally on the bottom row; we shuffle it up ready + secondFrameBuffer[fourthStripPos] >>= 1; +#else + // Move the MSB off the first strip, and pop MSB from second strip onto the first strip + screenBuffer[firstStripPos] = (screenBuffer[firstStripPos] >> 1) | ((screenBuffer[secondStripPos] & 0x01) << 7); + // Now shuffle off the second strip MSB, and replace it with the MSB of the secondary buffer + screenBuffer[secondStripPos] = (screenBuffer[secondStripPos] >> 1) | ((secondFrameBuffer[firstStripPos] & 0x01) << 7); + // Finally, do the shuffle on the second frame buffer + secondFrameBuffer[firstStripPos] = (secondFrameBuffer[firstStripPos] >> 1) | ((secondFrameBuffer[secondStripPos] & 0x01) << 7); + // Finally on the bottom row; we shuffle it up ready + secondFrameBuffer[secondStripPos] >>= 1; +#endif } - - // Set display start line (0x40~0x7F): - // X[5:0] - display start line value - uint8_t scrollCommandByte = 0b01000000 | (current & 0b00111111); - - // Also update setup command for "set display start line": - OLED_Setup_Array[8].val = scrollCommandByte; - - I2C_CLASS::I2C_RegisterWrite(DEVICEADDR_OLED, 0x80, scrollCommandByte); + if (getButtonState() != BUTTON_NONE) { + // Exit early, but have to transition whole buffer + memcpy(screenBuffer + FRAMEBUFFER_START, secondFrameBuffer + FRAMEBUFFER_START, sizeof(screenBuffer) - FRAMEBUFFER_START); + refresh(); // Now refresh to write out the contents to the new page + return; + } + refresh(); // Now refresh to write out the contents to the new page osDelay(TICKS_100MS / 7); } - // Now that scroll is done, revert to default page to avoid wrap issues - screenBuffer[13] = pageStart; - screenBuffer[15] = (pageStart + 1) % 8; - uint8_t scrollCommandByte = 0b01000000; - OLED_Setup_Array[8].val = scrollCommandByte; - refresh(); - I2C_CLASS::I2C_RegisterWrite(DEVICEADDR_OLED, 0x80, scrollCommandByte); } void OLED::setRotation(bool leftHanded) { @@ -387,7 +413,7 @@ void OLED::setRotation(bool leftHanded) { screenBuffer[7] = inLeftHandedMode ? OLED_GRAM_END_FLIP : OLED_GRAM_END; // End address of the ram segment we are writing to (96 wide) screenBuffer[9] = inLeftHandedMode ? 0xC8 : 0xC0; // Force a screen refresh - const int len = FRAMEBUFFER_START + (OLED_WIDTH * 2); + const int len = FRAMEBUFFER_START + (OLED_WIDTH * (OLED_HEIGHT / 8)); I2C_CLASS::Transmit(DEVICEADDR_OLED, screenBuffer, len); osDelay(TICKS_10MS); checkDisplayBufferChecksum(); @@ -540,15 +566,16 @@ void OLED::drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uin if (y == 0) { // Splat first line of data for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) { - firstStripPtr[xx + x] = ptr[xx]; + stripPointers[0][xx + x] = ptr[xx]; } } - if (y == 8 || height == 16) { + if (y == 8 || height >= 16) { // Splat the second line for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) { - secondStripPtr[x + xx] = ptr[xx + (height == 16 ? wide : 0)]; + stripPointers[1][x + xx] = ptr[xx + (height == 16 ? wide : 0)]; } } + // TODO NEEDS HEIGHT HANDLERS for 24/32 } // Draw an area, but y must be aligned on 0/8 offset @@ -574,15 +601,15 @@ void OLED::drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height, co if (y == 0) { // Splat first line of data for (uint8_t xx = visibleStart; xx < visibleEnd; xx += 2) { - firstStripPtr[xx + x] = ptr[xx + 1]; - firstStripPtr[xx + x + 1] = ptr[xx]; + stripPointers[0][xx + x] = ptr[xx + 1]; + stripPointers[0][xx + x + 1] = ptr[xx]; } } if (y == 8 || height == 16) { // Splat the second line for (uint8_t xx = visibleStart; xx < visibleEnd; xx += 2) { - secondStripPtr[x + xx] = ptr[xx + 1 + (height == 16 ? wide : 0)]; - secondStripPtr[x + xx + 1] = ptr[xx + (height == 16 ? wide : 0)]; + stripPointers[1][x + xx] = ptr[xx + 1 + (height == 16 ? wide : 0)]; + stripPointers[1][x + xx + 1] = ptr[xx + (height == 16 ? wide : 0)]; } } } @@ -608,13 +635,13 @@ void OLED::fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uin if (y == 0) { // Splat first line of data for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) { - firstStripPtr[xx + x] = value; + stripPointers[0][xx + x] = value; } } if (y == 8 || height == 16) { // Splat the second line for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) { - secondStripPtr[x + xx] = value; + stripPointers[1][x + xx] = value; } } } @@ -630,9 +657,9 @@ void OLED::drawFilledRect(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, bool c mask = mask << (y0 % 8); for (uint8_t col = x0; col < x1; col++) if (clear) - firstStripPtr[(y0 / 8) * 96 + col] &= ~mask; + stripPointers[0][(y0 / 8) * 96 + col] &= ~mask; else - firstStripPtr[(y0 / 8) * 96 + col] |= mask; + stripPointers[0][(y0 / 8) * 96 + col] |= mask; } // Next loop down the line the total number of solids if (y0 / 8 != y1 / 8) @@ -640,18 +667,18 @@ void OLED::drawFilledRect(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, bool c for (uint8_t r = (y0 / 8); r < (y1 / 8); r++) { // This gives us the row index r if (clear) - firstStripPtr[(r * 96) + col] = 0; + stripPointers[0][(r * 96) + col] = 0; else - firstStripPtr[(r * 96) + col] = 0xFF; + stripPointers[0][(r * 96) + col] = 0xFF; } // Finally draw the tail mask = ~(mask << (y1 % 8)); for (uint8_t col = x0; col < x1; col++) if (clear) - firstStripPtr[(y1 / 8) * 96 + col] &= ~mask; + stripPointers[0][(y1 / 8) * 96 + col] &= ~mask; else - firstStripPtr[(y1 / 8) * 96 + col] |= mask; + stripPointers[0][(y1 / 8) * 96 + col] |= mask; } void OLED::drawHeatSymbol(uint8_t state) { diff --git a/source/Core/Drivers/OLED.hpp b/source/Core/Drivers/OLED.hpp index fc35ebc6..eb71b86a 100644 --- a/source/Core/Drivers/OLED.hpp +++ b/source/Core/Drivers/OLED.hpp @@ -37,18 +37,15 @@ extern "C" { #define DEVICEADDR_OLED (0x3c << 1) #ifdef OLED_128x32 -// TODO; for now just cropping in on the screen from 128x32 to 96x16 -#define OLED_WIDTH 96 -#define OLED_HEIGHT 16 -#define OLED_GRAM_START 0x10 // Should be 0x00 when we have full width -#define OLED_GRAM_END 0x6F // Should be 0x7F when we have full width +#define OLED_WIDTH 128 +#define OLED_HEIGHT 32 +#define OLED_GRAM_START 0x00 // Should be 0x00 when we have full width +#define OLED_GRAM_END 0x7F // Should be 0x7F when we have full width #define OLED_GRAM_START_FLIP 0 -#define OLED_GRAM_END_FLIP 95 +#define OLED_GRAM_END_FLIP 0x7F #define OLED_VCOM_LAYOUT 0x12 #define OLED_SEGMENT_MAP_REVERSED - -#warning "128x32 OLED's Not fully supported" #else #define OLED_WIDTH 96 #define OLED_HEIGHT 16 @@ -80,7 +77,7 @@ public: static void refresh() { if (checkDisplayBufferChecksum()) { - const int len = FRAMEBUFFER_START + (OLED_WIDTH * 2); + const int len = FRAMEBUFFER_START + (OLED_WIDTH * (OLED_HEIGHT / 8)); I2C_CLASS::Transmit(DEVICEADDR_OLED, screenBuffer, len); // DMA tx time is ~ 20mS Ensure after calling this you delay for at least 25ms // or we need to goto double buffering @@ -121,7 +118,7 @@ public: // Draws a number at the current cursor location static void printNumber(uint16_t number, uint8_t places, FontStyle fontStyle, bool noLeaderZeros = true); // Clears the buffer - static void clearScreen() { memset(firstStripPtr, 0, OLED_WIDTH * 2); } + static void clearScreen() { memset(stripPointers[0], 0, OLED_WIDTH * (OLED_HEIGHT / 8)); } // Draws the battery level symbol static void drawBattery(uint8_t state) { drawSymbol(3 + (state > 10 ? 10 : state)); } // Draws a checkbox @@ -143,7 +140,7 @@ public: private: static bool checkDisplayBufferChecksum() { uint32_t hash = 0; - const int len = FRAMEBUFFER_START + (OLED_WIDTH * 2); + const int len = sizeof(screenBuffer); for (int i = 0; i < len; i++) { hash += (i * screenBuffer[i]); } @@ -154,16 +151,15 @@ private: } static void drawChar(uint16_t charCode, FontStyle fontStyle); // Draw a character to the current cursor location static void setFramebuffer(uint8_t *buffer); - static uint8_t *firstStripPtr; // Pointers to the strips to allow for buffer having extra content - static uint8_t *secondStripPtr; // Pointers to the strips + static uint8_t *stripPointers[4]; // Pointers to the strips to allow for buffer having extra content static bool inLeftHandedMode; // Whether the screen is in left or not (used for offsets in GRAM) static bool initDone; static DisplayState displayState; static int16_t cursor_x, cursor_y; static uint8_t displayOffset; static uint32_t displayChecksum; - static uint8_t screenBuffer[16 + (OLED_WIDTH * 2) + 10]; // The data buffer - static uint8_t secondFrameBuffer[OLED_WIDTH * 2]; + static uint8_t screenBuffer[16 + (OLED_WIDTH * (OLED_HEIGHT / 8)) + 10]; // The data buffer + static uint8_t secondFrameBuffer[16 + OLED_WIDTH * (OLED_HEIGHT / 8) + 10]; }; #endif /* OLED_HPP_ */ diff --git a/source/Core/Src/settingsGUI.cpp b/source/Core/Src/settingsGUI.cpp index c65596c4..f90af520 100644 --- a/source/Core/Src/settingsGUI.cpp +++ b/source/Core/Src/settingsGUI.cpp @@ -1006,9 +1006,6 @@ void gui_Menu(const menuitem *menu) { animOpenState = true; // The menu entering/exiting transition uses the secondary framebuffer, // but the scroll down transition does not. - if (navState == NavState::ScrollingDown) { - OLED::useSecondaryFramebuffer(false); - } OLED::setCursor(0, 0); OLED::clearScreen(); if (menu[currentScreen].shortDescriptionSize > 0) { @@ -1019,6 +1016,7 @@ void gui_Menu(const menuitem *menu) { // Play the scroll down animation. OLED::maskScrollIndicatorOnOLED(); OLED::transitionScrollDown(); + OLED::useSecondaryFramebuffer(false); } else { // The menu was drawn in a secondary framebuffer. // Now we play a transition from the pre-drawn primary