Merge pull request #672 from Ralim/supporting-FUSB302
Adding support for the TS80P using FUSB302 for USB-PD
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
#include "BSP_Power.h"
|
#include "BSP_Power.h"
|
||||||
#include "BSP_QC.h"
|
#include "BSP_QC.h"
|
||||||
#include "Defines.h"
|
#include "Defines.h"
|
||||||
#include "UnitSettings.h"
|
#include "Model_Config.h"
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
/*
|
/*
|
||||||
* BSP.h -- Board Support
|
* BSP.h -- Board Support
|
||||||
@@ -47,8 +47,11 @@ void reboot();
|
|||||||
// If the user has programmed in a bootup logo, draw it to the screen from flash
|
// If the user has programmed in a bootup logo, draw it to the screen from flash
|
||||||
// Returns 1 if the logo was printed so that the unit waits for the timeout or button
|
// Returns 1 if the logo was printed so that the unit waits for the timeout or button
|
||||||
uint8_t showBootLogoIfavailable();
|
uint8_t showBootLogoIfavailable();
|
||||||
|
//delay wrapper for delay using the hardware timer (used before RTOS)
|
||||||
|
void delay_ms(uint16_t count) ;
|
||||||
|
//Used to allow knowledge of if usb_pd is being used
|
||||||
|
uint8_t usb_pd_detect();
|
||||||
|
|
||||||
void delay_ms(uint16_t count);
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
16
workspace/TS100/Core/BSP/BSP_PD.h
Normal file
16
workspace/TS100/Core/BSP/BSP_PD.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* BSP_PD.h
|
||||||
|
*
|
||||||
|
* Created on: 21 Jul 2020
|
||||||
|
* Author: Ralim
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef USER_BSP_PD_H_
|
||||||
|
#define USER_BSP_PD_H_
|
||||||
|
#include "BSP.h"
|
||||||
|
/*
|
||||||
|
* An array of all of the desired voltages & minimum currents in preferred order
|
||||||
|
*/
|
||||||
|
extern const uint16_t USB_PD_Desired_Levels[];
|
||||||
|
extern const uint8_t USB_PD_Desired_Levels_Len;
|
||||||
|
#endif /* USER_BSP_PD_H_ */
|
||||||
@@ -12,9 +12,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Called once at startup, after RToS
|
|
||||||
// This can handle negotiations for QC/PD etc
|
|
||||||
void power_probe();
|
|
||||||
|
|
||||||
// Called periodically in the movement handling thread
|
// Called periodically in the movement handling thread
|
||||||
// Can be used to check any details for the power system
|
// Can be used to check any details for the power system
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "Pins.h"
|
#include "Pins.h"
|
||||||
#include "main.hpp"
|
#include "main.hpp"
|
||||||
#include "history.hpp"
|
#include "history.hpp"
|
||||||
|
#include "Model_Config.h"
|
||||||
#include "I2C_Wrapper.hpp"
|
#include "I2C_Wrapper.hpp"
|
||||||
volatile uint16_t PWMSafetyTimer = 0;
|
volatile uint16_t PWMSafetyTimer = 0;
|
||||||
volatile uint8_t pendingPWM = 0;
|
volatile uint8_t pendingPWM = 0;
|
||||||
@@ -16,8 +17,89 @@ history<uint16_t, PID_TIM_HZ> rawTempFilter = { { 0 }, 0, 0 };
|
|||||||
void resetWatchdog() {
|
void resetWatchdog() {
|
||||||
HAL_IWDG_Refresh(&hiwdg);
|
HAL_IWDG_Refresh(&hiwdg);
|
||||||
}
|
}
|
||||||
|
#ifdef TEMP_NTC
|
||||||
|
//Lookup table for the NTC
|
||||||
|
//Stored as ADCReading,Temp in degC
|
||||||
|
static const uint16_t NTCHandleLookup[] = {
|
||||||
|
//ADC Reading , Temp in C
|
||||||
|
29189, 0, //
|
||||||
|
29014, 1, //
|
||||||
|
28832, 2, //
|
||||||
|
28644, 3, //
|
||||||
|
28450, 4, //
|
||||||
|
28249, 5, //
|
||||||
|
28042, 6, //
|
||||||
|
27828, 7, //
|
||||||
|
27607, 8, //
|
||||||
|
27380, 9, //
|
||||||
|
27146, 10, //
|
||||||
|
26906, 11, //
|
||||||
|
26660, 12, //
|
||||||
|
26407, 13, //
|
||||||
|
26147, 14, //
|
||||||
|
25882, 15, //
|
||||||
|
25610, 16, //
|
||||||
|
25332, 17, //
|
||||||
|
25049, 18, //
|
||||||
|
24759, 19, //
|
||||||
|
24465, 20, //
|
||||||
|
24164, 21, //
|
||||||
|
23859, 22, //
|
||||||
|
23549, 23, //
|
||||||
|
23234, 24, //
|
||||||
|
22915, 25, //
|
||||||
|
22591, 26, //
|
||||||
|
22264, 27, //
|
||||||
|
21933, 28, //
|
||||||
|
21599, 29, //
|
||||||
|
// 21261, 30, //
|
||||||
|
// 20921, 31, //
|
||||||
|
// 20579, 32, //
|
||||||
|
// 20234, 33, //
|
||||||
|
// 19888, 34, //
|
||||||
|
// 19541, 35, //
|
||||||
|
// 19192, 36, //
|
||||||
|
// 18843, 37, //
|
||||||
|
// 18493, 38, //
|
||||||
|
// 18143, 39, //
|
||||||
|
// 17793, 40, //
|
||||||
|
// 17444, 41, //
|
||||||
|
// 17096, 42, //
|
||||||
|
// 16750, 43, //
|
||||||
|
// 16404, 44, //
|
||||||
|
// 16061, 45, //
|
||||||
|
// 15719, 46, //
|
||||||
|
// 15380, 47, //
|
||||||
|
// 15044, 48, //
|
||||||
|
// 14710, 49, //
|
||||||
|
// 14380, 50, //
|
||||||
|
// 14053, 51, //
|
||||||
|
// 13729, 52, //
|
||||||
|
// 13410, 53, //
|
||||||
|
// 13094, 54, //
|
||||||
|
// 12782, 55, //
|
||||||
|
// 12475, 56, //
|
||||||
|
// 12172, 57, //
|
||||||
|
// 11874, 58, //
|
||||||
|
// 11580, 59, //
|
||||||
|
// 11292, 60, //
|
||||||
|
};
|
||||||
|
#endif
|
||||||
uint16_t getHandleTemperature() {
|
uint16_t getHandleTemperature() {
|
||||||
|
#ifdef TEMP_NTC
|
||||||
|
//TS80P uses 100k NTC resistors instead
|
||||||
|
//NTCG104EF104FT1X from TDK
|
||||||
|
//For now not doing interpolation
|
||||||
|
int32_t result = getADC(0);
|
||||||
|
for (uint32_t i = 0; i < (sizeof(NTCHandleLookup) / (2 * sizeof(uint16_t)));
|
||||||
|
i++) {
|
||||||
|
if (result > NTCHandleLookup[(i * 2) + 0]) {
|
||||||
|
return NTCHandleLookup[(i * 2) + 1] * 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
#ifdef TEMP_TMP36
|
||||||
// We return the current handle temperature in X10 C
|
// We return the current handle temperature in X10 C
|
||||||
// TMP36 in handle, 0.5V offset and then 10mV per deg C (0.75V @ 25C for
|
// TMP36 in handle, 0.5V offset and then 10mV per deg C (0.75V @ 25C for
|
||||||
// example) STM32 = 4096 count @ 3.3V input -> But We oversample by 32/(2^2) =
|
// example) STM32 = 4096 count @ 3.3V input -> But We oversample by 32/(2^2) =
|
||||||
@@ -32,14 +114,15 @@ uint16_t getHandleTemperature() {
|
|||||||
result *= 100;
|
result *= 100;
|
||||||
result /= 993;
|
result /= 993;
|
||||||
return result;
|
return result;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getTipInstantTemperature() {
|
uint16_t getTipInstantTemperature() {
|
||||||
uint16_t sum = 0; // 12 bit readings * 8 -> 15 bits
|
uint16_t sum = 0; // 12 bit readings * 8 -> 15 bits
|
||||||
uint16_t readings[8];
|
uint16_t readings[8];
|
||||||
//Looking to reject the highest outlier readings.
|
//Looking to reject the highest outlier readings.
|
||||||
//As on some hardware these samples can run into the op-amp recovery time
|
//As on some hardware these samples can run into the op-amp recovery time
|
||||||
//Once this time is up the signal stabilises quickly, so no need to reject minimums
|
//Once this time is up the signal stabilises quickly, so no need to reject minimums
|
||||||
readings[0] = hadc1.Instance->JDR1;
|
readings[0] = hadc1.Instance->JDR1;
|
||||||
readings[1] = hadc1.Instance->JDR2;
|
readings[1] = hadc1.Instance->JDR2;
|
||||||
readings[2] = hadc1.Instance->JDR3;
|
readings[2] = hadc1.Instance->JDR3;
|
||||||
@@ -66,10 +149,10 @@ uint16_t getTipRawTemp(uint8_t refresh) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
|
uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
|
||||||
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
|
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
|
||||||
// Therefore we can divide down from there
|
// Therefore we can divide down from there
|
||||||
// Multiplying ADC max by 4 for additional calibration options,
|
// Multiplying ADC max by 4 for additional calibration options,
|
||||||
// ideal term is 467
|
// ideal term is 467
|
||||||
#ifdef MODEL_TS100
|
#ifdef MODEL_TS100
|
||||||
#define BATTFILTERDEPTH 32
|
#define BATTFILTERDEPTH 32
|
||||||
#else
|
#else
|
||||||
@@ -94,6 +177,9 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
|
|||||||
sum += samples[i];
|
sum += samples[i];
|
||||||
|
|
||||||
sum /= BATTFILTERDEPTH;
|
sum /= BATTFILTERDEPTH;
|
||||||
|
if (divisor == 0) {
|
||||||
|
divisor = 1;
|
||||||
|
}
|
||||||
return sum * 4 / divisor;
|
return sum * 4 / divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,13 +226,13 @@ void unstick_I2C() {
|
|||||||
int timeout = 100;
|
int timeout = 100;
|
||||||
int timeout_cnt = 0;
|
int timeout_cnt = 0;
|
||||||
|
|
||||||
// 1. Clear PE bit.
|
// 1. Clear PE bit.
|
||||||
hi2c1.Instance->CR1 &= ~(0x0001);
|
hi2c1.Instance->CR1 &= ~(0x0001);
|
||||||
/**I2C1 GPIO Configuration
|
/**I2C1 GPIO Configuration
|
||||||
PB6 ------> I2C1_SCL
|
PB6 ------> I2C1_SCL
|
||||||
PB7 ------> I2C1_SDA
|
PB7 ------> I2C1_SDA
|
||||||
*/
|
*/
|
||||||
// 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
|
// 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
||||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
@@ -173,7 +259,7 @@ void unstick_I2C() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
|
// 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
@@ -187,20 +273,20 @@ void unstick_I2C() {
|
|||||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
||||||
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
|
||||||
|
|
||||||
// 13. Set SWRST bit in I2Cx_CR1 register.
|
// 13. Set SWRST bit in I2Cx_CR1 register.
|
||||||
hi2c1.Instance->CR1 |= 0x8000;
|
hi2c1.Instance->CR1 |= 0x8000;
|
||||||
|
|
||||||
asm("nop");
|
asm("nop");
|
||||||
|
|
||||||
// 14. Clear SWRST bit in I2Cx_CR1 register.
|
// 14. Clear SWRST bit in I2Cx_CR1 register.
|
||||||
hi2c1.Instance->CR1 &= ~0x8000;
|
hi2c1.Instance->CR1 &= ~0x8000;
|
||||||
|
|
||||||
asm("nop");
|
asm("nop");
|
||||||
|
|
||||||
// 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
|
// 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
|
||||||
hi2c1.Instance->CR1 |= 0x0001;
|
hi2c1.Instance->CR1 |= 0x0001;
|
||||||
|
|
||||||
// Call initialization function.
|
// Call initialization function.
|
||||||
HAL_I2C_Init(&hi2c1);
|
HAL_I2C_Init(&hi2c1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +300,7 @@ uint8_t getButtonB() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void reboot() {
|
void reboot() {
|
||||||
|
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
workspace/TS100/Core/BSP/Miniware/BSP_PD.c
Normal file
22
workspace/TS100/Core/BSP/Miniware/BSP_PD.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* BSP_PD.c
|
||||||
|
*
|
||||||
|
* Created on: 21 Jul 2020
|
||||||
|
* Author: Ralim
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "BSP_PD.h"
|
||||||
|
#include "Model_Config.h"
|
||||||
|
#ifdef POW_PD
|
||||||
|
/*
|
||||||
|
* An array of all of the desired voltages & minimum currents in preferred order
|
||||||
|
*/
|
||||||
|
const uint16_t USB_PD_Desired_Levels[] = {
|
||||||
|
//mV desired input, mA minimum required current
|
||||||
|
12000, 2400, //12V @ 2.4A
|
||||||
|
9000, 2000, //9V @ 2A
|
||||||
|
5000, 100, //5V @ whatever
|
||||||
|
|
||||||
|
};
|
||||||
|
const uint8_t USB_PD_Desired_Levels_Len = 3;
|
||||||
|
#endif
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "IRQ.h"
|
#include "IRQ.h"
|
||||||
|
#include "int_n.h"
|
||||||
/*
|
/*
|
||||||
* Catch the IRQ that says that the conversion is done on the temperature
|
* Catch the IRQ that says that the conversion is done on the temperature
|
||||||
* readings coming in Once these have come in we can unblock the PID so that it
|
* readings coming in Once these have come in we can unblock the PID so that it
|
||||||
@@ -41,3 +42,8 @@ void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
|
|||||||
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
|
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
|
||||||
FRToSI2C::CpltCallback();
|
FRToSI2C::CpltCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
|
||||||
|
(void)GPIO_Pin;
|
||||||
|
InterruptHandler::irqCallback();
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
|
|||||||
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
|
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
|
||||||
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
|
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
|
||||||
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
|
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
|
||||||
|
void HAL_GPIO_EXTI_Callback(uint16_t);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
44
workspace/TS100/Core/BSP/Miniware/Model_Config.h
Normal file
44
workspace/TS100/Core/BSP/Miniware/Model_Config.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Model_Config.h
|
||||||
|
*
|
||||||
|
* Created on: 25 Jul 2020
|
||||||
|
* Author: Ralim
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BSP_MINIWARE_MODEL_CONFIG_H_
|
||||||
|
#define BSP_MINIWARE_MODEL_CONFIG_H_
|
||||||
|
/*
|
||||||
|
* Lookup for mapping features <-> Models
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(MODEL_TS100) + defined(MODEL_TS80)+defined(MODEL_TS80P) > 1
|
||||||
|
#error "Multiple models defined!"
|
||||||
|
#elif defined(MODEL_TS100) + defined(MODEL_TS80)+ defined(MODEL_TS80P) == 0
|
||||||
|
#error "No model defined!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODEL_TS100
|
||||||
|
#define ACCEL_MMA
|
||||||
|
#define ACCEL_LIS
|
||||||
|
#define TEMP_TMP36
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODEL_TS80
|
||||||
|
#define ACCEL_LIS
|
||||||
|
#define POW_QC
|
||||||
|
#define TEMP_TMP36
|
||||||
|
#define LIS_ORI_FLIP
|
||||||
|
#define OLED_FLIP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODEL_TS80P
|
||||||
|
#define ACCEL_LIS
|
||||||
|
#define POW_PD
|
||||||
|
#define POW_QC
|
||||||
|
#define TEMP_NTC
|
||||||
|
#define I2C_SOFT
|
||||||
|
#define LIS_ORI_FLIP
|
||||||
|
#define OLED_FLIP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* BSP_MINIWARE_MODEL_CONFIG_H_ */
|
||||||
@@ -7,12 +7,7 @@
|
|||||||
|
|
||||||
#ifndef BSP_MINIWARE_PINS_H_
|
#ifndef BSP_MINIWARE_PINS_H_
|
||||||
#define BSP_MINIWARE_PINS_H_
|
#define BSP_MINIWARE_PINS_H_
|
||||||
|
#include "Model_Config.h"
|
||||||
#if defined(MODEL_TS100) + defined(MODEL_TS80) > 1
|
|
||||||
#error "Multiple models defined!"
|
|
||||||
#elif defined(MODEL_TS100) + defined(MODEL_TS80) == 0
|
|
||||||
#error "No model defined!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MODEL_TS100
|
#ifdef MODEL_TS100
|
||||||
|
|
||||||
@@ -45,8 +40,8 @@
|
|||||||
#define SCL_GPIO_Port GPIOB
|
#define SCL_GPIO_Port GPIOB
|
||||||
#define SDA_Pin GPIO_PIN_7
|
#define SDA_Pin GPIO_PIN_7
|
||||||
#define SDA_GPIO_Port GPIOB
|
#define SDA_GPIO_Port GPIOB
|
||||||
|
#endif
|
||||||
#else
|
#ifdef MODEL_TS80
|
||||||
// TS80 pin map
|
// TS80 pin map
|
||||||
#define KEY_B_Pin GPIO_PIN_0
|
#define KEY_B_Pin GPIO_PIN_0
|
||||||
#define KEY_B_GPIO_Port GPIOB
|
#define KEY_B_GPIO_Port GPIOB
|
||||||
@@ -77,6 +72,51 @@
|
|||||||
#define SCL_GPIO_Port GPIOB
|
#define SCL_GPIO_Port GPIOB
|
||||||
#define SDA_Pin GPIO_PIN_7
|
#define SDA_Pin GPIO_PIN_7
|
||||||
#define SDA_GPIO_Port GPIOB
|
#define SDA_GPIO_Port GPIOB
|
||||||
|
#define SCL2_Pin GPIO_PIN_5
|
||||||
|
#define SCL2_GPIO_Port GPIOA
|
||||||
|
#define SDA2_Pin GPIO_PIN_1
|
||||||
|
#define SDA2_GPIO_Port GPIOA
|
||||||
|
#define INT_PD_Pin GPIO_PIN_9
|
||||||
|
#define INT_PD_GPIO_Port GPIOA
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#ifdef MODEL_TS80P
|
||||||
|
// TS80P pin map
|
||||||
|
#define KEY_B_Pin GPIO_PIN_0
|
||||||
|
#define KEY_B_GPIO_Port GPIOB
|
||||||
|
#define TMP36_INPUT_Pin GPIO_PIN_4
|
||||||
|
#define TMP36_INPUT_GPIO_Port GPIOA
|
||||||
|
#define TMP36_ADC1_CHANNEL ADC_CHANNEL_4
|
||||||
|
#define TIP_TEMP_Pin GPIO_PIN_3
|
||||||
|
#define TIP_TEMP_GPIO_Port GPIOA
|
||||||
|
#define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_3
|
||||||
|
#define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_3
|
||||||
|
|
||||||
|
#define VIN_Pin GPIO_PIN_2
|
||||||
|
#define VIN_GPIO_Port GPIOA
|
||||||
|
#define VIN_ADC1_CHANNEL ADC_CHANNEL_2
|
||||||
|
#define VIN_ADC2_CHANNEL ADC_CHANNEL_2
|
||||||
|
#define OLED_RESET_Pin GPIO_PIN_15
|
||||||
|
#define OLED_RESET_GPIO_Port GPIOA
|
||||||
|
#define KEY_A_Pin GPIO_PIN_1
|
||||||
|
#define KEY_A_GPIO_Port GPIOB
|
||||||
|
#define INT_Orientation_Pin GPIO_PIN_4
|
||||||
|
#define INT_Orientation_GPIO_Port GPIOB
|
||||||
|
#define PWM_Out_Pin GPIO_PIN_6
|
||||||
|
#define PWM_Out_GPIO_Port GPIOA
|
||||||
|
#define PWM_Out_CHANNEL TIM_CHANNEL_1
|
||||||
|
#define INT_Movement_Pin GPIO_PIN_5
|
||||||
|
#define INT_Movement_GPIO_Port GPIOB
|
||||||
|
#define SCL_Pin GPIO_PIN_6
|
||||||
|
#define SCL_GPIO_Port GPIOB
|
||||||
|
#define SDA_Pin GPIO_PIN_7
|
||||||
|
#define SDA_GPIO_Port GPIOB
|
||||||
|
#define SCL2_Pin GPIO_PIN_5
|
||||||
|
#define SCL2_GPIO_Port GPIOA
|
||||||
|
#define SDA2_Pin GPIO_PIN_1
|
||||||
|
#define SDA2_GPIO_Port GPIOA
|
||||||
|
#define INT_PD_Pin GPIO_PIN_9
|
||||||
|
#define INT_PD_GPIO_Port GPIOA
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -2,20 +2,35 @@
|
|||||||
#include "BSP_Power.h"
|
#include "BSP_Power.h"
|
||||||
#include "QC3.h"
|
#include "QC3.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
void power_probe() {
|
#include "Pins.h"
|
||||||
// If TS80 probe for QC
|
#include "fusbpd.h"
|
||||||
// If TS100 - noop
|
#include "Model_Config.h"
|
||||||
#ifdef MODEL_TS80
|
#include "policy_engine.h"
|
||||||
startQC(systemSettings.voltageDiv);
|
#include "int_n.h"
|
||||||
|
bool FUSB302_present = false;
|
||||||
seekQC((systemSettings.cutoutSetting) ? 120 : 90,
|
|
||||||
systemSettings.voltageDiv); // this will move the QC output to the preferred voltage to start with
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_check() {
|
void power_check() {
|
||||||
#ifdef MODEL_TS80
|
#ifdef POW_PD
|
||||||
QC_resync();
|
if (FUSB302_present) {
|
||||||
|
//Cant start QC until either PD works or fails
|
||||||
|
if (PolicyEngine::setupCompleteOrTimedOut() == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (PolicyEngine::pdHasNegotiated()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
#ifdef POW_QC
|
||||||
|
QC_resync();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
uint8_t usb_pd_detect() {
|
||||||
|
#ifdef POW_PD
|
||||||
|
FUSB302_present = fusb302_detect();
|
||||||
|
|
||||||
|
return FUSB302_present;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include "QC3.h"
|
#include "QC3.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
|
#include "Model_Config.h"
|
||||||
|
#ifdef POW_QC
|
||||||
void QC_DPlusZero_Six() {
|
void QC_DPlusZero_Six() {
|
||||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); // pull down D+
|
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); // pull down D+
|
||||||
}
|
}
|
||||||
@@ -65,10 +67,10 @@ void QC_Post_Probe_En() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t QC_DM_PulledDown() { return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET ? 1 : 0; }
|
uint8_t QC_DM_PulledDown() { return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET ? 1 : 0; }
|
||||||
|
#endif
|
||||||
void QC_resync() {
|
void QC_resync() {
|
||||||
#ifdef MODEL_TS80
|
#ifdef POW_QC
|
||||||
seekQC((systemSettings.cutoutSetting) ? 120 : 90,
|
seekQC((systemSettings.cutoutSetting) ? 120 : 90,
|
||||||
systemSettings.voltageDiv); // Run the QC seek again if we have drifted too much
|
systemSettings.voltageDiv); // Run the QC seek again if we have drifted too much
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ void Setup_HAL() {
|
|||||||
SystemClock_Config();
|
SystemClock_Config();
|
||||||
__HAL_AFIO_REMAP_SWJ_DISABLE()
|
__HAL_AFIO_REMAP_SWJ_DISABLE()
|
||||||
;
|
;
|
||||||
|
// __HAL_AFIO_REMAP_SWJ_NOJTAG();
|
||||||
MX_GPIO_Init();
|
MX_GPIO_Init();
|
||||||
MX_DMA_Init();
|
MX_DMA_Init();
|
||||||
MX_I2C1_Init();
|
MX_I2C1_Init();
|
||||||
@@ -458,3 +458,8 @@ static void MX_GPIO_Init(void) {
|
|||||||
HAL_Delay(30);
|
HAL_Delay(30);
|
||||||
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
|
||||||
}
|
}
|
||||||
|
#ifdef USE_FULL_ASSERT
|
||||||
|
void assert_failed(uint8_t* file, uint32_t line){
|
||||||
|
asm("bkpt");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
27
workspace/TS100/Core/BSP/Miniware/Software_I2C.h
Normal file
27
workspace/TS100/Core/BSP/Miniware/Software_I2C.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Software_I2C.h
|
||||||
|
*
|
||||||
|
* Created on: 25 Jul 2020
|
||||||
|
* Author: Ralim
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BSP_MINIWARE_SOFTWARE_I2C_H_
|
||||||
|
#define BSP_MINIWARE_SOFTWARE_I2C_H_
|
||||||
|
#include "Model_Config.h"
|
||||||
|
#include "BSP.h"
|
||||||
|
#include "stm32f1xx_hal.h"
|
||||||
|
#ifdef I2C_SOFT
|
||||||
|
|
||||||
|
#define SOFT_SCL_HIGH() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_SET)
|
||||||
|
#define SOFT_SCL_LOW() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_RESET)
|
||||||
|
#define SOFT_SDA_HIGH() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_SET)
|
||||||
|
#define SOFT_SDA_LOW() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_RESET)
|
||||||
|
#define SOFT_SDA_READ() (HAL_GPIO_ReadPin(SDA2_GPIO_Port,SDA2_Pin)==GPIO_PIN_SET?1:0)
|
||||||
|
#define SOFT_SCL_READ() (HAL_GPIO_ReadPin(SCL2_GPIO_Port,SCL2_Pin)==GPIO_PIN_SET?1:0)
|
||||||
|
#define SOFT_I2C_DELAY() {for(int xx=0;xx<40;xx++){asm("nop");}}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* BSP_MINIWARE_SOFTWARE_I2C_H_ */
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* UnitSettings.h
|
|
||||||
*
|
|
||||||
* Created on: 29 May 2020
|
|
||||||
* Author: Ralim
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BSP_MINIWARE_UNITSETTINGS_H_
|
|
||||||
#define BSP_MINIWARE_UNITSETTINGS_H_
|
|
||||||
//On the TS80, the LIS accel is mounted backwards
|
|
||||||
#ifdef MODEL_TS80
|
|
||||||
#define LIS_ORI_FLIP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BSP_MINIWARE_UNITSETTINGS_H_ */
|
|
||||||
@@ -291,7 +291,7 @@ typedef struct
|
|||||||
/** @defgroup RCC_Flag Flags
|
/** @defgroup RCC_Flag Flags
|
||||||
* Elements values convention: XXXYYYYYb
|
* Elements values convention: XXXYYYYYb
|
||||||
* - YYYYY : Flag position in the register
|
* - YYYYY : Flag position in the register
|
||||||
* - XXX : Register index
|
* - X XX : Register index
|
||||||
* - 001: CR register
|
* - 001: CR register
|
||||||
* - 010: BDCR register
|
* - 010: BDCR register
|
||||||
* - 011: CSR register
|
* - 011: CSR register
|
||||||
|
|||||||
@@ -1041,32 +1041,32 @@ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_I
|
|||||||
/* conversions is forced to 0x00 for alignment over all STM32 devices. */
|
/* conversions is forced to 0x00 for alignment over all STM32 devices. */
|
||||||
/* - if scan mode is enabled, injected channels sequence length is set to */
|
/* - if scan mode is enabled, injected channels sequence length is set to */
|
||||||
/* parameter "InjectedNbrOfConversion". */
|
/* parameter "InjectedNbrOfConversion". */
|
||||||
if (hadc->Init.ScanConvMode == ADC_SCAN_DISABLE)
|
// if (hadc->Init.ScanConvMode == ADC_SCAN_DISABLE)
|
||||||
{
|
// {
|
||||||
if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1)
|
// if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1)
|
||||||
{
|
// {
|
||||||
/* Clear the old SQx bits for all injected ranks */
|
// /* Clear the old SQx bits for all injected ranks */
|
||||||
MODIFY_REG(hadc->Instance->JSQR ,
|
// MODIFY_REG(hadc->Instance->JSQR ,
|
||||||
ADC_JSQR_JL |
|
// ADC_JSQR_JL |
|
||||||
ADC_JSQR_JSQ4 |
|
// ADC_JSQR_JSQ4 |
|
||||||
ADC_JSQR_JSQ3 |
|
// ADC_JSQR_JSQ3 |
|
||||||
ADC_JSQR_JSQ2 |
|
// ADC_JSQR_JSQ2 |
|
||||||
ADC_JSQR_JSQ1 ,
|
// ADC_JSQR_JSQ1 ,
|
||||||
ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel,
|
// ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel,
|
||||||
ADC_INJECTED_RANK_1,
|
// ADC_INJECTED_RANK_1,
|
||||||
0x01U));
|
// 0x01U));
|
||||||
}
|
// }
|
||||||
/* If another injected rank than rank1 was intended to be set, and could */
|
// /* If another injected rank than rank1 was intended to be set, and could */
|
||||||
/* not due to ScanConvMode disabled, error is reported. */
|
// /* not due to ScanConvMode disabled, error is reported. */
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
/* Update ADC state machine to error */
|
// /* Update ADC state machine to error */
|
||||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
|
// SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
|
||||||
|
//
|
||||||
tmp_hal_status = HAL_ERROR;
|
// tmp_hal_status = HAL_ERROR;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
{
|
||||||
/* Since injected channels rank conv. order depends on total number of */
|
/* Since injected channels rank conv. order depends on total number of */
|
||||||
/* injected conversions, selected rank must be below or equal to total */
|
/* injected conversions, selected rank must be below or equal to total */
|
||||||
|
|||||||
@@ -3479,6 +3479,7 @@ void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Slave mode selected */
|
/* Slave mode selected */
|
||||||
|
#if 0
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* ADDR set --------------------------------------------------------------*/
|
/* ADDR set --------------------------------------------------------------*/
|
||||||
@@ -3520,6 +3521,7 @@ void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -369,57 +369,6 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
|
|||||||
assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
|
assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
|
||||||
|
|
||||||
/*------------------------------- HSE Configuration ------------------------*/
|
/*------------------------------- HSE Configuration ------------------------*/
|
||||||
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
|
|
||||||
{
|
|
||||||
/* Check the parameters */
|
|
||||||
assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
|
|
||||||
|
|
||||||
/* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
|
|
||||||
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
|
|
||||||
|| ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
|
|
||||||
{
|
|
||||||
if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
|
|
||||||
{
|
|
||||||
return HAL_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set the new HSE configuration ---------------------------------------*/
|
|
||||||
__HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
|
|
||||||
|
|
||||||
|
|
||||||
/* Check the HSE State */
|
|
||||||
if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
|
|
||||||
{
|
|
||||||
/* Get Start Tick */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
|
|
||||||
/* Wait till HSE is ready */
|
|
||||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
|
|
||||||
{
|
|
||||||
if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
|
|
||||||
{
|
|
||||||
return HAL_TIMEOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Get Start Tick */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
|
|
||||||
/* Wait till HSE is disabled */
|
|
||||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
|
|
||||||
{
|
|
||||||
if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
|
|
||||||
{
|
|
||||||
return HAL_TIMEOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*----------------------------- HSI Configuration --------------------------*/
|
/*----------------------------- HSI Configuration --------------------------*/
|
||||||
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
|
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
|
||||||
{
|
{
|
||||||
@@ -486,121 +435,9 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*------------------------------ LSI Configuration -------------------------*/
|
/*------------------------------ LSI Configuration -------------------------*/
|
||||||
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
|
|
||||||
{
|
|
||||||
/* Check the parameters */
|
|
||||||
assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
|
|
||||||
|
|
||||||
/* Check the LSI State */
|
|
||||||
if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
|
|
||||||
{
|
|
||||||
/* Enable the Internal Low Speed oscillator (LSI). */
|
|
||||||
__HAL_RCC_LSI_ENABLE();
|
|
||||||
|
|
||||||
/* Get Start Tick */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
|
|
||||||
/* Wait till LSI is ready */
|
|
||||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
|
|
||||||
{
|
|
||||||
if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
|
|
||||||
{
|
|
||||||
return HAL_TIMEOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* To have a fully stabilized clock in the specified range, a software delay of 1ms
|
|
||||||
should be added.*/
|
|
||||||
RCC_Delay(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Disable the Internal Low Speed oscillator (LSI). */
|
|
||||||
__HAL_RCC_LSI_DISABLE();
|
|
||||||
|
|
||||||
/* Get Start Tick */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
|
|
||||||
/* Wait till LSI is disabled */
|
|
||||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
|
|
||||||
{
|
|
||||||
if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
|
|
||||||
{
|
|
||||||
return HAL_TIMEOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*------------------------------ LSE Configuration -------------------------*/
|
/*------------------------------ LSE Configuration -------------------------*/
|
||||||
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
|
|
||||||
{
|
|
||||||
FlagStatus pwrclkchanged = RESET;
|
|
||||||
|
|
||||||
/* Check the parameters */
|
|
||||||
assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
|
|
||||||
|
|
||||||
/* Update LSE configuration in Backup Domain control register */
|
|
||||||
/* Requires to enable write access to Backup Domain of necessary */
|
|
||||||
if(__HAL_RCC_PWR_IS_CLK_DISABLED())
|
|
||||||
{
|
|
||||||
__HAL_RCC_PWR_CLK_ENABLE();
|
|
||||||
pwrclkchanged = SET;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
|
|
||||||
{
|
|
||||||
/* Enable write access to Backup domain */
|
|
||||||
SET_BIT(PWR->CR, PWR_CR_DBP);
|
|
||||||
|
|
||||||
/* Wait for Backup domain Write protection disable */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
|
|
||||||
while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
|
|
||||||
{
|
|
||||||
if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
|
|
||||||
{
|
|
||||||
return HAL_TIMEOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the new LSE configuration -----------------------------------------*/
|
|
||||||
__HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
|
|
||||||
/* Check the LSE State */
|
|
||||||
if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
|
|
||||||
{
|
|
||||||
/* Get Start Tick */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
|
|
||||||
/* Wait till LSE is ready */
|
|
||||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
|
|
||||||
{
|
|
||||||
if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
|
|
||||||
{
|
|
||||||
return HAL_TIMEOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Get Start Tick */
|
|
||||||
tickstart = HAL_GetTick();
|
|
||||||
|
|
||||||
/* Wait till LSE is disabled */
|
|
||||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
|
|
||||||
{
|
|
||||||
if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
|
|
||||||
{
|
|
||||||
return HAL_TIMEOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Require to disable power clock if necessary */
|
|
||||||
if(pwrclkchanged == SET)
|
|
||||||
{
|
|
||||||
__HAL_RCC_PWR_CLK_DISABLE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(RCC_CR_PLL2ON)
|
#if defined(RCC_CR_PLL2ON)
|
||||||
/*-------------------------------- PLL2 Configuration -----------------------*/
|
/*-------------------------------- PLL2 Configuration -----------------------*/
|
||||||
|
|||||||
@@ -3968,129 +3968,129 @@ HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, TIM_ClockCo
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIM_CLOCKSOURCE_ETRMODE1:
|
// case TIM_CLOCKSOURCE_ETRMODE1:
|
||||||
{
|
// {
|
||||||
/* Check whether or not the timer instance supports external trigger input mode 1 (ETRF)*/
|
// /* Check whether or not the timer instance supports external trigger input mode 1 (ETRF)*/
|
||||||
assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance));
|
// assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance));
|
||||||
|
//
|
||||||
/* Check ETR input conditioning related parameters */
|
// /* Check ETR input conditioning related parameters */
|
||||||
assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
|
// assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
|
||||||
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
|
// assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
|
||||||
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
|
// assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
|
||||||
|
//
|
||||||
/* Configure the ETR Clock source */
|
// /* Configure the ETR Clock source */
|
||||||
TIM_ETR_SetConfig(htim->Instance,
|
// TIM_ETR_SetConfig(htim->Instance,
|
||||||
sClockSourceConfig->ClockPrescaler,
|
// sClockSourceConfig->ClockPrescaler,
|
||||||
sClockSourceConfig->ClockPolarity,
|
// sClockSourceConfig->ClockPolarity,
|
||||||
sClockSourceConfig->ClockFilter);
|
// sClockSourceConfig->ClockFilter);
|
||||||
/* Get the TIMx SMCR register value */
|
// /* Get the TIMx SMCR register value */
|
||||||
tmpsmcr = htim->Instance->SMCR;
|
// tmpsmcr = htim->Instance->SMCR;
|
||||||
/* Reset the SMS and TS Bits */
|
// /* Reset the SMS and TS Bits */
|
||||||
tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS);
|
// tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS);
|
||||||
/* Select the External clock mode1 and the ETRF trigger */
|
// /* Select the External clock mode1 and the ETRF trigger */
|
||||||
tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1);
|
// tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1);
|
||||||
/* Write to TIMx SMCR */
|
// /* Write to TIMx SMCR */
|
||||||
htim->Instance->SMCR = tmpsmcr;
|
// htim->Instance->SMCR = tmpsmcr;
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
|
//
|
||||||
case TIM_CLOCKSOURCE_ETRMODE2:
|
// case TIM_CLOCKSOURCE_ETRMODE2:
|
||||||
{
|
// {
|
||||||
/* Check whether or not the timer instance supports external trigger input mode 2 (ETRF)*/
|
// /* Check whether or not the timer instance supports external trigger input mode 2 (ETRF)*/
|
||||||
assert_param(IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(htim->Instance));
|
// assert_param(IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(htim->Instance));
|
||||||
|
//
|
||||||
/* Check ETR input conditioning related parameters */
|
// /* Check ETR input conditioning related parameters */
|
||||||
assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
|
// assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
|
||||||
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
|
// assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
|
||||||
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
|
// assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
|
||||||
|
//
|
||||||
/* Configure the ETR Clock source */
|
// /* Configure the ETR Clock source */
|
||||||
TIM_ETR_SetConfig(htim->Instance,
|
// TIM_ETR_SetConfig(htim->Instance,
|
||||||
sClockSourceConfig->ClockPrescaler,
|
// sClockSourceConfig->ClockPrescaler,
|
||||||
sClockSourceConfig->ClockPolarity,
|
// sClockSourceConfig->ClockPolarity,
|
||||||
sClockSourceConfig->ClockFilter);
|
// sClockSourceConfig->ClockFilter);
|
||||||
/* Enable the External clock mode2 */
|
// /* Enable the External clock mode2 */
|
||||||
htim->Instance->SMCR |= TIM_SMCR_ECE;
|
// htim->Instance->SMCR |= TIM_SMCR_ECE;
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
|
//
|
||||||
case TIM_CLOCKSOURCE_TI1:
|
// case TIM_CLOCKSOURCE_TI1:
|
||||||
{
|
// {
|
||||||
/* Check whether or not the timer instance supports external clock mode 1 */
|
// /* Check whether or not the timer instance supports external clock mode 1 */
|
||||||
assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
|
// assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
|
||||||
|
//
|
||||||
/* Check TI1 input conditioning related parameters */
|
// /* Check TI1 input conditioning related parameters */
|
||||||
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
|
// assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
|
||||||
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
|
// assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
|
||||||
|
//
|
||||||
TIM_TI1_ConfigInputStage(htim->Instance,
|
// TIM_TI1_ConfigInputStage(htim->Instance,
|
||||||
sClockSourceConfig->ClockPolarity,
|
// sClockSourceConfig->ClockPolarity,
|
||||||
sClockSourceConfig->ClockFilter);
|
// sClockSourceConfig->ClockFilter);
|
||||||
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1);
|
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1);
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case TIM_CLOCKSOURCE_TI2:
|
// case TIM_CLOCKSOURCE_TI2:
|
||||||
{
|
// {
|
||||||
/* Check whether or not the timer instance supports external clock mode 1 (ETRF)*/
|
// /* Check whether or not the timer instance supports external clock mode 1 (ETRF)*/
|
||||||
assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
|
// assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
|
||||||
|
//
|
||||||
/* Check TI2 input conditioning related parameters */
|
// /* Check TI2 input conditioning related parameters */
|
||||||
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
|
// assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
|
||||||
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
|
// assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
|
||||||
|
//
|
||||||
TIM_TI2_ConfigInputStage(htim->Instance,
|
// TIM_TI2_ConfigInputStage(htim->Instance,
|
||||||
sClockSourceConfig->ClockPolarity,
|
// sClockSourceConfig->ClockPolarity,
|
||||||
sClockSourceConfig->ClockFilter);
|
// sClockSourceConfig->ClockFilter);
|
||||||
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2);
|
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2);
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case TIM_CLOCKSOURCE_TI1ED:
|
// case TIM_CLOCKSOURCE_TI1ED:
|
||||||
{
|
// {
|
||||||
/* Check whether or not the timer instance supports external clock mode 1 */
|
// /* Check whether or not the timer instance supports external clock mode 1 */
|
||||||
assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
|
// assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
|
||||||
|
//
|
||||||
/* Check TI1 input conditioning related parameters */
|
// /* Check TI1 input conditioning related parameters */
|
||||||
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
|
// assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
|
||||||
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
|
// assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
|
||||||
|
//
|
||||||
TIM_TI1_ConfigInputStage(htim->Instance,
|
// TIM_TI1_ConfigInputStage(htim->Instance,
|
||||||
sClockSourceConfig->ClockPolarity,
|
// sClockSourceConfig->ClockPolarity,
|
||||||
sClockSourceConfig->ClockFilter);
|
// sClockSourceConfig->ClockFilter);
|
||||||
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED);
|
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED);
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case TIM_CLOCKSOURCE_ITR0:
|
// case TIM_CLOCKSOURCE_ITR0:
|
||||||
{
|
// {
|
||||||
/* Check whether or not the timer instance supports external clock mode 1 */
|
// /* Check whether or not the timer instance supports external clock mode 1 */
|
||||||
assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
|
// assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
|
||||||
|
//
|
||||||
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR0);
|
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR0);
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case TIM_CLOCKSOURCE_ITR1:
|
// case TIM_CLOCKSOURCE_ITR1:
|
||||||
{
|
// {
|
||||||
/* Check whether or not the timer instance supports external clock mode 1 */
|
// /* Check whether or not the timer instance supports external clock mode 1 */
|
||||||
assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
|
// assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
|
||||||
|
//
|
||||||
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR1);
|
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR1);
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case TIM_CLOCKSOURCE_ITR2:
|
// case TIM_CLOCKSOURCE_ITR2:
|
||||||
{
|
// {
|
||||||
/* Check whether or not the timer instance supports external clock mode 1 */
|
// /* Check whether or not the timer instance supports external clock mode 1 */
|
||||||
assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
|
// assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
|
||||||
|
//
|
||||||
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR2);
|
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR2);
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case TIM_CLOCKSOURCE_ITR3:
|
// case TIM_CLOCKSOURCE_ITR3:
|
||||||
{
|
// {
|
||||||
/* Check whether or not the timer instance supports external clock mode 1 */
|
// /* Check whether or not the timer instance supports external clock mode 1 */
|
||||||
assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
|
// assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
|
||||||
|
//
|
||||||
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR3);
|
// TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR3);
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
270
workspace/TS100/Core/BSP/Miniware/fusb302b.cpp
Normal file
270
workspace/TS100/Core/BSP/Miniware/fusb302b.cpp
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
* 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 "Model_Config.h"
|
||||||
|
#ifdef POW_PD
|
||||||
|
#include "BSP.h"
|
||||||
|
#include "fusb302b.h"
|
||||||
|
#include "I2CBB.hpp"
|
||||||
|
#include <pd.h>
|
||||||
|
#include "int_n.h"
|
||||||
|
/*
|
||||||
|
* Read a single byte from the FUSB302B
|
||||||
|
*
|
||||||
|
* cfg: The FUSB302B to communicate with
|
||||||
|
* addr: The memory address from which to read
|
||||||
|
*
|
||||||
|
* Returns the value read from addr.
|
||||||
|
*/
|
||||||
|
static uint8_t fusb_read_byte(uint8_t addr) {
|
||||||
|
uint8_t data[1];
|
||||||
|
if (!I2CBB::Mem_Read(FUSB302B_ADDR, addr, (uint8_t*) data, 1)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read multiple bytes from the FUSB302B
|
||||||
|
*
|
||||||
|
* cfg: The FUSB302B to communicate with
|
||||||
|
* addr: The memory address from which to read
|
||||||
|
* size: The number of bytes to read
|
||||||
|
* buf: The buffer into which data will be read
|
||||||
|
*/
|
||||||
|
static bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf) {
|
||||||
|
return I2CBB::Mem_Read(FUSB302B_ADDR, addr, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write a single byte to the FUSB302B
|
||||||
|
*
|
||||||
|
* cfg: The FUSB302B to communicate with
|
||||||
|
* addr: The memory address to which we will write
|
||||||
|
* byte: The value to write
|
||||||
|
*/
|
||||||
|
static bool fusb_write_byte(uint8_t addr, uint8_t byte) {
|
||||||
|
return I2CBB::Mem_Write(FUSB302B_ADDR, addr, (uint8_t*) &byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write multiple bytes to the FUSB302B
|
||||||
|
*
|
||||||
|
* cfg: The FUSB302B to communicate with
|
||||||
|
* addr: The memory address to which we will write
|
||||||
|
* size: The number of bytes to write
|
||||||
|
* buf: The buffer to write
|
||||||
|
*/
|
||||||
|
static bool fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf) {
|
||||||
|
return I2CBB::Mem_Write(FUSB302B_ADDR, addr, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fusb_send_message(const union pd_msg *msg) {
|
||||||
|
if (!I2CBB::lock2()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Token sequences for the FUSB302B */
|
||||||
|
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 };
|
||||||
|
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 */
|
||||||
|
/* Get the length of the message: a two-octet header plus NUMOBJ four-octet
|
||||||
|
* data objects */
|
||||||
|
uint8_t msg_len = 2 + 4 * PD_NUMOBJ_GET(msg);
|
||||||
|
|
||||||
|
/* Set the number of bytes to be transmitted in the packet */
|
||||||
|
sop_seq[4] = FUSB_FIFO_TX_PACKSYM | msg_len;
|
||||||
|
|
||||||
|
/* Write all three parts of the message to the TX FIFO */
|
||||||
|
fusb_write_buf( FUSB_FIFOS, 5, sop_seq);
|
||||||
|
fusb_write_buf( FUSB_FIFOS, msg_len, msg->bytes);
|
||||||
|
fusb_write_buf( FUSB_FIFOS, 4, eop_seq);
|
||||||
|
|
||||||
|
I2CBB::unlock2();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t fusb_read_message(union pd_msg *msg) {
|
||||||
|
if (!I2CBB::lock2()) {
|
||||||
|
asm("bkpt");
|
||||||
|
}
|
||||||
|
static uint8_t garbage[4];
|
||||||
|
uint8_t numobj;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
fusb_read_byte( FUSB_FIFOS);
|
||||||
|
/* Read the message header into msg */
|
||||||
|
fusb_read_buf( FUSB_FIFOS, 2, msg->bytes);
|
||||||
|
/* Get the number of data objects */
|
||||||
|
numobj = PD_NUMOBJ_GET(msg);
|
||||||
|
/* If there is at least one data object, read the data objects */
|
||||||
|
if (numobj > 0) {
|
||||||
|
fusb_read_buf( FUSB_FIFOS, numobj * 4, msg->bytes + 2);
|
||||||
|
}
|
||||||
|
/* Throw the CRC32 in the garbage, since the PHY already checked it. */
|
||||||
|
fusb_read_buf( FUSB_FIFOS, 4, garbage);
|
||||||
|
|
||||||
|
I2CBB::unlock2();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fusb_send_hardrst() {
|
||||||
|
|
||||||
|
if (!I2CBB::lock2()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Send a hard reset */
|
||||||
|
fusb_write_byte( FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET);
|
||||||
|
|
||||||
|
I2CBB::unlock2();
|
||||||
|
}
|
||||||
|
|
||||||
|
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()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Fully reset the FUSB302B */
|
||||||
|
fusb_write_byte( FUSB_RESET, FUSB_RESET_SW_RES);
|
||||||
|
osDelay(2);
|
||||||
|
if (!fusb_read_id()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn on all power */
|
||||||
|
fusb_write_byte( FUSB_POWER, 0x0F);
|
||||||
|
|
||||||
|
/* Set interrupt masks */
|
||||||
|
//Setting to 0 so interrupts are allowed
|
||||||
|
fusb_write_byte( FUSB_MASK1, 0x00);
|
||||||
|
fusb_write_byte( FUSB_MASKA, 0x00);
|
||||||
|
fusb_write_byte( FUSB_MASKB, 0x00);
|
||||||
|
fusb_write_byte( FUSB_CONTROL0, 0b11 << 2);
|
||||||
|
|
||||||
|
/* Enable automatic retransmission */
|
||||||
|
fusb_write_byte( FUSB_CONTROL3, 0x07);
|
||||||
|
//set defaults
|
||||||
|
fusb_write_byte( FUSB_CONTROL2, 0x00);
|
||||||
|
/* Flush the RX buffer */
|
||||||
|
fusb_write_byte( FUSB_CONTROL1,
|
||||||
|
FUSB_CONTROL1_RX_FLUSH);
|
||||||
|
|
||||||
|
/* Measure CC1 */
|
||||||
|
fusb_write_byte( FUSB_SWITCHES0, 0x07);
|
||||||
|
osDelay(10);
|
||||||
|
uint8_t cc1 = fusb_read_byte( FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
|
||||||
|
|
||||||
|
/* Measure CC2 */
|
||||||
|
fusb_write_byte( FUSB_SWITCHES0, 0x0B);
|
||||||
|
osDelay(10);
|
||||||
|
uint8_t cc2 = fusb_read_byte( FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
|
||||||
|
|
||||||
|
/* Select the correct CC line for BMC signaling; also enable AUTO_CRC */
|
||||||
|
if (cc1 > cc2) {
|
||||||
|
fusb_write_byte( FUSB_SWITCHES1, 0x25);
|
||||||
|
fusb_write_byte( FUSB_SWITCHES0, 0x07);
|
||||||
|
} else {
|
||||||
|
fusb_write_byte( FUSB_SWITCHES1, 0x26);
|
||||||
|
fusb_write_byte( FUSB_SWITCHES0, 0x0B);
|
||||||
|
}
|
||||||
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
|
I2CBB::unlock2();
|
||||||
|
}
|
||||||
|
fusb_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void fusb_get_status(union fusb_status *status) {
|
||||||
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
|
if (!I2CBB::lock2()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the interrupt and status flags into status */
|
||||||
|
fusb_read_buf( FUSB_STATUS0A, 7, status->bytes);
|
||||||
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
|
I2CBB::unlock2();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
enum fusb_typec_current fusb_get_typec_current() {
|
||||||
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
|
if (!I2CBB::lock2()) {
|
||||||
|
return fusb_tcc_none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Read the BC_LVL into a variable */
|
||||||
|
enum fusb_typec_current bc_lvl = (enum fusb_typec_current) (fusb_read_byte(
|
||||||
|
FUSB_STATUS0) & FUSB_STATUS0_BC_LVL);
|
||||||
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
|
I2CBB::unlock2();
|
||||||
|
}
|
||||||
|
return bc_lvl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fusb_reset() {
|
||||||
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
|
if (!I2CBB::lock2()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush the TX buffer */
|
||||||
|
fusb_write_byte( FUSB_CONTROL0, 0x44);
|
||||||
|
/* Flush the RX buffer */
|
||||||
|
fusb_write_byte( FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
|
||||||
|
/* Reset the PD logic */
|
||||||
|
// fusb_write_byte( FUSB_RESET, FUSB_RESET_PD_RESET);
|
||||||
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
|
I2CBB::unlock2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fusb_read_id() {
|
||||||
|
//Return true if read of the revision ID is sane
|
||||||
|
uint8_t version = 0;
|
||||||
|
fusb_read_buf(FUSB_DEVICE_ID, 1, &version);
|
||||||
|
if (version == 0 || version == 0xFF)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
uint8_t fusb302_detect() {
|
||||||
|
//Probe the I2C bus for its address
|
||||||
|
return I2CBB::probe(FUSB302B_ADDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -8,7 +8,12 @@
|
|||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "I2C_Wrapper.hpp"
|
#include "I2C_Wrapper.hpp"
|
||||||
|
#include "fusbpd.h"
|
||||||
void postRToSInit() {
|
void postRToSInit() {
|
||||||
// Any after RTos setup
|
// Any after RTos setup
|
||||||
FRToSI2C::FRToSInit();
|
FRToSI2C::FRToSInit();
|
||||||
|
#ifdef POW_PD
|
||||||
|
//Spawn all of the USB-C processors
|
||||||
|
fusb302_start_processing();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "Setup.h"
|
#include "Setup.h"
|
||||||
#include "Pins.h"
|
#include "Pins.h"
|
||||||
|
#include "I2CBB.hpp"
|
||||||
|
#include "fusbpd.h"
|
||||||
|
#include "Model_Config.h"
|
||||||
void preRToSInit() {
|
void preRToSInit() {
|
||||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick.
|
/* Reset of all peripherals, Initializes the Flash interface and the Systick.
|
||||||
*/
|
*/
|
||||||
@@ -18,5 +21,9 @@ void preRToSInit() {
|
|||||||
HAL_Delay(50);
|
HAL_Delay(50);
|
||||||
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
|
||||||
HAL_Delay(50);
|
HAL_Delay(50);
|
||||||
|
#ifdef I2C_SOFT
|
||||||
|
I2CBB::init();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,3 +82,6 @@ void DMA1_Channel6_IRQHandler(void) {
|
|||||||
void DMA1_Channel7_IRQHandler(void) {
|
void DMA1_Channel7_IRQHandler(void) {
|
||||||
HAL_DMA_IRQHandler(&hdma_i2c1_rx);
|
HAL_DMA_IRQHandler(&hdma_i2c1_rx);
|
||||||
}
|
}
|
||||||
|
void EXTI9_5_IRQHandler(void){
|
||||||
|
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||||
/* #define DATA_IN_ExtSRAM */
|
/* #define DATA_IN_ExtSRAM */
|
||||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||||
|
//#define LOCAL_BUILD
|
||||||
#ifndef LOCAL_BUILD
|
#ifndef LOCAL_BUILD
|
||||||
#define VECT_TAB_OFFSET 0x00004000U /*!< Vector Table base offset field.
|
#define VECT_TAB_OFFSET 0x00004000U /*!< Vector Table base offset field.
|
||||||
This value must be a multiple of 0x200. */
|
This value must be a multiple of 0x200. */
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ ButtonState getButtonState() {
|
|||||||
*/
|
*/
|
||||||
static uint8_t previousState = 0;
|
static uint8_t previousState = 0;
|
||||||
static uint32_t previousStateChange = 0;
|
static uint32_t previousStateChange = 0;
|
||||||
const uint16_t timeout = 40;
|
const uint16_t timeout = 400;
|
||||||
uint8_t currentState;
|
uint8_t currentState;
|
||||||
currentState = (getButtonA()) << 0;
|
currentState = (getButtonA()) << 0;
|
||||||
currentState |= (getButtonB()) << 1;
|
currentState |= (getButtonB()) << 1;
|
||||||
|
|||||||
305
workspace/TS100/Core/Drivers/FUSB302/fusb302b.h
Normal file
305
workspace/TS100/Core/Drivers/FUSB302/fusb302b.h
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
/*
|
||||||
|
* 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_FUSB302B_H
|
||||||
|
#define PDB_FUSB302B_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "pd.h"
|
||||||
|
#include <pdb_msg.h>
|
||||||
|
|
||||||
|
/* I2C addresses of the FUSB302B chips */
|
||||||
|
#define FUSB302B_ADDR (0x22<<1)
|
||||||
|
#define FUSB302B01_ADDR (0x23<<1)
|
||||||
|
#define FUSB302B10_ADDR (0x24<<1)
|
||||||
|
#define FUSB302B11_ADDR (0x25<<1)
|
||||||
|
|
||||||
|
/* Device ID register */
|
||||||
|
#define FUSB_DEVICE_ID 0x01
|
||||||
|
#define FUSB_DEVICE_ID_VERSION_ID_SHIFT 4
|
||||||
|
#define FUSB_DEVICE_ID_VERSION_ID (0xF << FUSB_DEVICE_ID_VERSION_ID_SHIFT)
|
||||||
|
#define FUSB_DEVICE_ID_PRODUCT_ID_SHIFT 2
|
||||||
|
#define FUSB_DEVICE_ID_PRODUCT_ID (0x3 << FUSB_DEVICE_ID_PRODUCT_ID_SHIFT)
|
||||||
|
#define FUSB_DEVICE_ID_REVISION_ID_SHIFT 0
|
||||||
|
#define FUSB_DEVICE_ID_REVISION_ID (0x3 << FUSB_DEVICE_ID_REVISION_ID_SHIFT)
|
||||||
|
|
||||||
|
/* Switches0 register */
|
||||||
|
#define FUSB_SWITCHES0 0x02
|
||||||
|
#define FUSB_SWITCHES0_PU_EN2 (1 << 7)
|
||||||
|
#define FUSB_SWITCHES0_PU_EN1 (1 << 6)
|
||||||
|
#define FUSB_SWITCHES0_VCONN_CC2 (1 << 5)
|
||||||
|
#define FUSB_SWITCHES0_VCONN_CC1 (1 << 4)
|
||||||
|
#define FUSB_SWITCHES0_MEAS_CC2 (1 << 3)
|
||||||
|
#define FUSB_SWITCHES0_MEAS_CC1 (1 << 2)
|
||||||
|
#define FUSB_SWITCHES0_PDWN_2 (1 << 1)
|
||||||
|
#define FUSB_SWITCHES0_PDWN_1 1
|
||||||
|
|
||||||
|
/* Switches1 register */
|
||||||
|
#define FUSB_SWITCHES1 0x03
|
||||||
|
#define FUSB_SWITCHES1_POWERROLE (1 << 7)
|
||||||
|
#define FUSB_SWITCHES1_SPECREV_SHIFT 5
|
||||||
|
#define FUSB_SWITCHES1_SPECREV (0x3 << FUSB_SWITCHES1_SPECREV_SHIFT)
|
||||||
|
#define FUSB_SWITCHES1_DATAROLE (1 << 4)
|
||||||
|
#define FUSB_SWITCHES1_AUTO_CRC (1 << 2)
|
||||||
|
#define FUSB_SWITCHES1_TXCC2 (1 << 1)
|
||||||
|
#define FUSB_SWITCHES1_TXCC1 1
|
||||||
|
|
||||||
|
/* Measure register */
|
||||||
|
#define FUSB_MEASURE 0x04
|
||||||
|
#define FUSB_MEASURE_MEAS_VBUS (1 << 6)
|
||||||
|
#define FUSB_MEASURE_MDAC_SHIFT 0
|
||||||
|
#define FUSB_MEASURE_MDAC (0x3F << FUSB_MEASURE_MDAC_SHIFT)
|
||||||
|
|
||||||
|
/* Slice register */
|
||||||
|
#define FUSB_SLICE 0x05
|
||||||
|
#define FUSB_SLICE_SDAC_HYS_SHIFT 6
|
||||||
|
#define FUSB_SLICE_SDAC_HYS (0x3 << FUSB_SLICE_SDAC_HYS_SHIFT)
|
||||||
|
#define FUSB_SLICE_SDAC_SHIFT 0
|
||||||
|
#define FUSB_SLICE_SDAC (0x3F << FUSB_SLICE_SDAC_SHIFT)
|
||||||
|
|
||||||
|
/* Control0 register */
|
||||||
|
#define FUSB_CONTROL0 0x06
|
||||||
|
#define FUSB_CONTROL0_TX_FLUSH (1 << 6)
|
||||||
|
#define FUSB_CONTROL0_INT_MASK (1 << 5)
|
||||||
|
#define FUSB_CONTROL0_HOST_CUR_SHIFT 2
|
||||||
|
#define FUSB_CONTROL0_HOST_CUR (0x3 << FUSB_CONTROL0_HOST_CUR_SHIFT)
|
||||||
|
#define FUSB_CONTROL0_AUTO_PRE (1 << 1)
|
||||||
|
#define FUSB_CONTROL0_TX_START 1
|
||||||
|
|
||||||
|
/* Control1 register */
|
||||||
|
#define FUSB_CONTROL1 0x07
|
||||||
|
#define FUSB_CONTROL1_ENSOP2DB (1 << 6)
|
||||||
|
#define FUSB_CONTROL1_ENSOP1DB (1 << 5)
|
||||||
|
#define FUSB_CONTROL1_BIST_MODE2 (1 << 4)
|
||||||
|
#define FUSB_CONTROL1_RX_FLUSH (1 << 2)
|
||||||
|
#define FUSB_CONTROL1_ENSOP2 (1 << 1)
|
||||||
|
#define FUSB_CONTROL1_ENSOP1 1
|
||||||
|
|
||||||
|
/* Control2 register */
|
||||||
|
#define FUSB_CONTROL2 0x08
|
||||||
|
#define FUSB_CONTROL2_TOG_SAVE_PWR_SHIFT 6
|
||||||
|
#define FUSB_CONTROL2_TOG_SAVE_PWR (0x3 << FUSB_CONTROL2_TOG_SAVE_PWR)
|
||||||
|
#define FUSB_CONTROL2_TOG_RD_ONLY (1 << 5)
|
||||||
|
#define FUSB_CONTROL2_WAKE_EN (1 << 3)
|
||||||
|
#define FUSB_CONTROL2_MODE_SHIFT 1
|
||||||
|
#define FUSB_CONTROL2_MODE (0x3 << FUSB_CONTROL2_MODE_SHIFT)
|
||||||
|
#define FUSB_CONTROL2_TOGGLE 1
|
||||||
|
|
||||||
|
/* Control3 register */
|
||||||
|
#define FUSB_CONTROL3 0x09
|
||||||
|
#define FUSB_CONTROL3_SEND_HARD_RESET (1 << 6)
|
||||||
|
#define FUSB_CONTROL3_BIST_TMODE (1 << 5)
|
||||||
|
#define FUSB_CONTROL3_AUTO_HARDRESET (1 << 4)
|
||||||
|
#define FUSB_CONTROL3_AUTO_SOFTRESET (1 << 3)
|
||||||
|
#define FUSB_CONTROL3_N_RETRIES_SHIFT 1
|
||||||
|
#define FUSB_CONTROL3_N_RETRIES (0x3 << FUSB_CONTROL3_N_RETRIES_SHIFT)
|
||||||
|
#define FUSB_CONTROL3_AUTO_RETRY 1
|
||||||
|
|
||||||
|
/* Mask1 register */
|
||||||
|
#define FUSB_MASK1 0x0A
|
||||||
|
#define FUSB_MASK1_M_VBUSOK (1 << 7)
|
||||||
|
#define FUSB_MASK1_M_ACTIVITY (1 << 6)
|
||||||
|
#define FUSB_MASK1_M_COMP_CHNG (1 << 5)
|
||||||
|
#define FUSB_MASK1_M_CRC_CHK (1 << 4)
|
||||||
|
#define FUSB_MASK1_M_ALERT (1 << 3)
|
||||||
|
#define FUSB_MASK1_M_WAKE (1 << 2)
|
||||||
|
#define FUSB_MASK1_M_COLLISION (1 << 1)
|
||||||
|
#define FUSB_MASK1_M_BC_LVL (1 << 0)
|
||||||
|
|
||||||
|
/* Power register */
|
||||||
|
#define FUSB_POWER 0x0B
|
||||||
|
#define FUSB_POWER_PWR3 (1 << 3)
|
||||||
|
#define FUSB_POWER_PWR2 (1 << 2)
|
||||||
|
#define FUSB_POWER_PWR1 (1 << 1)
|
||||||
|
#define FUSB_POWER_PWR0 1
|
||||||
|
|
||||||
|
/* Reset register */
|
||||||
|
#define FUSB_RESET 0x0C
|
||||||
|
#define FUSB_RESET_PD_RESET (1 << 1)
|
||||||
|
#define FUSB_RESET_SW_RES 1
|
||||||
|
|
||||||
|
/* OCPreg register */
|
||||||
|
#define FUSB_OCPREG 0x0D
|
||||||
|
#define FUSB_OCPREG_OCP_RANGE (1 << 3)
|
||||||
|
#define FUSB_OCPREG_OCP_CUR_SHIFT 0
|
||||||
|
#define FUSB_OCPREG_OCP_CUR (0x7 << FUSB_OCPREG_OCP_CUR_SHIFT)
|
||||||
|
|
||||||
|
/* Maska register */
|
||||||
|
#define FUSB_MASKA 0x0E
|
||||||
|
#define FUSB_MASKA_M_OCP_TEMP (1 << 7)
|
||||||
|
#define FUSB_MASKA_M_TOGDONE (1 << 6)
|
||||||
|
#define FUSB_MASKA_M_SOFTFAIL (1 << 5)
|
||||||
|
#define FUSB_MASKA_M_RETRYFAIL (1 << 4)
|
||||||
|
#define FUSB_MASKA_M_HARDSENT (1 << 3)
|
||||||
|
#define FUSB_MASKA_M_TXSENT (1 << 2)
|
||||||
|
#define FUSB_MASKA_M_SOFTRST (1 << 1)
|
||||||
|
#define FUSB_MASKA_M_HARDRST 1
|
||||||
|
|
||||||
|
/* Maskb register */
|
||||||
|
#define FUSB_MASKB 0x0F
|
||||||
|
#define FUSB_MASKB_M_GCRCSENT 1
|
||||||
|
|
||||||
|
/* Control4 register */
|
||||||
|
#define FUSB_CONTROL4 0x10
|
||||||
|
#define FUSB_CONTROL4_TOG_EXIT_AUD 1
|
||||||
|
|
||||||
|
/* Status0a register */
|
||||||
|
#define FUSB_STATUS0A 0x3C
|
||||||
|
#define FUSB_STATUS0A_SOFTFAIL (1 << 5)
|
||||||
|
#define FUSB_STATUS0A_RETRYFAIL (1 << 4)
|
||||||
|
#define FUSB_STATUS0A_POWER3 (1 << 3)
|
||||||
|
#define FUSB_STATUS0A_POWER2 (1 << 2)
|
||||||
|
#define FUSB_STATUS0A_SOFTRST (1 << 1)
|
||||||
|
#define FUSB_STATUS0A_HARDRST 1
|
||||||
|
|
||||||
|
/* Status1a register */
|
||||||
|
#define FUSB_STATUS1A 0x3D
|
||||||
|
#define FUSB_STATUS1A_TOGSS_SHIFT 3
|
||||||
|
#define FUSB_STATUS1A_TOGSS (0x7 << FUSB_STATUS1A_TOGSS_SHIFT)
|
||||||
|
#define FUSB_STATUS1A_RXSOP2DB (1 << 2)
|
||||||
|
#define FUSB_STATUS1A_RXSOP1DB (1 << 1)
|
||||||
|
#define FUSB_STATUS1A_RXSOP 1
|
||||||
|
|
||||||
|
/* Interrupta register */
|
||||||
|
#define FUSB_INTERRUPTA 0x3E
|
||||||
|
#define FUSB_INTERRUPTA_I_OCP_TEMP (1 << 7)
|
||||||
|
#define FUSB_INTERRUPTA_I_TOGDONE (1 << 6)
|
||||||
|
#define FUSB_INTERRUPTA_I_SOFTFAIL (1 << 5)
|
||||||
|
#define FUSB_INTERRUPTA_I_RETRYFAIL (1 << 4)
|
||||||
|
#define FUSB_INTERRUPTA_I_HARDSENT (1 << 3)
|
||||||
|
#define FUSB_INTERRUPTA_I_TXSENT (1 << 2)
|
||||||
|
#define FUSB_INTERRUPTA_I_SOFTRST (1 << 1)
|
||||||
|
#define FUSB_INTERRUPTA_I_HARDRST 1
|
||||||
|
|
||||||
|
/* Interruptb register */
|
||||||
|
#define FUSB_INTERRUPTB 0x3F
|
||||||
|
#define FUSB_INTERRUPTB_I_GCRCSENT 1
|
||||||
|
|
||||||
|
/* Status0 register */
|
||||||
|
#define FUSB_STATUS0 0x40
|
||||||
|
#define FUSB_STATUS0_VBUSOK (1 << 7)
|
||||||
|
#define FUSB_STATUS0_ACTIVITY (1 << 6)
|
||||||
|
#define FUSB_STATUS0_COMP (1 << 5)
|
||||||
|
#define FUSB_STATUS0_CRC_CHK (1 << 4)
|
||||||
|
#define FUSB_STATUS0_ALERT (1 << 3)
|
||||||
|
#define FUSB_STATUS0_WAKE (1 << 2)
|
||||||
|
#define FUSB_STATUS0_BC_LVL_SHIFT 0
|
||||||
|
#define FUSB_STATUS0_BC_LVL (0x3 << FUSB_STATUS0_BC_LVL_SHIFT)
|
||||||
|
|
||||||
|
/* Status1 register */
|
||||||
|
#define FUSB_STATUS1 0x41
|
||||||
|
#define FUSB_STATUS1_RXSOP2 (1 << 7)
|
||||||
|
#define FUSB_STATUS1_RXSOP1 (1 << 6)
|
||||||
|
#define FUSB_STATUS1_RX_EMPTY (1 << 5)
|
||||||
|
#define FUSB_STATUS1_RX_FULL (1 << 4)
|
||||||
|
#define FUSB_STATUS1_TX_EMPTY (1 << 3)
|
||||||
|
#define FUSB_STATUS1_TX_FULL (1 << 2)
|
||||||
|
#define FUSB_STATUS1_OVRTEMP (1 << 1)
|
||||||
|
#define FUSB_STATUS1_OCP 1
|
||||||
|
|
||||||
|
/* Interrupt register */
|
||||||
|
#define FUSB_INTERRUPT 0x42
|
||||||
|
#define FUSB_INTERRUPT_I_VBUSOK (1 << 7)
|
||||||
|
#define FUSB_INTERRUPT_I_ACTIVITY (1 << 6)
|
||||||
|
#define FUSB_INTERRUPT_I_COMP_CHNG (1 << 5)
|
||||||
|
#define FUSB_INTERRUPT_I_CRC_CHK (1 << 4)
|
||||||
|
#define FUSB_INTERRUPT_I_ALERT (1 << 3)
|
||||||
|
#define FUSB_INTERRUPT_I_WAKE (1 << 2)
|
||||||
|
#define FUSB_INTERRUPT_I_COLLISION (1 << 1)
|
||||||
|
#define FUSB_INTERRUPT_I_BC_LVL 1
|
||||||
|
|
||||||
|
/* FIFOs register */
|
||||||
|
#define FUSB_FIFOS 0x43
|
||||||
|
|
||||||
|
#define FUSB_FIFO_TX_TXON 0xA1
|
||||||
|
#define FUSB_FIFO_TX_SOP1 0x12
|
||||||
|
#define FUSB_FIFO_TX_SOP2 0x13
|
||||||
|
#define FUSB_FIFO_TX_SOP3 0x1B
|
||||||
|
#define FUSB_FIFO_TX_RESET1 0x15
|
||||||
|
#define FUSB_FIFO_TX_RESET2 0x16
|
||||||
|
#define FUSB_FIFO_TX_PACKSYM 0x80
|
||||||
|
#define FUSB_FIFO_TX_JAM_CRC 0xFF
|
||||||
|
#define FUSB_FIFO_TX_EOP 0x14
|
||||||
|
#define FUSB_FIFO_TX_TXOFF 0xFE
|
||||||
|
|
||||||
|
#define FUSB_FIFO_RX_TOKEN_BITS 0xE0
|
||||||
|
#define FUSB_FIFO_RX_SOP 0xE0
|
||||||
|
#define FUSB_FIFO_RX_SOP1 0xC0
|
||||||
|
#define FUSB_FIFO_RX_SOP2 0xA0
|
||||||
|
#define FUSB_FIFO_RX_SOP1DB 0x80
|
||||||
|
#define FUSB_FIFO_RX_SOP2DB 0x60
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FUSB status union
|
||||||
|
*
|
||||||
|
* Provides a nicer structure than just an array of uint8_t for working with
|
||||||
|
* the FUSB302B status and interrupt flags.
|
||||||
|
*/
|
||||||
|
union fusb_status {
|
||||||
|
uint8_t bytes[7];
|
||||||
|
struct {
|
||||||
|
uint8_t status0a;
|
||||||
|
uint8_t status1a;
|
||||||
|
uint8_t interrupta;
|
||||||
|
uint8_t interruptb;
|
||||||
|
uint8_t status0;
|
||||||
|
uint8_t status1;
|
||||||
|
uint8_t interrupt;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* FUSB functions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send a USB Power Delivery message to the FUSB302B
|
||||||
|
*/
|
||||||
|
void fusb_send_message(const union pd_msg *msg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a USB Power Delivery message from the FUSB302B
|
||||||
|
*/
|
||||||
|
uint8_t fusb_read_message(union pd_msg *msg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tell the FUSB302B to send a hard reset signal
|
||||||
|
*/
|
||||||
|
void fusb_send_hardrst();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the FUSB302B status and interrupt flags into *status
|
||||||
|
*/
|
||||||
|
void fusb_get_status(union fusb_status *status);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the FUSB302B BC_LVL as an enum fusb_typec_current
|
||||||
|
*/
|
||||||
|
enum fusb_typec_current fusb_get_typec_current();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialization routine for the FUSB302B
|
||||||
|
*/
|
||||||
|
void fusb_setup();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset the FUSB302B
|
||||||
|
*/
|
||||||
|
void fusb_reset();
|
||||||
|
|
||||||
|
bool fusb_read_id();
|
||||||
|
|
||||||
|
#endif /* PDB_FUSB302B_H */
|
||||||
38
workspace/TS100/Core/Drivers/FUSB302/fusbpd.cpp
Normal file
38
workspace/TS100/Core/Drivers/FUSB302/fusbpd.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* fusbpd.cpp
|
||||||
|
*
|
||||||
|
* Created on: 13 Jun 2020
|
||||||
|
* Author: Ralim
|
||||||
|
*/
|
||||||
|
#include "Model_Config.h"
|
||||||
|
#ifdef POW_PD
|
||||||
|
#include <fusbpd.h>
|
||||||
|
#include <pd.h>
|
||||||
|
#include "BSP.h"
|
||||||
|
#include "I2CBB.hpp"
|
||||||
|
#include "fusb302b.h"
|
||||||
|
#include "policy_engine.h"
|
||||||
|
#include "protocol_rx.h"
|
||||||
|
#include "protocol_tx.h"
|
||||||
|
#include "int_n.h"
|
||||||
|
#include "hard_reset.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void fusb302_start_processing() {
|
||||||
|
/* Initialize the FUSB302B */
|
||||||
|
resetWatchdog();
|
||||||
|
fusb_setup();
|
||||||
|
resetWatchdog();
|
||||||
|
/* Create the policy engine thread. */
|
||||||
|
PolicyEngine::init();
|
||||||
|
|
||||||
|
/* Create the protocol layer threads. */
|
||||||
|
ProtocolReceive::init();
|
||||||
|
ProtocolTransmit::init();
|
||||||
|
ResetHandler::init();
|
||||||
|
resetWatchdog();
|
||||||
|
/* Create the INT_N thread. */
|
||||||
|
InterruptHandler::init();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
18
workspace/TS100/Core/Drivers/FUSB302/fusbpd.h
Normal file
18
workspace/TS100/Core/Drivers/FUSB302/fusbpd.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* fusbpd.h
|
||||||
|
*
|
||||||
|
* Created on: 13 Jun 2020
|
||||||
|
* Author: Ralim
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DRIVERS_FUSB302_FUSBPD_H_
|
||||||
|
#define DRIVERS_FUSB302_FUSBPD_H_
|
||||||
|
//Wrapper for all of the FUSB302 PD work
|
||||||
|
extern struct pdb_config pdb_config_data;
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//returns 1 if the FUSB302 is on the I2C bus
|
||||||
|
uint8_t fusb302_detect();
|
||||||
|
|
||||||
|
void fusb302_start_processing();
|
||||||
|
#endif /* DRIVERS_FUSB302_FUSBPD_H_ */
|
||||||
152
workspace/TS100/Core/Drivers/FUSB302/hard_reset.cpp
Normal file
152
workspace/TS100/Core/Drivers/FUSB302/hard_reset.cpp
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
63
workspace/TS100/Core/Drivers/FUSB302/hard_reset.h
Normal file
63
workspace/TS100/Core/Drivers/FUSB302/hard_reset.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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 */
|
||||||
108
workspace/TS100/Core/Drivers/FUSB302/int_n.cpp
Normal file
108
workspace/TS100/Core/Drivers/FUSB302/int_n.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* 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 "int_n.h"
|
||||||
|
#include "fusbpd.h"
|
||||||
|
#include <pd.h>
|
||||||
|
#include "fusb302b.h"
|
||||||
|
#include "protocol_rx.h"
|
||||||
|
#include "protocol_tx.h"
|
||||||
|
#include "hard_reset.h"
|
||||||
|
#include "policy_engine.h"
|
||||||
|
#include "protocol_rx.h"
|
||||||
|
#include "protocol_tx.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "BSP.h"
|
||||||
|
|
||||||
|
osThreadId InterruptHandler::TaskHandle=NULL;
|
||||||
|
uint32_t InterruptHandler::TaskBuffer[InterruptHandler::TaskStackSize];
|
||||||
|
osStaticThreadDef_t InterruptHandler::TaskControlBlock;
|
||||||
|
|
||||||
|
void InterruptHandler::init() {
|
||||||
|
osThreadStaticDef(intTask, Thread, PDB_PRIO_PRL_INT_N, 0, TaskStackSize,
|
||||||
|
TaskBuffer, &TaskControlBlock);
|
||||||
|
TaskHandle = osThreadCreate(osThread(intTask), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterruptHandler::Thread(const void *arg) {
|
||||||
|
(void) arg;
|
||||||
|
union fusb_status status;
|
||||||
|
volatile uint32_t events;
|
||||||
|
bool notifSent = false;
|
||||||
|
while (true) {
|
||||||
|
/* If the INT_N line is low */
|
||||||
|
if (xTaskNotifyWait(0x00, 0x0F, NULL,
|
||||||
|
PolicyEngine::setupCompleteOrTimedOut() ? 1000 : 10) == pdPASS) {
|
||||||
|
//delay slightly so we catch the crc with better timing
|
||||||
|
osDelay(1);
|
||||||
|
}
|
||||||
|
notifSent = false;
|
||||||
|
/* Read the FUSB302B status and interrupt registers */
|
||||||
|
fusb_get_status(&status);
|
||||||
|
/* If the I_TXSENT or I_RETRYFAIL flag is set, tell the Protocol TX
|
||||||
|
* thread */
|
||||||
|
if (status.interrupta & FUSB_INTERRUPTA_I_TXSENT) {
|
||||||
|
ProtocolTransmit::notify(
|
||||||
|
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_TXSENT);
|
||||||
|
notifSent = true;
|
||||||
|
}
|
||||||
|
if (status.interrupta & FUSB_INTERRUPTA_I_RETRYFAIL) {
|
||||||
|
ProtocolTransmit::notify(
|
||||||
|
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_RETRYFAIL);
|
||||||
|
notifSent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the I_GCRCSENT flag is set, tell the Protocol RX thread */
|
||||||
|
//This means a message was recieved with a good CRC
|
||||||
|
if (status.interruptb & FUSB_INTERRUPTB_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
|
||||||
|
* Engine thread */
|
||||||
|
if (status.interrupta & FUSB_INTERRUPTA_I_OCP_TEMP
|
||||||
|
&& status.status1 & FUSB_STATUS1_OVRTEMP) {
|
||||||
|
PolicyEngine::notify(PDB_EVT_PE_I_OVRTEMP);
|
||||||
|
notifSent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void InterruptHandler::irqCallback() {
|
||||||
|
if (TaskHandle != NULL) {
|
||||||
|
BaseType_t taskWoke = pdFALSE;
|
||||||
|
xTaskNotifyFromISR(TaskHandle, 0x01, eNotifyAction::eSetBits,
|
||||||
|
&taskWoke);
|
||||||
|
portYIELD_FROM_ISR(taskWoke);
|
||||||
|
}
|
||||||
|
}
|
||||||
57
workspace/TS100/Core/Drivers/FUSB302/int_n.h
Normal file
57
workspace/TS100/Core/Drivers/FUSB302/int_n.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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_INT_N_OLD_H
|
||||||
|
#define PDB_INT_N_OLD_H
|
||||||
|
|
||||||
|
#include <pd.h>
|
||||||
|
|
||||||
|
class InterruptHandler {
|
||||||
|
public:
|
||||||
|
//Creates the thread to handle the Interrupt pin
|
||||||
|
static void init();
|
||||||
|
|
||||||
|
|
||||||
|
static void irqCallback();
|
||||||
|
private:
|
||||||
|
static void Thread(const void *arg);
|
||||||
|
static osThreadId TaskHandle;
|
||||||
|
static const size_t TaskStackSize = 1536 / 3;
|
||||||
|
static uint32_t TaskBuffer[TaskStackSize];
|
||||||
|
static osStaticThreadDef_t TaskControlBlock;
|
||||||
|
/*
|
||||||
|
* Hard Reset machine states
|
||||||
|
*/
|
||||||
|
enum hardrst_state {
|
||||||
|
PRLHRResetLayer,
|
||||||
|
PRLHRIndicateHardReset,
|
||||||
|
PRLHRRequestHardReset,
|
||||||
|
PRLHRWaitPHY,
|
||||||
|
PRLHRHardResetRequested,
|
||||||
|
PRLHRWaitPE,
|
||||||
|
PRLHRComplete
|
||||||
|
};
|
||||||
|
static enum hardrst_state hardrst_reset_layer();
|
||||||
|
static enum hardrst_state hardrst_indicate_hard_reset();
|
||||||
|
static enum hardrst_state hardrst_request_hard_reset();
|
||||||
|
static enum hardrst_state hardrst_wait_phy();
|
||||||
|
static enum hardrst_state hardrst_hard_reset_requested();
|
||||||
|
static enum hardrst_state hardrst_wait_pe();
|
||||||
|
static enum hardrst_state hardrst_complete();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PDB_INT_N_OLD_H */
|
||||||
400
workspace/TS100/Core/Drivers/FUSB302/pd.h
Normal file
400
workspace/TS100/Core/Drivers/FUSB302/pd.h
Normal file
@@ -0,0 +1,400 @@
|
|||||||
|
/*
|
||||||
|
* 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_PD_H
|
||||||
|
#define PDB_PD_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "pdb_msg.h"
|
||||||
|
#include "cmsis_os.h"
|
||||||
|
#include "pdb_conf.h"
|
||||||
|
/*
|
||||||
|
* Macros for working with USB Power Delivery messages.
|
||||||
|
*
|
||||||
|
* This file is mostly written from the PD Rev. 2.0 spec, but the header is
|
||||||
|
* written from the Rev. 3.0 spec.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PD Header
|
||||||
|
*/
|
||||||
|
#define PD_HDR_MSGTYPE_SHIFT 0
|
||||||
|
#define PD_HDR_MSGTYPE (0x1F << PD_HDR_MSGTYPE_SHIFT)
|
||||||
|
#define PD_HDR_DATAROLE_SHIFT 5
|
||||||
|
#define PD_HDR_DATAROLE (0x1 << PD_HDR_DATAROLE_SHIFT)
|
||||||
|
#define PD_HDR_SPECREV_SHIFT 6
|
||||||
|
#define PD_HDR_SPECREV (0x3 << PD_HDR_SPECREV_SHIFT)
|
||||||
|
#define PD_HDR_POWERROLE_SHIFT 8
|
||||||
|
#define PD_HDR_POWERROLE (1 << PD_HDR_POWERROLE_SHIFT)
|
||||||
|
#define PD_HDR_MESSAGEID_SHIFT 9
|
||||||
|
#define PD_HDR_MESSAGEID (0x7 << PD_HDR_MESSAGEID_SHIFT)
|
||||||
|
#define PD_HDR_NUMOBJ_SHIFT 12
|
||||||
|
#define PD_HDR_NUMOBJ (0x7 << PD_HDR_NUMOBJ_SHIFT)
|
||||||
|
#define PD_HDR_EXT (1 << 15)
|
||||||
|
|
||||||
|
/* Message types */
|
||||||
|
#define PD_MSGTYPE_GET(msg) (((msg)->hdr & PD_HDR_MSGTYPE) >> PD_HDR_MSGTYPE_SHIFT)
|
||||||
|
/* Control Message */
|
||||||
|
#define PD_MSGTYPE_GOODCRC 0x01
|
||||||
|
#define PD_MSGTYPE_GOTOMIN 0x02
|
||||||
|
#define PD_MSGTYPE_ACCEPT 0x03
|
||||||
|
#define PD_MSGTYPE_REJECT 0x04
|
||||||
|
#define PD_MSGTYPE_PING 0x05
|
||||||
|
#define PD_MSGTYPE_PS_RDY 0x06
|
||||||
|
#define PD_MSGTYPE_GET_SOURCE_CAP 0x07
|
||||||
|
#define PD_MSGTYPE_GET_SINK_CAP 0x08
|
||||||
|
#define PD_MSGTYPE_DR_SWAP 0x09
|
||||||
|
#define PD_MSGTYPE_PR_SWAP 0x0A
|
||||||
|
#define PD_MSGTYPE_VCONN_SWAP 0x0B
|
||||||
|
#define PD_MSGTYPE_WAIT 0x0C
|
||||||
|
#define PD_MSGTYPE_SOFT_RESET 0x0D
|
||||||
|
#define PD_MSGTYPE_NOT_SUPPORTED 0x10
|
||||||
|
#define PD_MSGTYPE_GET_SOURCE_CAP_EXTENDED 0x11
|
||||||
|
#define PD_MSGTYPE_GET_STATUS 0x12
|
||||||
|
#define PD_MSGTYPE_FR_SWAP 0x13
|
||||||
|
#define PD_MSGTYPE_GET_PPS_STATUS 0x14
|
||||||
|
#define PD_MSGTYPE_GET_COUNTRY_CODES 0x15
|
||||||
|
/* Data Message */
|
||||||
|
#define PD_MSGTYPE_SOURCE_CAPABILITIES 0x01
|
||||||
|
#define PD_MSGTYPE_REQUEST 0x02
|
||||||
|
#define PD_MSGTYPE_BIST 0x03
|
||||||
|
#define PD_MSGTYPE_SINK_CAPABILITIES 0x04
|
||||||
|
#define PD_MSGTYPE_BATTERY_STATUS 0x05
|
||||||
|
#define PD_MSGTYPE_ALERT 0x06
|
||||||
|
#define PD_MSGTYPE_GET_COUNTRY_INFO 0x07
|
||||||
|
#define PD_MSGTYPE_VENDOR_DEFINED 0x0F
|
||||||
|
/* Extended Message */
|
||||||
|
#define PD_MSGTYPE_SOURCE_CAPABILITIES_EXTENDED 0x01
|
||||||
|
#define PD_MSGTYPE_STATUS 0x02
|
||||||
|
#define PD_MSGTYPE_GET_BATTERY_CAP 0x03
|
||||||
|
#define PD_MSGTYPE_GET_BATTERY_STATUS 0x04
|
||||||
|
#define PD_MSGTYPE_BATTERY_CAPABILITIES 0x05
|
||||||
|
#define PD_MSGTYPE_GET_MANUFACTURER_INFO 0x06
|
||||||
|
#define PD_MSGTYPE_MANUFACTURER_INFO 0x07
|
||||||
|
#define PD_MSGTYPE_SECURITY_REQUEST 0x08
|
||||||
|
#define PD_MSGTYPE_SECURITY_RESPONSE 0x09
|
||||||
|
#define PD_MSGTYPE_FIRMWARE_UPDATE_REQUEST 0x0A
|
||||||
|
#define PD_MSGTYPE_FIRMWARE_UPDATE_RESPONSE 0x0B
|
||||||
|
#define PD_MSGTYPE_PPS_STATUS 0x0C
|
||||||
|
#define PD_MSGTYPE_COUNTRY_INFO 0x0D
|
||||||
|
#define PD_MSGTYPE_COUNTRY_CODES 0x0E
|
||||||
|
|
||||||
|
/* Data roles */
|
||||||
|
#define PD_DATAROLE_UFP (0x0 << PD_HDR_DATAROLE_SHIFT)
|
||||||
|
#define PD_DATAROLE_DFP (0x1 << PD_HDR_DATAROLE_SHIFT)
|
||||||
|
|
||||||
|
/* Specification revisions */
|
||||||
|
#define PD_SPECREV_1_0 (0x0 << PD_HDR_SPECREV_SHIFT)
|
||||||
|
#define PD_SPECREV_2_0 (0x1 << PD_HDR_SPECREV_SHIFT)
|
||||||
|
#define PD_SPECREV_3_0 (0x2 << PD_HDR_SPECREV_SHIFT)
|
||||||
|
|
||||||
|
/* Port power roles */
|
||||||
|
#define PD_POWERROLE_SINK (0x0 << PD_HDR_POWERROLE_SHIFT)
|
||||||
|
#define PD_POWERROLE_SOURCE (0x1 << PD_HDR_POWERROLE_SHIFT)
|
||||||
|
|
||||||
|
/* Message ID */
|
||||||
|
#define PD_MESSAGEID_GET(msg) (((msg)->hdr & PD_HDR_MESSAGEID) >> PD_HDR_MESSAGEID_SHIFT)
|
||||||
|
|
||||||
|
/* Number of data objects */
|
||||||
|
#define PD_NUMOBJ(n) (((n) << PD_HDR_NUMOBJ_SHIFT) & PD_HDR_NUMOBJ)
|
||||||
|
#define PD_NUMOBJ_GET(msg) (((msg)->hdr & PD_HDR_NUMOBJ) >> PD_HDR_NUMOBJ_SHIFT)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PD Extended Message Header
|
||||||
|
*/
|
||||||
|
#define PD_EXTHDR_DATA_SIZE_SHIFT 0
|
||||||
|
#define PD_EXTHDR_DATA_SIZE (0x1FF << PD_EXTHDR_DATA_SIZE_SHIFT)
|
||||||
|
#define PD_EXTHDR_REQUEST_CHUNK_SHIFT 10
|
||||||
|
#define PD_EXTHDR_REQUEST_CHUNK (1 << PD_EXTHDR_REQUEST_CHUNK_SHIFT)
|
||||||
|
#define PD_EXTHDR_CHUNK_NUMBER_SHIFT 11
|
||||||
|
#define PD_EXTHDR_CHUNK_NUMBER (0xF << PD_EXTHDR_CHUNK_NUMBER_SHIFT)
|
||||||
|
#define PD_EXTHDR_CHUNKED_SHIFT 15
|
||||||
|
#define PD_EXTHDR_CHUNKED (1 << PD_EXTHDR_CHUNKED_SHIFT)
|
||||||
|
|
||||||
|
/* Data size */
|
||||||
|
#define PD_DATA_SIZE(n) (((n) << PD_EXTHDR_DATA_SIZE_SHIFT) & PD_EXTHDR_DATA_SIZE)
|
||||||
|
#define PD_DATA_SIZE_GET(msg) (((msg)->exthdr & PD_EXTHDR_DATA_SIZE) >> PD_EXTHDR_DATA_SIZE_SHIFT)
|
||||||
|
|
||||||
|
/* Chunk number */
|
||||||
|
#define PD_CHUNK_NUMBER(n) (((n) << PD_EXTHDR_CHUNK_NUMBER_SHIFT) & PD_EXTHDR_CHUNK_NUMBER)
|
||||||
|
#define PD_CHUNK_NUMBER_GET(msg) (((msg)->exthdr & PD_EXTHDR_CHUNK_NUMBER) >> PD_EXTHDR_CHUNK_NUMBER_SHIFT)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PD Power Data Object
|
||||||
|
*/
|
||||||
|
#define PD_PDO_TYPE_SHIFT 30
|
||||||
|
#define PD_PDO_TYPE (0x3 << PD_PDO_TYPE_SHIFT)
|
||||||
|
|
||||||
|
/* PDO types */
|
||||||
|
#define PD_PDO_TYPE_FIXED ((unsigned) (0x0 << PD_PDO_TYPE_SHIFT))
|
||||||
|
#define PD_PDO_TYPE_BATTERY ((unsigned) (0x1 << PD_PDO_TYPE_SHIFT))
|
||||||
|
#define PD_PDO_TYPE_VARIABLE ((unsigned) (0x2 << PD_PDO_TYPE_SHIFT))
|
||||||
|
#define PD_PDO_TYPE_AUGMENTED ((unsigned) (0x3 << PD_PDO_TYPE_SHIFT))
|
||||||
|
|
||||||
|
#define PD_APDO_TYPE_SHIFT 28
|
||||||
|
#define PD_APDO_TYPE (0x3 << PD_APDO_TYPE_SHIFT)
|
||||||
|
|
||||||
|
/* APDO types */
|
||||||
|
#define PD_APDO_TYPE_PPS (0x0 << PD_APDO_TYPE_SHIFT)
|
||||||
|
|
||||||
|
/* PD Source Fixed PDO */
|
||||||
|
#define PD_PDO_SRC_FIXED_DUAL_ROLE_PWR_SHIFT 29
|
||||||
|
#define PD_PDO_SRC_FIXED_DUAL_ROLE_PWR (1 << PD_PDO_SRC_FIXED_DUAL_ROLE_PWR_SHIFT)
|
||||||
|
#define PD_PDO_SRC_FIXED_USB_SUSPEND_SHIFT 28
|
||||||
|
#define PD_PDO_SRC_FIXED_USB_SUSPEND (1 << PD_PDO_SRC_FIXED_USB_SUSPEND_SHIFT)
|
||||||
|
#define PD_PDO_SRC_FIXED_UNCONSTRAINED_SHIFT 27
|
||||||
|
#define PD_PDO_SRC_FIXED_UNCONSTRAINED (1 << PD_PDO_SRC_FIXED_UNCONSTRAINED_SHIFT)
|
||||||
|
#define PD_PDO_SRC_FIXED_USB_COMMS_SHIFT 26
|
||||||
|
#define PD_PDO_SRC_FIXED_USB_COMMS (1 << PD_PDO_SRC_FIXED_USB_COMMS_SHIFT)
|
||||||
|
#define PD_PDO_SRC_FIXED_DUAL_ROLE_DATA_SHIFT 25
|
||||||
|
#define PD_PDO_SRC_FIXED_DUAL_ROLE_DATA (1 << PD_PDO_SRC_FIXED_DUAL_ROLE_DATA_SHIFT)
|
||||||
|
#define PD_PDO_SRC_FIXED_UNCHUNKED_EXT_MSG_SHIFT 24
|
||||||
|
#define PD_PDO_SRC_FIXED_UNCHUNKED_EXT_MSG (1 << PD_PDO_SRC_FIXED_UNCHUNKED_EXT_MSG_SHIFT)
|
||||||
|
#define PD_PDO_SRC_FIXED_PEAK_CURRENT_SHIFT 20
|
||||||
|
#define PD_PDO_SRC_FIXED_PEAK_CURRENT (0x3 << PD_PDO_SRC_FIXED_PEAK_CURRENT_SHIFT)
|
||||||
|
#define PD_PDO_SRC_FIXED_VOLTAGE_SHIFT 10
|
||||||
|
#define PD_PDO_SRC_FIXED_VOLTAGE (0x3FF << PD_PDO_SRC_FIXED_VOLTAGE_SHIFT)
|
||||||
|
#define PD_PDO_SRC_FIXED_CURRENT_SHIFT 0
|
||||||
|
#define PD_PDO_SRC_FIXED_CURRENT (0x3FF << PD_PDO_SRC_FIXED_CURRENT_SHIFT)
|
||||||
|
|
||||||
|
/* PD Source Fixed PDO current */
|
||||||
|
#define PD_PDO_SRC_FIXED_CURRENT_GET(pdo) (((pdo) & PD_PDO_SRC_FIXED_CURRENT) >> PD_PDO_SRC_FIXED_CURRENT_SHIFT)
|
||||||
|
|
||||||
|
/* PD Source Fixed PDO voltage */
|
||||||
|
#define PD_PDO_SRC_FIXED_VOLTAGE_GET(pdo) (((pdo) & PD_PDO_SRC_FIXED_VOLTAGE) >> PD_PDO_SRC_FIXED_VOLTAGE_SHIFT)
|
||||||
|
|
||||||
|
/* PD Programmable Power Supply APDO */
|
||||||
|
#define PD_APDO_PPS_MAX_VOLTAGE_SHIFT 17
|
||||||
|
#define PD_APDO_PPS_MAX_VOLTAGE (0xFF << PD_APDO_PPS_MAX_VOLTAGE_SHIFT)
|
||||||
|
#define PD_APDO_PPS_MIN_VOLTAGE_SHIFT 8
|
||||||
|
#define PD_APDO_PPS_MIN_VOLTAGE (0xFF << PD_APDO_PPS_MIN_VOLTAGE_SHIFT)
|
||||||
|
#define PD_APDO_PPS_CURRENT_SHIFT 0
|
||||||
|
#define PD_APDO_PPS_CURRENT (0x7F << PD_APDO_PPS_CURRENT_SHIFT)
|
||||||
|
|
||||||
|
/* PD Programmable Power Supply APDO voltages */
|
||||||
|
#define PD_APDO_PPS_MAX_VOLTAGE_GET(pdo) (((pdo) & PD_APDO_PPS_MAX_VOLTAGE) >> PD_APDO_PPS_MAX_VOLTAGE_SHIFT)
|
||||||
|
#define PD_APDO_PPS_MIN_VOLTAGE_GET(pdo) (((pdo) & PD_APDO_PPS_MIN_VOLTAGE) >> PD_APDO_PPS_MIN_VOLTAGE_SHIFT)
|
||||||
|
|
||||||
|
#define PD_APDO_PPS_MAX_VOLTAGE_SET(v) (((v) << PD_APDO_PPS_MAX_VOLTAGE_SHIFT) & PD_APDO_PPS_MAX_VOLTAGE)
|
||||||
|
#define PD_APDO_PPS_MIN_VOLTAGE_SET(v) (((v) << PD_APDO_PPS_MIN_VOLTAGE_SHIFT) & PD_APDO_PPS_MIN_VOLTAGE)
|
||||||
|
|
||||||
|
/* PD Programmable Power Supply APDO current */
|
||||||
|
#define PD_APDO_PPS_CURRENT_GET(pdo) ((uint8_t) (((pdo) & PD_APDO_PPS_CURRENT) >> PD_APDO_PPS_CURRENT_SHIFT))
|
||||||
|
|
||||||
|
#define PD_APDO_PPS_CURRENT_SET(i) (((i) << PD_APDO_PPS_CURRENT_SHIFT) & PD_APDO_PPS_CURRENT)
|
||||||
|
|
||||||
|
|
||||||
|
/* PD Sink Fixed PDO */
|
||||||
|
#define PD_PDO_SNK_FIXED_DUAL_ROLE_PWR_SHIFT 29
|
||||||
|
#define PD_PDO_SNK_FIXED_DUAL_ROLE_PWR (1 << PD_PDO_SNK_FIXED_DUAL_ROLE_PWR_SHIFT)
|
||||||
|
#define PD_PDO_SNK_FIXED_HIGHER_CAP_SHIFT 28
|
||||||
|
#define PD_PDO_SNK_FIXED_HIGHER_CAP (1 << PD_PDO_SNK_FIXED_HIGHER_CAP_SHIFT)
|
||||||
|
#define PD_PDO_SNK_FIXED_UNCONSTRAINED_SHIFT 27
|
||||||
|
#define PD_PDO_SNK_FIXED_UNCONSTRAINED (1 << PD_PDO_SNK_FIXED_UNCONSTRAINED_SHIFT)
|
||||||
|
#define PD_PDO_SNK_FIXED_USB_COMMS_SHIFT 26
|
||||||
|
#define PD_PDO_SNK_FIXED_USB_COMMS (1 << PD_PDO_SNK_FIXED_USB_COMMS_SHIFT)
|
||||||
|
#define PD_PDO_SNK_FIXED_DUAL_ROLE_DATA_SHIFT 25
|
||||||
|
#define PD_PDO_SNK_FIXED_DUAL_ROLE_DATA (1 << PD_PDO_SNK_FIXED_DUAL_ROLE_DATA_SHIFT)
|
||||||
|
#define PD_PDO_SNK_FIXED_VOLTAGE_SHIFT 10
|
||||||
|
#define PD_PDO_SNK_FIXED_VOLTAGE (0x3FF << PD_PDO_SNK_FIXED_VOLTAGE_SHIFT)
|
||||||
|
#define PD_PDO_SNK_FIXED_CURRENT_SHIFT 0
|
||||||
|
#define PD_PDO_SNK_FIXED_CURRENT (0x3FF << PD_PDO_SNK_FIXED_CURRENT_SHIFT)
|
||||||
|
|
||||||
|
/* PD Sink Fixed PDO current */
|
||||||
|
#define PD_PDO_SNK_FIXED_CURRENT_SET(i) (((i) << PD_PDO_SNK_FIXED_CURRENT_SHIFT) & PD_PDO_SNK_FIXED_CURRENT)
|
||||||
|
|
||||||
|
/* PD Sink Fixed PDO voltage */
|
||||||
|
#define PD_PDO_SNK_FIXED_VOLTAGE_SET(v) (((v) << PD_PDO_SNK_FIXED_VOLTAGE_SHIFT) & PD_PDO_SNK_FIXED_VOLTAGE)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PD Request Data Object
|
||||||
|
*/
|
||||||
|
#define PD_RDO_OBJPOS_SHIFT 28
|
||||||
|
#define PD_RDO_OBJPOS (0x7 << PD_RDO_OBJPOS_SHIFT)
|
||||||
|
#define PD_RDO_GIVEBACK_SHIFT 27
|
||||||
|
#define PD_RDO_GIVEBACK (1 << PD_RDO_GIVEBACK_SHIFT)
|
||||||
|
#define PD_RDO_CAP_MISMATCH_SHIFT 26
|
||||||
|
#define PD_RDO_CAP_MISMATCH (1 << PD_RDO_CAP_MISMATCH_SHIFT)
|
||||||
|
#define PD_RDO_USB_COMMS_SHIFT 25
|
||||||
|
#define PD_RDO_USB_COMMS (1 << PD_RDO_USB_COMMS_SHIFT)
|
||||||
|
#define PD_RDO_NO_USB_SUSPEND_SHIFT 24
|
||||||
|
#define PD_RDO_NO_USB_SUSPEND (1 << PD_RDO_NO_USB_SUSPEND_SHIFT)
|
||||||
|
#define PD_RDO_UNCHUNKED_EXT_MSG_SHIFT 23
|
||||||
|
#define PD_RDO_UNCHUNKED_EXT_MSG (1 << PD_RDO_UNCHUNKED_EXT_MSG_SHIFT)
|
||||||
|
|
||||||
|
#define PD_RDO_OBJPOS_SET(i) (((i) << PD_RDO_OBJPOS_SHIFT) & PD_RDO_OBJPOS)
|
||||||
|
#define PD_RDO_OBJPOS_GET(msg) (((msg)->obj[0] & PD_RDO_OBJPOS) >> PD_RDO_OBJPOS_SHIFT)
|
||||||
|
|
||||||
|
/* Fixed and Variable RDO, no GiveBack support */
|
||||||
|
#define PD_RDO_FV_CURRENT_SHIFT 10
|
||||||
|
#define PD_RDO_FV_CURRENT (0x3FF << PD_RDO_FV_CURRENT_SHIFT)
|
||||||
|
#define PD_RDO_FV_MAX_CURRENT_SHIFT 0
|
||||||
|
#define PD_RDO_FV_MAX_CURRENT (0x3FF << PD_RDO_FV_MAX_CURRENT_SHIFT)
|
||||||
|
|
||||||
|
#define PD_RDO_FV_CURRENT_SET(i) (((i) << PD_RDO_FV_CURRENT_SHIFT) & PD_RDO_FV_CURRENT)
|
||||||
|
#define PD_RDO_FV_MAX_CURRENT_SET(i) (((i) << PD_RDO_FV_MAX_CURRENT_SHIFT) & PD_RDO_FV_MAX_CURRENT)
|
||||||
|
|
||||||
|
/* Fixed and Variable RDO with GiveBack support */
|
||||||
|
#define PD_RDO_FV_MIN_CURRENT_SHIFT 0
|
||||||
|
#define PD_RDO_FV_MIN_CURRENT (0x3FF << PD_RDO_FV_MIN_CURRENT_SHIFT)
|
||||||
|
|
||||||
|
#define PD_RDO_FV_MIN_CURRENT_SET(i) (((i) << PD_RDO_FV_MIN_CURRENT_SHIFT) & PD_RDO_FV_MIN_CURRENT)
|
||||||
|
|
||||||
|
/* TODO: Battery RDOs */
|
||||||
|
|
||||||
|
/* Programmable RDO */
|
||||||
|
#define PD_RDO_PROG_VOLTAGE_SHIFT 9
|
||||||
|
#define PD_RDO_PROG_VOLTAGE (0x7FF << PD_RDO_PROG_VOLTAGE_SHIFT)
|
||||||
|
#define PD_RDO_PROG_CURRENT_SHIFT 0
|
||||||
|
#define PD_RDO_PROG_CURRENT (0x7F << PD_RDO_PROG_CURRENT_SHIFT)
|
||||||
|
|
||||||
|
#define PD_RDO_PROG_VOLTAGE_SET(i) (((i) << PD_RDO_PROG_VOLTAGE_SHIFT) & PD_RDO_PROG_VOLTAGE)
|
||||||
|
#define PD_RDO_PROG_CURRENT_SET(i) (((i) << PD_RDO_PROG_CURRENT_SHIFT) & PD_RDO_PROG_CURRENT)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Time values
|
||||||
|
*
|
||||||
|
* Where a range is specified, the middle of the range (rounded down to the
|
||||||
|
* nearest millisecond) is used.
|
||||||
|
*/
|
||||||
|
#define PD_T_CHUNKING_NOT_SUPPORTED (450)
|
||||||
|
#define PD_T_HARD_RESET_COMPLETE (1000)
|
||||||
|
#define PD_T_PS_TRANSITION (5000)
|
||||||
|
#define PD_T_SENDER_RESPONSE (2700)
|
||||||
|
#define PD_T_SINK_REQUEST (1000)
|
||||||
|
#define PD_T_TYPEC_SINK_WAIT_CAP (1000)
|
||||||
|
#define PD_T_PD_DEBOUNCE (2000)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Counter maximums
|
||||||
|
*/
|
||||||
|
#define PD_N_HARD_RESET_COUNT 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Value parameters
|
||||||
|
*/
|
||||||
|
#define PD_MAX_EXT_MSG_LEN 260
|
||||||
|
#define PD_MAX_EXT_MSG_CHUNK_LEN 26
|
||||||
|
#define PD_MAX_EXT_MSG_LEGACY_LEN 26
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unit conversions
|
||||||
|
*
|
||||||
|
* V: volt
|
||||||
|
* CV: centivolt
|
||||||
|
* MV: millivolt
|
||||||
|
* PRV: Programmable RDO voltage unit (20 mV)
|
||||||
|
* PDV: Power Delivery voltage unit (50 mV)
|
||||||
|
* PAV: PPS APDO voltage unit (100 mV)
|
||||||
|
*
|
||||||
|
* A: ampere
|
||||||
|
* CA: centiampere
|
||||||
|
* MA: milliampere
|
||||||
|
* PDI: Power Delivery current unit (10 mA)
|
||||||
|
* PAI: PPS APDO current unit (50 mA)
|
||||||
|
*
|
||||||
|
* W: watt
|
||||||
|
* CW: centiwatt
|
||||||
|
* MW: milliwatt
|
||||||
|
*
|
||||||
|
* O: ohm
|
||||||
|
* CO: centiohm
|
||||||
|
* MO: milliohm
|
||||||
|
*/
|
||||||
|
#define PD_MV2PRV(mv) ((mv) / 20)
|
||||||
|
#define PD_MV2PDV(mv) ((mv) / 50)
|
||||||
|
#define PD_MV2PAV(mv) ((mv) / 100)
|
||||||
|
#define PD_PRV2MV(prv) ((prv) * 20)
|
||||||
|
#define PD_PDV2MV(pdv) ((pdv) * 50)
|
||||||
|
#define PD_PAV2MV(pav) ((pav) * 100)
|
||||||
|
|
||||||
|
#define PD_MA2CA(ma) (((ma) + 10 - 1) / 10)
|
||||||
|
#define PD_MA2PDI(ma) (((ma) + 10 - 1) / 10)
|
||||||
|
#define PD_MA2PAI(ma) (((ma) + 50 - 1) / 50)
|
||||||
|
#define PD_CA2PAI(ca) (((ca) + 5 - 1) / 5)
|
||||||
|
#define PD_PDI2MA(pdi) ((pdi) * 10)
|
||||||
|
#define PD_PAI2MA(pai) ((pai) * 50)
|
||||||
|
#define PD_PAI2CA(pai) ((pai) * 5)
|
||||||
|
|
||||||
|
#define PD_MW2CW(mw) ((mw) / 10)
|
||||||
|
|
||||||
|
#define PD_MO2CO(mo) ((mo) / 10)
|
||||||
|
|
||||||
|
/* Get portions of a voltage in more normal units */
|
||||||
|
#define PD_MV_V(mv) ((mv) / 1000)
|
||||||
|
#define PD_MV_MV(mv) ((mv) % 1000)
|
||||||
|
|
||||||
|
#define PD_PDV_V(pdv) ((pdv) / 20)
|
||||||
|
#define PD_PDV_CV(pdv) (5 * ((pdv) % 20))
|
||||||
|
|
||||||
|
#define PD_PAV_V(pav) ((pav) / 10)
|
||||||
|
#define PD_PAV_CV(pav) (10 * ((pav) % 10))
|
||||||
|
|
||||||
|
/* Get portions of a PD current in more normal units */
|
||||||
|
#define PD_PDI_A(pdi) ((pdi) / 100)
|
||||||
|
#define PD_PDI_CA(pdi) ((pdi) % 100)
|
||||||
|
|
||||||
|
#define PD_PAI_A(pai) ((pai) / 20)
|
||||||
|
#define PD_PAI_CA(pai) (5 * ((pai) % 20))
|
||||||
|
|
||||||
|
/* Get portions of a power in more normal units */
|
||||||
|
#define PD_CW_W(cw) ((cw) / 100)
|
||||||
|
#define PD_CW_CW(cw) ((cw) % 100)
|
||||||
|
|
||||||
|
/* Get portions of a resistance in more normal units */
|
||||||
|
#define PD_CO_O(co) ((co) / 100)
|
||||||
|
#define PD_CO_CO(co) ((co) % 100)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unit constants
|
||||||
|
*/
|
||||||
|
#define PD_MV_MIN 0
|
||||||
|
#define PD_MV_MAX 21000
|
||||||
|
#define PD_PDV_MIN PD_MV2PDV(PD_MV_MIN)
|
||||||
|
#define PD_PDV_MAX PD_MV2PDV(PD_MV_MAX)
|
||||||
|
|
||||||
|
#define PD_MA_MIN 0
|
||||||
|
#define PD_MA_MAX 5000
|
||||||
|
#define PD_CA_MIN PD_MA2CA(PD_MA_MIN)
|
||||||
|
#define PD_CA_MAX PD_MA2CA(PD_MA_MAX)
|
||||||
|
#define PD_PDI_MIN PD_MA2PDI(PD_MA_MIN)
|
||||||
|
#define PD_PDI_MAX PD_MA2PDI(PD_MA_MAX)
|
||||||
|
|
||||||
|
#define PD_MW_MIN 0
|
||||||
|
#define PD_MW_MAX 100000
|
||||||
|
|
||||||
|
#define PD_MO_MIN 500
|
||||||
|
#define PD_MO_MAX 655350
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FUSB Type-C Current level enum
|
||||||
|
*/
|
||||||
|
enum fusb_typec_current {
|
||||||
|
fusb_tcc_none = 0,
|
||||||
|
fusb_tcc_default = 1,
|
||||||
|
fusb_tcc_1_5 = 2,
|
||||||
|
fusb_sink_tx_ng = 2,
|
||||||
|
fusb_tcc_3_0 = 3,
|
||||||
|
fusb_sink_tx_ok = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PDB_PD_H */
|
||||||
32
workspace/TS100/Core/Drivers/FUSB302/pdb_conf.h
Normal file
32
workspace/TS100/Core/Drivers/FUSB302/pdb_conf.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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_CONF_H
|
||||||
|
#define PDB_CONF_H
|
||||||
|
|
||||||
|
|
||||||
|
/* Number of messages in the message pool */
|
||||||
|
#define PDB_MSG_POOL_SIZE 4
|
||||||
|
|
||||||
|
#define EVENT_MASK(x) (1<<x)
|
||||||
|
#define eventmask_t uint32_t
|
||||||
|
/* PD Buddy thread priorities */
|
||||||
|
#define PDB_PRIO_PE (osPriorityNormal)
|
||||||
|
#define PDB_PRIO_PRL (osPriorityBelowNormal)
|
||||||
|
#define PDB_PRIO_PRL_INT_N (osPriorityLow)
|
||||||
|
|
||||||
|
#endif /* PDB_CONF_H */
|
||||||
55
workspace/TS100/Core/Drivers/FUSB302/pdb_msg.h
Normal file
55
workspace/TS100/Core/Drivers/FUSB302/pdb_msg.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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_MSG_H
|
||||||
|
#define PDB_MSG_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PD message union
|
||||||
|
*
|
||||||
|
* This can be safely read from or written to in any form without any
|
||||||
|
* transformations because everything in the system is little-endian.
|
||||||
|
*
|
||||||
|
* Two bytes of padding are required at the start to prevent problems due to
|
||||||
|
* alignment. Specifically, without the padding, &obj[0] != &bytes[2], making
|
||||||
|
* the statement in the previous paragraph invalid.
|
||||||
|
*/
|
||||||
|
union pd_msg {
|
||||||
|
struct {
|
||||||
|
uint8_t _pad1[2];
|
||||||
|
uint8_t bytes[30];
|
||||||
|
} __attribute__((packed));
|
||||||
|
struct {
|
||||||
|
uint8_t _pad2[2];
|
||||||
|
uint16_t hdr;
|
||||||
|
union {
|
||||||
|
uint32_t obj[7];
|
||||||
|
struct {
|
||||||
|
uint16_t exthdr;
|
||||||
|
uint8_t data[26];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} __attribute__((packed));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PDB_MSG_H */
|
||||||
699
workspace/TS100/Core/Drivers/FUSB302/policy_engine.cpp
Normal file
699
workspace/TS100/Core/Drivers/FUSB302/policy_engine.cpp
Normal file
@@ -0,0 +1,699 @@
|
|||||||
|
/*
|
||||||
|
* 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 "policy_engine.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "int_n.h"
|
||||||
|
#include <pd.h>
|
||||||
|
#include "protocol_tx.h"
|
||||||
|
#include "hard_reset.h"
|
||||||
|
#include "fusb302b.h"
|
||||||
|
bool PolicyEngine::pdNegotiationComplete;
|
||||||
|
int PolicyEngine::current_voltage_mv;
|
||||||
|
int PolicyEngine::_requested_voltage;
|
||||||
|
bool PolicyEngine::_unconstrained_power;
|
||||||
|
union pd_msg PolicyEngine::currentMessage;
|
||||||
|
uint16_t PolicyEngine::hdr_template;
|
||||||
|
bool PolicyEngine::_explicit_contract;
|
||||||
|
int8_t PolicyEngine::_hard_reset_counter;
|
||||||
|
int8_t PolicyEngine::_old_tcc_match;
|
||||||
|
uint8_t PolicyEngine::_pps_index;
|
||||||
|
uint8_t PolicyEngine::_last_pps;
|
||||||
|
osThreadId PolicyEngine::TaskHandle = NULL;
|
||||||
|
uint32_t PolicyEngine::TaskBuffer[PolicyEngine::TaskStackSize];
|
||||||
|
osStaticThreadDef_t PolicyEngine::TaskControlBlock;
|
||||||
|
union pd_msg PolicyEngine::tempMessage;
|
||||||
|
union pd_msg PolicyEngine::_last_dpm_request;
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::state = PESinkStartup;
|
||||||
|
StaticQueue_t PolicyEngine::xStaticQueue;
|
||||||
|
uint8_t PolicyEngine::ucQueueStorageArea[PDB_MSG_POOL_SIZE
|
||||||
|
* sizeof(union pd_msg)];
|
||||||
|
QueueHandle_t PolicyEngine::messagesWaiting = NULL;
|
||||||
|
EventGroupHandle_t PolicyEngine::xEventGroupHandle = NULL;
|
||||||
|
StaticEventGroup_t PolicyEngine::xCreatedEventGroup;
|
||||||
|
void PolicyEngine::init() {
|
||||||
|
messagesWaiting = xQueueCreateStatic(PDB_MSG_POOL_SIZE,
|
||||||
|
sizeof(union pd_msg), ucQueueStorageArea, &xStaticQueue);
|
||||||
|
//Create static thread at PDB_PRIO_PE priority
|
||||||
|
osThreadStaticDef(PolEng, pe_task, PDB_PRIO_PE, 0, TaskStackSize,
|
||||||
|
TaskBuffer, &TaskControlBlock);
|
||||||
|
TaskHandle = osThreadCreate(osThread(PolEng), NULL);
|
||||||
|
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolicyEngine::notify(uint32_t notification) {
|
||||||
|
if (xEventGroupHandle != NULL) {
|
||||||
|
xEventGroupSetBits(xEventGroupHandle, notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolicyEngine::pe_task(const void *arg) {
|
||||||
|
(void) arg;
|
||||||
|
//Internal thread loop
|
||||||
|
hdr_template = PD_DATAROLE_UFP | PD_POWERROLE_SINK;
|
||||||
|
/* Initialize the old_tcc_match */
|
||||||
|
_old_tcc_match = -1;
|
||||||
|
/* Initialize the pps_index */
|
||||||
|
_pps_index = 8;
|
||||||
|
/* Initialize the last_pps */
|
||||||
|
_last_pps = 8;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
//Loop based on state
|
||||||
|
switch (state) {
|
||||||
|
|
||||||
|
case PESinkStartup:
|
||||||
|
state = pe_sink_startup();
|
||||||
|
break;
|
||||||
|
case PESinkDiscovery:
|
||||||
|
state = pe_sink_discovery();
|
||||||
|
break;
|
||||||
|
case PESinkWaitCap:
|
||||||
|
state = pe_sink_wait_cap();
|
||||||
|
break;
|
||||||
|
case PESinkEvalCap:
|
||||||
|
state = pe_sink_eval_cap();
|
||||||
|
break;
|
||||||
|
case PESinkSelectCap:
|
||||||
|
state = pe_sink_select_cap();
|
||||||
|
break;
|
||||||
|
case PESinkTransitionSink:
|
||||||
|
state = pe_sink_transition_sink();
|
||||||
|
break;
|
||||||
|
case PESinkReady:
|
||||||
|
state = pe_sink_ready();
|
||||||
|
break;
|
||||||
|
case PESinkGetSourceCap:
|
||||||
|
state = pe_sink_get_source_cap();
|
||||||
|
break;
|
||||||
|
case PESinkGiveSinkCap:
|
||||||
|
state = pe_sink_give_sink_cap();
|
||||||
|
break;
|
||||||
|
case PESinkHardReset:
|
||||||
|
state = pe_sink_hard_reset();
|
||||||
|
break;
|
||||||
|
case PESinkTransitionDefault:
|
||||||
|
state = pe_sink_transition_default();
|
||||||
|
break;
|
||||||
|
case PESinkSoftReset:
|
||||||
|
state = pe_sink_soft_reset();
|
||||||
|
break;
|
||||||
|
case PESinkSendSoftReset:
|
||||||
|
state = pe_sink_send_soft_reset();
|
||||||
|
break;
|
||||||
|
case PESinkSendNotSupported:
|
||||||
|
state = pe_sink_send_not_supported();
|
||||||
|
break;
|
||||||
|
case PESinkChunkReceived:
|
||||||
|
state = pe_sink_chunk_received();
|
||||||
|
break;
|
||||||
|
case PESinkSourceUnresponsive:
|
||||||
|
state = pe_sink_source_unresponsive();
|
||||||
|
break;
|
||||||
|
case PESinkNotSupportedReceived:
|
||||||
|
state = pe_sink_not_supported_received();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = PESinkStartup;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_startup() {
|
||||||
|
/* We don't have an explicit contract currently */
|
||||||
|
_explicit_contract = false;
|
||||||
|
|
||||||
|
//If desired could send an alert that PD is starting
|
||||||
|
|
||||||
|
/* No need to reset the protocol layer here. There are two ways into this
|
||||||
|
* state: startup and exiting hard reset. On startup, the protocol layer
|
||||||
|
* is reset by the startup procedure. When exiting hard reset, the
|
||||||
|
* protocol layer is reset by the hard reset state machine. Since it's
|
||||||
|
* already done somewhere else, there's no need to do it again here. */
|
||||||
|
|
||||||
|
return PESinkDiscovery;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_discovery() {
|
||||||
|
/* Wait for VBUS. Since it's our only power source, we already know that
|
||||||
|
* we have it, so just move on. */
|
||||||
|
|
||||||
|
return PESinkWaitCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_wait_cap() {
|
||||||
|
/* Fetch a message from the protocol layer */
|
||||||
|
eventmask_t evt = 0;
|
||||||
|
if (readMessage()) {
|
||||||
|
evt = PDB_EVT_PE_MSG_RX_PEND;
|
||||||
|
} else {
|
||||||
|
evt = waitForEvent(
|
||||||
|
PDB_EVT_PE_MSG_RX | PDB_EVT_PE_I_OVRTEMP | PDB_EVT_PE_RESET,
|
||||||
|
//Wait for cap timeout
|
||||||
|
PD_T_TYPEC_SINK_WAIT_CAP);
|
||||||
|
}
|
||||||
|
/* If we timed out waiting for Source_Capabilities, send a hard reset */
|
||||||
|
if (evt == 0) {
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkWaitCap;
|
||||||
|
}
|
||||||
|
/* If we're too hot, we shouldn't negotiate power yet */
|
||||||
|
if (evt & PDB_EVT_PE_I_OVRTEMP) {
|
||||||
|
return PESinkWaitCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got a message */
|
||||||
|
if (evt & (PDB_EVT_PE_MSG_RX | PDB_EVT_PE_MSG_RX_PEND)) {
|
||||||
|
/* Get the message */
|
||||||
|
while ((evt & PDB_EVT_PE_MSG_RX_PEND) || readMessage() == true) {
|
||||||
|
/* If we got a Source_Capabilities message, read it. */
|
||||||
|
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOURCE_CAPABILITIES
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) > 0) {
|
||||||
|
/* First, determine what PD revision we're using */
|
||||||
|
if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_1_0) {
|
||||||
|
// /* If the other end is using at least version 3.0, we'll
|
||||||
|
// * use version 3.0. */
|
||||||
|
// if ((tempMessage.hdr & PD_HDR_SPECREV) >= PD_SPECREV_3_0) {
|
||||||
|
// hdr_template |= PD_SPECREV_3_0;
|
||||||
|
// /* Otherwise, use 2.0. Don't worry about the 1.0 case
|
||||||
|
// * because we don't have hardware for PD 1.0 signaling. */
|
||||||
|
// } else {
|
||||||
|
hdr_template |= PD_SPECREV_2_0;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return PESinkEvalCap;
|
||||||
|
/* If the message was a Soft_Reset, do the soft reset procedure */
|
||||||
|
}
|
||||||
|
evt = 0;
|
||||||
|
}
|
||||||
|
return PESinkWaitCap; //wait for more messages?
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we failed to get a message, send a hard reset */
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_eval_cap() {
|
||||||
|
/* If we have a Source_Capabilities message, remember the index of the
|
||||||
|
* first PPS APDO so we can check if the request is for a PPS APDO in
|
||||||
|
* PE_SNK_Select_Cap. */
|
||||||
|
/* Start by assuming we won't find a PPS APDO (set the index greater
|
||||||
|
* than the maximum possible) */
|
||||||
|
_pps_index = 8;
|
||||||
|
/* Search for the first PPS APDO */
|
||||||
|
for (int8_t i = 0; i < PD_NUMOBJ_GET(&tempMessage); i++) {
|
||||||
|
if ((tempMessage.obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED
|
||||||
|
&& (tempMessage.obj[i] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS) {
|
||||||
|
_pps_index = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* New capabilities also means we can't be making a request from the
|
||||||
|
* same PPS APDO */
|
||||||
|
_last_pps = 8;
|
||||||
|
|
||||||
|
/* Ask the DPM what to request */
|
||||||
|
if (pdbs_dpm_evaluate_capability(&tempMessage, &_last_dpm_request)) {
|
||||||
|
|
||||||
|
return PESinkSelectCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PESinkWaitCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_select_cap() {
|
||||||
|
|
||||||
|
/* Transmit the request */
|
||||||
|
waitForEvent(0xFFFF, 0); //clear pending
|
||||||
|
ProtocolTransmit::pushMessage(&_last_dpm_request);
|
||||||
|
//Send indication that there is a message pending
|
||||||
|
ProtocolTransmit::notify(
|
||||||
|
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
||||||
|
eventmask_t evt = waitForEvent(
|
||||||
|
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET || evt == 0) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
/* If the message transmission failed, send a hard reset */
|
||||||
|
if ((evt & PDB_EVT_PE_TX_ERR) == PDB_EVT_PE_TX_ERR) {
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for a response */
|
||||||
|
evt = waitForEvent(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET,
|
||||||
|
PD_T_SENDER_RESPONSE);
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
/* If we didn't get a response before the timeout, send a hard reset */
|
||||||
|
if (evt == 0) {
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the response message */
|
||||||
|
if (messageWaiting()) {
|
||||||
|
readMessage();
|
||||||
|
/* If the source accepted our request, wait for the new power */
|
||||||
|
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_ACCEPT
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkTransitionSink;
|
||||||
|
/* If the message was a Soft_Reset, do the soft reset procedure */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
return PESinkSoftReset;
|
||||||
|
/* If the message was Wait or Reject */
|
||||||
|
} else if ((PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_REJECT
|
||||||
|
|| PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_WAIT)
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
/* If we don't have an explicit contract, wait for capabilities */
|
||||||
|
if (!_explicit_contract) {
|
||||||
|
return PESinkWaitCap;
|
||||||
|
/* If we do have an explicit contract, go to the ready state */
|
||||||
|
} else {
|
||||||
|
return PESinkReady;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return PESinkSendSoftReset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_transition_sink() {
|
||||||
|
/* Wait for the PS_RDY message */
|
||||||
|
eventmask_t evt = waitForEvent(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET,
|
||||||
|
PD_T_PS_TRANSITION);
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
/* If no message was received, send a hard reset */
|
||||||
|
if (evt == 0) {
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we received a message, read it */
|
||||||
|
if (messageWaiting()) {
|
||||||
|
readMessage();
|
||||||
|
/* If we got a PS_RDY, handle it */
|
||||||
|
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_PS_RDY
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
/* We just finished negotiating an explicit contract */
|
||||||
|
_explicit_contract = true;
|
||||||
|
|
||||||
|
/* Set the output appropriately */
|
||||||
|
pdbs_dpm_transition_requested();
|
||||||
|
|
||||||
|
return PESinkReady;
|
||||||
|
/* If there was a protocol error, send a hard reset */
|
||||||
|
} else {
|
||||||
|
/* Turn off the power output before this hard reset to make sure we
|
||||||
|
* don't supply an incorrect voltage to the device we're powering.
|
||||||
|
*/
|
||||||
|
pdbs_dpm_transition_default();
|
||||||
|
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_ready() {
|
||||||
|
eventmask_t evt;
|
||||||
|
|
||||||
|
/* Wait for an event */
|
||||||
|
evt = waitForEvent(
|
||||||
|
PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET | PDB_EVT_PE_I_OVRTEMP);
|
||||||
|
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we overheated, send a hard reset */
|
||||||
|
if (evt & PDB_EVT_PE_I_OVRTEMP) {
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we received a message */
|
||||||
|
if (evt & PDB_EVT_PE_MSG_RX) {
|
||||||
|
if (messageWaiting()) {
|
||||||
|
readMessage();
|
||||||
|
/* Ignore vendor-defined messages */
|
||||||
|
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_VENDOR_DEFINED
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) > 0) {
|
||||||
|
|
||||||
|
return PESinkReady;
|
||||||
|
/* Ignore Ping messages */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_PING
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkReady;
|
||||||
|
/* DR_Swap messages are not supported */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_DR_SWAP
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkSendNotSupported;
|
||||||
|
/* Get_Source_Cap messages are not supported */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_GET_SOURCE_CAP
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkSendNotSupported;
|
||||||
|
/* PR_Swap messages are not supported */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_PR_SWAP
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkSendNotSupported;
|
||||||
|
/* VCONN_Swap messages are not supported */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_VCONN_SWAP
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkSendNotSupported;
|
||||||
|
/* Request messages are not supported */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_REQUEST
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) > 0) {
|
||||||
|
|
||||||
|
return PESinkSendNotSupported;
|
||||||
|
/* Sink_Capabilities messages are not supported */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage)
|
||||||
|
== PD_MSGTYPE_SINK_CAPABILITIES
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) > 0) {
|
||||||
|
|
||||||
|
return PESinkSendNotSupported;
|
||||||
|
/* Handle GotoMin messages */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_GOTOMIN
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
/* GiveBack is not supported */
|
||||||
|
return PESinkSendNotSupported;
|
||||||
|
|
||||||
|
/* Evaluate new Source_Capabilities */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage)
|
||||||
|
== PD_MSGTYPE_SOURCE_CAPABILITIES
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) > 0) {
|
||||||
|
/* Don't free the message: we need to keep the
|
||||||
|
* Source_Capabilities message so we can evaluate it. */
|
||||||
|
return PESinkEvalCap;
|
||||||
|
/* Give sink capabilities when asked */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_GET_SINK_CAP
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkGiveSinkCap;
|
||||||
|
/* If the message was a Soft_Reset, do the soft reset procedure */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkSoftReset;
|
||||||
|
/* PD 3.0 messges */
|
||||||
|
} else if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) {
|
||||||
|
/* If the message is a multi-chunk extended message, let it
|
||||||
|
* time out. */
|
||||||
|
if ((tempMessage.hdr & PD_HDR_EXT)
|
||||||
|
&& (PD_DATA_SIZE_GET(&tempMessage)
|
||||||
|
> PD_MAX_EXT_MSG_LEGACY_LEN)) {
|
||||||
|
|
||||||
|
return PESinkChunkReceived;
|
||||||
|
/* Tell the DPM a message we sent got a response of
|
||||||
|
* Not_Supported. */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage)
|
||||||
|
== PD_MSGTYPE_NOT_SUPPORTED
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkNotSupportedReceived;
|
||||||
|
/* If we got an unknown message, send a soft reset */
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return PESinkSendSoftReset;
|
||||||
|
}
|
||||||
|
/* If we got an unknown message, send a soft reset ??? */
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return PESinkSendSoftReset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PESinkReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_get_source_cap() {
|
||||||
|
/* Get a message object */
|
||||||
|
union pd_msg *get_source_cap = &tempMessage;
|
||||||
|
/* Make a Get_Source_Cap message */
|
||||||
|
get_source_cap->hdr = hdr_template | PD_MSGTYPE_GET_SOURCE_CAP
|
||||||
|
| PD_NUMOBJ(0);
|
||||||
|
/* Transmit the Get_Source_Cap */
|
||||||
|
ProtocolTransmit::pushMessage(get_source_cap);
|
||||||
|
ProtocolTransmit::notify(
|
||||||
|
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
||||||
|
eventmask_t evt = waitForEvent(
|
||||||
|
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
|
||||||
|
/* Free the sent message */
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
/* If the message transmission failed, send a hard reset */
|
||||||
|
if ((evt & PDB_EVT_PE_TX_DONE) == 0) {
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PESinkReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_give_sink_cap() {
|
||||||
|
/* Get a message object */
|
||||||
|
union pd_msg *snk_cap = &tempMessage;
|
||||||
|
/* Get our capabilities from the DPM */
|
||||||
|
pdbs_dpm_get_sink_capability(snk_cap);
|
||||||
|
|
||||||
|
/* Transmit our capabilities */
|
||||||
|
ProtocolTransmit::pushMessage(snk_cap);
|
||||||
|
ProtocolTransmit::notify(
|
||||||
|
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
||||||
|
eventmask_t evt = waitForEvent(
|
||||||
|
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
|
||||||
|
|
||||||
|
/* Free the Sink_Capabilities message */
|
||||||
|
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
/* If the message transmission failed, send a hard reset */
|
||||||
|
if ((evt & PDB_EVT_PE_TX_DONE) == 0) {
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PESinkReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_hard_reset() {
|
||||||
|
/* If we've already sent the maximum number of hard resets, assume the
|
||||||
|
* source is unresponsive. */
|
||||||
|
if (_hard_reset_counter > PD_N_HARD_RESET_COUNT) {
|
||||||
|
return PESinkSourceUnresponsive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate a hard reset signal */
|
||||||
|
ResetHandler::notify(PDB_EVT_HARDRST_RESET);
|
||||||
|
waitForEvent(PDB_EVT_PE_HARD_SENT);
|
||||||
|
|
||||||
|
/* Increment HardResetCounter */
|
||||||
|
_hard_reset_counter++;
|
||||||
|
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_transition_default() {
|
||||||
|
_explicit_contract = false;
|
||||||
|
|
||||||
|
/* Tell the DPM to transition to default power */
|
||||||
|
pdbs_dpm_transition_default();
|
||||||
|
|
||||||
|
/* There is no local hardware to reset. */
|
||||||
|
/* Since we never change our data role from UFP, there is no reason to set
|
||||||
|
* it here. */
|
||||||
|
|
||||||
|
/* Tell the protocol layer we're done with the reset */
|
||||||
|
ResetHandler::notify( PDB_EVT_HARDRST_DONE);
|
||||||
|
|
||||||
|
return PESinkStartup;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_soft_reset() {
|
||||||
|
/* No need to explicitly reset the protocol layer here. It resets itself
|
||||||
|
* when a Soft_Reset message is received. */
|
||||||
|
|
||||||
|
/* Get a message object */
|
||||||
|
union pd_msg accept;
|
||||||
|
/* Make an Accept message */
|
||||||
|
accept.hdr = hdr_template | PD_MSGTYPE_ACCEPT | PD_NUMOBJ(0);
|
||||||
|
/* Transmit the Accept */
|
||||||
|
ProtocolTransmit::pushMessage(&accept);
|
||||||
|
ProtocolTransmit::notify(
|
||||||
|
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
||||||
|
eventmask_t evt = waitForEvent(
|
||||||
|
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
|
||||||
|
/* Free the sent message */
|
||||||
|
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
/* If the message transmission failed, send a hard reset */
|
||||||
|
if ((evt & PDB_EVT_PE_TX_DONE) == 0) {
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PESinkWaitCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_send_soft_reset() {
|
||||||
|
/* No need to explicitly reset the protocol layer here. It resets itself
|
||||||
|
* just before a Soft_Reset message is transmitted. */
|
||||||
|
|
||||||
|
/* Get a message object */
|
||||||
|
union pd_msg *softrst = &tempMessage;
|
||||||
|
/* Make a Soft_Reset message */
|
||||||
|
softrst->hdr = hdr_template | PD_MSGTYPE_SOFT_RESET | PD_NUMOBJ(0);
|
||||||
|
/* Transmit the soft reset */
|
||||||
|
ProtocolTransmit::pushMessage(softrst);
|
||||||
|
ProtocolTransmit::notify(
|
||||||
|
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
||||||
|
eventmask_t evt = waitForEvent(
|
||||||
|
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
/* If the message transmission failed, send a hard reset */
|
||||||
|
if ((evt & PDB_EVT_PE_TX_DONE) == 0) {
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for a response */
|
||||||
|
evt = waitForEvent(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET,
|
||||||
|
PD_T_SENDER_RESPONSE);
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
/* If we didn't get a response before the timeout, send a hard reset */
|
||||||
|
if (evt == 0) {
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the response message */
|
||||||
|
if (messageWaiting()) {
|
||||||
|
readMessage();
|
||||||
|
/* If the source accepted our soft reset, wait for capabilities. */
|
||||||
|
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_ACCEPT
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkWaitCap;
|
||||||
|
/* If the message was a Soft_Reset, do the soft reset procedure */
|
||||||
|
} else if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOFT_RESET
|
||||||
|
&& PD_NUMOBJ_GET(&tempMessage) == 0) {
|
||||||
|
|
||||||
|
return PESinkSoftReset;
|
||||||
|
/* Otherwise, send a hard reset */
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PESinkHardReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_send_not_supported() {
|
||||||
|
/* Get a message object */
|
||||||
|
union pd_msg *not_supported = &tempMessage;
|
||||||
|
|
||||||
|
if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_2_0) {
|
||||||
|
/* Make a Reject message */
|
||||||
|
not_supported->hdr = hdr_template | PD_MSGTYPE_REJECT | PD_NUMOBJ(0);
|
||||||
|
} else if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) {
|
||||||
|
/* Make a Not_Supported message */
|
||||||
|
not_supported->hdr = hdr_template | PD_MSGTYPE_NOT_SUPPORTED
|
||||||
|
| PD_NUMOBJ(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transmit the message */
|
||||||
|
ProtocolTransmit::pushMessage(not_supported);
|
||||||
|
ProtocolTransmit::notify(
|
||||||
|
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
||||||
|
eventmask_t evt = waitForEvent(
|
||||||
|
PDB_EVT_PE_TX_DONE | PDB_EVT_PE_TX_ERR | PDB_EVT_PE_RESET);
|
||||||
|
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
/* If the message transmission failed, send a soft reset */
|
||||||
|
if ((evt & PDB_EVT_PE_TX_DONE) == 0) {
|
||||||
|
return PESinkSendSoftReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PESinkReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_chunk_received() {
|
||||||
|
|
||||||
|
/* Wait for tChunkingNotSupported */
|
||||||
|
eventmask_t evt = waitForEvent(PDB_EVT_PE_RESET,
|
||||||
|
PD_T_CHUNKING_NOT_SUPPORTED);
|
||||||
|
/* If we got reset signaling, transition to default */
|
||||||
|
if (evt & PDB_EVT_PE_RESET) {
|
||||||
|
return PESinkTransitionDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PESinkSendNotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_not_supported_received() {
|
||||||
|
/* Inform the Device Policy Manager that we received a Not_Supported
|
||||||
|
* message. */
|
||||||
|
|
||||||
|
return PESinkReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_source_unresponsive() {
|
||||||
|
//Sit and chill, as PD is not working
|
||||||
|
osDelay(PD_T_PD_DEBOUNCE);
|
||||||
|
|
||||||
|
return PESinkSourceUnresponsive;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PolicyEngine::waitForEvent(uint32_t mask, uint32_t ticksToWait) {
|
||||||
|
return xEventGroupWaitBits(xEventGroupHandle, mask, mask, pdFALSE,
|
||||||
|
ticksToWait);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PolicyEngine::isPD3_0() {
|
||||||
|
return (hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0;
|
||||||
|
}
|
||||||
|
|
||||||
198
workspace/TS100/Core/Drivers/FUSB302/policy_engine.h
Normal file
198
workspace/TS100/Core/Drivers/FUSB302/policy_engine.h
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* 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_POLICY_ENGINE_H
|
||||||
|
#define PDB_POLICY_ENGINE_H
|
||||||
|
|
||||||
|
#include <pd.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Events for the Policy Engine thread, used internally + sent by user code
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PDB_EVT_PE_RESET EVENT_MASK(0)
|
||||||
|
#define PDB_EVT_PE_MSG_RX EVENT_MASK(1)
|
||||||
|
#define PDB_EVT_PE_TX_DONE EVENT_MASK(2)
|
||||||
|
#define PDB_EVT_PE_TX_ERR EVENT_MASK(3)
|
||||||
|
#define PDB_EVT_PE_HARD_SENT EVENT_MASK(4)
|
||||||
|
#define PDB_EVT_PE_I_OVRTEMP EVENT_MASK(5)
|
||||||
|
#define PDB_EVT_PE_MSG_RX_PEND EVENT_MASK(7) /* Never SEND THIS DIRECTLY*/
|
||||||
|
|
||||||
|
class PolicyEngine {
|
||||||
|
public:
|
||||||
|
//Sets up internal state and registers the thread
|
||||||
|
static void init();
|
||||||
|
//Push an incoming message to the Policy Engine
|
||||||
|
static void handleMessage(union pd_msg *msg);
|
||||||
|
//Send a notification
|
||||||
|
static void notify(uint32_t notification);
|
||||||
|
//Returns true if headers indicate PD3.0 compliant
|
||||||
|
static bool isPD3_0();
|
||||||
|
static bool setupCompleteOrTimedOut() {
|
||||||
|
if (pdNegotiationComplete)
|
||||||
|
return true;
|
||||||
|
if (state == policy_engine_state::PESinkSourceUnresponsive)
|
||||||
|
return true;
|
||||||
|
if (state == policy_engine_state::PESinkReady)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//Has pd negotiation completed
|
||||||
|
static bool pdHasNegotiated() {
|
||||||
|
return pdNegotiationComplete;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static bool pdNegotiationComplete;
|
||||||
|
static int current_voltage_mv; //The current voltage PD is expecting
|
||||||
|
static int _requested_voltage; //The voltage the unit wanted to requests
|
||||||
|
static bool _unconstrained_power; // If the source is unconstrained
|
||||||
|
//Current message being handled
|
||||||
|
static union pd_msg currentMessage;
|
||||||
|
/* PD message header template */
|
||||||
|
static uint16_t hdr_template;
|
||||||
|
/* Whether or not we have an explicit contract */
|
||||||
|
static bool _explicit_contract;
|
||||||
|
/* The number of hard resets we've sent */
|
||||||
|
static int8_t _hard_reset_counter;
|
||||||
|
/* The result of the last Type-C Current match comparison */
|
||||||
|
static int8_t _old_tcc_match;
|
||||||
|
/* The index of the first PPS APDO */
|
||||||
|
static uint8_t _pps_index;
|
||||||
|
/* The index of the just-requested PPS APDO */
|
||||||
|
static uint8_t _last_pps;
|
||||||
|
static void pe_task(const void *arg);
|
||||||
|
enum policy_engine_state {
|
||||||
|
PESinkStartup,
|
||||||
|
PESinkDiscovery,
|
||||||
|
PESinkWaitCap,
|
||||||
|
PESinkEvalCap,
|
||||||
|
PESinkSelectCap,
|
||||||
|
PESinkTransitionSink,
|
||||||
|
PESinkReady,
|
||||||
|
PESinkGetSourceCap,
|
||||||
|
PESinkGiveSinkCap,
|
||||||
|
PESinkHardReset,
|
||||||
|
PESinkTransitionDefault,
|
||||||
|
PESinkSoftReset,
|
||||||
|
PESinkSendSoftReset,
|
||||||
|
PESinkSendNotSupported,
|
||||||
|
PESinkChunkReceived,
|
||||||
|
PESinkNotSupportedReceived,
|
||||||
|
PESinkSourceUnresponsive
|
||||||
|
};
|
||||||
|
static enum policy_engine_state pe_sink_startup();
|
||||||
|
static enum policy_engine_state pe_sink_discovery();
|
||||||
|
static enum policy_engine_state pe_sink_wait_cap();
|
||||||
|
static enum policy_engine_state pe_sink_eval_cap();
|
||||||
|
static enum policy_engine_state pe_sink_select_cap();
|
||||||
|
static enum policy_engine_state pe_sink_transition_sink();
|
||||||
|
static enum policy_engine_state pe_sink_ready();
|
||||||
|
static enum policy_engine_state pe_sink_get_source_cap();
|
||||||
|
static enum policy_engine_state pe_sink_give_sink_cap();
|
||||||
|
static enum policy_engine_state pe_sink_hard_reset();
|
||||||
|
static enum policy_engine_state pe_sink_transition_default();
|
||||||
|
static enum policy_engine_state pe_sink_soft_reset();
|
||||||
|
static enum policy_engine_state pe_sink_send_soft_reset();
|
||||||
|
static enum policy_engine_state pe_sink_send_not_supported();
|
||||||
|
static enum policy_engine_state pe_sink_chunk_received();
|
||||||
|
static enum policy_engine_state pe_sink_not_supported_received();
|
||||||
|
static enum policy_engine_state pe_sink_source_unresponsive();
|
||||||
|
static EventGroupHandle_t xEventGroupHandle;
|
||||||
|
static StaticEventGroup_t xCreatedEventGroup;
|
||||||
|
static uint32_t waitForEvent(uint32_t mask, uint32_t ticksToWait =
|
||||||
|
portMAX_DELAY);
|
||||||
|
//Task resources
|
||||||
|
static osThreadId TaskHandle;
|
||||||
|
static const size_t TaskStackSize = 2048 / 4;
|
||||||
|
static uint32_t TaskBuffer[TaskStackSize];
|
||||||
|
static osStaticThreadDef_t TaskControlBlock;
|
||||||
|
static union pd_msg tempMessage;
|
||||||
|
static union pd_msg _last_dpm_request;
|
||||||
|
static policy_engine_state state;
|
||||||
|
//queue of up to PDB_MSG_POOL_SIZE messages to send
|
||||||
|
static StaticQueue_t xStaticQueue;
|
||||||
|
/* The array to use as the queue's storage area. This must be at least
|
||||||
|
uxQueueLength * uxItemSize bytes. */
|
||||||
|
static uint8_t ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)];
|
||||||
|
static QueueHandle_t messagesWaiting;
|
||||||
|
static bool messageWaiting();
|
||||||
|
//Read a pending message into the temp message
|
||||||
|
static bool readMessage();
|
||||||
|
|
||||||
|
// These callbacks are called to implement the logic for the iron to select the desired voltage
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a Request message based on the given Source_Capabilities message. If
|
||||||
|
* capabilities is NULL, the last non-null Source_Capabilities message passes
|
||||||
|
* is used. If none has been provided, the behavior is undefined.
|
||||||
|
*
|
||||||
|
* Returns true if sufficient power is available, false otherwise.
|
||||||
|
*/
|
||||||
|
static bool pdbs_dpm_evaluate_capability(const union pd_msg *capabilities,
|
||||||
|
union pd_msg *request);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a Sink_Capabilities message for our current capabilities.
|
||||||
|
*/
|
||||||
|
static void pdbs_dpm_get_sink_capability(union pd_msg *cap);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return whether or not GiveBack support is enabled.
|
||||||
|
*/
|
||||||
|
static bool pdbs_dpm_giveback_enabled();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluate whether or not the currently offered Type-C Current can fulfill our
|
||||||
|
* power needs.
|
||||||
|
*
|
||||||
|
* Returns true if sufficient power is available, false otherwise.
|
||||||
|
*/
|
||||||
|
static bool pdbs_dpm_evaluate_typec_current(enum fusb_typec_current tcc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Indicate that power negotiations are starting.
|
||||||
|
*/
|
||||||
|
static void pdbs_dpm_pd_start();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transition the sink to default power.
|
||||||
|
*/
|
||||||
|
static void pdbs_dpm_transition_default();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transition to the requested minimum current.
|
||||||
|
*/
|
||||||
|
static void pdbs_dpm_transition_min();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transition to Sink Standby if necessary.
|
||||||
|
*/
|
||||||
|
static void pdbs_dpm_transition_standby();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transition to the requested power level
|
||||||
|
*/
|
||||||
|
static void pdbs_dpm_transition_requested();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transition to the Type-C Current power level
|
||||||
|
*/
|
||||||
|
static void pdbs_dpm_transition_typec();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PDB_POLICY_ENGINE_H */
|
||||||
227
workspace/TS100/Core/Drivers/FUSB302/policy_engine_user.cpp
Normal file
227
workspace/TS100/Core/Drivers/FUSB302/policy_engine_user.cpp
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
/*
|
||||||
|
* policy_engine_user.cpp
|
||||||
|
*
|
||||||
|
* Created on: 14 Jun 2020
|
||||||
|
* Author: Ralim
|
||||||
|
*/
|
||||||
|
#include "pd.h"
|
||||||
|
#include "policy_engine.h"
|
||||||
|
#include "BSP_PD.h"
|
||||||
|
/* The current draw when the output is disabled */
|
||||||
|
#define DPM_MIN_CURRENT PD_MA2PDI(50)
|
||||||
|
/*
|
||||||
|
* Find the index of the first PDO from capabilities in the voltage range,
|
||||||
|
* using the desired order.
|
||||||
|
*
|
||||||
|
* If there is no such PDO, returns -1 instead.
|
||||||
|
*/
|
||||||
|
static int8_t dpm_get_range_fixed_pdo_index(const union pd_msg *caps) {
|
||||||
|
/* Get the number of PDOs */
|
||||||
|
uint8_t numobj = PD_NUMOBJ_GET(caps);
|
||||||
|
|
||||||
|
/* Get ready to iterate over the PDOs */
|
||||||
|
int8_t i;
|
||||||
|
int8_t step;
|
||||||
|
i = numobj - 1;
|
||||||
|
step = -1;
|
||||||
|
uint16_t current = 100; // in centiamps
|
||||||
|
uint16_t voltagemin = 8000;
|
||||||
|
uint16_t voltagemax = 10000;
|
||||||
|
/* Look at the PDOs to see if one falls in our voltage range. */
|
||||||
|
while (0 <= i && i < numobj) {
|
||||||
|
/* If we have a fixed PDO, its V is within our range, and its I is at
|
||||||
|
* least our desired I */
|
||||||
|
uint16_t v = PD_PDO_SRC_FIXED_VOLTAGE_GET(caps->obj[i]);
|
||||||
|
if ((caps->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
|
||||||
|
if ( PD_PDO_SRC_FIXED_CURRENT_GET(caps->obj[i]) >= current) {
|
||||||
|
if (v >= PD_MV2PDV(voltagemin) && v <= PD_MV2PDV(voltagemax)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += step;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bool PolicyEngine::pdbs_dpm_evaluate_capability(
|
||||||
|
const union pd_msg *capabilities, union pd_msg *request) {
|
||||||
|
|
||||||
|
/* Get the number of PDOs */
|
||||||
|
uint8_t numobj = PD_NUMOBJ_GET(capabilities);
|
||||||
|
|
||||||
|
/* Get whether or not the power supply is constrained */
|
||||||
|
_unconstrained_power =
|
||||||
|
capabilities->obj[0] & PD_PDO_SRC_FIXED_UNCONSTRAINED;
|
||||||
|
|
||||||
|
/* Make sure we have configuration */
|
||||||
|
/* Look at the PDOs to see if one matches our desires */
|
||||||
|
//Look against USB_PD_Desired_Levels to select in order of preference
|
||||||
|
for (uint8_t desiredLevel = 0; desiredLevel < USB_PD_Desired_Levels_Len;
|
||||||
|
desiredLevel++) {
|
||||||
|
for (uint8_t i = 0; i < numobj; i++) {
|
||||||
|
/* If we have a fixed PDO, its V equals our desired V, and its I is
|
||||||
|
* at least our desired I */
|
||||||
|
if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
|
||||||
|
//This is a fixed PDO entry
|
||||||
|
int voltage = PD_PDV2MV(
|
||||||
|
PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities->obj[i]));
|
||||||
|
int current = PD_PDO_SRC_FIXED_CURRENT_GET(
|
||||||
|
capabilities->obj[i]);
|
||||||
|
uint16_t desiredVoltage = USB_PD_Desired_Levels[(desiredLevel
|
||||||
|
* 2) + 0];
|
||||||
|
uint16_t desiredminCurrent = USB_PD_Desired_Levels[(desiredLevel
|
||||||
|
* 2) + 1];
|
||||||
|
//As pd stores current in 10mA increments, divide by 10
|
||||||
|
desiredminCurrent /= 10;
|
||||||
|
if (voltage == desiredVoltage) {
|
||||||
|
if (current >= desiredminCurrent) {
|
||||||
|
/* We got what we wanted, so build a request for that */
|
||||||
|
request->hdr = hdr_template | PD_MSGTYPE_REQUEST
|
||||||
|
| PD_NUMOBJ(1);
|
||||||
|
|
||||||
|
/* GiveBack disabled */
|
||||||
|
request->obj[0] =
|
||||||
|
PD_RDO_FV_MAX_CURRENT_SET(
|
||||||
|
current) | PD_RDO_FV_CURRENT_SET(current)
|
||||||
|
| PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(i + 1);
|
||||||
|
//We support usb comms (ish)
|
||||||
|
request->obj[0] |= PD_RDO_USB_COMMS;
|
||||||
|
|
||||||
|
/* Update requested voltage */
|
||||||
|
_requested_voltage = voltage;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nothing matched (or no configuration), so get 5 V at low current */
|
||||||
|
request->hdr = hdr_template | PD_MSGTYPE_REQUEST | PD_NUMOBJ(1);
|
||||||
|
request->obj[0] =
|
||||||
|
PD_RDO_FV_MAX_CURRENT_SET(
|
||||||
|
DPM_MIN_CURRENT) | PD_RDO_FV_CURRENT_SET(DPM_MIN_CURRENT) | PD_RDO_NO_USB_SUSPEND
|
||||||
|
| PD_RDO_OBJPOS_SET(1);
|
||||||
|
/* If the output is enabled and we got here, it must be a capability
|
||||||
|
* mismatch. */
|
||||||
|
if (pdNegotiationComplete) {
|
||||||
|
request->obj[0] |= PD_RDO_CAP_MISMATCH;
|
||||||
|
}
|
||||||
|
request->obj[0] |= PD_RDO_USB_COMMS;
|
||||||
|
|
||||||
|
/* Update requested voltage */
|
||||||
|
_requested_voltage = 5000;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolicyEngine::pdbs_dpm_get_sink_capability(union pd_msg *cap) {
|
||||||
|
/* Keep track of how many PDOs we've added */
|
||||||
|
int numobj = 0;
|
||||||
|
|
||||||
|
/* If we have no configuration or want something other than 5 V, add a PDO
|
||||||
|
* for vSafe5V */
|
||||||
|
/* Minimum current, 5 V, and higher capability. */
|
||||||
|
cap->obj[numobj++] =
|
||||||
|
PD_PDO_TYPE_FIXED
|
||||||
|
| PD_PDO_SNK_FIXED_VOLTAGE_SET(
|
||||||
|
PD_MV2PDV(5000)) | PD_PDO_SNK_FIXED_CURRENT_SET(DPM_MIN_CURRENT);
|
||||||
|
|
||||||
|
/* Get the current we want */
|
||||||
|
uint16_t current = USB_PD_Desired_Levels[1] / 10; // In centi-amps
|
||||||
|
uint16_t voltage = USB_PD_Desired_Levels[0]; // in mv
|
||||||
|
/* Add a PDO for the desired power. */
|
||||||
|
cap->obj[numobj++] = PD_PDO_TYPE_FIXED
|
||||||
|
| PD_PDO_SNK_FIXED_VOLTAGE_SET(
|
||||||
|
PD_MV2PDV(voltage)) | PD_PDO_SNK_FIXED_CURRENT_SET(current);
|
||||||
|
|
||||||
|
/* Get the PDO from the voltage range */
|
||||||
|
int8_t i = dpm_get_range_fixed_pdo_index(cap);
|
||||||
|
|
||||||
|
/* If it's vSafe5V, set our vSafe5V's current to what we want */
|
||||||
|
if (i == 0) {
|
||||||
|
cap->obj[0] &= ~PD_PDO_SNK_FIXED_CURRENT;
|
||||||
|
cap->obj[0] |= PD_PDO_SNK_FIXED_CURRENT_SET(current);
|
||||||
|
} else {
|
||||||
|
/* If we want more than 5 V, set the Higher Capability flag */
|
||||||
|
if (PD_MV2PDV(voltage) != PD_MV2PDV(5000)) {
|
||||||
|
cap->obj[0] |= PD_PDO_SNK_FIXED_HIGHER_CAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the range PDO is a different voltage than the preferred
|
||||||
|
* voltage, add it to the array. */
|
||||||
|
if (i
|
||||||
|
> 0&& PD_PDO_SRC_FIXED_VOLTAGE_GET(cap->obj[i]) != PD_MV2PDV(voltage)) {
|
||||||
|
cap->obj[numobj++] =
|
||||||
|
PD_PDO_TYPE_FIXED
|
||||||
|
| PD_PDO_SNK_FIXED_VOLTAGE_SET(
|
||||||
|
PD_PDO_SRC_FIXED_VOLTAGE_GET(cap->obj[i])) | PD_PDO_SNK_FIXED_CURRENT_SET(
|
||||||
|
PD_PDO_SRC_FIXED_CURRENT_GET(cap->obj[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have three PDOs at this point, make sure the last two are
|
||||||
|
* sorted by voltage. */
|
||||||
|
if (numobj == 3
|
||||||
|
&& (cap->obj[1] & PD_PDO_SNK_FIXED_VOLTAGE)
|
||||||
|
> (cap->obj[2] & PD_PDO_SNK_FIXED_VOLTAGE)) {
|
||||||
|
cap->obj[1] ^= cap->obj[2];
|
||||||
|
cap->obj[2] ^= cap->obj[1];
|
||||||
|
cap->obj[1] ^= cap->obj[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the unconstrained power flag. */
|
||||||
|
if (_unconstrained_power) {
|
||||||
|
cap->obj[0] |= PD_PDO_SNK_FIXED_UNCONSTRAINED;
|
||||||
|
}
|
||||||
|
/* Set the USB communications capable flag. */
|
||||||
|
cap->obj[0] |= PD_PDO_SNK_FIXED_USB_COMMS;
|
||||||
|
|
||||||
|
/* Set the Sink_Capabilities message header */
|
||||||
|
cap->hdr = hdr_template | PD_MSGTYPE_SINK_CAPABILITIES | PD_NUMOBJ(numobj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PolicyEngine::pdbs_dpm_evaluate_typec_current(
|
||||||
|
enum fusb_typec_current tcc) {
|
||||||
|
(void) tcc;
|
||||||
|
//This is for evaluating 5V static current advertised by resistors
|
||||||
|
/* We don't control the voltage anymore; it will always be 5 V. */
|
||||||
|
current_voltage_mv = _requested_voltage = 5000;
|
||||||
|
//For the soldering iron we accept this as a fallback, but it sucks
|
||||||
|
pdNegotiationComplete = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolicyEngine::pdbs_dpm_transition_default() {
|
||||||
|
/* Cast the dpm_data to the right type */
|
||||||
|
|
||||||
|
/* Pretend we requested 5 V */
|
||||||
|
current_voltage_mv = 5000;
|
||||||
|
/* Turn the output off */
|
||||||
|
pdNegotiationComplete = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolicyEngine::pdbs_dpm_transition_requested() {
|
||||||
|
/* Cast the dpm_data to the right type */
|
||||||
|
pdNegotiationComplete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolicyEngine::handleMessage(union pd_msg *msg) {
|
||||||
|
xQueueSend(messagesWaiting, msg, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PolicyEngine::messageWaiting() {
|
||||||
|
return uxQueueMessagesWaiting(messagesWaiting) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PolicyEngine::readMessage() {
|
||||||
|
return xQueueReceive(messagesWaiting, &tempMessage, 0) == pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolicyEngine::pdbs_dpm_transition_typec() {
|
||||||
|
//This means PD failed, so we either have a dump 5V only type C or a QC charger
|
||||||
|
//For now; treat this as failed neg
|
||||||
|
pdNegotiationComplete = false;
|
||||||
|
}
|
||||||
189
workspace/TS100/Core/Drivers/FUSB302/protocol_rx.cpp
Normal file
189
workspace/TS100/Core/Drivers/FUSB302/protocol_rx.cpp
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* 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 "protocol_rx.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "string.h"
|
||||||
|
#include <pd.h>
|
||||||
|
#include "policy_engine.h"
|
||||||
|
#include "protocol_tx.h"
|
||||||
|
#include "fusb302b.h"
|
||||||
|
osThreadId ProtocolReceive::TaskHandle = NULL;
|
||||||
|
EventGroupHandle_t ProtocolReceive::xEventGroupHandle = NULL;
|
||||||
|
StaticEventGroup_t ProtocolReceive::xCreatedEventGroup;
|
||||||
|
uint32_t ProtocolReceive::TaskBuffer[ProtocolReceive::TaskStackSize];
|
||||||
|
osStaticThreadDef_t ProtocolReceive::TaskControlBlock;
|
||||||
|
union pd_msg ProtocolReceive::tempMessage;
|
||||||
|
uint8_t ProtocolReceive::_rx_messageid;
|
||||||
|
uint8_t ProtocolReceive::_tx_messageidcounter;
|
||||||
|
/*
|
||||||
|
* PRL_Rx_Wait_for_PHY_Message state
|
||||||
|
*/
|
||||||
|
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_wait_phy() {
|
||||||
|
/* Wait for an event */
|
||||||
|
_rx_messageid = 0;
|
||||||
|
eventmask_t evt = waitForEvent(
|
||||||
|
PDB_EVT_PRLRX_RESET | PDB_EVT_PRLRX_I_GCRCSENT | PDB_EVT_PRLRX_I_RXPEND);
|
||||||
|
|
||||||
|
/* If we got a reset event, reset */
|
||||||
|
if (evt & PDB_EVT_PRLRX_RESET) {
|
||||||
|
waitForEvent(PDB_EVT_PRLRX_RESET, 0);
|
||||||
|
return PRLRxWaitPHY;
|
||||||
|
}
|
||||||
|
/* If we got an I_GCRCSENT event, read the message and decide what to do */
|
||||||
|
if (evt & PDB_EVT_PRLRX_I_GCRCSENT) {
|
||||||
|
/* Get a buffer to read the message into. Guaranteed to not fail
|
||||||
|
* because we have a big enough pool and are careful. */
|
||||||
|
union pd_msg *_rx_message = &tempMessage;
|
||||||
|
memset(&tempMessage, 0, sizeof(tempMessage));
|
||||||
|
/* Read the message */
|
||||||
|
fusb_read_message(_rx_message);
|
||||||
|
/* If it's a Soft_Reset, go to the soft reset state */
|
||||||
|
if (PD_MSGTYPE_GET(_rx_message) == PD_MSGTYPE_SOFT_RESET
|
||||||
|
&& PD_NUMOBJ_GET(_rx_message) == 0) {
|
||||||
|
return PRLRxReset;
|
||||||
|
} else {
|
||||||
|
/* Otherwise, check the message ID */
|
||||||
|
return PRLRxCheckMessageID;
|
||||||
|
}
|
||||||
|
} else if (evt & PDB_EVT_PRLRX_I_RXPEND) {
|
||||||
|
//There is an RX message pending that is not a Good CRC
|
||||||
|
union pd_msg *_rx_message = &tempMessage;
|
||||||
|
/* Read the message */
|
||||||
|
fusb_read_message(_rx_message);
|
||||||
|
return PRLRxWaitPHY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PRLRxWaitPHY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PRL_Rx_Layer_Reset_for_Receive state
|
||||||
|
*/
|
||||||
|
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_reset() {
|
||||||
|
/* Reset MessageIDCounter */
|
||||||
|
_tx_messageidcounter = 0;
|
||||||
|
|
||||||
|
/* Clear stored MessageID */
|
||||||
|
_rx_messageid = -1;
|
||||||
|
|
||||||
|
/* TX transitions to its reset state */
|
||||||
|
ProtocolTransmit::notify(
|
||||||
|
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_RESET);
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
/* If we got a RESET signal, reset the machine */
|
||||||
|
if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) != 0) {
|
||||||
|
return PRLRxWaitPHY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go to the Check_MessageID state */
|
||||||
|
return PRLRxCheckMessageID;
|
||||||
|
}
|
||||||
|
volatile uint32_t rxCounter = 0;
|
||||||
|
/*
|
||||||
|
* PRL_Rx_Check_MessageID state
|
||||||
|
*/
|
||||||
|
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_check_messageid() {
|
||||||
|
/* If we got a RESET signal, reset the machine */
|
||||||
|
// if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) == PDB_EVT_PRLRX_RESET) {
|
||||||
|
// return PRLRxWaitPHY;
|
||||||
|
// }
|
||||||
|
/* If the message has the stored ID, we've seen this message before. Free
|
||||||
|
* it and don't pass it to the policy engine. */
|
||||||
|
|
||||||
|
/* Otherwise, there's either no stored ID or this message has an ID we
|
||||||
|
* haven't just seen. Transition to the Store_MessageID state. */
|
||||||
|
// if (PD_MESSAGEID_GET(&tempMessage) == _rx_messageid) {
|
||||||
|
// return PRLRxWaitPHY;
|
||||||
|
// } else
|
||||||
|
{
|
||||||
|
rxCounter++;
|
||||||
|
return PRLRxStoreMessageID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PRL_Rx_Store_MessageID state
|
||||||
|
*/
|
||||||
|
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_store_messageid() {
|
||||||
|
/* Tell ProtocolTX to discard the message being transmitted */
|
||||||
|
|
||||||
|
ProtocolTransmit::notify(
|
||||||
|
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_DISCARD);
|
||||||
|
|
||||||
|
/* Update the stored MessageID */
|
||||||
|
_rx_messageid = PD_MESSAGEID_GET(&tempMessage);
|
||||||
|
|
||||||
|
/* Pass the message to the policy engine. */
|
||||||
|
|
||||||
|
PolicyEngine::handleMessage(&tempMessage);
|
||||||
|
PolicyEngine::notify(PDB_EVT_PE_MSG_RX);
|
||||||
|
taskYIELD();
|
||||||
|
/* Don't check if we got a RESET because we'd do nothing different. */
|
||||||
|
|
||||||
|
return PRLRxWaitPHY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolReceive::init() {
|
||||||
|
osThreadStaticDef(protRX, thread, PDB_PRIO_PRL, 0, TaskStackSize,
|
||||||
|
TaskBuffer, &TaskControlBlock);
|
||||||
|
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
|
||||||
|
TaskHandle = osThreadCreate(osThread(protRX), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolReceive::thread(const void *args) {
|
||||||
|
(void) args;
|
||||||
|
ProtocolReceive::protocol_rx_state state = PRLRxWaitPHY;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
switch (state) {
|
||||||
|
case PRLRxWaitPHY:
|
||||||
|
state = protocol_rx_wait_phy();
|
||||||
|
break;
|
||||||
|
case PRLRxReset:
|
||||||
|
state = protocol_rx_reset();
|
||||||
|
break;
|
||||||
|
case PRLRxCheckMessageID:
|
||||||
|
state = protocol_rx_check_messageid();
|
||||||
|
break;
|
||||||
|
case PRLRxStoreMessageID:
|
||||||
|
state = protocol_rx_store_messageid();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* This is an error. It really shouldn't happen. We might
|
||||||
|
* want to handle it anyway, though. */
|
||||||
|
state = PRLRxWaitPHY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolReceive::notify(uint32_t notification) {
|
||||||
|
if (xEventGroupHandle != NULL) {
|
||||||
|
xEventGroupSetBits(xEventGroupHandle, notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ProtocolReceive::waitForEvent(uint32_t mask, uint32_t ticksToWait) {
|
||||||
|
if (xEventGroupHandle != NULL) {
|
||||||
|
return xEventGroupWaitBits(xEventGroupHandle, mask, mask,
|
||||||
|
pdFALSE, ticksToWait);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
64
workspace/TS100/Core/Drivers/FUSB302/protocol_rx.h
Normal file
64
workspace/TS100/Core/Drivers/FUSB302/protocol_rx.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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_PROTOCOL_RX_H
|
||||||
|
#define PDB_PROTOCOL_RX_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <pd.h>
|
||||||
|
|
||||||
|
/* Events for the Protocol RX thread */
|
||||||
|
#define PDB_EVT_PRLRX_RESET EVENT_MASK(0)
|
||||||
|
#define PDB_EVT_PRLRX_I_GCRCSENT EVENT_MASK(1)
|
||||||
|
#define PDB_EVT_PRLRX_I_RXPEND EVENT_MASK(2)
|
||||||
|
|
||||||
|
class ProtocolReceive {
|
||||||
|
public:
|
||||||
|
static void init();
|
||||||
|
static void notify(uint32_t notification);
|
||||||
|
private:
|
||||||
|
static void thread(const void *args);
|
||||||
|
|
||||||
|
static EventGroupHandle_t xEventGroupHandle;
|
||||||
|
static StaticEventGroup_t xCreatedEventGroup;
|
||||||
|
static osThreadId TaskHandle;
|
||||||
|
static const size_t TaskStackSize = 1024 / 4;
|
||||||
|
static uint32_t TaskBuffer[TaskStackSize];
|
||||||
|
static osStaticThreadDef_t TaskControlBlock;
|
||||||
|
/*
|
||||||
|
* Protocol RX machine states
|
||||||
|
*
|
||||||
|
* There is no Send_GoodCRC state because the PHY sends the GoodCRC for us.
|
||||||
|
* All transitions that would go to that state instead go to Check_MessageID.
|
||||||
|
*/
|
||||||
|
enum protocol_rx_state {
|
||||||
|
PRLRxWaitPHY, PRLRxReset, PRLRxCheckMessageID, PRLRxStoreMessageID
|
||||||
|
};
|
||||||
|
static protocol_rx_state protocol_rx_store_messageid();
|
||||||
|
static protocol_rx_state protocol_rx_check_messageid();
|
||||||
|
static protocol_rx_state protocol_rx_reset();
|
||||||
|
static protocol_rx_state protocol_rx_wait_phy();
|
||||||
|
static union pd_msg tempMessage;
|
||||||
|
static uint8_t _rx_messageid;
|
||||||
|
static uint8_t _tx_messageidcounter;
|
||||||
|
static uint32_t waitForEvent(uint32_t mask, uint32_t ticksToWait =
|
||||||
|
portMAX_DELAY);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PDB_PROTOCOL_RX_H */
|
||||||
298
workspace/TS100/Core/Drivers/FUSB302/protocol_tx.cpp
Normal file
298
workspace/TS100/Core/Drivers/FUSB302/protocol_tx.cpp
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
/*
|
||||||
|
* 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 "protocol_tx.h"
|
||||||
|
#include <pd.h>
|
||||||
|
#include "policy_engine.h"
|
||||||
|
#include "protocol_rx.h"
|
||||||
|
#include "fusb302b.h"
|
||||||
|
#include "fusbpd.h"
|
||||||
|
|
||||||
|
osThreadId ProtocolTransmit::TaskHandle = NULL;
|
||||||
|
uint32_t ProtocolTransmit::TaskBuffer[ProtocolTransmit::TaskStackSize];
|
||||||
|
osStaticThreadDef_t ProtocolTransmit::TaskControlBlock;
|
||||||
|
StaticQueue_t ProtocolTransmit::xStaticQueue;
|
||||||
|
bool ProtocolTransmit::messageSending = false;
|
||||||
|
uint8_t ProtocolTransmit::ucQueueStorageArea[PDB_MSG_POOL_SIZE
|
||||||
|
* sizeof(union pd_msg)];
|
||||||
|
QueueHandle_t ProtocolTransmit::messagesWaiting = NULL;
|
||||||
|
uint8_t ProtocolTransmit::_tx_messageidcounter;
|
||||||
|
union pd_msg ProtocolTransmit::temp_msg;
|
||||||
|
EventGroupHandle_t ProtocolTransmit::xEventGroupHandle = NULL;
|
||||||
|
StaticEventGroup_t ProtocolTransmit::xCreatedEventGroup;
|
||||||
|
/*
|
||||||
|
* PRL_Tx_PHY_Layer_Reset state
|
||||||
|
*/
|
||||||
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_phy_reset() {
|
||||||
|
/* Reset the PHY */
|
||||||
|
fusb_reset();
|
||||||
|
|
||||||
|
/* If a message was pending when we got here, tell the policy engine that
|
||||||
|
* we failed to send it */
|
||||||
|
if (messagePending()) {
|
||||||
|
/* Tell the policy engine that we failed */
|
||||||
|
PolicyEngine::notify( PDB_EVT_PE_TX_ERR);
|
||||||
|
/* Finish failing to send the message */
|
||||||
|
while (messagePending()) {
|
||||||
|
getMessage(); //Discard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for a message request */
|
||||||
|
return PRLTxWaitMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PRL_Tx_Wait_for_Message_Request state
|
||||||
|
*/
|
||||||
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_message() {
|
||||||
|
/* Wait for an event */
|
||||||
|
ProtocolTransmit::Notifications evt = waitForEvent(
|
||||||
|
(uint32_t) Notifications::PDB_EVT_PRLTX_RESET
|
||||||
|
| (uint32_t) Notifications::PDB_EVT_PRLTX_DISCARD
|
||||||
|
| (uint32_t) Notifications::PDB_EVT_PRLTX_MSG_TX);
|
||||||
|
|
||||||
|
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_RESET) {
|
||||||
|
return PRLTxPHYReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the policy engine is trying to send a message */
|
||||||
|
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_MSG_TX) {
|
||||||
|
/* Get the message */
|
||||||
|
getMessage();
|
||||||
|
|
||||||
|
/* If it's a Soft_Reset, reset the TX layer first */
|
||||||
|
if (PD_MSGTYPE_GET(&temp_msg) == PD_MSGTYPE_SOFT_RESET
|
||||||
|
&& PD_NUMOBJ_GET(&(temp_msg)) == 0) {
|
||||||
|
return PRLTxReset;
|
||||||
|
/* Otherwise, just send the message */
|
||||||
|
} else {
|
||||||
|
return PRLTxConstructMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Silence the compiler warning */
|
||||||
|
return PRLTxWaitMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_reset() {
|
||||||
|
/* Clear MessageIDCounter */
|
||||||
|
_tx_messageidcounter = 0;
|
||||||
|
|
||||||
|
/* Tell the Protocol RX thread to reset */
|
||||||
|
ProtocolReceive::notify( PDB_EVT_PRLRX_RESET);
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
return PRLTxConstructMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PRL_Tx_Construct_Message state
|
||||||
|
*/
|
||||||
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_construct_message() {
|
||||||
|
/* Set the correct MessageID in the message */
|
||||||
|
temp_msg.hdr &= ~PD_HDR_MESSAGEID;
|
||||||
|
temp_msg.hdr |= (_tx_messageidcounter % 8) << PD_HDR_MESSAGEID_SHIFT;
|
||||||
|
|
||||||
|
/* PD 3.0 collision avoidance */
|
||||||
|
// if (PolicyEngine::isPD3_0()) {
|
||||||
|
// /* If we're starting an AMS, wait for permission to transmit */
|
||||||
|
// evt = waitForEvent((uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS,
|
||||||
|
// 0);
|
||||||
|
// if ((uint32_t) evt
|
||||||
|
// & (uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS) {
|
||||||
|
// while (fusb_get_typec_current() != fusb_sink_tx_ok) {
|
||||||
|
// osDelay(1);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
messageSending = true;
|
||||||
|
/* Send the message to the PHY */
|
||||||
|
fusb_send_message(&temp_msg);
|
||||||
|
|
||||||
|
return PRLTxWaitResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PRL_Tx_Wait_for_PHY_Response state
|
||||||
|
*/
|
||||||
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_response() {
|
||||||
|
/* Wait for an event. There is no need to run CRCReceiveTimer, since the
|
||||||
|
* FUSB302B handles that as part of its retry mechanism. */
|
||||||
|
ProtocolTransmit::Notifications evt = waitForEvent(
|
||||||
|
(uint32_t) Notifications::PDB_EVT_PRLTX_RESET
|
||||||
|
| (uint32_t) Notifications::PDB_EVT_PRLTX_DISCARD
|
||||||
|
| (uint32_t) Notifications::PDB_EVT_PRLTX_I_TXSENT
|
||||||
|
| (uint32_t) Notifications::PDB_EVT_PRLTX_I_RETRYFAIL);
|
||||||
|
|
||||||
|
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_RESET) {
|
||||||
|
return PRLTxPHYReset;
|
||||||
|
}
|
||||||
|
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_DISCARD) {
|
||||||
|
return PRLTxDiscardMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the message was sent successfully */
|
||||||
|
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_I_TXSENT) {
|
||||||
|
return PRLTxMatchMessageID;
|
||||||
|
}
|
||||||
|
/* If the message failed to be sent */
|
||||||
|
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_I_RETRYFAIL) {
|
||||||
|
return PRLTxTransmissionError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Silence the compiler warning */
|
||||||
|
return PRLTxDiscardMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PRL_Tx_Match_MessageID state
|
||||||
|
*/
|
||||||
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_match_messageid() {
|
||||||
|
union pd_msg goodcrc;
|
||||||
|
|
||||||
|
/* Read the GoodCRC */
|
||||||
|
fusb_read_message(&goodcrc);
|
||||||
|
|
||||||
|
/* Check that the message is correct */
|
||||||
|
if (PD_MSGTYPE_GET(&goodcrc) == PD_MSGTYPE_GOODCRC
|
||||||
|
&& PD_NUMOBJ_GET(&goodcrc) == 0
|
||||||
|
&& PD_MESSAGEID_GET(&goodcrc) == _tx_messageidcounter) {
|
||||||
|
return PRLTxMessageSent;
|
||||||
|
} else {
|
||||||
|
return PRLTxTransmissionError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_transmission_error() {
|
||||||
|
/* Increment MessageIDCounter */
|
||||||
|
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
|
||||||
|
|
||||||
|
/* Tell the policy engine that we failed */
|
||||||
|
PolicyEngine::notify( PDB_EVT_PE_TX_ERR);
|
||||||
|
|
||||||
|
return PRLTxWaitMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_message_sent() {
|
||||||
|
messageSending = false;
|
||||||
|
/* Increment MessageIDCounter */
|
||||||
|
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
|
||||||
|
|
||||||
|
/* Tell the policy engine that we succeeded */
|
||||||
|
PolicyEngine::notify( PDB_EVT_PE_TX_DONE);
|
||||||
|
|
||||||
|
return PRLTxWaitMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_discard_message() {
|
||||||
|
/* If we were working on sending a message, increment MessageIDCounter */
|
||||||
|
if (messageSending) {
|
||||||
|
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
|
||||||
|
|
||||||
|
return PRLTxPHYReset;
|
||||||
|
} else {
|
||||||
|
return PRLTxWaitMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ProtocolTransmit::thread(const void *args) {
|
||||||
|
(void) args;
|
||||||
|
ProtocolTransmit::protocol_tx_state state = PRLTxPHYReset;
|
||||||
|
|
||||||
|
//Init the incoming message queue
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
switch (state) {
|
||||||
|
case PRLTxPHYReset:
|
||||||
|
state = protocol_tx_phy_reset();
|
||||||
|
break;
|
||||||
|
case PRLTxWaitMessage:
|
||||||
|
state = protocol_tx_wait_message();
|
||||||
|
break;
|
||||||
|
case PRLTxReset:
|
||||||
|
state = protocol_tx_reset();
|
||||||
|
break;
|
||||||
|
case PRLTxConstructMessage:
|
||||||
|
state = protocol_tx_construct_message();
|
||||||
|
break;
|
||||||
|
case PRLTxWaitResponse:
|
||||||
|
state = protocol_tx_wait_response();
|
||||||
|
break;
|
||||||
|
case PRLTxMatchMessageID:
|
||||||
|
state = protocol_tx_match_messageid();
|
||||||
|
break;
|
||||||
|
case PRLTxTransmissionError:
|
||||||
|
state = protocol_tx_transmission_error();
|
||||||
|
break;
|
||||||
|
case PRLTxMessageSent:
|
||||||
|
state = protocol_tx_message_sent();
|
||||||
|
break;
|
||||||
|
case PRLTxDiscardMessage:
|
||||||
|
state = protocol_tx_discard_message();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = PRLTxPHYReset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolTransmit::notify(ProtocolTransmit::Notifications notification) {
|
||||||
|
if (xEventGroupHandle != NULL) {
|
||||||
|
xEventGroupSetBits(xEventGroupHandle, (uint32_t) notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolTransmit::init() {
|
||||||
|
messagesWaiting = xQueueCreateStatic(PDB_MSG_POOL_SIZE,
|
||||||
|
sizeof(union pd_msg), ucQueueStorageArea, &xStaticQueue);
|
||||||
|
|
||||||
|
osThreadStaticDef(pd_txTask, thread, PDB_PRIO_PRL, 0, TaskStackSize,
|
||||||
|
TaskBuffer, &TaskControlBlock);
|
||||||
|
TaskHandle = osThreadCreate(osThread(pd_txTask), NULL);
|
||||||
|
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolTransmit::pushMessage(union pd_msg *msg) {
|
||||||
|
if (messagesWaiting) {
|
||||||
|
xQueueSend(messagesWaiting, msg, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProtocolTransmit::messagePending() {
|
||||||
|
if (messagesWaiting) {
|
||||||
|
return uxQueueMessagesWaiting(messagesWaiting) > 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolTransmit::getMessage() {
|
||||||
|
//Loads the pending message into the buffer
|
||||||
|
if (messagesWaiting) {
|
||||||
|
xQueueReceive(messagesWaiting, &temp_msg, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolTransmit::Notifications ProtocolTransmit::waitForEvent(uint32_t mask,
|
||||||
|
uint32_t ticksToWait) {
|
||||||
|
if (xEventGroupHandle) {
|
||||||
|
return (Notifications) xEventGroupWaitBits(xEventGroupHandle, mask,
|
||||||
|
mask,
|
||||||
|
pdFALSE, ticksToWait);
|
||||||
|
}
|
||||||
|
return (Notifications)0;
|
||||||
|
}
|
||||||
97
workspace/TS100/Core/Drivers/FUSB302/protocol_tx.h
Normal file
97
workspace/TS100/Core/Drivers/FUSB302/protocol_tx.h
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* 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_PROTOCOL_TX_H
|
||||||
|
#define PDB_PROTOCOL_TX_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "policy_engine.h"
|
||||||
|
#include "protocol_rx.h"
|
||||||
|
#include <pd.h>
|
||||||
|
|
||||||
|
/* Events for the Protocol TX thread */
|
||||||
|
|
||||||
|
class ProtocolTransmit {
|
||||||
|
public:
|
||||||
|
static void init();
|
||||||
|
//Push a message to the queue to be sent out the pd comms bus
|
||||||
|
static void pushMessage(union pd_msg *msg);
|
||||||
|
|
||||||
|
enum class Notifications {
|
||||||
|
|
||||||
|
PDB_EVT_PRLTX_RESET = EVENT_MASK(0), //
|
||||||
|
PDB_EVT_PRLTX_I_TXSENT = EVENT_MASK(1), //
|
||||||
|
PDB_EVT_PRLTX_I_RETRYFAIL = EVENT_MASK(2), //
|
||||||
|
PDB_EVT_PRLTX_DISCARD = EVENT_MASK(3), //
|
||||||
|
PDB_EVT_PRLTX_MSG_TX = EVENT_MASK(4), //
|
||||||
|
PDB_EVT_PRLTX_START_AMS = EVENT_MASK(5), //
|
||||||
|
};
|
||||||
|
static void notify(Notifications notification);
|
||||||
|
private:
|
||||||
|
static void thread(const void *args);
|
||||||
|
static EventGroupHandle_t xEventGroupHandle;
|
||||||
|
static StaticEventGroup_t xCreatedEventGroup;
|
||||||
|
static osThreadId TaskHandle;
|
||||||
|
static const size_t TaskStackSize = 1024 / 4;
|
||||||
|
static uint32_t TaskBuffer[TaskStackSize];
|
||||||
|
static osStaticThreadDef_t TaskControlBlock;
|
||||||
|
static bool messageSending;
|
||||||
|
/*
|
||||||
|
* Protocol TX machine states
|
||||||
|
*
|
||||||
|
* Because the PHY can automatically send retries, the Check_RetryCounter state
|
||||||
|
* has been removed, transitions relating to it are modified appropriately, and
|
||||||
|
* we don't even keep a RetryCounter.
|
||||||
|
*/
|
||||||
|
enum protocol_tx_state {
|
||||||
|
PRLTxPHYReset,
|
||||||
|
PRLTxWaitMessage,
|
||||||
|
PRLTxReset,
|
||||||
|
PRLTxConstructMessage,
|
||||||
|
PRLTxWaitResponse,
|
||||||
|
PRLTxMatchMessageID,
|
||||||
|
PRLTxTransmissionError,
|
||||||
|
PRLTxMessageSent,
|
||||||
|
PRLTxDiscardMessage
|
||||||
|
};
|
||||||
|
//Internal states
|
||||||
|
static protocol_tx_state protocol_tx_discard_message();
|
||||||
|
static protocol_tx_state protocol_tx_message_sent();
|
||||||
|
static protocol_tx_state protocol_tx_transmission_error();
|
||||||
|
static protocol_tx_state protocol_tx_match_messageid();
|
||||||
|
static protocol_tx_state protocol_tx_wait_response();
|
||||||
|
static protocol_tx_state protocol_tx_construct_message();
|
||||||
|
static protocol_tx_state protocol_tx_reset();
|
||||||
|
static protocol_tx_state protocol_tx_wait_message();
|
||||||
|
static protocol_tx_state protocol_tx_phy_reset();
|
||||||
|
//queue of up to PDB_MSG_POOL_SIZE messages to send
|
||||||
|
static StaticQueue_t xStaticQueue;
|
||||||
|
/* The array to use as the queue's storage area. This must be at least
|
||||||
|
uxQueueLength * uxItemSize bytes. */
|
||||||
|
static uint8_t ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)];
|
||||||
|
static QueueHandle_t messagesWaiting;
|
||||||
|
static uint8_t _tx_messageidcounter;
|
||||||
|
static bool messagePending();
|
||||||
|
//Reads a message off the queue into the temp message
|
||||||
|
static void getMessage();
|
||||||
|
static union pd_msg temp_msg;
|
||||||
|
static Notifications waitForEvent(uint32_t mask, uint32_t ticksToWait =
|
||||||
|
portMAX_DELAY);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PDB_PROTOCOL_TX_H */
|
||||||
@@ -126,18 +126,6 @@ const uint8_t idleScreenBG[] = {
|
|||||||
0x8A,0x84,0x82,0x81,0x80,0x80,0x80,0x40,0x40,0x20,0x18,0x07
|
0x8A,0x84,0x82,0x81,0x80,0x80,0x80,0x40,0x40,0x20,0x18,0x07
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t idleScreenBGF[] = {
|
|
||||||
//width = 84
|
|
||||||
//height = 16
|
|
||||||
0xE0,0x18,0x04,0x02,0x02,0x01,0x41,0x81,0x01,0x01,0x65,0x99,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
|
||||||
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x04,0x18,0xE0,0x00,0x00,0xE0,0x18,0x04,0x02,0x02,
|
|
||||||
0x01,0x01,0x41,0x61,0x61,0x61,0xE1,0xC1,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0xC1,
|
|
||||||
0xE1,0x61,0x61,0x61,0x41,0x01,0x02,0x02,0x04,0x18,0xE0,0x00,
|
|
||||||
0x07,0x18,0x20,0x40,0x40,0x80,0x80,0x80,0x81,0x82,0x84,0x8A,0x92,0x82,0x82,0x82,0x80,0x82,0x80,0x82,0x82,0x82,0x87,0x87,
|
|
||||||
0x85,0x87,0x85,0x87,0x87,0x85,0x85,0x85,0x85,0x87,0x82,0x80,0x40,0x40,0x20,0x18,0x07,0x00,0x00,0x07,0x18,0x20,0x40,0x40,
|
|
||||||
0x80,0x80,0x82,0x86,0x86,0x86,0x87,0x83,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x83,
|
|
||||||
0x87,0x86,0x86,0x86,0x82,0x80,0x40,0x40,0x20,0x18,0x07,0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 16x16 icons
|
* 16x16 icons
|
||||||
|
|||||||
310
workspace/TS100/Core/Drivers/I2CBB.cpp
Normal file
310
workspace/TS100/Core/Drivers/I2CBB.cpp
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
/*
|
||||||
|
* I2CBB.cpp
|
||||||
|
*
|
||||||
|
* Created on: 12 Jun 2020
|
||||||
|
* Author: Ralim
|
||||||
|
*/
|
||||||
|
#include "Model_Config.h"
|
||||||
|
#ifdef I2C_SOFT
|
||||||
|
#include <I2CBB.hpp>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
SemaphoreHandle_t I2CBB::I2CSemaphore = NULL;
|
||||||
|
StaticSemaphore_t I2CBB::xSemaphoreBuffer;
|
||||||
|
SemaphoreHandle_t I2CBB::I2CSemaphore2 = NULL;
|
||||||
|
StaticSemaphore_t I2CBB::xSemaphoreBuffer2;
|
||||||
|
void I2CBB::init() {
|
||||||
|
//Set GPIO's to output open drain
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||||
|
GPIO_InitStruct.Pin = SDA2_Pin ;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
|
HAL_GPIO_Init(SDA2_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||||
|
GPIO_InitStruct.Pin = SCL2_Pin;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
|
HAL_GPIO_Init(SCL2_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
SOFT_SDA_HIGH();
|
||||||
|
SOFT_SCL_HIGH();
|
||||||
|
I2CSemaphore = xSemaphoreCreateMutexStatic (&xSemaphoreBuffer);
|
||||||
|
I2CSemaphore2 = xSemaphoreCreateMutexStatic (&xSemaphoreBuffer2);
|
||||||
|
unlock();
|
||||||
|
unlock2();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool I2CBB::probe(uint8_t address) {
|
||||||
|
start();
|
||||||
|
bool ack = send(address);
|
||||||
|
stop();
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
|
||||||
|
uint16_t Size) {
|
||||||
|
if (!lock())
|
||||||
|
return false;
|
||||||
|
start();
|
||||||
|
bool ack = send(DevAddress);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ack = send(MemAddress);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SOFT_SCL_LOW();
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
// stop();
|
||||||
|
start();
|
||||||
|
ack = send(DevAddress | 1);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (Size) {
|
||||||
|
pData[0] = read(Size > 1);
|
||||||
|
pData++;
|
||||||
|
Size--;
|
||||||
|
}
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||||
|
const uint8_t *pData, uint16_t Size) {
|
||||||
|
if (!lock())
|
||||||
|
return false;
|
||||||
|
start();
|
||||||
|
bool ack = send(DevAddress);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
asm("bkpt");
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ack = send(MemAddress);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
asm("bkpt");
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (Size) {
|
||||||
|
resetWatchdog();
|
||||||
|
ack = send(pData[0]);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
asm("bkpt");
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pData++;
|
||||||
|
Size--;
|
||||||
|
}
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||||
|
if (!lock())
|
||||||
|
return;
|
||||||
|
start();
|
||||||
|
bool ack = send(DevAddress);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (Size) {
|
||||||
|
ack = send(pData[0]);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pData++;
|
||||||
|
Size--;
|
||||||
|
}
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||||
|
if (!lock())
|
||||||
|
return;
|
||||||
|
start();
|
||||||
|
bool ack = send(DevAddress | 1);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (Size) {
|
||||||
|
pData[0] = read(Size > 1);
|
||||||
|
pData++;
|
||||||
|
Size--;
|
||||||
|
}
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
|
||||||
|
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) {
|
||||||
|
if (Size_tx == 0 && Size_rx == 0)
|
||||||
|
return;
|
||||||
|
if (lock() == false)
|
||||||
|
return;
|
||||||
|
if (Size_tx) {
|
||||||
|
start();
|
||||||
|
bool ack = send(DevAddress);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (Size_tx) {
|
||||||
|
ack = send(pData_tx[0]);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pData_tx++;
|
||||||
|
Size_tx--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Size_rx) {
|
||||||
|
start();
|
||||||
|
bool ack = send(DevAddress | 1);
|
||||||
|
if (!ack) {
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (Size_rx) {
|
||||||
|
pData_rx[0] = read(Size_rx > 1);
|
||||||
|
pData_rx++;
|
||||||
|
Size_rx--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stop();
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2CBB::start() {
|
||||||
|
/* I2C Start condition, data line goes low when clock is high */
|
||||||
|
SOFT_SCL_HIGH();
|
||||||
|
SOFT_SDA_HIGH();
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
SOFT_SDA_LOW();
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
SOFT_SCL_LOW();
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
SOFT_SDA_HIGH();
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2CBB::stop() {
|
||||||
|
/* I2C Stop condition, clock goes high when data is low */
|
||||||
|
SOFT_SDA_LOW();
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
SOFT_SCL_HIGH();
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
SOFT_SDA_HIGH();
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool I2CBB::send(uint8_t value) {
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
write_bit(value & 0x80); // write the most-significant bit
|
||||||
|
value <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOFT_SDA_HIGH();
|
||||||
|
bool ack = (read_bit() == 0);
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t I2CBB::read(bool ack) {
|
||||||
|
uint8_t B = 0;
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
B <<= 1;
|
||||||
|
B |= read_bit();
|
||||||
|
}
|
||||||
|
|
||||||
|
SOFT_SDA_HIGH();
|
||||||
|
if (ack)
|
||||||
|
write_bit(0);
|
||||||
|
else
|
||||||
|
write_bit(1);
|
||||||
|
return B;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t I2CBB::read_bit() {
|
||||||
|
uint8_t b;
|
||||||
|
|
||||||
|
SOFT_SDA_HIGH();
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
SOFT_SCL_HIGH();
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
|
||||||
|
if (SOFT_SDA_READ())
|
||||||
|
b = 1;
|
||||||
|
else
|
||||||
|
b = 0;
|
||||||
|
|
||||||
|
SOFT_SCL_LOW();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2CBB::unlock() {
|
||||||
|
xSemaphoreGive(I2CSemaphore);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool I2CBB::lock() {
|
||||||
|
if (I2CSemaphore == NULL) {
|
||||||
|
asm("bkpt");
|
||||||
|
}
|
||||||
|
bool a = xSemaphoreTake(I2CSemaphore, (TickType_t) 100) == pdTRUE;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2CBB::write_bit(uint8_t val) {
|
||||||
|
if (val) {
|
||||||
|
SOFT_SDA_HIGH();
|
||||||
|
} else {
|
||||||
|
SOFT_SDA_LOW();
|
||||||
|
}
|
||||||
|
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
SOFT_SCL_HIGH();
|
||||||
|
SOFT_I2C_DELAY();
|
||||||
|
SOFT_SCL_LOW();
|
||||||
|
}
|
||||||
|
|
||||||
|
void I2CBB::unlock2() {
|
||||||
|
xSemaphoreGive(I2CSemaphore2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool I2CBB::lock2() {
|
||||||
|
if (I2CSemaphore2 == NULL) {
|
||||||
|
asm("bkpt");
|
||||||
|
}
|
||||||
|
bool a = xSemaphoreTake(I2CSemaphore2, (TickType_t) 500) == pdTRUE;
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
51
workspace/TS100/Core/Drivers/I2CBB.hpp
Normal file
51
workspace/TS100/Core/Drivers/I2CBB.hpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* I2CBB.hpp
|
||||||
|
*
|
||||||
|
* Created on: 12 Jun 2020
|
||||||
|
* Author: Ralim
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BSP_MINIWARE_I2CBB_HPP_
|
||||||
|
#define BSP_MINIWARE_I2CBB_HPP_
|
||||||
|
#include "Model_Config.h"
|
||||||
|
#ifdef I2C_SOFT
|
||||||
|
#include "BSP.h"
|
||||||
|
#include "Setup.h"
|
||||||
|
#include "Pins.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
#include "Software_I2C.h"
|
||||||
|
|
||||||
|
class I2CBB {
|
||||||
|
public:
|
||||||
|
static void init();
|
||||||
|
//Probe if device ACK's address or not
|
||||||
|
static bool probe(uint8_t address);
|
||||||
|
//Issues a complete 8bit register read
|
||||||
|
static bool Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
|
||||||
|
uint8_t *pData, uint16_t Size);
|
||||||
|
//Implements a register write
|
||||||
|
static bool Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||||
|
const uint8_t *pData, uint16_t Size);
|
||||||
|
static void Transmit(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,
|
||||||
|
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx);
|
||||||
|
static void unlock2();
|
||||||
|
static bool lock2();
|
||||||
|
private:
|
||||||
|
static SemaphoreHandle_t I2CSemaphore;
|
||||||
|
static StaticSemaphore_t xSemaphoreBuffer;
|
||||||
|
static SemaphoreHandle_t I2CSemaphore2;
|
||||||
|
static StaticSemaphore_t xSemaphoreBuffer2;
|
||||||
|
static void unlock();
|
||||||
|
static bool lock();
|
||||||
|
static void start();
|
||||||
|
static void stop();
|
||||||
|
static bool send(uint8_t value);
|
||||||
|
static uint8_t read(bool ack);
|
||||||
|
static uint8_t read_bit();
|
||||||
|
static void write_bit(uint8_t val);
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#endif /* BSP_MINIWARE_I2CBB_HPP_ */
|
||||||
@@ -40,6 +40,9 @@ public:
|
|||||||
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 void Transmit(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,
|
||||||
|
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 void 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);
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) {
|
|||||||
|
|
||||||
while (duration <= totalDuration) {
|
while (duration <= totalDuration) {
|
||||||
duration = xTaskGetTickCount() - start;
|
duration = xTaskGetTickCount() - start;
|
||||||
uint8_t progress = duration * 100 / totalDuration;
|
uint8_t progress = duration * 1000 / totalDuration;
|
||||||
progress = easeInOutTiming(progress);
|
progress = easeInOutTiming(progress);
|
||||||
progress = lerp(0, OLED_WIDTH, progress);
|
progress = lerp(0, OLED_WIDTH, progress);
|
||||||
if (progress > OLED_WIDTH) {
|
if (progress > OLED_WIDTH) {
|
||||||
@@ -191,9 +191,9 @@ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) {
|
|||||||
offset = progress;
|
offset = progress;
|
||||||
|
|
||||||
memmove(&firstStripPtr[oldStart], &firstStripPtr[oldPrevious],
|
memmove(&firstStripPtr[oldStart], &firstStripPtr[oldPrevious],
|
||||||
OLED_WIDTH - progress);
|
OLED_WIDTH - progress);
|
||||||
memmove(&secondStripPtr[oldStart], &secondStripPtr[oldPrevious],
|
memmove(&secondStripPtr[oldStart], &secondStripPtr[oldPrevious],
|
||||||
OLED_WIDTH - progress);
|
OLED_WIDTH - progress);
|
||||||
|
|
||||||
memmove(&firstStripPtr[newStart], &firstBackStripPtr[newEnd], progress);
|
memmove(&firstStripPtr[newStart], &firstBackStripPtr[newEnd], progress);
|
||||||
memmove(&secondStripPtr[newStart], &secondBackStripPtr[newEnd],
|
memmove(&secondStripPtr[newStart], &secondBackStripPtr[newEnd],
|
||||||
@@ -213,7 +213,7 @@ void OLED::useSecondaryFramebuffer(bool useSecondary) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OLED::setRotation(bool leftHanded) {
|
void OLED::setRotation(bool leftHanded) {
|
||||||
#ifdef MODEL_TS80
|
#ifdef OLED_FLIP
|
||||||
leftHanded = !leftHanded;
|
leftHanded = !leftHanded;
|
||||||
#endif
|
#endif
|
||||||
if (inLeftHandedMode == leftHanded) {
|
if (inLeftHandedMode == leftHanded) {
|
||||||
|
|||||||
@@ -27,12 +27,11 @@
|
|||||||
* This was bought to my attention by <Kuba Sztandera>
|
* This was bought to my attention by <Kuba Sztandera>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
uint32_t TipThermoModel::convertTipRawADCTouV(uint16_t rawADC) {
|
uint32_t TipThermoModel::convertTipRawADCTouV(uint16_t rawADC) {
|
||||||
// This takes the raw ADC samples, converts these to uV
|
// This takes the raw ADC samples, converts these to uV
|
||||||
// Then divides this down by the gain to convert to the uV on the input to the op-amp (A+B terminals)
|
// Then divides this down by the gain to convert to the uV on the input to the op-amp (A+B terminals)
|
||||||
// Then remove the calibration value that is stored as a tip offset
|
// Then remove the calibration value that is stored as a tip offset
|
||||||
uint32_t vddRailmVX10 = 33000; //The vreg is +-2%, but we have no higher accuracy available
|
uint32_t vddRailmVX10 = 33000;//The vreg is +-2%, but we have no higher accuracy available
|
||||||
// 4096 * 8 readings for full scale
|
// 4096 * 8 readings for full scale
|
||||||
// Convert the input ADC reading back into mV times 10 format.
|
// Convert the input ADC reading back into mV times 10 format.
|
||||||
uint32_t rawInputmVX10 = (rawADC * vddRailmVX10) / (4096 * 8);
|
uint32_t rawInputmVX10 = (rawADC * vddRailmVX10) / (4096 * 8);
|
||||||
@@ -76,7 +75,7 @@ uint32_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) {
|
|||||||
tipuVDelta *= 10;
|
tipuVDelta *= 10;
|
||||||
tipuVDelta /= systemSettings.TipGain;
|
tipuVDelta /= systemSettings.TipGain;
|
||||||
|
|
||||||
#ifdef MODEL_TS80
|
#if defined( MODEL_TS80)+defined( MODEL_TS80P)>0
|
||||||
tipuVDelta /= OP_AMP_GAIN_STAGE_TS100 / OP_AMP_GAIN_STAGE_TS80;
|
tipuVDelta /= OP_AMP_GAIN_STAGE_TS100 / OP_AMP_GAIN_STAGE_TS80;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,173 +1,171 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
All rights reserved
|
All rights reserved
|
||||||
|
|
||||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
>>! obliged to provide the source code for proprietary components !<<
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
>>! outside of the FreeRTOS kernel. !<<
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||||
link: http://www.freertos.org/a00114.html
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS provides completely free yet professionally developed, *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* robust, strictly quality controlled, supported, and cross *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* platform software that is more than just the market leader, it *
|
* platform software that is more than just the market leader, it *
|
||||||
* is the industry's de facto standard. *
|
* is the industry's de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Help yourself get started quickly while simultaneously helping *
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
* tutorial book, reference manual, or both: *
|
* tutorial book, reference manual, or both: *
|
||||||
* http://www.FreeRTOS.org/Documentation *
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
defined configASSERT()?
|
defined configASSERT()?
|
||||||
|
|
||||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
embedded software for free we request you assist our global community by
|
embedded software for free we request you assist our global community by
|
||||||
participating in the support forum.
|
participating in the support forum.
|
||||||
|
|
||||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
be as productive as possible as early as possible. Now you can receive
|
be as productive as possible as early as possible. Now you can receive
|
||||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
licenses offer ticketed support, indemnification and commercial middleware.
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
engineered and independently SIL3 certified version for use in safety and
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
mission critical applications that require provable dependability.
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FREERTOS_CONFIG_H
|
#ifndef FREERTOS_CONFIG_H
|
||||||
#define FREERTOS_CONFIG_H
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Application specific definitions.
|
* Application specific definitions.
|
||||||
*
|
*
|
||||||
* These definitions should be adjusted for your particular hardware and
|
* These definitions should be adjusted for your particular hardware and
|
||||||
* application requirements.
|
* application requirements.
|
||||||
*
|
*
|
||||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
*
|
*
|
||||||
* See http://www.freertos.org/a00110.html.
|
* See http://www.freertos.org/a00110.html.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
/* Section where include file can be added */
|
/* Section where include file can be added */
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Ensure stdint is only used by the compiler, and not the assembler. */
|
/* Ensure stdint is only used by the compiler, and not the assembler. */
|
||||||
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
|
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
extern uint32_t SystemCoreClock;
|
extern uint32_t SystemCoreClock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||||
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
||||||
#define configUSE_IDLE_HOOK 1
|
#define configUSE_IDLE_HOOK 1
|
||||||
#define configUSE_TICK_HOOK 0
|
#define configUSE_TICK_HOOK 0
|
||||||
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||||
#define configTICK_RATE_HZ ((TickType_t)100)
|
#define configTICK_RATE_HZ ((TickType_t)1000)
|
||||||
#define configMAX_PRIORITIES ( 4 )
|
#define configMAX_PRIORITIES ( 6 )
|
||||||
#define configMINIMAL_STACK_SIZE ((uint16_t)256)
|
#define configMINIMAL_STACK_SIZE ((uint16_t)256)
|
||||||
#define configTOTAL_HEAP_SIZE ((size_t)1024*14) /*Currently use about 9000*/
|
#define configTOTAL_HEAP_SIZE ((size_t)1024*14) /*Currently use about 9000*/
|
||||||
#define configMAX_TASK_NAME_LEN ( 24 )
|
#define configMAX_TASK_NAME_LEN ( 32 )
|
||||||
#define configUSE_16_BIT_TICKS 0
|
#define configUSE_16_BIT_TICKS 0
|
||||||
#define configUSE_MUTEXES 1
|
#define configUSE_MUTEXES 1
|
||||||
#define configQUEUE_REGISTRY_SIZE 8
|
#define configQUEUE_REGISTRY_SIZE 8
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_TIMERS 0
|
||||||
#define configCHECK_FOR_STACK_OVERFLOW 2 /*Bump this to 2 during development and bug hunting*/
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 2 /*Bump this to 2 during development and bug hunting*/
|
||||||
|
|
||||||
/* Co-routine definitions. */
|
/* Co-routine definitions. */
|
||||||
#define configUSE_CO_ROUTINES 0
|
#define configUSE_CO_ROUTINES 0
|
||||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||||
|
|
||||||
/* Set the following definitions to 1 to include the API function, or zero
|
/* Set the following definitions to 1 to include the API function, or zero
|
||||||
to exclude the API function. */
|
to exclude the API function. */
|
||||||
#define INCLUDE_vTaskPrioritySet 1
|
#define INCLUDE_vTaskPrioritySet 1
|
||||||
#define INCLUDE_uxTaskPriorityGet 0
|
#define INCLUDE_uxTaskPriorityGet 0
|
||||||
#define INCLUDE_vTaskDelete 0
|
#define INCLUDE_vTaskDelete 0
|
||||||
#define INCLUDE_vTaskCleanUpResources 0
|
#define INCLUDE_vTaskCleanUpResources 0
|
||||||
#define INCLUDE_vTaskSuspend 0
|
#define INCLUDE_vTaskSuspend 0
|
||||||
#define INCLUDE_vTaskDelayUntil 0
|
#define INCLUDE_vTaskDelayUntil 0
|
||||||
#define INCLUDE_vTaskDelay 1
|
#define INCLUDE_vTaskDelay 1
|
||||||
#define INCLUDE_xTaskGetSchedulerState 1
|
#define INCLUDE_xTaskGetSchedulerState 1
|
||||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||||
|
|
||||||
/* Cortex-M specific definitions. */
|
/* Cortex-M specific definitions. */
|
||||||
#ifdef __NVIC_PRIO_BITS
|
#ifdef __NVIC_PRIO_BITS
|
||||||
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
|
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
|
||||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||||
#else
|
#else
|
||||||
#define configPRIO_BITS 4
|
#define configPRIO_BITS 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The lowest interrupt priority that can be used in a call to a "set priority"
|
/* The lowest interrupt priority that can be used in a call to a "set priority"
|
||||||
function. */
|
function. */
|
||||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
|
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
|
||||||
|
|
||||||
/* The highest interrupt priority that can be used by any interrupt service
|
/* The highest interrupt priority that can be used by any interrupt service
|
||||||
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||||
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||||
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
|
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
|
||||||
|
|
||||||
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||||
to all Cortex-M ports, and do not rely on any particular library functions. */
|
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||||
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||||
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||||
|
|
||||||
/* Normal assert() semantics without relying on the provision of an assert.h
|
/* Normal assert() semantics without relying on the provision of an assert.h
|
||||||
header file. */
|
header file. */
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
|
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
|
||||||
/* USER CODE END 1 */
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
||||||
standard names. */
|
standard names. */
|
||||||
#define vPortSVCHandler SVC_Handler
|
#define vPortSVCHandler SVC_Handler
|
||||||
#define xPortPendSVHandler PendSV_Handler
|
#define xPortPendSVHandler PendSV_Handler
|
||||||
|
|
||||||
/* IMPORTANT: This define MUST be commented when used with STM32Cube firmware,
|
#if configUSE_TIMERS
|
||||||
to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
|
#define configTIMER_TASK_PRIORITY 2
|
||||||
/* #define xPortSysTickHandler SysTick_Handler */
|
#define configTIMER_QUEUE_LENGTH 8
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH (512/4)
|
||||||
/* USER CODE BEGIN Defines */
|
#endif
|
||||||
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
|
|
||||||
/* USER CODE END Defines */
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
||||||
#endif /* FREERTOS_CONFIG_H */
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
|
|
||||||
#define PRESS_ACCEL_STEP 3
|
#define PRESS_ACCEL_STEP 3
|
||||||
#define PRESS_ACCEL_INTERVAL_MIN 10
|
#define PRESS_ACCEL_INTERVAL_MIN 100
|
||||||
#define PRESS_ACCEL_INTERVAL_MAX 30
|
#define PRESS_ACCEL_INTERVAL_MAX 300
|
||||||
|
|
||||||
//GUI holds the menu structure and all its methods for the menu itself
|
//GUI holds the menu structure and all its methods for the menu itself
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
extern uint8_t PCBVersion;
|
extern uint8_t PCBVersion;
|
||||||
extern uint32_t currentTempTargetDegC;
|
extern uint32_t currentTempTargetDegC;
|
||||||
extern bool settingsWereReset;
|
extern bool settingsWereReset;
|
||||||
|
extern bool usb_pd_available;
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <history.hpp>
|
#include <history.hpp>
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "expMovingAverage.h"
|
#include "expMovingAverage.h"
|
||||||
|
#include "../../configuration.h"
|
||||||
#ifndef POWER_HPP_
|
#ifndef POWER_HPP_
|
||||||
#define POWER_HPP_
|
#define POWER_HPP_
|
||||||
|
|
||||||
@@ -18,16 +19,6 @@
|
|||||||
// This is necessary because of the temp noise and thermal lag in the system.
|
// This is necessary because of the temp noise and thermal lag in the system.
|
||||||
// Once we have feed-forward temp estimation we should be able to better tune this.
|
// Once we have feed-forward temp estimation we should be able to better tune this.
|
||||||
|
|
||||||
#ifdef MODEL_TS100
|
|
||||||
const int32_t tipMass = 45; // X10 watts to raise 1 deg C in 1 second
|
|
||||||
const uint8_t tipResistance = 85; //x10 ohms, 8.5 typical for ts100, 4.5 typical for ts80
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#ifdef MODEL_TS80
|
|
||||||
const uint32_t tipMass = 40;
|
|
||||||
const uint8_t tipResistance = 45; //x10 ohms, 8.5 typical for ts100, 4.5 typical for ts80
|
|
||||||
|
|
||||||
#endif
|
|
||||||
const uint8_t wattHistoryFilter = 24; // I term look back weighting
|
const uint8_t wattHistoryFilter = 24; // I term look back weighting
|
||||||
extern expMovingAverage<uint32_t, wattHistoryFilter> x10WattHistory;
|
extern expMovingAverage<uint32_t, wattHistoryFilter> x10WattHistory;
|
||||||
|
|
||||||
|
|||||||
@@ -1,365 +1,364 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @file stm32f1xx_hal_conf.h
|
* @file stm32f1xx_hal_conf.h
|
||||||
* @brief HAL configuration file.
|
* @brief HAL configuration file.
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @attention
|
* @attention
|
||||||
*
|
*
|
||||||
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
|
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
* are permitted provided that the following conditions are met:
|
* are permitted provided that the following conditions are met:
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
* may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
#ifndef __STM32F1xx_HAL_CONF_H
|
#ifndef __STM32F1xx_HAL_CONF_H
|
||||||
#define __STM32F1xx_HAL_CONF_H
|
#define __STM32F1xx_HAL_CONF_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
/* Exported types ------------------------------------------------------------*/
|
||||||
/* Exported constants --------------------------------------------------------*/
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
/* ########################## Module Selection ############################## */
|
/* ########################## Module Selection ############################## */
|
||||||
/**
|
/**
|
||||||
* @brief This is the list of modules to be used in the HAL driver
|
* @brief This is the list of modules to be used in the HAL driver
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define HAL_MODULE_ENABLED
|
#define HAL_MODULE_ENABLED
|
||||||
#define HAL_ADC_MODULE_ENABLED
|
#define HAL_ADC_MODULE_ENABLED
|
||||||
/*#define HAL_CRYP_MODULE_ENABLED */
|
/*#define HAL_CRYP_MODULE_ENABLED */
|
||||||
/*#define HAL_CAN_MODULE_ENABLED */
|
/*#define HAL_CAN_MODULE_ENABLED */
|
||||||
/*#define HAL_CEC_MODULE_ENABLED */
|
/*#define HAL_CEC_MODULE_ENABLED */
|
||||||
/*#define HAL_CORTEX_MODULE_ENABLED */
|
/*#define HAL_CORTEX_MODULE_ENABLED */
|
||||||
/*#define HAL_CRC_MODULE_ENABLED */
|
/*#define HAL_CRC_MODULE_ENABLED */
|
||||||
/*#define HAL_DAC_MODULE_ENABLED */
|
/*#define HAL_DAC_MODULE_ENABLED */
|
||||||
#define HAL_DMA_MODULE_ENABLED
|
#define HAL_DMA_MODULE_ENABLED
|
||||||
/*#define HAL_ETH_MODULE_ENABLED */
|
/*#define HAL_ETH_MODULE_ENABLED */
|
||||||
/*#define HAL_FLASH_MODULE_ENABLED */
|
/*#define HAL_FLASH_MODULE_ENABLED */
|
||||||
#define HAL_GPIO_MODULE_ENABLED
|
#define HAL_GPIO_MODULE_ENABLED
|
||||||
#define HAL_I2C_MODULE_ENABLED
|
#define HAL_I2C_MODULE_ENABLED
|
||||||
/*#define HAL_I2S_MODULE_ENABLED */
|
/*#define HAL_I2S_MODULE_ENABLED */
|
||||||
/*#define HAL_IRDA_MODULE_ENABLED */
|
/*#define HAL_IRDA_MODULE_ENABLED */
|
||||||
#define HAL_IWDG_MODULE_ENABLED
|
#define HAL_IWDG_MODULE_ENABLED
|
||||||
/*#define HAL_NOR_MODULE_ENABLED */
|
/*#define HAL_NOR_MODULE_ENABLED */
|
||||||
/*#define HAL_NAND_MODULE_ENABLED */
|
/*#define HAL_NAND_MODULE_ENABLED */
|
||||||
/*#define HAL_PCCARD_MODULE_ENABLED */
|
/*#define HAL_PCCARD_MODULE_ENABLED */
|
||||||
/*#define HAL_PCD_MODULE_ENABLED */
|
/*#define HAL_PCD_MODULE_ENABLED */
|
||||||
/*#define HAL_HCD_MODULE_ENABLED */
|
/*#define HAL_HCD_MODULE_ENABLED */
|
||||||
/*#define HAL_PWR_MODULE_ENABLED */
|
/*#define HAL_PWR_MODULE_ENABLED */
|
||||||
/*#define HAL_RCC_MODULE_ENABLED */
|
/*#define HAL_RCC_MODULE_ENABLED */
|
||||||
/*#define HAL_RTC_MODULE_ENABLED */
|
/*#define HAL_RTC_MODULE_ENABLED */
|
||||||
/*#define HAL_SD_MODULE_ENABLED */
|
/*#define HAL_SD_MODULE_ENABLED */
|
||||||
/*#define HAL_MMC_MODULE_ENABLED */
|
/*#define HAL_MMC_MODULE_ENABLED */
|
||||||
/*#define HAL_SDRAM_MODULE_ENABLED */
|
/*#define HAL_SDRAM_MODULE_ENABLED */
|
||||||
/*#define HAL_SMARTCARD_MODULE_ENABLED */
|
/*#define HAL_SMARTCARD_MODULE_ENABLED */
|
||||||
/*#define HAL_SPI_MODULE_ENABLED */
|
/*#define HAL_SPI_MODULE_ENABLED */
|
||||||
/*#define HAL_SRAM_MODULE_ENABLED */
|
/*#define HAL_SRAM_MODULE_ENABLED */
|
||||||
#define HAL_TIM_MODULE_ENABLED
|
#define HAL_TIM_MODULE_ENABLED
|
||||||
/*#define HAL_UART_MODULE_ENABLED */
|
/*#define HAL_UART_MODULE_ENABLED */
|
||||||
/*#define HAL_USART_MODULE_ENABLED */
|
/*#define HAL_USART_MODULE_ENABLED */
|
||||||
/*#define HAL_WWDG_MODULE_ENABLED */
|
/*#define HAL_WWDG_MODULE_ENABLED */
|
||||||
|
|
||||||
#define HAL_CORTEX_MODULE_ENABLED
|
#define HAL_CORTEX_MODULE_ENABLED
|
||||||
#define HAL_DMA_MODULE_ENABLED
|
#define HAL_DMA_MODULE_ENABLED
|
||||||
#define HAL_FLASH_MODULE_ENABLED
|
#define HAL_FLASH_MODULE_ENABLED
|
||||||
#define HAL_GPIO_MODULE_ENABLED
|
#define HAL_GPIO_MODULE_ENABLED
|
||||||
#define HAL_PWR_MODULE_ENABLED
|
#define HAL_PWR_MODULE_ENABLED
|
||||||
#define HAL_RCC_MODULE_ENABLED
|
#define HAL_RCC_MODULE_ENABLED
|
||||||
|
|
||||||
/* ########################## Oscillator Values adaptation ####################*/
|
/* ########################## Oscillator Values adaptation ####################*/
|
||||||
/**
|
/**
|
||||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||||
* This value is used by the RCC HAL module to compute the system frequency
|
* This value is used by the RCC HAL module to compute the system frequency
|
||||||
* (when HSE is used as system clock source, directly or through the PLL).
|
* (when HSE is used as system clock source, directly or through the PLL).
|
||||||
*/
|
*/
|
||||||
#if !defined (HSE_VALUE)
|
#if !defined (HSE_VALUE)
|
||||||
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
|
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
|
||||||
#endif /* HSE_VALUE */
|
#endif /* HSE_VALUE */
|
||||||
|
|
||||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||||
#define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */
|
#define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */
|
||||||
#endif /* HSE_STARTUP_TIMEOUT */
|
#endif /* HSE_STARTUP_TIMEOUT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Internal High Speed oscillator (HSI) value.
|
* @brief Internal High Speed oscillator (HSI) value.
|
||||||
* This value is used by the RCC HAL module to compute the system frequency
|
* This value is used by the RCC HAL module to compute the system frequency
|
||||||
* (when HSI is used as system clock source, directly or through the PLL).
|
* (when HSI is used as system clock source, directly or through the PLL).
|
||||||
*/
|
*/
|
||||||
#if !defined (HSI_VALUE)
|
#if !defined (HSI_VALUE)
|
||||||
#define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/
|
#define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/
|
||||||
#endif /* HSI_VALUE */
|
#endif /* HSI_VALUE */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Internal Low Speed oscillator (LSI) value.
|
* @brief Internal Low Speed oscillator (LSI) value.
|
||||||
*/
|
*/
|
||||||
#if !defined (LSI_VALUE)
|
#if !defined (LSI_VALUE)
|
||||||
#define LSI_VALUE 40000U /*!< LSI Typical Value in Hz */
|
#define LSI_VALUE 40000U /*!< LSI Typical Value in Hz */
|
||||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||||
The real value may vary depending on the variations
|
The real value may vary depending on the variations
|
||||||
in voltage and temperature. */
|
in voltage and temperature. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief External Low Speed oscillator (LSE) value.
|
* @brief External Low Speed oscillator (LSE) value.
|
||||||
* This value is used by the UART, RTC HAL module to compute the system frequency
|
* This value is used by the UART, RTC HAL module to compute the system frequency
|
||||||
*/
|
*/
|
||||||
#if !defined (LSE_VALUE)
|
#if !defined (LSE_VALUE)
|
||||||
#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External oscillator in Hz*/
|
#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External oscillator in Hz*/
|
||||||
#endif /* LSE_VALUE */
|
#endif /* LSE_VALUE */
|
||||||
|
|
||||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||||
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */
|
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */
|
||||||
#endif /* LSE_STARTUP_TIMEOUT */
|
#endif /* LSE_STARTUP_TIMEOUT */
|
||||||
|
|
||||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||||
|
|
||||||
/* ########################### System Configuration ######################### */
|
/* ########################### System Configuration ######################### */
|
||||||
/**
|
/**
|
||||||
* @brief This is the HAL system configuration section
|
* @brief This is the HAL system configuration section
|
||||||
*/
|
*/
|
||||||
#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
|
#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
|
||||||
#define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority (lowest by default) */
|
#define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority (lowest by default) */
|
||||||
#define USE_RTOS 0
|
#define USE_RTOS 0
|
||||||
#define PREFETCH_ENABLE 1
|
#define PREFETCH_ENABLE 1
|
||||||
|
|
||||||
/* ########################## Assert Selection ############################## */
|
/* ########################## Assert Selection ############################## */
|
||||||
/**
|
/**
|
||||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||||
* HAL drivers code
|
* HAL drivers code
|
||||||
*/
|
*/
|
||||||
/* #define USE_FULL_ASSERT 1 */
|
/* #define USE_FULL_ASSERT 1 */
|
||||||
|
|
||||||
/* ################## Ethernet peripheral configuration ##################### */
|
/* ################## Ethernet peripheral configuration ##################### */
|
||||||
|
|
||||||
/* Section 1 : Ethernet peripheral configuration */
|
/* Section 1 : Ethernet peripheral configuration */
|
||||||
|
|
||||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||||
#define MAC_ADDR0 2
|
#define MAC_ADDR0 2
|
||||||
#define MAC_ADDR1 0
|
#define MAC_ADDR1 0
|
||||||
#define MAC_ADDR2 0
|
#define MAC_ADDR2 0
|
||||||
#define MAC_ADDR3 0
|
#define MAC_ADDR3 0
|
||||||
#define MAC_ADDR4 0
|
#define MAC_ADDR4 0
|
||||||
#define MAC_ADDR5 0
|
#define MAC_ADDR5 0
|
||||||
|
|
||||||
/* Definition of the Ethernet driver buffers size and count */
|
/* Definition of the Ethernet driver buffers size and count */
|
||||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||||
#define ETH_RXBUFNB ((uint32_t)8) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
|
#define ETH_RXBUFNB ((uint32_t)8) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||||
#define ETH_TXBUFNB ((uint32_t)4) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
#define ETH_TXBUFNB ((uint32_t)4) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||||
|
|
||||||
/* Section 2: PHY configuration section */
|
/* Section 2: PHY configuration section */
|
||||||
|
|
||||||
/* DP83848_PHY_ADDRESS Address*/
|
/* DP83848_PHY_ADDRESS Address*/
|
||||||
#define DP83848_PHY_ADDRESS 0x01U
|
#define DP83848_PHY_ADDRESS 0x01U
|
||||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||||
#define PHY_RESET_DELAY ((uint32_t)0x000000FF)
|
#define PHY_RESET_DELAY ((uint32_t)0x000000FF)
|
||||||
/* PHY Configuration delay */
|
/* PHY Configuration delay */
|
||||||
#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF)
|
#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF)
|
||||||
|
|
||||||
#define PHY_READ_TO ((uint32_t)0x0000FFFF)
|
#define PHY_READ_TO ((uint32_t)0x0000FFFF)
|
||||||
#define PHY_WRITE_TO ((uint32_t)0x0000FFFF)
|
#define PHY_WRITE_TO ((uint32_t)0x0000FFFF)
|
||||||
|
|
||||||
/* Section 3: Common PHY Registers */
|
/* Section 3: Common PHY Registers */
|
||||||
|
|
||||||
#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */
|
#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */
|
||||||
#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */
|
#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */
|
||||||
|
|
||||||
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
|
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
|
||||||
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
|
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
|
||||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
|
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
|
||||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
|
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
|
||||||
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
|
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
|
||||||
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
|
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
|
||||||
|
|
||||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
|
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
|
||||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
|
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
|
||||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
|
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
|
||||||
|
|
||||||
/* Section 4: Extended PHY Registers */
|
/* Section 4: Extended PHY Registers */
|
||||||
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
|
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
|
||||||
|
|
||||||
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
|
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
|
||||||
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
|
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* @brief Include module's header file
|
* @brief Include module's header file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAL_RCC_MODULE_ENABLED
|
#ifdef HAL_RCC_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_rcc.h"
|
#include "stm32f1xx_hal_rcc.h"
|
||||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_gpio.h"
|
#include "stm32f1xx_hal_gpio.h"
|
||||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_DMA_MODULE_ENABLED
|
#ifdef HAL_DMA_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_dma.h"
|
#include "stm32f1xx_hal_dma.h"
|
||||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_ETH_MODULE_ENABLED
|
#ifdef HAL_ETH_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_eth.h"
|
#include "stm32f1xx_hal_eth.h"
|
||||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_CAN_MODULE_ENABLED
|
#ifdef HAL_CAN_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_can.h"
|
#include "stm32f1xx_hal_can.h"
|
||||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_CEC_MODULE_ENABLED
|
#ifdef HAL_CEC_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_cec.h"
|
#include "stm32f1xx_hal_cec.h"
|
||||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_cortex.h"
|
#include "stm32f1xx_hal_cortex.h"
|
||||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_ADC_MODULE_ENABLED
|
#ifdef HAL_ADC_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_adc.h"
|
#include "stm32f1xx_hal_adc.h"
|
||||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_CRC_MODULE_ENABLED
|
#ifdef HAL_CRC_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_crc.h"
|
#include "stm32f1xx_hal_crc.h"
|
||||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_DAC_MODULE_ENABLED
|
#ifdef HAL_DAC_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_dac.h"
|
#include "stm32f1xx_hal_dac.h"
|
||||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_flash.h"
|
#include "stm32f1xx_hal_flash.h"
|
||||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_sram.h"
|
#include "stm32f1xx_hal_sram.h"
|
||||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_NOR_MODULE_ENABLED
|
#ifdef HAL_NOR_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_nor.h"
|
#include "stm32f1xx_hal_nor.h"
|
||||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_I2C_MODULE_ENABLED
|
#ifdef HAL_I2C_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_i2c.h"
|
#include "stm32f1xx_hal_i2c.h"
|
||||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_I2S_MODULE_ENABLED
|
#ifdef HAL_I2S_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_i2s.h"
|
#include "stm32f1xx_hal_i2s.h"
|
||||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_iwdg.h"
|
#include "stm32f1xx_hal_iwdg.h"
|
||||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_PWR_MODULE_ENABLED
|
#ifdef HAL_PWR_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_pwr.h"
|
#include "stm32f1xx_hal_pwr.h"
|
||||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_RTC_MODULE_ENABLED
|
#ifdef HAL_RTC_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_rtc.h"
|
#include "stm32f1xx_hal_rtc.h"
|
||||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_PCCARD_MODULE_ENABLED
|
#ifdef HAL_PCCARD_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_pccard.h"
|
#include "stm32f1xx_hal_pccard.h"
|
||||||
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_SD_MODULE_ENABLED
|
#ifdef HAL_SD_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_sd.h"
|
#include "stm32f1xx_hal_sd.h"
|
||||||
#endif /* HAL_SD_MODULE_ENABLED */
|
#endif /* HAL_SD_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_MMC_MODULE_ENABLED
|
#ifdef HAL_MMC_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_mmc.h"
|
#include "stm32f1xx_hal_mmc.h"
|
||||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_NAND_MODULE_ENABLED
|
#ifdef HAL_NAND_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_nand.h"
|
#include "stm32f1xx_hal_nand.h"
|
||||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_SPI_MODULE_ENABLED
|
#ifdef HAL_SPI_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_spi.h"
|
#include "stm32f1xx_hal_spi.h"
|
||||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_TIM_MODULE_ENABLED
|
#ifdef HAL_TIM_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_tim.h"
|
#include "stm32f1xx_hal_tim.h"
|
||||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_UART_MODULE_ENABLED
|
#ifdef HAL_UART_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_uart.h"
|
#include "stm32f1xx_hal_uart.h"
|
||||||
#endif /* HAL_UART_MODULE_ENABLED */
|
#endif /* HAL_UART_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_USART_MODULE_ENABLED
|
#ifdef HAL_USART_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_usart.h"
|
#include "stm32f1xx_hal_usart.h"
|
||||||
#endif /* HAL_USART_MODULE_ENABLED */
|
#endif /* HAL_USART_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_irda.h"
|
#include "stm32f1xx_hal_irda.h"
|
||||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_smartcard.h"
|
#include "stm32f1xx_hal_smartcard.h"
|
||||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_wwdg.h"
|
#include "stm32f1xx_hal_wwdg.h"
|
||||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_PCD_MODULE_ENABLED
|
#ifdef HAL_PCD_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_pcd.h"
|
#include "stm32f1xx_hal_pcd.h"
|
||||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||||
|
|
||||||
#ifdef HAL_HCD_MODULE_ENABLED
|
#ifdef HAL_HCD_MODULE_ENABLED
|
||||||
#include "stm32f1xx_hal_hcd.h"
|
#include "stm32f1xx_hal_hcd.h"
|
||||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
#ifdef USE_FULL_ASSERT
|
||||||
#ifdef USE_FULL_ASSERT
|
/**
|
||||||
/**
|
* @brief The assert_param macro is used for function's parameters check.
|
||||||
* @brief The assert_param macro is used for function's parameters check.
|
* @param expr: If expr is false, it calls assert_failed function
|
||||||
* @param expr: If expr is false, it calls assert_failed function
|
* which reports the name of the source file and the source
|
||||||
* which reports the name of the source file and the source
|
* line number of the call that failed.
|
||||||
* line number of the call that failed.
|
* If expr is true, it returns no value.
|
||||||
* If expr is true, it returns no value.
|
* @retval None
|
||||||
* @retval None
|
*/
|
||||||
*/
|
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||||
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
/* Exported functions ------------------------------------------------------- */
|
||||||
/* Exported functions ------------------------------------------------------- */
|
void assert_failed(uint8_t* file, uint32_t line);
|
||||||
void assert_failed(uint8_t* file, uint32_t line);
|
#else
|
||||||
#else
|
#define assert_param(expr) ((void)0U)
|
||||||
#define assert_param(expr) ((void)0U)
|
#endif /* USE_FULL_ASSERT */
|
||||||
#endif /* USE_FULL_ASSERT */
|
|
||||||
|
#ifdef __cplusplus
|
||||||
#ifdef __cplusplus
|
}
|
||||||
}
|
#endif
|
||||||
#endif
|
|
||||||
|
#endif /* __STM32F1xx_HAL_CONF_H */
|
||||||
#endif /* __STM32F1xx_HAL_CONF_H */
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
|
|||||||
@@ -23,10 +23,12 @@ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
|
|||||||
/* place for user code */
|
/* place for user code */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void vApplicationStackOverflowHook(xTaskHandle *pxTask,
|
void vApplicationStackOverflowHook(xTaskHandle *pxTask,
|
||||||
signed portCHAR *pcTaskName) {
|
signed portCHAR *pcTaskName) {
|
||||||
(void) pxTask;
|
(void) pxTask;
|
||||||
(void) pcTaskName;
|
(void) pcTaskName;
|
||||||
|
asm("bkpt");
|
||||||
// We dont have a good way to handle a stack overflow at this point in time
|
// We dont have a good way to handle a stack overflow at this point in time
|
||||||
reboot();
|
reboot();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,68 +13,72 @@
|
|||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
void QC_Seek9V() {
|
void QC_Seek9V() {
|
||||||
QC_DNegZero_Six();
|
QC_DNegZero_Six();
|
||||||
QC_DPlusThree_Three();
|
QC_DPlusThree_Three();
|
||||||
}
|
}
|
||||||
void QC_Seek12V() {
|
void QC_Seek12V() {
|
||||||
QC_DNegZero_Six();
|
QC_DNegZero_Six();
|
||||||
QC_DPlusZero_Six();
|
QC_DPlusZero_Six();
|
||||||
}
|
}
|
||||||
void QC_Seek20V() {
|
void QC_Seek20V() {
|
||||||
QC_DNegThree_Three();
|
QC_DNegThree_Three();
|
||||||
QC_DPlusThree_Three();
|
QC_DPlusThree_Three();
|
||||||
}
|
}
|
||||||
void QC_SeekContMode() {
|
void QC_SeekContMode() {
|
||||||
QC_DNegThree_Three();
|
QC_DNegThree_Three();
|
||||||
QC_DPlusZero_Six();
|
QC_DPlusZero_Six();
|
||||||
}
|
}
|
||||||
void QC_SeekContPlus() {
|
void QC_SeekContPlus() {
|
||||||
QC_SeekContMode();
|
QC_SeekContMode();
|
||||||
vTaskDelay(3);
|
osDelay(30);
|
||||||
QC_Seek20V();
|
QC_Seek20V();
|
||||||
vTaskDelay(1);
|
osDelay(10);
|
||||||
QC_SeekContMode();
|
QC_SeekContMode();
|
||||||
}
|
}
|
||||||
void QC_SeekContNeg() {
|
void QC_SeekContNeg() {
|
||||||
QC_SeekContMode();
|
QC_SeekContMode();
|
||||||
vTaskDelay(3);
|
osDelay(30);
|
||||||
QC_Seek12V();
|
QC_Seek12V();
|
||||||
vTaskDelay(1);
|
osDelay(10);
|
||||||
QC_SeekContMode();
|
QC_SeekContMode();
|
||||||
}
|
}
|
||||||
uint8_t QCMode = 0;
|
uint8_t QCMode = 0;
|
||||||
uint8_t QCTries = 0;
|
uint8_t QCTries = 0;
|
||||||
void seekQC(int16_t Vx10, uint16_t divisor) {
|
void seekQC(int16_t Vx10, uint16_t divisor) {
|
||||||
if (QCMode == 5) startQC(divisor);
|
if (QCMode == 0)
|
||||||
if (QCMode == 0) return; // NOT connected to a QC Charger
|
startQC(divisor);
|
||||||
|
|
||||||
if (Vx10 < 45) return;
|
if (Vx10 < 45)
|
||||||
if (xTaskGetTickCount() < 100) return;
|
return;
|
||||||
if (Vx10 > 130) Vx10 = 130; // Cap max value at 13V
|
if (xTaskGetTickCount() < 1000)
|
||||||
// Seek the QC to the Voltage given if this adapter supports continuous mode
|
return;
|
||||||
// try and step towards the wanted value
|
if (Vx10 > 130)
|
||||||
|
Vx10 = 130; // Cap max value at 13V
|
||||||
|
// Seek the QC to the Voltage given if this adapter supports continuous mode
|
||||||
|
// try and step towards the wanted value
|
||||||
|
|
||||||
// 1. Measure current voltage
|
// 1. Measure current voltage
|
||||||
int16_t vStart = getInputVoltageX10(divisor, 1);
|
int16_t vStart = getInputVoltageX10(divisor, 1);
|
||||||
int difference = Vx10 - vStart;
|
int difference = Vx10 - vStart;
|
||||||
|
|
||||||
// 2. calculate ideal steps (0.2V changes)
|
// 2. calculate ideal steps (0.2V changes)
|
||||||
|
|
||||||
int steps = difference / 2;
|
int steps = difference / 2;
|
||||||
if (QCMode == 3) {
|
if (QCMode == 3) {
|
||||||
if (steps > -2 && steps < 2) return; // dont bother with small steps
|
if (steps > -2 && steps < 2)
|
||||||
while (steps < 0) {
|
return; // dont bother with small steps
|
||||||
QC_SeekContNeg();
|
while (steps < 0) {
|
||||||
vTaskDelay(3);
|
QC_SeekContNeg();
|
||||||
steps++;
|
osDelay(30);
|
||||||
}
|
steps++;
|
||||||
while (steps > 0) {
|
}
|
||||||
QC_SeekContPlus();
|
while (steps > 0) {
|
||||||
vTaskDelay(3);
|
QC_SeekContPlus();
|
||||||
steps--;
|
osDelay(30);
|
||||||
}
|
steps--;
|
||||||
vTaskDelay(10);
|
}
|
||||||
}
|
osDelay(100);
|
||||||
|
}
|
||||||
#ifdef ENABLE_QC2
|
#ifdef ENABLE_QC2
|
||||||
// Re-measure
|
// Re-measure
|
||||||
/* Disabled due to nothing to test and code space of around 1k*/
|
/* Disabled due to nothing to test and code space of around 1k*/
|
||||||
@@ -99,59 +103,61 @@ void seekQC(int16_t Vx10, uint16_t divisor) {
|
|||||||
}
|
}
|
||||||
// Must be called after FreeRToS Starts
|
// Must be called after FreeRToS Starts
|
||||||
void startQC(uint16_t divisor) {
|
void startQC(uint16_t divisor) {
|
||||||
// Pre check that the input could be >5V already, and if so, dont both
|
// Pre check that the input could be >5V already, and if so, dont both
|
||||||
// negotiating as someone is feeding in hv
|
// negotiating as someone is feeding in hv
|
||||||
uint16_t vin = getInputVoltageX10(divisor, 1);
|
uint16_t vin = getInputVoltageX10(divisor, 1);
|
||||||
if (vin > 100) {
|
if (vin > 100) {
|
||||||
QCMode = 1; // Already at 12V, user has probably over-ridden this
|
QCMode = 1; // Already at 12V, user has probably over-ridden this
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QC_Init_GPIO();
|
if (QCTries > 10) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QC_Init_GPIO();
|
||||||
|
|
||||||
// Tries to negotiate QC for 9V
|
// Tries to negotiate QC for 9V
|
||||||
// This is a multiple step process.
|
// This is a multiple step process.
|
||||||
// 1. Set around 0.6V on D+ for 1.25 Seconds or so
|
// 1. Set around 0.6V on D+ for 1.25 Seconds or so
|
||||||
// 2. After this It should un-short D+->D- and instead add a 20k pulldown on
|
// 2. After this It should un-short D+->D- and instead add a 20k pulldown on
|
||||||
// D-
|
// D-
|
||||||
QC_DPlusZero_Six();
|
QC_DPlusZero_Six();
|
||||||
|
|
||||||
|
// Delay 1.25 seconds
|
||||||
|
uint8_t enteredQC = 0;
|
||||||
|
for (uint16_t i = 0; i < 200 && enteredQC == 0; i++) {
|
||||||
|
osDelay(10); // 10mS pause
|
||||||
|
if (i > 130) {
|
||||||
|
if (QC_DM_PulledDown()) {
|
||||||
|
enteredQC = 1;
|
||||||
|
}
|
||||||
|
if (i == 140) {
|
||||||
|
// For some marginal QC chargers, we try adding a pulldown
|
||||||
|
QC_DM_PullDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QC_DM_No_PullDown();
|
||||||
|
if (enteredQC) {
|
||||||
|
// We have a QC capable charger
|
||||||
|
QC_Seek9V();
|
||||||
|
QC_Post_Probe_En();
|
||||||
|
QC_Seek9V();
|
||||||
|
// Wait for frontend ADC to stabilise
|
||||||
|
QCMode = 4;
|
||||||
|
for (uint8_t i = 0; i < 10; i++) {
|
||||||
|
if (getInputVoltageX10(divisor, 1) > 80) {
|
||||||
|
// yay we have at least QC2.0 or QC3.0
|
||||||
|
QCMode = 3; // We have at least QC2, pray for 3
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
osDelay(100); // 100mS
|
||||||
|
}
|
||||||
|
QCMode = 0;
|
||||||
|
QCTries++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// no QC
|
||||||
|
QCMode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Delay 1.25 seconds
|
|
||||||
uint8_t enteredQC = 0;
|
|
||||||
for (uint16_t i = 0; i < 200 && enteredQC == 0; i++) {
|
|
||||||
vTaskDelay(1); // 10mS pause
|
|
||||||
if (i > 130) {
|
|
||||||
if (QC_DM_PulledDown()) {
|
|
||||||
enteredQC = 1;
|
|
||||||
}
|
|
||||||
if (i == 140) {
|
|
||||||
// For some marginal QC chargers, we try adding a pulldown
|
|
||||||
QC_DM_PullDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QC_DM_No_PullDown();
|
|
||||||
if (enteredQC) {
|
|
||||||
// We have a QC capable charger
|
|
||||||
QC_Seek9V();
|
|
||||||
QC_Post_Probe_En();
|
|
||||||
QC_Seek9V();
|
|
||||||
// Wait for frontend ADC to stabilise
|
|
||||||
QCMode = 4;
|
|
||||||
for (uint8_t i = 0; i < 10; i++) {
|
|
||||||
if (getInputVoltageX10(divisor, 1) > 80) {
|
|
||||||
// yay we have at least QC2.0 or QC3.0
|
|
||||||
QCMode = 3; // We have at least QC2, pray for 3
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
vTaskDelay(10); // 100mS
|
|
||||||
}
|
|
||||||
QCMode = 5;
|
|
||||||
QCTries++;
|
|
||||||
if (QCTries > 10) // 10 goes to get it going
|
|
||||||
QCMode = 0;
|
|
||||||
} else {
|
|
||||||
// no QC
|
|
||||||
QCMode = 0;
|
|
||||||
}
|
|
||||||
if (QCTries > 10) QCMode = 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,14 +120,14 @@ static void settings_enterAdvancedMenu(void);
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const menuitem rootSettingsMenu[] {
|
const menuitem rootSettingsMenu[] {
|
||||||
/*
|
/*
|
||||||
* Power Source
|
* Power Source
|
||||||
* Soldering Menu
|
* Soldering Menu
|
||||||
* Power Saving Menu
|
* Power Saving Menu
|
||||||
* UI Menu
|
* UI Menu
|
||||||
* Advanced Menu
|
* Advanced Menu
|
||||||
* Exit
|
* Exit
|
||||||
*/
|
*/
|
||||||
#ifdef MODEL_TS100
|
#ifdef MODEL_TS100
|
||||||
{ (const char*) SettingsDescriptions[0], { settings_setInputVRange }, {
|
{ (const char*) SettingsDescriptions[0], { settings_setInputVRange }, {
|
||||||
settings_displayInputVRange } }, /*Voltage input*/
|
settings_displayInputVRange } }, /*Voltage input*/
|
||||||
@@ -291,7 +291,7 @@ static int userConfirmation(const char *message) {
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int16_t messageOffset = ((xTaskGetTickCount() - messageStart)
|
int16_t messageOffset = ((xTaskGetTickCount() - messageStart)
|
||||||
/ (systemSettings.descriptionScrollSpeed == 1 ? 1 : 2));
|
/ (systemSettings.descriptionScrollSpeed == 1 ? 10 : 20));
|
||||||
messageOffset %= messageWidth; // Roll around at the end
|
messageOffset %= messageWidth; // Roll around at the end
|
||||||
|
|
||||||
if (lastOffset != messageOffset) {
|
if (lastOffset != messageOffset) {
|
||||||
@@ -353,8 +353,7 @@ static void settings_setInputPRange(void) {
|
|||||||
static void settings_displayInputPRange(void) {
|
static void settings_displayInputPRange(void) {
|
||||||
printShortDescription(0, 5);
|
printShortDescription(0, 5);
|
||||||
//0 = 9V, 1=12V (Fixed Voltages, these imply 1.5A limits)
|
//0 = 9V, 1=12V (Fixed Voltages, these imply 1.5A limits)
|
||||||
//2 = 18W, 2=24W (Auto Adjusting V, estimated from the tip resistance???) # TODO
|
/// TODO TS80P
|
||||||
// Need to come back and look at these ^ as there were issues with voltage hunting
|
|
||||||
switch (systemSettings.cutoutSetting) {
|
switch (systemSettings.cutoutSetting) {
|
||||||
case 0:
|
case 0:
|
||||||
OLED::printNumber(9, 2);
|
OLED::printNumber(9, 2);
|
||||||
@@ -647,7 +646,7 @@ static void settings_setResetSettings(void) {
|
|||||||
OLED::print(ResetOKMessage);
|
OLED::print(ResetOKMessage);
|
||||||
OLED::refresh();
|
OLED::refresh();
|
||||||
|
|
||||||
waitForButtonPressOrTimeout(200); // 2 second timeout
|
waitForButtonPressOrTimeout(2000); // 2 second timeout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,6 +728,10 @@ static void settings_setCalibrateVIN(void) {
|
|||||||
case BUTTON_F_LONG:
|
case BUTTON_F_LONG:
|
||||||
case BUTTON_B_LONG:
|
case BUTTON_B_LONG:
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
OLED::setCursor(0, 0);
|
||||||
|
OLED::printNumber(systemSettings.voltageDiv, 3);
|
||||||
|
OLED::refresh();
|
||||||
|
waitForButtonPressOrTimeout(1000);
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case BUTTON_NONE:
|
case BUTTON_NONE:
|
||||||
@@ -740,7 +743,7 @@ static void settings_setCalibrateVIN(void) {
|
|||||||
osDelay(40);
|
osDelay(40);
|
||||||
|
|
||||||
// Cap to sensible values
|
// Cap to sensible values
|
||||||
#ifdef MODEL_TS80
|
#if defined(MODEL_TS80)+defined(MODEL_TS80P)>0
|
||||||
if (systemSettings.voltageDiv < 500) {
|
if (systemSettings.voltageDiv < 500) {
|
||||||
systemSettings.voltageDiv = 500;
|
systemSettings.voltageDiv = 500;
|
||||||
} else if (systemSettings.voltageDiv > 900) {
|
} else if (systemSettings.voltageDiv > 900) {
|
||||||
@@ -930,7 +933,7 @@ void gui_Menu(const menuitem *menu) {
|
|||||||
OLED::setCursor(0, 0);
|
OLED::setCursor(0, 0);
|
||||||
// If the user has hesitated for >=3 seconds, show the long text
|
// If the user has hesitated for >=3 seconds, show the long text
|
||||||
// Otherwise "draw" the option
|
// Otherwise "draw" the option
|
||||||
if ((xTaskGetTickCount() - lastButtonTime < 300)
|
if ((xTaskGetTickCount() - lastButtonTime < 3000)
|
||||||
|| menu[currentScreen].description == NULL) {
|
|| menu[currentScreen].description == NULL) {
|
||||||
OLED::clearScreen();
|
OLED::clearScreen();
|
||||||
menu[currentScreen].draw.func();
|
menu[currentScreen].draw.func();
|
||||||
@@ -949,7 +952,7 @@ void gui_Menu(const menuitem *menu) {
|
|||||||
int16_t descriptionOffset =
|
int16_t descriptionOffset =
|
||||||
((xTaskGetTickCount() - descriptionStart)
|
((xTaskGetTickCount() - descriptionStart)
|
||||||
/ (systemSettings.descriptionScrollSpeed == 1 ?
|
/ (systemSettings.descriptionScrollSpeed == 1 ?
|
||||||
1 : 2));
|
10 : 20));
|
||||||
descriptionOffset %= descriptionWidth; // Roll around at the end
|
descriptionOffset %= descriptionWidth; // Roll around at the end
|
||||||
if (lastOffset != descriptionOffset) {
|
if (lastOffset != descriptionOffset) {
|
||||||
OLED::clearScreen();
|
OLED::clearScreen();
|
||||||
@@ -1037,7 +1040,7 @@ void gui_Menu(const menuitem *menu) {
|
|||||||
osDelay(40);
|
osDelay(40);
|
||||||
lcdRefresh = false;
|
lcdRefresh = false;
|
||||||
}
|
}
|
||||||
if ((xTaskGetTickCount() - lastButtonTime) > (100 * 30)) {
|
if ((xTaskGetTickCount() - lastButtonTime) > (1000 * 30)) {
|
||||||
// If user has not pressed any buttons in 30 seconds, exit back a menu layer
|
// If user has not pressed any buttons in 30 seconds, exit back a menu layer
|
||||||
// This will trickle the user back to the main screen eventually
|
// This will trickle the user back to the main screen eventually
|
||||||
earlyExit = true;
|
earlyExit = true;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
uint8_t PCBVersion = 0;
|
uint8_t PCBVersion = 0;
|
||||||
// File local variables
|
// File local variables
|
||||||
|
bool usb_pd_available = false;
|
||||||
bool settingsWereReset = false;
|
bool settingsWereReset = false;
|
||||||
// FreeRTOS variables
|
// FreeRTOS variables
|
||||||
|
|
||||||
@@ -43,21 +43,28 @@ int main(void) {
|
|||||||
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();
|
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()) {
|
if (MMA8652FC::detect()) {
|
||||||
PCBVersion = 1;
|
PCBVersion = 1;
|
||||||
MMA8652FC::initalize(); // this sets up the I2C registers
|
MMA8652FC::initalize(); // this sets up the I2C registers
|
||||||
} else if (LIS2DH12::detect()) {
|
} else
|
||||||
|
#endif
|
||||||
|
#ifdef ACCEL_LIS
|
||||||
|
if (LIS2DH12::detect()) {
|
||||||
PCBVersion = 2;
|
PCBVersion = 2;
|
||||||
// Setup the ST Accelerometer
|
// Setup the ST Accelerometer
|
||||||
LIS2DH12::initalize(); // startup the accelerometer
|
LIS2DH12::initalize(); // startup the accelerometer
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
PCBVersion = 3;
|
PCBVersion = 3;
|
||||||
systemSettings.SleepTime = 0;
|
systemSettings.SleepTime = 0;
|
||||||
systemSettings.ShutdownTime = 0; // No accel -> disable sleep
|
systemSettings.ShutdownTime = 0; // No accel -> disable sleep
|
||||||
systemSettings.sensitivity = 0;
|
systemSettings.sensitivity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetWatchdog();
|
resetWatchdog();
|
||||||
|
|
||||||
/* Create the thread(s) */
|
/* Create the thread(s) */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,6 @@ uint32_t lastMovementTime = 0;
|
|||||||
void startMOVTask(void const *argument __unused) {
|
void startMOVTask(void const *argument __unused) {
|
||||||
OLED::setRotation(systemSettings.OrientationMode & 1);
|
OLED::setRotation(systemSettings.OrientationMode & 1);
|
||||||
postRToSInit();
|
postRToSInit();
|
||||||
power_probe();
|
|
||||||
lastMovementTime = 0;
|
lastMovementTime = 0;
|
||||||
int16_t datax[MOVFilter] = { 0 };
|
int16_t datax[MOVFilter] = { 0 };
|
||||||
int16_t datay[MOVFilter] = { 0 };
|
int16_t datay[MOVFilter] = { 0 };
|
||||||
@@ -39,13 +38,20 @@ void startMOVTask(void const *argument __unused) {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
int32_t threshold = 1500 + (9 * 200);
|
int32_t threshold = 1500 + (9 * 200);
|
||||||
threshold -= systemSettings.sensitivity * 200; // 200 is the step size
|
threshold -= systemSettings.sensitivity * 200; // 200 is the step size
|
||||||
|
#ifdef ACCEL_LIS
|
||||||
if (PCBVersion == 2) {
|
if (PCBVersion == 2) {
|
||||||
LIS2DH12::getAxisReadings(tx, ty, tz);
|
LIS2DH12::getAxisReadings(tx, ty, tz);
|
||||||
rotation = LIS2DH12::getOrientation();
|
rotation = LIS2DH12::getOrientation();
|
||||||
} else if (PCBVersion == 1) {
|
} else
|
||||||
|
#endif
|
||||||
|
#ifdef ACCEL_MMA
|
||||||
|
if (PCBVersion == 1) {
|
||||||
MMA8652FC::getAxisReadings(tx, ty, tz);
|
MMA8652FC::getAxisReadings(tx, ty, tz);
|
||||||
rotation = MMA8652FC::getOrientation();
|
rotation = MMA8652FC::getOrientation();
|
||||||
|
}else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
//do nothing :(
|
||||||
}
|
}
|
||||||
if (systemSettings.OrientationMode == 2) {
|
if (systemSettings.OrientationMode == 2) {
|
||||||
if (rotation != ORIENTATION_FLAT) {
|
if (rotation != ORIENTATION_FLAT) {
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
static TickType_t powerPulseRate = 1000;
|
static TickType_t powerPulseRate = 10000;
|
||||||
static TickType_t powerPulseDuration = 50;
|
static TickType_t powerPulseDuration = 250;
|
||||||
TaskHandle_t pidTaskNotification = NULL;
|
TaskHandle_t pidTaskNotification = NULL;
|
||||||
uint32_t currentTempTargetDegC = 0; // Current temperature target in C
|
uint32_t currentTempTargetDegC = 0; // Current temperature target in C
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ MEMORY
|
|||||||
{
|
{
|
||||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
/* LOCAL_BUILD*/
|
/* LOCAL_BUILD*/
|
||||||
/*ROM (rx) : ORIGIN = 0x08000000, LENGTH = 46K*/
|
/*ROM (rx) : ORIGIN = 0x08000000, LENGTH = 48K*/
|
||||||
/* production*/
|
/* production*/
|
||||||
ROM (rx) : ORIGIN = 0x08004000, LENGTH = 46K
|
ROM (rx) : ORIGIN = 0x08004000, LENGTH = 46K
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ FRTOS_CMIS_INC_DIR = ./Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS
|
|||||||
FRTOS_INC_DIR = ./Middlewares/Third_Party/FreeRTOS/Source/include
|
FRTOS_INC_DIR = ./Middlewares/Third_Party/FreeRTOS/Source/include
|
||||||
FRTOS_GCC_INC_DIR = ./Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM3
|
FRTOS_GCC_INC_DIR = ./Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM3
|
||||||
DRIVER_INC_DIR =./Core/Drivers
|
DRIVER_INC_DIR =./Core/Drivers
|
||||||
|
FUSB_DRIVERS_INC_DIR = ./Core/Drivers/FUSB302
|
||||||
BSP_INC_DIR = ./Core/BSP
|
BSP_INC_DIR = ./Core/BSP
|
||||||
MINIWARE_INC_DIR = ./Core/BSP/Miniware
|
MINIWARE_INC_DIR = ./Core/BSP/Miniware
|
||||||
THREADS_INC_DIR = ./Core/Threads
|
THREADS_INC_DIR = ./Core/Threads
|
||||||
@@ -37,7 +38,8 @@ INCLUDES = -I$(APP_INC_DIR) \
|
|||||||
-I$(DRIVER_INC_DIR) \
|
-I$(DRIVER_INC_DIR) \
|
||||||
-I$(BSP_INC_DIR) \
|
-I$(BSP_INC_DIR) \
|
||||||
-I$(MINIWARE_INC_DIR) \
|
-I$(MINIWARE_INC_DIR) \
|
||||||
-I$(THREADS_INC_DIR)
|
-I$(THREADS_INC_DIR) \
|
||||||
|
-I$(FUSB_DRIVERS_INC_DIR)
|
||||||
# output folder
|
# output folder
|
||||||
HEXFILE_DIR=Hexfile
|
HEXFILE_DIR=Hexfile
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ TRANSLATION_SCRIPT="make_translation.py"
|
|||||||
# AVAILABLE_LANGUAGES will be calculating according to json files in $TRANSLATION_DIR
|
# AVAILABLE_LANGUAGES will be calculating according to json files in $TRANSLATION_DIR
|
||||||
AVAILABLE_LANGUAGES=()
|
AVAILABLE_LANGUAGES=()
|
||||||
BUILD_LANGUAGES=()
|
BUILD_LANGUAGES=()
|
||||||
AVAILABLE_MODELS=("TS100" "TS80")
|
AVAILABLE_MODELS=("TS100" "TS80" "TS80P")
|
||||||
BUILD_MODELS=()
|
BUILD_MODELS=()
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Model_Config.h"
|
||||||
/**
|
/**
|
||||||
* Configuration.h
|
* Configuration.h
|
||||||
* Define here your default pre settings for TS80 or TS100
|
* Define here your default pre settings for TS80 or TS100
|
||||||
@@ -76,7 +77,6 @@
|
|||||||
#define DETAILED_SOLDERING 0 // 0: Disable 1: Enable - Default 0
|
#define DETAILED_SOLDERING 0 // 0: Disable 1: Enable - Default 0
|
||||||
#define DETAILED_IDLE 0 // 0: Disable 1: Enable - Default 0
|
#define DETAILED_IDLE 0 // 0: Disable 1: Enable - Default 0
|
||||||
|
|
||||||
|
|
||||||
#define CUT_OUT_SETTING 0 // default to no cut-off voltage (or 18W for TS80)
|
#define CUT_OUT_SETTING 0 // default to no cut-off voltage (or 18W for TS80)
|
||||||
#define TEMPERATURE_INF 0 // default to 0
|
#define TEMPERATURE_INF 0 // default to 0
|
||||||
#define DESCRIPTION_SCROLL_SPEED 0 // 0: Slow 1: Fast - default to slow
|
#define DESCRIPTION_SCROLL_SPEED 0 // 0: Slow 1: Fast - default to slow
|
||||||
@@ -94,6 +94,10 @@
|
|||||||
|
|
||||||
#define OP_AMP_GAIN_STAGE_TS80 (1+(OP_AMP_Rf_TS80/OP_AMP_Rin_TS80))
|
#define OP_AMP_GAIN_STAGE_TS80 (1+(OP_AMP_Rf_TS80/OP_AMP_Rin_TS80))
|
||||||
|
|
||||||
|
//Deriving the Voltage div:
|
||||||
|
// Vin_max = (3.3*(r1+r2))/(r2)
|
||||||
|
//vdiv = (32768*4)/(vin_max*10)
|
||||||
|
|
||||||
#ifdef MODEL_TS100
|
#ifdef MODEL_TS100
|
||||||
#define VOLTAGE_DIV 467 // 467 - Default divider from schematic
|
#define VOLTAGE_DIV 467 // 467 - Default divider from schematic
|
||||||
#define CALIBRATION_OFFSET 900 // 900 - Default adc offset in uV
|
#define CALIBRATION_OFFSET 900 // 900 - Default adc offset in uV
|
||||||
@@ -105,11 +109,38 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MODEL_TS80
|
#ifdef MODEL_TS80
|
||||||
#define VOLTAGE_DIV 780 // Default divider from schematic
|
#define VOLTAGE_DIV 780 // Default divider from schematic
|
||||||
#define PID_POWER_LIMIT 24 // Sets the max pwm power limit
|
#define PID_POWER_LIMIT 24 // Sets the max pwm power limit
|
||||||
#define CALIBRATION_OFFSET 900 // the adc offset in uV
|
#define CALIBRATION_OFFSET 900 // the adc offset in uV
|
||||||
#define POWER_LIMIT 24 // 24 watts default power limit
|
#define POWER_LIMIT 24 // 24 watts default power limit
|
||||||
#define MAX_POWER_LIMIT 30 //
|
#define MAX_POWER_LIMIT 30 //
|
||||||
#define POWER_LIMIT_STEPS 2
|
#define POWER_LIMIT_STEPS 2
|
||||||
#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_TS80
|
#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_TS80
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODEL_TS80P
|
||||||
|
#define VOLTAGE_DIV 650 // Default for TS80P with slightly different resistors
|
||||||
|
#define PID_POWER_LIMIT 35 // Sets the max pwm power limit
|
||||||
|
#define CALIBRATION_OFFSET 900 // the adc offset in uV
|
||||||
|
#define POWER_LIMIT 30 // 30 watts default power limit
|
||||||
|
#define MAX_POWER_LIMIT 35 //
|
||||||
|
#define POWER_LIMIT_STEPS 2
|
||||||
|
#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_TS80
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MODEL_TS100
|
||||||
|
const int32_t tipMass = 45; // X10 watts to raise 1 deg C in 1 second
|
||||||
|
const uint8_t tipResistance = 85; //x10 ohms, 8.5 typical for ts100, 4.5 typical for ts80
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODEL_TS80
|
||||||
|
const uint32_t tipMass = 40;
|
||||||
|
const uint8_t tipResistance = 45; //x10 ohms, 4.5 typical for ts80 tips
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MODEL_TS80P
|
||||||
|
const uint32_t tipMass = 40;
|
||||||
|
const uint8_t tipResistance = 45; //x10 ohms, 4.5 typical for ts80 tips
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user