Beginnings of the shuffle
This commit is contained in:
19
workspace/TS100/Core/BSP/Defines.h
Normal file
19
workspace/TS100/Core/BSP/Defines.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Defines.h
|
||||
*
|
||||
* Created on: 29 May 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
|
||||
#ifndef BSP_DEFINES_H_
|
||||
#define BSP_DEFINES_H_
|
||||
|
||||
|
||||
enum Orientation {
|
||||
ORIENTATION_LEFT_HAND = 0, ORIENTATION_RIGHT_HAND = 1, ORIENTATION_FLAT = 3
|
||||
};
|
||||
|
||||
//It is assumed that all hardware implements an 8Hz update period at this time
|
||||
#define PID_TIM_HZ (8)
|
||||
|
||||
#endif /* BSP_DEFINES_H_ */
|
||||
212
workspace/TS100/Core/BSP/Miniware/BSP.cpp
Normal file
212
workspace/TS100/Core/BSP/Miniware/BSP.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
//BSP mapping functions
|
||||
|
||||
#include "BSP.h"
|
||||
#include "Setup.h"
|
||||
#include "history.hpp"
|
||||
#include "Pins.h"
|
||||
#include "history.hpp"
|
||||
volatile uint16_t PWMSafetyTimer = 0;
|
||||
volatile uint8_t pendingPWM = 0;
|
||||
|
||||
|
||||
//2 second filter (ADC is PID_TIM_HZ Hz)
|
||||
history<uint16_t, PID_TIM_HZ> rawTempFilter = { { 0 }, 0, 0 };
|
||||
void resetWatchdog() {
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
}
|
||||
|
||||
uint16_t getHandleTemperature() {
|
||||
// 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
|
||||
// example) STM32 = 4096 count @ 3.3V input -> But We oversample by 32/(2^2) =
|
||||
// 8 times oversampling Therefore 32768 is the 3.3V input, so 0.1007080078125
|
||||
// mV per count So we need to subtract an offset of 0.5V to center on 0C
|
||||
// (4964.8 counts)
|
||||
//
|
||||
int32_t result = getADC(0);
|
||||
result -= 4965; // remove 0.5V offset
|
||||
// 10mV per C
|
||||
// 99.29 counts per Deg C above 0C
|
||||
result *= 100;
|
||||
result /= 993;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t getTipInstantTemperature() {
|
||||
uint16_t sum = 0; // 12 bit readings * 8 -> 15 bits
|
||||
uint16_t readings[8];
|
||||
//Looking to reject the highest outlier readings.
|
||||
//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
|
||||
readings[0] = hadc1.Instance->JDR1;
|
||||
readings[1] = hadc1.Instance->JDR2;
|
||||
readings[2] = hadc1.Instance->JDR3;
|
||||
readings[3] = hadc1.Instance->JDR4;
|
||||
readings[4] = hadc2.Instance->JDR1;
|
||||
readings[5] = hadc2.Instance->JDR2;
|
||||
readings[6] = hadc2.Instance->JDR3;
|
||||
readings[7] = hadc2.Instance->JDR4;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
sum += readings[i];
|
||||
}
|
||||
return sum; // 8x over sample
|
||||
}
|
||||
|
||||
uint16_t getTipRawTemp(uint8_t refresh) {
|
||||
if (refresh) {
|
||||
uint16_t lastSample = getTipInstantTemperature();
|
||||
rawTempFilter.update(lastSample);
|
||||
return lastSample;
|
||||
} else {
|
||||
return rawTempFilter.average();
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
|
||||
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
|
||||
// Therefore we can divide down from there
|
||||
// Multiplying ADC max by 4 for additional calibration options,
|
||||
// ideal term is 467
|
||||
#ifdef MODEL_TS100
|
||||
#define BATTFILTERDEPTH 32
|
||||
#else
|
||||
#define BATTFILTERDEPTH 8
|
||||
|
||||
#endif
|
||||
static uint8_t preFillneeded = 10;
|
||||
static uint32_t samples[BATTFILTERDEPTH];
|
||||
static uint8_t index = 0;
|
||||
if (preFillneeded) {
|
||||
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
|
||||
samples[i] = getADC(1);
|
||||
preFillneeded--;
|
||||
}
|
||||
if (sample) {
|
||||
samples[index] = getADC(1);
|
||||
index = (index + 1) % BATTFILTERDEPTH;
|
||||
}
|
||||
uint32_t sum = 0;
|
||||
|
||||
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
|
||||
sum += samples[i];
|
||||
|
||||
sum /= BATTFILTERDEPTH;
|
||||
return sum * 4 / divisor;
|
||||
}
|
||||
|
||||
void setTipPWM(uint8_t pulse) {
|
||||
PWMSafetyTimer = 10; // This is decremented in the handler for PWM so that the tip pwm is
|
||||
// disabled if the PID task is not scheduled often enough.
|
||||
|
||||
pendingPWM = pulse;
|
||||
}
|
||||
|
||||
// These are called by the HAL after the corresponding events from the system
|
||||
// timers.
|
||||
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
||||
// Period has elapsed
|
||||
if (htim->Instance == TIM2) {
|
||||
// we want to turn on the output again
|
||||
PWMSafetyTimer--;
|
||||
// We decrement this safety value so that lockups in the
|
||||
// scheduler will not cause the PWM to become locked in an
|
||||
// active driving state.
|
||||
// While we could assume this could never happen, its a small price for
|
||||
// increased safety
|
||||
htim2.Instance->CCR4 = pendingPWM;
|
||||
if (htim2.Instance->CCR4 && PWMSafetyTimer) {
|
||||
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
|
||||
} else {
|
||||
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
|
||||
}
|
||||
} else if (htim->Instance == TIM1) {
|
||||
// STM uses this for internal functions as a counter for timeouts
|
||||
HAL_IncTick();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) {
|
||||
// This was a when the PWM for the output has timed out
|
||||
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) {
|
||||
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
|
||||
}
|
||||
}
|
||||
void unstick_I2C() {
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
int timeout = 100;
|
||||
int timeout_cnt = 0;
|
||||
|
||||
// 1. Clear PE bit.
|
||||
hi2c1.Instance->CR1 &= ~(0x0001);
|
||||
/**I2C1 GPIO Configuration
|
||||
PB6 ------> I2C1_SCL
|
||||
PB7 ------> I2C1_SDA
|
||||
*/
|
||||
// 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.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
|
||||
GPIO_InitStruct.Pin = SCL_Pin;
|
||||
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
|
||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
||||
|
||||
GPIO_InitStruct.Pin = SDA_Pin;
|
||||
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
|
||||
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
|
||||
|
||||
while (GPIO_PIN_SET != HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin)) {
|
||||
//Move clock to release I2C
|
||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET);
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
||||
|
||||
timeout_cnt++;
|
||||
if (timeout_cnt > timeout)
|
||||
return;
|
||||
}
|
||||
|
||||
// 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
|
||||
GPIO_InitStruct.Pin = SCL_Pin;
|
||||
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = SDA_Pin;
|
||||
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
|
||||
|
||||
// 13. Set SWRST bit in I2Cx_CR1 register.
|
||||
hi2c1.Instance->CR1 |= 0x8000;
|
||||
|
||||
asm("nop");
|
||||
|
||||
// 14. Clear SWRST bit in I2Cx_CR1 register.
|
||||
hi2c1.Instance->CR1 &= ~0x8000;
|
||||
|
||||
asm("nop");
|
||||
|
||||
// 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
|
||||
hi2c1.Instance->CR1 |= 0x0001;
|
||||
|
||||
// Call initialization function.
|
||||
HAL_I2C_Init(&hi2c1);
|
||||
}
|
||||
|
||||
uint8_t getButtonA() {
|
||||
return HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ?
|
||||
1 : 0;
|
||||
}
|
||||
uint8_t getButtonB() {
|
||||
return HAL_GPIO_ReadPin(KEY_B_GPIO_Port, KEY_B_Pin) == GPIO_PIN_RESET ?
|
||||
1 : 0;
|
||||
}
|
||||
@@ -1,148 +1,83 @@
|
||||
/*
|
||||
* Hardware.h
|
||||
*
|
||||
* Created on: 29Aug.,2017
|
||||
* Author: Ben V. Brown
|
||||
*/
|
||||
|
||||
#ifndef HARDWARE_H_
|
||||
#define HARDWARE_H_
|
||||
#include "Setup.h"
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "cmsis_os.h"
|
||||
#include "unit.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum Orientation {
|
||||
ORIENTATION_LEFT_HAND = 0, ORIENTATION_RIGHT_HAND = 1, ORIENTATION_FLAT = 3
|
||||
};
|
||||
#define PID_TIM_HZ (8)
|
||||
#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
|
||||
|
||||
#define KEY_B_Pin GPIO_PIN_6
|
||||
#define KEY_B_GPIO_Port GPIOA
|
||||
#define TMP36_INPUT_Pin GPIO_PIN_7
|
||||
#define TMP36_INPUT_GPIO_Port GPIOA
|
||||
#define TMP36_ADC1_CHANNEL ADC_CHANNEL_7
|
||||
#define TIP_TEMP_Pin GPIO_PIN_0
|
||||
#define TIP_TEMP_GPIO_Port GPIOB
|
||||
#define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_8
|
||||
#define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_8
|
||||
#define VIN_Pin GPIO_PIN_1
|
||||
#define VIN_GPIO_Port GPIOB
|
||||
#define VIN_ADC1_CHANNEL ADC_CHANNEL_9
|
||||
#define VIN_ADC2_CHANNEL ADC_CHANNEL_9
|
||||
#define OLED_RESET_Pin GPIO_PIN_8
|
||||
#define OLED_RESET_GPIO_Port GPIOA
|
||||
#define KEY_A_Pin GPIO_PIN_9
|
||||
#define KEY_A_GPIO_Port GPIOA
|
||||
#define INT_Orientation_Pin GPIO_PIN_3
|
||||
#define INT_Orientation_GPIO_Port GPIOB
|
||||
#define PWM_Out_Pin GPIO_PIN_4
|
||||
#define PWM_Out_GPIO_Port GPIOB
|
||||
#define PWM_Out_CHANNEL TIM_CHANNEL_1
|
||||
#define PWM_Out_CCR
|
||||
#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
|
||||
|
||||
#else
|
||||
// TS80 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
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Keep in a uint8_t range for the ID's
|
||||
*/
|
||||
#ifdef MODEL_TS100
|
||||
enum TipType {
|
||||
TS_B2 = 0,
|
||||
TS_D24 = 1,
|
||||
TS_BC2 = 2,
|
||||
TS_C1 = 3,
|
||||
Tip_MiniWare = 4,
|
||||
HAKKO_BC2 = 4,
|
||||
Tip_Hakko = 5,
|
||||
Tip_Custom = 5,
|
||||
};
|
||||
#endif
|
||||
#ifdef MODEL_TS80
|
||||
enum TipType {
|
||||
TS_B02 = 0, TS_D25 = 1, Tip_MiniWare = 2, Tip_Custom = 3,
|
||||
};
|
||||
#endif
|
||||
extern uint16_t tipGainCalValue ;
|
||||
|
||||
uint16_t lookupTipDefaultCalValue(enum TipType tipID);
|
||||
uint16_t getHandleTemperature();
|
||||
uint16_t getTipRawTemp(uint8_t refresh);
|
||||
uint16_t getInputVoltageX10(uint16_t divisor,uint8_t sample);
|
||||
|
||||
void setTipPWM(uint8_t pulse);
|
||||
uint16_t ctoTipMeasurement(uint16_t temp);
|
||||
uint16_t tipMeasurementToC(uint16_t raw);
|
||||
uint16_t ftoTipMeasurement(uint16_t temp);
|
||||
#ifdef ENABLED_FAHRENHEIT_SUPPORT
|
||||
uint16_t tipMeasurementToF(uint16_t raw);
|
||||
#endif
|
||||
void seekQC(int16_t Vx10, uint16_t divisor);
|
||||
void setCalibrationOffset(int16_t offSet);
|
||||
void setTipType(enum TipType tipType, uint8_t manualCalGain);
|
||||
uint32_t calculateTipR();
|
||||
int16_t calculateMaxVoltage(uint8_t useHP);
|
||||
void startQC(uint16_t divisor); // Tries to negotiate QC for highest voltage, must be run after
|
||||
// RToS
|
||||
// This will try for 12V, failing that 9V, failing that 5V
|
||||
// If input is over 12V returns -1
|
||||
// If the input is [5-12] Will return the value.
|
||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
|
||||
StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) ;
|
||||
void vApplicationIdleHook(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HARDWARE_H_ */
|
||||
/*
|
||||
* Pins.h
|
||||
*
|
||||
* Created on: 29 May 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
|
||||
#ifndef BSP_MINIWARE_PINS_H_
|
||||
#define BSP_MINIWARE_PINS_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
|
||||
|
||||
#define KEY_B_Pin GPIO_PIN_6
|
||||
#define KEY_B_GPIO_Port GPIOA
|
||||
#define TMP36_INPUT_Pin GPIO_PIN_7
|
||||
#define TMP36_INPUT_GPIO_Port GPIOA
|
||||
#define TMP36_ADC1_CHANNEL ADC_CHANNEL_7
|
||||
#define TIP_TEMP_Pin GPIO_PIN_0
|
||||
#define TIP_TEMP_GPIO_Port GPIOB
|
||||
#define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_8
|
||||
#define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_8
|
||||
#define VIN_Pin GPIO_PIN_1
|
||||
#define VIN_GPIO_Port GPIOB
|
||||
#define VIN_ADC1_CHANNEL ADC_CHANNEL_9
|
||||
#define VIN_ADC2_CHANNEL ADC_CHANNEL_9
|
||||
#define OLED_RESET_Pin GPIO_PIN_8
|
||||
#define OLED_RESET_GPIO_Port GPIOA
|
||||
#define KEY_A_Pin GPIO_PIN_9
|
||||
#define KEY_A_GPIO_Port GPIOA
|
||||
#define INT_Orientation_Pin GPIO_PIN_3
|
||||
#define INT_Orientation_GPIO_Port GPIOB
|
||||
#define PWM_Out_Pin GPIO_PIN_4
|
||||
#define PWM_Out_GPIO_Port GPIOB
|
||||
#define PWM_Out_CHANNEL TIM_CHANNEL_1
|
||||
#define PWM_Out_CCR
|
||||
#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
|
||||
|
||||
#else
|
||||
// TS80 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
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* BSP_MINIWARE_PINS_H_ */
|
||||
18
workspace/TS100/Core/BSP/Miniware/UnitSettings.h
Normal file
18
workspace/TS100/Core/BSP/Miniware/UnitSettings.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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_ */
|
||||
35
workspace/TS100/Core/Inc/Buttons.hpp
Normal file
35
workspace/TS100/Core/Inc/Buttons.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Buttons.h
|
||||
*
|
||||
* Created on: 29 May 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
#include "BSP.h"
|
||||
#ifndef INC_BUTTONS_H_
|
||||
#define INC_BUTTONS_H_
|
||||
|
||||
extern uint32_t lastButtonTime;
|
||||
|
||||
enum ButtonState {
|
||||
BUTTON_NONE = 0, /* No buttons pressed / < filter time*/
|
||||
BUTTON_F_SHORT = 1, /* User has pressed the front button*/
|
||||
BUTTON_B_SHORT = 2, /* User has pressed the back button*/
|
||||
BUTTON_F_LONG = 4, /* User is holding the front button*/
|
||||
BUTTON_B_LONG = 8, /* User is holding the back button*/
|
||||
BUTTON_BOTH = 16, /* User has pressed both buttons*/
|
||||
|
||||
/*
|
||||
* Note:
|
||||
* Pressed means press + release, we trigger on a full \__/ pulse
|
||||
* holding means it has gone low, and been low for longer than filter time
|
||||
*/
|
||||
};
|
||||
|
||||
//Returns what buttons are pressed (if any)
|
||||
ButtonState getButtonState();
|
||||
//Helpers
|
||||
void waitForButtonPressOrTimeout(uint32_t timeout);
|
||||
void waitForButtonPress();
|
||||
|
||||
|
||||
#endif /* INC_BUTTONS_H_ */
|
||||
@@ -1,44 +1,46 @@
|
||||
/*
|
||||
* FRToSI2C.hpp
|
||||
*
|
||||
* Created on: 14Apr.,2018
|
||||
* Author: Ralim
|
||||
*/
|
||||
|
||||
#ifndef FRTOSI2C_HPP_
|
||||
#define FRTOSI2C_HPP_
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
class FRToSI2C {
|
||||
public:
|
||||
|
||||
static void init(I2C_HandleTypeDef *i2chandle) {
|
||||
i2c = i2chandle;
|
||||
I2CSemaphore = nullptr;
|
||||
}
|
||||
|
||||
static void FRToSInit() {
|
||||
I2CSemaphore = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer);
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
}
|
||||
|
||||
static void CpltCallback(); //Normal Tx Callback
|
||||
|
||||
static void Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
|
||||
uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
|
||||
static void Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||
uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
|
||||
|
||||
static void Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
|
||||
static void I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data);
|
||||
static uint8_t I2C_RegisterRead(uint8_t address, uint8_t reg);
|
||||
|
||||
private:
|
||||
static I2C_HandleTypeDef *i2c;
|
||||
static void I2C1_ClearBusyFlagErratum();
|
||||
static SemaphoreHandle_t I2CSemaphore;
|
||||
static StaticSemaphore_t xSemaphoreBuffer;
|
||||
};
|
||||
|
||||
#endif /* FRTOSI2C_HPP_ */
|
||||
/*
|
||||
* FRToSI2C.hpp
|
||||
*
|
||||
* Created on: 14Apr.,2018
|
||||
* Author: Ralim
|
||||
*/
|
||||
|
||||
#ifndef FRTOSI2C_HPP_
|
||||
#define FRTOSI2C_HPP_
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
class FRToSI2C {
|
||||
public:
|
||||
|
||||
static void init(I2C_HandleTypeDef *i2chandle) {
|
||||
i2c = i2chandle;
|
||||
I2CSemaphore = nullptr;
|
||||
}
|
||||
|
||||
static void FRToSInit() {
|
||||
I2CSemaphore = xSemaphoreCreateBinaryStatic(&xSemaphoreBuffer);
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
}
|
||||
|
||||
static void CpltCallback(); //Normal Tx Callback
|
||||
|
||||
static bool Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
|
||||
uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
|
||||
static void Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||
uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
|
||||
//Returns true if device ACK's being addressed
|
||||
static bool probe(uint16_t DevAddress);
|
||||
|
||||
static void Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
|
||||
static void I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data);
|
||||
static uint8_t I2C_RegisterRead(uint8_t address, uint8_t reg);
|
||||
|
||||
private:
|
||||
static I2C_HandleTypeDef *i2c;
|
||||
static void I2C1_ClearBusyFlagErratum();
|
||||
static SemaphoreHandle_t I2CSemaphore;
|
||||
static StaticSemaphore_t xSemaphoreBuffer;
|
||||
};
|
||||
|
||||
#endif /* FRTOSI2C_HPP_ */
|
||||
|
||||
28
workspace/TS100/Core/Inc/FreeRTOSHooks.h
Normal file
28
workspace/TS100/Core/Inc/FreeRTOSHooks.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* FreeRTOSHooks.h
|
||||
*
|
||||
* Created on: 29 May 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
|
||||
#ifndef INC_FREERTOSHOOKS_H_
|
||||
#define INC_FREERTOSHOOKS_H_
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "cmsis_os.h"
|
||||
#include "unit.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// RToS
|
||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
|
||||
StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize);
|
||||
void vApplicationIdleHook(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* INC_FREERTOSHOOKS_H_ */
|
||||
@@ -10,11 +10,8 @@
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "FRToSI2C.hpp"
|
||||
#include "LIS2DH12_defines.hpp"
|
||||
#include "hardware.h"
|
||||
#include "BSP.h"
|
||||
|
||||
#ifdef MODEL_TS80
|
||||
#define LIS_ORI_FLIP
|
||||
#endif
|
||||
class LIS2DH12 {
|
||||
public:
|
||||
static bool detect();
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "MMA8652FC_defines.h"
|
||||
#include "FRToSI2C.hpp"
|
||||
#include "hardware.h"
|
||||
#include "BSP.h"
|
||||
|
||||
class MMA8652FC {
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#ifndef OLED_HPP_
|
||||
#define OLED_HPP_
|
||||
#include <hardware.h>
|
||||
#include <BSP.h>
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
21
workspace/TS100/Core/Inc/QC3.h
Normal file
21
workspace/TS100/Core/Inc/QC3.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* QC3.h
|
||||
*
|
||||
* Created on: 29 May 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
|
||||
#ifndef INC_QC3_H_
|
||||
#define INC_QC3_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void seekQC(int16_t Vx10, uint16_t divisor);
|
||||
void startQC(uint16_t divisor); // Tries to negotiate QC for highest voltage, must be run after
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INC_QC3_H_ */
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef SRC_TIPTHERMOMODEL_H_
|
||||
#define SRC_TIPTHERMOMODEL_H_
|
||||
#include "stdint.h"
|
||||
#include "hardware.h"
|
||||
#include "BSP.h"
|
||||
#include "unit.h"
|
||||
class TipThermoModel {
|
||||
public:
|
||||
@@ -1,38 +1,38 @@
|
||||
/*
|
||||
* gui.h
|
||||
*
|
||||
* Created on: 3Sep.,2017
|
||||
* Author: Ben V. Brown
|
||||
*/
|
||||
|
||||
#ifndef GUI_HPP_
|
||||
#define GUI_HPP_
|
||||
#include "Translation.h"
|
||||
#include "Settings.h"
|
||||
#include "hardware.h"
|
||||
|
||||
#define PRESS_ACCEL_STEP 3
|
||||
#define PRESS_ACCEL_INTERVAL_MIN 10
|
||||
#define PRESS_ACCEL_INTERVAL_MAX 30
|
||||
|
||||
|
||||
//GUI holds the menu structure and all its methods for the menu itself
|
||||
|
||||
//Declarations for all the methods for the settings menu (at end of this file)
|
||||
|
||||
//Wrapper for holding a function pointer
|
||||
typedef struct state_func_t {
|
||||
void (*func)(void);
|
||||
} state_func;
|
||||
|
||||
//Struct for holding the function pointers and descriptions
|
||||
typedef struct {
|
||||
const char *description;
|
||||
const state_func incrementHandler;
|
||||
const state_func draw;
|
||||
} menuitem;
|
||||
|
||||
void enterSettingsMenu();
|
||||
extern const menuitem rootSettingsMenu[];
|
||||
|
||||
#endif /* GUI_HPP_ */
|
||||
/*
|
||||
* gui.h
|
||||
*
|
||||
* Created on: 3Sep.,2017
|
||||
* Author: Ben V. Brown
|
||||
*/
|
||||
|
||||
#ifndef GUI_HPP_
|
||||
#define GUI_HPP_
|
||||
#include "Translation.h"
|
||||
#include "Settings.h"
|
||||
#include "BSP.h"
|
||||
|
||||
#define PRESS_ACCEL_STEP 3
|
||||
#define PRESS_ACCEL_INTERVAL_MIN 10
|
||||
#define PRESS_ACCEL_INTERVAL_MAX 30
|
||||
|
||||
//GUI holds the menu structure and all its methods for the menu itself
|
||||
|
||||
//Declarations for all the methods for the settings menu (at end of this file)
|
||||
|
||||
//Wrapper for holding a function pointer
|
||||
typedef struct state_func_t {
|
||||
void (*func)(void);
|
||||
} state_func;
|
||||
|
||||
//Struct for holding the function pointers and descriptions
|
||||
typedef struct {
|
||||
const char *description;
|
||||
const state_func incrementHandler;
|
||||
const state_func draw;
|
||||
} menuitem;
|
||||
|
||||
void enterSettingsMenu();
|
||||
void GUIDelay();
|
||||
extern const menuitem rootSettingsMenu[];
|
||||
|
||||
#endif /* GUI_HPP_ */
|
||||
|
||||
@@ -7,25 +7,7 @@
|
||||
extern uint8_t PCBVersion;
|
||||
extern uint32_t currentTempTargetDegC;
|
||||
extern bool settingsWereReset;
|
||||
enum ButtonState {
|
||||
BUTTON_NONE = 0, /* No buttons pressed / < filter time*/
|
||||
BUTTON_F_SHORT = 1, /* User has pressed the front button*/
|
||||
BUTTON_B_SHORT = 2, /* User has pressed the back button*/
|
||||
BUTTON_F_LONG = 4, /* User is holding the front button*/
|
||||
BUTTON_B_LONG = 8, /* User is holding the back button*/
|
||||
BUTTON_BOTH = 16, /* User has pressed both buttons*/
|
||||
|
||||
/*
|
||||
* Note:
|
||||
* Pressed means press + release, we trigger on a full \__/ pulse
|
||||
* holding means it has gone low, and been low for longer than filter time
|
||||
*/
|
||||
};
|
||||
|
||||
ButtonState getButtonState();
|
||||
void waitForButtonPressOrTimeout(uint32_t timeout);
|
||||
void waitForButtonPress();
|
||||
void GUIDelay();
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "stdint.h"
|
||||
#include <history.hpp>
|
||||
#include "hardware.h"
|
||||
#include "BSP.h"
|
||||
#include "expMovingAverage.h"
|
||||
#ifndef POWER_HPP_
|
||||
#define POWER_HPP_
|
||||
|
||||
115
workspace/TS100/Core/Src/Buttons.cpp
Normal file
115
workspace/TS100/Core/Src/Buttons.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Buttons.c
|
||||
*
|
||||
* Created on: 29 May 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
#include <Buttons.hpp>
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "gui.hpp"
|
||||
uint32_t lastButtonTime = 0;
|
||||
|
||||
ButtonState getButtonState() {
|
||||
/*
|
||||
* Read in the buttons and then determine if a state change needs to occur
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the previous state was 00 Then we want to latch the new state if
|
||||
* different & update time
|
||||
* If the previous state was !00 Then we want to search if we trigger long
|
||||
* press (buttons still down), or if release we trigger press
|
||||
* (downtime>filter)
|
||||
*/
|
||||
static uint8_t previousState = 0;
|
||||
static uint32_t previousStateChange = 0;
|
||||
const uint16_t timeout = 40;
|
||||
uint8_t currentState;
|
||||
currentState = (getButtonA()) << 0;
|
||||
currentState |= (getButtonB()) << 1;
|
||||
|
||||
if (currentState)
|
||||
lastButtonTime = xTaskGetTickCount();
|
||||
if (currentState == previousState) {
|
||||
if (currentState == 0)
|
||||
return BUTTON_NONE;
|
||||
if ((xTaskGetTickCount() - previousStateChange) > timeout) {
|
||||
// User has been holding the button down
|
||||
// We want to send a button is held message
|
||||
if (currentState == 0x01)
|
||||
return BUTTON_F_LONG;
|
||||
else if (currentState == 0x02)
|
||||
return BUTTON_B_LONG;
|
||||
else
|
||||
return BUTTON_NONE; // Both being held case, we dont long hold this
|
||||
} else
|
||||
return BUTTON_NONE;
|
||||
} else {
|
||||
// A change in button state has occurred
|
||||
ButtonState retVal = BUTTON_NONE;
|
||||
if (currentState) {
|
||||
// User has pressed a button down (nothing done on down)
|
||||
if (currentState != previousState) {
|
||||
// There has been a change in the button states
|
||||
// If there is a rising edge on one of the buttons from double press we
|
||||
// want to mask that out As users are having issues with not release
|
||||
// both at once
|
||||
if (previousState == 0x03)
|
||||
currentState = 0x03;
|
||||
}
|
||||
} else {
|
||||
// User has released buttons
|
||||
// If they previously had the buttons down we want to check if they were <
|
||||
// long hold and trigger a press
|
||||
if ((xTaskGetTickCount() - previousStateChange) < timeout) {
|
||||
// The user didn't hold the button for long
|
||||
// So we send button press
|
||||
|
||||
if (previousState == 0x01)
|
||||
retVal = BUTTON_F_SHORT;
|
||||
else if (previousState == 0x02)
|
||||
retVal = BUTTON_B_SHORT;
|
||||
else
|
||||
retVal = BUTTON_BOTH; // Both being held case
|
||||
}
|
||||
}
|
||||
previousState = currentState;
|
||||
previousStateChange = xTaskGetTickCount();
|
||||
return retVal;
|
||||
}
|
||||
return BUTTON_NONE;
|
||||
}
|
||||
|
||||
void waitForButtonPress() {
|
||||
// we are just lazy and sleep until user confirms button press
|
||||
// This also eats the button press event!
|
||||
ButtonState buttons = getButtonState();
|
||||
while (buttons) {
|
||||
buttons = getButtonState();
|
||||
GUIDelay();
|
||||
}
|
||||
while (!buttons) {
|
||||
buttons = getButtonState();
|
||||
GUIDelay();
|
||||
}
|
||||
}
|
||||
|
||||
void waitForButtonPressOrTimeout(uint32_t timeout) {
|
||||
timeout += xTaskGetTickCount();
|
||||
// calculate the exit point
|
||||
|
||||
ButtonState buttons = getButtonState();
|
||||
while (buttons) {
|
||||
buttons = getButtonState();
|
||||
GUIDelay();
|
||||
if (xTaskGetTickCount() > timeout)
|
||||
return;
|
||||
}
|
||||
while (!buttons) {
|
||||
buttons = getButtonState();
|
||||
GUIDelay();
|
||||
if (xTaskGetTickCount() > timeout)
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,189 +1,142 @@
|
||||
/*
|
||||
* FRToSI2C.cpp
|
||||
*
|
||||
* Created on: 14Apr.,2018
|
||||
* Author: Ralim
|
||||
*/
|
||||
#include "hardware.h"
|
||||
#include "FRToSI2C.hpp"
|
||||
#define I2CUSESDMA
|
||||
I2C_HandleTypeDef* FRToSI2C::i2c;
|
||||
SemaphoreHandle_t FRToSI2C::I2CSemaphore;
|
||||
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
|
||||
|
||||
void FRToSI2C::CpltCallback() {
|
||||
i2c->State = HAL_I2C_STATE_READY; // Force state reset (even if tx error)
|
||||
if (I2CSemaphore) {
|
||||
xSemaphoreGiveFromISR(I2CSemaphore, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
|
||||
uint16_t MemAddSize, uint8_t* pData, uint16_t Size) {
|
||||
|
||||
if (I2CSemaphore == NULL) {
|
||||
// no RToS, run blocking code
|
||||
HAL_I2C_Mem_Read(i2c, DevAddress, MemAddress, MemAddSize, pData, Size,
|
||||
5000);
|
||||
} else {
|
||||
// RToS is active, run threading
|
||||
// Get the mutex so we can use the I2C port
|
||||
// Wait up to 1 second for the mutex
|
||||
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
|
||||
#ifdef I2CUSESDMA
|
||||
if (HAL_I2C_Mem_Read(i2c, DevAddress, MemAddress, MemAddSize, pData,
|
||||
Size, 500) != HAL_OK) {
|
||||
|
||||
I2C1_ClearBusyFlagErratum();
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
}
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
#else
|
||||
|
||||
HAL_I2C_Mem_Read(i2c, DevAddress, MemAddress, MemAddSize, pData, Size,
|
||||
5000);
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
|
||||
Mem_Write(address, reg, I2C_MEMADD_SIZE_8BIT, &data, 1);
|
||||
}
|
||||
|
||||
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
|
||||
uint8_t tx_data[1];
|
||||
Mem_Read(add, reg, I2C_MEMADD_SIZE_8BIT, tx_data, 1);
|
||||
return tx_data[0];
|
||||
}
|
||||
void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||
uint16_t MemAddSize, uint8_t* pData, uint16_t Size) {
|
||||
|
||||
if (I2CSemaphore == NULL) {
|
||||
// no RToS, run blocking code
|
||||
HAL_I2C_Mem_Write(i2c, DevAddress, MemAddress, MemAddSize, pData, Size,
|
||||
5000);
|
||||
} else {
|
||||
// RToS is active, run threading
|
||||
// Get the mutex so we can use the I2C port
|
||||
// Wait up to 1 second for the mutex
|
||||
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
|
||||
#ifdef I2CUSESDMA
|
||||
if (HAL_I2C_Mem_Write(i2c, DevAddress, MemAddress, MemAddSize,
|
||||
pData, Size, 500) != HAL_OK) {
|
||||
|
||||
I2C1_ClearBusyFlagErratum();
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
}
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
#else
|
||||
if (HAL_I2C_Mem_Write(i2c, DevAddress, MemAddress, MemAddSize, pData,
|
||||
Size, 5000) != HAL_OK) {
|
||||
}
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t* pData, uint16_t Size) {
|
||||
if (I2CSemaphore == NULL) {
|
||||
// no RToS, run blocking code
|
||||
HAL_I2C_Master_Transmit(i2c, DevAddress, pData, Size, 5000);
|
||||
} else {
|
||||
// RToS is active, run threading
|
||||
// Get the mutex so we can use the I2C port
|
||||
// Wait up to 1 second for the mutex
|
||||
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
|
||||
#ifdef I2CUSESDMA
|
||||
|
||||
if (HAL_I2C_Master_Transmit_DMA(i2c, DevAddress, pData, Size)
|
||||
!= HAL_OK) {
|
||||
|
||||
I2C1_ClearBusyFlagErratum();
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
|
||||
}
|
||||
#else
|
||||
HAL_I2C_Master_Transmit(i2c, DevAddress, pData, Size, 5000);
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FRToSI2C::I2C1_ClearBusyFlagErratum() {
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
int timeout = 100;
|
||||
int timeout_cnt = 0;
|
||||
|
||||
// 1. Clear PE bit.
|
||||
i2c->Instance->CR1 &= ~(0x0001);
|
||||
/**I2C1 GPIO Configuration
|
||||
PB6 ------> I2C1_SCL
|
||||
PB7 ------> I2C1_SDA
|
||||
*/
|
||||
// 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.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
|
||||
GPIO_InitStruct.Pin = SCL_Pin;
|
||||
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
|
||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
||||
|
||||
GPIO_InitStruct.Pin = SDA_Pin;
|
||||
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
|
||||
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
|
||||
|
||||
while (GPIO_PIN_SET != HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin)) {
|
||||
//Move clock to release I2C
|
||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET);
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
||||
|
||||
timeout_cnt++;
|
||||
if (timeout_cnt > timeout)
|
||||
return;
|
||||
}
|
||||
|
||||
// 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
|
||||
GPIO_InitStruct.Pin = SCL_Pin;
|
||||
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = SDA_Pin;
|
||||
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
|
||||
|
||||
// 13. Set SWRST bit in I2Cx_CR1 register.
|
||||
i2c->Instance->CR1 |= 0x8000;
|
||||
|
||||
asm("nop");
|
||||
|
||||
// 14. Clear SWRST bit in I2Cx_CR1 register.
|
||||
i2c->Instance->CR1 &= ~0x8000;
|
||||
|
||||
asm("nop");
|
||||
|
||||
// 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
|
||||
i2c->Instance->CR1 |= 0x0001;
|
||||
|
||||
// Call initialization function.
|
||||
HAL_I2C_Init(i2c);
|
||||
}
|
||||
/*
|
||||
* FRToSI2C.cpp
|
||||
*
|
||||
* Created on: 14Apr.,2018
|
||||
* Author: Ralim
|
||||
*/
|
||||
#include "BSP.h"
|
||||
#include "FRToSI2C.hpp"
|
||||
#define I2CUSESDMA
|
||||
I2C_HandleTypeDef *FRToSI2C::i2c;
|
||||
SemaphoreHandle_t FRToSI2C::I2CSemaphore;
|
||||
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
|
||||
|
||||
void FRToSI2C::CpltCallback() {
|
||||
i2c->State = HAL_I2C_STATE_READY; // Force state reset (even if tx error)
|
||||
if (I2CSemaphore) {
|
||||
xSemaphoreGiveFromISR(I2CSemaphore, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
|
||||
uint16_t MemAddSize, uint8_t *pData, uint16_t Size) {
|
||||
|
||||
if (I2CSemaphore == NULL) {
|
||||
// no RToS, run blocking code
|
||||
HAL_I2C_Mem_Read(i2c, DevAddress, MemAddress, MemAddSize, pData, Size,
|
||||
5000);
|
||||
return true;
|
||||
} else {
|
||||
// RToS is active, run threading
|
||||
// Get the mutex so we can use the I2C port
|
||||
// Wait up to 1 second for the mutex
|
||||
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
|
||||
#ifdef I2CUSESDMA
|
||||
if (HAL_I2C_Mem_Read(i2c, DevAddress, MemAddress, MemAddSize, pData,
|
||||
Size, 500) != HAL_OK) {
|
||||
|
||||
I2C1_ClearBusyFlagErratum();
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
return false;
|
||||
} else {
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
|
||||
if (HAL_I2C_Mem_Read(i2c, DevAddress, MemAddress, MemAddSize, pData, Size,
|
||||
5000)==HAL_OK){
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
return true;
|
||||
}
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
return false;
|
||||
#endif
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
|
||||
Mem_Write(address, reg, I2C_MEMADD_SIZE_8BIT, &data, 1);
|
||||
}
|
||||
|
||||
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
|
||||
uint8_t tx_data[1];
|
||||
Mem_Read(add, reg, I2C_MEMADD_SIZE_8BIT, tx_data, 1);
|
||||
return tx_data[0];
|
||||
}
|
||||
void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||
uint16_t MemAddSize, uint8_t *pData, uint16_t Size) {
|
||||
|
||||
if (I2CSemaphore == NULL) {
|
||||
// no RToS, run blocking code
|
||||
HAL_I2C_Mem_Write(i2c, DevAddress, MemAddress, MemAddSize, pData, Size,
|
||||
5000);
|
||||
} else {
|
||||
// RToS is active, run threading
|
||||
// Get the mutex so we can use the I2C port
|
||||
// Wait up to 1 second for the mutex
|
||||
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
|
||||
#ifdef I2CUSESDMA
|
||||
if (HAL_I2C_Mem_Write(i2c, DevAddress, MemAddress, MemAddSize,
|
||||
pData, Size, 500) != HAL_OK) {
|
||||
|
||||
I2C1_ClearBusyFlagErratum();
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
}
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
#else
|
||||
if (HAL_I2C_Mem_Write(i2c, DevAddress, MemAddress, MemAddSize, pData,
|
||||
Size, 5000) != HAL_OK) {
|
||||
}
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
if (I2CSemaphore == NULL) {
|
||||
// no RToS, run blocking code
|
||||
HAL_I2C_Master_Transmit(i2c, DevAddress, pData, Size, 5000);
|
||||
} else {
|
||||
// RToS is active, run threading
|
||||
// Get the mutex so we can use the I2C port
|
||||
// Wait up to 1 second for the mutex
|
||||
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
|
||||
#ifdef I2CUSESDMA
|
||||
|
||||
if (HAL_I2C_Master_Transmit_DMA(i2c, DevAddress, pData, Size)
|
||||
!= HAL_OK) {
|
||||
|
||||
I2C1_ClearBusyFlagErratum();
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
|
||||
}
|
||||
#else
|
||||
HAL_I2C_Master_Transmit(i2c, DevAddress, pData, Size, 5000);
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool FRToSI2C::probe(uint16_t DevAddress) {
|
||||
uint8_t buffer[1];
|
||||
if (Mem_Read(DevAddress, 0, I2C_MEMADD_SIZE_8BIT, buffer, 1)) {
|
||||
//ACK'd
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FRToSI2C::I2C1_ClearBusyFlagErratum() {
|
||||
unstick_I2C();
|
||||
}
|
||||
|
||||
24
workspace/TS100/Core/Src/FreeRTOSHooks.c
Normal file
24
workspace/TS100/Core/Src/FreeRTOSHooks.c
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* FreeRTOSHooks.c
|
||||
*
|
||||
* Created on: 29 May 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
|
||||
#include "FreeRTOSHooks.h"
|
||||
#include "BSP.h"
|
||||
void vApplicationIdleHook(void) {
|
||||
resetWatchdog();
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
|
||||
static StaticTask_t xIdleTaskTCBBuffer;
|
||||
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];
|
||||
|
||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
|
||||
StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
|
||||
*ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
|
||||
*ppxIdleTaskStackBuffer = &xIdleStack[0];
|
||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||
/* place for user code */
|
||||
}
|
||||
@@ -19,14 +19,13 @@
|
||||
#include "TipThermoModel.h"
|
||||
#include "unit.h"
|
||||
#include "../../configuration.h"
|
||||
|
||||
#include "Buttons.hpp"
|
||||
extern uint8_t PCBVersion;
|
||||
// File local variables
|
||||
extern uint32_t currentTempTargetDegC;
|
||||
extern uint8_t accelInit;
|
||||
extern uint32_t lastMovementTime;
|
||||
extern int16_t idealQCVoltage;
|
||||
uint32_t lastButtonTime = 0;
|
||||
extern osThreadId GUITaskHandle;
|
||||
extern osThreadId MOVTaskHandle;
|
||||
extern osThreadId PIDTaskHandle;
|
||||
@@ -87,113 +86,8 @@ void gui_drawTipTemp(bool symbol) {
|
||||
}
|
||||
}
|
||||
}
|
||||
ButtonState getButtonState() {
|
||||
/*
|
||||
* Read in the buttons and then determine if a state change needs to occur
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the previous state was 00 Then we want to latch the new state if
|
||||
* different & update time
|
||||
* If the previous state was !00 Then we want to search if we trigger long
|
||||
* press (buttons still down), or if release we trigger press
|
||||
* (downtime>filter)
|
||||
*/
|
||||
static uint8_t previousState = 0;
|
||||
static uint32_t previousStateChange = 0;
|
||||
const uint16_t timeout = 40;
|
||||
uint8_t currentState;
|
||||
currentState = (
|
||||
HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ?
|
||||
1 : 0) << 0;
|
||||
currentState |= (
|
||||
HAL_GPIO_ReadPin(KEY_B_GPIO_Port, KEY_B_Pin) == GPIO_PIN_RESET ?
|
||||
1 : 0) << 1;
|
||||
|
||||
if (currentState)
|
||||
lastButtonTime = xTaskGetTickCount();
|
||||
if (currentState == previousState) {
|
||||
if (currentState == 0)
|
||||
return BUTTON_NONE;
|
||||
if ((xTaskGetTickCount() - previousStateChange) > timeout) {
|
||||
// User has been holding the button down
|
||||
// We want to send a buttong is held message
|
||||
if (currentState == 0x01)
|
||||
return BUTTON_F_LONG;
|
||||
else if (currentState == 0x02)
|
||||
return BUTTON_B_LONG;
|
||||
else
|
||||
return BUTTON_NONE; // Both being held case, we dont long hold this
|
||||
} else
|
||||
return BUTTON_NONE;
|
||||
} else {
|
||||
// A change in button state has occurred
|
||||
ButtonState retVal = BUTTON_NONE;
|
||||
if (currentState) {
|
||||
// User has pressed a button down (nothing done on down)
|
||||
if (currentState != previousState) {
|
||||
// There has been a change in the button states
|
||||
// If there is a rising edge on one of the buttons from double press we
|
||||
// want to mask that out As users are having issues with not release
|
||||
// both at once
|
||||
if (previousState == 0x03)
|
||||
currentState = 0x03;
|
||||
}
|
||||
} else {
|
||||
// User has released buttons
|
||||
// If they previously had the buttons down we want to check if they were <
|
||||
// long hold and trigger a press
|
||||
if ((xTaskGetTickCount() - previousStateChange) < timeout) {
|
||||
// The user didn't hold the button for long
|
||||
// So we send button press
|
||||
|
||||
if (previousState == 0x01)
|
||||
retVal = BUTTON_F_SHORT;
|
||||
else if (previousState == 0x02)
|
||||
retVal = BUTTON_B_SHORT;
|
||||
else
|
||||
retVal = BUTTON_BOTH; // Both being held case
|
||||
}
|
||||
}
|
||||
previousState = currentState;
|
||||
previousStateChange = xTaskGetTickCount();
|
||||
return retVal;
|
||||
}
|
||||
return BUTTON_NONE;
|
||||
}
|
||||
|
||||
void waitForButtonPress() {
|
||||
// we are just lazy and sleep until user confirms button press
|
||||
// This also eats the button press event!
|
||||
ButtonState buttons = getButtonState();
|
||||
while (buttons) {
|
||||
buttons = getButtonState();
|
||||
GUIDelay();
|
||||
}
|
||||
while (!buttons) {
|
||||
buttons = getButtonState();
|
||||
GUIDelay();
|
||||
}
|
||||
}
|
||||
|
||||
void waitForButtonPressOrTimeout(uint32_t timeout) {
|
||||
timeout += xTaskGetTickCount();
|
||||
// calculate the exit point
|
||||
|
||||
ButtonState buttons = getButtonState();
|
||||
while (buttons) {
|
||||
buttons = getButtonState();
|
||||
GUIDelay();
|
||||
if (xTaskGetTickCount() > timeout)
|
||||
return;
|
||||
}
|
||||
while (!buttons) {
|
||||
buttons = getButtonState();
|
||||
GUIDelay();
|
||||
if (xTaskGetTickCount() > timeout)
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef MODEL_TS100
|
||||
// returns true if undervoltage has occured
|
||||
static bool checkVoltageForExit() {
|
||||
|
||||
@@ -15,17 +15,16 @@ typedef struct {
|
||||
const uint8_t value;
|
||||
} LIS_REG;
|
||||
|
||||
static const LIS_REG i2c_registers[] =
|
||||
{ { LIS_CTRL_REG1, 0x17 }, // 25Hz
|
||||
{ LIS_CTRL_REG2, 0b00001000 }, // Highpass filter off
|
||||
{ LIS_CTRL_REG3, 0b01100000 }, // Setup interrupt pins
|
||||
{ LIS_CTRL_REG4, 0b00001000 }, // Block update mode off, HR on
|
||||
{ LIS_CTRL_REG5, 0b00000010 }, { LIS_CTRL_REG6, 0b01100010 },
|
||||
//Basically setup the unit to run, and enable 4D orientation detection
|
||||
{ LIS_INT2_CFG, 0b01111110 }, //setup for movement detection
|
||||
{ LIS_INT2_THS, 0x28 }, { LIS_INT2_DURATION, 64 }, {
|
||||
LIS_INT1_CFG, 0b01111110 }, { LIS_INT1_THS, 0x28 }, {
|
||||
LIS_INT1_DURATION, 64 } };
|
||||
static const LIS_REG i2c_registers[] = { { LIS_CTRL_REG1, 0x17 }, // 25Hz
|
||||
{ LIS_CTRL_REG2, 0b00001000 }, // Highpass filter off
|
||||
{ LIS_CTRL_REG3, 0b01100000 }, // Setup interrupt pins
|
||||
{ LIS_CTRL_REG4, 0b00001000 }, // Block update mode off, HR on
|
||||
{ LIS_CTRL_REG5, 0b00000010 }, { LIS_CTRL_REG6, 0b01100010 },
|
||||
//Basically setup the unit to run, and enable 4D orientation detection
|
||||
{ LIS_INT2_CFG, 0b01111110 }, //setup for movement detection
|
||||
{ LIS_INT2_THS, 0x28 }, { LIS_INT2_DURATION, 64 }, {
|
||||
LIS_INT1_CFG, 0b01111110 }, { LIS_INT1_THS, 0x28 }, {
|
||||
LIS_INT1_DURATION, 64 } };
|
||||
|
||||
void LIS2DH12::initalize() {
|
||||
for (size_t index = 0;
|
||||
@@ -49,12 +48,5 @@ void LIS2DH12::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
||||
}
|
||||
|
||||
bool LIS2DH12::detect() {
|
||||
uint8_t buffer[1];
|
||||
if (HAL_I2C_Mem_Read(&hi2c1, 25 << 1, 0x0F, I2C_MEMADD_SIZE_8BIT, buffer, 1,
|
||||
1000) == HAL_OK) {
|
||||
//ACK'd
|
||||
return true;
|
||||
}
|
||||
//NAK'd
|
||||
return false;
|
||||
return FRToSI2C::probe(LIS2DH_I2C_ADDRESS);
|
||||
}
|
||||
|
||||
@@ -84,12 +84,5 @@ void MMA8652FC::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
||||
}
|
||||
|
||||
bool MMA8652FC::detect() {
|
||||
uint8_t buffer[1];
|
||||
if (HAL_I2C_Mem_Read(&hi2c1, 29 << 1, 0x0F, I2C_MEMADD_SIZE_8BIT, buffer, 1,
|
||||
1000) == HAL_OK) {
|
||||
//The device ACK'd
|
||||
return true;
|
||||
}
|
||||
//NAK'd
|
||||
return false;
|
||||
return FRToSI2C::probe(MMA8652FC_I2C_ADDRESS);
|
||||
}
|
||||
|
||||
@@ -95,10 +95,6 @@ void OLED::initialize() {
|
||||
displayOffset = 0;
|
||||
memcpy(&screenBuffer[0], &REFRESH_COMMANDS[0], sizeof(REFRESH_COMMANDS));
|
||||
|
||||
HAL_Delay(50);
|
||||
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
|
||||
HAL_Delay(50);
|
||||
|
||||
// Set the display to be ON once the settings block is sent and send the
|
||||
// initialisation data to the OLED.
|
||||
|
||||
|
||||
203
workspace/TS100/Core/Src/QC3.c
Normal file
203
workspace/TS100/Core/Src/QC3.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* QC3.c
|
||||
*
|
||||
* Created on: 29 May 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
|
||||
|
||||
//Quick charge 3.0 supporting functions
|
||||
|
||||
|
||||
|
||||
#ifdef MODEL_TS80
|
||||
void DPlusZero_Six() {
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); // pull down D+
|
||||
}
|
||||
void DNegZero_Six() {
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
|
||||
}
|
||||
void DPlusThree_Three() {
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET); // pull up D+
|
||||
}
|
||||
void DNegThree_Three() {
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void QC_Seek9V() {
|
||||
DNegZero_Six();
|
||||
DPlusThree_Three();
|
||||
}
|
||||
void QC_Seek12V() {
|
||||
DNegZero_Six();
|
||||
DPlusZero_Six();
|
||||
}
|
||||
void QC_Seek20V() {
|
||||
DNegThree_Three();
|
||||
DPlusThree_Three();
|
||||
}
|
||||
void QC_SeekContMode() {
|
||||
DNegThree_Three();
|
||||
DPlusZero_Six();
|
||||
}
|
||||
void QC_SeekContPlus() {
|
||||
QC_SeekContMode();
|
||||
vTaskDelay(3);
|
||||
QC_Seek20V();
|
||||
vTaskDelay(1);
|
||||
QC_SeekContMode();
|
||||
}
|
||||
void QC_SeekContNeg() {
|
||||
QC_SeekContMode();
|
||||
vTaskDelay(3);
|
||||
QC_Seek12V();
|
||||
vTaskDelay(1);
|
||||
QC_SeekContMode();
|
||||
}
|
||||
uint8_t QCMode = 0;
|
||||
uint8_t QCTries = 0;
|
||||
void seekQC(int16_t Vx10, uint16_t divisor) {
|
||||
if (QCMode == 5)
|
||||
startQC(divisor);
|
||||
if (QCMode == 0)
|
||||
return; // NOT connected to a QC Charger
|
||||
|
||||
if (Vx10 < 45)
|
||||
return;
|
||||
if (xTaskGetTickCount() < 100)
|
||||
return;
|
||||
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
|
||||
int16_t vStart = getInputVoltageX10(divisor, 1);
|
||||
int difference = Vx10 - vStart;
|
||||
|
||||
// 2. calculate ideal steps (0.2V changes)
|
||||
|
||||
int steps = difference / 2;
|
||||
if (QCMode == 3) {
|
||||
if (steps > -2 && steps < 2)
|
||||
return; // dont bother with small steps
|
||||
while (steps < 0) {
|
||||
QC_SeekContNeg();
|
||||
vTaskDelay(3);
|
||||
steps++;
|
||||
}
|
||||
while (steps > 0) {
|
||||
QC_SeekContPlus();
|
||||
vTaskDelay(3);
|
||||
steps--;
|
||||
}
|
||||
vTaskDelay(10);
|
||||
}
|
||||
#ifdef ENABLE_QC2
|
||||
// Re-measure
|
||||
/* Disabled due to nothing to test and code space of around 1k*/
|
||||
steps = vStart - getInputVoltageX10(divisor, 1);
|
||||
if (steps < 0)
|
||||
steps = -steps;
|
||||
if (steps > 4) {
|
||||
// No continuous mode, so QC2
|
||||
QCMode = 2;
|
||||
// Goto nearest
|
||||
if (Vx10 > 110) {
|
||||
// request 12V
|
||||
// D- = 0.6V, D+ = 0.6V
|
||||
// Clamp PB3
|
||||
QC_Seek12V();
|
||||
|
||||
} else {
|
||||
// request 9V
|
||||
QC_Seek9V();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// Must be called after FreeRToS Starts
|
||||
void startQC(uint16_t divisor) {
|
||||
// Pre check that the input could be >5V already, and if so, dont both
|
||||
// negotiating as someone is feeding in hv
|
||||
uint16_t vin = getInputVoltageX10(divisor, 1);
|
||||
if (vin > 100) {
|
||||
QCMode = 1; // Already at 12V, user has probably over-ridden this
|
||||
return;
|
||||
}
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
//Turn off output mode on pins that we can
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
// Tries to negotiate QC for 9V
|
||||
// This is a multiple step process.
|
||||
// 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
|
||||
// D-
|
||||
DPlusZero_Six();
|
||||
|
||||
// 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 (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET) {
|
||||
enteredQC = 1;
|
||||
}
|
||||
if (i == 140) {
|
||||
//For some marginal QC chargers, we try adding a pulldown
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
if (enteredQC) {
|
||||
// We have a QC capable charger
|
||||
QC_Seek9V();
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "TipThermoModel.h"
|
||||
#include "Settings.h"
|
||||
#include "hardware.h"
|
||||
#include "BSP.h"
|
||||
#include "../../configuration.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "string.h"
|
||||
#include "unit.h"
|
||||
#include "../../configuration.h"
|
||||
|
||||
#include "Buttons.hpp"
|
||||
extern uint32_t lastButtonTime;
|
||||
void gui_Menu(const menuitem *menu);
|
||||
|
||||
|
||||
@@ -1,393 +0,0 @@
|
||||
/*
|
||||
* hardware.c
|
||||
*
|
||||
* Created on: 2Sep.,2017
|
||||
* Author: Ben V. Brown
|
||||
*/
|
||||
|
||||
// These are all the functions for interacting with the hardware
|
||||
#include "hardware.h"
|
||||
#include "history.hpp"
|
||||
volatile uint16_t PWMSafetyTimer = 0;
|
||||
|
||||
uint16_t getHandleTemperature() {
|
||||
// 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
|
||||
// example) STM32 = 4096 count @ 3.3V input -> But We oversample by 32/(2^2) =
|
||||
// 8 times oversampling Therefore 32768 is the 3.3V input, so 0.1007080078125
|
||||
// mV per count So we need to subtract an offset of 0.5V to center on 0C
|
||||
// (4964.8 counts)
|
||||
//
|
||||
int32_t result = getADC(0);
|
||||
result -= 4965; // remove 0.5V offset
|
||||
// 10mV per C
|
||||
// 99.29 counts per Deg C above 0C
|
||||
result *= 100;
|
||||
result /= 993;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t getTipInstantTemperature() {
|
||||
uint16_t sum = 0; // 12 bit readings * 8 -> 15 bits
|
||||
uint16_t readings[8];
|
||||
//Looking to reject the highest outlier readings.
|
||||
//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
|
||||
readings[0] = hadc1.Instance->JDR1;
|
||||
readings[1] = hadc1.Instance->JDR2;
|
||||
readings[2] = hadc1.Instance->JDR3;
|
||||
readings[3] = hadc1.Instance->JDR4;
|
||||
readings[4] = hadc2.Instance->JDR1;
|
||||
readings[5] = hadc2.Instance->JDR2;
|
||||
readings[6] = hadc2.Instance->JDR3;
|
||||
readings[7] = hadc2.Instance->JDR4;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
sum += readings[i];
|
||||
}
|
||||
return sum; // 8x over sample
|
||||
}
|
||||
|
||||
//2 second filter (ADC is PID_TIM_HZ Hz)
|
||||
history<uint16_t, PID_TIM_HZ> rawTempFilter = { { 0 }, 0, 0 };
|
||||
|
||||
uint16_t getTipRawTemp(uint8_t refresh) {
|
||||
if (refresh) {
|
||||
uint16_t lastSample = getTipInstantTemperature();
|
||||
rawTempFilter.update(lastSample);
|
||||
return lastSample;
|
||||
} else {
|
||||
return rawTempFilter.average();
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
|
||||
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
|
||||
// Therefore we can divide down from there
|
||||
// Multiplying ADC max by 4 for additional calibration options,
|
||||
// ideal term is 467
|
||||
#ifdef MODEL_TS100
|
||||
#define BATTFILTERDEPTH 32
|
||||
#else
|
||||
#define BATTFILTERDEPTH 8
|
||||
|
||||
#endif
|
||||
static uint8_t preFillneeded = 10;
|
||||
static uint32_t samples[BATTFILTERDEPTH];
|
||||
static uint8_t index = 0;
|
||||
if (preFillneeded) {
|
||||
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
|
||||
samples[i] = getADC(1);
|
||||
preFillneeded--;
|
||||
}
|
||||
if (sample) {
|
||||
samples[index] = getADC(1);
|
||||
index = (index + 1) % BATTFILTERDEPTH;
|
||||
}
|
||||
uint32_t sum = 0;
|
||||
|
||||
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
|
||||
sum += samples[i];
|
||||
|
||||
sum /= BATTFILTERDEPTH;
|
||||
return sum * 4 / divisor;
|
||||
}
|
||||
#ifdef MODEL_TS80
|
||||
void DPlusZero_Six() {
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); // pull down D+
|
||||
}
|
||||
void DNegZero_Six() {
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
|
||||
}
|
||||
void DPlusThree_Three() {
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET); // pull up D+
|
||||
}
|
||||
void DNegThree_Three() {
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void QC_Seek9V() {
|
||||
DNegZero_Six();
|
||||
DPlusThree_Three();
|
||||
}
|
||||
void QC_Seek12V() {
|
||||
DNegZero_Six();
|
||||
DPlusZero_Six();
|
||||
}
|
||||
void QC_Seek20V() {
|
||||
DNegThree_Three();
|
||||
DPlusThree_Three();
|
||||
}
|
||||
void QC_SeekContMode() {
|
||||
DNegThree_Three();
|
||||
DPlusZero_Six();
|
||||
}
|
||||
void QC_SeekContPlus() {
|
||||
QC_SeekContMode();
|
||||
vTaskDelay(3);
|
||||
QC_Seek20V();
|
||||
vTaskDelay(1);
|
||||
QC_SeekContMode();
|
||||
}
|
||||
void QC_SeekContNeg() {
|
||||
QC_SeekContMode();
|
||||
vTaskDelay(3);
|
||||
QC_Seek12V();
|
||||
vTaskDelay(1);
|
||||
QC_SeekContMode();
|
||||
}
|
||||
uint8_t QCMode = 0;
|
||||
uint8_t QCTries = 0;
|
||||
void seekQC(int16_t Vx10, uint16_t divisor) {
|
||||
if (QCMode == 5)
|
||||
startQC(divisor);
|
||||
if (QCMode == 0)
|
||||
return; // NOT connected to a QC Charger
|
||||
|
||||
if (Vx10 < 45)
|
||||
return;
|
||||
if (xTaskGetTickCount() < 100)
|
||||
return;
|
||||
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
|
||||
int16_t vStart = getInputVoltageX10(divisor, 1);
|
||||
int difference = Vx10 - vStart;
|
||||
|
||||
// 2. calculate ideal steps (0.2V changes)
|
||||
|
||||
int steps = difference / 2;
|
||||
if (QCMode == 3) {
|
||||
if (steps > -2 && steps < 2)
|
||||
return; // dont bother with small steps
|
||||
while (steps < 0) {
|
||||
QC_SeekContNeg();
|
||||
vTaskDelay(3);
|
||||
steps++;
|
||||
}
|
||||
while (steps > 0) {
|
||||
QC_SeekContPlus();
|
||||
vTaskDelay(3);
|
||||
steps--;
|
||||
}
|
||||
vTaskDelay(10);
|
||||
}
|
||||
#ifdef ENABLE_QC2
|
||||
// Re-measure
|
||||
/* Disabled due to nothing to test and code space of around 1k*/
|
||||
steps = vStart - getInputVoltageX10(divisor, 1);
|
||||
if (steps < 0)
|
||||
steps = -steps;
|
||||
if (steps > 4) {
|
||||
// No continuous mode, so QC2
|
||||
QCMode = 2;
|
||||
// Goto nearest
|
||||
if (Vx10 > 110) {
|
||||
// request 12V
|
||||
// D- = 0.6V, D+ = 0.6V
|
||||
// Clamp PB3
|
||||
QC_Seek12V();
|
||||
|
||||
} else {
|
||||
// request 9V
|
||||
QC_Seek9V();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// Must be called after FreeRToS Starts
|
||||
void startQC(uint16_t divisor) {
|
||||
// Pre check that the input could be >5V already, and if so, dont both
|
||||
// negotiating as someone is feeding in hv
|
||||
uint16_t vin = getInputVoltageX10(divisor, 1);
|
||||
if (vin > 100) {
|
||||
QCMode = 1; // Already at 12V, user has probably over-ridden this
|
||||
return;
|
||||
}
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
//Turn off output mode on pins that we can
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
// Tries to negotiate QC for 9V
|
||||
// This is a multiple step process.
|
||||
// 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
|
||||
// D-
|
||||
DPlusZero_Six();
|
||||
|
||||
// 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 (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET) {
|
||||
enteredQC = 1;
|
||||
}
|
||||
if (i == 140) {
|
||||
//For some marginal QC chargers, we try adding a pulldown
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
if (enteredQC) {
|
||||
// We have a QC capable charger
|
||||
QC_Seek9V();
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
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;
|
||||
}
|
||||
|
||||
static unsigned int sqrt32(unsigned long n) {
|
||||
unsigned int c = 0x8000;
|
||||
unsigned int g = 0x8000;
|
||||
|
||||
for (;;) {
|
||||
if (g * g > n)
|
||||
g ^= c;
|
||||
c >>= 1;
|
||||
if (c == 0)
|
||||
return g;
|
||||
g |= c;
|
||||
}
|
||||
}
|
||||
int16_t calculateMaxVoltage(uint8_t useHP) {
|
||||
// This measures the tip resistance, then it calculates the appropriate
|
||||
// voltage To stay under ~18W. Mosfet is "9A", so no issues there
|
||||
// QC3.0 supports up to 18W, which is 2A @9V and 1.5A @12V
|
||||
uint32_t milliOhms = 4500;
|
||||
// Check no tip
|
||||
if (milliOhms > 10000)
|
||||
return -1;
|
||||
//Because of tolerance, if a user has asked for the higher power mode, then just goto 12V and call it a day
|
||||
if (useHP)
|
||||
return 120;
|
||||
//
|
||||
// V = sqrt(18W*R)
|
||||
// Convert this to sqrt(18W)*sqrt(milli ohms)*sqrt(1/1000)
|
||||
|
||||
uint32_t Vx = sqrt32(milliOhms);
|
||||
if (useHP)
|
||||
Vx *= 1549; //sqrt(24)*sqrt(1/1000)*10000
|
||||
else
|
||||
Vx *= 1342; // sqrt(18) * sqrt(1/1000)*10000
|
||||
|
||||
// Round to nearest 200mV,
|
||||
// So divide by 100 to start, to get in Vxx
|
||||
Vx /= 100;
|
||||
if (Vx % 10 >= 5)
|
||||
Vx += 10;
|
||||
Vx /= 10;
|
||||
// Round to nearest increment of 2
|
||||
if (Vx % 2 == 1)
|
||||
Vx++;
|
||||
//Because of how bad the tolerance is on detecting the tip resistance is
|
||||
//Its more functional to bin this
|
||||
if (Vx < 90)
|
||||
Vx = 90;
|
||||
else if (Vx >= 105)
|
||||
Vx = 120;
|
||||
return Vx;
|
||||
}
|
||||
|
||||
#endif
|
||||
volatile uint8_t pendingPWM = 0;
|
||||
|
||||
void setTipPWM(uint8_t pulse) {
|
||||
PWMSafetyTimer = 10; // This is decremented in the handler for PWM so that the tip pwm is
|
||||
// disabled if the PID task is not scheduled often enough.
|
||||
|
||||
pendingPWM = pulse;
|
||||
}
|
||||
|
||||
// These are called by the HAL after the corresponding events from the system
|
||||
// timers.
|
||||
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
||||
// Period has elapsed
|
||||
if (htim->Instance == TIM2) {
|
||||
// we want to turn on the output again
|
||||
PWMSafetyTimer--;
|
||||
// We decrement this safety value so that lockups in the
|
||||
// scheduler will not cause the PWM to become locked in an
|
||||
// active driving state.
|
||||
// While we could assume this could never happen, its a small price for
|
||||
// increased safety
|
||||
htim2.Instance->CCR4 = pendingPWM;
|
||||
if (htim2.Instance->CCR4 && PWMSafetyTimer) {
|
||||
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
|
||||
} else {
|
||||
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
|
||||
}
|
||||
} else if (htim->Instance == TIM1) {
|
||||
// STM uses this for internal functions as a counter for timeouts
|
||||
HAL_IncTick();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) {
|
||||
// This was a when the PWM for the output has timed out
|
||||
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) {
|
||||
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
|
||||
}
|
||||
}
|
||||
|
||||
void vApplicationIdleHook(void) {
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
|
||||
static StaticTask_t xIdleTaskTCBBuffer;
|
||||
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];
|
||||
|
||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
|
||||
StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
|
||||
*ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
|
||||
*ppxIdleTaskStackBuffer = &xIdleStack[0];
|
||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||
/* place for user code */
|
||||
}
|
||||
/* USER CODE END GET_IDLE_TASK_MEMORY */
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <power.hpp>
|
||||
#include <Settings.h>
|
||||
#include <hardware.h>
|
||||
#include <BSP.h>
|
||||
|
||||
const uint16_t powerPWM = 255;
|
||||
const uint16_t totalPWM = 255 + 17; //htim2.Init.Period, the full PWM cycle
|
||||
|
||||
Reference in New Issue
Block a user