Merge pull request #686 from Ralim/looking_at_i2c

Fixing up a load bearing bug in the i2c setup (and fixing up some PD logic for free)
This commit is contained in:
Ben V. Brown
2020-09-06 11:05:39 +10:00
committed by GitHub
16 changed files with 116 additions and 425 deletions

View File

@@ -7,8 +7,7 @@
#include <I2C_Wrapper.hpp> #include <I2C_Wrapper.hpp>
#include "BSP.h" #include "BSP.h"
#include "Setup.h" #include "Setup.h"
#define I2CUSESDMA SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr;
SemaphoreHandle_t FRToSI2C::I2CSemaphore;
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer; StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
void FRToSI2C::CpltCallback() { void FRToSI2C::CpltCallback() {
@@ -21,45 +20,22 @@ void FRToSI2C::CpltCallback() {
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size) { uint8_t *pData, uint16_t Size) {
if (I2CSemaphore == NULL) { if (!lock())
// no RToS, run blocking code return false;
HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress,
pData, Size, 5000); I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
return true;
} else {
// RToS is active, run threading
// Get the mutex so we can use the I2C port
// Wait up to 1 second for the mutex
if (xSemaphoreTake(I2CSemaphore, (TickType_t)500) == pdTRUE) {
#ifdef I2CUSESDMA
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress,
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
I2C_Unstick(); I2C_Unstick();
xSemaphoreGive(I2CSemaphore); unlock();
return false; return false;
} else {
xSemaphoreGive(I2CSemaphore);
return true;
}
#else
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, Size,
5000)==HAL_OK){
xSemaphoreGive(I2CSemaphore);
return true;
}
xSemaphoreGive(I2CSemaphore);
return false;
#endif
} else {
return false;
}
} }
unlock();
return true;
} }
void FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) { bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
Mem_Write(address, reg, &data, 1); return Mem_Write(address, reg, &data, 1);
} }
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) { uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
@@ -67,67 +43,55 @@ uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
Mem_Read(add, reg, tx_data, 1); Mem_Read(add, reg, tx_data, 1);
return tx_data[0]; return tx_data[0];
} }
void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size) { uint8_t *pData, uint16_t Size) {
if (I2CSemaphore == NULL) { if (!lock())
// no RToS, run blocking code return false;
HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress,
pData, Size, 5000); I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
} else {
// RToS is active, run threading
// Get the mutex so we can use the I2C port
// Wait up to 1 second for the mutex
if (xSemaphoreTake(I2CSemaphore, (TickType_t)500) == pdTRUE) {
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress,
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
I2C_Unstick(); I2C_Unstick();
xSemaphoreGive(I2CSemaphore); unlock();
} return false;
xSemaphoreGive(I2CSemaphore);
}
} }
unlock();
return true;
} }
void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) { bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
if (I2CSemaphore == NULL) { if (!lock())
// no RToS, run blocking code return false;
HAL_I2C_Master_Transmit(&hi2c1, DevAddress, pData, Size, 5000); if (HAL_I2C_Master_Transmit_DMA(&hi2c1, DevAddress, pData, Size)
} else { != HAL_OK) {
// RToS is active, run threading I2C_Unstick();
// Get the mutex so we can use the I2C port unlock();
// Wait up to 1 second for the mutex return false;
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
#ifdef I2CUSESDMA
if (HAL_I2C_Master_Transmit_DMA(&hi2c1, DevAddress, pData, Size)
!= HAL_OK) {
I2C_Unstick();
xSemaphoreGive(I2CSemaphore);
}
#else
HAL_I2C_Master_Transmit(&hi2c1, DevAddress, pData, Size, 5000);
xSemaphoreGive(I2CSemaphore);
#endif
} else {
}
} }
return true;
} }
bool FRToSI2C::probe(uint16_t DevAddress) { bool FRToSI2C::probe(uint16_t DevAddress) {
if (!lock())
return false;
uint8_t buffer[1]; uint8_t buffer[1];
return HAL_I2C_Mem_Read(&hi2c1, DevAddress, 0x0F, I2C_MEMADD_SIZE_8BIT, bool worked = HAL_I2C_Mem_Read(&hi2c1, DevAddress, 0x0F,
buffer, 1, 1000) == HAL_OK; I2C_MEMADD_SIZE_8BIT, buffer, 1, 1000) == HAL_OK;
unlock();
return worked;
} }
void FRToSI2C::I2C_Unstick() { void FRToSI2C::I2C_Unstick() {
unstick_I2C(); unstick_I2C();
} }
void FRToSI2C::unlock() {
xSemaphoreGive(I2CSemaphore);
}
bool FRToSI2C::lock() {
return xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE;
}

