M harmony_changelog.md => harmony_changelog.md +1 -0
@@ 24,6 24,7 @@
### Changed / Improved
* Information about device memory is now sent to MC in floating points numbers
+* General improvement in Eink display and error handling
## [2.0.0 2023-06-29]
M module-bsp/board/linux/eink/LinuxEinkDisplay.cpp => module-bsp/board/linux/eink/LinuxEinkDisplay.cpp +20 -8
@@ 78,25 78,31 @@ namespace hal::eink
[[maybe_unused]] const WaveformTemperature behaviour)
{}
- void LinuxEinkDisplay::dither()
- {}
+ EinkStatus LinuxEinkDisplay::dither()
+ {
+ return EinkStatus::EinkOK;
+ }
- void LinuxEinkDisplay::powerOn()
+ EinkStatus LinuxEinkDisplay::powerOn()
{
EinkPowerOn();
+ return EinkStatus::EinkOK;
}
- void LinuxEinkDisplay::powerOff()
+ EinkStatus LinuxEinkDisplay::powerOff()
{
EinkPowerOff();
+ return EinkStatus::EinkOK;
}
- void LinuxEinkDisplay::shutdown()
- {}
+ EinkStatus LinuxEinkDisplay::shutdown()
+ {
+ return EinkStatus::EinkOK;
+ }
- void LinuxEinkDisplay::wipeOut()
+ EinkStatus LinuxEinkDisplay::wipeOut()
{
- EinkFillScreenWithColor(EinkDisplayColorFilling_e::EinkDisplayColorWhite);
+ return translateStatus(EinkFillScreenWithColor(EinkDisplayColorFilling_e::EinkDisplayColorWhite));
}
EinkStatus LinuxEinkDisplay::resetAndInit()
@@ 105,6 111,12 @@ namespace hal::eink
return EinkStatus::EinkOK;
}
+ EinkStatus LinuxEinkDisplay::reinitAndPowerOn()
+ {
+ resetAndInit();
+ return EinkStatus::EinkOK;
+ }
+
[[nodiscard]] auto LinuxEinkDisplay::getDevice() const noexcept -> std::shared_ptr<devices::Device>
{
return {};
M module-bsp/board/linux/eink/LinuxEinkDisplay.hpp => module-bsp/board/linux/eink/LinuxEinkDisplay.hpp +6 -5
@@ 26,12 26,13 @@ namespace hal::eink
const EinkRefreshMode refreshMode) override;
void prepareEarlyRequest(const EinkRefreshMode refreshMode, const WaveformTemperature behaviour) override;
- void dither() override;
- void powerOn() override;
- void powerOff() override;
- void shutdown() override;
- void wipeOut() override;
+ EinkStatus dither() override;
+ EinkStatus powerOn() override;
+ EinkStatus powerOff() override;
+ EinkStatus shutdown() override;
+ EinkStatus wipeOut() override;
EinkStatus resetAndInit() override;
+ EinkStatus reinitAndPowerOn() override;
[[nodiscard]] std::shared_ptr<devices::Device> getDevice() const noexcept override;
FrameSize size;
M module-bsp/board/rt1051/bsp/eink/ED028TC1.cpp => module-bsp/board/rt1051/bsp/eink/ED028TC1.cpp +251 -281
@@ 1,32 1,15 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "dma_config.h"
-#include "fsl_dmamux.h"
-#include "fsl_edma.h"
#include "ED028TC1.h"
+#include "macros.h"
#include "bsp_eink.h"
-#include "board.h"
+#include "eink_dimensions.hpp"
+#include "eink_binarization_luts.h"
-#include <stdbool.h>
-#include <assert.h>
#include <math.h>
-#include <string.h>
-
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
#include <log/log.hpp>
-#include "board.h"
-#include "eink_binarization_luts.h"
-#include "macros.h"
-#include "eink_dimensions.hpp"
-
-#include <magic_enum.hpp>
-#include "drivers/pll/DriverPLL.hpp"
-#include "drivers/dmamux/DriverDMAMux.hpp"
-#include "drivers/dma/DriverDMA.hpp"
#include "board/BoardDefinitions.hpp"
#define EPD_BOOSTER_START_PERIOD_10MS 0
@@ 60,13 43,6 @@
#define EINK_2BPP_WHITE_PIXEL_MASK 0x03 // This is the mask for the white pixel in 2bpp mode
#define EINK_4BPP_WHITE_PIXEL_MASK 0x0F // This is the mask for the white pixel in 4bpp mode
-#define ED028TC1_BUSY_STATE_TIMEOUT_MS 2000 // Time after the display should for sure exit the busy state
-
-using namespace drivers;
-using namespace magic_enum;
-static std::shared_ptr<drivers::DriverDMA> dma;
-static std::shared_ptr<drivers::DriverDMAMux> dmamux;
-
/* Internal variable definitions */
static bool s_einkIsPoweredOn = false; // Variable which contains the state of the power of the EPD display
@@ 79,12 55,12 @@ static CACHEABLE_SECTION_SDRAM(uint8_t s_einkServiceRotatedBuf[BOARD_EINK_DISPLA
/**
* @brief This lut is used for convertion of the 4bp input grayscale pixel to the 1bpp output pixel
*/
-static uint8_t s_einkMaskLut_1Bpp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1};
+static std::uint8_t s_einkMaskLut_1Bpp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1};
/**
* @brief This lut is used for convertion of the 4bp input grayscale pixel to the 2bpp output pixel
*/
-static uint8_t s_einkMaskLut_2Bpp[16] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3};
+static std::uint8_t s_einkMaskLut_2Bpp[16] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3};
/* External variable definitions */
@@ 133,11 109,11 @@ static uint8_t s_einkMaskLut_2Bpp[16] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3,
*
* @return
*/
-static uint8_t *s_EinkTransformFrameCoordinateSystem_1Bpp(const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
- EinkDisplayColorMode_e invertColors);
+static std::uint8_t *s_EinkTransformFrameCoordinateSystem_1Bpp(const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
+ EinkDisplayColorMode_e invertColors);
/**
* This function makes rotation of the image from the standard GUI coordinate system to the coord system used by the
@@ 182,11 158,11 @@ static uint8_t *s_EinkTransformFrameCoordinateSystem_1Bpp(const uint8_t *dataIn,
*
* @return
*/
-static uint8_t *s_EinkTransformFrameCoordinateSystem_2Bpp(const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
- EinkDisplayColorMode_e invertColors);
+static std::uint8_t *s_EinkTransformFrameCoordinateSystem_2Bpp(const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
+ EinkDisplayColorMode_e invertColors);
/**
* This function makes rotation of the image from the standard GUI coordinate system to the coord system used by the
@@ 231,11 207,11 @@ static uint8_t *s_EinkTransformFrameCoordinateSystem_2Bpp(const uint8_t *dataIn,
*
* @return
*/
-static uint8_t *s_EinkTransformFrameCoordinateSystem_3Bpp(const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
- EinkDisplayColorMode_e invertColors);
+static std::uint8_t *s_EinkTransformFrameCoordinateSystem_3Bpp(const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
+ EinkDisplayColorMode_e invertColors);
/**
* This function makes rotation of the image from the standard GUI coordinate system to the coord system used by the
@@ 280,11 256,11 @@ static uint8_t *s_EinkTransformFrameCoordinateSystem_3Bpp(const uint8_t *dataIn,
*
* @return
*/
-static uint8_t *s_EinkTransformFrameCoordinateSystem_4Bpp(const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
- EinkDisplayColorMode_e invertColors);
+static std::uint8_t *s_EinkTransformFrameCoordinateSystem_4Bpp(const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
+ EinkDisplayColorMode_e invertColors);
/**
* This function makes rotation of the image from the standard GUI coordinate system to the coord system used by the
@@ 329,11 305,11 @@ static uint8_t *s_EinkTransformFrameCoordinateSystem_4Bpp(const uint8_t *dataIn,
*
* @return
*/
-static uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_1Bpp(const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
- EinkDisplayColorMode_e invertColors);
+static std::uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_1Bpp(const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
+ EinkDisplayColorMode_e invertColors);
/**
* This function makes rotation of the image from the standard GUI coordinate system to the coord system used by the
@@ 378,11 354,11 @@ static uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_1Bpp(const uint8_t
*
* @return
*/
-static uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_2Bpp(const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
- EinkDisplayColorMode_e invertColors);
+static std::uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_2Bpp(const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
+ EinkDisplayColorMode_e invertColors);
/**
* This function makes rotation of the image from the standard GUI coordinate system to the coord system used by the
@@ 427,11 403,11 @@ static uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_2Bpp(const uint8_t
*
* @return
*/
-static uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_3Bpp(const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
- EinkDisplayColorMode_e invertColors);
+static std::uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_3Bpp(const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
+ EinkDisplayColorMode_e invertColors);
/**
* This function makes rotation of the image from the standard GUI coordinate system to the coord system used by the
@@ 482,11 458,11 @@ static uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_3Bpp(const uint8_t
* It is used when EINK_ROTATE_90_CLOCKWISE is not defined.
*/
-static uint8_t *s_EinkTransformFrameCoordinateSystemNoRotation_4Bpp(const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
- EinkDisplayColorMode_e invertColors);
+static std::uint8_t *s_EinkTransformFrameCoordinateSystemNoRotation_4Bpp(const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
+ EinkDisplayColorMode_e invertColors);
/* Function bodies */
@@ 516,85 492,90 @@ void EinkChangeDisplayUpdateTimings(EinkDisplayTimingsMode_e timingsMode)
}
if (BSP_EinkWriteData(tmpbuf, 4, SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
return;
}
}
-uint8_t EinkIsPoweredOn()
+bool EinkIsPoweredOn()
{
return s_einkIsPoweredOn;
}
-void EinkPowerOn()
+EinkStatus_e EinkPowerOn()
{
if (s_einkIsPoweredOn) {
- return;
+ return EinkOK;
}
- BSP_EinkLogicPowerOn();
-
- uint8_t cmd = EinkPowerON; // 0x04
+ std::uint8_t cmd = EinkPowerON; // 0x04
if (BSP_EinkWriteData(&cmd, sizeof(cmd), SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
- return;
+ return EinkSPIErr;
}
- BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));
s_einkIsPoweredOn = true;
+
+ if (BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout)) == 0) {
+ return EinkSPIErr;
+ }
+
+ return EinkOK;
}
-void EinkPowerOff()
+EinkStatus_e EinkPowerOff()
{
if (!s_einkIsPoweredOn) {
- return;
+ return EinkOK;
}
- uint8_t cmd = EinkPowerOFF; // 0x02
+ std::uint8_t cmd = EinkPowerOFF; // 0x02
if (BSP_EinkWriteData(&cmd, sizeof(cmd), SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
- return;
+ return EinkSPIErr;
}
- BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));
+ const auto ret = BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout)) == 1 ? EinkOK : EinkSPIErr;
+
+ // continue procedure regardless result
BSP_EinkLogicPowerOff();
s_einkIsPoweredOn = false;
+ return ret;
}
-void EinkPowerDown(void)
+EinkStatus_e EinkPowerDown(void)
{
- EinkPowerOff();
+ const auto powerOffStatus = EinkPowerOff();
BSP_EinkDeinit();
+
+ return powerOffStatus;
}
-int16_t EinkGetTemperatureInternal()
+std::int16_t EinkGetTemperatureInternal()
{
- uint8_t cmd[1];
- int8_t temp[2] = {0, 0};
+ std::uint8_t cmd;
+ std::int8_t temp[2] = {0, 0};
- cmd[0] = EinkTemperatureSensorCalibration;
+ cmd = EinkTemperatureSensorCalibration;
BSP_EinkWriteCS(BSP_Eink_CS_Clr);
- if (BSP_EinkWriteData(cmd, sizeof(cmd), SPI_MANUAL_CS) != 0) {
+ if (BSP_EinkWriteData(&cmd, sizeof(cmd), SPI_MANUAL_CS) != 0) {
BSP_EinkWriteCS(BSP_Eink_CS_Set);
- EinkResetAndInitialize();
return -1;
}
- BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));
+ if (BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout)) == 0) {
+ return -1;
+ }
if (BSP_EinkReadData(temp, sizeof(temp), SPI_MANUAL_CS) != 0) {
BSP_EinkWriteCS(BSP_Eink_CS_Set);
- EinkResetAndInitialize();
return -1;
}
BSP_EinkWriteCS(BSP_Eink_CS_Set);
// First byte of the temp describes the integer part of the temperature in degrees Celsius
- int8_t temperatureInteger = temp[0];
+ const std::int8_t temperatureInteger = temp[0];
// The MSB bit of the second byte describes the fraction of the temperature. Bit value of 1 means .5 degree Celsius,
// bit value of 0 means .0 degree Celsius
// int8_t temperatureFraction = ((temp[1] & 0x80) >> 7);
@@ 604,14 585,13 @@ int16_t EinkGetTemperatureInternal()
static void s_EinkSetGateOrder()
{
- uint8_t buf[3];
+ std::uint8_t buf[3];
// Set the order of gate refreshing
buf[0] = EinkGDOrderSetting;
buf[1] = 0x02; // Magic value required by the ED028TC1 display manufacturer
buf[2] = 0x00;
- if (BSP_EinkWriteData(buf, 3, SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
+ if (BSP_EinkWriteData(buf, sizeof(buf), SPI_AUTOMATIC_CS) != 0) {
return;
}
}
@@ 712,6 692,8 @@ static void s_EinkSetInitialConfig()
EinkStatus_e EinkResetAndInitialize()
{
+ BSP_EinkLogicPowerOn();
+
// Initialize the synchronization resources, SPI and GPIOs for the Eink BSP
BSP_EinkInit(NULL);
// Reset the display
@@ 728,13 710,11 @@ EinkStatus_e EinkUpdateWaveform(const EinkWaveformSettings_t *settings)
{
/// LUTD
if (BSP_EinkWriteData(settings->LUTDData, settings->LUTDSize, SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
return EinkSPIErr;
}
/// LUTC
if (BSP_EinkWriteData(settings->LUTCData, settings->LUTCSize + 1, SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
return EinkSPIErr;
}
@@ 743,21 723,19 @@ EinkStatus_e EinkUpdateWaveform(const EinkWaveformSettings_t *settings)
return EinkOK;
}
-static EinkStatus_e s_EinkReadFlagsRegister(uint16_t *flags)
+static EinkStatus_e s_EinkReadFlagsRegister(std::uint16_t *flags)
{
- uint8_t cmd = EinkFLG;
+ std::uint8_t cmd = EinkFLG;
BSP_EinkWriteCS(BSP_Eink_CS_Clr);
if (BSP_EinkWriteData(&cmd, sizeof(cmd), SPI_MANUAL_CS) != 0) {
BSP_EinkWriteCS(BSP_Eink_CS_Set);
- EinkResetAndInitialize();
return EinkSPIErr;
}
- if (BSP_EinkReadData(flags, sizeof(uint16_t), SPI_MANUAL_CS) != 0) {
+ if (BSP_EinkReadData(flags, sizeof(std::uint16_t), SPI_MANUAL_CS) != 0) {
BSP_EinkWriteCS(BSP_Eink_CS_Set);
- EinkResetAndInitialize();
return EinkSPIErr;
}
@@ 768,7 746,7 @@ static EinkStatus_e s_EinkReadFlagsRegister(uint16_t *flags)
EinkStatus_e EinkWaitTillPipelineBusy()
{
- uint16_t flags = 0;
+ std::uint16_t flags = 0;
s_EinkReadFlagsRegister(&flags);
@@ 782,33 760,30 @@ EinkStatus_e EinkWaitTillPipelineBusy()
EinkStatus_e EinkDitherDisplay()
{
- uint8_t cmdWithArgs[2] = {EinkDPC, EINK_DITHER_4BPP_MODE | EINK_DITHER_START};
+ std::uint8_t cmdWithArgs[2] = {EinkDPC, EINK_DITHER_4BPP_MODE | EINK_DITHER_START};
if (BSP_EinkWriteData(cmdWithArgs, sizeof(cmdWithArgs), SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
return EinkSPIErr;
}
- uint16_t flags = 0;
+ std::uint16_t flags = 0;
s_EinkReadFlagsRegister(&flags);
- // Wait for the dither operation finish
- while (flags & EINK_FLAG_DITHER_IN_PROGRESS) {
- vTaskDelay(pdMS_TO_TICKS(1));
- s_EinkReadFlagsRegister(&flags);
+ if ((flags & EINK_FLAG_DITHER_IN_PROGRESS)) {
+ return EinkSPIErr;
}
return EinkOK;
}
EinkStatus_e EinkUpdateFrame(EinkFrame_t frame,
- const uint8_t *buffer,
+ const std::uint8_t *buffer,
EinkBpp_e bpp,
EinkDisplayColorMode_e invertColors)
{
- uint8_t buf[10];
- uint8_t pixelsInByte = 8 / bpp;
+ std::uint8_t buf[10];
+ std::uint8_t pixelsInByte = 8 / bpp;
s_einkServiceRotatedBuf[0] = EinkDataStartTransmission1;
s_einkServiceRotatedBuf[1] = bpp - 1; // 0 - 1Bpp, 1 - 2Bpp, 2 - 3Bpp, 3 - 4Bpp
@@ 865,42 840,40 @@ EinkStatus_e EinkUpdateFrame(EinkFrame_t frame,
}
buf[0] = EinkDataStartTransmissionWindow; // set display window
- buf[1] = static_cast<uint8_t>(hal::eink::getDisplayXAxis(frame) >>
- 8); // MSB of the X axis in the EPD display. Value converted
- // from the standard GUI coords system to the ED028TC1 one
- buf[2] = static_cast<uint8_t>(
+ buf[1] = static_cast<std::uint8_t>(hal::eink::getDisplayXAxis(frame) >>
+ 8); // MSB of the X axis in the EPD display. Value converted
+ // from the standard GUI coords system to the ED028TC1 one
+ buf[2] = static_cast<std::uint8_t>(
hal::eink::getDisplayXAxis(frame)); // LSB of the X axis in the EPD display. Value converted from
// the standard GUI coords system to the ED028TC1 one
- buf[3] = static_cast<uint8_t>(hal::eink::getDisplayYAxis(frame) >>
- 8); // MSB of the Y axis in the EPD display. Value converted
- // from the standard GUI coords system to the ED028TC1 one
- buf[4] = static_cast<uint8_t>(
+ buf[3] = static_cast<std::uint8_t>(hal::eink::getDisplayYAxis(frame) >>
+ 8); // MSB of the Y axis in the EPD display. Value converted
+ // from the standard GUI coords system to the ED028TC1 one
+ buf[4] = static_cast<std::uint8_t>(
hal::eink::getDisplayYAxis(frame)); // LSB of the Y axis in the EPD display. Value converted from
// the standard GUI coords system to the ED028TC1 one
- buf[5] = static_cast<uint8_t>(hal::eink::getDisplayWindowWidth(frame) >>
- 8); // MSB of the window height in the EPD display. Value converted
- // from the standard GUI coords system to the ED028TC1 one
- buf[6] = static_cast<uint8_t>(
+ buf[5] = static_cast<std::uint8_t>(hal::eink::getDisplayWindowWidth(frame) >>
+ 8); // MSB of the window height in the EPD display. Value converted
+ // from the standard GUI coords system to the ED028TC1 one
+ buf[6] = static_cast<std::uint8_t>(
hal::eink::getDisplayWindowWidth(frame)); // LSB of the window height in the EPD display. Value converted from
// the standard GUI coords system to the ED028TC1 one
- buf[7] = static_cast<uint8_t>(hal::eink::getDisplayWindowHeight(frame) >>
- 8); // MSB of the window width in the EPD display. Value converted
- // from the standard GUI coords system to the ED028TC1 one
- buf[8] = static_cast<uint8_t>(
+ buf[7] = static_cast<std::uint8_t>(hal::eink::getDisplayWindowHeight(frame) >>
+ 8); // MSB of the window width in the EPD display. Value converted
+ // from the standard GUI coords system to the ED028TC1 one
+ buf[8] = static_cast<std::uint8_t>(
hal::eink::getDisplayWindowHeight(frame)); // LSB of the window width in the EPD display. Value converted from
- // the standard GUI coords system to the ED028TC1 one
+ // the standard GUI coords system to the ED028TC1 one
if (BSP_EinkWriteData(buf, 9, SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
return EinkSPIErr;
}
- uint32_t msgSize = 2 + (static_cast<uint32_t>(frame.width) * static_cast<uint32_t>(frame.height) /
- pixelsInByte); // command (1 byte) + bpp (1 byte) + dataSize(W*H/pixelsInByte bytes)
+ std::uint32_t msgSize = 2 + (static_cast<std::uint32_t>(frame.width) * static_cast<std::uint32_t>(frame.height) /
+ pixelsInByte); // command (1 byte) + bpp (1 byte) + dataSize(W*H/pixelsInByte bytes)
// Send the part of the image to the display memory
if (BSP_EinkWriteData(s_einkServiceRotatedBuf, msgSize, SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
return EinkSPIErr;
}
@@ 909,7 882,7 @@ EinkStatus_e EinkUpdateFrame(EinkFrame_t frame,
EinkStatus_e EinkFillScreenWithColor(EinkDisplayColorFilling_e colorFill)
{
- uint8_t buf[10];
+ std::uint8_t buf[10];
// Set the window to the entire screen
buf[0] = EinkDataStartTransmissionWindow; // 0x83
@@ 923,7 896,6 @@ EinkStatus_e EinkFillScreenWithColor(EinkDisplayColorFilling_e colorFill)
buf[8] = EINK_DISPLAY_RES_Y & 0x00FF;
if (BSP_EinkWriteData(buf, 9, SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
return EinkSPIErr;
}
@@ 933,11 905,10 @@ EinkStatus_e EinkFillScreenWithColor(EinkDisplayColorFilling_e colorFill)
buf[1] = Eink1Bpp - 1;
if (BSP_EinkWriteData(buf, 2, SPI_MANUAL_CS) != 0) {
BSP_EinkWriteCS(BSP_Eink_CS_Set);
- EinkResetAndInitialize();
return EinkSPIErr;
}
- uint8_t background = colorFill;
+ std::uint8_t background = colorFill;
std::unique_ptr<char[]> bg;
try {
@@ 952,7 923,6 @@ EinkStatus_e EinkFillScreenWithColor(EinkDisplayColorFilling_e colorFill)
if (BSP_EinkWriteData(bg.get(), BOARD_EINK_DISPLAY_RES_Y * BOARD_EINK_DISPLAY_RES_X / 8, SPI_MANUAL_CS) != 0) {
BSP_EinkWriteCS(BSP_Eink_CS_Set);
- EinkResetAndInitialize();
return EinkSPIErr;
}
@@ 970,71 940,71 @@ EinkStatus_e EinkRefreshImage(EinkFrame_t frame, EinkDisplayTimingsMode_e refres
s_EinkSetGateOrder();
- uint8_t buf[10];
+ std::uint8_t buf[10];
buf[0] = EinkDisplayRefresh;
buf[1] = UPD_CPY_TO_PRE;
- buf[2] = static_cast<uint8_t>(hal::eink::getDisplayXAxis(frame) >>
- 8); // MSB of the X axis in the EPD display. Value converted
- // from the standard GUI coords system to the ED028TC1 one
- buf[3] = static_cast<uint8_t>(
+ buf[2] = static_cast<std::uint8_t>(hal::eink::getDisplayXAxis(frame) >>
+ 8); // MSB of the X axis in the EPD display. Value converted
+ // from the standard GUI coords system to the ED028TC1 one
+ buf[3] = static_cast<std::uint8_t>(
hal::eink::getDisplayXAxis(frame)); // LSB of the X axis in the EPD display. Value converted from
// the standard GUI coords system to the ED028TC1 one
- buf[4] = static_cast<uint8_t>(hal::eink::getDisplayYAxis(frame) >>
- 8); // MSB of the Y axis in the EPD display. Value converted
- // from the standard GUI coords system to the ED028TC1 one
- buf[5] = static_cast<uint8_t>(
+ buf[4] = static_cast<std::uint8_t>(hal::eink::getDisplayYAxis(frame) >>
+ 8); // MSB of the Y axis in the EPD display. Value converted
+ // from the standard GUI coords system to the ED028TC1 one
+ buf[5] = static_cast<std::uint8_t>(
hal::eink::getDisplayYAxis(frame)); // LSB of the Y axis in the EPD display. Value converted from
// the standard GUI coords system to the ED028TC1 one
- buf[6] = static_cast<uint8_t>(hal::eink::getDisplayWindowWidth(frame) >>
- 8); // MSB of the window height in the EPD display. Value converted
- // from the standard GUI coords system to the ED028TC1 one
- buf[7] = static_cast<uint8_t>(
+ buf[6] = static_cast<std::uint8_t>(hal::eink::getDisplayWindowWidth(frame) >>
+ 8); // MSB of the window height in the EPD display. Value converted
+ // from the standard GUI coords system to the ED028TC1 one
+ buf[7] = static_cast<std::uint8_t>(
hal::eink::getDisplayWindowWidth(frame)); // LSB of the window height in the EPD display. Value converted from
// the standard GUI coords system to the ED028TC1 one
- buf[8] = static_cast<uint8_t>(hal::eink::getDisplayWindowHeight(frame) >>
- 8); // MSB of the window width in the EPD display. Value converted
- // from the standard GUI coords system to the ED028TC1 one
- buf[9] = static_cast<uint8_t>(
+ buf[8] = static_cast<std::uint8_t>(hal::eink::getDisplayWindowHeight(frame) >>
+ 8); // MSB of the window width in the EPD display. Value converted
+ // from the standard GUI coords system to the ED028TC1 one
+ buf[9] = static_cast<std::uint8_t>(
hal::eink::getDisplayWindowHeight(frame)); // LSB of the window width in the EPD display. Value converted from
- // the standard GUI coords system to the ED028TC1 one
+ // the standard GUI coords system to the ED028TC1 one
if (BSP_EinkWriteData(buf, sizeof(buf), SPI_AUTOMATIC_CS) != 0) {
- EinkResetAndInitialize();
return EinkSPIErr;
}
- BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));
+ if (BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout)) == 0) {
+ return EinkSPIErr;
+ }
return EinkOK;
}
-__attribute__((optimize("O3"))) void EinkARGBToLuminance(const uint8_t *dataIn,
- uint8_t *dataOut,
- uint32_t displayWidth,
- uint32_t displayHeight)
+__attribute__((optimize("O3"))) void EinkARGBToLuminance(const std::uint8_t *dataIn,
+ std::uint8_t *dataOut,
+ std::uint32_t displayWidth,
+ std::uint32_t displayHeight)
{
- // uint32_t i, j;
- uint8_t r, g, b;
+ std::uint8_t r, g, b;
float fi;
- uint32_t *src;
- uint8_t *dst;
+ std::uint32_t *src;
+ std::uint8_t *dst;
- src = (uint32_t *)dataIn;
- dst = (uint8_t *)dataOut;
+ src = (std::uint32_t *)dataIn;
+ dst = (std::uint8_t *)dataOut;
- for (uint32_t i = 0; i < (displayWidth * displayHeight);
+ for (std::uint32_t i = 0; i < (displayWidth * displayHeight);
i += 2) // increase by 8 pixels - 32bit word is 8 pixels in 4BPP
{
*dst = 0x00000000;
- for (uint8_t j = 0; j < 8; j += 4) {
- r = (uint8_t)((*(src)) >> 16);
- g = (uint8_t)((*(src)) >> 8);
- b = (uint8_t) * (src);
+ for (std::uint8_t j = 0; j < 8; j += 4) {
+ r = (std::uint8_t)((*(src)) >> 16);
+ g = (std::uint8_t)((*(src)) >> 8);
+ b = (std::uint8_t) * (src);
fi = (r + g + b) / 3;
- *dst |= ((uint32_t)(floor(fi / 16))) << (4 - j);
+ *dst |= ((std::uint32_t)(floor(fi / 16))) << (4 - j);
src++;
}
@@ 1042,36 1012,36 @@ __attribute__((optimize("O3"))) void EinkARGBToLuminance(const uint8_t *dataIn,
}
}
-__attribute__((optimize("O1"))) static uint8_t *s_EinkTransformFrameCoordinateSystem_1Bpp(
- const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
+__attribute__((optimize("O1"))) static std::uint8_t *s_EinkTransformFrameCoordinateSystem_1Bpp(
+ const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
EinkDisplayColorMode_e invertColors)
{
// In 1bpp mode there are 8 pixels in the byte
- const uint8_t pixelsInByte = 8;
+ const std::uint8_t pixelsInByte = 8;
- uint8_t pixels = 0;
- uint8_t *outArray = dataOut;
+ std::uint8_t pixels = 0;
+ std::uint8_t *outArray = dataOut;
- for (int32_t inputCol = windowWidthPx - 1; inputCol >= 0; --inputCol) {
- for (int32_t inputRow = windowHeightPx - 1; inputRow >= 7; inputRow -= pixelsInByte) {
+ for (std::int32_t inputCol = windowWidthPx - 1; inputCol >= 0; --inputCol) {
+ for (std::int32_t inputRow = windowHeightPx - 1; inputRow >= 7; inputRow -= pixelsInByte) {
// HACK: Did not create the loop for accessing pixels and merging them in the single byte for better
// performance.
// Wanted to avoid unneeded loop count increasing and jump operations which for large amount of data
// take considerable amount of time.
- uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
+ std::uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
// Use the LUT to convert the input pixel from 4bpp to 1bpp
- uint8_t firstPixel = s_einkMaskLut_1Bpp[dataIn[index - 0 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t secondPixel = s_einkMaskLut_1Bpp[dataIn[index - 1 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t thirdPixel = s_einkMaskLut_1Bpp[dataIn[index - 2 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t fourthPixel = s_einkMaskLut_1Bpp[dataIn[index - 3 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t fifthPixel = s_einkMaskLut_1Bpp[dataIn[index - 4 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t sixthPixel = s_einkMaskLut_1Bpp[dataIn[index - 5 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t seventhPixel = s_einkMaskLut_1Bpp[dataIn[index - 6 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t eightPixel = s_einkMaskLut_1Bpp[dataIn[index - 7 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t firstPixel = s_einkMaskLut_1Bpp[dataIn[index - 0 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t secondPixel = s_einkMaskLut_1Bpp[dataIn[index - 1 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t thirdPixel = s_einkMaskLut_1Bpp[dataIn[index - 2 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t fourthPixel = s_einkMaskLut_1Bpp[dataIn[index - 3 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t fifthPixel = s_einkMaskLut_1Bpp[dataIn[index - 4 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t sixthPixel = s_einkMaskLut_1Bpp[dataIn[index - 5 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t seventhPixel = s_einkMaskLut_1Bpp[dataIn[index - 6 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t eightPixel = s_einkMaskLut_1Bpp[dataIn[index - 7 * BOARD_EINK_DISPLAY_RES_X]];
// Put the pixels in order: Most left positioned pixel at the most significant side of byte
pixels = (firstPixel << 7) | (secondPixel << 6) | (thirdPixel << 5) | (fourthPixel << 4) |
@@ 1089,26 1059,26 @@ __attribute__((optimize("O1"))) static uint8_t *s_EinkTransformFrameCoordinateSy
return dataOut;
}
-__attribute__((optimize("O1"))) static uint8_t *s_EinkTransformFrameCoordinateSystem_2Bpp(
- const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
+__attribute__((optimize("O1"))) static std::uint8_t *s_EinkTransformFrameCoordinateSystem_2Bpp(
+ const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
EinkDisplayColorMode_e invertColors)
{
// In 2bpp mode there are 4 pixels in the byte
- const uint8_t pixelsInByte = 8;
- uint16_t pixels = 0;
- uint16_t *outArray = (uint16_t *)dataOut;
- uint8_t temp = 0;
+ const std::uint8_t pixelsInByte = 8;
+ std::uint16_t pixels = 0;
+ std::uint16_t *outArray = (std::uint16_t *)dataOut;
+ std::uint8_t temp = 0;
- for (int32_t inputCol = windowWidthPx - 1; inputCol >= 0; --inputCol) {
- for (int32_t inputRow = windowHeightPx - 1; inputRow >= 7; inputRow -= pixelsInByte) {
+ for (std::int32_t inputCol = windowWidthPx - 1; inputCol >= 0; --inputCol) {
+ for (std::int32_t inputRow = windowHeightPx - 1; inputRow >= 7; inputRow -= pixelsInByte) {
// HACK: Did not create the loop for accessing pixels and merging them in the single byte for better
// performance.
// Wanted to avoid unneeded loop count increasing and jump operations which for large amount of data
// take considerable amount of time.
- uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
+ std::uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
// Use the LUT to convert the input pixel from 4bpp to 2bpp and put 4 pixels in single byte
temp = (s_einkMaskLut_2Bpp[dataIn[index - 0 * BOARD_EINK_DISPLAY_RES_X]] << 6);
@@ 1140,47 1110,47 @@ __attribute__((optimize("O1"))) static uint8_t *s_EinkTransformFrameCoordinateSy
return dataOut;
}
-__attribute__((optimize("O1"))) static uint8_t *s_EinkTransformFrameCoordinateSystem_3Bpp(
- const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
+__attribute__((optimize("O1"))) static std::uint8_t *s_EinkTransformFrameCoordinateSystem_3Bpp(
+ const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
EinkDisplayColorMode_e invertColors)
{
// The 4bpp is coded the same way as the 3bpp
return s_EinkTransformFrameCoordinateSystem_4Bpp(dataIn, windowWidthPx, windowHeightPx, dataOut, invertColors);
}
-__attribute__((optimize("O1"))) static uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_1Bpp(
- const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
+__attribute__((optimize("O1"))) static std::uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_1Bpp(
+ const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
EinkDisplayColorMode_e invertColors)
{
// In 1bpp mode there are 8 pixels in the byte
- const uint8_t pixelsInByte = 8;
- uint8_t pixels = 0;
- uint8_t *outArray = dataOut;
+ const std::uint8_t pixelsInByte = 8;
+ std::uint8_t pixels = 0;
+ std::uint8_t *outArray = dataOut;
- for (int32_t inputCol = windowWidthPx - 1; inputCol >= 0; --inputCol) {
- for (int32_t inputRow = windowHeightPx - 1; inputRow >= 7; inputRow -= pixelsInByte) {
+ for (std::int32_t inputCol = windowWidthPx - 1; inputCol >= 0; --inputCol) {
+ for (std::int32_t inputRow = windowHeightPx - 1; inputRow >= 7; inputRow -= pixelsInByte) {
// HACK: Did not create the loop for accessing pixels and merging them in the single byte for better
// performance.
// Wanted to avoid unneeded loop count increasing and jump operations which for large amount of data
// take considerable amount of time.
- uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
+ std::uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
// Use the LUT to convert the input pixel from 4bpp to 1bpp
- uint8_t firstPixel = s_einkMaskLut_1Bpp[dataIn[index - 0 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t secondPixel = s_einkMaskLut_1Bpp[dataIn[index - 1 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t thirdPixel = s_einkMaskLut_1Bpp[dataIn[index - 2 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t fourthPixel = s_einkMaskLut_1Bpp[dataIn[index - 3 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t fifthPixel = s_einkMaskLut_1Bpp[dataIn[index - 4 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t sixthPixel = s_einkMaskLut_1Bpp[dataIn[index - 5 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t seventhPixel = s_einkMaskLut_1Bpp[dataIn[index - 6 * BOARD_EINK_DISPLAY_RES_X]];
- uint8_t eightPixel = s_einkMaskLut_1Bpp[dataIn[index - 7 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t firstPixel = s_einkMaskLut_1Bpp[dataIn[index - 0 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t secondPixel = s_einkMaskLut_1Bpp[dataIn[index - 1 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t thirdPixel = s_einkMaskLut_1Bpp[dataIn[index - 2 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t fourthPixel = s_einkMaskLut_1Bpp[dataIn[index - 3 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t fifthPixel = s_einkMaskLut_1Bpp[dataIn[index - 4 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t sixthPixel = s_einkMaskLut_1Bpp[dataIn[index - 5 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t seventhPixel = s_einkMaskLut_1Bpp[dataIn[index - 6 * BOARD_EINK_DISPLAY_RES_X]];
+ std::uint8_t eightPixel = s_einkMaskLut_1Bpp[dataIn[index - 7 * BOARD_EINK_DISPLAY_RES_X]];
// Put the pixels in order: Most left positioned pixel at the most significant side of byte
pixels = (firstPixel << 7) | (secondPixel << 6) | (thirdPixel << 5) | (fourthPixel << 4) |
@@ 1198,25 1168,25 @@ __attribute__((optimize("O1"))) static uint8_t *s_EinkTransformAnimationFrameCoo
return dataOut;
}
-__attribute__((optimize("O1"))) static uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_2Bpp(
- const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
+__attribute__((optimize("O1"))) static std::uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_2Bpp(
+ const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
EinkDisplayColorMode_e invertColors)
{
// In 2bpp mode there are 4 pixels in the byte
- const uint8_t pixelsInByte = 8;
- uint16_t pixels = 0;
- uint16_t *outArray = (uint16_t *)dataOut;
- uint8_t temp = 0;
- for (int32_t inputCol = windowWidthPx - 1; inputCol >= 0; --inputCol) {
- for (int32_t inputRow = windowHeightPx - 1; inputRow >= 7; inputRow -= pixelsInByte) {
+ const std::uint8_t pixelsInByte = 8;
+ std::uint16_t pixels = 0;
+ std::uint16_t *outArray = (std::uint16_t *)dataOut;
+ std::uint8_t temp = 0;
+ for (std::int32_t inputCol = windowWidthPx - 1; inputCol >= 0; --inputCol) {
+ for (std::int32_t inputRow = windowHeightPx - 1; inputRow >= 7; inputRow -= pixelsInByte) {
// HACK: Did not create the loop for accessing pixels and merging them in the single byte for better
// performance.
// Wanted to avoid unneeded loop count increasing and jump operations which for large amount of data
// take considerable amount of time.
- uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
+ std::uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
// Use the LUT to convert the input pixel from 4bpp to 2bpp and put 4 pixels in single byte
temp = (s_einkMaskLut_2Bpp[dataIn[index - 0 * BOARD_EINK_DISPLAY_RES_X]] << 6);
@@ 1247,46 1217,46 @@ __attribute__((optimize("O1"))) static uint8_t *s_EinkTransformAnimationFrameCoo
return dataOut;
}
-__attribute__((optimize("O3"))) static uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_3Bpp(
- const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
+__attribute__((optimize("O3"))) static std::uint8_t *s_EinkTransformAnimationFrameCoordinateSystem_3Bpp(
+ const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
EinkDisplayColorMode_e invertColors)
{
// The 4bpp is coded the same way as the 3bpp
return s_EinkTransformFrameCoordinateSystem_4Bpp(dataIn, windowWidthPx, windowHeightPx, dataOut, invertColors);
}
-__attribute__((optimize("O1"))) static uint8_t *s_EinkTransformFrameCoordinateSystem_4Bpp(
- const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
+__attribute__((optimize("O1"))) static std::uint8_t *s_EinkTransformFrameCoordinateSystem_4Bpp(
+ const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
EinkDisplayColorMode_e invertColors)
{
// In 3bpp and 4bpp modes there are 2 pixels in the byte. Using 8bpp to process the whole uint32_t at once for
// faster execution
- const uint8_t pixelsInByte = 8;
+ const std::uint8_t pixelsInByte = 8;
- uint32_t pixels = 0;
- uint32_t *outArray = (uint32_t *)dataOut;
+ std::uint32_t pixels = 0;
+ std::uint32_t *outArray = (std::uint32_t *)dataOut;
- for (int32_t inputCol = windowWidthPx - 1; inputCol >= 0; --inputCol) {
- for (int32_t inputRow = windowHeightPx - 1; inputRow >= 7; inputRow -= pixelsInByte) {
+ for (std::int32_t inputCol = windowWidthPx - 1; inputCol >= 0; --inputCol) {
+ for (std::int32_t inputRow = windowHeightPx - 1; inputRow >= 7; inputRow -= pixelsInByte) {
// HACK: Did not create the loop for accessing pixels and merging them in the single byte for better
// performance.
// Wanted to avoid unneeded loop count increasing and jump operations which for large amount of data
// take considerable amount of time. Using 8 pixels at a time for better performance
- uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
+ std::uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
- uint8_t firstPixelPair =
+ std::uint8_t firstPixelPair =
(dataIn[index - 0 * BOARD_EINK_DISPLAY_RES_X] << 4) | dataIn[index - 1 * BOARD_EINK_DISPLAY_RES_X];
- uint8_t secondPixelPair =
+ std::uint8_t secondPixelPair =
(dataIn[index - 2 * BOARD_EINK_DISPLAY_RES_X] << 4) | dataIn[index - 3 * BOARD_EINK_DISPLAY_RES_X];
- uint8_t thirdPixelPair =
+ std::uint8_t thirdPixelPair =
(dataIn[index - 4 * BOARD_EINK_DISPLAY_RES_X] << 4) | dataIn[index - 5 * BOARD_EINK_DISPLAY_RES_X];
- uint8_t fourthPixelPair =
+ std::uint8_t fourthPixelPair =
(dataIn[index - 6 * BOARD_EINK_DISPLAY_RES_X] << 4) | dataIn[index - 7 * BOARD_EINK_DISPLAY_RES_X];
// Put the pixels in the uint32_t for faster processing
@@ 1305,21 1275,21 @@ __attribute__((optimize("O1"))) static uint8_t *s_EinkTransformFrameCoordinateSy
return dataOut;
}
-__attribute__((optimize("O1"))) static uint8_t *s_EinkTransformFrameCoordinateSystemNoRotation_4Bpp(
- const uint8_t *dataIn,
- uint16_t windowWidthPx,
- uint16_t windowHeightPx,
- uint8_t *dataOut,
+__attribute__((optimize("O1"))) static std::uint8_t *s_EinkTransformFrameCoordinateSystemNoRotation_4Bpp(
+ const std::uint8_t *dataIn,
+ std::uint16_t windowWidthPx,
+ std::uint16_t windowHeightPx,
+ std::uint8_t *dataOut,
EinkDisplayColorMode_e invertColors)
{
// In 3bpp and 4bpp modes there are 2 pixels in the byte. Using 8bpp to process the whole uint32_t at once for
// faster execution
- const uint8_t pixelsInByte = 8;
+ const std::uint8_t pixelsInByte = 8;
- uint32_t pixels = 0;
- uint32_t *outArray = (uint32_t *)dataOut;
- int32_t inputRow = 0;
- int32_t inputCol = 0;
+ std::uint32_t pixels = 0;
+ std::uint32_t *outArray = (std::uint32_t *)dataOut;
+ std::int32_t inputRow = 0;
+ std::int32_t inputCol = 0;
for (inputRow = 0; inputRow < windowHeightPx; ++inputRow) {
for (inputCol = windowWidthPx - 7; inputCol >= 0; inputCol -= pixelsInByte) {
@@ 1327,13 1297,13 @@ __attribute__((optimize("O1"))) static uint8_t *s_EinkTransformFrameCoordinateSy
// performance.
// Wanted to avoid unneeded loop count increasing and jump operations which for large amount of data
// take considerable amount of time. Using 8 pixels at a time for better performance
- uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
+ std::uint32_t index = inputRow * BOARD_EINK_DISPLAY_RES_X + inputCol;
// Get 4x 2 adjacent pixels to process them as uint32_t for better execution timings
- uint8_t firstPixelPair = (dataIn[index]) | (dataIn[index + 1] << 4);
- uint8_t secondPixelPair = (dataIn[index + 2]) | (dataIn[index + 3] << 4);
- uint8_t thirdPixelPair = (dataIn[index + 4]) | (dataIn[index + 5] << 4);
- uint8_t fourthPixelPair = (dataIn[index + 6]) | (dataIn[index + 7] << 4);
+ std::uint8_t firstPixelPair = (dataIn[index]) | (dataIn[index + 1] << 4);
+ std::uint8_t secondPixelPair = (dataIn[index + 2]) | (dataIn[index + 3] << 4);
+ std::uint8_t thirdPixelPair = (dataIn[index + 4]) | (dataIn[index + 5] << 4);
+ std::uint8_t fourthPixelPair = (dataIn[index + 6]) | (dataIn[index + 7] << 4);
// Put the pixels in the uint32_t for faster processing
pixels = (firstPixelPair << 24) | (secondPixelPair << 16) | (thirdPixelPair << 8) | (fourthPixelPair);
M module-bsp/board/rt1051/bsp/eink/ED028TC1.h => module-bsp/board/rt1051/bsp/eink/ED028TC1.h +9 -9
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
/**
@@ 14,10 14,6 @@
#ifndef __ED028TC1_H
#define __ED028TC1_H
-/* Includes ------------------------------------------------------------------*/
-#include <stdio.h>
-#include <stdbool.h>
-#include <functional>
#include "FreeRTOS.h"
#include "semphr.h"
@@ 328,22 324,22 @@ extern "C"
* This function returns the state of the EPD siplay powe
* @return 1 if is currently powered on, 0 otherwise
*/
- uint8_t EinkIsPoweredOn();
+ bool EinkIsPoweredOn();
/**
* This function powers on the display. Needed for refreshing, measuring the temperature
*/
- void EinkPowerOn();
+ EinkStatus_e EinkPowerOn();
/**
* This functions powers off the display
*/
- void EinkPowerOff();
+ EinkStatus_e EinkPowerOff();
/**
* @brief This function is responsible for turning eink of and releasing all resources.
*/
- void EinkPowerDown(void);
+ EinkStatus_e EinkPowerDown(void);
/**
* This function measures the ambient temperature using the ED028TC1 display internal temperature sensor.
@@ 433,6 429,10 @@ extern "C"
*/
void EinkARGBToLuminance(const uint8_t *dataIn, uint8_t *dataOut, uint32_t displayWidth, uint32_t displayHeight);
+ /**
+ * This function gets resolutions settings from EINK display
+ */
+ EinkStatus_e EinkGetResolutionSettings();
#if defined(__cplusplus)
}
#endif /* __cplusplus */
M module-bsp/board/rt1051/bsp/eink/EinkDisplay.cpp => module-bsp/board/rt1051/bsp/eink/EinkDisplay.cpp +42 -13
@@ 136,7 136,9 @@ namespace hal::eink
EinkStatus EinkDisplay::prepareDisplay(const EinkRefreshMode refreshMode, const WaveformTemperature behaviour)
{
- powerOn();
+ if (const auto status = reinitAndPowerOn(); status != EinkStatus::EinkOK) {
+ return status;
+ }
const auto temperature =
behaviour == WaveformTemperature::KEEP_CURRENT ? getLastTemperature() : EinkGetTemperatureInternal();
@@ 144,7 146,9 @@ namespace hal::eink
if (refreshMode == EinkRefreshMode::REFRESH_DEEP) {
auto status = setWaveform(EinkWaveforms_e::EinkWaveformGC16, temperature);
if (status == EinkStatus::EinkOK) {
- dither();
+ if (const auto ditherStatus = dither(); ditherStatus != EinkStatus::EinkOK) {
+ return ditherStatus;
+ }
}
return status;
}
@@ 173,7 177,9 @@ namespace hal::eink
EinkStatus EinkDisplay::showImageUpdate(const std::vector<EinkFrame> &updateFrames, const std::uint8_t *frameBuffer)
{
- powerOn();
+ if (const auto status = reinitAndPowerOn(); status != EinkStatus::EinkOK) {
+ return status;
+ }
for (const EinkFrame &frame : updateFrames) {
const std::uint8_t *buffer = frameBuffer + frame.pos_y * frame.size.width;
@@ 233,35 239,43 @@ namespace hal::eink
return translateStatus(EinkResetAndInitialize());
}
- void EinkDisplay::dither()
+ EinkStatus EinkDisplay::dither()
{
- EinkDitherDisplay();
+ return translateStatus(EinkDitherDisplay());
}
- void EinkDisplay::powerOn()
+ EinkStatus EinkDisplay::powerOn()
{
if (driverLPSPI) {
driverLPSPI->Enable();
}
- EinkPowerOn();
+ return translateStatus(EinkPowerOn());
}
- void EinkDisplay::powerOff()
+ EinkStatus EinkDisplay::powerOff()
{
- EinkPowerOff();
+ const auto status = translateStatus(EinkPowerOff());
if (driverLPSPI) {
driverLPSPI->Disable();
}
+ return status;
}
- void EinkDisplay::shutdown()
+ EinkStatus EinkDisplay::shutdown()
{
- EinkPowerDown();
+ const auto status = translateStatus(EinkPowerDown());
+ if (driverLPSPI) {
+ driverLPSPI->Disable();
+ }
+ return status;
}
- void EinkDisplay::wipeOut()
+ EinkStatus EinkDisplay::wipeOut()
{
- EinkFillScreenWithColor(EinkDisplayColorFilling_e::EinkDisplayColorWhite);
+ if (const auto status = reinitAndPowerOn(); status != EinkStatus::EinkOK) {
+ return status;
+ }
+ return translateStatus(EinkFillScreenWithColor(EinkDisplayColorFilling_e::EinkDisplayColorWhite));
}
EinkBpp_e EinkDisplay::getCurrentBitsPerPixelFormat() const noexcept
@@ 303,6 317,7 @@ namespace hal::eink
EinkStatus EinkDisplay::setWaveform(const EinkWaveforms_e mode, const std::int32_t temperature)
{
if (!isNewWaveformNeeded(mode, temperature)) {
+ EinkUpdateWaveform(¤tWaveform);
return EinkStatus::EinkOK;
}
@@ 382,4 397,18 @@ namespace hal::eink
return std::make_unique<EinkDisplay>(size);
}
+ EinkStatus EinkDisplay::reinitAndPowerOn()
+ {
+ if (EinkIsPoweredOn()) {
+ return EinkStatus::EinkOK;
+ }
+ if (resetAndInit() != EinkStatus::EinkOK) {
+ return EinkStatus::EinkError;
+ }
+ if (powerOn() != EinkStatus::EinkOK) {
+ return EinkStatus::EinkError;
+ }
+ return EinkStatus::EinkOK;
+ }
+
} // namespace hal::eink
M module-bsp/board/rt1051/bsp/eink/EinkDisplay.hpp => module-bsp/board/rt1051/bsp/eink/EinkDisplay.hpp +6 -5
@@ 38,11 38,12 @@ namespace hal::eink
void prepareEarlyRequest(EinkRefreshMode refreshMode, const WaveformTemperature behaviour) override;
EinkStatus resetAndInit() override;
- void dither() override;
- void powerOn() override;
- void powerOff() override;
- void shutdown() override;
- void wipeOut() override;
+ EinkStatus dither() override;
+ EinkStatus powerOn() override;
+ EinkStatus powerOff() override;
+ EinkStatus shutdown() override;
+ EinkStatus wipeOut() override;
+ EinkStatus reinitAndPowerOn() override;
[[nodiscard]] auto getDevice() const noexcept -> std::shared_ptr<devices::Device> override;
M module-bsp/board/rt1051/bsp/eink/bsp_eink.cpp => module-bsp/board/rt1051/bsp/eink/bsp_eink.cpp +69 -59
@@ 2,18 2,17 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "bsp_eink.h"
+
#include "board.h"
#include "fsl_lpspi.h"
#include "fsl_lpspi_edma.h"
-#include "fsl_common.h"
+
#include "dma_config.h"
#include "bsp/eink/eink_gpio.hpp"
#include "FreeRTOS.h"
#include "semphr.h"
-#include "queue.h"
-#include "drivers/pll/DriverPLL.hpp"
#include "drivers/dmamux/DriverDMAMux.hpp"
#include "drivers/dma/DriverDMA.hpp"
#include "drivers/gpio/DriverGPIO.hpp"
@@ 39,12 38,12 @@ typedef enum
typedef const struct _lpspi_edma_resource
{
DMA_Type *txEdmaBase;
- uint32_t txEdmaChannel;
- uint8_t txDmaRequest;
+ std::uint32_t txEdmaChannel;
+ std::uint8_t txDmaRequest;
DMA_Type *rxEdmaBase;
- uint32_t rxEdmaChannel;
- uint8_t rxDmaRequest;
+ std::uint32_t rxEdmaChannel;
+ std::uint8_t rxDmaRequest;
#if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT)
DMAMUX_Type *txDmamuxBase;
@@ 55,8 54,8 @@ typedef const struct _lpspi_edma_resource
typedef const struct _lpspi_resource
{
LPSPI_Type *base;
- uint32_t instance;
- uint32_t (*GetFreq)(void);
+ std::uint32_t instance;
+ std::uint32_t (*GetFreq)(void);
} lpspi_resource_t;
typedef struct _bsp_eink_driver
@@ 66,8 65,8 @@ typedef struct _bsp_eink_driver
lpspi_master_edma_handle_t *handle;
edma_handle_t *edmaRxRegToRxDataHandle;
edma_handle_t *edmaTxDataToTxRegHandle;
- uint32_t baudRate_Bps;
- uint8_t flags; /*!< Control and state flags. */
+ std::uint32_t baudRate_Bps;
+ std::uint8_t flags; /*!< Control and state flags. */
bsp_eink_BusyEvent event;
/* Current transfer chip select configuration( automatic of manual ) */
@@ 77,16 76,18 @@ typedef struct _bsp_eink_driver
} bsp_eink_driver_t;
-using namespace drivers;
-static lpspi_master_config_t s_eink_lpspi_master_config;
-static std::shared_ptr<drivers::DriverGPIO> gpio;
-static std::shared_ptr<drivers::DriverPLL> pll;
-static std::shared_ptr<drivers::DriverDMA> dma;
-static std::shared_ptr<drivers::DriverDMAMux> dmamux;
-static std::unique_ptr<drivers::DriverDMAHandle> rxDMAHandle;
-static std::unique_ptr<drivers::DriverDMAHandle> txDMAHandle;
-
-static uint32_t BSP_EINK_LPSPI_GetFreq(void)
+namespace
+{
+ using namespace drivers;
+ static lpspi_master_config_t s_eink_lpspi_master_config;
+ static std::shared_ptr<drivers::DriverGPIO> gpio;
+ static std::shared_ptr<drivers::DriverDMA> dma;
+ static std::shared_ptr<drivers::DriverDMAMux> dmamux;
+ static std::unique_ptr<drivers::DriverDMAHandle> rxDMAHandle;
+ static std::unique_ptr<drivers::DriverDMAHandle> txDMAHandle;
+} // namespace
+
+static std::uint32_t BSP_EINK_LPSPI_GetFreq(void)
{
return GetPerphSourceClock(PerphClock_LPSPI);
}
@@ 120,6 121,8 @@ static bsp_eink_driver_t BSP_EINK_LPSPI_EdmaDriverState = {
EventWaitRegistered,
};
+static bool bsp_eink_IsInitialised = false;
+
static SemaphoreHandle_t bsp_eink_TransferComplete;
static SemaphoreHandle_t bsp_eink_busySemaphore; // This semaphore suspends the task until the EPD display is busy
@@ 146,6 149,9 @@ static void s_LPSPI_MasterEdmaCallback(LPSPI_Type *base,
status_t BSP_EinkInit(bsp_eink_BusyEvent event)
{
+ if (bsp_eink_IsInitialised) {
+ return kStatus_Success;
+ }
bsp_eink_driver_t *lpspi = &BSP_EINK_LPSPI_EdmaDriverState;
// lpspi_edma_resource_t *dmaResource = lpspi->dmaResource;
@@ 169,7 175,7 @@ status_t BSP_EinkInit(bsp_eink_BusyEvent event)
}
// Create new queue
- bsp_eink_TransferComplete = xQueueCreate(1, sizeof(uint32_t));
+ bsp_eink_TransferComplete = xQueueCreate(1, sizeof(std::uint32_t));
if (bsp_eink_TransferComplete == NULL) {
vSemaphoreDelete(bsp_eink_busySemaphore);
bsp_eink_busySemaphore = NULL;
@@ 206,11 212,11 @@ status_t BSP_EinkInit(bsp_eink_BusyEvent event)
dmamux = DriverDMAMux::Create(static_cast<DMAMuxInstances>(BoardDefinitions::EINK_DMAMUX), DriverDMAMuxParams{});
dma = DriverDMA::Create(static_cast<DMAInstances>(BoardDefinitions::EINK_DMA), DriverDMAParams{});
- txDMAHandle = dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions::EINK_TX_DMA_CHANNEL));
- rxDMAHandle = dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions::EINK_RX_DMA_CHANNEL));
- dmamux->Enable(static_cast<uint32_t>(BoardDefinitions::EINK_TX_DMA_CHANNEL),
+ txDMAHandle = dma->CreateHandle(static_cast<std::uint32_t>(BoardDefinitions::EINK_TX_DMA_CHANNEL));
+ rxDMAHandle = dma->CreateHandle(static_cast<std::uint32_t>(BoardDefinitions::EINK_RX_DMA_CHANNEL));
+ dmamux->Enable(static_cast<std::uint32_t>(BoardDefinitions::EINK_TX_DMA_CHANNEL),
BSP_EINK_LPSPI_DMA_TX_PERI_SEL); // TODO: M.P fix BSP_EINK_LPSPI_DMA_TX_PERI_SEL
- dmamux->Enable(static_cast<uint32_t>(BoardDefinitions::EINK_RX_DMA_CHANNEL),
+ dmamux->Enable(static_cast<std::uint32_t>(BoardDefinitions::EINK_RX_DMA_CHANNEL),
BSP_EINK_LPSPI_DMA_RX_PERI_SEL); // TODO: M.P fix BSP_EINK_LPSPI_DMA_RX_PERI_SEL
BSP_EINK_LPSPI_EdmaDriverState.edmaTxDataToTxRegHandle =
@@ 226,11 232,16 @@ status_t BSP_EinkInit(bsp_eink_BusyEvent event)
lpspi->edmaRxRegToRxDataHandle,
lpspi->edmaTxDataToTxRegHandle);
+ bsp_eink_IsInitialised = true;
+
return kStatus_Success;
}
void BSP_EinkDeinit(void)
{
+ if (!bsp_eink_IsInitialised) {
+ return;
+ }
LPSPI_Enable(BSP_EINK_LPSPI_BASE, false);
if (bsp_eink_busySemaphore != NULL) {
@@ 243,17 254,16 @@ void BSP_EinkDeinit(void)
bsp_eink_TransferComplete = NULL;
}
- pll.reset();
-
- dmamux->Disable(static_cast<uint32_t>(BoardDefinitions::EINK_TX_DMA_CHANNEL));
- dmamux->Disable(static_cast<uint32_t>(BoardDefinitions::EINK_RX_DMA_CHANNEL));
-
- dma.reset();
+ dmamux->Disable(static_cast<std::uint32_t>(BoardDefinitions::EINK_TX_DMA_CHANNEL));
+ dmamux->Disable(static_cast<std::uint32_t>(BoardDefinitions::EINK_RX_DMA_CHANNEL));
dmamux.reset();
+ dma.reset();
- gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
- gpio->ClearPortInterrupts(1 << static_cast<uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
+ gpio->DisableInterrupt(1 << static_cast<std::uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
+ gpio->ClearPortInterrupts(1 << static_cast<std::uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
gpio.reset();
+
+ bsp_eink_IsInitialised = false;
}
void BSP_EinkLogicPowerOn()
@@ 266,9 276,9 @@ void BSP_EinkLogicPowerOff()
bsp::eink::eink_gpio_power_off();
}
-status_t BSP_EinkChangeSpiFrequency(uint32_t frequencyHz)
+status_t BSP_EinkChangeSpiFrequency(std::uint32_t frequencyHz)
{
- uint32_t tcrPrescalerValue = 0;
+ std::uint32_t tcrPrescalerValue = 0;
LPSPI_Enable(BSP_EINK_LPSPI_BASE, false);
LPSPI_MasterSetBaudRate(
@@ 284,10 294,10 @@ status_t BSP_EinkChangeSpiFrequency(uint32_t frequencyHz)
return 0;
}
-status_t BSP_EinkWriteData(void *txBuffer, uint32_t len, eink_spi_cs_config_e cs)
+status_t BSP_EinkWriteData(void *txBuffer, std::uint32_t len, eink_spi_cs_config_e cs)
{
- const uint32_t TX_TIMEOUT_MS = 2000;
- status_t tx_status = 0;
+ constexpr std::uint32_t TX_TIMEOUT_MS = 2000;
+ status_t tx_status = -1;
status_t status;
lpspi_transfer_t xfer = {};
@@ 295,9 305,9 @@ status_t BSP_EinkWriteData(void *txBuffer, uint32_t len, eink_spi_cs_config_e cs
BSP_EinkWriteCS(BSP_Eink_CS_Clr);
}
- const uint8_t loopCnt = (len / (DMA_MAX_SINGLE_TRANSACTION_PAYLOAD + 1)) + 1;
- uint32_t frameSize = 0;
- uint32_t bytesSent = 0;
+ const std::uint8_t loopCnt = (len / (DMA_MAX_SINGLE_TRANSACTION_PAYLOAD + 1)) + 1;
+ std::uint32_t frameSize = 0;
+ std::uint32_t bytesSent = 0;
// Increase the SPI frequency to the SPI WRITE value
BSP_EinkChangeSpiFrequency(BSP_EINK_TRANSFER_WRITE_CLOCK);
@@ 308,15 318,15 @@ status_t BSP_EinkWriteData(void *txBuffer, uint32_t len, eink_spi_cs_config_e cs
// Clean the TX complete queue
xQueueReset(bsp_eink_TransferComplete);
// Clear the BUSY Pin IRQ Flag
- gpio->ClearPortInterrupts(1 << static_cast<uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
+ gpio->ClearPortInterrupts(1 << static_cast<std::uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
// Enable the BUSY Pin IRQ
- gpio->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
+ gpio->EnableInterrupt(1 << static_cast<std::uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
// Take the BUSY semaphore without timeout just in case the transmission makes the BUSY pin state change. It
// enables the driver to block then on the bsp_eink_busySemaphore until the BUSY pin is deasserted
xSemaphoreTake(bsp_eink_busySemaphore, 0);
// The MAJOR loop of the DMA can be maximum of value 32767
- for (uint8_t i = 0; i < loopCnt; ++i) {
+ for (std::uint8_t i = 0; i < loopCnt; ++i) {
if (len > DMA_MAX_SINGLE_TRANSACTION_PAYLOAD) {
frameSize = DMA_MAX_SINGLE_TRANSACTION_PAYLOAD;
}
@@ 325,7 335,7 @@ status_t BSP_EinkWriteData(void *txBuffer, uint32_t len, eink_spi_cs_config_e cs
}
xfer.rxData = NULL;
- xfer.txData = (uint8_t *)txBuffer + bytesSent;
+ xfer.txData = (std::uint8_t *)txBuffer + bytesSent;
xfer.dataSize = frameSize;
xfer.configFlags = /*RTE_SPI1_MASTER_PCS_PIN_SEL |*/ kLPSPI_MasterByteSwap | kLPSPI_MasterPcsContinuous;
@@ 365,15 375,15 @@ status_t BSP_EinkWriteData(void *txBuffer, uint32_t len, eink_spi_cs_config_e cs
return tx_status;
}
-status_t BSP_EinkReadData(void *rxBuffer, uint32_t len, eink_spi_cs_config_e cs)
+status_t BSP_EinkReadData(void *rxBuffer, std::uint32_t len, eink_spi_cs_config_e cs)
{
const int RX_TIMEOUT_MS = 2000;
- status_t tx_status = 0;
+ status_t tx_status = -1;
status_t status;
lpspi_transfer_t xfer = {};
xfer.txData = NULL;
- xfer.rxData = (uint8_t *)rxBuffer;
+ xfer.rxData = (std::uint8_t *)rxBuffer;
xfer.dataSize = len;
xfer.configFlags = /*RTE_SPI1_MASTER_PCS_PIN_SEL |*/ kLPSPI_MasterByteSwap | kLPSPI_MasterPcsContinuous;
@@ 390,9 400,9 @@ status_t BSP_EinkReadData(void *rxBuffer, uint32_t len, eink_spi_cs_config_e cs)
// Clean the TX complete queue
xQueueReset(bsp_eink_TransferComplete);
// Clear the BUSY Pin IRQ Flag
- gpio->ClearPortInterrupts(1 << static_cast<uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
+ gpio->ClearPortInterrupts(1 << static_cast<std::uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
// Enable the BUSY Pin IRQ
- gpio->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
+ gpio->EnableInterrupt(1 << static_cast<std::uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
// Take the BUSY semaphore without timeout just in case the transmission makes the BUSY pin state change. It
// enables the driver to block then on the bsp_eink_busySemaphore until the BUSY pin is deasserted
xSemaphoreTake(bsp_eink_busySemaphore, 0);
@@ 401,7 411,7 @@ status_t BSP_EinkReadData(void *rxBuffer, uint32_t len, eink_spi_cs_config_e cs)
BSP_EINK_LPSPI_EdmaDriverState.resource->base, BSP_EINK_LPSPI_EdmaDriverState.handle, &xfer);
if (status != kStatus_Success) {
// in case of error just flush transfer complete queue
- uint32_t dummy = 0;
+ std::uint32_t dummy = 0;
xQueueReceive(bsp_eink_TransferComplete, &dummy, 0);
if (cs == SPI_AUTOMATIC_CS) {
BSP_EinkWriteCS(BSP_Eink_CS_Set);
@@ 427,9 437,9 @@ status_t BSP_EinkReadData(void *rxBuffer, uint32_t len, eink_spi_cs_config_e cs)
return tx_status;
}
-uint8_t BSP_EinkWaitUntilDisplayBusy(uint32_t timeout)
+std::uint8_t BSP_EinkWaitUntilDisplayBusy(std::uint32_t timeout)
{
- uint8_t ret = 0;
+ std::uint8_t ret = 0;
BSP_EINK_LPSPI_EdmaDriverState.eventRegister = EventWaitRegistered;
if (xSemaphoreTake(bsp_eink_busySemaphore, timeout) != pdPASS) {
ret = 0;
@@ 447,19 457,19 @@ void BSP_EinkResetDisplayController(void)
{
BSP_EinkWriteCS(BSP_Eink_CS_Set);
- gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::EINK_RESET_PIN), 0);
+ gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::EINK_RESET_PIN), 0);
vTaskDelay(10);
- gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::EINK_RESET_PIN), 1);
+ gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::EINK_RESET_PIN), 1);
vTaskDelay(10);
}
void BSP_EinkWriteCS(bsp_eink_cs_ctrl_t ctrl)
{
if (ctrl == BSP_Eink_CS_Clr) {
- gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::EINK_CS_PIN), 0);
+ gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::EINK_CS_PIN), 0);
}
else if (ctrl == BSP_Eink_CS_Set) {
- gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::EINK_CS_PIN), 1);
+ gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::EINK_CS_PIN), 1);
}
}
@@ 469,7 479,7 @@ BaseType_t BSP_EinkBusyPinStateChangeHandler(void)
/* Give semaphore only if something is waiting on it */
if (BSP_EINK_LPSPI_EdmaDriverState.eventRegister == EventWaitRegistered) {
- gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
+ gpio->DisableInterrupt(1 << static_cast<std::uint32_t>(BoardDefinitions::EINK_BUSY_PIN));
if (xSemaphoreGiveFromISR(bsp_eink_busySemaphore, &xHigherPriorityTaskWoken) != pdPASS) {
// shouldn't get here!
M module-bsp/board/rt1051/bsp/eink/bsp_eink.h => module-bsp/board/rt1051/bsp/eink/bsp_eink.h +2 -2
@@ 4,7 4,7 @@
#ifndef EINK_BSP_EINK_H_
#define EINK_BSP_EINK_H_
-#include <stdint.h>
+#include <cstdint>
#include "fsl_common.h"
#include "FreeRTOS.h"
@@ 36,7 36,7 @@ extern "C"
void BSP_EinkLogicPowerOff();
void BSP_EinkWriteCS(bsp_eink_cs_ctrl_t ctrl);
- uint8_t BSP_EinkWaitUntilDisplayBusy(uint32_t timeout);
+ std::uint8_t BSP_EinkWaitUntilDisplayBusy(std::uint32_t timeout);
void BSP_EinkResetDisplayController(void);
status_t BSP_EinkChangeSpiFrequency(uint32_t frequencyHz);
M module-bsp/drivers/pll/DriverPLL.cpp => module-bsp/drivers/pll/DriverPLL.cpp +4 -4
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "DriverPLL.hpp"
@@ 14,7 14,7 @@
namespace drivers
{
- std::weak_ptr<DriverPLL> DriverPLL::singleton[static_cast<uint32_t>(PLLInstances::COUNT)];
+ std::weak_ptr<DriverPLL> DriverPLL::singleton[static_cast<std::uint32_t>(PLLInstances::COUNT)];
std::shared_ptr<DriverPLL> DriverPLL::Create(const drivers::PLLInstances instance,
const drivers::DriverPLLParams ¶ms)
@@ 22,7 22,7 @@ namespace drivers
{
cpp_freertos::CriticalSection::Enter();
- std::shared_ptr<DriverPLL> inst = singleton[static_cast<uint32_t>(instance)].lock();
+ std::shared_ptr<DriverPLL> inst = singleton[static_cast<std::uint32_t>(instance)].lock();
if (!inst) {
#if defined(TARGET_RT1051)
@@ 32,7 32,7 @@ namespace drivers
#error "Unsupported target"
#endif
- singleton[static_cast<uint32_t>(instance)] = inst;
+ singleton[static_cast<std::uint32_t>(instance)] = inst;
}
cpp_freertos::CriticalSection::Exit();
M module-bsp/drivers/pll/DriverPLL.hpp => module-bsp/drivers/pll/DriverPLL.hpp +3 -5
@@ 1,8 1,7 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#ifndef PUREPHONE_DRIVERPLL_HPP
-#define PUREPHONE_DRIVERPLL_HPP
+#pragma once
#include <memory>
#include <cstdint>
@@ 44,9 43,8 @@ namespace drivers
const DriverPLLParams parameters;
private:
- static std::weak_ptr<DriverPLL> singleton[static_cast<uint32_t>(PLLInstances::COUNT)];
+ static std::weak_ptr<DriverPLL> singleton[static_cast<std::uint32_t>(PLLInstances::COUNT)];
};
} // namespace drivers
-#endif // PUREPHONE_DRIVERPLL_HPP
M module-bsp/hal/include/hal/eink/AbstractEinkDisplay.hpp => module-bsp/hal/include/hal/eink/AbstractEinkDisplay.hpp +7 -6
@@ 77,14 77,15 @@ namespace hal::eink
const EinkFrame &refreshFrame,
const std::uint8_t *frameBuffer,
const EinkRefreshMode refreshMode) = 0;
- virtual void prepareEarlyRequest(EinkRefreshMode refreshMode, const WaveformTemperature behaviour) = 0;
+ virtual void prepareEarlyRequest(EinkRefreshMode refreshMode, const WaveformTemperature behaviour) = 0;
- virtual void dither() = 0;
- virtual void powerOn() = 0;
- virtual void powerOff() = 0;
- virtual void shutdown() = 0;
- virtual void wipeOut() = 0;
+ virtual EinkStatus dither() = 0;
+ virtual EinkStatus powerOn() = 0;
+ virtual EinkStatus powerOff() = 0;
+ virtual EinkStatus shutdown() = 0;
+ virtual EinkStatus wipeOut() = 0;
virtual EinkStatus resetAndInit() = 0;
virtual std::shared_ptr<devices::Device> getDevice() const noexcept = 0;
+ virtual EinkStatus reinitAndPowerOn() = 0;
};
} // namespace hal::eink
M module-services/service-eink/ServiceEink.cpp => module-services/service-eink/ServiceEink.cpp +13 -13
@@ 56,7 56,9 @@ namespace service::eink
{
displayPowerOffTimer = sys::TimerFactory::createSingleShotTimer(
this, "einkDisplayPowerOff", displayPowerOffTimeout, [this](sys::Timer &) {
- display->powerOff();
+ if (display->shutdown() != hal::eink::EinkStatus::EinkOK) {
+ LOG_ERROR("Error during display powerOff.");
+ }
eInkSentinel->ReleaseMinimumFrequency();
});
connect(typeid(EinkModeMessage),
@@ 86,7 88,7 @@ namespace service::eink
sys::ReturnCodes ServiceEink::InitHandler()
{
LOG_INFO("Initializing Eink");
- if (const auto status = display->resetAndInit(); status != hal::eink::EinkStatus::EinkOK) {
+ if (const auto status = display->reinitAndPowerOn(); status != hal::eink::EinkStatus::EinkOK) {
LOG_FATAL("Error: Could not initialize Eink display!");
return sys::ReturnCodes::Failure;
}
@@ 100,7 102,6 @@ namespace service::eink
const auto sentinelRegistrationMsg = std::make_shared<sys::SentinelRegistrationMessage>(eInkSentinel);
bus.sendUnicast(sentinelRegistrationMsg, service::name::system_manager);
- display->powerOn();
eInkSentinel->HoldMinimumFrequency();
return sys::ReturnCodes::Success;
@@ 117,7 118,7 @@ namespace service::eink
sys::ReturnCodes ServiceEink::DeinitHandler()
{
// Eink must be turned on before wiping out the display
- display->powerOn();
+ display->reinitAndPowerOn();
if ((exitAction == ExitAction::WipeOut) ||
((display->getMode() == hal::eink::EinkDisplayColorMode::EinkDisplayColorModeInverted) &&
@@ 160,20 161,11 @@ namespace service::eink
void ServiceEink::enterActiveMode()
{
setState(State::Running);
-
- if (const auto status = display->resetAndInit(); status != hal::eink::EinkStatus::EinkOK) {
- LOG_FATAL("Error: Could not initialize Eink display!");
- }
- eInkSentinel->HoldMinimumFrequency();
- display->powerOn();
- display->powerOff();
- eInkSentinel->ReleaseMinimumFrequency();
}
void ServiceEink::suspend()
{
setState(State::Suspended);
- display->shutdown();
}
sys::MessagePointer ServiceEink::handleEinkModeChangedMessage(sys::Message *message)
@@ 351,6 343,9 @@ namespace service::eink
previousContext->insert(0, 0, ctx);
}
}
+ if (previousRefreshStatus == RefreshStatus::Failed) {
+ updateFrames.front() = {0, 0, BOARD_EINK_DISPLAY_RES_X, BOARD_EINK_DISPLAY_RES_Y};
+ }
// If parts of the screen were changed, update eink
bool isImageUpdated = false;
@@ 416,11 411,16 @@ namespace service::eink
const auto message = static_cast<service::eink::RefreshMessage *>(request);
if (einkDisplayState == EinkDisplayState::NeedRefresh) {
+ if (previousRefreshStatus == RefreshStatus::Failed) {
+ refreshModeSum = hal::eink::EinkRefreshMode::REFRESH_DEEP;
+ previousRefreshStatus = RefreshStatus::Success;
+ }
const auto status = display->showImageRefresh(refreshFramesSum, refreshModeSum);
if (status != hal::eink::EinkStatus::EinkOK) {
previousContext.reset();
previousRefreshMode = hal::eink::EinkRefreshMode::REFRESH_NONE;
LOG_ERROR("Error during drawing image on eink: %s", magic_enum::enum_name(status).data());
+ previousRefreshStatus = RefreshStatus::Failed;
}
einkDisplayState = EinkDisplayState::Idle;
M module-services/service-eink/ServiceEink.hpp => module-services/service-eink/ServiceEink.hpp +7 -0
@@ 58,6 58,12 @@ namespace service::eink
Canceled
};
+ enum class RefreshStatus
+ {
+ Success,
+ Failed
+ };
+
void setState(State state) noexcept;
bool isInState(State state) const noexcept;
void restartDisplayPowerOffTimer();
@@ 88,6 94,7 @@ namespace service::eink
hal::eink::EinkFrame refreshFramesSum;
hal::eink::EinkRefreshMode refreshModeSum = hal::eink::EinkRefreshMode::REFRESH_NONE;
bool isRefreshFramesSumValid = false;
+ RefreshStatus previousRefreshStatus = RefreshStatus::Success;
sys::CloseReason systemCloseReason = sys::CloseReason::RegularPowerDown;
};
M module-services/service-gui/ServiceGUI.cpp => module-services/service-gui/ServiceGUI.cpp +2 -1
@@ 202,7 202,8 @@ namespace service::gui
void ServiceGUI::sendOnDisplay(::gui::Context *context, int contextId, ::gui::RefreshModes refreshMode)
{
isDisplaying = true;
- auto msg = std::make_shared<service::eink::ImageMessage>(contextId, context, refreshMode);
+
+ auto msg = std::make_shared<service::eink::ImageMessage>(contextId, context, refreshMode);
bus.sendUnicast(std::move(msg), service::name::eink);
scheduleContextRelease(contextId);
}
M pure_changelog.md => pure_changelog.md +5 -0
@@ 3,10 3,15 @@
## Unreleased
### Added
+
* Added VoLTE support in Poland, Germany, Denmark, United Kingdom, Netherlands, Canada and Austria
* Added extended information to crashdump filename
* Added extended information to log filename
+### Changed / Improved
+
+* General improvement in Eink display and error handling
+
### Fixed
* Fixed unsupported character in several quotes