Refactor TwiMaster as a generic class that implements the concept IsTwi.

This commit is contained in:
Jean-François Milants 2022-12-27 21:22:57 +01:00
parent d8757c50ae
commit 0fa32f3de0
13 changed files with 104 additions and 47 deletions

View File

@ -438,6 +438,7 @@ list(APPEND SOURCE_FILES
drivers/St7789.cpp
drivers/nrf52/SpiMaster.cpp
drivers/nrf52/Spi.cpp
drivers/nrf52/TwiMaster.cpp
drivers/spiFlash/SpiNorFlash.cpp
drivers/Watchdog.cpp
drivers/DebugPins.cpp
@ -484,7 +485,6 @@ list(APPEND SOURCE_FILES
systemtask/SystemTask.cpp
systemtask/SystemMonitor.cpp
drivers/TwiMaster.cpp
heartratetask/HeartRateTask.cpp
components/heartrate/Ppg.cpp
@ -505,6 +505,7 @@ list(APPEND RECOVERY_SOURCE_FILES
drivers/St7789.cpp
drivers/nrf52/SpiMaster.cpp
drivers/nrf52/Spi.cpp
drivers/nrf52/TwiMaster.cpp
drivers/Watchdog.cpp
drivers/DebugPins.cpp
drivers/InternalFlash.cpp
@ -545,7 +546,6 @@ list(APPEND RECOVERY_SOURCE_FILES
systemtask/SystemTask.cpp
systemtask/SystemMonitor.cpp
drivers/TwiMaster.cpp
components/gfx/Gfx.cpp
components/rle/RleDecoder.cpp
components/heartrate/HeartRateController.cpp
@ -567,6 +567,7 @@ list(APPEND RECOVERYLOADER_SOURCE_FILES
drivers/nrf52/SpiMaster.cpp
drivers/nrf52/Spi.cpp
drivers/nrf52/TwiMaster.cpp
logging/NrfLogger.cpp
components/rle/RleDecoder.cpp
@ -620,6 +621,7 @@ set(INCLUDE_FILES
drivers/SpiNorFlash.h
drivers/nrf52/SpiMaster.h
drivers/nrf52/Spi.h
drivers/nrf52/TwiMaster.h
drivers/spiFlash/SpiNorFlash.h
drivers/Watchdog.h
drivers/DebugPins.h

View File

@ -1,9 +1,10 @@
#pragma once
#include "drivers/TwiMaster.h"
#include "port/infinitime.h"
#include <drivers/Bma421_C/bma4_defs.h>
namespace Pinetime {
namespace Drivers {
class TwiMaster;
class Bma421 {
public:
enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 };

View File

@ -1,6 +1,6 @@
#pragma once
#include "drivers/TwiMaster.h"
#include "port/infinitime.h"
namespace Pinetime {
namespace Drivers {

View File

@ -1,6 +1,7 @@
#pragma once
#include "drivers/TwiMaster.h"
#include "port/infinitime.h"
namespace Pinetime {
namespace Drivers {

View File

@ -17,8 +17,7 @@ namespace Pinetime {
requires IsSpi<T>
class Spi {
public:
Spi(T& spi) : impl {spi} {
}
explicit Spi(T& spi) : impl {spi} { }
Spi(const Spi&) = delete;
Spi& operator=(const Spi&) = delete;
Spi(Spi&&) = delete;

View File

@ -23,8 +23,7 @@ namespace Pinetime {
requires IsSpiMaster<T>
class SpiMaster {
public:
SpiMaster(T& spiMaster) : impl {spiMaster} {
}
explicit SpiMaster(T& spiMaster) : impl {spiMaster} { }
SpiMaster(const SpiMaster&) = delete;
SpiMaster& operator=(const SpiMaster&) = delete;
SpiMaster(SpiMaster&&) = delete;

View File

@ -1,41 +1,55 @@
#pragma once
#include <FreeRTOS.h>
#include <semphr.h>
#include <drivers/include/nrfx_twi.h> // NRF_TWIM_Type
#include <concepts>
#include <cstddef>
#include <cstdint>
namespace Pinetime {
namespace Drivers {
class TwiMaster {
public:
enum class ErrorCodes { NoError, TransactionFailed };
template <typename TwiImpl>
concept IsTwi = requires(TwiImpl twi, uint8_t deviceAddress, uint8_t registerAddress, uint8_t* data, const uint8_t* constData, size_t size) {
{ twi.Init() };
{ twi.Write(deviceAddress, registerAddress, constData, size) };
{ twi.Read(deviceAddress, registerAddress, data, size) };
{ twi.Sleep() };
{ twi.Wakeup() };
};
TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, uint8_t pinScl);
namespace Interface {
template <class T>
requires IsTwi<T>
class TwiMaster {
public:
explicit TwiMaster(T& impl) : impl {impl} {}
TwiMaster(const TwiMaster&) = delete;
TwiMaster& operator=(const TwiMaster&) = delete;
TwiMaster(TwiMaster&&) = delete;
TwiMaster& operator=(TwiMaster&&) = delete;
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);
enum class ErrorCodes { NoError, TransactionFailed };
void Sleep();
void Wakeup();
void Init() {
impl.Init();
}
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();
void ConfigurePins() const;
ErrorCodes Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size) {
return static_cast<ErrorCodes>(impl.Read(deviceAddress, registerAddress, buffer, size));
}
NRF_TWIM_Type* twiBaseAddress;
SemaphoreHandle_t mutex = nullptr;
NRF_TWIM_Type* module;
uint32_t frequency;
uint8_t pinSda;
uint8_t pinScl;
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};
};
ErrorCodes Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size) {
return static_cast<ErrorCodes>(impl.Write(deviceAddress, registerAddress, data, size));
}
void Sleep() {
impl.Sleep();
}
void Wakeup() {
impl.WakeUp();
}
private:
T& impl;
};
}
}
}

View File

@ -1,9 +1,9 @@
#include "drivers/TwiMaster.h"
#include "drivers/nrf52/TwiMaster.h"
#include <cstring>
#include <hal/nrf_gpio.h>
#include <nrfx_log.h>
using namespace Pinetime::Drivers;
using namespace Pinetime::Drivers::Nrf52;
// TODO use shortcut to automatically send STOP when receive LastTX, for example
// TODO use DMA/IRQ

View File

@ -0,0 +1,44 @@
#pragma once
#include <FreeRTOS.h>
#include <semphr.h>
#include <drivers/include/nrfx_twi.h> // NRF_TWIM_Type
#include <cstdint>
#include "drivers/TwiMaster.h"
namespace Pinetime {
namespace Drivers {
namespace Nrf52 {
class TwiMaster {
public:
enum class ErrorCodes { NoError, TransactionFailed };
TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, uint8_t pinScl);
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();
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();
void ConfigurePins() const;
NRF_TWIM_Type* twiBaseAddress;
SemaphoreHandle_t mutex = nullptr;
NRF_TWIM_Type* module;
uint32_t frequency;
uint8_t pinSda;
uint8_t pinScl;
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

@ -88,7 +88,8 @@ Pinetime::Drivers::SpiNorFlash spiNorFlash {spiNorFlashImpl};
// respecting correct timings. According to erratas heet, this magic value makes it run
// at ~390Khz with correct timings.
static constexpr uint32_t MaxTwiFrequencyWithoutHardwareBug {0x06200000};
Pinetime::Drivers::TwiMaster twiMaster {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, Pinetime::PinMap::TwiSda, Pinetime::PinMap::TwiScl};
Pinetime::Drivers::Nrf52::TwiMaster twiMasterImpl {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, Pinetime::PinMap::TwiSda, Pinetime::PinMap::TwiScl};
Pinetime::Drivers::TwiMaster twiMaster{twiMasterImpl};
Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress};
#ifdef PINETIME_IS_RECOVERY
#include "displayapp/DummyLittleVgl.h"

View File

@ -1,12 +1,14 @@
#pragma once
#include "drivers/Spi.h"
#include "drivers/SpiMaster.h"
#include "drivers/TwiMaster.h"
#include <cstdint>
#include <drivers/SpiNorFlash.h>
#ifdef TARGET_DEVICE_PINETIME
#include <drivers/nrf52/Spi.h>
#include <drivers/nrf52/SpiMaster.h>
#include <drivers/nrf52/TwiMaster.h>
#include <drivers/spiFlash/SpiNorFlash.h>
#endif
@ -15,6 +17,7 @@ namespace Pinetime {
#ifdef TARGET_DEVICE_PINETIME
using SpiMaster = Interface::SpiMaster<Pinetime::Drivers::Nrf52::SpiMaster>;
using Spi = Interface::Spi<Pinetime::Drivers::Nrf52::Spi>;
using TwiMaster = Interface::TwiMaster<Pinetime::Drivers::Nrf52::TwiMaster>;
using SpiNorFlash = Interface::SpiNorFlash<Pinetime::Drivers::SpiFlash::SpiNorFlash>;
#else
#error "No target device specified!"

View File

@ -8,17 +8,11 @@
#include "displayapp/TouchEvents.h"
#include "drivers/Cst816s.h"
#include "drivers/St7789.h"
#include "drivers/InternalFlash.h"
#include "drivers/SpiMaster.h"
#include "drivers/SpiNorFlash.h"
#include "drivers/TwiMaster.h"
#include "drivers/Hrs3300.h"
#include "drivers/PinMap.h"
#include "main.h"
#include "BootErrors.h"
#include <memory>
using namespace Pinetime::System;
namespace {

View File

@ -42,7 +42,6 @@ namespace Pinetime {
namespace Drivers {
class Cst816S;
class St7789;
class TwiMaster;
class Hrs3300;
}
namespace Controllers {