View File

@@ -30,7 +30,7 @@ static void MX_TIM2_Init(void);
static void MX_DMA_Init(void); static void MX_DMA_Init(void);
static void MX_GPIO_Init(void); static void MX_GPIO_Init(void);
static void MX_ADC2_Init(void); static void MX_ADC2_Init(void);
#define SWD_ENABLE
void Setup_HAL() { void Setup_HAL() {
SystemClock_Config(); SystemClock_Config();

View File

@@ -23,7 +23,7 @@ uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
__HAL_FLASH_CLEAR_FLAG( __HAL_FLASH_CLEAR_FLAG(
FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_BSY); FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_BSY);
HAL_FLASH_Unlock(); HAL_FLASH_Unlock();
HAL_Delay(10); HAL_Delay(1);
resetWatchdog(); resetWatchdog();
HAL_FLASHEx_Erase(&pEraseInit, &failingAddress); HAL_FLASHEx_Erase(&pEraseInit, &failingAddress);
//^ Erase the page of flash (1024 bytes on this stm32) //^ Erase the page of flash (1024 bytes on this stm32)

View File

@@ -143,23 +143,13 @@ void fusb_send_hardrst() {
} }
void fusb_setup() { void fusb_setup() {
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 12, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { if (!I2CBB::lock2()) {
if (!I2CBB::lock2()) { return;
return;
}
} }
/* 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);
osDelay(2); // osDelay(2);
if (!fusb_read_id()) { if (!fusb_read_id()) {
return; return;
} }
@@ -200,10 +190,16 @@ void fusb_setup() {
fusb_write_byte( FUSB_SWITCHES1, 0x26); fusb_write_byte( FUSB_SWITCHES1, 0x26);
fusb_write_byte( FUSB_SWITCHES0, 0x0B); fusb_write_byte( FUSB_SWITCHES0, 0x0B);
} }
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { I2CBB::unlock2();
I2CBB::unlock2();
}
fusb_reset(); fusb_reset();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
} }
void fusb_get_status(union fusb_status *status) { void fusb_get_status(union fusb_status *status) {

View File

@@ -12,11 +12,10 @@
// Initialisation to be performed with scheduler active // Initialisation to be performed with scheduler active
void postRToSInit() { void postRToSInit() {
/* Init the IPC objects */
FRToSI2C::FRToSInit();
#ifdef POW_PD #ifdef POW_PD
//Spawn all of the USB-C processors if (usb_pd_detect() == true) {
fusb302_start_processing(); //Spawn all of the USB-C processors
fusb302_start_processing();
}
#endif #endif
} }

View File

@@ -17,13 +17,9 @@ void preRToSInit() {
*/ */
HAL_Init(); HAL_Init();
Setup_HAL(); // Setup all the HAL objects Setup_HAL(); // Setup all the HAL objects
FRToSI2C::init();
HAL_Delay(50);
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
HAL_Delay(50);
#ifdef I2C_SOFT #ifdef I2C_SOFT
I2CBB::init(); I2CBB::init();
#endif #endif
/* Init the IPC objects */
FRToSI2C::FRToSInit();
} }

View File

@@ -15,24 +15,13 @@
#include "protocol_rx.h" #include "protocol_rx.h"
#include "protocol_tx.h" #include "protocol_tx.h"
#include "int_n.h" #include "int_n.h"
#include "hard_reset.h"
void fusb302_start_processing() { void fusb302_start_processing() {
/* Initialize the FUSB302B */ /* Initialize the FUSB302B */
resetWatchdog();
fusb_setup(); fusb_setup();
resetWatchdog();
/* Create the policy engine thread. */
PolicyEngine::init(); PolicyEngine::init();
/* Create the protocol layer threads. */
ProtocolReceive::init();
ProtocolTransmit::init(); ProtocolTransmit::init();
ResetHandler::init(); ProtocolReceive::init();
resetWatchdog();
/* Create the INT_N thread. */
InterruptHandler::init(); InterruptHandler::init();
} }
#endif #endif

