diff --git a/src/FreeRTOSConfig.h b/src/FreeRTOSConfig.h index cf18f4189e..67c33a34cc 100644 --- a/src/FreeRTOSConfig.h +++ b/src/FreeRTOSConfig.h @@ -75,6 +75,7 @@ #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configUSE_TASK_NOTIFICATIONS 0 /* Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 9c7d87b2b8..d9b2e9b3ab 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -142,9 +142,6 @@ void DisplayApp::Process(void* instance) { NRF_LOG_INFO("displayapp task started!"); app->InitHw(); - // Send a dummy notification to unlock the lvgl display driver for the first iteration - xTaskNotifyGive(xTaskGetCurrentTaskHandle()); - while (true) { app->Refresh(); } diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index 002ee3bd04..2889272370 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -38,9 +38,6 @@ void DisplayApp::Process(void* instance) { auto* app = static_cast(instance); NRF_LOG_INFO("displayapp task started!"); - // Send a dummy notification to unlock the lvgl display driver for the first iteration - xTaskNotifyGive(xTaskGetCurrentTaskHandle()); - app->InitHw(); while (true) { app->Refresh(); @@ -94,7 +91,6 @@ void DisplayApp::DisplayLogo(uint16_t color) { Pinetime::Tools::RleDecoder rleDecoder(infinitime_nb, sizeof(infinitime_nb), color, colorBlack); for (int i = 0; i < displayWidth; i++) { rleDecoder.DecodeNext(displayBuffer, displayWidth * bytesPerPixel); - ulTaskNotifyTake(pdTRUE, 500); lcd.DrawBuffer(0, i, displayWidth, 1, reinterpret_cast(displayBuffer), displayWidth * bytesPerPixel); } } @@ -103,7 +99,6 @@ void DisplayApp::DisplayOtaProgress(uint8_t percent, uint16_t color) { const uint8_t barHeight = 20; std::fill(displayBuffer, displayBuffer + (displayWidth * bytesPerPixel), color); for (int i = 0; i < barHeight; i++) { - ulTaskNotifyTake(pdTRUE, 500); uint16_t barWidth = std::min(static_cast(percent) * 2.4f, static_cast(displayWidth)); lcd.DrawBuffer(0, displayWidth - barHeight + i, barWidth, 1, reinterpret_cast(displayBuffer), barWidth * bytesPerPixel); } diff --git a/src/displayapp/LittleVgl.cpp b/src/displayapp/LittleVgl.cpp index 89893cf79d..c70a08565b 100644 --- a/src/displayapp/LittleVgl.cpp +++ b/src/displayapp/LittleVgl.cpp @@ -152,10 +152,6 @@ void LittleVgl::SetFullRefresh(FullRefreshDirections direction) { void LittleVgl::FlushDisplay(const lv_area_t* area, lv_color_t* color_p) { uint16_t y1, y2, width, height = 0; - ulTaskNotifyTake(pdTRUE, 200); - // Notification is still needed (even if there is a mutex on SPI) because of the DataCommand pin - // which cannot be set/clear during a transfer. - if ((scrollDirection == LittleVgl::FullRefreshDirections::Down) && (area->y2 == visibleNbLines - 1)) { writeOffset = ((writeOffset + totalNbLines) - visibleNbLines) % totalNbLines; } else if ((scrollDirection == FullRefreshDirections::Up) && (area->y1 == 0)) { @@ -219,7 +215,6 @@ void LittleVgl::FlushDisplay(const lv_area_t* area, lv_color_t* color_p) { if (height > 0) { lcd.DrawBuffer(area->x1, y1, width, height, reinterpret_cast(color_p), width * height * 2); - ulTaskNotifyTake(pdTRUE, 100); } uint16_t pixOffset = width * height; diff --git a/src/drivers/Spi.cpp b/src/drivers/Spi.cpp index c85b90c17c..a95a7eaee1 100644 --- a/src/drivers/Spi.cpp +++ b/src/drivers/Spi.cpp @@ -9,8 +9,8 @@ Spi::Spi(SpiMaster& spiMaster, uint8_t pinCsn) : spiMaster {spiMaster}, pinCsn { nrf_gpio_pin_set(pinCsn); } -bool Spi::Write(const uint8_t* data, size_t size) { - return spiMaster.Write(pinCsn, data, size); +bool Spi::Write(const uint8_t* data, size_t size, const std::function& preTransactionHook) { + return spiMaster.Write(pinCsn, data, size, preTransactionHook); } bool Spi::Read(uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize) { diff --git a/src/drivers/Spi.h b/src/drivers/Spi.h index 9b6a30f43b..0c5edf0870 100644 --- a/src/drivers/Spi.h +++ b/src/drivers/Spi.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "drivers/SpiMaster.h" namespace Pinetime { @@ -14,7 +15,7 @@ namespace Pinetime { Spi& operator=(Spi&&) = delete; bool Init(); - bool Write(const uint8_t* data, size_t size); + bool Write(const uint8_t* data, size_t size, const std::function& preTransactionHook); bool Read(uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize); bool WriteCmdAndBuffer(const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize); void Sleep(); diff --git a/src/drivers/SpiMaster.cpp b/src/drivers/SpiMaster.cpp index 3446d639fa..690a322602 100644 --- a/src/drivers/SpiMaster.cpp +++ b/src/drivers/SpiMaster.cpp @@ -136,17 +136,11 @@ void SpiMaster::OnEndEvent() { spiBaseAddress->TASKS_START = 1; } else { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - if (taskToNotify != nullptr) { - vTaskNotifyGiveFromISR(taskToNotify, &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } - nrf_gpio_pin_set(this->pinCsn); currentBufferAddr = 0; - BaseType_t xHigherPriorityTaskWoken2 = pdFALSE; - xSemaphoreGiveFromISR(mutex, &xHigherPriorityTaskWoken2); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken | xHigherPriorityTaskWoken2); + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + xSemaphoreGiveFromISR(mutex, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } @@ -173,12 +167,11 @@ void SpiMaster::PrepareRx(const uint32_t bufferAddress, const size_t size) { spiBaseAddress->EVENTS_END = 0; } -bool SpiMaster::Write(uint8_t pinCsn, const uint8_t* data, size_t size) { +bool SpiMaster::Write(uint8_t pinCsn, const uint8_t* data, size_t size, const std::function& preTransactionHook) { if (data == nullptr) return false; auto ok = xSemaphoreTake(mutex, portMAX_DELAY); ASSERT(ok == true); - taskToNotify = xTaskGetCurrentTaskHandle(); this->pinCsn = pinCsn; @@ -188,6 +181,9 @@ bool SpiMaster::Write(uint8_t pinCsn, const uint8_t* data, size_t size) { DisableWorkaroundForFtpan58(spiBaseAddress, 0, 0); } + if (preTransactionHook != nullptr) { + preTransactionHook(); + } nrf_gpio_pin_clear(this->pinCsn); currentBufferAddr = (uint32_t) data; @@ -216,8 +212,6 @@ bool SpiMaster::Write(uint8_t pinCsn, const uint8_t* data, size_t size) { bool SpiMaster::Read(uint8_t pinCsn, uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize) { xSemaphoreTake(mutex, portMAX_DELAY); - taskToNotify = nullptr; - this->pinCsn = pinCsn; DisableWorkaroundForFtpan58(spiBaseAddress, 0, 0); spiBaseAddress->INTENCLR = (1 << 6); @@ -265,8 +259,6 @@ void SpiMaster::Wakeup() { bool SpiMaster::WriteCmdAndBuffer(uint8_t pinCsn, const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize) { xSemaphoreTake(mutex, portMAX_DELAY); - taskToNotify = nullptr; - this->pinCsn = pinCsn; DisableWorkaroundForFtpan58(spiBaseAddress, 0, 0); spiBaseAddress->INTENCLR = (1 << 6); diff --git a/src/drivers/SpiMaster.h b/src/drivers/SpiMaster.h index 8b698c57b5..af38e87b7e 100644 --- a/src/drivers/SpiMaster.h +++ b/src/drivers/SpiMaster.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include @@ -31,7 +32,7 @@ namespace Pinetime { SpiMaster& operator=(SpiMaster&&) = delete; bool Init(); - bool Write(uint8_t pinCsn, const uint8_t* data, size_t size); + bool Write(uint8_t pinCsn, const uint8_t* data, size_t size, const std::function& preTransactionHook); bool Read(uint8_t pinCsn, uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize); bool WriteCmdAndBuffer(uint8_t pinCsn, const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize); @@ -56,7 +57,6 @@ namespace Pinetime { volatile uint32_t currentBufferAddr = 0; volatile size_t currentBufferSize = 0; - volatile TaskHandle_t taskToNotify; SemaphoreHandle_t mutex = nullptr; }; } diff --git a/src/drivers/SpiNorFlash.cpp b/src/drivers/SpiNorFlash.cpp index 28f82fe6c4..56a8aabd9a 100644 --- a/src/drivers/SpiNorFlash.cpp +++ b/src/drivers/SpiNorFlash.cpp @@ -22,7 +22,7 @@ void SpiNorFlash::Uninit() { void SpiNorFlash::Sleep() { auto cmd = static_cast(Commands::DeepPowerDown); - spi.Write(&cmd, sizeof(uint8_t)); + spi.Write(&cmd, sizeof(uint8_t), nullptr); NRF_LOG_INFO("[SpiNorFlash] Sleep") } diff --git a/src/drivers/St7789.cpp b/src/drivers/St7789.cpp index e583aac84b..d1747c2392 100644 --- a/src/drivers/St7789.cpp +++ b/src/drivers/St7789.cpp @@ -29,18 +29,28 @@ void St7789::Init() { DisplayOn(); } -void St7789::WriteCommand(uint8_t cmd) { - nrf_gpio_pin_clear(pinDataCommand); - WriteSpi(&cmd, 1); +void St7789::WriteData(uint8_t data) { + WriteData(&data, 1); } -void St7789::WriteData(uint8_t data) { - nrf_gpio_pin_set(pinDataCommand); - WriteSpi(&data, 1); +void St7789::WriteData(const uint8_t* data, size_t size) { + WriteSpi(data, size, [pinDataCommand = pinDataCommand]() { + nrf_gpio_pin_set(pinDataCommand); + }); +} + +void St7789::WriteCommand(uint8_t data) { + WriteCommand(&data, 1); } -void St7789::WriteSpi(const uint8_t* data, size_t size) { - spi.Write(data, size); +void St7789::WriteCommand(const uint8_t* data, size_t size) { + WriteSpi(data, size, [pinDataCommand = pinDataCommand]() { + nrf_gpio_pin_clear(pinDataCommand); + }); +} + +void St7789::WriteSpi(const uint8_t* data, size_t size, const std::function& preTransactionHook) { + spi.Write(data, size, preTransactionHook); } void St7789::SoftwareReset() { @@ -120,12 +130,11 @@ void St7789::SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { WriteData(y0 & 0xff); WriteData(y1 >> 8); WriteData(y1 & 0xff); - - WriteToRam(); } -void St7789::WriteToRam() { +void St7789::WriteToRam(const uint8_t* data, size_t size) { WriteCommand(static_cast(Commands::WriteToRam)); + WriteData(data, size); } void St7789::SetVdv() { @@ -152,8 +161,7 @@ void St7789::Uninit() { void St7789::DrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data, size_t size) { SetAddrWindow(x, y, x + width - 1, y + height - 1); - nrf_gpio_pin_set(pinDataCommand); - WriteSpi(data, size); + WriteToRam(data, size); } void St7789::HardwareReset() { diff --git a/src/drivers/St7789.h b/src/drivers/St7789.h index b00bee03bd..715bd1bd72 100644 --- a/src/drivers/St7789.h +++ b/src/drivers/St7789.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace Pinetime { namespace Drivers { @@ -38,14 +39,15 @@ namespace Pinetime { void MemoryDataAccessControl(); void DisplayInversionOn(); void NormalModeOn(); - void WriteToRam(); + void WriteToRam(const uint8_t* data, size_t size); void DisplayOn(); void DisplayOff(); void SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); void SetVdv(); void WriteCommand(uint8_t cmd); - void WriteSpi(const uint8_t* data, size_t size); + void WriteCommand(const uint8_t* data, size_t size); + void WriteSpi(const uint8_t* data, size_t size, const std::function& preTransactionHook); enum class Commands : uint8_t { SoftwareReset = 0x01, @@ -65,6 +67,7 @@ namespace Pinetime { VdvSet = 0xc4, }; void WriteData(uint8_t data); + void WriteData(const uint8_t* data, size_t size); void ColumnAddressSet(); static constexpr uint16_t Width = 240; diff --git a/src/recoveryLoader.cpp b/src/recoveryLoader.cpp index a0b4d784c3..fc9ab76cff 100644 --- a/src/recoveryLoader.cpp +++ b/src/recoveryLoader.cpp @@ -121,7 +121,6 @@ void DisplayLogo() { Pinetime::Tools::RleDecoder rleDecoder(infinitime_nb, sizeof(infinitime_nb)); for (int i = 0; i < displayWidth; i++) { rleDecoder.DecodeNext(displayBuffer, displayWidth * bytesPerPixel); - ulTaskNotifyTake(pdTRUE, 500); lcd.DrawBuffer(0, i, displayWidth, 1, reinterpret_cast(displayBuffer), displayWidth * bytesPerPixel); } } @@ -130,7 +129,6 @@ void DisplayProgressBar(uint8_t percent, uint16_t color) { static constexpr uint8_t barHeight = 20; std::fill(displayBuffer, displayBuffer + (displayWidth * bytesPerPixel), color); for (int i = 0; i < barHeight; i++) { - ulTaskNotifyTake(pdTRUE, 500); uint16_t barWidth = std::min(static_cast(percent) * 2.4f, static_cast(displayWidth)); lcd.DrawBuffer(0, displayWidth - barHeight + i, barWidth, 1, reinterpret_cast(displayBuffer), barWidth * bytesPerPixel); }