1
0
forked from me/IronOS

Formatting

This commit is contained in:
Ben V. Brown
2021-05-01 12:22:06 +10:00
parent 0bfe052127
commit 2ca2f9084f
3 changed files with 159 additions and 175 deletions

View File

@@ -23,148 +23,141 @@
#include <pd.h> #include <pd.h>
void fusb_send_message(const union pd_msg *msg) { void fusb_send_message(const union pd_msg *msg) {
/* Token sequences for the FUSB302B */ /* Token sequences for the FUSB302B */
static uint8_t sop_seq[5] = { FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP1, static uint8_t sop_seq[5] = {FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP2, FUSB_FIFO_TX_PACKSYM};
FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP2, FUSB_FIFO_TX_PACKSYM }; static const uint8_t eop_seq[4] = {FUSB_FIFO_TX_JAM_CRC, FUSB_FIFO_TX_EOP, FUSB_FIFO_TX_TXOFF, FUSB_FIFO_TX_TXON};
static const uint8_t eop_seq[4] = { FUSB_FIFO_TX_JAM_CRC, FUSB_FIFO_TX_EOP,
FUSB_FIFO_TX_TXOFF, FUSB_FIFO_TX_TXON };
/* Take the I2C2 mutex now so there can't be a race condition on sop_seq */ /* Take the I2C2 mutex now so there can't be a race condition on sop_seq */
/* Get the length of the message: a two-octet header plus NUMOBJ four-octet /* Get the length of the message: a two-octet header plus NUMOBJ four-octet
* data objects */ * data objects */
uint8_t msg_len = 2 + 4 * PD_NUMOBJ_GET(msg); uint8_t msg_len = 2 + 4 * PD_NUMOBJ_GET(msg);
/* Set the number of bytes to be transmitted in the packet */ /* Set the number of bytes to be transmitted in the packet */
sop_seq[4] = FUSB_FIFO_TX_PACKSYM | msg_len; sop_seq[4] = FUSB_FIFO_TX_PACKSYM | msg_len;
/* Write all three parts of the message to the TX FIFO */ /* Write all three parts of the message to the TX FIFO */
fusb_write_buf(FUSB_FIFOS, 5, sop_seq); fusb_write_buf(FUSB_FIFOS, 5, sop_seq);
fusb_write_buf(FUSB_FIFOS, msg_len, msg->bytes); fusb_write_buf(FUSB_FIFOS, msg_len, msg->bytes);
fusb_write_buf(FUSB_FIFOS, 4, eop_seq); fusb_write_buf(FUSB_FIFOS, 4, eop_seq);
} }
bool fusb_rx_pending() { bool fusb_rx_pending() { return (fusb_read_byte(FUSB_STATUS1) & FUSB_STATUS1_RX_EMPTY) != FUSB_STATUS1_RX_EMPTY; }
return (fusb_read_byte( FUSB_STATUS1) & FUSB_STATUS1_RX_EMPTY)
!= FUSB_STATUS1_RX_EMPTY;
}
uint8_t fusb_read_message(union pd_msg *msg) { uint8_t fusb_read_message(union pd_msg *msg) {
static uint8_t garbage[4]; static uint8_t garbage[4];
uint8_t numobj; uint8_t numobj;
// Read the header. If its not a SOP we dont actually want it at all // Read the header. If its not a SOP we dont actually want it at all
// But on some revisions of the fusb if you dont both pick them up and read them out of the fifo, it gets stuck // But on some revisions of the fusb if you dont both pick them up and read them out of the fifo, it gets stuck
if ((fusb_read_byte( FUSB_FIFOS) & FUSB_FIFO_RX_TOKEN_BITS) if ((fusb_read_byte(FUSB_FIFOS) & FUSB_FIFO_RX_TOKEN_BITS) != FUSB_FIFO_RX_SOP) {
!= FUSB_FIFO_RX_SOP) { return 1;
return 1; }
}
// fusb_read_byte(FUSB_FIFOS); // fusb_read_byte(FUSB_FIFOS);
/* Read the message header into msg */ /* Read the message header into msg */
fusb_read_buf(FUSB_FIFOS, 2, msg->bytes); fusb_read_buf(FUSB_FIFOS, 2, msg->bytes);
/* Get the number of data objects */ /* Get the number of data objects */
numobj = PD_NUMOBJ_GET(msg); numobj = PD_NUMOBJ_GET(msg);
/* If there is at least one data object, read the data objects */ /* If there is at least one data object, read the data objects */
if (numobj > 0) { if (numobj > 0) {
fusb_read_buf(FUSB_FIFOS, numobj * 4, msg->bytes + 2); fusb_read_buf(FUSB_FIFOS, numobj * 4, msg->bytes + 2);
} }
/* Throw the CRC32 in the garbage, since the PHY already checked it. */ /* Throw the CRC32 in the garbage, since the PHY already checked it. */
fusb_read_buf(FUSB_FIFOS, 4, garbage); fusb_read_buf(FUSB_FIFOS, 4, garbage);
return 0; return 0;
} }
void fusb_send_hardrst() { void fusb_send_hardrst() {
/* Send a hard reset */ /* Send a hard reset */
fusb_write_byte(FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET); fusb_write_byte(FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET);
} }
bool fusb_setup() { bool fusb_setup() {
/* Fully reset the FUSB302B */ /* Fully reset the FUSB302B */
fusb_write_byte(FUSB_RESET, FUSB_RESET_SW_RES); fusb_write_byte(FUSB_RESET, FUSB_RESET_SW_RES);
vTaskDelay(TICKS_10MS); vTaskDelay(TICKS_10MS);
uint8_t tries = 0; uint8_t tries = 0;
while (!fusb_read_id()) { while (!fusb_read_id()) {
vTaskDelay(TICKS_10MS); vTaskDelay(TICKS_10MS);
tries++; tries++;
if (tries > 5) { if (tries > 5) {
return false; // Welp :( return false; // Welp :(
} }
} }
/* Turn on all power */ /* Turn on all power */
fusb_write_byte(FUSB_POWER, 0x0F); fusb_write_byte(FUSB_POWER, 0x0F);
/* Set interrupt masks */ /* Set interrupt masks */
// Setting to 0 so interrupts are allowed // Setting to 0 so interrupts are allowed
fusb_write_byte(FUSB_MASK1, 0x00); fusb_write_byte(FUSB_MASK1, 0x00);
fusb_write_byte(FUSB_MASKA, 0x00); fusb_write_byte(FUSB_MASKA, 0x00);
fusb_write_byte(FUSB_MASKB, 0x00); fusb_write_byte(FUSB_MASKB, 0x00);
fusb_write_byte(FUSB_CONTROL0, 0b11 << 2); fusb_write_byte(FUSB_CONTROL0, 0b11 << 2);
/* Enable automatic retransmission */ /* Enable automatic retransmission */
fusb_write_byte(FUSB_CONTROL3, 0x07); fusb_write_byte(FUSB_CONTROL3, 0x07);
// set defaults // set defaults
fusb_write_byte(FUSB_CONTROL2, 0x00); fusb_write_byte(FUSB_CONTROL2, 0x00);
/* Flush the RX buffer */ /* Flush the RX buffer */
fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH); fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
/* Measure CC1 */ /* Measure CC1 */
fusb_write_byte(FUSB_SWITCHES0, 0x07); fusb_write_byte(FUSB_SWITCHES0, 0x07);
vTaskDelay(TICKS_10MS); vTaskDelay(TICKS_10MS);
uint8_t cc1 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL; uint8_t cc1 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
/* Measure CC2 */ /* Measure CC2 */
fusb_write_byte(FUSB_SWITCHES0, 0x0B); fusb_write_byte(FUSB_SWITCHES0, 0x0B);
vTaskDelay(TICKS_10MS); vTaskDelay(TICKS_10MS);
uint8_t cc2 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL; uint8_t cc2 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
/* Select the correct CC line for BMC signaling; also enable AUTO_CRC */ /* Select the correct CC line for BMC signaling; also enable AUTO_CRC */
if (cc1 > cc2) { if (cc1 > cc2) {
fusb_write_byte(FUSB_SWITCHES1, 0x25); // TX_CC1|AUTO_CRC|SPECREV0 fusb_write_byte(FUSB_SWITCHES1, 0x25); // TX_CC1|AUTO_CRC|SPECREV0
fusb_write_byte(FUSB_SWITCHES0, 0x07); // PWDN1|PWDN2|MEAS_CC1 fusb_write_byte(FUSB_SWITCHES0, 0x07); // PWDN1|PWDN2|MEAS_CC1
} else { } else {
fusb_write_byte(FUSB_SWITCHES1, 0x26); // TX_CC2|AUTO_CRC|SPECREV0 fusb_write_byte(FUSB_SWITCHES1, 0x26); // TX_CC2|AUTO_CRC|SPECREV0
fusb_write_byte(FUSB_SWITCHES0, 0x0B); // PWDN1|PWDN2|MEAS_CC2 fusb_write_byte(FUSB_SWITCHES0, 0x0B); // PWDN1|PWDN2|MEAS_CC2
} }
fusb_reset(); fusb_reset();
setupFUSBIRQ(); setupFUSBIRQ();
return true; return true;
} }
bool fusb_get_status(union fusb_status *status) { bool fusb_get_status(union fusb_status *status) {
/* Read the interrupt and status flags into status */ /* Read the interrupt and status flags into status */
return fusb_read_buf(FUSB_STATUS0A, 7, status->bytes); return fusb_read_buf(FUSB_STATUS0A, 7, status->bytes);
} }
enum fusb_typec_current fusb_get_typec_current() { enum fusb_typec_current fusb_get_typec_current() {
/* Read the BC_LVL into a variable */ /* Read the BC_LVL into a variable */
enum fusb_typec_current bc_lvl = (enum fusb_typec_current) (fusb_read_byte( enum fusb_typec_current bc_lvl = (enum fusb_typec_current)(fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL);
FUSB_STATUS0) & FUSB_STATUS0_BC_LVL);
return bc_lvl; return bc_lvl;
} }
void fusb_reset() { void fusb_reset() {
/* Flush the TX buffer */ /* Flush the TX buffer */
fusb_write_byte(FUSB_CONTROL0, 0x44); fusb_write_byte(FUSB_CONTROL0, 0x44);
/* Flush the RX buffer */ /* Flush the RX buffer */
fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH); fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
/* Reset the PD logic */ /* Reset the PD logic */
fusb_write_byte( FUSB_RESET, FUSB_RESET_PD_RESET); fusb_write_byte(FUSB_RESET, FUSB_RESET_PD_RESET);
} }
bool fusb_read_id() { bool fusb_read_id() {
// Return true if read of the revision ID is sane // Return true if read of the revision ID is sane
uint8_t version = 0; uint8_t version = 0;
fusb_read_buf(FUSB_DEVICE_ID, 1, &version); fusb_read_buf(FUSB_DEVICE_ID, 1, &version);
if (version == 0 || version == 0xFF) if (version == 0 || version == 0xFF)
return false; return false;
return true; return true;
} }