View File

@@ -1,152 +0,0 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hard_reset.h"
#include "fusbpd.h"
#include <pd.h>
#include "policy_engine.h"
#include "protocol_rx.h"
#include "protocol_tx.h"
#include "fusb302b.h"
osThreadId ResetHandler::TaskHandle = NULL;
uint32_t ResetHandler::TaskBuffer[ResetHandler::TaskStackSize];
osStaticThreadDef_t ResetHandler::TaskControlBlock;
/*
* PRL_HR_Reset_Layer state
*/
ResetHandler::hardrst_state ResetHandler::hardrst_reset_layer() {
/* First, wait for the signal to run a hard reset. */
eventmask_t evt = waitForEvent(
PDB_EVT_HARDRST_RESET | PDB_EVT_HARDRST_I_HARDRST);
if (evt & (PDB_EVT_HARDRST_RESET | PDB_EVT_HARDRST_I_HARDRST)) {
/* Reset the Protocol RX machine */
ProtocolReceive::notify( PDB_EVT_PRLRX_RESET);
taskYIELD();
/* Reset the Protocol TX machine */
ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_RESET);
taskYIELD();
/* Continue the process based on what event started the reset. */
if (evt & PDB_EVT_HARDRST_RESET) {
/* Policy Engine started the reset. */
return PRLHRRequestHardReset;
} else {
/* PHY started the reset */
return PRLHRIndicateHardReset;
}
} else {
return PRLHRResetLayer;
}
}
ResetHandler::hardrst_state ResetHandler::hardrst_indicate_hard_reset() {
/* Tell the PE that we're doing a hard reset */
PolicyEngine::notify( PDB_EVT_PE_RESET);
return PRLHRWaitPE;
}
ResetHandler::hardrst_state ResetHandler::hardrst_request_hard_reset() {
/* Tell the PHY to send a hard reset */
fusb_send_hardrst();
return PRLHRWaitPHY;
}
ResetHandler::hardrst_state ResetHandler::hardrst_wait_phy() {
/* Wait for the PHY to tell us that it's done sending the hard reset */
waitForEvent(PDB_EVT_HARDRST_I_HARDSENT, PD_T_HARD_RESET_COMPLETE);
/* Move on no matter what made us stop waiting. */
return PRLHRHardResetRequested;
}
ResetHandler::hardrst_state ResetHandler::hardrst_hard_reset_requested() {
/* Tell the PE that the hard reset was sent */
PolicyEngine::notify( PDB_EVT_PE_HARD_SENT);
return PRLHRWaitPE;
}
ResetHandler::hardrst_state ResetHandler::hardrst_wait_pe() {
/* Wait for the PE to tell us that it's done */
waitForEvent(PDB_EVT_HARDRST_DONE);
return PRLHRComplete;
}
ResetHandler::hardrst_state ResetHandler::hardrst_complete() {
/* I'm not aware of anything we have to tell the FUSB302B, so just finish
* the reset routine. */
return PRLHRResetLayer;
}
void ResetHandler::init() {
osThreadStaticDef(rstHand, Thread, PDB_PRIO_PRL, 0, TaskStackSize,
TaskBuffer, &TaskControlBlock);
TaskHandle = osThreadCreate(osThread(rstHand), NULL);
}
void ResetHandler::notify(uint32_t notification) {
if (TaskHandle != NULL) {
xTaskNotify(TaskHandle, notification, eNotifyAction::eSetBits);
}
}
void ResetHandler::Thread(const void *arg) {
(void) arg;
ResetHandler::hardrst_state state = PRLHRResetLayer;
while (true) {
switch (state) {
case PRLHRResetLayer:
state = hardrst_reset_layer();
break;
case PRLHRIndicateHardReset:
state = hardrst_indicate_hard_reset();
break;
case PRLHRRequestHardReset:
state = hardrst_request_hard_reset();
break;
case PRLHRWaitPHY:
state = hardrst_wait_phy();
break;
case PRLHRHardResetRequested:
state = hardrst_hard_reset_requested();
break;
case PRLHRWaitPE:
state = hardrst_wait_pe();
break;
case PRLHRComplete:
state = hardrst_complete();
break;
default:
/* This is an error. It really shouldn't happen. We might
* want to handle it anyway, though. */
state = PRLHRResetLayer;
break;
}
}
}
uint32_t ResetHandler::waitForEvent(uint32_t mask, uint32_t ticksToWait) {
uint32_t pulNotificationValue;
xTaskNotifyWait(0x00, mask, &pulNotificationValue, ticksToWait);
return pulNotificationValue;
}

