Skip to content

Commit

Permalink
Replace templates with abstract class for PDPhy
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelbl committed Apr 7, 2024
1 parent 0d25cef commit ac6d81b
Show file tree
Hide file tree
Showing 16 changed files with 155 additions and 182 deletions.
10 changes: 5 additions & 5 deletions dev/ListCapabilities/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@

#if defined(ARDUINO_ARCH_ESP32)

typedef PDPhyFUSB302 PDPhy;
typedef PDPhyFUSB302 Phy;
#define USB_PD_PHY USB_PD_PHY_FUSB302

#elif defined(ARDUINO_ARCH_STM32)

typedef PDPhySTM32UCPD PDPhy;
typedef PDPhySTM32UCPD Phy;
#define USB_PD_PHY USB_PD_PHY_UCPD1

#endif
Expand All @@ -34,9 +34,9 @@ static void handleEvent(PDSinkEventType eventType);
static void listCapabilities();
static const char* getSupplyTypeName(PDSupplyType type);

static PDPhy pdPhy;
static PDController<PDPhy> powerController(&pdPhy);
static PDSink<PDController<PDPhy>> sink(&powerController);
static Phy pdPhy;
static PDController powerController(&pdPhy);
static PDSink sink(&powerController);

void setup() {
Serial.begin(115200);
Expand Down
12 changes: 6 additions & 6 deletions dev/VoltageChange/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@

#if defined(ARDUINO_ARCH_ESP32)

typedef PDPhyFUSB302 PDPhy;
typedef PDPhyFUSB302 Phy;
#define USB_PD_PHY USB_PD_PHY_FUSB302

#elif defined(ARDUINO_ARCH_STM32)

typedef PDPhySTM32UCPD PDPhy;
typedef PDPhySTM32UCPD Phy;
#define USB_PD_PHY USB_PD_PHY_UCPD1

#endif
Expand All @@ -38,10 +38,10 @@ static bool isUSBPDSource = false;
static uint32_t nextVoltageChangeTime = 0;
static int voltageIndex = 0;

static PDPhy pdPhy;
static PDController<PDPhy> powerController(&pdPhy);
static PDProtocolAnalyzer<PDController<PDPhy>> protocolAnalyzer(&powerController);
static PDSink<PDController<PDPhy>> sink(&powerController);
static Phy pdPhy;
static PDController powerController(&pdPhy);
static PDProtocolAnalyzer protocolAnalyzer(&powerController);
static PDSink sink(&powerController);

void setup() {
Serial.begin(115200);
Expand Down
10 changes: 5 additions & 5 deletions examples/ListCapabilities/ListCapabilities.ino
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@

#if defined(ARDUINO_ARCH_ESP32)

typedef PDPhyFUSB302 PDPhy;
typedef PDPhyFUSB302 Phy;
#define USB_PD_PHY USB_PD_PHY_FUSB302

#elif defined(ARDUINO_ARCH_STM32)

typedef PDPhySTM32UCPD PDPhy;
typedef PDPhySTM32UCPD Phy;
#define USB_PD_PHY USB_PD_PHY_UCPD1

#endif

#include "USBPowerDeliveryCode.h"


static PDPhy pdPhy;
static PDController<PDPhy> powerController(&pdPhy);
static PDSink<PDController<PDPhy>> sink(&powerController);
static Phy pdPhy;
static PDController powerController(&pdPhy);
static PDSink sink(&powerController);


void setup() {
Expand Down
10 changes: 5 additions & 5 deletions examples/TriggerBoard/TriggerBoard.ino
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@

#if defined(ARDUINO_ARCH_ESP32)

typedef PDPhyFUSB302 PDPhy;
typedef PDPhyFUSB302 Phy;
#define USB_PD_PHY USB_PD_PHY_FUSB302

#elif defined(ARDUINO_ARCH_STM32)

typedef PDPhySTM32UCPD PDPhy;
typedef PDPhySTM32UCPD Phy;
#define USB_PD_PHY USB_PD_PHY_UCPD1

#endif

#include "USBPowerDeliveryCode.h"


static PDPhy pdPhy;
static PDController<PDPhy> powerController(&pdPhy);
static PDSink<PDController<PDPhy>> sink(&powerController);
static Phy pdPhy;
static PDController powerController(&pdPhy);
static PDSink sink(&powerController);


void setup() {
Expand Down
10 changes: 5 additions & 5 deletions examples/TriggerBoardAdvanced/TriggerBoardAdvanced.ino
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@

#if defined(ARDUINO_ARCH_ESP32)

typedef PDPhyFUSB302 PDPhy;
typedef PDPhyFUSB302 Phy;
#define USB_PD_PHY USB_PD_PHY_FUSB302

#elif defined(ARDUINO_ARCH_STM32)

typedef PDPhySTM32UCPD PDPhy;
typedef PDPhySTM32UCPD Phy;
#define USB_PD_PHY USB_PD_PHY_UCPD1

#endif

#include "USBPowerDeliveryCode.h"


static PDPhy pdPhy;
static PDController<PDPhy> powerController(&pdPhy);
static PDSink<PDController<PDPhy>> sink(&powerController);
static Phy pdPhy;
static PDController powerController(&pdPhy);
static PDSink sink(&powerController);


void setup() {
Expand Down
65 changes: 16 additions & 49 deletions src/PDController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,36 @@
#include "TaskScheduler.h"


template <class Phy>
PDController<Phy>::PDController(Phy* phy) :
PDController::PDController(PDPhy* phy) :
ccPin(0), eventHandler(nullptr), phy(phy), isMonitorOnly(true), isPhyGoodCrc(false),
rxMessageHead(rxBuffer), txMessage((PDMessage*)txBuffer),
txMessageId(0), txRetryCount(0), lastRxMessageId(-1), lastSpecRev(1), lastMessage(nullptr) {}

template <class Phy>
void PDController<Phy>::setGoodCrcHandling(bool phyGoodCrc) {
void PDController::setGoodCrcHandling(bool phyGoodCrc) {
isPhyGoodCrc = phyGoodCrc;
}

template <class Phy>
void PDController<Phy>::startController(EventHandlerFunction handler) {
void PDController::startController(EventHandlerFunction handler) {
eventHandler = handler;
isMonitorOnly = false;
phy->startSink(this);
reset();
}

template <class Phy>
const PDLogEntry* PDController<Phy>::popLogEntry() {
const PDLogEntry* PDController::popLogEntry() {
bool found = logEntries.get(currentLogEntry);
return found ? &currentLogEntry : nullptr;
}

template <class Phy>
void PDController<Phy>::log(PDLogEntryType type, const PDMessage* message) {
void PDController::log(PDLogEntryType type, const PDMessage* message) {
PDLogEntry entry;
entry.type = type;
entry.time = micros();
entry.message = message;
logEntries.put(entry);
}

template <class Phy>
void PDController<Phy>::reset() {
void PDController::reset() {
lastRxMessageId = -1;
txMessageId = 0;
txRetryCount = 0;
Expand All @@ -60,25 +54,22 @@ void PDController<Phy>::reset() {
eventHandler(PDControllerEvent(PDControllerEventType::reset));
}

template <class Phy>
void PDController<Phy>::onReset(PDSOPSequence seq) {
void PDController::onReset(PDSOPSequence seq) {
reset();
log(seq == PDSOPSequence::hardReset ? PDLogEntryType::hardReset : PDLogEntryType::cableReset);
if (eventHandler != nullptr)
eventHandler(PDControllerEvent(PDControllerEventType::reset));
}

template <class Phy>
bool PDController<Phy>::sendControlMessage(PDMessageType messageType) {
bool PDController::sendControlMessage(PDMessageType messageType) {
if (isTransmitting())
return false;
txMessage->initControl(messageType, lastSpecRev);
txRetryCount = paramNRetryCount + 1;
return sendMessage();
}

template <class Phy>
bool PDController<Phy>::sendDataMessage(PDMessageType messageType, int numObjects, const uint32_t* objects) {
bool PDController::sendDataMessage(PDMessageType messageType, int numObjects, const uint32_t* objects) {
if (isTransmitting())
return false;
txMessage->initData(messageType, numObjects, lastSpecRev);
Expand All @@ -87,8 +78,7 @@ bool PDController<Phy>::sendDataMessage(PDMessageType messageType, int numObject
return sendMessage();
}

template <class Phy>
bool PDController<Phy>::sendMessage() {
bool PDController::sendMessage() {
// add message ID
if (isPhyGoodCrc) {
txMessage->setMessageId(txMessageId);
Expand All @@ -105,8 +95,7 @@ bool PDController<Phy>::sendMessage() {
return true;
}

template <class Phy>
void PDController<Phy>::onMessageTransmitted(bool successful) {
void PDController::onMessageTransmitted(bool successful) {

if (!successful) {
log(PDLogEntryType::transmissionFailed);
Expand Down Expand Up @@ -140,8 +129,7 @@ void PDController<Phy>::onMessageTransmitted(bool successful) {
}
}

template <class Phy>
void PDController<Phy>::onNoGoodCrcReceived() {
void PDController::onNoGoodCrcReceived() {
Scheduler.cancelTask(TaskIdNoGoodCrcReceived);

txRetryCount -= 1;
Expand All @@ -155,8 +143,7 @@ void PDController<Phy>::onNoGoodCrcReceived() {
}
}

template <class Phy>
void PDController<Phy>::onMessageReceived(PDMessage* message) {
void PDController::onMessageReceived(PDMessage* message) {
int messageId = message->messageId();
PDMessageType type = message->type();
PDSOPSequence sopSeq = message->sopSequence;
Expand Down Expand Up @@ -209,8 +196,7 @@ void PDController<Phy>::onMessageReceived(PDMessage* message) {
}
}

template <class Phy>
void PDController<Phy>::prepareNextTxMessage() {
void PDController::prepareNextTxMessage() {
txRetryCount = 0;

if (isPhyGoodCrc) {
Expand All @@ -233,35 +219,16 @@ void PDController<Phy>::prepareNextTxMessage() {
txMessage = (PDMessage*)head;
}

template <class Phy>
void PDController<Phy>::onError() {
void PDController::onError() {
log(PDLogEntryType::error);

// re-setup same buffer for reception
phy->prepareRead(reinterpret_cast<PDMessage*>(rxMessageHead));
}

template <class Phy>
void PDController<Phy>::onVoltageChanged(int cc) {
void PDController::onVoltageChanged(int cc) {
ccPin = cc;
log(cc == 0 ? PDLogEntryType::sinkSourceDisconnected : PDLogEntryType::sinkSourceConnected);
if (eventHandler != nullptr)
eventHandler(PDControllerEvent(cc == 0 ? PDControllerEventType::disconnected : PDControllerEventType::connected));
}


// template instantiation

#if defined(ARDUINO_ARCH_ESP32)

#include "phy/ESP32FUSB302/PDPhyFUSB302.h"
template class PDController<PDPhyFUSB302>;

#elif defined(ARDUINO_ARCH_STM32)

#if defined(STM32G0xx) || defined(STM32G4xx)
#include "phy/STM32UCPD/PDPhySTM32UCPD.h"
template class PDController<PDPhySTM32UCPD>;
#endif

#endif
36 changes: 21 additions & 15 deletions src/PDController.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#pragma once

#include <functional>
#include "PDMessage.h"
#include "PDPhy.h"
#include "RingBuffer.h"


Expand Down Expand Up @@ -94,10 +94,7 @@ struct PDControllerEvent {
*
* As USB PD communication is timing sensitive, most code will run as part of
* an interrupt handler.
*
* @tparam Phy Physical layer implementation (e.g. PDPhySTM32F4)
*/
template <class Phy>
class PDController {
public:
/// Event handler function to be called when an event occurs (called from interrupt)
Expand All @@ -108,7 +105,7 @@ class PDController {
*
* @param phy Physical layer instance
*/
PDController(Phy* phy);
PDController(PDPhy* phy);

/**
* @brief Set the GoodCRC handling.
Expand Down Expand Up @@ -154,6 +151,24 @@ class PDController {
/// Starts sending a data message
bool sendDataMessage(PDMessageType messageType, int numObjects, const uint32_t* objects);

// --- handlers called from PDPhy IRQ handlers

/// Called when the voltage has changed
/// @param cc indicates the active CC line (1 or 2), or 0 if no USB PD communication is active
void onVoltageChanged(int cc);

/// Called when an error has occurred
void onError();

/// Called when a message has been transmitted
void onMessageTransmitted(bool successful);

/// Called when a message has been received
void onMessageReceived(PDMessage* message);

/// Called when a reset has been detected (hard reset, soft reset etc.)
void onReset(PDSOPSequence seq);

private:
static constexpr int LogSize = 32;
static constexpr int RxBufferLength = 512;
Expand All @@ -166,7 +181,7 @@ class PDController {
static constexpr int TaskIdNoGoodCrcReceived = 801;

EventHandlerFunction eventHandler;
Phy* phy;
PDPhy* phy;
bool isMonitorOnly;
bool isPhyGoodCrc;

Expand Down Expand Up @@ -195,13 +210,4 @@ class PDController {
void prepareNextTxMessage();

void onNoGoodCrcReceived();

// handlers called from PhyPD IRQ handler
void onVoltageChanged(int cc);
void onError();
void onMessageTransmitted(bool successful);
void onMessageReceived(PDMessage* message);
void onReset(PDSOPSequence seq);

friend Phy;
};
Loading

0 comments on commit ac6d81b

Please sign in to comment.