View File

@@ -27,87 +27,78 @@
#include <string.h> #include <string.h>
volatile osThreadId InterruptHandler::TaskHandle = NULL; volatile osThreadId InterruptHandler::TaskHandle = NULL;
uint32_t InterruptHandler::TaskBuffer[InterruptHandler::TaskStackSize]; uint32_t InterruptHandler::TaskBuffer[InterruptHandler::TaskStackSize];
osStaticThreadDef_t InterruptHandler::TaskControlBlock; osStaticThreadDef_t InterruptHandler::TaskControlBlock;
union pd_msg InterruptHandler::tempMessage; union pd_msg InterruptHandler::tempMessage;
void InterruptHandler::init() { void InterruptHandler::init() {
TaskHandle = NULL; TaskHandle = NULL;
osThreadStaticDef(intTask, Thread, PDB_PRIO_PRL_INT_N, 0, TaskStackSize, osThreadStaticDef(intTask, Thread, PDB_PRIO_PRL_INT_N, 0, TaskStackSize, TaskBuffer, &TaskControlBlock);
TaskBuffer, &TaskControlBlock); TaskHandle = osThreadCreate(osThread(intTask), NULL);
TaskHandle = osThreadCreate(osThread(intTask), NULL);
} }
volatile uint32_t msgCounter = 0; volatile uint32_t msgCounter = 0;
volatile uint32_t msgCounter1 = 0; volatile uint32_t msgCounter1 = 0;
void InterruptHandler::readPendingMessage() { void InterruptHandler::readPendingMessage() {
memset(&tempMessage, 0, sizeof(tempMessage)); memset(&tempMessage, 0, sizeof(tempMessage));
while (fusb_rx_pending()) { while (fusb_rx_pending()) {
msgCounter++; msgCounter++;
/* Read the message */ /* Read the message */
if (fusb_read_message(&tempMessage) == 0) { if (fusb_read_message(&tempMessage) == 0) {
/* If it's a Soft_Reset, go to the soft reset state */ /* If it's a Soft_Reset, go to the soft reset state */
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET && PD_NUMOBJ_GET(&tempMessage) == 0) {
&& PD_NUMOBJ_GET(&tempMessage) == 0) { /* TX transitions to its reset state */
/* TX transitions to its reset state */ PolicyEngine::notify(PolicyEngine::Notifications::PDB_EVT_PE_RESET);
PolicyEngine::notify( } else {
PolicyEngine::Notifications::PDB_EVT_PE_RESET); /* Tell PolicyEngine to discard the message being transmitted */
} else { PolicyEngine::notify(PolicyEngine::Notifications::PDB_EVT_TX_DISCARD);
/* Tell PolicyEngine to discard the message being transmitted */
PolicyEngine::notify(
PolicyEngine::Notifications::PDB_EVT_TX_DISCARD);
/* Pass the message to the policy engine. */ /* Pass the message to the policy engine. */
PolicyEngine::handleMessage(&tempMessage); PolicyEngine::handleMessage(&tempMessage);
} }
} else { } else {
msgCounter1++; msgCounter1++;
} }
} }
} }
void InterruptHandler::Thread(const void *arg) { void InterruptHandler::Thread(const void *arg) {
(void) arg; (void)arg;
union fusb_status status; union fusb_status status;
for (;;) { for (;;) {
// If the irq is low continue, otherwise wait for irq or timeout // If the irq is low continue, otherwise wait for irq or timeout
if (!getFUS302IRQLow()) { if (!getFUS302IRQLow()) {
xTaskNotifyWait(0x00, 0x0F, NULL, TICKS_SECOND * 30); xTaskNotifyWait(0x00, 0x0F, NULL, TICKS_SECOND * 30);
} }
/* Read the FUSB302B status and interrupt registers */ /* Read the FUSB302B status and interrupt registers */
if (fusb_get_status(&status)) { if (fusb_get_status(&status)) {
/* If the I_GCRCSENT flag is set, tell the Protocol RX thread */ /* If the I_GCRCSENT flag is set, tell the Protocol RX thread */
// This means a message was received with a good CRC // This means a message was received with a good CRC
if (status.interruptb & FUSB_INTERRUPTB_I_GCRCSENT) { if (status.interruptb & FUSB_INTERRUPTB_I_GCRCSENT) {
readPendingMessage(); readPendingMessage();
} }
/* If the I_TXSENT or I_RETRYFAIL flag is set, tell the Protocol TX /* If the I_TXSENT or I_RETRYFAIL flag is set, tell the Protocol TX
* thread */ * thread */
if (status.interrupta & FUSB_INTERRUPTA_I_TXSENT) { if (status.interrupta & FUSB_INTERRUPTA_I_TXSENT) {
PolicyEngine::notify( PolicyEngine::notify(PolicyEngine::Notifications::PDB_EVT_TX_I_TXSENT);
PolicyEngine::Notifications::PDB_EVT_TX_I_TXSENT); }
} if (status.interrupta & FUSB_INTERRUPTA_I_RETRYFAIL) {
if (status.interrupta & FUSB_INTERRUPTA_I_RETRYFAIL) { PolicyEngine::notify(PolicyEngine::Notifications::PDB_EVT_TX_I_RETRYFAIL);
PolicyEngine::notify( }
PolicyEngine::Notifications::PDB_EVT_TX_I_RETRYFAIL);
}
/* If the I_OCP_TEMP and OVRTEMP flags are set, tell the Policy /* If the I_OCP_TEMP and OVRTEMP flags are set, tell the Policy
* Engine thread */ * Engine thread */
if ((status.interrupta & FUSB_INTERRUPTA_I_OCP_TEMP) if ((status.interrupta & FUSB_INTERRUPTA_I_OCP_TEMP) && (status.status1 & FUSB_STATUS1_OVRTEMP)) {
&& (status.status1 & FUSB_STATUS1_OVRTEMP)) { PolicyEngine::notify(PolicyEngine::Notifications::PDB_EVT_PE_I_OVRTEMP);
PolicyEngine::notify( }
PolicyEngine::Notifications::PDB_EVT_PE_I_OVRTEMP); }
} }
}
}
} }
void InterruptHandler::irqCallback() { void InterruptHandler::irqCallback() {
if (TaskHandle != NULL) { if (TaskHandle != NULL) {
BaseType_t taskWoke = pdFALSE; BaseType_t taskWoke = pdFALSE;
xTaskNotifyFromISR(TaskHandle, 0x01, eNotifyAction::eSetBits, xTaskNotifyFromISR(TaskHandle, 0x01, eNotifyAction::eSetBits, &taskWoke);
&taskWoke); portYIELD_FROM_ISR(taskWoke);
portYIELD_FROM_ISR(taskWoke); }
}
} }

View File

@@ -631,9 +631,9 @@ EventBits_t PolicyEngine::pushMessage(union pd_msg *msg) {
/* PD 3.0 collision avoidance */ /* PD 3.0 collision avoidance */
if (PolicyEngine::isPD3_0()) { if (PolicyEngine::isPD3_0()) {
/* If we're starting an AMS, wait for permission to transmit */ /* If we're starting an AMS, wait for permission to transmit */
// while (fusb_get_typec_current() != fusb_sink_tx_ok) { // while (fusb_get_typec_current() != fusb_sink_tx_ok) {
// vTaskDelay(TICKS_10MS); // vTaskDelay(TICKS_10MS);
// } // }
} }
/* Send the message to the PHY */ /* Send the message to the PHY */
fusb_send_message(msg); fusb_send_message(msg);