Reformatted all the files according to clang-format style

This commit is contained in:
Avamander
2021-04-18 20:28:14 +03:00
parent e56ebb8bd6
commit 40d45d923b
179 changed files with 10119 additions and 10688 deletions

View File

@@ -24,7 +24,7 @@ namespace {
}
}
Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster{twiMaster}, deviceAddress{twiAddress} {
Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, deviceAddress {twiAddress} {
bma.intf = BMA4_I2C_INTF;
bma.bus_read = user_i2c_read;
bma.bus_write = user_i2c_write;
@@ -35,25 +35,32 @@ Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster{twiMaster},
}
void Bma421::Init() {
if(not isResetOk) return; // Call SoftReset (and reset TWI device) first!
if (not isResetOk)
return; // Call SoftReset (and reset TWI device) first!
auto ret = bma423_init(&bma);
if(ret != BMA4_OK) return;
if (ret != BMA4_OK)
return;
ret = bma423_write_config_file(&bma);
if(ret != BMA4_OK) return;
if (ret != BMA4_OK)
return;
ret = bma4_set_interrupt_mode(BMA4_LATCH_MODE, &bma);
if(ret != BMA4_OK) return;
if (ret != BMA4_OK)
return;
ret = bma423_feature_enable(BMA423_STEP_CNTR, 1, &bma);
if(ret != BMA4_OK) return;
if (ret != BMA4_OK)
return;
ret = bma423_step_detector_enable(0, &bma);
if(ret != BMA4_OK) return;
if (ret != BMA4_OK)
return;
ret = bma4_set_accel_enable(1, &bma);
if(ret != BMA4_OK) return;
if (ret != BMA4_OK)
return;
struct bma4_accel_config accel_conf;
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
@@ -61,7 +68,8 @@ void Bma421::Init() {
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
ret = bma4_set_accel_config(&accel_conf, &bma);
if(ret != BMA4_OK) return;
if (ret != BMA4_OK)
return;
isOk = true;
}
@@ -71,16 +79,17 @@ void Bma421::Reset() {
twiMaster.Write(deviceAddress, 0x7E, &data, 1);
}
void Bma421::Read(uint8_t registerAddress, uint8_t *buffer, size_t size) {
void Bma421::Read(uint8_t registerAddress, uint8_t* buffer, size_t size) {
twiMaster.Read(deviceAddress, registerAddress, buffer, size);
}
void Bma421::Write(uint8_t registerAddress, const uint8_t *data, size_t size) {
void Bma421::Write(uint8_t registerAddress, const uint8_t* data, size_t size) {
twiMaster.Write(deviceAddress, registerAddress, data, size);
}
Bma421::Values Bma421::Process() {
if(not isOk) return {};
if (not isOk)
return {};
struct bma4_accel data;
bma4_read_accel_xyz(&data, &bma);
@@ -109,7 +118,7 @@ void Bma421::ResetStepCounter() {
void Bma421::SoftReset() {
auto ret = bma4_soft_reset(&bma);
if(ret == BMA4_OK) {
if (ret == BMA4_OK) {
isResetOk = true;
nrf_delay_ms(1);
}

View File

@@ -5,7 +5,7 @@ namespace Pinetime {
namespace Drivers {
class TwiMaster;
class Bma421 {
public:
public:
struct Values {
uint32_t steps;
int16_t x;
@@ -25,12 +25,12 @@ namespace Pinetime {
Values Process();
void ResetStepCounter();
void Read(uint8_t registerAddress, uint8_t *buffer, size_t size);
void Write(uint8_t registerAddress, const uint8_t *data, size_t size);
void Read(uint8_t registerAddress, uint8_t* buffer, size_t size);
void Write(uint8_t registerAddress, const uint8_t* data, size_t size);
bool IsOk() const;
private:
private:
void Reset();
TwiMaster& twiMaster;

View File

@@ -5,8 +5,8 @@
namespace Pinetime {
namespace Drivers {
class BufferProvider {
public:
virtual bool GetNextBuffer(uint8_t** buffer, size_t& size) = 0;
public:
virtual bool GetNextBuffer(uint8_t** buffer, size_t& size) = 0;
};
}
}

View File

@@ -7,14 +7,14 @@
using namespace Pinetime::Drivers;
/* References :
* This implementation is based on this article : https://medium.com/@ly.lee/building-a-rust-driver-for-pinetimes-touch-controller-cbc1a5d5d3e9
* Touch panel datasheet (weird chinese translation) : https://wiki.pine64.org/images/5/51/CST816S%E6%95%B0%E6%8D%AE%E6%89%8B%E5%86%8CV1.1.en.pdf
* This implementation is based on this article :
* https://medium.com/@ly.lee/building-a-rust-driver-for-pinetimes-touch-controller-cbc1a5d5d3e9 Touch panel datasheet (weird chinese
* translation) : https://wiki.pine64.org/images/5/51/CST816S%E6%95%B0%E6%8D%AE%E6%89%8B%E5%86%8CV1.1.en.pdf
*
* TODO : we need a complete datasheet and protocol reference!
* */
Cst816S::Cst816S(TwiMaster &twiMaster, uint8_t twiAddress) : twiMaster{twiMaster}, twiAddress{twiAddress} {
Cst816S::Cst816S(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, twiAddress {twiAddress} {
}
void Cst816S::Init() {
@@ -32,7 +32,7 @@ void Cst816S::Init() {
vTaskDelay(5);
twiMaster.Read(twiAddress, 0xa7, &dummy, 1);
vTaskDelay(5);
/*
[2] EnConLR - Continuous operation can slide around
[1] EnConUD - Slide up and down to enable continuous operation
@@ -40,23 +40,22 @@ void Cst816S::Init() {
*/
static constexpr uint8_t motionMask = 0b00000101;
twiMaster.Write(twiAddress, 0xEC, &motionMask, 1);
}
Cst816S::TouchInfos Cst816S::GetTouchInfo() {
Cst816S::TouchInfos info;
auto ret = twiMaster.Read(twiAddress, 0, touchData, sizeof(touchData));
if(ret != TwiMaster::ErrorCodes::NoError) return {};
if (ret != TwiMaster::ErrorCodes::NoError)
return {};
auto nbTouchPoints = touchData[2] & 0x0f;
uint8_t i = 0;
uint8_t pointId = (touchData[touchIdIndex + (touchStep * i)]) >> 4;
if(nbTouchPoints == 0 && pointId == lastTouchId) return info;
if (nbTouchPoints == 0 && pointId == lastTouchId)
return info;
info.isTouch = true;

View File

@@ -5,57 +5,58 @@
namespace Pinetime {
namespace Drivers {
class Cst816S {
public :
enum class Gestures : uint8_t {
None = 0x00,
SlideDown = 0x01,
SlideUp = 0x02,
SlideLeft = 0x03,
SlideRight = 0x04,
SingleTap = 0x05,
DoubleTap = 0x0B,
LongPress = 0x0C
};
struct TouchInfos {
uint16_t x = 0;
uint16_t y = 0;
uint8_t action = 0;
uint8_t finger = 0;
uint8_t pressure = 0;
uint8_t area = 0;
Gestures gesture = Gestures::None;
bool isTouch = false;
};
public:
enum class Gestures : uint8_t {
None = 0x00,
SlideDown = 0x01,
SlideUp = 0x02,
SlideLeft = 0x03,
SlideRight = 0x04,
SingleTap = 0x05,
DoubleTap = 0x0B,
LongPress = 0x0C
};
struct TouchInfos {
uint16_t x = 0;
uint16_t y = 0;
uint8_t action = 0;
uint8_t finger = 0;
uint8_t pressure = 0;
uint8_t area = 0;
Gestures gesture = Gestures::None;
bool isTouch = false;
};
Cst816S(TwiMaster& twiMaster, uint8_t twiAddress);
Cst816S(const Cst816S&) = delete;
Cst816S& operator=(const Cst816S&) = delete;
Cst816S(Cst816S&&) = delete;
Cst816S& operator=(Cst816S&&) = delete;
Cst816S(TwiMaster& twiMaster, uint8_t twiAddress);
Cst816S(const Cst816S&) = delete;
Cst816S& operator=(const Cst816S&) = delete;
Cst816S(Cst816S&&) = delete;
Cst816S& operator=(Cst816S&&) = delete;
void Init();
TouchInfos GetTouchInfo();
void Sleep();
void Wakeup();
private:
static constexpr uint8_t pinIrq = 28;
static constexpr uint8_t pinReset = 10;
static constexpr uint8_t lastTouchId = 0x0f;
static constexpr uint8_t touchPointNumIndex = 2;
static constexpr uint8_t touchMiscIndex = 8;
static constexpr uint8_t touchXYIndex = 7;
static constexpr uint8_t touchEventIndex = 3;
static constexpr uint8_t touchXHighIndex = 3;
static constexpr uint8_t touchXLowIndex = 4;
static constexpr uint8_t touchYHighIndex = 5;
static constexpr uint8_t touchYLowIndex = 6;
static constexpr uint8_t touchIdIndex = 5;
static constexpr uint8_t touchStep = 6;
static constexpr uint8_t gestureIndex = 1;
void Init();
TouchInfos GetTouchInfo();
void Sleep();
void Wakeup();
uint8_t touchData[10];
TwiMaster& twiMaster;
uint8_t twiAddress;
private:
static constexpr uint8_t pinIrq = 28;
static constexpr uint8_t pinReset = 10;
static constexpr uint8_t lastTouchId = 0x0f;
static constexpr uint8_t touchPointNumIndex = 2;
static constexpr uint8_t touchMiscIndex = 8;
static constexpr uint8_t touchXYIndex = 7;
static constexpr uint8_t touchEventIndex = 3;
static constexpr uint8_t touchXHighIndex = 3;
static constexpr uint8_t touchXLowIndex = 4;
static constexpr uint8_t touchYHighIndex = 5;
static constexpr uint8_t touchYLowIndex = 6;
static constexpr uint8_t touchIdIndex = 5;
static constexpr uint8_t touchStep = 6;
static constexpr uint8_t gestureIndex = 1;
uint8_t touchData[10];
TwiMaster& twiMaster;
uint8_t twiAddress;
};
}

View File

@@ -19,31 +19,27 @@ void debugpins_init() {
nrf_gpio_pin_clear(DebugPin4);
}
void debugpins_set(debugpins_pins pin) {
nrf_gpio_pin_set((uint32_t)(pin));
nrf_gpio_pin_set((uint32_t) (pin));
}
void debugpins_clear(debugpins_pins pin) {
nrf_gpio_pin_clear((uint32_t)(pin));
nrf_gpio_pin_clear((uint32_t) (pin));
}
void debugpins_pulse(debugpins_pins pin) {
nrf_gpio_pin_set((uint32_t)(pin));
nrf_gpio_pin_clear((uint32_t)(pin));
nrf_gpio_pin_set((uint32_t) (pin));
nrf_gpio_pin_clear((uint32_t) (pin));
}
#else
void debugpins_init() {
}
void debugpins_set(debugpins_pins pin) {
}
void debugpins_clear(debugpins_pins pin) {
}
void debugpins_pulse(debugpins_pins pin) {
}
#endif

View File

@@ -22,4 +22,3 @@ void debugpins_pulse(debugpins_pins pin);
#ifdef __cplusplus
}
#endif

View File

@@ -16,8 +16,7 @@ using namespace Pinetime::Drivers;
/** Driver for the HRS3300 heart rate sensor.
* Original implementation from wasp-os : https://github.com/daniel-thompson/wasp-os/blob/master/wasp/drivers/hrs3300.py
*/
Hrs3300::Hrs3300(TwiMaster &twiMaster, uint8_t twiAddress) : twiMaster{twiMaster}, twiAddress{twiAddress} {
Hrs3300::Hrs3300(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, twiAddress {twiAddress} {
}
void Hrs3300::Init() {
@@ -73,7 +72,7 @@ void Hrs3300::SetGain(uint8_t gain) {
constexpr uint8_t maxGain = 64U;
gain = std::min(gain, maxGain);
uint8_t hgain = 0;
while((1 << hgain) < gain){
while ((1 << hgain) < gain) {
++hgain;
}
@@ -93,25 +92,14 @@ void Hrs3300::SetDrive(uint8_t drive) {
void Hrs3300::WriteRegister(uint8_t reg, uint8_t data) {
auto ret = twiMaster.Write(twiAddress, reg, &data, 1);
if(ret != TwiMaster::ErrorCodes::NoError)
if (ret != TwiMaster::ErrorCodes::NoError)
NRF_LOG_INFO("WRITE ERROR");
}
uint8_t Hrs3300::ReadRegister(uint8_t reg) {
uint8_t value;
auto ret = twiMaster.Read(twiAddress, reg, &value, 1);
if(ret != TwiMaster::ErrorCodes::NoError)
if (ret != TwiMaster::ErrorCodes::NoError)
NRF_LOG_INFO("READ ERROR");
return value;
}

View File

@@ -5,7 +5,7 @@
namespace Pinetime {
namespace Drivers {
class Hrs3300 {
public:
public:
enum class Registers : uint8_t {
Id = 0x00,
Enable = 0x01,
@@ -35,13 +35,12 @@ namespace Pinetime {
void SetGain(uint8_t gain);
void SetDrive(uint8_t drive);
private:
private:
TwiMaster& twiMaster;
uint8_t twiAddress;
void WriteRegister(uint8_t reg, uint8_t data);
uint8_t ReadRegister(uint8_t reg);
};
}
}

View File

@@ -25,7 +25,7 @@ void InternalFlash::WriteWord(uint32_t address, uint32_t value) {
__DSB();
// Write word
*(uint32_t*)address = value;
*(uint32_t*) address = value;
Wait();
// Disable write
@@ -35,5 +35,7 @@ void InternalFlash::WriteWord(uint32_t address, uint32_t value) {
}
void InternalFlash::Wait() {
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {;}
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
;
}
}

View File

@@ -5,10 +5,11 @@
namespace Pinetime {
namespace Drivers {
class InternalFlash {
public:
public:
static void ErasePage(uint32_t address);
static void WriteWord(uint32_t address, uint32_t value);
private:
private:
static inline void Wait();
};
}

View File

@@ -4,17 +4,16 @@
using namespace Pinetime::Drivers;
Spi::Spi(SpiMaster& spiMaster, uint8_t pinCsn) :
spiMaster{spiMaster}, pinCsn{pinCsn} {
Spi::Spi(SpiMaster& spiMaster, uint8_t pinCsn) : spiMaster {spiMaster}, pinCsn {pinCsn} {
nrf_gpio_cfg_output(pinCsn);
nrf_gpio_pin_set(pinCsn);
}
bool Spi::Write(const uint8_t *data, size_t size) {
bool Spi::Write(const uint8_t* data, size_t size) {
return spiMaster.Write(pinCsn, data, size);
}
bool Spi::Read(uint8_t* cmd, size_t cmdSize, uint8_t *data, size_t dataSize) {
bool Spi::Read(uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize) {
return spiMaster.Read(pinCsn, cmd, cmdSize, data, dataSize);
}
@@ -23,7 +22,7 @@ void Spi::Sleep() {
NRF_LOG_INFO("[SPI] Sleep")
}
bool Spi::WriteCmdAndBuffer(const uint8_t *cmd, size_t cmdSize, const uint8_t *data, size_t dataSize) {
bool Spi::WriteCmdAndBuffer(const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize) {
return spiMaster.WriteCmdAndBuffer(pinCsn, cmd, cmdSize, data, dataSize);
}
@@ -37,5 +36,3 @@ void Spi::Wakeup() {
nrf_gpio_pin_set(pinCsn);
NRF_LOG_INFO("[SPI] Wakeup")
}

View File

@@ -6,23 +6,23 @@
namespace Pinetime {
namespace Drivers {
class Spi {
public:
Spi(SpiMaster& spiMaster, uint8_t pinCsn);
Spi(const Spi&) = delete;
Spi& operator=(const Spi&) = delete;
Spi(Spi&&) = delete;
Spi& operator=(Spi&&) = delete;
public:
Spi(SpiMaster& spiMaster, uint8_t pinCsn);
Spi(const Spi&) = delete;
Spi& operator=(const Spi&) = delete;
Spi(Spi&&) = delete;
Spi& operator=(Spi&&) = delete;
bool Init();
bool Write(const uint8_t* data, size_t size);
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();
void Wakeup();
bool Init();
bool Write(const uint8_t* data, size_t size);
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();
void Wakeup();
private:
SpiMaster& spiMaster;
uint8_t pinCsn;
private:
SpiMaster& spiMaster;
uint8_t pinCsn;
};
}
}

View File

@@ -6,8 +6,7 @@
using namespace Pinetime::Drivers;
SpiMaster::SpiMaster(const SpiMaster::SpiModule spi, const SpiMaster::Parameters &params) :
spi{spi}, params{params} {
SpiMaster::SpiMaster(const SpiMaster::SpiModule spi, const SpiMaster::Parameters& params) : spi {spi}, params {params} {
mutex = xSemaphoreCreateBinary();
ASSERT(mutex != NULL);
}
@@ -19,39 +18,58 @@ bool SpiMaster::Init() {
nrf_gpio_pin_clear(params.pinMOSI);
nrf_gpio_cfg_output(params.pinMOSI);
nrf_gpio_cfg_input(params.pinMISO, NRF_GPIO_PIN_NOPULL);
// nrf_gpio_cfg_output(params.pinCSN);
// pinCsn = params.pinCSN;
// nrf_gpio_cfg_output(params.pinCSN);
// pinCsn = params.pinCSN;
switch(spi) {
case SpiModule::SPI0: spiBaseAddress = NRF_SPIM0; break;
case SpiModule::SPI1: spiBaseAddress = NRF_SPIM1; break;
default: return false;
switch (spi) {
case SpiModule::SPI0:
spiBaseAddress = NRF_SPIM0;
break;
case SpiModule::SPI1:
spiBaseAddress = NRF_SPIM1;
break;
default:
return false;
}
/* Configure pins, frequency and mode */
spiBaseAddress->PSELSCK = params.pinSCK;
spiBaseAddress->PSELSCK = params.pinSCK;
spiBaseAddress->PSELMOSI = params.pinMOSI;
spiBaseAddress->PSELMISO = params.pinMISO;
uint32_t frequency;
switch(params.Frequency) {
case Frequencies::Freq8Mhz: frequency = 0x80000000; break;
default: return false;
switch (params.Frequency) {
case Frequencies::Freq8Mhz:
frequency = 0x80000000;
break;
default:
return false;
}
spiBaseAddress->FREQUENCY = frequency;
uint32_t regConfig = 0;
switch(params.bitOrder) {
case BitOrder::Msb_Lsb: break;
case BitOrder::Lsb_Msb: regConfig = 1;
default: return false;
switch (params.bitOrder) {
case BitOrder::Msb_Lsb:
break;
case BitOrder::Lsb_Msb:
regConfig = 1;
default:
return false;
}
switch(params.mode) {
case Modes::Mode0: break;
case Modes::Mode1: regConfig |= (0x01 << 1); break;
case Modes::Mode2: regConfig |= (0x02 << 1); break;
case Modes::Mode3: regConfig |= (0x03 << 1); break;
default: return false;
switch (params.mode) {
case Modes::Mode0:
break;
case Modes::Mode1:
regConfig |= (0x01 << 1);
break;
case Modes::Mode2:
regConfig |= (0x02 << 1);
break;
case Modes::Mode3:
regConfig |= (0x03 << 1);
break;
default:
return false;
}
spiBaseAddress->CONFIG = regConfig;
@@ -59,24 +77,22 @@ bool SpiMaster::Init() {
spiBaseAddress->EVENTS_ENDTX = 0;
spiBaseAddress->EVENTS_END = 0;
spiBaseAddress->INTENSET = ((unsigned)1 << (unsigned)6);
spiBaseAddress->INTENSET = ((unsigned)1 << (unsigned)1);
spiBaseAddress->INTENSET = ((unsigned)1 << (unsigned)19);
spiBaseAddress->INTENSET = ((unsigned) 1 << (unsigned) 6);
spiBaseAddress->INTENSET = ((unsigned) 1 << (unsigned) 1);
spiBaseAddress->INTENSET = ((unsigned) 1 << (unsigned) 19);
spiBaseAddress->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos);
NRFX_IRQ_PRIORITY_SET(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn,2);
NRFX_IRQ_PRIORITY_SET(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn, 2);
NRFX_IRQ_ENABLE(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn);
xSemaphoreGive(mutex);
return true;
}
void SpiMaster::SetupWorkaroundForFtpan58(NRF_SPIM_Type *spim, uint32_t ppi_channel, uint32_t gpiote_channel) {
void SpiMaster::SetupWorkaroundForFtpan58(NRF_SPIM_Type* spim, uint32_t ppi_channel, uint32_t gpiote_channel) {
// Create an event when SCK toggles.
NRF_GPIOTE->CONFIG[gpiote_channel] = (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos) |
(spim->PSEL.SCK << GPIOTE_CONFIG_PSEL_Pos) |
NRF_GPIOTE->CONFIG[gpiote_channel] = (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos) | (spim->PSEL.SCK << GPIOTE_CONFIG_PSEL_Pos) |
(GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
// Stop the spim instance when SCK toggles.
@@ -86,29 +102,29 @@ void SpiMaster::SetupWorkaroundForFtpan58(NRF_SPIM_Type *spim, uint32_t ppi_chan
spiBaseAddress->EVENTS_END = 0;
// Disable IRQ
spim->INTENCLR = (1<<6);
spim->INTENCLR = (1<<1);
spim->INTENCLR = (1<<19);
spim->INTENCLR = (1 << 6);
spim->INTENCLR = (1 << 1);
spim->INTENCLR = (1 << 19);
}
void SpiMaster::DisableWorkaroundForFtpan58(NRF_SPIM_Type *spim, uint32_t ppi_channel, uint32_t gpiote_channel) {
void SpiMaster::DisableWorkaroundForFtpan58(NRF_SPIM_Type* spim, uint32_t ppi_channel, uint32_t gpiote_channel) {
NRF_GPIOTE->CONFIG[gpiote_channel] = 0;
NRF_PPI->CH[ppi_channel].EEP = 0;
NRF_PPI->CH[ppi_channel].TEP = 0;
NRF_PPI->CHENSET = ppi_channel;
spiBaseAddress->EVENTS_END = 0;
spim->INTENSET = (1<<6);
spim->INTENSET = (1<<1);
spim->INTENSET = (1<<19);
spim->INTENSET = (1 << 6);
spim->INTENSET = (1 << 1);
spim->INTENSET = (1 << 19);
}
void SpiMaster::OnEndEvent() {
if(currentBufferAddr == 0) {
if (currentBufferAddr == 0) {
return;
}
auto s = currentBufferSize;
if(s > 0) {
if (s > 0) {
auto currentSize = std::min((size_t) 255, s);
PrepareTx(currentBufferAddr, currentSize);
currentBufferAddr += currentSize;
@@ -116,17 +132,17 @@ void SpiMaster::OnEndEvent() {
spiBaseAddress->TASKS_START = 1;
} else {
if(taskToNotify != nullptr) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(taskToNotify, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
nrf_gpio_pin_set(this->pinCsn);
currentBufferAddr = 0;
if (taskToNotify != nullptr) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(mutex, &xHigherPriorityTaskWoken);
vTaskNotifyGiveFromISR(taskToNotify, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
nrf_gpio_pin_set(this->pinCsn);
currentBufferAddr = 0;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(mutex, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
@@ -143,7 +159,10 @@ void SpiMaster::PrepareTx(const volatile uint32_t bufferAddress, const volatile
spiBaseAddress->EVENTS_END = 0;
}
void SpiMaster::PrepareRx(const volatile uint32_t cmdAddress, const volatile size_t cmdSize, const volatile uint32_t bufferAddress, const volatile size_t size) {
void SpiMaster::PrepareRx(const volatile uint32_t cmdAddress,
const volatile size_t cmdSize,
const volatile uint32_t bufferAddress,
const volatile size_t size) {
spiBaseAddress->TXD.PTR = 0;
spiBaseAddress->TXD.MAXCNT = 0;
spiBaseAddress->TXD.LIST = 0;
@@ -153,35 +172,35 @@ void SpiMaster::PrepareRx(const volatile uint32_t cmdAddress, const volatile siz
spiBaseAddress->EVENTS_END = 0;
}
bool SpiMaster::Write(uint8_t pinCsn, const uint8_t *data, size_t size) {
if(data == nullptr) return false;
bool SpiMaster::Write(uint8_t pinCsn, const uint8_t* data, size_t size) {
if (data == nullptr)
return false;
auto ok = xSemaphoreTake(mutex, portMAX_DELAY);
ASSERT(ok == true);
taskToNotify = xTaskGetCurrentTaskHandle();
this->pinCsn = pinCsn;
if(size == 1) {
SetupWorkaroundForFtpan58(spiBaseAddress, 0,0);
if (size == 1) {
SetupWorkaroundForFtpan58(spiBaseAddress, 0, 0);
} else {
DisableWorkaroundForFtpan58(spiBaseAddress, 0, 0);
}
nrf_gpio_pin_clear(this->pinCsn);
currentBufferAddr = (uint32_t)data;
currentBufferAddr = (uint32_t) data;
currentBufferSize = size;
auto currentSize = std::min((size_t)255, (size_t)currentBufferSize);
auto currentSize = std::min((size_t) 255, (size_t) currentBufferSize);
PrepareTx(currentBufferAddr, currentSize);
currentBufferSize -= currentSize;
currentBufferAddr += currentSize;
spiBaseAddress->TASKS_START = 1;
if(size == 1) {
while (spiBaseAddress->EVENTS_END == 0);
if (size == 1) {
while (spiBaseAddress->EVENTS_END == 0)
;
nrf_gpio_pin_set(this->pinCsn);
currentBufferAddr = 0;
xSemaphoreGive(mutex);
@@ -190,41 +209,41 @@ bool SpiMaster::Write(uint8_t pinCsn, const uint8_t *data, size_t size) {
return true;
}
bool SpiMaster::Read(uint8_t pinCsn, uint8_t* cmd, size_t cmdSize, uint8_t *data, size_t dataSize) {
xSemaphoreTake(mutex, portMAX_DELAY);
bool SpiMaster::Read(uint8_t pinCsn, uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize) {
xSemaphoreTake(mutex, portMAX_DELAY);
taskToNotify = nullptr;
taskToNotify = nullptr;
this->pinCsn = pinCsn;
DisableWorkaroundForFtpan58(spiBaseAddress, 0,0);
spiBaseAddress->INTENCLR = (1<<6);
spiBaseAddress->INTENCLR = (1<<1);
spiBaseAddress->INTENCLR = (1<<19);
this->pinCsn = pinCsn;
DisableWorkaroundForFtpan58(spiBaseAddress, 0, 0);
spiBaseAddress->INTENCLR = (1 << 6);
spiBaseAddress->INTENCLR = (1 << 1);
spiBaseAddress->INTENCLR = (1 << 19);
nrf_gpio_pin_clear(this->pinCsn);
nrf_gpio_pin_clear(this->pinCsn);
currentBufferAddr = 0;
currentBufferSize = 0;
currentBufferAddr = 0;
currentBufferSize = 0;
PrepareTx((uint32_t) cmd, cmdSize);
spiBaseAddress->TASKS_START = 1;
while (spiBaseAddress->EVENTS_END == 0)
;
PrepareTx((uint32_t)cmd, cmdSize);
spiBaseAddress->TASKS_START = 1;
while (spiBaseAddress->EVENTS_END == 0);
PrepareRx((uint32_t) cmd, cmdSize, (uint32_t) data, dataSize);
spiBaseAddress->TASKS_START = 1;
PrepareRx((uint32_t)cmd, cmdSize, (uint32_t)data, dataSize);
spiBaseAddress->TASKS_START = 1;
while (spiBaseAddress->EVENTS_END == 0)
;
nrf_gpio_pin_set(this->pinCsn);
while (spiBaseAddress->EVENTS_END == 0);
nrf_gpio_pin_set(this->pinCsn);
xSemaphoreGive(mutex);
xSemaphoreGive(mutex);
return true;
return true;
}
void SpiMaster::Sleep() {
while(spiBaseAddress->ENABLE != 0) {
while (spiBaseAddress->ENABLE != 0) {
spiBaseAddress->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos);
}
nrf_gpio_cfg_default(params.pinSCK);
@@ -239,37 +258,35 @@ void SpiMaster::Wakeup() {
NRF_LOG_INFO("[SPIMASTER] Wakeup");
}
bool SpiMaster::WriteCmdAndBuffer(uint8_t pinCsn, const uint8_t *cmd, size_t cmdSize, const uint8_t *data, size_t dataSize) {
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);
spiBaseAddress->INTENCLR = (1<<1);
spiBaseAddress->INTENCLR = (1<<19);
DisableWorkaroundForFtpan58(spiBaseAddress, 0, 0);
spiBaseAddress->INTENCLR = (1 << 6);
spiBaseAddress->INTENCLR = (1 << 1);
spiBaseAddress->INTENCLR = (1 << 19);
nrf_gpio_pin_clear(this->pinCsn);
currentBufferAddr = 0;
currentBufferSize = 0;
PrepareTx((uint32_t)cmd, cmdSize);
PrepareTx((uint32_t) cmd, cmdSize);
spiBaseAddress->TASKS_START = 1;
while (spiBaseAddress->EVENTS_END == 0);
while (spiBaseAddress->EVENTS_END == 0)
;
PrepareTx((uint32_t)data, dataSize);
PrepareTx((uint32_t) data, dataSize);
spiBaseAddress->TASKS_START = 1;
while (spiBaseAddress->EVENTS_END == 0);
while (spiBaseAddress->EVENTS_END == 0)
;
nrf_gpio_pin_set(this->pinCsn);
xSemaphoreGive(mutex);
return true;
}

View File

@@ -9,54 +9,58 @@
namespace Pinetime {
namespace Drivers {
class SpiMaster {
public:;
enum class SpiModule : uint8_t {SPI0, SPI1};
enum class BitOrder : uint8_t {Msb_Lsb, Lsb_Msb};
enum class Modes : uint8_t {Mode0, Mode1, Mode2, Mode3};
enum class Frequencies : uint8_t {Freq8Mhz};
struct Parameters {
BitOrder bitOrder;
Modes mode;
Frequencies Frequency;
uint8_t pinSCK;
uint8_t pinMOSI;
uint8_t pinMISO;
};
public:
;
enum class SpiModule : uint8_t { SPI0, SPI1 };
enum class BitOrder : uint8_t { Msb_Lsb, Lsb_Msb };
enum class Modes : uint8_t { Mode0, Mode1, Mode2, Mode3 };
enum class Frequencies : uint8_t { Freq8Mhz };
struct Parameters {
BitOrder bitOrder;
Modes mode;
Frequencies Frequency;
uint8_t pinSCK;
uint8_t pinMOSI;
uint8_t pinMISO;
};
SpiMaster(const SpiModule spi, const Parameters& params);
SpiMaster(const SpiMaster&) = delete;
SpiMaster& operator=(const SpiMaster&) = delete;
SpiMaster(SpiMaster&&) = delete;
SpiMaster& operator=(SpiMaster&&) = delete;
SpiMaster(const SpiModule spi, const Parameters& params);
SpiMaster(const SpiMaster&) = delete;
SpiMaster& operator=(const SpiMaster&) = delete;
SpiMaster(SpiMaster&&) = delete;
SpiMaster& operator=(SpiMaster&&) = delete;
bool Init();
bool Write(uint8_t pinCsn, const uint8_t* data, size_t size);
bool Read(uint8_t pinCsn, uint8_t* cmd, size_t cmdSize, uint8_t *data, size_t dataSize);
bool Init();
bool Write(uint8_t pinCsn, const uint8_t* data, size_t size);
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);
bool WriteCmdAndBuffer(uint8_t pinCsn, const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize);
void OnStartedEvent();
void OnEndEvent();
void OnStartedEvent();
void OnEndEvent();
void Sleep();
void Wakeup();
void Sleep();
void Wakeup();
private:
void SetupWorkaroundForFtpan58(NRF_SPIM_Type *spim, uint32_t ppi_channel, uint32_t gpiote_channel);
void DisableWorkaroundForFtpan58(NRF_SPIM_Type *spim, uint32_t ppi_channel, uint32_t gpiote_channel);
void PrepareTx(const volatile uint32_t bufferAddress, const volatile size_t size);
void PrepareRx(const volatile uint32_t cmdAddress, const volatile size_t cmdSize, const volatile uint32_t bufferAddress, const volatile size_t size);
private:
void SetupWorkaroundForFtpan58(NRF_SPIM_Type* spim, uint32_t ppi_channel, uint32_t gpiote_channel);
void DisableWorkaroundForFtpan58(NRF_SPIM_Type* spim, uint32_t ppi_channel, uint32_t gpiote_channel);
void PrepareTx(const volatile uint32_t bufferAddress, const volatile size_t size);
void PrepareRx(const volatile uint32_t cmdAddress,
const volatile size_t cmdSize,
const volatile uint32_t bufferAddress,
const volatile size_t size);
NRF_SPIM_Type * spiBaseAddress;
uint8_t pinCsn;
NRF_SPIM_Type* spiBaseAddress;
uint8_t pinCsn;
SpiMaster::SpiModule spi;
SpiMaster::Parameters params;
SpiMaster::SpiModule spi;
SpiMaster::Parameters params;
volatile uint32_t currentBufferAddr = 0;
volatile size_t currentBufferSize = 0;
volatile TaskHandle_t taskToNotify;
SemaphoreHandle_t mutex;
volatile uint32_t currentBufferAddr = 0;
volatile size_t currentBufferSize = 0;
volatile TaskHandle_t taskToNotify;
SemaphoreHandle_t mutex;
};
}
}

View File

@@ -6,17 +6,16 @@
using namespace Pinetime::Drivers;
SpiNorFlash::SpiNorFlash(Spi& spi) : spi{spi} {
SpiNorFlash::SpiNorFlash(Spi& spi) : spi {spi} {
}
void SpiNorFlash::Init() {
device_id = ReadIdentificaion();
NRF_LOG_INFO("[SpiNorFlash] Manufacturer : %d, Memory type : %d, memory density : %d", device_id.manufacturer, device_id.type, device_id.density);
NRF_LOG_INFO(
"[SpiNorFlash] Manufacturer : %d, Memory type : %d, memory density : %d", device_id.manufacturer, device_id.type, device_id.density);
}
void SpiNorFlash::Uninit() {
}
void SpiNorFlash::Sleep() {
@@ -30,12 +29,11 @@ void SpiNorFlash::Wakeup() {
static constexpr uint8_t cmdSize = 4;
uint8_t cmd[cmdSize] = {static_cast<uint8_t>(Commands::ReleaseFromDeepPowerDown), 0x01, 0x02, 0x03};
uint8_t id = 0;
spi.Read(reinterpret_cast<uint8_t *>(&cmd), cmdSize, &id, 1);
auto devId = device_id = ReadIdentificaion();
if(devId.type != device_id.type) {
spi.Read(reinterpret_cast<uint8_t*>(&cmd), cmdSize, &id, 1);
auto devId = device_id = ReadIdentificaion();
if (devId.type != device_id.type) {
NRF_LOG_INFO("[SpiNorFlash] ID on Wakeup: Failed");
}
else {
} else {
NRF_LOG_INFO("[SpiNorFlash] ID on Wakeup: %d", id);
}
NRF_LOG_INFO("[SpiNorFlash] Wakeup")
@@ -44,7 +42,7 @@ void SpiNorFlash::Wakeup() {
SpiNorFlash::Identification SpiNorFlash::ReadIdentificaion() {
auto cmd = static_cast<uint8_t>(Commands::ReadIdentification);
Identification identification;
spi.Read(&cmd, 1, reinterpret_cast<uint8_t *>(&identification), sizeof(Identification));
spi.Read(&cmd, 1, reinterpret_cast<uint8_t*>(&identification), sizeof(Identification));
return identification;
}
@@ -70,11 +68,10 @@ uint8_t SpiNorFlash::ReadConfigurationRegister() {
return status;
}
void SpiNorFlash::Read(uint32_t address, uint8_t *buffer, size_t size) {
void SpiNorFlash::Read(uint32_t address, uint8_t* buffer, size_t size) {
static constexpr uint8_t cmdSize = 4;
uint8_t cmd[cmdSize] = { static_cast<uint8_t>(Commands::Read), (uint8_t)(address >> 16U), (uint8_t)(address >> 8U),
(uint8_t)address };
spi.Read(reinterpret_cast<uint8_t *>(&cmd), cmdSize, buffer, size);
uint8_t cmd[cmdSize] = {static_cast<uint8_t>(Commands::Read), (uint8_t) (address >> 16U), (uint8_t) (address >> 8U), (uint8_t) address};
spi.Read(reinterpret_cast<uint8_t*>(&cmd), cmdSize, buffer, size);
}
void SpiNorFlash::WriteEnable() {
@@ -84,15 +81,19 @@ void SpiNorFlash::WriteEnable() {
void SpiNorFlash::SectorErase(uint32_t sectorAddress) {
static constexpr uint8_t cmdSize = 4;
uint8_t cmd[cmdSize] = { static_cast<uint8_t>(Commands::SectorErase), (uint8_t)(sectorAddress >> 16U), (uint8_t)(sectorAddress >> 8U),
(uint8_t)sectorAddress };
uint8_t cmd[cmdSize] = {static_cast<uint8_t>(Commands::SectorErase),
(uint8_t) (sectorAddress >> 16U),
(uint8_t) (sectorAddress >> 8U),
(uint8_t) sectorAddress};
WriteEnable();
while(!WriteEnabled()) vTaskDelay(1);
while (!WriteEnabled())
vTaskDelay(1);
spi.Read(reinterpret_cast<uint8_t *>(&cmd), cmdSize, nullptr, 0);
spi.Read(reinterpret_cast<uint8_t*>(&cmd), cmdSize, nullptr, 0);
while(WriteInProgress()) vTaskDelay(1);
while (WriteInProgress())
vTaskDelay(1);
}
uint8_t SpiNorFlash::ReadSecurityRegister() {
@@ -110,29 +111,29 @@ bool SpiNorFlash::EraseFailed() {
return (ReadSecurityRegister() & 0x40u) == 0x40u;
}
void SpiNorFlash::Write(uint32_t address, const uint8_t *buffer, size_t size) {
void SpiNorFlash::Write(uint32_t address, const uint8_t* buffer, size_t size) {
static constexpr uint8_t cmdSize = 4;
size_t len = size;
uint32_t addr = address;
const uint8_t* b = buffer;
while(len > 0) {
while (len > 0) {
uint32_t pageLimit = (addr & ~(pageSize - 1u)) + pageSize;
uint32_t toWrite = pageLimit - addr > len ? len : pageLimit - addr;
uint32_t toWrite = pageLimit - addr > len ? len : pageLimit - addr;
uint8_t cmd[cmdSize] = { static_cast<uint8_t>(Commands::PageProgram), (uint8_t)(addr >> 16U), (uint8_t)(addr >> 8U),
(uint8_t)addr };
uint8_t cmd[cmdSize] = {static_cast<uint8_t>(Commands::PageProgram), (uint8_t) (addr >> 16U), (uint8_t) (addr >> 8U), (uint8_t) addr};
WriteEnable();
while(!WriteEnabled()) vTaskDelay(1);
while (!WriteEnabled())
vTaskDelay(1);
spi.WriteCmdAndBuffer(cmd, cmdSize, b, toWrite);
while(WriteInProgress()) vTaskDelay(1);
while (WriteInProgress())
vTaskDelay(1);
addr += toWrite;
b += toWrite;
len -= toWrite;
}
}

View File

@@ -6,58 +6,55 @@ namespace Pinetime {
namespace Drivers {
class Spi;
class SpiNorFlash {
public:
explicit SpiNorFlash(Spi& spi);
SpiNorFlash(const SpiNorFlash&) = delete;
SpiNorFlash& operator=(const SpiNorFlash&) = delete;
SpiNorFlash(SpiNorFlash&&) = delete;
SpiNorFlash& operator=(SpiNorFlash&&) = delete;
public:
explicit SpiNorFlash(Spi& spi);
SpiNorFlash(const SpiNorFlash&) = delete;
SpiNorFlash& operator=(const SpiNorFlash&) = delete;
SpiNorFlash(SpiNorFlash&&) = delete;
SpiNorFlash& operator=(SpiNorFlash&&) = delete;
typedef struct __attribute__((packed)) {
uint8_t manufacturer = 0;
uint8_t type = 0;
uint8_t density = 0;
} Identification;
typedef struct __attribute__((packed)) {
uint8_t manufacturer = 0;
uint8_t type = 0;
uint8_t density = 0;
} Identification;
Identification ReadIdentificaion();
uint8_t ReadStatusRegister();
bool WriteInProgress();
bool WriteEnabled();
uint8_t ReadConfigurationRegister();
void Read(uint32_t address, uint8_t* buffer, size_t size);
void Write(uint32_t address, const uint8_t *buffer, size_t size);
void WriteEnable();
void SectorErase(uint32_t sectorAddress);
uint8_t ReadSecurityRegister();
bool ProgramFailed();
bool EraseFailed();
Identification ReadIdentificaion();
uint8_t ReadStatusRegister();
bool WriteInProgress();
bool WriteEnabled();
uint8_t ReadConfigurationRegister();
void Read(uint32_t address, uint8_t* buffer, size_t size);
void Write(uint32_t address, const uint8_t* buffer, size_t size);
void WriteEnable();
void SectorErase(uint32_t sectorAddress);
uint8_t ReadSecurityRegister();
bool ProgramFailed();
bool EraseFailed();
void Init();
void Uninit();
void Init();
void Uninit();
void Sleep();
void Wakeup();
private:
enum class Commands : uint8_t {
PageProgram = 0x02,
Read = 0x03,
ReadStatusRegister = 0x05,
WriteEnable = 0x06,
ReadConfigurationRegister = 0x15,
SectorErase = 0x20,
ReadSecurityRegister = 0x2B,
ReadIdentification = 0x9F,
ReleaseFromDeepPowerDown = 0xAB,
DeepPowerDown = 0xB9
};
static constexpr uint16_t pageSize = 256;
void Sleep();
void Wakeup();
private:
enum class Commands : uint8_t {
PageProgram = 0x02,
Read = 0x03,
ReadStatusRegister = 0x05,
WriteEnable = 0x06,
ReadConfigurationRegister = 0x15,
SectorErase = 0x20,
ReadSecurityRegister = 0x2B,
ReadIdentification = 0x9F,
ReleaseFromDeepPowerDown = 0xAB,
DeepPowerDown = 0xB9
};
static constexpr uint16_t pageSize = 256;
Spi& spi;
Identification device_id;
Spi& spi;
Identification device_id;
};
}
}

View File

@@ -6,11 +6,9 @@
using namespace Pinetime::Drivers;
St7789::St7789(Spi &spi, uint8_t pinDataCommand) : spi{spi}, pinDataCommand{pinDataCommand} {
St7789::St7789(Spi& spi, uint8_t pinDataCommand) : spi {spi}, pinDataCommand {pinDataCommand} {
}
void St7789::Init() {
spi.Init();
nrf_gpio_cfg_output(pinDataCommand);
@@ -38,9 +36,8 @@ void St7789::WriteData(uint8_t data) {
WriteSpi(&data, 1);
}
void St7789::WriteSpi(const uint8_t* data, size_t size) {
spi.Write(data, size);
spi.Write(data, size);
}
void St7789::SoftwareReset() {
@@ -105,7 +102,7 @@ void St7789::SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
WriteData(x1 & 0xff);
WriteCommand(static_cast<uint8_t>(Commands::RowAddressSet));
WriteData(y0>>8);
WriteData(y0 >> 8);
WriteData(y0 & 0xff);
WriteData(y1 >> 8);
WriteData(y1 & 0xff);
@@ -139,21 +136,20 @@ void St7789::VerticalScrollStartAddress(uint16_t line) {
WriteData(line & 0x00ffu);
}
void St7789::Uninit() {
}
void St7789::DrawPixel(uint16_t x, uint16_t y, uint32_t color) {
if((x < 0) ||(x >= Width) || (y < 0) || (y >= Height)) return;
if ((x < 0) || (x >= Width) || (y < 0) || (y >= Height))
return;
SetAddrWindow(x, y, x+1, y+1);
SetAddrWindow(x, y, x + 1, y + 1);
nrf_gpio_pin_set(pinDataCommand);
WriteSpi(reinterpret_cast<const uint8_t *>(&color), 2);
WriteSpi(reinterpret_cast<const uint8_t*>(&color), 2);
}
void St7789::DrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *data, size_t size) {
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);

View File

@@ -6,69 +6,68 @@ namespace Pinetime {
namespace Drivers {
class Spi;
class St7789 {
public:
explicit St7789(Spi& spi, uint8_t pinDataCommand);
St7789(const St7789&) = delete;
St7789& operator=(const St7789&) = delete;
St7789(St7789&&) = delete;
St7789& operator=(St7789&&) = delete;
public:
explicit St7789(Spi& spi, uint8_t pinDataCommand);
St7789(const St7789&) = delete;
St7789& operator=(const St7789&) = delete;
St7789(St7789&&) = delete;
St7789& operator=(St7789&&) = delete;
void Init();
void Uninit();
void DrawPixel(uint16_t x, uint16_t y, uint32_t color);
void Init();
void Uninit();
void DrawPixel(uint16_t x, uint16_t y, uint32_t color);
void VerticalScrollDefinition(uint16_t topFixedLines, uint16_t scrollLines, uint16_t bottomFixedLines);
void VerticalScrollStartAddress(uint16_t line);
void VerticalScrollDefinition(uint16_t topFixedLines, uint16_t scrollLines, uint16_t bottomFixedLines);
void VerticalScrollStartAddress(uint16_t line);
void DrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *data, size_t size);
void DrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data, size_t size);
void DisplayOn();
void DisplayOff();
void DisplayOn();
void DisplayOff();
void Sleep();
void Wakeup();
private:
Spi& spi;
uint8_t pinDataCommand;
uint8_t verticalScrollingStartAddress = 0;
void Sleep();
void Wakeup();
void HardwareReset();
void SoftwareReset();
void SleepOut();
void SleepIn();
void ColMod();
void MemoryDataAccessControl();
void DisplayInversionOn();
void NormalModeOn();
void WriteToRam();
void SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
void WriteCommand(uint8_t cmd);
void WriteSpi(const uint8_t* data, size_t size);
private:
Spi& spi;
uint8_t pinDataCommand;
uint8_t verticalScrollingStartAddress = 0;
enum class Commands : uint8_t {
SoftwareReset = 0x01,
SleepIn = 0x10,
SleepOut = 0x11,
NormalModeOn = 0x13,
DisplayInversionOn = 0x21,
DisplayOff = 0x28,
DisplayOn = 0x29,
ColumnAddressSet = 0x2a,
RowAddressSet = 0x2b,
WriteToRam = 0x2c,
MemoryDataAccessControl = 0x36,
VerticalScrollDefinition = 0x33,
VerticalScrollStartAddress = 0x37,
ColMod = 0x3a,
};
void WriteData(uint8_t data);
void ColumnAddressSet();
void HardwareReset();
void SoftwareReset();
void SleepOut();
void SleepIn();
void ColMod();
void MemoryDataAccessControl();
void DisplayInversionOn();
void NormalModeOn();
void WriteToRam();
void SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
void WriteCommand(uint8_t cmd);
void WriteSpi(const uint8_t* data, size_t size);
static constexpr uint16_t Width = 240;
static constexpr uint16_t Height = 320;
void RowAddressSet();
enum class Commands : uint8_t {
SoftwareReset = 0x01,
SleepIn = 0x10,
SleepOut = 0x11,
NormalModeOn = 0x13,
DisplayInversionOn = 0x21,
DisplayOff = 0x28,
DisplayOn = 0x29,
ColumnAddressSet = 0x2a,
RowAddressSet = 0x2b,
WriteToRam = 0x2c,
MemoryDataAccessControl = 0x36,
VerticalScrollDefinition = 0x33,
VerticalScrollStartAddress = 0x37,
ColMod = 0x3a,
};
void WriteData(uint8_t data);
void ColumnAddressSet();
static constexpr uint16_t Width = 240;
static constexpr uint16_t Height = 320;
void RowAddressSet();
};
}
}

View File

@@ -8,33 +8,39 @@ using namespace Pinetime::Drivers;
// TODO use shortcut to automatically send STOP when receive LastTX, for example
// TODO use DMA/IRQ
TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module{module}, params{params} {
TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module {module}, params {params} {
mutex = xSemaphoreCreateBinary();
}
void TwiMaster::Init() {
NRF_GPIO->PIN_CNF[params.pinScl] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)
| ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
| ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos)
| ((uint32_t)GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos)
| ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
NRF_GPIO->PIN_CNF[params.pinScl] =
((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
NRF_GPIO->PIN_CNF[params.pinSda] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)
| ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
| ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos)
| ((uint32_t)GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos)
| ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
NRF_GPIO->PIN_CNF[params.pinSda] =
((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
switch(module) {
case Modules::TWIM1: twiBaseAddress = NRF_TWIM1; break;
switch (module) {
case Modules::TWIM1:
twiBaseAddress = NRF_TWIM1;
break;
default:
return;
}
switch(static_cast<Frequencies>(params.frequency)) {
case Frequencies::Khz100 : twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K100; break;
case Frequencies::Khz250 : twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K250; break;
case Frequencies::Khz400 : twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K400; break;
switch (static_cast<Frequencies>(params.frequency)) {
case Frequencies::Khz100:
twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K100;
break;
case Frequencies::Khz250:
twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K250;
break;
case Frequencies::Khz400:
twiBaseAddress->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K400;
break;
}
twiBaseAddress->PSEL.SCL = params.pinScl;
@@ -49,7 +55,6 @@ void TwiMaster::Init() {
twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos);
/* // IRQ
NVIC_ClearPendingIRQ(_IRQn);
NVIC_SetPriority(_IRQn, 2);
@@ -57,10 +62,9 @@ void TwiMaster::Init() {
*/
xSemaphoreGive(mutex);
}
TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t *data, size_t size) {
TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* data, size_t size) {
xSemaphoreTake(mutex, portMAX_DELAY);
auto ret = Write(deviceAddress, &registerAddress, 1, false);
ret = Read(deviceAddress, data, size, true);
@@ -68,7 +72,7 @@ TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAdd
return ret;
}
TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t *data, size_t size) {
TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size) {
ASSERT(size <= maxDataSize);
xSemaphoreTake(mutex, portMAX_DELAY);
internalBuffer[0] = registerAddress;
@@ -78,22 +82,23 @@ TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, uint8_t registerAd
return ret;
}
TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t *buffer, size_t size, bool stop) {
TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop) {
twiBaseAddress->ADDRESS = deviceAddress;
twiBaseAddress->TASKS_RESUME = 0x1UL;
twiBaseAddress->RXD.PTR = (uint32_t)buffer;
twiBaseAddress->RXD.PTR = (uint32_t) buffer;
twiBaseAddress->RXD.MAXCNT = size;
twiBaseAddress->TASKS_STARTRX = 1;
while(!twiBaseAddress->EVENTS_RXSTARTED && !twiBaseAddress->EVENTS_ERROR);
while (!twiBaseAddress->EVENTS_RXSTARTED && !twiBaseAddress->EVENTS_ERROR)
;
twiBaseAddress->EVENTS_RXSTARTED = 0x0UL;
txStartedCycleCount = DWT->CYCCNT;
uint32_t currentCycleCount;
while(!twiBaseAddress->EVENTS_LASTRX && !twiBaseAddress->EVENTS_ERROR) {
while (!twiBaseAddress->EVENTS_LASTRX && !twiBaseAddress->EVENTS_ERROR) {
currentCycleCount = DWT->CYCCNT;
if ((currentCycleCount-txStartedCycleCount) > HwFreezedDelay) {
if ((currentCycleCount - txStartedCycleCount) > HwFreezedDelay) {
FixHwFreezed();
return ErrorCodes::TransactionFailed;
}
@@ -102,12 +107,13 @@ TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t *buffer, si
if (stop || twiBaseAddress->EVENTS_ERROR) {
twiBaseAddress->TASKS_STOP = 0x1UL;
while(!twiBaseAddress->EVENTS_STOPPED);
while (!twiBaseAddress->EVENTS_STOPPED)
;
twiBaseAddress->EVENTS_STOPPED = 0x0UL;
}
else {
} else {
twiBaseAddress->TASKS_SUSPEND = 0x1UL;
while(!twiBaseAddress->EVENTS_SUSPENDED);
while (!twiBaseAddress->EVENTS_SUSPENDED)
;
twiBaseAddress->EVENTS_SUSPENDED = 0x0UL;
}
@@ -117,22 +123,23 @@ TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t *buffer, si
return ErrorCodes::NoError;
}
TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, const uint8_t *data, size_t size, bool stop) {
TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop) {
twiBaseAddress->ADDRESS = deviceAddress;
twiBaseAddress->TASKS_RESUME = 0x1UL;
twiBaseAddress->TXD.PTR = (uint32_t)data;
twiBaseAddress->TXD.PTR = (uint32_t) data;
twiBaseAddress->TXD.MAXCNT = size;
twiBaseAddress->TASKS_STARTTX = 1;
while(!twiBaseAddress->EVENTS_TXSTARTED && !twiBaseAddress->EVENTS_ERROR);
while (!twiBaseAddress->EVENTS_TXSTARTED && !twiBaseAddress->EVENTS_ERROR)
;
twiBaseAddress->EVENTS_TXSTARTED = 0x0UL;
txStartedCycleCount = DWT->CYCCNT;
uint32_t currentCycleCount;
while(!twiBaseAddress->EVENTS_LASTTX && !twiBaseAddress->EVENTS_ERROR) {
while (!twiBaseAddress->EVENTS_LASTTX && !twiBaseAddress->EVENTS_ERROR) {
currentCycleCount = DWT->CYCCNT;
if ((currentCycleCount-txStartedCycleCount) > HwFreezedDelay) {
if ((currentCycleCount - txStartedCycleCount) > HwFreezedDelay) {
FixHwFreezed();
return ErrorCodes::TransactionFailed;
}
@@ -141,12 +148,13 @@ TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, const uint8_t *dat
if (stop || twiBaseAddress->EVENTS_ERROR) {
twiBaseAddress->TASKS_STOP = 0x1UL;
while(!twiBaseAddress->EVENTS_STOPPED);
while (!twiBaseAddress->EVENTS_STOPPED)
;
twiBaseAddress->EVENTS_STOPPED = 0x0UL;
}
else {
} else {
twiBaseAddress->TASKS_SUSPEND = 0x1UL;
while(!twiBaseAddress->EVENTS_SUSPENDED);
while (!twiBaseAddress->EVENTS_SUSPENDED)
;
twiBaseAddress->EVENTS_SUSPENDED = 0x0UL;
}
@@ -160,7 +168,7 @@ TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, const uint8_t *dat
}
void TwiMaster::Sleep() {
while(twiBaseAddress->ENABLE != 0) {
while (twiBaseAddress->ENABLE != 0) {
twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos);
}
nrf_gpio_cfg_default(6);
@@ -184,17 +192,15 @@ void TwiMaster::FixHwFreezed() {
uint32_t twi_state = NRF_TWI1->ENABLE;
twiBaseAddress->ENABLE = TWIM_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
NRF_GPIO->PIN_CNF[params.pinScl] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)
| ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
| ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos)
| ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
NRF_GPIO->PIN_CNF[params.pinScl] =
((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
NRF_GPIO->PIN_CNF[params.pinSda] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)
| ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
| ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos)
| ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
NRF_GPIO->PIN_CNF[params.pinSda] =
((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
((uint32_t) GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
// Re-enable I²C
twiBaseAddress->ENABLE = twi_state;

View File

@@ -7,39 +7,38 @@
namespace Pinetime {
namespace Drivers {
class TwiMaster {
public:
enum class Modules { TWIM1 };
enum class Frequencies {Khz100, Khz250, Khz400};
enum class ErrorCodes {NoError, TransactionFailed};
struct Parameters {
uint32_t frequency;
uint8_t pinSda;
uint8_t pinScl;
};
public:
enum class Modules { TWIM1 };
enum class Frequencies { Khz100, Khz250, Khz400 };
enum class ErrorCodes { NoError, TransactionFailed };
struct Parameters {
uint32_t frequency;
uint8_t pinSda;
uint8_t pinScl;
};
TwiMaster(const Modules module, const Parameters& params);
TwiMaster(const Modules module, const Parameters& params);
void Init();
ErrorCodes Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size);
ErrorCodes Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size);
void Init();
ErrorCodes Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size);
ErrorCodes Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size);
void Sleep();
void Wakeup();
void Sleep();
void Wakeup();
private:
ErrorCodes Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop);
ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop);
void FixHwFreezed();
NRF_TWIM_Type* twiBaseAddress;
SemaphoreHandle_t mutex;
const Modules module;
const Parameters params;
static constexpr uint8_t maxDataSize{16};
static constexpr uint8_t registerSize{1};
uint8_t internalBuffer[maxDataSize + registerSize];
uint32_t txStartedCycleCount = 0;
static constexpr uint32_t HwFreezedDelay{161000};
private:
ErrorCodes Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop);
ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop);
void FixHwFreezed();
NRF_TWIM_Type* twiBaseAddress;
SemaphoreHandle_t mutex;
const Modules module;
const Parameters params;
static constexpr uint8_t maxDataSize {16};
static constexpr uint8_t registerSize {1};
uint8_t internalBuffer[maxDataSize + registerSize];
uint32_t txStartedCycleCount = 0;
static constexpr uint32_t HwFreezedDelay {161000};
};
}
}

View File

@@ -2,7 +2,6 @@
#include <mdk/nrf.h>
using namespace Pinetime::Drivers;
void Watchdog::Setup(uint8_t timeoutSeconds) {
NRF_WDT->CONFIG &= ~(WDT_CONFIG_SLEEP_Msk << WDT_CONFIG_SLEEP_Pos);
NRF_WDT->CONFIG |= (WDT_CONFIG_HALT_Run << WDT_CONFIG_SLEEP_Pos);
@@ -12,7 +11,7 @@ void Watchdog::Setup(uint8_t timeoutSeconds) {
/* timeout (s) = (CRV + 1) / 32768 */
// JF : 7500 = 7.5s
uint32_t crv = (((timeoutSeconds*1000u) << 15u) / 1000) - 1;
uint32_t crv = (((timeoutSeconds * 1000u) << 15u) / 1000) - 1;
NRF_WDT->CRV = crv;
/* Enable reload requests */
@@ -33,28 +32,46 @@ Watchdog::ResetReasons Watchdog::ActualResetReason() const {
uint32_t reason = NRF_POWER->RESETREAS;
NRF_POWER->RESETREAS = 0xffffffff;
if(reason & 0x01u) return ResetReasons::ResetPin;
if((reason >> 1u) & 0x01u) return ResetReasons::Watchdog;
if((reason >> 2u) & 0x01u) return ResetReasons::SoftReset;
if((reason >> 3u) & 0x01u) return ResetReasons::CpuLockup;
if((reason >> 16u) & 0x01u) return ResetReasons::SystemOff;
if((reason >> 17u) & 0x01u) return ResetReasons::LpComp;
if((reason) & 0x01u) return ResetReasons::DebugInterface;
if((reason >> 19u) & 0x01u) return ResetReasons::NFC;
if (reason & 0x01u)
return ResetReasons::ResetPin;
if ((reason >> 1u) & 0x01u)
return ResetReasons::Watchdog;
if ((reason >> 2u) & 0x01u)
return ResetReasons::SoftReset;
if ((reason >> 3u) & 0x01u)
return ResetReasons::CpuLockup;
if ((reason >> 16u) & 0x01u)
return ResetReasons::SystemOff;
if ((reason >> 17u) & 0x01u)
return ResetReasons::LpComp;
if ((reason) &0x01u)
return ResetReasons::DebugInterface;
if ((reason >> 19u) & 0x01u)
return ResetReasons::NFC;
return ResetReasons::HardReset;
}
const char *Watchdog::ResetReasonToString(Watchdog::ResetReasons reason) {
switch(reason) {
case ResetReasons::ResetPin: return "Reset pin";
case ResetReasons::Watchdog: return "Watchdog";
case ResetReasons::DebugInterface: return "Debug interface";
case ResetReasons::LpComp: return "LPCOMP";
case ResetReasons::SystemOff: return "System OFF";
case ResetReasons::CpuLockup: return "CPU Lock-up";
case ResetReasons::SoftReset: return "Soft reset";
case ResetReasons::NFC: return "NFC";
case ResetReasons::HardReset: return "Hard reset";
default: return "Unknown";
const char* Watchdog::ResetReasonToString(Watchdog::ResetReasons reason) {
switch (reason) {
case ResetReasons::ResetPin:
return "Reset pin";
case ResetReasons::Watchdog:
return "Watchdog";
case ResetReasons::DebugInterface:
return "Debug interface";
case ResetReasons::LpComp:
return "LPCOMP";
case ResetReasons::SystemOff:
return "System OFF";
case ResetReasons::CpuLockup:
return "CPU Lock-up";
case ResetReasons::SoftReset:
return "Soft reset";
case ResetReasons::NFC:
return "NFC";
case ResetReasons::HardReset:
return "Hard reset";
default:
return "Unknown";
}
}

View File

@@ -4,25 +4,31 @@
namespace Pinetime {
namespace Drivers {
class Watchdog {
public:
enum class ResetReasons { ResetPin, Watchdog, SoftReset, CpuLockup, SystemOff, LpComp, DebugInterface, NFC, HardReset };
void Setup(uint8_t timeoutSeconds);
void Start();
void Kick();
ResetReasons ResetReason() const { return resetReason; }
static const char* ResetReasonToString(ResetReasons reason);
private:
ResetReasons resetReason;
ResetReasons ActualResetReason() const;
public:
enum class ResetReasons { ResetPin, Watchdog, SoftReset, CpuLockup, SystemOff, LpComp, DebugInterface, NFC, HardReset };
void Setup(uint8_t timeoutSeconds);
void Start();
void Kick();
ResetReasons ResetReason() const {
return resetReason;
}
static const char* ResetReasonToString(ResetReasons reason);
private:
ResetReasons resetReason;
ResetReasons ActualResetReason() const;
};
class WatchdogView {
public:
WatchdogView(const Watchdog& watchdog) : watchdog{watchdog} { }
Watchdog::ResetReasons ResetReason() const { return watchdog.ResetReason();}
public:
WatchdogView(const Watchdog& watchdog) : watchdog {watchdog} {
}
Watchdog::ResetReasons ResetReason() const {
return watchdog.ResetReason();
}
private:
const Watchdog& watchdog;
private:
const Watchdog& watchdog;
};
}
}