View File

@@ -1,63 +0,0 @@
/*
* PD Buddy Firmware Library - USB Power Delivery for everyone
* Copyright 2017-2018 Clayton G. Hobbs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PDB_HARD_RESET_H
#define PDB_HARD_RESET_H
#include <pd.h>
/* Events for the Hard Reset thread */
#define PDB_EVT_HARDRST_RESET EVENT_MASK(0)
#define PDB_EVT_HARDRST_I_HARDRST EVENT_MASK(1)
#define PDB_EVT_HARDRST_I_HARDSENT EVENT_MASK(2)
#define PDB_EVT_HARDRST_DONE EVENT_MASK(3)
class ResetHandler {
public:
static void init();
static void notify(uint32_t notification);
private:
static void Thread(const void *arg);
static osThreadId TaskHandle;
static const size_t TaskStackSize = 1536 / 2;
static uint32_t TaskBuffer[TaskStackSize];
static osStaticThreadDef_t TaskControlBlock;
static uint32_t waitForEvent(uint32_t mask, uint32_t ticksToWait =
portMAX_DELAY);
/*
* Hard Reset machine states
*/
enum hardrst_state {
PRLHRResetLayer,
PRLHRIndicateHardReset,
PRLHRRequestHardReset,
PRLHRWaitPHY,
PRLHRHardResetRequested,
PRLHRWaitPE,
PRLHRComplete
};
static hardrst_state hardrst_reset_layer();
static hardrst_state hardrst_indicate_hard_reset();
static hardrst_state hardrst_request_hard_reset();
static hardrst_state hardrst_wait_phy();
static hardrst_state hardrst_hard_reset_requested();
static hardrst_state hardrst_wait_pe();
static hardrst_state hardrst_complete();
};
#endif /* PDB_HARD_RESET_H */

View File

