Author: mark9064 <30447455+mark9064@users.noreply.github.com>
SPI transaction hooks
src/drivers/Spi.cpp | 4 +- src/drivers/Spi.h | 2 src/drivers/SpiMaster.cpp | 16 +++++++++++++- src/drivers/SpiMaster.h | 3 + src/drivers/SpiNorFlash.cpp | 2 src/drivers/St7789.cpp | 42 ++++++++++++++++++++++++-------------- src/drivers/St7789.h | 8 +++--- src/main.cpp | 2 src/recoveryLoader.cpp | 2
diff --git a/src/drivers/Spi.cpp b/src/drivers/Spi.cpp index c85b90c17c568a88341ecc8d8cd2cb4452cac04a..e0b716faa1e5092fe03f271481e630a9e90677fe 100644 --- a/src/drivers/Spi.cpp +++ b/src/drivers/Spi.cpp @@ -9,8 +9,8 @@ nrf_gpio_cfg_output(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, void (*TransactionHook)(bool)) { + return spiMaster.Write(pinCsn, data, size, TransactionHook); } 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 9b6a30f43b0541dc41c2d09c7d98e3827aaeb89c..55eef05cabb9765d4a275346571e3aae1afd5f55 100644 --- a/src/drivers/Spi.h +++ b/src/drivers/Spi.h @@ -14,7 +14,7 @@ Spi(Spi&&) = delete; Spi& operator=(Spi&&) = delete; bool Init(); - bool Write(const uint8_t* data, size_t size); + bool Write(const uint8_t* data, size_t size, void (*TransactionHook)(bool)); 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 3446d639fa9a7f2765dcbc746fecaa45e30d49f2..4c2bc940be2972d15b53929cd1197f325d609dde 100644 --- a/src/drivers/SpiMaster.cpp +++ b/src/drivers/SpiMaster.cpp @@ -143,6 +143,9 @@ portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } nrf_gpio_pin_set(this->pinCsn); + if (this->TransactionHook != nullptr) { + this->TransactionHook(false); + } currentBufferAddr = 0; BaseType_t xHigherPriorityTaskWoken2 = pdFALSE; xSemaphoreGiveFromISR(mutex, &xHigherPriorityTaskWoken2); @@ -173,13 +176,14 @@ spiBaseAddress->RXD.LIST = 0; 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, void (*TransactionHook)(bool)) { if (data == nullptr) return false; auto ok = xSemaphoreTake(mutex, portMAX_DELAY); ASSERT(ok == true); taskToNotify = xTaskGetCurrentTaskHandle(); + this->TransactionHook = TransactionHook; this->pinCsn = pinCsn; if (size == 1) { @@ -188,6 +192,9 @@ } else { DisableWorkaroundForFtpan58(spiBaseAddress, 0, 0); } + if (this->TransactionHook != nullptr) { + this->TransactionHook(true); + } nrf_gpio_pin_clear(this->pinCsn); currentBufferAddr = (uint32_t) data; @@ -203,6 +210,9 @@ if (size == 1) { while (spiBaseAddress->EVENTS_END == 0) ; nrf_gpio_pin_set(this->pinCsn); + if (this->TransactionHook != nullptr) { + this->TransactionHook(false); + } currentBufferAddr = 0; DisableWorkaroundForFtpan58(spiBaseAddress, 0, 0); @@ -217,7 +227,7 @@ 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->TransactionHook = nullptr; this->pinCsn = pinCsn; DisableWorkaroundForFtpan58(spiBaseAddress, 0, 0); spiBaseAddress->INTENCLR = (1 << 6); @@ -266,6 +276,8 @@ 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->TransactionHook = nullptr; this->pinCsn = pinCsn; DisableWorkaroundForFtpan58(spiBaseAddress, 0, 0); diff --git a/src/drivers/SpiMaster.h b/src/drivers/SpiMaster.h index 8b698c57b5a1b6f9635ef6d9808ec29a6131e183..9014061ea0322f511675acb925f1acab16b39e9b 100644 --- a/src/drivers/SpiMaster.h +++ b/src/drivers/SpiMaster.h @@ -31,7 +31,7 @@ SpiMaster(SpiMaster&&) = delete; 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, void (*TransactionHook)(bool)); 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); @@ -50,6 +50,7 @@ void PrepareRx(const volatile uint32_t bufferAddress, const volatile size_t size); NRF_SPIM_Type* spiBaseAddress; uint8_t pinCsn; + void (*TransactionHook)(bool); SpiMaster::SpiModule spi; SpiMaster::Parameters params; diff --git a/src/drivers/SpiNorFlash.cpp b/src/drivers/SpiNorFlash.cpp index 28f82fe6c4bdcc27249ff45f539cd7ac20cfc249..56a8aabd9a674df646f3781ff869561a9bbe16b8 100644 --- a/src/drivers/SpiNorFlash.cpp +++ b/src/drivers/SpiNorFlash.cpp @@ -22,7 +22,7 @@ } void SpiNorFlash::Sleep() { auto cmd = static_cast<uint8_t>(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 e583aac84b5a09d02b4c978dd8d8333646fbb5ec..6824acd88946e3909cd5e9866a372333fbb76957 100644 --- a/src/drivers/St7789.cpp +++ b/src/drivers/St7789.cpp @@ -3,16 +3,17 @@ #include#include <libraries/delay/nrf_delay.h> #include <nrfx_log.h> #include "drivers/Spi.h" +#include "drivers/PinMap.h" using namespace Pinetime::Drivers; -St7789::St7789(Spi& spi, uint8_t pinDataCommand, uint8_t pinReset) : spi {spi}, pinDataCommand {pinDataCommand}, pinReset {pinReset} { +St7789::St7789(Spi& spi) : spi {spi} { } void St7789::Init() { - nrf_gpio_cfg_output(pinDataCommand); - nrf_gpio_cfg_output(pinReset); - nrf_gpio_pin_set(pinReset); + nrf_gpio_cfg_output(PinMap::LcdDataCommand); + nrf_gpio_cfg_output(PinMap::LcdReset); + nrf_gpio_pin_set(PinMap::LcdReset); HardwareReset(); SoftwareReset(); SleepOut(); @@ -29,18 +30,28 @@ SetVdv(); DisplayOn(); } +void St7789::EnableDataMode(bool isStart) { + if (isStart) { + nrf_gpio_pin_set(PinMap::LcdDataCommand); + } +} + +void St7789::EnableCommandMode(bool isStart) { + if (isStart) { + nrf_gpio_pin_clear(PinMap::LcdDataCommand); + } +} + void St7789::WriteCommand(uint8_t cmd) { - nrf_gpio_pin_clear(pinDataCommand); - WriteSpi(&cmd, 1); + WriteSpi(&cmd, 1, EnableCommandMode); } void St7789::WriteData(uint8_t data) { - nrf_gpio_pin_set(pinDataCommand); - WriteSpi(&data, 1); + WriteSpi(&data, 1, EnableDataMode); } -void St7789::WriteSpi(const uint8_t* data, size_t size) { - spi.Write(data, size); +void St7789::WriteSpi(const uint8_t* data, size_t size, void (*TransactionHook)(bool)) { + spi.Write(data, size, TransactionHook); } void St7789::SoftwareReset() { @@ -152,24 +163,23 @@ } 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); + WriteSpi(data, size, EnableDataMode); } void St7789::HardwareReset() { - nrf_gpio_pin_clear(pinReset); + nrf_gpio_pin_clear(PinMap::LcdReset); nrf_delay_ms(10); - nrf_gpio_pin_set(pinReset); + nrf_gpio_pin_set(PinMap::LcdReset); } void St7789::Sleep() { SleepIn(); - nrf_gpio_cfg_default(pinDataCommand); + nrf_gpio_cfg_default(PinMap::LcdDataCommand); NRF_LOG_INFO("[LCD] Sleep"); } void St7789::Wakeup() { - nrf_gpio_cfg_output(pinDataCommand); + nrf_gpio_cfg_output(PinMap::LcdDataCommand); SleepOut(); VerticalScrollStartAddress(verticalScrollingStartAddress); DisplayOn(); diff --git a/src/drivers/St7789.h b/src/drivers/St7789.h index b00bee03bdc78549759bf003f298f133868e8f0f..185c44a079dc9dcca1317d67d1b93906db171b22 100644 --- a/src/drivers/St7789.h +++ b/src/drivers/St7789.h @@ -8,7 +8,7 @@ class Spi; class St7789 { public: - explicit St7789(Spi& spi, uint8_t pinDataCommand, uint8_t pinReset); + explicit St7789(Spi& spi); St7789(const St7789&) = delete; St7789& operator=(const St7789&) = delete; St7789(St7789&&) = delete; @@ -26,8 +26,6 @@ void Wakeup(); private: Spi& spi; - uint8_t pinDataCommand; - uint8_t pinReset; uint8_t verticalScrollingStartAddress = 0; void HardwareReset(); @@ -45,7 +43,9 @@ 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 WriteSpi(const uint8_t* data, size_t size, void (*TransactionHook)(bool)); + static void EnableDataMode(bool isStart); + static void EnableCommandMode(bool isStart); enum class Commands : uint8_t { SoftwareReset = 0x01, diff --git a/src/main.cpp b/src/main.cpp index ee6a6d3de5c600b8bab5ba846a30893d2edd0e0c..723c2e63e812c4def647117ff9e7685270af4f5d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -68,7 +68,7 @@ Pinetime::PinMap::SpiMosi, Pinetime::PinMap::SpiMiso}}; Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; -Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand, Pinetime::PinMap::LcdReset}; +Pinetime::Drivers::St7789 lcd {lcdSpi}; Pinetime::Drivers::Spi flashSpi {spi, Pinetime::PinMap::SpiFlashCsn}; Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; diff --git a/src/recoveryLoader.cpp b/src/recoveryLoader.cpp index a0b4d784c385d7313bac7ece39e1347c0aa7f9c0..56cb965ff17b0a317d85337bb910eb39efe7762c 100644 --- a/src/recoveryLoader.cpp +++ b/src/recoveryLoader.cpp @@ -45,7 +45,7 @@ Pinetime::Drivers::Spi flashSpi {spi, Pinetime::PinMap::SpiFlashCsn}; Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; -Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand, Pinetime::PinMap::LcdReset}; +Pinetime::Drivers::St7789 lcd {lcdSpi}; Pinetime::Controllers::BrightnessController brightnessController;