@@ -21,14 +21,13 @@
#include "fusb302b.h" #include "fusb302b.h"
#include "protocol_rx.h" #include "protocol_rx.h"
#include "protocol_tx.h" #include "protocol_tx.h"
#include "hard_reset.h"
#include "policy_engine.h" #include "policy_engine.h"
#include "protocol_rx.h" #include "protocol_rx.h"
#include "protocol_tx.h" #include "protocol_tx.h"
#include "task.h" #include "task.h"
#include "BSP.h" #include "BSP.h"
osThreadId InterruptHandler::TaskHandle=NULL; osThreadId InterruptHandler::TaskHandle = NULL;
uint32_t InterruptHandler::TaskBuffer[InterruptHandler::TaskStackSize]; uint32_t InterruptHandler::TaskBuffer[InterruptHandler::TaskStackSize];
osStaticThreadDef_t InterruptHandler::TaskControlBlock; osStaticThreadDef_t InterruptHandler::TaskControlBlock;
@@ -41,8 +40,6 @@ void InterruptHandler::init() {
void InterruptHandler::Thread(const void *arg) { void InterruptHandler::Thread(const void *arg) {
(void) arg; (void) arg;
union fusb_status status; union fusb_status status;
volatile uint32_t events;
bool notifSent = false;
while (true) { while (true) {
/* If the INT_N line is low */ /* If the INT_N line is low */
if (xTaskNotifyWait(0x00, 0x0F, NULL, if (xTaskNotifyWait(0x00, 0x0F, NULL,
@@ -50,7 +47,6 @@ void InterruptHandler::Thread(const void *arg) {
//delay slightly so we catch the crc with better timing //delay slightly so we catch the crc with better timing
osDelay(1); osDelay(1);
} }
notifSent = false;
/* Read the FUSB302B status and interrupt registers */ /* Read the FUSB302B status and interrupt registers */
fusb_get_status(&status); fusb_get_status(&status);
/* 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
@@ -58,43 +54,23 @@ void InterruptHandler::Thread(const void *arg) {
if (status.interrupta & FUSB_INTERRUPTA_I_TXSENT) { if (status.interrupta & FUSB_INTERRUPTA_I_TXSENT) {
ProtocolTransmit::notify( ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_TXSENT); ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_TXSENT);
notifSent = true;
} }
if (status.interrupta & FUSB_INTERRUPTA_I_RETRYFAIL) { if (status.interrupta & FUSB_INTERRUPTA_I_RETRYFAIL) {
ProtocolTransmit::notify( ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_RETRYFAIL); ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_RETRYFAIL);
notifSent = true;
} }
/* 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 recieved with a good CRC //This means a message was recieved with a good CRC
if (status.interruptb & FUSB_INTERRUPTB_I_GCRCSENT) { if (status.interruptb & FUSB_INTERRUPTB_I_GCRCSENT) {
ProtocolReceive::notify(PDB_EVT_PRLRX_I_GCRCSENT); ProtocolReceive::notify(PDB_EVT_PRLRX_I_GCRCSENT);
notifSent = true;
} }
/* If the I_HARDRST or I_HARDSENT flag is set, tell the Hard Reset
* thread */
if (notifSent == false) {
events = 0;
if (status.interrupta & FUSB_INTERRUPTA_I_HARDRST) {
events |= PDB_EVT_HARDRST_I_HARDRST;
notifSent = true;
} else if (status.interrupta & FUSB_INTERRUPTA_I_HARDSENT) {
events |= PDB_EVT_HARDRST_I_HARDSENT;
notifSent = true;
}
if (events) {
ResetHandler::notify(events);
}
}
/* 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(PDB_EVT_PE_I_OVRTEMP); PolicyEngine::notify(PDB_EVT_PE_I_OVRTEMP);
notifSent = true;
} }
} }
} }

View File

@@ -20,7 +20,6 @@
#include "int_n.h" #include "int_n.h"
#include <pd.h> #include <pd.h>
#include "protocol_tx.h" #include "protocol_tx.h"
#include "hard_reset.h"
#include "fusb302b.h" #include "fusb302b.h"
bool PolicyEngine::pdNegotiationComplete; bool PolicyEngine::pdNegotiationComplete;
int PolicyEngine::current_voltage_mv; int PolicyEngine::current_voltage_mv;
@@ -189,15 +188,15 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_wait_cap() {
&& PD_NUMOBJ_GET(&tempMessage) > 0) { && PD_NUMOBJ_GET(&tempMessage) > 0) {
/* First, determine what PD revision we're using */ /* First, determine what PD revision we're using */
if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_1_0) { if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_1_0) {
// /* If the other end is using at least version 3.0, we'll /* If the other end is using at least version 3.0, we'll
// * use version 3.0. */ * use version 3.0. */
// if ((tempMessage.hdr & PD_HDR_SPECREV) >= PD_SPECREV_3_0) { if ((tempMessage.hdr & PD_HDR_SPECREV) >= PD_SPECREV_3_0) {
// hdr_template |= PD_SPECREV_3_0; hdr_template |= PD_SPECREV_3_0;
// /* Otherwise, use 2.0. Don't worry about the 1.0 case /* Otherwise, use 2.0. Don't worry about the 1.0 case
// * because we don't have hardware for PD 1.0 signaling. */ * because we don't have hardware for PD 1.0 signaling. */
// } else { } else {
hdr_template |= PD_SPECREV_2_0; hdr_template |= PD_SPECREV_2_0;
// } }
} }
return PESinkEvalCap; return PESinkEvalCap;
/* If the message was a Soft_Reset, do the soft reset procedure */ /* If the message was a Soft_Reset, do the soft reset procedure */
@@ -516,11 +515,8 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_hard_reset() {
if (_hard_reset_counter > PD_N_HARD_RESET_COUNT) { if (_hard_reset_counter > PD_N_HARD_RESET_COUNT) {
return PESinkSourceUnresponsive; return PESinkSourceUnresponsive;
} }
//So, we could send a hardreset here; however that will cause a power cycle on the PSU end.. Which will then reset this MCU
/* Generate a hard reset signal */ //So therefore we went get anywhere :)
ResetHandler::notify(PDB_EVT_HARDRST_RESET);
waitForEvent(PDB_EVT_PE_HARD_SENT);
/* Increment HardResetCounter */ /* Increment HardResetCounter */
_hard_reset_counter++; _hard_reset_counter++;
@@ -537,9 +533,6 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_transition_default() {
/* Since we never change our data role from UFP, there is no reason to set /* Since we never change our data role from UFP, there is no reason to set
* it here. */ * it here. */
/* Tell the protocol layer we're done with the reset */
ResetHandler::notify( PDB_EVT_HARDRST_DONE);
return PESinkStartup; return PESinkStartup;
} }

View File

@@ -17,28 +17,31 @@ void I2CBB::init() {
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Pin = SDA2_Pin ; GPIO_InitStruct.Pin = SDA2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(SDA2_GPIO_Port, &GPIO_InitStruct); HAL_GPIO_Init(SDA2_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Pin = SCL2_Pin; GPIO_InitStruct.Pin = SCL2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(SCL2_GPIO_Port, &GPIO_InitStruct); HAL_GPIO_Init(SCL2_GPIO_Port, &GPIO_InitStruct);
SOFT_SDA_HIGH(); SOFT_SDA_HIGH();
SOFT_SCL_HIGH(); SOFT_SCL_HIGH();
I2CSemaphore = xSemaphoreCreateMutexStatic (&xSemaphoreBuffer); I2CSemaphore = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer);
I2CSemaphore2 = xSemaphoreCreateMutexStatic (&xSemaphoreBuffer2); I2CSemaphore2 = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer2);
unlock(); unlock();
unlock2(); unlock2();
} }
bool I2CBB::probe(uint8_t address) { bool I2CBB::probe(uint8_t address) {
if (!lock())
return false;
start(); start();
bool ack = send(address); bool ack = send(address);
stop(); stop();
unlock();
return ack; return ack;
} }

View File

@@ -21,10 +21,6 @@
class FRToSI2C { class FRToSI2C {
public: public:
static void init() {
I2CSemaphore = nullptr;
}
static void FRToSInit() { static void FRToSInit() {
I2CSemaphore = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer); I2CSemaphore = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer);
xSemaphoreGive(I2CSemaphore); xSemaphoreGive(I2CSemaphore);
@@ -34,19 +30,21 @@ public:
static bool Mem_Read(uint16_t DevAddress, uint16_t MemAddress, static bool Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size); uint8_t *pData, uint16_t Size);
static void Mem_Write(uint16_t DevAddress, uint16_t MemAddress, static bool Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size); uint8_t *pData, uint16_t Size);
//Returns true if device ACK's being addressed //Returns true if device ACK's being addressed
static bool probe(uint16_t DevAddress); static bool probe(uint16_t DevAddress);
static void Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size); static bool Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
static void Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size); static void Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
static void TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, static void TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx); uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx);
static void I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data); static bool I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data);
static uint8_t I2C_RegisterRead(uint8_t address, uint8_t reg); static uint8_t I2C_RegisterRead(uint8_t address, uint8_t reg);
private: private:
static void unlock();
static bool lock();
static void I2C_Unstick(); static void I2C_Unstick();
static SemaphoreHandle_t I2CSemaphore; static SemaphoreHandle_t I2CSemaphore;
static StaticSemaphore_t xSemaphoreBuffer; static StaticSemaphore_t xSemaphoreBuffer;

View File

@@ -12,8 +12,6 @@
#include "Settings.h" #include "Settings.h"
#include "cmsis_os.h" #include "cmsis_os.h"
uint8_t PCBVersion = 0; uint8_t PCBVersion = 0;
// File local variables
bool usb_pd_available = false;
bool settingsWereReset = false; bool settingsWereReset = false;
// FreeRTOS variables // FreeRTOS variables
@@ -32,44 +30,17 @@ uint32_t MOVTaskBuffer[MOVTaskStackSize];
osStaticThreadDef_t MOVTaskControlBlock; osStaticThreadDef_t MOVTaskControlBlock;
// End FreeRTOS // End FreeRTOS
// Main sets up the hardware then hands over to the FreeRTOS kernel // Main sets up the hardware then hands over to the FreeRTOS kernel
int main(void) { int main(void) {
preRToSInit(); preRToSInit();
setTipX10Watts(0); // force tip off setTipX10Watts(0); // force tip off
resetWatchdog(); resetWatchdog();
OLED::initialize(); // start up the LCD
OLED::setFont(0); // default to bigger font OLED::setFont(0); // default to bigger font
// Testing for which accelerometer is mounted // Testing for which accelerometer is mounted
resetWatchdog();
usb_pd_available = usb_pd_detect();
resetWatchdog();
settingsWereReset = restoreSettings(); // load the settings from flash settingsWereReset = restoreSettings(); // load the settings from flash
#ifdef ACCEL_MMA
if (MMA8652FC::detect()) {
PCBVersion = 1;
MMA8652FC::initalize(); // this sets up the I2C registers
} else
#endif
#ifdef ACCEL_LIS
if (LIS2DH12::detect()) {
PCBVersion = 2;
// Setup the ST Accelerometer
LIS2DH12::initalize(); // startup the accelerometer
} else
#endif
{
PCBVersion = 3;
systemSettings.SleepTime = 0;
systemSettings.ShutdownTime = 0; // No accel -> disable sleep
systemSettings.sensitivity = 0;
}
resetWatchdog(); resetWatchdog();
/* Create the thread(s) */ /* Create the thread(s) */
/* definition and creation of GUITask */ /* definition and creation of GUITask */
osThreadStaticDef(GUITask, startGUITask, osPriorityBelowNormal, 0, osThreadStaticDef(GUITask, startGUITask, osPriorityBelowNormal, 0,
GUITaskStackSize, GUITaskBuffer, &GUITaskControlBlock); GUITaskStackSize, GUITaskBuffer, &GUITaskControlBlock);
GUITaskHandle = osThreadCreate(osThread(GUITask), NULL); GUITaskHandle = osThreadCreate(osThread(GUITask), NULL);

View File

@@ -632,6 +632,7 @@ void showDebugMenu(void) {
uint8_t idleScreenBGF[sizeof(idleScreenBG)]; uint8_t idleScreenBGF[sizeof(idleScreenBG)];
/* StartGUITask function */ /* StartGUITask function */
void startGUITask(void const *argument __unused) { void startGUITask(void const *argument __unused) {
OLED::initialize(); // start up the LCD
uint8_t tempWarningState = 0; uint8_t tempWarningState = 0;
bool buttonLockout = false; bool buttonLockout = false;

View File

@@ -23,8 +23,28 @@
uint8_t accelInit = 0; uint8_t accelInit = 0;
uint32_t lastMovementTime = 0; uint32_t lastMovementTime = 0;
void startMOVTask(void const *argument __unused) { void startMOVTask(void const *argument __unused) {
OLED::setRotation(systemSettings.OrientationMode & 1); #ifdef ACCEL_MMA
if (MMA8652FC::detect()) {
PCBVersion = 1;
MMA8652FC::initalize(); // this sets up the I2C registers
} else
#endif
#ifdef ACCEL_LIS
if (LIS2DH12::detect()) {
PCBVersion = 2;
// Setup the ST Accelerometer
LIS2DH12::initalize(); // startup the accelerometer
} else
#endif
{
PCBVersion = 3;
systemSettings.SleepTime = 0;
systemSettings.ShutdownTime = 0; // No accel -> disable sleep
systemSettings.sensitivity = 0;
}
postRToSInit(); postRToSInit();
OLED::setRotation(systemSettings.OrientationMode & 1);
lastMovementTime = 0; lastMovementTime = 0;
int16_t datax[MOVFilter] = { 0 }; int16_t datax[MOVFilter] = { 0 };
int16_t datay[MOVFilter] = { 0 }; int16_t datay[MOVFilter] = { 0 };