Formatting the C/C++ files
This commit is contained in:
@@ -1,159 +1,156 @@
|
|||||||
//BSP mapping functions
|
// BSP mapping functions
|
||||||
|
|
||||||
#include <IRQ.h>
|
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
|
#include "I2C_Wrapper.hpp"
|
||||||
|
#include "Model_Config.h"
|
||||||
|
#include "Pins.h"
|
||||||
#include "Setup.h"
|
#include "Setup.h"
|
||||||
#include "history.hpp"
|
#include "history.hpp"
|
||||||
#include "Pins.h"
|
|
||||||
#include "main.hpp"
|
#include "main.hpp"
|
||||||
#include "history.hpp"
|
#include <IRQ.h>
|
||||||
#include "Model_Config.h"
|
|
||||||
#include "I2C_Wrapper.hpp"
|
|
||||||
volatile uint16_t PWMSafetyTimer = 0;
|
volatile uint16_t PWMSafetyTimer = 0;
|
||||||
volatile uint8_t pendingPWM = 0;
|
volatile uint8_t pendingPWM = 0;
|
||||||
|
|
||||||
const uint16_t powerPWM = 255;
|
const uint16_t powerPWM = 255;
|
||||||
static const uint8_t holdoffTicks = 14; // delay of 8 ms
|
static const uint8_t holdoffTicks = 14; // delay of 8 ms
|
||||||
static const uint8_t tempMeasureTicks = 14;
|
static const uint8_t tempMeasureTicks = 14;
|
||||||
|
|
||||||
uint16_t totalPWM; //htim2.Init.Period, the full PWM cycle
|
uint16_t totalPWM; // htim2.Init.Period, the full PWM cycle
|
||||||
|
|
||||||
static bool fastPWM;
|
static bool fastPWM;
|
||||||
|
|
||||||
//2 second filter (ADC is PID_TIM_HZ Hz)
|
// 2 second filter (ADC is PID_TIM_HZ Hz)
|
||||||
history<uint16_t, PID_TIM_HZ> rawTempFilter = { { 0 }, 0, 0 };
|
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
|
#ifdef TEMP_NTC
|
||||||
//Lookup table for the NTC
|
// Lookup table for the NTC
|
||||||
//Stored as ADCReading,Temp in degC
|
// Stored as ADCReading,Temp in degC
|
||||||
static const uint16_t NTCHandleLookup[] = {
|
static const uint16_t NTCHandleLookup[] = {
|
||||||
//ADC Reading , Temp in C
|
// ADC Reading , Temp in C
|
||||||
29189, 0, //
|
29189, 0, //
|
||||||
29014, 1, //
|
29014, 1, //
|
||||||
28832, 2, //
|
28832, 2, //
|
||||||
28644, 3, //
|
28644, 3, //
|
||||||
28450, 4, //
|
28450, 4, //
|
||||||
28249, 5, //
|
28249, 5, //
|
||||||
28042, 6, //
|
28042, 6, //
|
||||||
27828, 7, //
|
27828, 7, //
|
||||||
27607, 8, //
|
27607, 8, //
|
||||||
27380, 9, //
|
27380, 9, //
|
||||||
27146, 10, //
|
27146, 10, //
|
||||||
26906, 11, //
|
26906, 11, //
|
||||||
26660, 12, //
|
26660, 12, //
|
||||||
26407, 13, //
|
26407, 13, //
|
||||||
26147, 14, //
|
26147, 14, //
|
||||||
25882, 15, //
|
25882, 15, //
|
||||||
25610, 16, //
|
25610, 16, //
|
||||||
25332, 17, //
|
25332, 17, //
|
||||||
25049, 18, //
|
25049, 18, //
|
||||||
24759, 19, //
|
24759, 19, //
|
||||||
24465, 20, //
|
24465, 20, //
|
||||||
24164, 21, //
|
24164, 21, //
|
||||||
23859, 22, //
|
23859, 22, //
|
||||||
23549, 23, //
|
23549, 23, //
|
||||||
23234, 24, //
|
23234, 24, //
|
||||||
22915, 25, //
|
22915, 25, //
|
||||||
22591, 26, //
|
22591, 26, //
|
||||||
22264, 27, //
|
22264, 27, //
|
||||||
21933, 28, //
|
21933, 28, //
|
||||||
21599, 29, //
|
21599, 29, //
|
||||||
21261, 30, //
|
21261, 30, //
|
||||||
20921, 31, //
|
20921, 31, //
|
||||||
20579, 32, //
|
20579, 32, //
|
||||||
20234, 33, //
|
20234, 33, //
|
||||||
19888, 34, //
|
19888, 34, //
|
||||||
19541, 35, //
|
19541, 35, //
|
||||||
19192, 36, //
|
19192, 36, //
|
||||||
18843, 37, //
|
18843, 37, //
|
||||||
18493, 38, //
|
18493, 38, //
|
||||||
18143, 39, //
|
18143, 39, //
|
||||||
17793, 40, //
|
17793, 40, //
|
||||||
17444, 41, //
|
17444, 41, //
|
||||||
17096, 42, //
|
17096, 42, //
|
||||||
16750, 43, //
|
16750, 43, //
|
||||||
16404, 44, //
|
16404, 44, //
|
||||||
16061, 45, //
|
16061, 45, //
|
||||||
// 15719, 46, //
|
// 15719, 46, //
|
||||||
// 15380, 47, //
|
// 15380, 47, //
|
||||||
// 15044, 48, //
|
// 15044, 48, //
|
||||||
// 14710, 49, //
|
// 14710, 49, //
|
||||||
// 14380, 50, //
|
// 14380, 50, //
|
||||||
// 14053, 51, //
|
// 14053, 51, //
|
||||||
// 13729, 52, //
|
// 13729, 52, //
|
||||||
// 13410, 53, //
|
// 13410, 53, //
|
||||||
// 13094, 54, //
|
// 13094, 54, //
|
||||||
// 12782, 55, //
|
// 12782, 55, //
|
||||||
// 12475, 56, //
|
// 12475, 56, //
|
||||||
// 12172, 57, //
|
// 12172, 57, //
|
||||||
// 11874, 58, //
|
// 11874, 58, //
|
||||||
// 11580, 59, //
|
// 11580, 59, //
|
||||||
// 11292, 60, //
|
// 11292, 60, //
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint16_t getHandleTemperature() {
|
uint16_t getHandleTemperature() {
|
||||||
#ifdef TEMP_NTC
|
#ifdef TEMP_NTC
|
||||||
//TS80P uses 100k NTC resistors instead
|
// TS80P uses 100k NTC resistors instead
|
||||||
//NTCG104EF104FT1X from TDK
|
// NTCG104EF104FT1X from TDK
|
||||||
//For now not doing interpolation
|
// For now not doing interpolation
|
||||||
int32_t result = getADC(0);
|
int32_t result = getADC(0);
|
||||||
for (uint32_t i = 0; i < (sizeof(NTCHandleLookup) / (2 * sizeof(uint16_t))); i++) {
|
for (uint32_t i = 0; i < (sizeof(NTCHandleLookup) / (2 * sizeof(uint16_t))); i++) {
|
||||||
if (result > NTCHandleLookup[(i * 2) + 0]) {
|
if (result > NTCHandleLookup[(i * 2) + 0]) {
|
||||||
return NTCHandleLookup[(i * 2) + 1] * 10;
|
return NTCHandleLookup[(i * 2) + 1] * 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 45 * 10;
|
return 45 * 10;
|
||||||
#endif
|
#endif
|
||||||
#ifdef TEMP_TMP36
|
#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) =
|
||||||
// 8 times oversampling Therefore 32768 is the 3.3V input, so 0.1007080078125
|
// 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
|
// mV per count So we need to subtract an offset of 0.5V to center on 0C
|
||||||
// (4964.8 counts)
|
// (4964.8 counts)
|
||||||
//
|
//
|
||||||
int32_t result = getADC(0);
|
int32_t result = getADC(0);
|
||||||
result -= 4965; // remove 0.5V offset
|
result -= 4965; // remove 0.5V offset
|
||||||
// 10mV per C
|
// 10mV per C
|
||||||
// 99.29 counts per Deg C above 0C. Tends to read a tad over across all of my sample units
|
// 99.29 counts per Deg C above 0C. Tends to read a tad over across all of my sample units
|
||||||
result *= 100;
|
result *= 100;
|
||||||
result /= 994;
|
result /= 994;
|
||||||
return result;
|
return result;
|
||||||
#endif
|
#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;
|
||||||
readings[3] = hadc1.Instance->JDR4;
|
readings[3] = hadc1.Instance->JDR4;
|
||||||
readings[4] = hadc2.Instance->JDR1;
|
readings[4] = hadc2.Instance->JDR1;
|
||||||
readings[5] = hadc2.Instance->JDR2;
|
readings[5] = hadc2.Instance->JDR2;
|
||||||
readings[6] = hadc2.Instance->JDR3;
|
readings[6] = hadc2.Instance->JDR3;
|
||||||
readings[7] = hadc2.Instance->JDR4;
|
readings[7] = hadc2.Instance->JDR4;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
sum += readings[i];
|
sum += readings[i];
|
||||||
}
|
}
|
||||||
return sum; // 8x over sample
|
return sum; // 8x over sample
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getTipRawTemp(uint8_t refresh) {
|
uint16_t getTipRawTemp(uint8_t refresh) {
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
uint16_t lastSample = getTipInstantTemperature();
|
uint16_t lastSample = getTipInstantTemperature();
|
||||||
rawTempFilter.update(lastSample);
|
rawTempFilter.update(lastSample);
|
||||||
return lastSample;
|
return lastSample;
|
||||||
} else {
|
} else {
|
||||||
return rawTempFilter.average();
|
return rawTempFilter.average();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
|
uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
|
||||||
@@ -167,187 +164,177 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
|
|||||||
#define BATTFILTERDEPTH 8
|
#define BATTFILTERDEPTH 8
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
static uint8_t preFillneeded = 10;
|
static uint8_t preFillneeded = 10;
|
||||||
static uint32_t samples[BATTFILTERDEPTH];
|
static uint32_t samples[BATTFILTERDEPTH];
|
||||||
static uint8_t index = 0;
|
static uint8_t index = 0;
|
||||||
if (preFillneeded) {
|
if (preFillneeded) {
|
||||||
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
|
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
|
||||||
samples[i] = getADC(1);
|
samples[i] = getADC(1);
|
||||||
preFillneeded--;
|
preFillneeded--;
|
||||||
}
|
}
|
||||||
if (sample) {
|
if (sample) {
|
||||||
samples[index] = getADC(1);
|
samples[index] = getADC(1);
|
||||||
index = (index + 1) % BATTFILTERDEPTH;
|
index = (index + 1) % BATTFILTERDEPTH;
|
||||||
}
|
}
|
||||||
uint32_t sum = 0;
|
uint32_t sum = 0;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
|
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
|
||||||
sum += samples[i];
|
sum += samples[i];
|
||||||
|
|
||||||
sum /= BATTFILTERDEPTH;
|
sum /= BATTFILTERDEPTH;
|
||||||
if (divisor == 0) {
|
if (divisor == 0) {
|
||||||
divisor = 1;
|
divisor = 1;
|
||||||
}
|
}
|
||||||
return sum * 4 / divisor;
|
return sum * 4 / divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTipPWM(uint8_t pulse) {
|
void setTipPWM(uint8_t pulse) {
|
||||||
PWMSafetyTimer = 10; // This is decremented in the handler for PWM so that the tip pwm is
|
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.
|
// disabled if the PID task is not scheduled often enough.
|
||||||
|
|
||||||
pendingPWM = pulse;
|
pendingPWM = pulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void switchToFastPWM(void) {
|
static void switchToFastPWM(void) {
|
||||||
fastPWM = true;
|
fastPWM = true;
|
||||||
totalPWM = powerPWM + tempMeasureTicks * 2 + holdoffTicks;
|
totalPWM = powerPWM + tempMeasureTicks * 2 + holdoffTicks;
|
||||||
htim2.Instance->ARR = totalPWM;
|
htim2.Instance->ARR = totalPWM;
|
||||||
// ~3.5 Hz rate
|
// ~3.5 Hz rate
|
||||||
htim2.Instance->CCR1 = powerPWM + holdoffTicks * 2;
|
htim2.Instance->CCR1 = powerPWM + holdoffTicks * 2;
|
||||||
// 2 MHz timer clock/2000 = 1 kHz tick rate
|
// 2 MHz timer clock/2000 = 1 kHz tick rate
|
||||||
htim2.Instance->PSC = 2000;
|
htim2.Instance->PSC = 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void switchToSlowPWM(void) {
|
static void switchToSlowPWM(void) {
|
||||||
fastPWM = false;
|
fastPWM = false;
|
||||||
totalPWM = powerPWM + tempMeasureTicks + holdoffTicks;
|
totalPWM = powerPWM + tempMeasureTicks + holdoffTicks;
|
||||||
htim2.Instance->ARR = totalPWM;
|
htim2.Instance->ARR = totalPWM;
|
||||||
// ~1.84 Hz rate
|
// ~1.84 Hz rate
|
||||||
htim2.Instance->CCR1 = powerPWM + holdoffTicks;
|
htim2.Instance->CCR1 = powerPWM + holdoffTicks;
|
||||||
// 2 MHz timer clock/4000 = 500 Hz tick rate
|
// 2 MHz timer clock/4000 = 500 Hz tick rate
|
||||||
htim2.Instance->PSC = 4000;
|
htim2.Instance->PSC = 4000;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tryBetterPWM(uint8_t pwm) {
|
bool tryBetterPWM(uint8_t pwm) {
|
||||||
if (fastPWM && pwm == powerPWM) {
|
if (fastPWM && pwm == powerPWM) {
|
||||||
// maximum power for fast PWM reached, need to go slower to get more
|
// maximum power for fast PWM reached, need to go slower to get more
|
||||||
switchToSlowPWM();
|
switchToSlowPWM();
|
||||||
return true;
|
return true;
|
||||||
} else if (!fastPWM && pwm < 230) {
|
} else if (!fastPWM && pwm < 230) {
|
||||||
// 254 in fast PWM mode gives the same power as 239 in slow
|
// 254 in fast PWM mode gives the same power as 239 in slow
|
||||||
// allow for some reasonable hysteresis by switching only when it goes
|
// allow for some reasonable hysteresis by switching only when it goes
|
||||||
// below 230 (equivalent to 245 in fast mode)
|
// below 230 (equivalent to 245 in fast mode)
|
||||||
switchToFastPWM();
|
switchToFastPWM();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are called by the HAL after the corresponding events from the system
|
// These are called by the HAL after the corresponding events from the system
|
||||||
// timers.
|
// timers.
|
||||||
|
|
||||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
||||||
// Period has elapsed
|
// Period has elapsed
|
||||||
if (htim->Instance == TIM2) {
|
if (htim->Instance == TIM2) {
|
||||||
// we want to turn on the output again
|
// we want to turn on the output again
|
||||||
PWMSafetyTimer--;
|
PWMSafetyTimer--;
|
||||||
// We decrement this safety value so that lockups in the
|
// We decrement this safety value so that lockups in the
|
||||||
// scheduler will not cause the PWM to become locked in an
|
// scheduler will not cause the PWM to become locked in an
|
||||||
// active driving state.
|
// active driving state.
|
||||||
// While we could assume this could never happen, its a small price for
|
// While we could assume this could never happen, its a small price for
|
||||||
// increased safety
|
// increased safety
|
||||||
htim2.Instance->CCR4 = pendingPWM;
|
htim2.Instance->CCR4 = pendingPWM;
|
||||||
if (htim2.Instance->CCR4 && PWMSafetyTimer) {
|
if (htim2.Instance->CCR4 && PWMSafetyTimer) {
|
||||||
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
|
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
|
||||||
} else {
|
} else {
|
||||||
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
|
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
|
||||||
}
|
}
|
||||||
} else if (htim->Instance == TIM1) {
|
} else if (htim->Instance == TIM1) {
|
||||||
// STM uses this for internal functions as a counter for timeouts
|
// STM uses this for internal functions as a counter for timeouts
|
||||||
HAL_IncTick();
|
HAL_IncTick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) {
|
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) {
|
||||||
// This was a when the PWM for the output has timed out
|
// This was a when the PWM for the output has timed out
|
||||||
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) {
|
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) {
|
||||||
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
|
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void unstick_I2C() {
|
void unstick_I2C() {
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
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;
|
||||||
|
|
||||||
GPIO_InitStruct.Pin = SCL_Pin;
|
GPIO_InitStruct.Pin = SCL_Pin;
|
||||||
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
|
||||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
||||||
|
|
||||||
GPIO_InitStruct.Pin = SDA_Pin;
|
GPIO_InitStruct.Pin = SDA_Pin;
|
||||||
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
|
||||||
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
|
||||||
|
|
||||||
while (GPIO_PIN_SET != HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin)) {
|
while (GPIO_PIN_SET != HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin)) {
|
||||||
//Move clock to release I2C
|
// Move clock to release I2C
|
||||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET);
|
||||||
asm("nop");
|
asm("nop");
|
||||||
asm("nop");
|
asm("nop");
|
||||||
asm("nop");
|
asm("nop");
|
||||||
asm("nop");
|
asm("nop");
|
||||||
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
|
||||||
|
|
||||||
timeout_cnt++;
|
timeout_cnt++;
|
||||||
if (timeout_cnt > timeout)
|
if (timeout_cnt > timeout)
|
||||||
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;
|
||||||
|
|
||||||
GPIO_InitStruct.Pin = SCL_Pin;
|
GPIO_InitStruct.Pin = SCL_Pin;
|
||||||
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
GPIO_InitStruct.Pin = SDA_Pin;
|
GPIO_InitStruct.Pin = SDA_Pin;
|
||||||
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getButtonA() {
|
uint8_t getButtonA() { return HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ? 1 : 0; }
|
||||||
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; }
|
||||||
}
|
|
||||||
uint8_t getButtonB() {
|
|
||||||
return HAL_GPIO_ReadPin(KEY_B_GPIO_Port, KEY_B_Pin) == GPIO_PIN_RESET ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BSPInit(void) {
|
void BSPInit(void) { switchToFastPWM(); }
|
||||||
switchToFastPWM();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reboot() {
|
void reboot() { NVIC_SystemReset(); }
|
||||||
NVIC_SystemReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void delay_ms(uint16_t count) {
|
void delay_ms(uint16_t count) { HAL_Delay(count); }
|
||||||
HAL_Delay(count);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,11 +12,11 @@
|
|||||||
* An array of all of the desired voltages & minimum currents in preferred order
|
* An array of all of the desired voltages & minimum currents in preferred order
|
||||||
*/
|
*/
|
||||||
const uint16_t USB_PD_Desired_Levels[] = {
|
const uint16_t USB_PD_Desired_Levels[] = {
|
||||||
//mV desired input, mA minimum required current
|
// mV desired input, mA minimum required current
|
||||||
12000, 2400, //12V @ 2.4A
|
12000, 2400, // 12V @ 2.4A
|
||||||
9000, 2000, //9V @ 2A
|
9000, 2000, // 9V @ 2A
|
||||||
5000, 100, //5V @ whatever
|
5000, 100, // 5V @ whatever
|
||||||
|
|
||||||
};
|
};
|
||||||
const uint8_t USB_PD_Desired_Levels_Len = 3;
|
const uint8_t USB_PD_Desired_Levels_Len = 3;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -11,97 +11,81 @@ SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr;
|
|||||||
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
|
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
|
||||||
|
|
||||||
void FRToSI2C::CpltCallback() {
|
void FRToSI2C::CpltCallback() {
|
||||||
hi2c1.State = HAL_I2C_STATE_READY; // Force state reset (even if tx error)
|
hi2c1.State = HAL_I2C_STATE_READY; // Force state reset (even if tx error)
|
||||||
if (I2CSemaphore) {
|
if (I2CSemaphore) {
|
||||||
xSemaphoreGiveFromISR(I2CSemaphore, NULL);
|
xSemaphoreGiveFromISR(I2CSemaphore, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
|
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) {
|
||||||
uint8_t *pData, uint16_t Size) {
|
|
||||||
|
|
||||||
if (!lock())
|
if (!lock())
|
||||||
return false;
|
return false;
|
||||||
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT,
|
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
|
||||||
pData, Size, 500) != HAL_OK) {
|
|
||||||
|
|
||||||
I2C_Unstick();
|
I2C_Unstick();
|
||||||
unlock();
|
unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
|
|
||||||
return Mem_Write(address, reg, &data, 1);
|
|
||||||
}
|
}
|
||||||
|
bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) { return Mem_Write(address, reg, &data, 1); }
|
||||||
|
|
||||||
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
|
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
|
||||||
uint8_t tx_data[1];
|
uint8_t tx_data[1];
|
||||||
Mem_Read(add, reg, tx_data, 1);
|
Mem_Read(add, reg, tx_data, 1);
|
||||||
return tx_data[0];
|
return tx_data[0];
|
||||||
}
|
}
|
||||||
bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) {
|
||||||
uint8_t *pData, uint16_t Size) {
|
|
||||||
|
|
||||||
if (!lock())
|
if (!lock())
|
||||||
return false;
|
return false;
|
||||||
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT,
|
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
|
||||||
pData, Size, 500) != HAL_OK) {
|
|
||||||
|
|
||||||
I2C_Unstick();
|
I2C_Unstick();
|
||||||
unlock();
|
unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||||
if (!lock())
|
if (!lock())
|
||||||
return false;
|
return false;
|
||||||
if (HAL_I2C_Master_Transmit_DMA(&hi2c1, DevAddress, pData, Size)
|
if (HAL_I2C_Master_Transmit_DMA(&hi2c1, DevAddress, pData, Size) != HAL_OK) {
|
||||||
!= HAL_OK) {
|
I2C_Unstick();
|
||||||
I2C_Unstick();
|
unlock();
|
||||||
unlock();
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FRToSI2C::probe(uint16_t DevAddress) {
|
bool FRToSI2C::probe(uint16_t DevAddress) {
|
||||||
if (!lock())
|
if (!lock())
|
||||||
return false;
|
return false;
|
||||||
uint8_t buffer[1];
|
uint8_t buffer[1];
|
||||||
bool worked = HAL_I2C_Mem_Read(&hi2c1, DevAddress, 0x0F,
|
bool worked = HAL_I2C_Mem_Read(&hi2c1, DevAddress, 0x0F, I2C_MEMADD_SIZE_8BIT, buffer, 1, 1000) == HAL_OK;
|
||||||
I2C_MEMADD_SIZE_8BIT, buffer, 1, 1000) == HAL_OK;
|
unlock();
|
||||||
unlock();
|
return worked;
|
||||||
return worked;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FRToSI2C::I2C_Unstick() {
|
void FRToSI2C::I2C_Unstick() { unstick_I2C(); }
|
||||||
unstick_I2C();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FRToSI2C::unlock() {
|
void FRToSI2C::unlock() { xSemaphoreGive(I2CSemaphore); }
|
||||||
xSemaphoreGive(I2CSemaphore);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FRToSI2C::lock() {
|
bool FRToSI2C::lock() { return xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE; }
|
||||||
return xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FRToSI2C::writeRegistersBulk(const uint8_t address,
|
bool FRToSI2C::writeRegistersBulk(const uint8_t address, const I2C_REG *registers, const uint8_t registersLength) {
|
||||||
const I2C_REG *registers, const uint8_t registersLength) {
|
for (int index = 0; index < registersLength; index++) {
|
||||||
for (int index = 0; index < registersLength; index++) {
|
if (!I2C_RegisterWrite(address, registers[index].reg, registers[index].val)) {
|
||||||
if (!I2C_RegisterWrite(address, registers[index].reg,
|
return false;
|
||||||
registers[index].val)) {
|
}
|
||||||
return false;
|
if (registers[index].pause_ms)
|
||||||
}
|
delay_ms(registers[index].pause_ms);
|
||||||
if (registers[index].pause_ms)
|
}
|
||||||
delay_ms(registers[index].pause_ms);
|
return true;
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,37 +13,22 @@
|
|||||||
* runs again
|
* runs again
|
||||||
*/
|
*/
|
||||||
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc) {
|
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc) {
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
if (hadc == &hadc1) {
|
if (hadc == &hadc1) {
|
||||||
if (pidTaskNotification) {
|
if (pidTaskNotification) {
|
||||||
vTaskNotifyGiveFromISR(pidTaskNotification,
|
vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
|
||||||
&xHigherPriorityTaskWoken);
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
|
|
||||||
FRToSI2C::CpltCallback();
|
|
||||||
}
|
|
||||||
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
|
|
||||||
FRToSI2C::CpltCallback();
|
|
||||||
}
|
|
||||||
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
|
|
||||||
FRToSI2C::CpltCallback();
|
|
||||||
}
|
|
||||||
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c __unused) {
|
|
||||||
|
|
||||||
FRToSI2C::CpltCallback();
|
|
||||||
}
|
|
||||||
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
|
|
||||||
|
|
||||||
FRToSI2C::CpltCallback();
|
|
||||||
}
|
|
||||||
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
|
|
||||||
FRToSI2C::CpltCallback();
|
|
||||||
}
|
}
|
||||||
|
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCallback(); }
|
||||||
|
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCallback(); }
|
||||||
|
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCallback(); }
|
||||||
|
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCallback(); }
|
||||||
|
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCallback(); }
|
||||||
|
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) { FRToSI2C::CpltCallback(); }
|
||||||
|
|
||||||
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
|
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
|
||||||
(void) GPIO_Pin;
|
(void)GPIO_Pin;
|
||||||
InterruptHandler::irqCallback();
|
InterruptHandler::irqCallback();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,48 @@
|
|||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "BSP_Power.h"
|
#include "BSP_Power.h"
|
||||||
|
#include "Model_Config.h"
|
||||||
|
#include "Pins.h"
|
||||||
#include "QC3.h"
|
#include "QC3.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "Pins.h"
|
|
||||||
#include "fusbpd.h"
|
#include "fusbpd.h"
|
||||||
#include "Model_Config.h"
|
|
||||||
#include "policy_engine.h"
|
|
||||||
#include "int_n.h"
|
#include "int_n.h"
|
||||||
|
#include "policy_engine.h"
|
||||||
bool FUSB302_present = false;
|
bool FUSB302_present = false;
|
||||||
|
|
||||||
void power_check() {
|
void power_check() {
|
||||||
#ifdef POW_PD
|
#ifdef POW_PD
|
||||||
if (FUSB302_present) {
|
if (FUSB302_present) {
|
||||||
//Cant start QC until either PD works or fails
|
// Cant start QC until either PD works or fails
|
||||||
if (PolicyEngine::setupCompleteOrTimedOut() == false) {
|
if (PolicyEngine::setupCompleteOrTimedOut() == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (PolicyEngine::pdHasNegotiated()) {
|
if (PolicyEngine::pdHasNegotiated()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef POW_QC
|
#ifdef POW_QC
|
||||||
QC_resync();
|
QC_resync();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
uint8_t usb_pd_detect() {
|
uint8_t usb_pd_detect() {
|
||||||
#ifdef POW_PD
|
#ifdef POW_PD
|
||||||
FUSB302_present = fusb302_detect();
|
FUSB302_present = fusb302_detect();
|
||||||
return FUSB302_present;
|
return FUSB302_present;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getIsPoweredByDCIN() {
|
bool getIsPoweredByDCIN() {
|
||||||
#ifdef MODEL_TS80
|
#ifdef MODEL_TS80
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MODEL_TS80P
|
#ifdef MODEL_TS80P
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MODEL_TS100
|
#ifdef MODEL_TS100
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,74 +5,72 @@
|
|||||||
* Author: Ralim
|
* Author: Ralim
|
||||||
*/
|
*/
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
|
#include "Model_Config.h"
|
||||||
#include "Pins.h"
|
#include "Pins.h"
|
||||||
#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
|
#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+
|
||||||
}
|
}
|
||||||
void QC_DNegZero_Six() {
|
void QC_DNegZero_Six() {
|
||||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
|
||||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
|
||||||
}
|
}
|
||||||
void QC_DPlusThree_Three() {
|
void QC_DPlusThree_Three() {
|
||||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET); // pull up D+
|
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET); // pull up D+
|
||||||
}
|
}
|
||||||
void QC_DNegThree_Three() {
|
void QC_DNegThree_Three() {
|
||||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
|
||||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
|
||||||
}
|
}
|
||||||
void QC_DM_PullDown() {
|
void QC_DM_PullDown() {
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
}
|
}
|
||||||
void QC_DM_No_PullDown() {
|
void QC_DM_No_PullDown() {
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
}
|
}
|
||||||
void QC_Init_GPIO() {
|
void QC_Init_GPIO() {
|
||||||
// Setup any GPIO into the right states for QC
|
// Setup any GPIO into the right states for QC
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10;
|
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10;
|
||||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
// Turn off output mode on pins that we can
|
// Turn off output mode on pins that we can
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
|
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
}
|
}
|
||||||
void QC_Post_Probe_En() {
|
void QC_Post_Probe_En() {
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10;
|
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t QC_DM_PulledDown() {
|
uint8_t QC_DM_PulledDown() { return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET ? 1 : 0; }
|
||||||
return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET ? 1 : 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
void QC_resync() {
|
void QC_resync() {
|
||||||
#ifdef POW_QC
|
#ifdef POW_QC
|
||||||
seekQC((systemSettings.QCIdealVoltage) ? 120 : 90,
|
seekQC((systemSettings.QCIdealVoltage) ? 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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ DMA_HandleTypeDef hdma_i2c1_rx;
|
|||||||
DMA_HandleTypeDef hdma_i2c1_tx;
|
DMA_HandleTypeDef hdma_i2c1_tx;
|
||||||
|
|
||||||
IWDG_HandleTypeDef hiwdg;
|
IWDG_HandleTypeDef hiwdg;
|
||||||
TIM_HandleTypeDef htim2;
|
TIM_HandleTypeDef htim2;
|
||||||
TIM_HandleTypeDef htim3;
|
TIM_HandleTypeDef htim3;
|
||||||
#define ADC_CHANNELS 2
|
#define ADC_CHANNELS 2
|
||||||
#define ADC_SAMPLES 16
|
#define ADC_SAMPLES 16
|
||||||
uint32_t ADCReadings[ADC_SAMPLES * ADC_CHANNELS]; // room for 32 lots of the pair of readings
|
uint32_t ADCReadings[ADC_SAMPLES * ADC_CHANNELS]; // room for 32 lots of the pair of readings
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void SystemClock_Config(void);
|
static void SystemClock_Config(void);
|
||||||
@@ -31,358 +31,352 @@ static void MX_TIM2_Init(void);
|
|||||||
static void MX_DMA_Init(void);
|
static void MX_DMA_Init(void);
|
||||||
static void MX_GPIO_Init(void);
|
static void MX_GPIO_Init(void);
|
||||||
static void MX_ADC2_Init(void);
|
static void MX_ADC2_Init(void);
|
||||||
void Setup_HAL() {
|
void Setup_HAL() {
|
||||||
SystemClock_Config();
|
SystemClock_Config();
|
||||||
|
|
||||||
#ifndef SWD_ENABLE
|
#ifndef SWD_ENABLE
|
||||||
__HAL_AFIO_REMAP_SWJ_DISABLE();
|
__HAL_AFIO_REMAP_SWJ_DISABLE();
|
||||||
#else
|
#else
|
||||||
__HAL_AFIO_REMAP_SWJ_NOJTAG();
|
__HAL_AFIO_REMAP_SWJ_NOJTAG();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MX_GPIO_Init();
|
MX_GPIO_Init();
|
||||||
MX_DMA_Init();
|
MX_DMA_Init();
|
||||||
MX_I2C1_Init();
|
MX_I2C1_Init();
|
||||||
MX_ADC1_Init();
|
MX_ADC1_Init();
|
||||||
MX_ADC2_Init();
|
MX_ADC2_Init();
|
||||||
MX_TIM3_Init();
|
MX_TIM3_Init();
|
||||||
MX_TIM2_Init();
|
MX_TIM2_Init();
|
||||||
MX_IWDG_Init();
|
MX_IWDG_Init();
|
||||||
HAL_ADC_Start(&hadc2);
|
HAL_ADC_Start(&hadc2);
|
||||||
HAL_ADCEx_MultiModeStart_DMA(&hadc1, ADCReadings, (ADC_SAMPLES * ADC_CHANNELS)); // start DMA of normal readings
|
HAL_ADCEx_MultiModeStart_DMA(&hadc1, ADCReadings, (ADC_SAMPLES * ADC_CHANNELS)); // start DMA of normal readings
|
||||||
HAL_ADCEx_InjectedStart(&hadc1); // enable injected readings
|
HAL_ADCEx_InjectedStart(&hadc1); // enable injected readings
|
||||||
HAL_ADCEx_InjectedStart(&hadc2); // enable injected readings
|
HAL_ADCEx_InjectedStart(&hadc2); // enable injected readings
|
||||||
}
|
}
|
||||||
|
|
||||||
// channel 0 -> temperature sensor, 1-> VIN
|
// channel 0 -> temperature sensor, 1-> VIN
|
||||||
uint16_t getADC(uint8_t channel) {
|
uint16_t getADC(uint8_t channel) {
|
||||||
uint32_t sum = 0;
|
uint32_t sum = 0;
|
||||||
for (uint8_t i = 0; i < ADC_SAMPLES; i++) {
|
for (uint8_t i = 0; i < ADC_SAMPLES; i++) {
|
||||||
uint16_t adc1Sample = ADCReadings[channel + (i * ADC_CHANNELS)];
|
uint16_t adc1Sample = ADCReadings[channel + (i * ADC_CHANNELS)];
|
||||||
uint16_t adc2Sample = ADCReadings[channel + (i * ADC_CHANNELS)] >> 16;
|
uint16_t adc2Sample = ADCReadings[channel + (i * ADC_CHANNELS)] >> 16;
|
||||||
|
|
||||||
sum += (adc1Sample + adc2Sample);
|
sum += (adc1Sample + adc2Sample);
|
||||||
}
|
}
|
||||||
return sum >> 2;
|
return sum >> 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** System Clock Configuration
|
/** System Clock Configuration
|
||||||
*/
|
*/
|
||||||
void SystemClock_Config(void) {
|
void SystemClock_Config(void) {
|
||||||
RCC_OscInitTypeDef RCC_OscInitStruct;
|
RCC_OscInitTypeDef RCC_OscInitStruct;
|
||||||
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||||
RCC_PeriphCLKInitTypeDef PeriphClkInit;
|
RCC_PeriphCLKInitTypeDef PeriphClkInit;
|
||||||
|
|
||||||
/**Initializes the CPU, AHB and APB busses clocks
|
/**Initializes the CPU, AHB and APB busses clocks
|
||||||
*/
|
*/
|
||||||
RCC_OscInitStruct.OscillatorType =
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI;
|
||||||
RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI;
|
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
RCC_OscInitStruct.HSICalibrationValue = 16;
|
||||||
RCC_OscInitStruct.HSICalibrationValue = 16;
|
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
|
||||||
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
|
||||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
|
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16; // 64MHz
|
||||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16; // 64MHz
|
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
||||||
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
|
||||||
|
|
||||||
/**Initializes the CPU, AHB and APB busses clocks
|
/**Initializes the CPU, AHB and APB busses clocks
|
||||||
*/
|
*/
|
||||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK |
|
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
|
||||||
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
|
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV16; // TIM
|
||||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV16; // TIM
|
// 2,3,4,5,6,7,12,13,14
|
||||||
// 2,3,4,5,6,7,12,13,14
|
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 64 mhz to some peripherals and adc
|
||||||
RCC_ClkInitStruct.APB2CLKDivider =
|
|
||||||
RCC_HCLK_DIV1; // 64 mhz to some peripherals and adc
|
|
||||||
|
|
||||||
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
|
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
|
||||||
|
|
||||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
|
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
|
||||||
PeriphClkInit.AdcClockSelection =
|
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; // 6 or 8 are the only non overclocked options
|
||||||
RCC_ADCPCLK2_DIV6; // 6 or 8 are the only non overclocked options
|
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
|
||||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
|
|
||||||
|
|
||||||
/**Configure the Systick interrupt time
|
/**Configure the Systick interrupt time
|
||||||
*/
|
*/
|
||||||
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
|
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
|
||||||
|
|
||||||
/**Configure the Systick
|
/**Configure the Systick
|
||||||
*/
|
*/
|
||||||
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
|
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
|
||||||
|
|
||||||
/* SysTick_IRQn interrupt configuration */
|
/* SysTick_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
|
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ADC1 init function */
|
/* ADC1 init function */
|
||||||
static void MX_ADC1_Init(void) {
|
static void MX_ADC1_Init(void) {
|
||||||
ADC_MultiModeTypeDef multimode;
|
ADC_MultiModeTypeDef multimode;
|
||||||
|
|
||||||
ADC_ChannelConfTypeDef sConfig;
|
ADC_ChannelConfTypeDef sConfig;
|
||||||
ADC_InjectionConfTypeDef sConfigInjected;
|
ADC_InjectionConfTypeDef sConfigInjected;
|
||||||
/**Common config
|
/**Common config
|
||||||
*/
|
*/
|
||||||
hadc1.Instance = ADC1;
|
hadc1.Instance = ADC1;
|
||||||
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
|
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
|
||||||
hadc1.Init.ContinuousConvMode = ENABLE;
|
hadc1.Init.ContinuousConvMode = ENABLE;
|
||||||
hadc1.Init.DiscontinuousConvMode = DISABLE;
|
hadc1.Init.DiscontinuousConvMode = DISABLE;
|
||||||
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
||||||
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||||
hadc1.Init.NbrOfConversion = ADC_CHANNELS;
|
hadc1.Init.NbrOfConversion = ADC_CHANNELS;
|
||||||
HAL_ADC_Init(&hadc1);
|
HAL_ADC_Init(&hadc1);
|
||||||
|
|
||||||
/**Configure the ADC multi-mode
|
/**Configure the ADC multi-mode
|
||||||
*/
|
*/
|
||||||
multimode.Mode = ADC_DUALMODE_REGSIMULT_INJECSIMULT;
|
multimode.Mode = ADC_DUALMODE_REGSIMULT_INJECSIMULT;
|
||||||
HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode);
|
HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode);
|
||||||
|
|
||||||
/**Configure Regular Channel
|
/**Configure Regular Channel
|
||||||
*/
|
*/
|
||||||
sConfig.Channel = TMP36_ADC1_CHANNEL;
|
sConfig.Channel = TMP36_ADC1_CHANNEL;
|
||||||
sConfig.Rank = ADC_REGULAR_RANK_1;
|
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||||
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
|
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
|
||||||
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
|
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
|
||||||
|
|
||||||
/**Configure Regular Channel
|
/**Configure Regular Channel
|
||||||
*/
|
*/
|
||||||
sConfig.Channel = VIN_ADC1_CHANNEL;
|
sConfig.Channel = VIN_ADC1_CHANNEL;
|
||||||
sConfig.Rank = ADC_REGULAR_RANK_2;
|
sConfig.Rank = ADC_REGULAR_RANK_2;
|
||||||
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
|
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
|
||||||
|
|
||||||
/**Configure Injected Channel
|
/**Configure Injected Channel
|
||||||
*/
|
*/
|
||||||
// F in = 10.66 MHz
|
// F in = 10.66 MHz
|
||||||
/*
|
/*
|
||||||
* Injected time is 1 delay clock + (12 adc cycles*4)+4*sampletime =~217
|
* Injected time is 1 delay clock + (12 adc cycles*4)+4*sampletime =~217
|
||||||
* clocks = 0.2ms Charge time is 0.016 uS ideally So Sampling time must be >=
|
* clocks = 0.2ms Charge time is 0.016 uS ideally So Sampling time must be >=
|
||||||
* 0.016uS 1/10.66MHz is 0.09uS, so 1 CLK is *should* be enough
|
* 0.016uS 1/10.66MHz is 0.09uS, so 1 CLK is *should* be enough
|
||||||
* */
|
* */
|
||||||
sConfigInjected.InjectedChannel = TIP_TEMP_ADC1_CHANNEL;
|
sConfigInjected.InjectedChannel = TIP_TEMP_ADC1_CHANNEL;
|
||||||
sConfigInjected.InjectedRank = 1;
|
sConfigInjected.InjectedRank = 1;
|
||||||
sConfigInjected.InjectedNbrOfConversion = 4;
|
sConfigInjected.InjectedNbrOfConversion = 4;
|
||||||
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
|
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
|
||||||
sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T2_CC1;
|
sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T2_CC1;
|
||||||
sConfigInjected.AutoInjectedConv = DISABLE;
|
sConfigInjected.AutoInjectedConv = DISABLE;
|
||||||
sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
|
sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
|
||||||
sConfigInjected.InjectedOffset = 0;
|
sConfigInjected.InjectedOffset = 0;
|
||||||
|
|
||||||
HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
|
HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
|
||||||
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
|
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
|
||||||
|
|
||||||
sConfigInjected.InjectedRank = 2;
|
sConfigInjected.InjectedRank = 2;
|
||||||
HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
|
HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
|
||||||
sConfigInjected.InjectedRank = 3;
|
sConfigInjected.InjectedRank = 3;
|
||||||
HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
|
HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
|
||||||
sConfigInjected.InjectedRank = 4;
|
sConfigInjected.InjectedRank = 4;
|
||||||
HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
|
HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
|
||||||
SET_BIT(hadc1.Instance->CR1, (ADC_CR1_JEOCIE)); // Enable end of injected conv irq
|
SET_BIT(hadc1.Instance->CR1, (ADC_CR1_JEOCIE)); // Enable end of injected conv irq
|
||||||
// Run ADC internal calibration
|
// Run ADC internal calibration
|
||||||
while (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK)
|
while (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ADC2 init function */
|
/* ADC2 init function */
|
||||||
static void MX_ADC2_Init(void) {
|
static void MX_ADC2_Init(void) {
|
||||||
ADC_ChannelConfTypeDef sConfig;
|
ADC_ChannelConfTypeDef sConfig;
|
||||||
ADC_InjectionConfTypeDef sConfigInjected;
|
ADC_InjectionConfTypeDef sConfigInjected;
|
||||||
|
|
||||||
/**Common config
|
/**Common config
|
||||||
*/
|
*/
|
||||||
hadc2.Instance = ADC2;
|
hadc2.Instance = ADC2;
|
||||||
hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;
|
hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;
|
||||||
hadc2.Init.ContinuousConvMode = ENABLE;
|
hadc2.Init.ContinuousConvMode = ENABLE;
|
||||||
hadc2.Init.DiscontinuousConvMode = DISABLE;
|
hadc2.Init.DiscontinuousConvMode = DISABLE;
|
||||||
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
||||||
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||||
hadc2.Init.NbrOfConversion = ADC_CHANNELS;
|
hadc2.Init.NbrOfConversion = ADC_CHANNELS;
|
||||||
HAL_ADC_Init(&hadc2);
|
HAL_ADC_Init(&hadc2);
|
||||||
|
|
||||||
/**Configure Regular Channel
|
/**Configure Regular Channel
|
||||||
*/
|
*/
|
||||||
sConfig.Channel = TMP36_ADC2_CHANNEL;
|
sConfig.Channel = TMP36_ADC2_CHANNEL;
|
||||||
sConfig.Rank = ADC_REGULAR_RANK_1;
|
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||||
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
|
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
|
||||||
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
|
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
|
||||||
|
|
||||||
sConfig.Channel = VIN_ADC2_CHANNEL;
|
sConfig.Channel = VIN_ADC2_CHANNEL;
|
||||||
sConfig.Rank = ADC_REGULAR_RANK_2;
|
sConfig.Rank = ADC_REGULAR_RANK_2;
|
||||||
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
|
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
|
||||||
|
|
||||||
/**Configure Injected Channel
|
/**Configure Injected Channel
|
||||||
*/
|
*/
|
||||||
sConfigInjected.InjectedChannel = TIP_TEMP_ADC2_CHANNEL;
|
sConfigInjected.InjectedChannel = TIP_TEMP_ADC2_CHANNEL;
|
||||||
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;
|
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;
|
||||||
sConfigInjected.InjectedNbrOfConversion = 4;
|
sConfigInjected.InjectedNbrOfConversion = 4;
|
||||||
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
|
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
|
||||||
sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T2_CC1;
|
sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T2_CC1;
|
||||||
sConfigInjected.AutoInjectedConv = DISABLE;
|
sConfigInjected.AutoInjectedConv = DISABLE;
|
||||||
sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
|
sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
|
||||||
sConfigInjected.InjectedOffset = 0;
|
sConfigInjected.InjectedOffset = 0;
|
||||||
HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected);
|
HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected);
|
||||||
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
|
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
|
||||||
|
|
||||||
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_2;
|
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_2;
|
||||||
HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected);
|
HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected);
|
||||||
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_3;
|
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_3;
|
||||||
HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected);
|
HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected);
|
||||||
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_4;
|
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_4;
|
||||||
HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected);
|
HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected);
|
||||||
|
|
||||||
// Run ADC internal calibration
|
// Run ADC internal calibration
|
||||||
while (HAL_ADCEx_Calibration_Start(&hadc2) != HAL_OK)
|
while (HAL_ADCEx_Calibration_Start(&hadc2) != HAL_OK)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
/* I2C1 init function */
|
/* I2C1 init function */
|
||||||
static void MX_I2C1_Init(void) {
|
static void MX_I2C1_Init(void) {
|
||||||
hi2c1.Instance = I2C1;
|
hi2c1.Instance = I2C1;
|
||||||
hi2c1.Init.ClockSpeed = 75000;
|
hi2c1.Init.ClockSpeed = 75000;
|
||||||
// OLED doesnt handle >100k when its asleep (off).
|
// OLED doesnt handle >100k when its asleep (off).
|
||||||
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
|
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
|
||||||
hi2c1.Init.OwnAddress1 = 0;
|
hi2c1.Init.OwnAddress1 = 0;
|
||||||
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||||
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||||||
hi2c1.Init.OwnAddress2 = 0;
|
hi2c1.Init.OwnAddress2 = 0;
|
||||||
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||||
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||||||
HAL_I2C_Init(&hi2c1);
|
HAL_I2C_Init(&hi2c1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IWDG init function */
|
/* IWDG init function */
|
||||||
static void MX_IWDG_Init(void) {
|
static void MX_IWDG_Init(void) {
|
||||||
hiwdg.Instance = IWDG;
|
hiwdg.Instance = IWDG;
|
||||||
hiwdg.Init.Prescaler = IWDG_PRESCALER_256;
|
hiwdg.Init.Prescaler = IWDG_PRESCALER_256;
|
||||||
hiwdg.Init.Reload = 100;
|
hiwdg.Init.Reload = 100;
|
||||||
#ifndef SWD_ENABLE
|
#ifndef SWD_ENABLE
|
||||||
HAL_IWDG_Init(&hiwdg);
|
HAL_IWDG_Init(&hiwdg);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TIM3 init function */
|
/* TIM3 init function */
|
||||||
static void MX_TIM3_Init(void) {
|
static void MX_TIM3_Init(void) {
|
||||||
TIM_ClockConfigTypeDef sClockSourceConfig;
|
TIM_ClockConfigTypeDef sClockSourceConfig;
|
||||||
TIM_MasterConfigTypeDef sMasterConfig;
|
TIM_MasterConfigTypeDef sMasterConfig;
|
||||||
TIM_OC_InitTypeDef sConfigOC;
|
TIM_OC_InitTypeDef sConfigOC;
|
||||||
|
|
||||||
htim3.Instance = TIM3;
|
htim3.Instance = TIM3;
|
||||||
htim3.Init.Prescaler = 8;
|
htim3.Init.Prescaler = 8;
|
||||||
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
|
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
htim3.Init.Period = 100; // 5 Khz PWM freq
|
htim3.Init.Period = 100; // 5 Khz PWM freq
|
||||||
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 4mhz before div
|
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 4mhz before div
|
||||||
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; //Preload the ARR register (though we dont use this)
|
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; // Preload the ARR register (though we dont use this)
|
||||||
HAL_TIM_Base_Init(&htim3);
|
HAL_TIM_Base_Init(&htim3);
|
||||||
|
|
||||||
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||||||
HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig);
|
HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig);
|
||||||
|
|
||||||
HAL_TIM_PWM_Init(&htim3);
|
HAL_TIM_PWM_Init(&htim3);
|
||||||
|
|
||||||
HAL_TIM_OC_Init(&htim3);
|
HAL_TIM_OC_Init(&htim3);
|
||||||
|
|
||||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||||
HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);
|
HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);
|
||||||
|
|
||||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||||
sConfigOC.Pulse = 50; //50% duty cycle, that is AC coupled through the cap
|
sConfigOC.Pulse = 50; // 50% duty cycle, that is AC coupled through the cap
|
||||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||||
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
|
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
|
||||||
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, PWM_Out_CHANNEL);
|
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, PWM_Out_CHANNEL);
|
||||||
|
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
|
||||||
/**TIM3 GPIO Configuration
|
/**TIM3 GPIO Configuration
|
||||||
PWM_Out_Pin ------> TIM3_CH1
|
PWM_Out_Pin ------> TIM3_CH1
|
||||||
*/
|
*/
|
||||||
GPIO_InitStruct.Pin = PWM_Out_Pin;
|
GPIO_InitStruct.Pin = PWM_Out_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //We would like sharp rising edges
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // We would like sharp rising edges
|
||||||
HAL_GPIO_Init(PWM_Out_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(PWM_Out_GPIO_Port, &GPIO_InitStruct);
|
||||||
#ifdef MODEL_TS100
|
#ifdef MODEL_TS100
|
||||||
// Remap TIM3_CH1 to be on PB4
|
// Remap TIM3_CH1 to be on PB4
|
||||||
__HAL_AFIO_REMAP_TIM3_PARTIAL()
|
__HAL_AFIO_REMAP_TIM3_PARTIAL();
|
||||||
;
|
|
||||||
#else
|
#else
|
||||||
// No re-map required
|
// No re-map required
|
||||||
#endif
|
#endif
|
||||||
HAL_TIM_PWM_Start(&htim3, PWM_Out_CHANNEL);
|
HAL_TIM_PWM_Start(&htim3, PWM_Out_CHANNEL);
|
||||||
}
|
}
|
||||||
/* TIM3 init function */
|
/* TIM3 init function */
|
||||||
static void MX_TIM2_Init(void) {
|
static void MX_TIM2_Init(void) {
|
||||||
/*
|
/*
|
||||||
* We use the channel 1 to trigger the ADC at end of PWM period
|
* We use the channel 1 to trigger the ADC at end of PWM period
|
||||||
* And we use the channel 4 as the PWM modulation source using Interrupts
|
* And we use the channel 4 as the PWM modulation source using Interrupts
|
||||||
* */
|
* */
|
||||||
TIM_ClockConfigTypeDef sClockSourceConfig;
|
TIM_ClockConfigTypeDef sClockSourceConfig;
|
||||||
TIM_MasterConfigTypeDef sMasterConfig;
|
TIM_MasterConfigTypeDef sMasterConfig;
|
||||||
TIM_OC_InitTypeDef sConfigOC;
|
TIM_OC_InitTypeDef sConfigOC;
|
||||||
|
|
||||||
// Timer 2 is fairly slow as its being used to run the PWM and trigger the ADC
|
// Timer 2 is fairly slow as its being used to run the PWM and trigger the ADC
|
||||||
// in the PWM off time.
|
// in the PWM off time.
|
||||||
htim2.Instance = TIM2;
|
htim2.Instance = TIM2;
|
||||||
// dummy value, will be reconfigured by BSPInit()
|
// dummy value, will be reconfigured by BSPInit()
|
||||||
htim2.Init.Prescaler = 2000; // 2 MHz timer clock/2000 = 1 kHz tick rate
|
htim2.Init.Prescaler = 2000; // 2 MHz timer clock/2000 = 1 kHz tick rate
|
||||||
|
|
||||||
// pwm out is 10k from tim3, we want to run our PWM at around 10hz or slower on the output stage
|
// pwm out is 10k from tim3, we want to run our PWM at around 10hz or slower on the output stage
|
||||||
// These values give a rate of around 3.5 Hz for "fast" mode and 1.84 Hz for "slow"
|
// These values give a rate of around 3.5 Hz for "fast" mode and 1.84 Hz for "slow"
|
||||||
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
|
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
// dummy value, will be reconfigured by BSPInit()
|
// dummy value, will be reconfigured by BSPInit()
|
||||||
htim2.Init.Period = 255 + 17 * 2;
|
htim2.Init.Period = 255 + 17 * 2;
|
||||||
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 8 MHz (x2 APB1) before divide
|
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 8 MHz (x2 APB1) before divide
|
||||||
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||||
htim2.Init.RepetitionCounter = 0;
|
htim2.Init.RepetitionCounter = 0;
|
||||||
HAL_TIM_Base_Init(&htim2);
|
HAL_TIM_Base_Init(&htim2);
|
||||||
|
|
||||||
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||||||
HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);
|
HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);
|
||||||
|
|
||||||
HAL_TIM_PWM_Init(&htim2);
|
HAL_TIM_PWM_Init(&htim2);
|
||||||
HAL_TIM_OC_Init(&htim2);
|
HAL_TIM_OC_Init(&htim2);
|
||||||
|
|
||||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||||
HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
|
HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
|
||||||
|
|
||||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||||
// dummy value, will be reconfigured by BSPInit() in the BSP.cpp
|
// dummy value, will be reconfigured by BSPInit() in the BSP.cpp
|
||||||
sConfigOC.Pulse = 255 + 13 * 2; // 13 -> Delay of 7 ms
|
sConfigOC.Pulse = 255 + 13 * 2; // 13 -> Delay of 7 ms
|
||||||
//255 is the largest time period of the drive signal, and then offset ADC sample to be a bit delayed after this
|
// 255 is the largest time period of the drive signal, and then offset ADC sample to be a bit delayed after this
|
||||||
/*
|
/*
|
||||||
* It takes 4 milliseconds for output to be stable after PWM turns off.
|
* It takes 4 milliseconds for output to be stable after PWM turns off.
|
||||||
* Assume ADC samples in 0.5ms
|
* Assume ADC samples in 0.5ms
|
||||||
* We need to set this to 100% + 4.5ms
|
* We need to set this to 100% + 4.5ms
|
||||||
* */
|
* */
|
||||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||||
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
|
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
|
||||||
HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
|
HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
|
||||||
sConfigOC.Pulse = 0; //default to entirely off
|
sConfigOC.Pulse = 0; // default to entirely off
|
||||||
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4);
|
HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4);
|
||||||
|
|
||||||
HAL_TIM_Base_Start_IT(&htim2);
|
HAL_TIM_Base_Start_IT(&htim2);
|
||||||
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
|
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
|
||||||
HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_4);
|
HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_4);
|
||||||
HAL_NVIC_SetPriority(TIM2_IRQn, 15, 0);
|
HAL_NVIC_SetPriority(TIM2_IRQn, 15, 0);
|
||||||
HAL_NVIC_EnableIRQ(TIM2_IRQn);
|
HAL_NVIC_EnableIRQ(TIM2_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable DMA controller clock
|
* Enable DMA controller clock
|
||||||
*/
|
*/
|
||||||
static void MX_DMA_Init(void) {
|
static void MX_DMA_Init(void) {
|
||||||
/* DMA controller clock enable */
|
/* DMA controller clock enable */
|
||||||
__HAL_RCC_DMA1_CLK_ENABLE()
|
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||||
;
|
|
||||||
|
|
||||||
/* DMA interrupt init */
|
/* DMA interrupt init */
|
||||||
/* DMA1_Channel1_IRQn interrupt configuration */
|
/* DMA1_Channel1_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 5, 0);
|
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
|
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
|
||||||
/* DMA1_Channel6_IRQn interrupt configuration */
|
/* DMA1_Channel6_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 0);
|
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
|
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
|
||||||
/* DMA1_Channel7_IRQn interrupt configuration */
|
/* DMA1_Channel7_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 5, 0);
|
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
|
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Configure pins as
|
/** Configure pins as
|
||||||
@@ -396,90 +390,80 @@ static void MX_DMA_Init(void) {
|
|||||||
PB1 ------> ADCx_IN9
|
PB1 ------> ADCx_IN9
|
||||||
*/
|
*/
|
||||||
static void MX_GPIO_Init(void) {
|
static void MX_GPIO_Init(void) {
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
|
||||||
/* GPIO Ports Clock Enable */
|
/* GPIO Ports Clock Enable */
|
||||||
__HAL_RCC_GPIOD_CLK_ENABLE()
|
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||||
;
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||||
__HAL_RCC_GPIOA_CLK_ENABLE()
|
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||||
;
|
|
||||||
__HAL_RCC_GPIOB_CLK_ENABLE()
|
|
||||||
;
|
|
||||||
|
|
||||||
/*Configure GPIO pin Output Level */
|
/*Configure GPIO pin Output Level */
|
||||||
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_RESET);
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
/*Configure GPIO pins : PD0 PD1 */
|
/*Configure GPIO pins : PD0 PD1 */
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
|
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||||
/*Configure peripheral I/O remapping */
|
/*Configure peripheral I/O remapping */
|
||||||
__HAL_AFIO_REMAP_PD01_ENABLE()
|
__HAL_AFIO_REMAP_PD01_ENABLE();
|
||||||
;
|
//^ remap XTAL so that pins can be analog (all input buffers off).
|
||||||
//^ remap XTAL so that pins can be analog (all input buffers off).
|
// reduces power consumption
|
||||||
// reduces power consumption
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure All pins as analog by default
|
* Configure All pins as analog by default
|
||||||
*/
|
*/
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
|
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_15;
|
||||||
GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 |
|
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||||
GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_15;
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
|
|
||||||
#ifdef MODEL_TS100
|
#ifdef MODEL_TS100
|
||||||
GPIO_PIN_3 |
|
GPIO_PIN_3 |
|
||||||
#endif
|
#endif
|
||||||
GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 |
|
GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
|
||||||
GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 |
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
|
|
||||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
|
||||||
|
|
||||||
#ifdef MODEL_TS100
|
#ifdef MODEL_TS100
|
||||||
#ifndef SWD_ENABLE
|
#ifndef SWD_ENABLE
|
||||||
/* Pull USB and SWD lines low to prevent enumeration attempts and EMI affecting
|
/* Pull USB and SWD lines low to prevent enumeration attempts and EMI affecting
|
||||||
* the debug core */
|
* the debug core */
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14;
|
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
|
||||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
|
||||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_13, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_13, GPIO_PIN_RESET);
|
||||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_14, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_14, GPIO_PIN_RESET);
|
||||||
#else
|
#else
|
||||||
/* Make all lines affecting SWD floating to allow debugging */
|
/* Make all lines affecting SWD floating to allow debugging */
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
|
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
/* TS80 */
|
/* TS80 */
|
||||||
/* Leave USB lines open circuit*/
|
/* Leave USB lines open circuit*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*Configure GPIO pins : KEY_B_Pin KEY_A_Pin */
|
/*Configure GPIO pins : KEY_B_Pin KEY_A_Pin */
|
||||||
GPIO_InitStruct.Pin = KEY_B_Pin | KEY_A_Pin;
|
GPIO_InitStruct.Pin = KEY_B_Pin | KEY_A_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
HAL_GPIO_Init(KEY_B_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(KEY_B_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
/*Configure GPIO pin : OLED_RESET_Pin */
|
/*Configure GPIO pin : OLED_RESET_Pin */
|
||||||
GPIO_InitStruct.Pin = OLED_RESET_Pin;
|
GPIO_InitStruct.Pin = OLED_RESET_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
HAL_GPIO_Init(OLED_RESET_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(OLED_RESET_GPIO_Port, &GPIO_InitStruct);
|
||||||
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_RESET);
|
||||||
|
|
||||||
// Pull down LCD reset
|
// Pull down LCD reset
|
||||||
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_RESET);
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
#ifdef USE_FULL_ASSERT
|
||||||
|
void assert_failed(uint8_t *file, uint32_t line) { asm("bkpt"); }
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -52,13 +52,13 @@
|
|||||||
#include "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
|
|
||||||
/** @addtogroup STM32F1xx_HAL_Driver
|
/** @addtogroup STM32F1xx_HAL_Driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup HAL HAL
|
/** @defgroup HAL HAL
|
||||||
* @brief HAL module driver.
|
* @brief HAL module driver.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAL_MODULE_ENABLED
|
#ifdef HAL_MODULE_ENABLED
|
||||||
|
|
||||||
@@ -66,44 +66,41 @@
|
|||||||
/* Private define ------------------------------------------------------------*/
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
|
||||||
/** @defgroup HAL_Private_Constants HAL Private Constants
|
/** @defgroup HAL_Private_Constants HAL Private Constants
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* @brief STM32F1xx HAL Driver version number V1.1.3
|
* @brief STM32F1xx HAL Driver version number V1.1.3
|
||||||
*/
|
*/
|
||||||
#define __STM32F1xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
#define __STM32F1xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||||
#define __STM32F1xx_HAL_VERSION_SUB1 (0x01U) /*!< [23:16] sub1 version */
|
#define __STM32F1xx_HAL_VERSION_SUB1 (0x01U) /*!< [23:16] sub1 version */
|
||||||
#define __STM32F1xx_HAL_VERSION_SUB2 (0x03U) /*!< [15:8] sub2 version */
|
#define __STM32F1xx_HAL_VERSION_SUB2 (0x03U) /*!< [15:8] sub2 version */
|
||||||
#define __STM32F1xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
#define __STM32F1xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||||
#define __STM32F1xx_HAL_VERSION ((__STM32F1xx_HAL_VERSION_MAIN << 24)\
|
#define __STM32F1xx_HAL_VERSION ((__STM32F1xx_HAL_VERSION_MAIN << 24) | (__STM32F1xx_HAL_VERSION_SUB1 << 16) | (__STM32F1xx_HAL_VERSION_SUB2 << 8) | (__STM32F1xx_HAL_VERSION_RC))
|
||||||
|(__STM32F1xx_HAL_VERSION_SUB1 << 16)\
|
|
||||||
|(__STM32F1xx_HAL_VERSION_SUB2 << 8 )\
|
|
||||||
|(__STM32F1xx_HAL_VERSION_RC))
|
|
||||||
|
|
||||||
#define IDCODE_DEVID_MASK 0x00000FFFU
|
#define IDCODE_DEVID_MASK 0x00000FFFU
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
/* Private macro -------------------------------------------------------------*/
|
||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
|
||||||
/** @defgroup HAL_Private_Variables HAL Private Variables
|
/** @defgroup HAL_Private_Variables HAL Private Variables
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
__IO uint32_t uwTick;
|
__IO uint32_t uwTick;
|
||||||
uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
|
uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
|
||||||
HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
|
HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
/* Exported functions ---------------------------------------------------------*/
|
/* Exported functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
/** @defgroup HAL_Exported_Functions HAL Exported Functions
|
/** @defgroup HAL_Exported_Functions HAL Exported Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions
|
/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions
|
||||||
* @brief Initialization and de-initialization functions
|
* @brief Initialization and de-initialization functions
|
||||||
@@ -139,30 +136,27 @@ HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function is used to initialize the HAL Library; it must be the first
|
* @brief This function is used to initialize the HAL Library; it must be the first
|
||||||
* instruction to be executed in the main program (before to call any other
|
* instruction to be executed in the main program (before to call any other
|
||||||
* HAL function), it performs the following:
|
* HAL function), it performs the following:
|
||||||
* Configure the Flash prefetch.
|
* Configure the Flash prefetch.
|
||||||
* Configures the SysTick to generate an interrupt each 1 millisecond,
|
* Configures the SysTick to generate an interrupt each 1 millisecond,
|
||||||
* which is clocked by the HSI (at this stage, the clock is not yet
|
* which is clocked by the HSI (at this stage, the clock is not yet
|
||||||
* configured and thus the system is running from the internal HSI at 16 MHz).
|
* configured and thus the system is running from the internal HSI at 16 MHz).
|
||||||
* Set NVIC Group Priority to 4.
|
* Set NVIC Group Priority to 4.
|
||||||
* Calls the HAL_MspInit() callback function defined in user file
|
* Calls the HAL_MspInit() callback function defined in user file
|
||||||
* "stm32f1xx_hal_msp.c" to do the global low level hardware initialization
|
* "stm32f1xx_hal_msp.c" to do the global low level hardware initialization
|
||||||
*
|
*
|
||||||
* @note SysTick is used as time base for the HAL_Delay() function, the application
|
* @note SysTick is used as time base for the HAL_Delay() function, the application
|
||||||
* need to ensure that the SysTick time base is always set to 1 millisecond
|
* need to ensure that the SysTick time base is always set to 1 millisecond
|
||||||
* to have correct HAL operation.
|
* to have correct HAL operation.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_Init(void)
|
HAL_StatusTypeDef HAL_Init(void) {
|
||||||
{
|
|
||||||
/* Configure Flash prefetch */
|
/* Configure Flash prefetch */
|
||||||
#if (PREFETCH_ENABLE != 0)
|
#if (PREFETCH_ENABLE != 0)
|
||||||
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
|
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || defined(STM32F103xB) \
|
||||||
defined(STM32F102x6) || defined(STM32F102xB) || \
|
|| defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
|
||||||
defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
|
|
||||||
defined(STM32F105xC) || defined(STM32F107xC)
|
|
||||||
|
|
||||||
/* Prefetch buffer is not available on value line devices */
|
/* Prefetch buffer is not available on value line devices */
|
||||||
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
|
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
|
||||||
@@ -183,13 +177,12 @@ HAL_StatusTypeDef HAL_Init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function de-Initializes common part of the HAL and stops the systick.
|
* @brief This function de-Initializes common part of the HAL and stops the systick.
|
||||||
* of time base.
|
* of time base.
|
||||||
* @note This function is optional.
|
* @note This function is optional.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_DeInit(void)
|
HAL_StatusTypeDef HAL_DeInit(void) {
|
||||||
{
|
|
||||||
/* Reset of all peripherals */
|
/* Reset of all peripherals */
|
||||||
__HAL_RCC_APB1_FORCE_RESET();
|
__HAL_RCC_APB1_FORCE_RESET();
|
||||||
__HAL_RCC_APB1_RELEASE_RESET();
|
__HAL_RCC_APB1_RELEASE_RESET();
|
||||||
@@ -210,59 +203,52 @@ HAL_StatusTypeDef HAL_DeInit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the MSP.
|
* @brief Initialize the MSP.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
__weak void HAL_MspInit(void)
|
__weak void HAL_MspInit(void) {
|
||||||
{
|
|
||||||
/* NOTE : This function should not be modified, when the callback is needed,
|
/* NOTE : This function should not be modified, when the callback is needed,
|
||||||
the HAL_MspInit could be implemented in the user file
|
the HAL_MspInit could be implemented in the user file
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief DeInitializes the MSP.
|
* @brief DeInitializes the MSP.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
__weak void HAL_MspDeInit(void)
|
__weak void HAL_MspDeInit(void) {
|
||||||
{
|
|
||||||
/* NOTE : This function should not be modified, when the callback is needed,
|
/* NOTE : This function should not be modified, when the callback is needed,
|
||||||
the HAL_MspDeInit could be implemented in the user file
|
the HAL_MspDeInit could be implemented in the user file
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function configures the source of the time base.
|
* @brief This function configures the source of the time base.
|
||||||
* The time source is configured to have 1ms time base with a dedicated
|
* The time source is configured to have 1ms time base with a dedicated
|
||||||
* Tick interrupt priority.
|
* Tick interrupt priority.
|
||||||
* @note This function is called automatically at the beginning of program after
|
* @note This function is called automatically at the beginning of program after
|
||||||
* reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
|
* reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
|
||||||
* @note In the default implementation, SysTick timer is the source of time base.
|
* @note In the default implementation, SysTick timer is the source of time base.
|
||||||
* It is used to generate interrupts at regular time intervals.
|
* It is used to generate interrupts at regular time intervals.
|
||||||
* Care must be taken if HAL_Delay() is called from a peripheral ISR process,
|
* Care must be taken if HAL_Delay() is called from a peripheral ISR process,
|
||||||
* The SysTick interrupt must have higher priority (numerically lower)
|
* The SysTick interrupt must have higher priority (numerically lower)
|
||||||
* than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
|
* than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
|
||||||
* The function is declared as __weak to be overwritten in case of other
|
* The function is declared as __weak to be overwritten in case of other
|
||||||
* implementation in user file.
|
* implementation in user file.
|
||||||
* @param TickPriority Tick interrupt priority.
|
* @param TickPriority Tick interrupt priority.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
|
||||||
{
|
|
||||||
/* Configure the SysTick to have interrupt in 1ms time basis*/
|
/* Configure the SysTick to have interrupt in 1ms time basis*/
|
||||||
if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
|
if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) {
|
||||||
{
|
|
||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure the SysTick IRQ priority */
|
/* Configure the SysTick IRQ priority */
|
||||||
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
|
if (TickPriority < (1UL << __NVIC_PRIO_BITS)) {
|
||||||
{
|
|
||||||
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
|
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
|
||||||
uwTickPrio = TickPriority;
|
uwTickPrio = TickPriority;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,8 +257,8 @@ __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions
|
/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions
|
||||||
* @brief HAL Control functions
|
* @brief HAL Control functions
|
||||||
@@ -298,50 +284,39 @@ __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function is called to increment a global variable "uwTick"
|
* @brief This function is called to increment a global variable "uwTick"
|
||||||
* used as application time base.
|
* used as application time base.
|
||||||
* @note In the default implementation, this variable is incremented each 1ms
|
* @note In the default implementation, this variable is incremented each 1ms
|
||||||
* in SysTick ISR.
|
* in SysTick ISR.
|
||||||
* @note This function is declared as __weak to be overwritten in case of other
|
* @note This function is declared as __weak to be overwritten in case of other
|
||||||
* implementations in user file.
|
* implementations in user file.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
__weak void HAL_IncTick(void)
|
__weak void HAL_IncTick(void) { uwTick += uwTickFreq; }
|
||||||
{
|
|
||||||
uwTick += uwTickFreq;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Provides a tick value in millisecond.
|
* @brief Provides a tick value in millisecond.
|
||||||
* @note This function is declared as __weak to be overwritten in case of other
|
* @note This function is declared as __weak to be overwritten in case of other
|
||||||
* implementations in user file.
|
* implementations in user file.
|
||||||
* @retval tick value
|
* @retval tick value
|
||||||
*/
|
*/
|
||||||
__weak uint32_t HAL_GetTick(void)
|
__weak uint32_t HAL_GetTick(void) { return uwTick; }
|
||||||
{
|
|
||||||
return uwTick;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function returns a tick priority.
|
* @brief This function returns a tick priority.
|
||||||
* @retval tick priority
|
* @retval tick priority
|
||||||
*/
|
*/
|
||||||
uint32_t HAL_GetTickPrio(void)
|
uint32_t HAL_GetTickPrio(void) { return uwTickPrio; }
|
||||||
{
|
|
||||||
return uwTickPrio;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set new tick Freq.
|
* @brief Set new tick Freq.
|
||||||
* @retval Status
|
* @retval Status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
|
HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq) {
|
||||||
{
|
HAL_StatusTypeDef status = HAL_OK;
|
||||||
HAL_StatusTypeDef status = HAL_OK;
|
|
||||||
assert_param(IS_TICKFREQ(Freq));
|
assert_param(IS_TICKFREQ(Freq));
|
||||||
|
|
||||||
if (uwTickFreq != Freq)
|
if (uwTickFreq != Freq) {
|
||||||
{
|
|
||||||
uwTickFreq = Freq;
|
uwTickFreq = Freq;
|
||||||
|
|
||||||
/* Apply the new tick Freq */
|
/* Apply the new tick Freq */
|
||||||
@@ -352,244 +327,207 @@ HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return tick frequency.
|
* @brief Return tick frequency.
|
||||||
* @retval tick period in Hz
|
* @retval tick period in Hz
|
||||||
*/
|
*/
|
||||||
HAL_TickFreqTypeDef HAL_GetTickFreq(void)
|
HAL_TickFreqTypeDef HAL_GetTickFreq(void) { return uwTickFreq; }
|
||||||
{
|
|
||||||
return uwTickFreq;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function provides minimum delay (in milliseconds) based
|
* @brief This function provides minimum delay (in milliseconds) based
|
||||||
* on variable incremented.
|
* on variable incremented.
|
||||||
* @note In the default implementation , SysTick timer is the source of time base.
|
* @note In the default implementation , SysTick timer is the source of time base.
|
||||||
* It is used to generate interrupts at regular time intervals where uwTick
|
* It is used to generate interrupts at regular time intervals where uwTick
|
||||||
* is incremented.
|
* is incremented.
|
||||||
* @note This function is declared as __weak to be overwritten in case of other
|
* @note This function is declared as __weak to be overwritten in case of other
|
||||||
* implementations in user file.
|
* implementations in user file.
|
||||||
* @param Delay specifies the delay time length, in milliseconds.
|
* @param Delay specifies the delay time length, in milliseconds.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
__weak void HAL_Delay(uint32_t Delay)
|
__weak void HAL_Delay(uint32_t Delay) {
|
||||||
{
|
|
||||||
uint32_t tickstart = HAL_GetTick();
|
uint32_t tickstart = HAL_GetTick();
|
||||||
uint32_t wait = Delay;
|
uint32_t wait = Delay;
|
||||||
|
|
||||||
/* Add a freq to guarantee minimum wait */
|
/* Add a freq to guarantee minimum wait */
|
||||||
if (wait < HAL_MAX_DELAY)
|
if (wait < HAL_MAX_DELAY) {
|
||||||
{
|
|
||||||
wait += (uint32_t)(uwTickFreq);
|
wait += (uint32_t)(uwTickFreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((HAL_GetTick() - tickstart) < wait)
|
while ((HAL_GetTick() - tickstart) < wait) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Suspend Tick increment.
|
* @brief Suspend Tick increment.
|
||||||
* @note In the default implementation , SysTick timer is the source of time base. It is
|
* @note In the default implementation , SysTick timer is the source of time base. It is
|
||||||
* used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
|
* used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
|
||||||
* is called, the SysTick interrupt will be disabled and so Tick increment
|
* is called, the SysTick interrupt will be disabled and so Tick increment
|
||||||
* is suspended.
|
* is suspended.
|
||||||
* @note This function is declared as __weak to be overwritten in case of other
|
* @note This function is declared as __weak to be overwritten in case of other
|
||||||
* implementations in user file.
|
* implementations in user file.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
__weak void HAL_SuspendTick(void)
|
__weak void HAL_SuspendTick(void) {
|
||||||
{
|
|
||||||
/* Disable SysTick Interrupt */
|
/* Disable SysTick Interrupt */
|
||||||
CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
|
CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resume Tick increment.
|
* @brief Resume Tick increment.
|
||||||
* @note In the default implementation , SysTick timer is the source of time base. It is
|
* @note In the default implementation , SysTick timer is the source of time base. It is
|
||||||
* used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
|
* used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
|
||||||
* is called, the SysTick interrupt will be enabled and so Tick increment
|
* is called, the SysTick interrupt will be enabled and so Tick increment
|
||||||
* is resumed.
|
* is resumed.
|
||||||
* @note This function is declared as __weak to be overwritten in case of other
|
* @note This function is declared as __weak to be overwritten in case of other
|
||||||
* implementations in user file.
|
* implementations in user file.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
__weak void HAL_ResumeTick(void)
|
__weak void HAL_ResumeTick(void) {
|
||||||
{
|
|
||||||
/* Enable SysTick Interrupt */
|
/* Enable SysTick Interrupt */
|
||||||
SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
|
SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the HAL revision
|
* @brief Returns the HAL revision
|
||||||
* @retval version 0xXYZR (8bits for each decimal, R for RC)
|
* @retval version 0xXYZR (8bits for each decimal, R for RC)
|
||||||
*/
|
*/
|
||||||
uint32_t HAL_GetHalVersion(void)
|
uint32_t HAL_GetHalVersion(void) { return __STM32F1xx_HAL_VERSION; }
|
||||||
{
|
|
||||||
return __STM32F1xx_HAL_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the device revision identifier.
|
* @brief Returns the device revision identifier.
|
||||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||||
* STM32F101xF/G and STM32F103xF/G
|
* STM32F101xF/G and STM32F103xF/G
|
||||||
* STM32F10xx4 and STM32F10xx6
|
* STM32F10xx4 and STM32F10xx6
|
||||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||||
* debug mode (not accessible by the user software in normal mode).
|
* debug mode (not accessible by the user software in normal mode).
|
||||||
* Refer to errata sheet of these devices for more details.
|
* Refer to errata sheet of these devices for more details.
|
||||||
* @retval Device revision identifier
|
* @retval Device revision identifier
|
||||||
*/
|
*/
|
||||||
uint32_t HAL_GetREVID(void)
|
uint32_t HAL_GetREVID(void) { return ((DBGMCU->IDCODE) >> DBGMCU_IDCODE_REV_ID_Pos); }
|
||||||
{
|
|
||||||
return ((DBGMCU->IDCODE) >> DBGMCU_IDCODE_REV_ID_Pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the device identifier.
|
* @brief Returns the device identifier.
|
||||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||||
* STM32F101xF/G and STM32F103xF/G
|
* STM32F101xF/G and STM32F103xF/G
|
||||||
* STM32F10xx4 and STM32F10xx6
|
* STM32F10xx4 and STM32F10xx6
|
||||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||||
* debug mode (not accessible by the user software in normal mode).
|
* debug mode (not accessible by the user software in normal mode).
|
||||||
* Refer to errata sheet of these devices for more details.
|
* Refer to errata sheet of these devices for more details.
|
||||||
* @retval Device identifier
|
* @retval Device identifier
|
||||||
*/
|
*/
|
||||||
uint32_t HAL_GetDEVID(void)
|
uint32_t HAL_GetDEVID(void) { return ((DBGMCU->IDCODE) & IDCODE_DEVID_MASK); }
|
||||||
{
|
|
||||||
return ((DBGMCU->IDCODE) & IDCODE_DEVID_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable the Debug Module during SLEEP mode
|
* @brief Enable the Debug Module during SLEEP mode
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_DBGMCU_EnableDBGSleepMode(void)
|
void HAL_DBGMCU_EnableDBGSleepMode(void) { SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); }
|
||||||
{
|
|
||||||
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disable the Debug Module during SLEEP mode
|
* @brief Disable the Debug Module during SLEEP mode
|
||||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||||
* STM32F101xF/G and STM32F103xF/G
|
* STM32F101xF/G and STM32F103xF/G
|
||||||
* STM32F10xx4 and STM32F10xx6
|
* STM32F10xx4 and STM32F10xx6
|
||||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||||
* debug mode (not accessible by the user software in normal mode).
|
* debug mode (not accessible by the user software in normal mode).
|
||||||
* Refer to errata sheet of these devices for more details.
|
* Refer to errata sheet of these devices for more details.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_DBGMCU_DisableDBGSleepMode(void)
|
void HAL_DBGMCU_DisableDBGSleepMode(void) { CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); }
|
||||||
{
|
|
||||||
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable the Debug Module during STOP mode
|
* @brief Enable the Debug Module during STOP mode
|
||||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||||
* STM32F101xF/G and STM32F103xF/G
|
* STM32F101xF/G and STM32F103xF/G
|
||||||
* STM32F10xx4 and STM32F10xx6
|
* STM32F10xx4 and STM32F10xx6
|
||||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||||
* debug mode (not accessible by the user software in normal mode).
|
* debug mode (not accessible by the user software in normal mode).
|
||||||
* Refer to errata sheet of these devices for more details.
|
* Refer to errata sheet of these devices for more details.
|
||||||
* Note: On all STM32F1 devices:
|
* Note: On all STM32F1 devices:
|
||||||
* If the system tick timer interrupt is enabled during the Stop mode
|
* If the system tick timer interrupt is enabled during the Stop mode
|
||||||
* debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
|
* debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
|
||||||
* the system from Stop mode.
|
* the system from Stop mode.
|
||||||
* Workaround: To debug the Stop mode, disable the system tick timer
|
* Workaround: To debug the Stop mode, disable the system tick timer
|
||||||
* interrupt.
|
* interrupt.
|
||||||
* Refer to errata sheet of these devices for more details.
|
* Refer to errata sheet of these devices for more details.
|
||||||
* Note: On all STM32F1 devices:
|
* Note: On all STM32F1 devices:
|
||||||
* If the system tick timer interrupt is enabled during the Stop mode
|
* If the system tick timer interrupt is enabled during the Stop mode
|
||||||
* debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
|
* debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
|
||||||
* the system from Stop mode.
|
* the system from Stop mode.
|
||||||
* Workaround: To debug the Stop mode, disable the system tick timer
|
* Workaround: To debug the Stop mode, disable the system tick timer
|
||||||
* interrupt.
|
* interrupt.
|
||||||
* Refer to errata sheet of these devices for more details.
|
* Refer to errata sheet of these devices for more details.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_DBGMCU_EnableDBGStopMode(void)
|
void HAL_DBGMCU_EnableDBGStopMode(void) { SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); }
|
||||||
{
|
|
||||||
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disable the Debug Module during STOP mode
|
* @brief Disable the Debug Module during STOP mode
|
||||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||||
* STM32F101xF/G and STM32F103xF/G
|
* STM32F101xF/G and STM32F103xF/G
|
||||||
* STM32F10xx4 and STM32F10xx6
|
* STM32F10xx4 and STM32F10xx6
|
||||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||||
* debug mode (not accessible by the user software in normal mode).
|
* debug mode (not accessible by the user software in normal mode).
|
||||||
* Refer to errata sheet of these devices for more details.
|
* Refer to errata sheet of these devices for more details.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_DBGMCU_DisableDBGStopMode(void)
|
void HAL_DBGMCU_DisableDBGStopMode(void) { CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); }
|
||||||
{
|
|
||||||
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable the Debug Module during STANDBY mode
|
* @brief Enable the Debug Module during STANDBY mode
|
||||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||||
* STM32F101xF/G and STM32F103xF/G
|
* STM32F101xF/G and STM32F103xF/G
|
||||||
* STM32F10xx4 and STM32F10xx6
|
* STM32F10xx4 and STM32F10xx6
|
||||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||||
* debug mode (not accessible by the user software in normal mode).
|
* debug mode (not accessible by the user software in normal mode).
|
||||||
* Refer to errata sheet of these devices for more details.
|
* Refer to errata sheet of these devices for more details.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_DBGMCU_EnableDBGStandbyMode(void)
|
void HAL_DBGMCU_EnableDBGStandbyMode(void) { SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); }
|
||||||
{
|
|
||||||
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disable the Debug Module during STANDBY mode
|
* @brief Disable the Debug Module during STANDBY mode
|
||||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||||
* STM32F101xF/G and STM32F103xF/G
|
* STM32F101xF/G and STM32F103xF/G
|
||||||
* STM32F10xx4 and STM32F10xx6
|
* STM32F10xx4 and STM32F10xx6
|
||||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||||
* debug mode (not accessible by the user software in normal mode).
|
* debug mode (not accessible by the user software in normal mode).
|
||||||
* Refer to errata sheet of these devices for more details.
|
* Refer to errata sheet of these devices for more details.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_DBGMCU_DisableDBGStandbyMode(void)
|
void HAL_DBGMCU_DisableDBGStandbyMode(void) { CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); }
|
||||||
{
|
|
||||||
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the unique device identifier (UID based on 96 bits)
|
* @brief Return the unique device identifier (UID based on 96 bits)
|
||||||
* @param UID pointer to 3 words array.
|
* @param UID pointer to 3 words array.
|
||||||
* @retval Device identifier
|
* @retval Device identifier
|
||||||
*/
|
*/
|
||||||
void HAL_GetUID(uint32_t *UID)
|
void HAL_GetUID(uint32_t *UID) {
|
||||||
{
|
|
||||||
UID[0] = (uint32_t)(READ_REG(*((uint32_t *)UID_BASE)));
|
UID[0] = (uint32_t)(READ_REG(*((uint32_t *)UID_BASE)));
|
||||||
UID[1] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 4U))));
|
UID[1] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 4U))));
|
||||||
UID[2] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 8U))));
|
UID[2] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 8U))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#endif /* HAL_MODULE_ENABLED */
|
#endif /* HAL_MODULE_ENABLED */
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,43 +3,43 @@
|
|||||||
* @file stm32f1xx_hal_cortex.c
|
* @file stm32f1xx_hal_cortex.c
|
||||||
* @author MCD Application Team
|
* @author MCD Application Team
|
||||||
* @brief CORTEX HAL module driver.
|
* @brief CORTEX HAL module driver.
|
||||||
* This file provides firmware functions to manage the following
|
* This file provides firmware functions to manage the following
|
||||||
* functionalities of the CORTEX:
|
* functionalities of the CORTEX:
|
||||||
* + Initialization and de-initialization functions
|
* + Initialization and de-initialization functions
|
||||||
* + Peripheral Control functions
|
* + Peripheral Control functions
|
||||||
*
|
*
|
||||||
@verbatim
|
@verbatim
|
||||||
==============================================================================
|
==============================================================================
|
||||||
##### How to use this driver #####
|
##### How to use this driver #####
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
[..]
|
[..]
|
||||||
*** How to configure Interrupts using CORTEX HAL driver ***
|
*** How to configure Interrupts using CORTEX HAL driver ***
|
||||||
===========================================================
|
===========================================================
|
||||||
[..]
|
[..]
|
||||||
This section provides functions allowing to configure the NVIC interrupts (IRQ).
|
This section provides functions allowing to configure the NVIC interrupts (IRQ).
|
||||||
The Cortex-M3 exceptions are managed by CMSIS functions.
|
The Cortex-M3 exceptions are managed by CMSIS functions.
|
||||||
|
|
||||||
(#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping()
|
(#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping()
|
||||||
function according to the following table.
|
function according to the following table.
|
||||||
(#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority().
|
(#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority().
|
||||||
(#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
|
(#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
|
||||||
(#) please refer to programming manual for details in how to configure priority.
|
(#) please refer to programming manual for details in how to configure priority.
|
||||||
|
|
||||||
-@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible.
|
-@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible.
|
||||||
The pending IRQ priority will be managed only by the sub priority.
|
The pending IRQ priority will be managed only by the sub priority.
|
||||||
|
|
||||||
-@- IRQ priority order (sorted by highest to lowest priority):
|
-@- IRQ priority order (sorted by highest to lowest priority):
|
||||||
(+@) Lowest preemption priority
|
(+@) Lowest preemption priority
|
||||||
(+@) Lowest sub priority
|
(+@) Lowest sub priority
|
||||||
(+@) Lowest hardware priority (IRQ number)
|
(+@) Lowest hardware priority (IRQ number)
|
||||||
|
|
||||||
[..]
|
[..]
|
||||||
*** How to configure Systick using CORTEX HAL driver ***
|
*** How to configure Systick using CORTEX HAL driver ***
|
||||||
========================================================
|
========================================================
|
||||||
[..]
|
[..]
|
||||||
Setup SysTick Timer for time base.
|
Setup SysTick Timer for time base.
|
||||||
|
|
||||||
(+) The HAL_SYSTICK_Config()function calls the SysTick_Config() function which
|
(+) The HAL_SYSTICK_Config()function calls the SysTick_Config() function which
|
||||||
is a CMSIS function that:
|
is a CMSIS function that:
|
||||||
(++) Configures the SysTick Reload register with value passed as function parameter.
|
(++) Configures the SysTick Reload register with value passed as function parameter.
|
||||||
@@ -48,22 +48,22 @@
|
|||||||
(++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
|
(++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
|
||||||
(++) Enables the SysTick Interrupt.
|
(++) Enables the SysTick Interrupt.
|
||||||
(++) Starts the SysTick Counter.
|
(++) Starts the SysTick Counter.
|
||||||
|
|
||||||
(+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
|
(+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
|
||||||
__HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
|
__HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
|
||||||
HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
|
HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
|
||||||
inside the stm32f1xx_hal_cortex.h file.
|
inside the stm32f1xx_hal_cortex.h file.
|
||||||
|
|
||||||
(+) You can change the SysTick IRQ priority by calling the
|
(+) You can change the SysTick IRQ priority by calling the
|
||||||
HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
|
HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
|
||||||
call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
|
call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
|
||||||
|
|
||||||
(+) To adjust the SysTick time base, use the following formula:
|
(+) To adjust the SysTick time base, use the following formula:
|
||||||
|
|
||||||
Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
|
Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
|
||||||
(++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
|
(++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
|
||||||
(++) Reload Value should not exceed 0xFFFFFF
|
(++) Reload Value should not exceed 0xFFFFFF
|
||||||
|
|
||||||
@endverbatim
|
@endverbatim
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @attention
|
* @attention
|
||||||
@@ -99,13 +99,13 @@
|
|||||||
#include "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
|
|
||||||
/** @addtogroup STM32F1xx_HAL_Driver
|
/** @addtogroup STM32F1xx_HAL_Driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup CORTEX CORTEX
|
/** @defgroup CORTEX CORTEX
|
||||||
* @brief CORTEX HAL module driver
|
* @brief CORTEX HAL module driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||||
|
|
||||||
@@ -117,91 +117,86 @@
|
|||||||
/* Exported functions --------------------------------------------------------*/
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions
|
/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions
|
/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||||
* @brief Initialization and Configuration functions
|
* @brief Initialization and Configuration functions
|
||||||
*
|
*
|
||||||
@verbatim
|
@verbatim
|
||||||
==============================================================================
|
==============================================================================
|
||||||
##### Initialization and de-initialization functions #####
|
##### Initialization and de-initialization functions #####
|
||||||
==============================================================================
|
==============================================================================
|
||||||
[..]
|
[..]
|
||||||
This section provides the CORTEX HAL driver functions allowing to configure Interrupts
|
This section provides the CORTEX HAL driver functions allowing to configure Interrupts
|
||||||
Systick functionalities
|
Systick functionalities
|
||||||
|
|
||||||
@endverbatim
|
@endverbatim
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the priority grouping field (preemption priority and subpriority)
|
* @brief Sets the priority grouping field (preemption priority and subpriority)
|
||||||
* using the required unlock sequence.
|
* using the required unlock sequence.
|
||||||
* @param PriorityGroup: The priority grouping bits length.
|
* @param PriorityGroup: The priority grouping bits length.
|
||||||
* This parameter can be one of the following values:
|
* This parameter can be one of the following values:
|
||||||
* @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
|
* @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
|
||||||
* 4 bits for subpriority
|
* 4 bits for subpriority
|
||||||
* @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
|
* @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
|
||||||
* 3 bits for subpriority
|
* 3 bits for subpriority
|
||||||
* @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
|
* @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
|
||||||
* 2 bits for subpriority
|
* 2 bits for subpriority
|
||||||
* @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
|
* @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
|
||||||
* 1 bits for subpriority
|
* 1 bits for subpriority
|
||||||
* @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
|
* @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
|
||||||
* 0 bits for subpriority
|
* 0 bits for subpriority
|
||||||
* @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible.
|
* @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible.
|
||||||
* The pending IRQ priority will be managed only by the subpriority.
|
* The pending IRQ priority will be managed only by the subpriority.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
|
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
|
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
|
||||||
|
|
||||||
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
|
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
|
||||||
NVIC_SetPriorityGrouping(PriorityGroup);
|
NVIC_SetPriorityGrouping(PriorityGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the priority of an interrupt.
|
* @brief Sets the priority of an interrupt.
|
||||||
* @param IRQn: External interrupt number.
|
* @param IRQn: External interrupt number.
|
||||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xx.h))
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xx.h))
|
||||||
* @param PreemptPriority: The preemption priority for the IRQn channel.
|
* @param PreemptPriority: The preemption priority for the IRQn channel.
|
||||||
* This parameter can be a value between 0 and 15
|
* This parameter can be a value between 0 and 15
|
||||||
* A lower priority value indicates a higher priority
|
* A lower priority value indicates a higher priority
|
||||||
* @param SubPriority: the subpriority level for the IRQ channel.
|
* @param SubPriority: the subpriority level for the IRQ channel.
|
||||||
* This parameter can be a value between 0 and 15
|
* This parameter can be a value between 0 and 15
|
||||||
* A lower priority value indicates a higher priority.
|
* A lower priority value indicates a higher priority.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
|
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) {
|
||||||
{
|
|
||||||
uint32_t prioritygroup = 0x00U;
|
uint32_t prioritygroup = 0x00U;
|
||||||
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
|
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
|
||||||
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
|
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
|
||||||
|
|
||||||
prioritygroup = NVIC_GetPriorityGrouping();
|
prioritygroup = NVIC_GetPriorityGrouping();
|
||||||
|
|
||||||
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
|
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables a device specific interrupt in the NVIC interrupt controller.
|
* @brief Enables a device specific interrupt in the NVIC interrupt controller.
|
||||||
* @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
|
* @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
|
||||||
* function should be called before.
|
* function should be called before.
|
||||||
* @param IRQn External interrupt number.
|
* @param IRQn External interrupt number.
|
||||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
|
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
@@ -210,14 +205,13 @@ void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables a device specific interrupt in the NVIC interrupt controller.
|
* @brief Disables a device specific interrupt in the NVIC interrupt controller.
|
||||||
* @param IRQn External interrupt number.
|
* @param IRQn External interrupt number.
|
||||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
|
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
@@ -226,95 +220,88 @@ void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initiates a system reset request to reset the MCU.
|
* @brief Initiates a system reset request to reset the MCU.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_NVIC_SystemReset(void)
|
void HAL_NVIC_SystemReset(void) {
|
||||||
{
|
|
||||||
/* System Reset */
|
/* System Reset */
|
||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
* @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||||
* Counter is in free running mode to generate periodic interrupts.
|
* Counter is in free running mode to generate periodic interrupts.
|
||||||
* @param TicksNumb: Specifies the ticks Number of ticks between two interrupts.
|
* @param TicksNumb: Specifies the ticks Number of ticks between two interrupts.
|
||||||
* @retval status: - 0 Function succeeded.
|
* @retval status: - 0 Function succeeded.
|
||||||
* - 1 Function failed.
|
* - 1 Function failed.
|
||||||
*/
|
*/
|
||||||
uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
|
uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb) { return SysTick_Config(TicksNumb); }
|
||||||
{
|
|
||||||
return SysTick_Config(TicksNumb);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
|
/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
|
||||||
* @brief Cortex control functions
|
* @brief Cortex control functions
|
||||||
*
|
*
|
||||||
@verbatim
|
@verbatim
|
||||||
==============================================================================
|
==============================================================================
|
||||||
##### Peripheral Control functions #####
|
##### Peripheral Control functions #####
|
||||||
==============================================================================
|
==============================================================================
|
||||||
[..]
|
[..]
|
||||||
This subsection provides a set of functions allowing to control the CORTEX
|
This subsection provides a set of functions allowing to control the CORTEX
|
||||||
(NVIC, SYSTICK, MPU) functionalities.
|
(NVIC, SYSTICK, MPU) functionalities.
|
||||||
|
|
||||||
|
|
||||||
@endverbatim
|
@endverbatim
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if (__MPU_PRESENT == 1U)
|
#if (__MPU_PRESENT == 1U)
|
||||||
/**
|
/**
|
||||||
* @brief Disables the MPU
|
* @brief Disables the MPU
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_MPU_Disable(void)
|
void HAL_MPU_Disable(void) {
|
||||||
{
|
|
||||||
/* Make sure outstanding transfers are done */
|
/* Make sure outstanding transfers are done */
|
||||||
__DMB();
|
__DMB();
|
||||||
|
|
||||||
/* Disable fault exceptions */
|
/* Disable fault exceptions */
|
||||||
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||||
|
|
||||||
/* Disable the MPU and clear the control register*/
|
/* Disable the MPU and clear the control register*/
|
||||||
MPU->CTRL = 0U;
|
MPU->CTRL = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable the MPU.
|
* @brief Enable the MPU.
|
||||||
* @param MPU_Control: Specifies the control mode of the MPU during hard fault,
|
* @param MPU_Control: Specifies the control mode of the MPU during hard fault,
|
||||||
* NMI, FAULTMASK and privileged access to the default memory
|
* NMI, FAULTMASK and privileged access to the default memory
|
||||||
* This parameter can be one of the following values:
|
* This parameter can be one of the following values:
|
||||||
* @arg MPU_HFNMI_PRIVDEF_NONE
|
* @arg MPU_HFNMI_PRIVDEF_NONE
|
||||||
* @arg MPU_HARDFAULT_NMI
|
* @arg MPU_HARDFAULT_NMI
|
||||||
* @arg MPU_PRIVILEGED_DEFAULT
|
* @arg MPU_PRIVILEGED_DEFAULT
|
||||||
* @arg MPU_HFNMI_PRIVDEF
|
* @arg MPU_HFNMI_PRIVDEF
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_MPU_Enable(uint32_t MPU_Control)
|
void HAL_MPU_Enable(uint32_t MPU_Control) {
|
||||||
{
|
|
||||||
/* Enable the MPU */
|
/* Enable the MPU */
|
||||||
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||||
|
|
||||||
/* Enable fault exceptions */
|
/* Enable fault exceptions */
|
||||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||||
|
|
||||||
/* Ensure MPU setting take effects */
|
/* Ensure MPU setting take effects */
|
||||||
__DSB();
|
__DSB();
|
||||||
__ISB();
|
__ISB();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes and configures the Region and the memory to be protected.
|
* @brief Initializes and configures the Region and the memory to be protected.
|
||||||
* @param MPU_Init: Pointer to a MPU_Region_InitTypeDef structure that contains
|
* @param MPU_Init: Pointer to a MPU_Region_InitTypeDef structure that contains
|
||||||
* the initialization and configuration information.
|
* the initialization and configuration information.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
|
void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
|
assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
|
||||||
assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
|
assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
|
||||||
@@ -322,8 +309,7 @@ void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
|
|||||||
/* Set the Region number */
|
/* Set the Region number */
|
||||||
MPU->RNR = MPU_Init->Number;
|
MPU->RNR = MPU_Init->Number;
|
||||||
|
|
||||||
if ((MPU_Init->Enable) != RESET)
|
if ((MPU_Init->Enable) != RESET) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
|
assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
|
||||||
assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
|
assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
|
||||||
@@ -333,20 +319,12 @@ void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
|
|||||||
assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
|
assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
|
||||||
assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
|
assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
|
||||||
assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
|
assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
|
||||||
|
|
||||||
MPU->RBAR = MPU_Init->BaseAddress;
|
MPU->RBAR = MPU_Init->BaseAddress;
|
||||||
MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) |
|
MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) | ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) | ((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos)
|
||||||
((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) |
|
| ((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) | ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) | ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos)
|
||||||
((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) |
|
| ((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) | ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) | ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
|
||||||
((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) |
|
} else {
|
||||||
((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) |
|
|
||||||
((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
|
|
||||||
((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) |
|
|
||||||
((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) |
|
|
||||||
((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MPU->RBAR = 0x00U;
|
MPU->RBAR = 0x00U;
|
||||||
MPU->RASR = 0x00U;
|
MPU->RASR = 0x00U;
|
||||||
}
|
}
|
||||||
@@ -354,71 +332,67 @@ void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
|
|||||||
#endif /* __MPU_PRESENT */
|
#endif /* __MPU_PRESENT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the priority grouping field from the NVIC Interrupt Controller.
|
* @brief Gets the priority grouping field from the NVIC Interrupt Controller.
|
||||||
* @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
|
* @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
|
||||||
*/
|
*/
|
||||||
uint32_t HAL_NVIC_GetPriorityGrouping(void)
|
uint32_t HAL_NVIC_GetPriorityGrouping(void) {
|
||||||
{
|
|
||||||
/* Get the PRIGROUP[10:8] field value */
|
/* Get the PRIGROUP[10:8] field value */
|
||||||
return NVIC_GetPriorityGrouping();
|
return NVIC_GetPriorityGrouping();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the priority of an interrupt.
|
* @brief Gets the priority of an interrupt.
|
||||||
* @param IRQn: External interrupt number.
|
* @param IRQn: External interrupt number.
|
||||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||||
* @param PriorityGroup: the priority grouping bits length.
|
* @param PriorityGroup: the priority grouping bits length.
|
||||||
* This parameter can be one of the following values:
|
* This parameter can be one of the following values:
|
||||||
* @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
|
* @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
|
||||||
* 4 bits for subpriority
|
* 4 bits for subpriority
|
||||||
* @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
|
* @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
|
||||||
* 3 bits for subpriority
|
* 3 bits for subpriority
|
||||||
* @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
|
* @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
|
||||||
* 2 bits for subpriority
|
* 2 bits for subpriority
|
||||||
* @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
|
* @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
|
||||||
* 1 bits for subpriority
|
* 1 bits for subpriority
|
||||||
* @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
|
* @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
|
||||||
* 0 bits for subpriority
|
* 0 bits for subpriority
|
||||||
* @param pPreemptPriority: Pointer on the Preemptive priority value (starting from 0).
|
* @param pPreemptPriority: Pointer on the Preemptive priority value (starting from 0).
|
||||||
* @param pSubPriority: Pointer on the Subpriority value (starting from 0).
|
* @param pSubPriority: Pointer on the Subpriority value (starting from 0).
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
|
void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
|
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
|
||||||
/* Get priority for Cortex-M system or device specific interrupts */
|
/* Get priority for Cortex-M system or device specific interrupts */
|
||||||
NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
|
NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets Pending bit of an external interrupt.
|
* @brief Sets Pending bit of an external interrupt.
|
||||||
* @param IRQn External interrupt number
|
* @param IRQn External interrupt number
|
||||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
/* Set interrupt pending */
|
/* Set interrupt pending */
|
||||||
NVIC_SetPendingIRQ(IRQn);
|
NVIC_SetPendingIRQ(IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets Pending Interrupt (reads the pending register in the NVIC
|
* @brief Gets Pending Interrupt (reads the pending register in the NVIC
|
||||||
* and returns the pending bit for the specified interrupt).
|
* and returns the pending bit for the specified interrupt).
|
||||||
* @param IRQn External interrupt number.
|
* @param IRQn External interrupt number.
|
||||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||||
* @retval status: - 0 Interrupt status is not pending.
|
* @retval status: - 0 Interrupt status is not pending.
|
||||||
* - 1 Interrupt status is pending.
|
* - 1 Interrupt status is pending.
|
||||||
*/
|
*/
|
||||||
uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
@@ -427,14 +401,13 @@ uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clears the pending bit of an external interrupt.
|
* @brief Clears the pending bit of an external interrupt.
|
||||||
* @param IRQn External interrupt number.
|
* @param IRQn External interrupt number.
|
||||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
@@ -443,15 +416,14 @@ void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit).
|
* @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit).
|
||||||
* @param IRQn External interrupt number
|
* @param IRQn External interrupt number
|
||||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||||
* @retval status: - 0 Interrupt status is not pending.
|
* @retval status: - 0 Interrupt status is not pending.
|
||||||
* - 1 Interrupt status is pending.
|
* - 1 Interrupt status is pending.
|
||||||
*/
|
*/
|
||||||
uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
|
uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||||
|
|
||||||
@@ -460,62 +432,54 @@ uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures the SysTick clock source.
|
* @brief Configures the SysTick clock source.
|
||||||
* @param CLKSource: specifies the SysTick clock source.
|
* @param CLKSource: specifies the SysTick clock source.
|
||||||
* This parameter can be one of the following values:
|
* This parameter can be one of the following values:
|
||||||
* @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
|
* @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
|
||||||
* @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
|
* @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
|
void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
|
assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
|
||||||
if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
|
if (CLKSource == SYSTICK_CLKSOURCE_HCLK) {
|
||||||
{
|
|
||||||
SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
|
SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
|
SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles SYSTICK interrupt request.
|
* @brief This function handles SYSTICK interrupt request.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_SYSTICK_IRQHandler(void)
|
void HAL_SYSTICK_IRQHandler(void) { HAL_SYSTICK_Callback(); }
|
||||||
{
|
|
||||||
HAL_SYSTICK_Callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SYSTICK callback.
|
* @brief SYSTICK callback.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
__weak void HAL_SYSTICK_Callback(void)
|
__weak void HAL_SYSTICK_Callback(void) {
|
||||||
{
|
|
||||||
/* NOTE : This function Should not be modified, when the callback is needed,
|
/* NOTE : This function Should not be modified, when the callback is needed,
|
||||||
the HAL_SYSTICK_Callback could be implemented in the user file
|
the HAL_SYSTICK_Callback could be implemented in the user file
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
==============================================================================
|
==============================================================================
|
||||||
[..]
|
[..]
|
||||||
(#) Enable and configure the peripheral to be connected to the DMA Channel
|
(#) Enable and configure the peripheral to be connected to the DMA Channel
|
||||||
(except for internal SRAM / FLASH memories: no initialization is
|
(except for internal SRAM / FLASH memories: no initialization is
|
||||||
necessary). Please refer to the Reference manual for connection between peripherals
|
necessary). Please refer to the Reference manual for connection between peripherals
|
||||||
and DMA requests.
|
and DMA requests.
|
||||||
|
|
||||||
@@ -23,11 +23,11 @@
|
|||||||
Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
|
Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
|
||||||
using HAL_DMA_Init() function.
|
using HAL_DMA_Init() function.
|
||||||
|
|
||||||
(#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
|
(#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
|
||||||
detection.
|
detection.
|
||||||
|
|
||||||
(#) Use HAL_DMA_Abort() function to abort the current transfer
|
(#) Use HAL_DMA_Abort() function to abort the current transfer
|
||||||
|
|
||||||
-@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
|
-@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
|
||||||
*** Polling mode IO operation ***
|
*** Polling mode IO operation ***
|
||||||
=================================
|
=================================
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
XferErrorCallback (i.e. a member of DMA handle structure).
|
XferErrorCallback (i.e. a member of DMA handle structure).
|
||||||
|
|
||||||
*** DMA HAL driver macros list ***
|
*** DMA HAL driver macros list ***
|
||||||
=============================================
|
=============================================
|
||||||
[..]
|
[..]
|
||||||
Below the list of most used macros in DMA HAL driver.
|
Below the list of most used macros in DMA HAL driver.
|
||||||
|
|
||||||
@@ -61,10 +61,10 @@
|
|||||||
(+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
|
(+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
|
||||||
(+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
|
(+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
|
||||||
(+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
|
(+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
|
||||||
(+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not.
|
(+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not.
|
||||||
|
|
||||||
[..]
|
[..]
|
||||||
(@) You can refer to the DMA HAL driver header file for more useful macros
|
(@) You can refer to the DMA HAL driver header file for more useful macros
|
||||||
|
|
||||||
@endverbatim
|
@endverbatim
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
@@ -101,13 +101,13 @@
|
|||||||
#include "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
|
|
||||||
/** @addtogroup STM32F1xx_HAL_Driver
|
/** @addtogroup STM32F1xx_HAL_Driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup DMA DMA
|
/** @defgroup DMA DMA
|
||||||
* @brief DMA HAL module driver
|
* @brief DMA HAL module driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAL_DMA_MODULE_ENABLED
|
#ifdef HAL_DMA_MODULE_ENABLED
|
||||||
|
|
||||||
@@ -117,21 +117,21 @@
|
|||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
/** @defgroup DMA_Private_Functions DMA Private Functions
|
/** @defgroup DMA_Private_Functions DMA Private Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
|
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Exported functions ---------------------------------------------------------*/
|
/* Exported functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
/** @defgroup DMA_Exported_Functions DMA Exported Functions
|
/** @defgroup DMA_Exported_Functions DMA Exported Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
|
/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||||
* @brief Initialization and de-initialization functions
|
* @brief Initialization and de-initialization functions
|
||||||
*
|
*
|
||||||
@verbatim
|
@verbatim
|
||||||
===============================================================================
|
===============================================================================
|
||||||
@@ -139,30 +139,28 @@ static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t
|
|||||||
===============================================================================
|
===============================================================================
|
||||||
[..]
|
[..]
|
||||||
This section provides functions allowing to initialize the DMA Channel source
|
This section provides functions allowing to initialize the DMA Channel source
|
||||||
and destination addresses, incrementation and data sizes, transfer direction,
|
and destination addresses, incrementation and data sizes, transfer direction,
|
||||||
circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
|
circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
|
||||||
[..]
|
[..]
|
||||||
The HAL_DMA_Init() function follows the DMA configuration procedures as described in
|
The HAL_DMA_Init() function follows the DMA configuration procedures as described in
|
||||||
reference manual.
|
reference manual.
|
||||||
|
|
||||||
@endverbatim
|
@endverbatim
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the DMA according to the specified
|
* @brief Initialize the DMA according to the specified
|
||||||
* parameters in the DMA_InitTypeDef and initialize the associated handle.
|
* parameters in the DMA_InitTypeDef and initialize the associated handle.
|
||||||
* @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
|
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma) {
|
||||||
{
|
|
||||||
uint32_t tmp = 0U;
|
uint32_t tmp = 0U;
|
||||||
|
|
||||||
/* Check the DMA handle allocation */
|
/* Check the DMA handle allocation */
|
||||||
if(hdma == NULL)
|
if (hdma == NULL) {
|
||||||
{
|
|
||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,23 +174,20 @@ HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
|
|||||||
assert_param(IS_DMA_MODE(hdma->Init.Mode));
|
assert_param(IS_DMA_MODE(hdma->Init.Mode));
|
||||||
assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
|
assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
|
||||||
|
|
||||||
#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
|
#if defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F100xE) || defined(STM32F105xC) || defined(STM32F107xC)
|
||||||
/* calculation of the channel index */
|
/* calculation of the channel index */
|
||||||
if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
|
if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1)) {
|
||||||
{
|
|
||||||
/* DMA1 */
|
/* DMA1 */
|
||||||
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
|
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
|
||||||
hdma->DmaBaseAddress = DMA1;
|
hdma->DmaBaseAddress = DMA1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* DMA2 */
|
/* DMA2 */
|
||||||
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
|
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
|
||||||
hdma->DmaBaseAddress = DMA2;
|
hdma->DmaBaseAddress = DMA2;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* DMA1 */
|
/* DMA1 */
|
||||||
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
|
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
|
||||||
hdma->DmaBaseAddress = DMA1;
|
hdma->DmaBaseAddress = DMA1;
|
||||||
#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F100xE || STM32F105xC || STM32F107xC */
|
#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F100xE || STM32F105xC || STM32F107xC */
|
||||||
|
|
||||||
@@ -203,15 +198,10 @@ HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
|
|||||||
tmp = hdma->Instance->CCR;
|
tmp = hdma->Instance->CCR;
|
||||||
|
|
||||||
/* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
|
/* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
|
||||||
tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
|
tmp &= ((uint32_t) ~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | DMA_CCR_DIR));
|
||||||
DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
|
|
||||||
DMA_CCR_DIR));
|
|
||||||
|
|
||||||
/* Prepare the DMA Channel configuration */
|
/* Prepare the DMA Channel configuration */
|
||||||
tmp |= hdma->Init.Direction |
|
tmp |= hdma->Init.Direction | hdma->Init.PeriphInc | hdma->Init.MemInc | hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment | hdma->Init.Mode | hdma->Init.Priority;
|
||||||
hdma->Init.PeriphInc | hdma->Init.MemInc |
|
|
||||||
hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
|
|
||||||
hdma->Init.Mode | hdma->Init.Priority;
|
|
||||||
|
|
||||||
/* Write to DMA Channel CR register */
|
/* Write to DMA Channel CR register */
|
||||||
hdma->Instance->CCR = tmp;
|
hdma->Instance->CCR = tmp;
|
||||||
@@ -228,16 +218,14 @@ HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief DeInitialize the DMA peripheral.
|
* @brief DeInitialize the DMA peripheral.
|
||||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
|
HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) {
|
||||||
{
|
|
||||||
/* Check the DMA handle allocation */
|
/* Check the DMA handle allocation */
|
||||||
if(hdma == NULL)
|
if (hdma == NULL) {
|
||||||
{
|
|
||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,34 +236,31 @@ HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
|
|||||||
__HAL_DMA_DISABLE(hdma);
|
__HAL_DMA_DISABLE(hdma);
|
||||||
|
|
||||||
/* Reset DMA Channel control register */
|
/* Reset DMA Channel control register */
|
||||||
hdma->Instance->CCR = 0U;
|
hdma->Instance->CCR = 0U;
|
||||||
|
|
||||||
/* Reset DMA Channel Number of Data to Transfer register */
|
/* Reset DMA Channel Number of Data to Transfer register */
|
||||||
hdma->Instance->CNDTR = 0U;
|
hdma->Instance->CNDTR = 0U;
|
||||||
|
|
||||||
/* Reset DMA Channel peripheral address register */
|
/* Reset DMA Channel peripheral address register */
|
||||||
hdma->Instance->CPAR = 0U;
|
hdma->Instance->CPAR = 0U;
|
||||||
|
|
||||||
/* Reset DMA Channel memory address register */
|
/* Reset DMA Channel memory address register */
|
||||||
hdma->Instance->CMAR = 0U;
|
hdma->Instance->CMAR = 0U;
|
||||||
|
|
||||||
#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
|
#if defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F100xE) || defined(STM32F105xC) || defined(STM32F107xC)
|
||||||
/* calculation of the channel index */
|
/* calculation of the channel index */
|
||||||
if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
|
if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1)) {
|
||||||
{
|
|
||||||
/* DMA1 */
|
/* DMA1 */
|
||||||
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
|
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
|
||||||
hdma->DmaBaseAddress = DMA1;
|
hdma->DmaBaseAddress = DMA1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* DMA2 */
|
/* DMA2 */
|
||||||
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
|
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
|
||||||
hdma->DmaBaseAddress = DMA2;
|
hdma->DmaBaseAddress = DMA2;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* DMA1 */
|
/* DMA1 */
|
||||||
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
|
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
|
||||||
hdma->DmaBaseAddress = DMA1;
|
hdma->DmaBaseAddress = DMA1;
|
||||||
#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F100xE || STM32F105xC || STM32F107xC */
|
#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F100xE || STM32F105xC || STM32F107xC */
|
||||||
|
|
||||||
@@ -283,10 +268,10 @@ HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
|
|||||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex));
|
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex));
|
||||||
|
|
||||||
/* Clean all callbacks */
|
/* Clean all callbacks */
|
||||||
hdma->XferCpltCallback = NULL;
|
hdma->XferCpltCallback = NULL;
|
||||||
hdma->XferHalfCpltCallback = NULL;
|
hdma->XferHalfCpltCallback = NULL;
|
||||||
hdma->XferErrorCallback = NULL;
|
hdma->XferErrorCallback = NULL;
|
||||||
hdma->XferAbortCallback = NULL;
|
hdma->XferAbortCallback = NULL;
|
||||||
|
|
||||||
/* Reset the error code */
|
/* Reset the error code */
|
||||||
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
||||||
@@ -301,8 +286,8 @@ HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
|
/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
|
||||||
* @brief Input and Output operation functions
|
* @brief Input and Output operation functions
|
||||||
@@ -324,16 +309,15 @@ HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start the DMA Transfer.
|
* @brief Start the DMA Transfer.
|
||||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @param SrcAddress: The source memory Buffer address
|
* @param SrcAddress: The source memory Buffer address
|
||||||
* @param DstAddress: The destination memory Buffer address
|
* @param DstAddress: The destination memory Buffer address
|
||||||
* @param DataLength: The length of data to be transferred from source to destination
|
* @param DataLength: The length of data to be transferred from source to destination
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) {
|
||||||
{
|
|
||||||
HAL_StatusTypeDef status = HAL_OK;
|
HAL_StatusTypeDef status = HAL_OK;
|
||||||
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
@@ -342,41 +326,37 @@ HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, ui
|
|||||||
/* Process locked */
|
/* Process locked */
|
||||||
__HAL_LOCK(hdma);
|
__HAL_LOCK(hdma);
|
||||||
|
|
||||||
if(HAL_DMA_STATE_READY == hdma->State)
|
if (HAL_DMA_STATE_READY == hdma->State) {
|
||||||
{
|
|
||||||
/* Change DMA peripheral state */
|
/* Change DMA peripheral state */
|
||||||
hdma->State = HAL_DMA_STATE_BUSY;
|
hdma->State = HAL_DMA_STATE_BUSY;
|
||||||
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
||||||
|
|
||||||
/* Disable the peripheral */
|
/* Disable the peripheral */
|
||||||
__HAL_DMA_DISABLE(hdma);
|
__HAL_DMA_DISABLE(hdma);
|
||||||
|
|
||||||
/* Configure the source, destination address and the data length & clear flags*/
|
/* Configure the source, destination address and the data length & clear flags*/
|
||||||
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
|
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
|
||||||
|
|
||||||
/* Enable the Peripheral */
|
/* Enable the Peripheral */
|
||||||
__HAL_DMA_ENABLE(hdma);
|
__HAL_DMA_ENABLE(hdma);
|
||||||
|
} else {
|
||||||
|
/* Process Unlocked */
|
||||||
|
__HAL_UNLOCK(hdma);
|
||||||
|
status = HAL_BUSY;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Process Unlocked */
|
|
||||||
__HAL_UNLOCK(hdma);
|
|
||||||
status = HAL_BUSY;
|
|
||||||
}
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start the DMA Transfer with interrupt enabled.
|
* @brief Start the DMA Transfer with interrupt enabled.
|
||||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @param SrcAddress: The source memory Buffer address
|
* @param SrcAddress: The source memory Buffer address
|
||||||
* @param DstAddress: The destination memory Buffer address
|
* @param DstAddress: The destination memory Buffer address
|
||||||
* @param DataLength: The length of data to be transferred from source to destination
|
* @param DataLength: The length of data to be transferred from source to destination
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) {
|
||||||
{
|
|
||||||
HAL_StatusTypeDef status = HAL_OK;
|
HAL_StatusTypeDef status = HAL_OK;
|
||||||
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
@@ -384,61 +364,54 @@ HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress,
|
|||||||
|
|
||||||
/* Process locked */
|
/* Process locked */
|
||||||
__HAL_LOCK(hdma);
|
__HAL_LOCK(hdma);
|
||||||
|
|
||||||
if(HAL_DMA_STATE_READY == hdma->State)
|
if (HAL_DMA_STATE_READY == hdma->State) {
|
||||||
{
|
|
||||||
/* Change DMA peripheral state */
|
/* Change DMA peripheral state */
|
||||||
hdma->State = HAL_DMA_STATE_BUSY;
|
hdma->State = HAL_DMA_STATE_BUSY;
|
||||||
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
||||||
|
|
||||||
/* Disable the peripheral */
|
/* Disable the peripheral */
|
||||||
__HAL_DMA_DISABLE(hdma);
|
__HAL_DMA_DISABLE(hdma);
|
||||||
|
|
||||||
/* Configure the source, destination address and the data length & clear flags*/
|
/* Configure the source, destination address and the data length & clear flags*/
|
||||||
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
|
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
|
||||||
|
|
||||||
/* Enable the transfer complete interrupt */
|
/* Enable the transfer complete interrupt */
|
||||||
/* Enable the transfer Error interrupt */
|
/* Enable the transfer Error interrupt */
|
||||||
if(NULL != hdma->XferHalfCpltCallback)
|
if (NULL != hdma->XferHalfCpltCallback) {
|
||||||
{
|
|
||||||
/* Enable the Half transfer complete interrupt as well */
|
/* Enable the Half transfer complete interrupt as well */
|
||||||
__HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
__HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
|
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
|
||||||
__HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
|
__HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
|
||||||
}
|
}
|
||||||
/* Enable the Peripheral */
|
/* Enable the Peripheral */
|
||||||
__HAL_DMA_ENABLE(hdma);
|
__HAL_DMA_ENABLE(hdma);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Process Unlocked */
|
/* Process Unlocked */
|
||||||
__HAL_UNLOCK(hdma);
|
__HAL_UNLOCK(hdma);
|
||||||
|
|
||||||
/* Remain BUSY */
|
/* Remain BUSY */
|
||||||
status = HAL_BUSY;
|
status = HAL_BUSY;
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Abort the DMA Transfer.
|
* @brief Abort the DMA Transfer.
|
||||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
|
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma) {
|
||||||
{
|
|
||||||
HAL_StatusTypeDef status = HAL_OK;
|
HAL_StatusTypeDef status = HAL_OK;
|
||||||
|
|
||||||
/* Disable DMA IT */
|
/* Disable DMA IT */
|
||||||
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
||||||
|
|
||||||
/* Disable the channel */
|
/* Disable the channel */
|
||||||
__HAL_DMA_DISABLE(hdma);
|
__HAL_DMA_DISABLE(hdma);
|
||||||
|
|
||||||
/* Clear all flags */
|
/* Clear all flags */
|
||||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
|
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
|
||||||
|
|
||||||
@@ -446,30 +419,26 @@ HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
|
|||||||
hdma->State = HAL_DMA_STATE_READY;
|
hdma->State = HAL_DMA_STATE_READY;
|
||||||
|
|
||||||
/* Process Unlocked */
|
/* Process Unlocked */
|
||||||
__HAL_UNLOCK(hdma);
|
__HAL_UNLOCK(hdma);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Aborts the DMA Transfer in Interrupt mode.
|
* @brief Aborts the DMA Transfer in Interrupt mode.
|
||||||
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
|
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma) {
|
||||||
{
|
|
||||||
HAL_StatusTypeDef status = HAL_OK;
|
HAL_StatusTypeDef status = HAL_OK;
|
||||||
|
|
||||||
if(HAL_DMA_STATE_BUSY != hdma->State)
|
if (HAL_DMA_STATE_BUSY != hdma->State) {
|
||||||
{
|
|
||||||
/* no transfer ongoing */
|
/* no transfer ongoing */
|
||||||
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
|
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
|
||||||
|
|
||||||
status = HAL_ERROR;
|
status = HAL_ERROR;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Disable DMA IT */
|
/* Disable DMA IT */
|
||||||
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
||||||
|
|
||||||
@@ -486,29 +455,26 @@ HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
|
|||||||
__HAL_UNLOCK(hdma);
|
__HAL_UNLOCK(hdma);
|
||||||
|
|
||||||
/* Call User Abort callback */
|
/* Call User Abort callback */
|
||||||
if(hdma->XferAbortCallback != NULL)
|
if (hdma->XferAbortCallback != NULL) {
|
||||||
{
|
|
||||||
hdma->XferAbortCallback(hdma);
|
hdma->XferAbortCallback(hdma);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Polling for transfer complete.
|
* @brief Polling for transfer complete.
|
||||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @param CompleteLevel: Specifies the DMA level complete.
|
* @param CompleteLevel: Specifies the DMA level complete.
|
||||||
* @param Timeout: Timeout duration.
|
* @param Timeout: Timeout duration.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
|
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout) {
|
||||||
{
|
|
||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
uint32_t tickstart = 0U;
|
uint32_t tickstart = 0U;
|
||||||
|
|
||||||
if(HAL_DMA_STATE_BUSY != hdma->State)
|
if (HAL_DMA_STATE_BUSY != hdma->State) {
|
||||||
{
|
|
||||||
/* no transfer ongoing */
|
/* no transfer ongoing */
|
||||||
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
|
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
|
||||||
__HAL_UNLOCK(hdma);
|
__HAL_UNLOCK(hdma);
|
||||||
@@ -516,20 +482,16 @@ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t Comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Polling mode not supported in circular mode */
|
/* Polling mode not supported in circular mode */
|
||||||
if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC))
|
if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC)) {
|
||||||
{
|
|
||||||
hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
|
hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
|
||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the level transfer complete flag */
|
/* Get the level transfer complete flag */
|
||||||
if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
|
if (CompleteLevel == HAL_DMA_FULL_TRANSFER) {
|
||||||
{
|
|
||||||
/* Transfer Complete flag */
|
/* Transfer Complete flag */
|
||||||
temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
|
temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Half Transfer Complete flag */
|
/* Half Transfer Complete flag */
|
||||||
temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
|
temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
|
||||||
}
|
}
|
||||||
@@ -537,10 +499,8 @@ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t Comp
|
|||||||
/* Get tick */
|
/* Get tick */
|
||||||
tickstart = HAL_GetTick();
|
tickstart = HAL_GetTick();
|
||||||
|
|
||||||
while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
|
while (__HAL_DMA_GET_FLAG(hdma, temp) == RESET) {
|
||||||
{
|
if ((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)) {
|
||||||
if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
|
|
||||||
{
|
|
||||||
/* When a DMA transfer error occurs */
|
/* When a DMA transfer error occurs */
|
||||||
/* A hardware clear of its EN bits is performed */
|
/* A hardware clear of its EN bits is performed */
|
||||||
/* Clear all flags */
|
/* Clear all flags */
|
||||||
@@ -550,7 +510,7 @@ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t Comp
|
|||||||
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
|
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
|
||||||
|
|
||||||
/* Change the DMA state */
|
/* Change the DMA state */
|
||||||
hdma->State= HAL_DMA_STATE_READY;
|
hdma->State = HAL_DMA_STATE_READY;
|
||||||
|
|
||||||
/* Process Unlocked */
|
/* Process Unlocked */
|
||||||
__HAL_UNLOCK(hdma);
|
__HAL_UNLOCK(hdma);
|
||||||
@@ -558,10 +518,8 @@ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t Comp
|
|||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
/* Check for the Timeout */
|
/* Check for the Timeout */
|
||||||
if(Timeout != HAL_MAX_DELAY)
|
if (Timeout != HAL_MAX_DELAY) {
|
||||||
{
|
if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) {
|
||||||
if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
|
|
||||||
{
|
|
||||||
/* Update error code */
|
/* Update error code */
|
||||||
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
|
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
|
||||||
|
|
||||||
@@ -576,21 +534,18 @@ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t Comp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
|
if (CompleteLevel == HAL_DMA_FULL_TRANSFER) {
|
||||||
{
|
|
||||||
/* Clear the transfer complete flag */
|
/* Clear the transfer complete flag */
|
||||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
||||||
|
|
||||||
/* The selected Channelx EN bit is cleared (DMA is disabled and
|
/* The selected Channelx EN bit is cleared (DMA is disabled and
|
||||||
all transfers are complete) */
|
all transfers are complete) */
|
||||||
hdma->State = HAL_DMA_STATE_READY;
|
hdma->State = HAL_DMA_STATE_READY;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Clear the half transfer complete flag */
|
/* Clear the half transfer complete flag */
|
||||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
|
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process unlocked */
|
/* Process unlocked */
|
||||||
__HAL_UNLOCK(hdma);
|
__HAL_UNLOCK(hdma);
|
||||||
|
|
||||||
@@ -598,22 +553,19 @@ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t Comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles DMA interrupt request.
|
* @brief Handles DMA interrupt request.
|
||||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
|
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) {
|
||||||
{
|
uint32_t flag_it = hdma->DmaBaseAddress->ISR;
|
||||||
uint32_t flag_it = hdma->DmaBaseAddress->ISR;
|
|
||||||
uint32_t source_it = hdma->Instance->CCR;
|
uint32_t source_it = hdma->Instance->CCR;
|
||||||
|
|
||||||
/* Half Transfer Complete Interrupt management ******************************/
|
/* Half Transfer Complete Interrupt management ******************************/
|
||||||
if (((flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_HT) != RESET))
|
if (((flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_HT) != RESET)) {
|
||||||
{
|
|
||||||
/* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
|
/* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
|
||||||
if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) {
|
||||||
{
|
|
||||||
/* Disable the half transfer interrupt */
|
/* Disable the half transfer interrupt */
|
||||||
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
|
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
|
||||||
}
|
}
|
||||||
@@ -623,40 +575,35 @@ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
|
|||||||
/* DMA peripheral state is not updated in Half Transfer */
|
/* DMA peripheral state is not updated in Half Transfer */
|
||||||
/* but in Transfer Complete case */
|
/* but in Transfer Complete case */
|
||||||
|
|
||||||
if(hdma->XferHalfCpltCallback != NULL)
|
if (hdma->XferHalfCpltCallback != NULL) {
|
||||||
{
|
|
||||||
/* Half transfer callback */
|
/* Half transfer callback */
|
||||||
hdma->XferHalfCpltCallback(hdma);
|
hdma->XferHalfCpltCallback(hdma);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transfer Complete Interrupt management ***********************************/
|
/* Transfer Complete Interrupt management ***********************************/
|
||||||
else if (((flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_TC) != RESET))
|
else if (((flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_TC) != RESET)) {
|
||||||
{
|
if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) {
|
||||||
if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
|
||||||
{
|
|
||||||
/* Disable the transfer complete and error interrupt */
|
/* Disable the transfer complete and error interrupt */
|
||||||
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
|
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
|
||||||
|
|
||||||
/* Change the DMA state */
|
/* Change the DMA state */
|
||||||
hdma->State = HAL_DMA_STATE_READY;
|
hdma->State = HAL_DMA_STATE_READY;
|
||||||
}
|
}
|
||||||
/* Clear the transfer complete flag */
|
/* Clear the transfer complete flag */
|
||||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
||||||
|
|
||||||
/* Process Unlocked */
|
/* Process Unlocked */
|
||||||
__HAL_UNLOCK(hdma);
|
__HAL_UNLOCK(hdma);
|
||||||
|
|
||||||
if(hdma->XferCpltCallback != NULL)
|
if (hdma->XferCpltCallback != NULL) {
|
||||||
{
|
|
||||||
/* Transfer complete callback */
|
/* Transfer complete callback */
|
||||||
hdma->XferCpltCallback(hdma);
|
hdma->XferCpltCallback(hdma);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transfer Error Interrupt management **************************************/
|
/* Transfer Error Interrupt management **************************************/
|
||||||
else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
|
else if ((RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE))) {
|
||||||
{
|
|
||||||
/* When a DMA transfer error occurs */
|
/* When a DMA transfer error occurs */
|
||||||
/* A hardware clear of its EN bits is performed */
|
/* A hardware clear of its EN bits is performed */
|
||||||
/* Disable ALL DMA IT */
|
/* Disable ALL DMA IT */
|
||||||
@@ -674,8 +621,7 @@ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
|
|||||||
/* Process Unlocked */
|
/* Process Unlocked */
|
||||||
__HAL_UNLOCK(hdma);
|
__HAL_UNLOCK(hdma);
|
||||||
|
|
||||||
if (hdma->XferErrorCallback != NULL)
|
if (hdma->XferErrorCallback != NULL) {
|
||||||
{
|
|
||||||
/* Transfer error callback */
|
/* Transfer error callback */
|
||||||
hdma->XferErrorCallback(hdma);
|
hdma->XferErrorCallback(hdma);
|
||||||
}
|
}
|
||||||
@@ -684,119 +630,109 @@ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Register callbacks
|
* @brief Register callbacks
|
||||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @param CallbackID: User Callback identifer
|
* @param CallbackID: User Callback identifer
|
||||||
* a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
|
* a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
|
||||||
* @param pCallback: pointer to private callbacsk function which has pointer to
|
* @param pCallback: pointer to private callbacsk function which has pointer to
|
||||||
* a DMA_HandleTypeDef structure as parameter.
|
* a DMA_HandleTypeDef structure as parameter.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma))
|
HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (*pCallback)(DMA_HandleTypeDef *_hdma)) {
|
||||||
{
|
|
||||||
HAL_StatusTypeDef status = HAL_OK;
|
HAL_StatusTypeDef status = HAL_OK;
|
||||||
|
|
||||||
/* Process locked */
|
/* Process locked */
|
||||||
__HAL_LOCK(hdma);
|
__HAL_LOCK(hdma);
|
||||||
|
|
||||||
if(HAL_DMA_STATE_READY == hdma->State)
|
if (HAL_DMA_STATE_READY == hdma->State) {
|
||||||
{
|
switch (CallbackID) {
|
||||||
switch (CallbackID)
|
case HAL_DMA_XFER_CPLT_CB_ID:
|
||||||
{
|
|
||||||
case HAL_DMA_XFER_CPLT_CB_ID:
|
|
||||||
hdma->XferCpltCallback = pCallback;
|
hdma->XferCpltCallback = pCallback;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HAL_DMA_XFER_HALFCPLT_CB_ID:
|
|
||||||
hdma->XferHalfCpltCallback = pCallback;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HAL_DMA_XFER_ERROR_CB_ID:
|
case HAL_DMA_XFER_HALFCPLT_CB_ID:
|
||||||
|
hdma->XferHalfCpltCallback = pCallback;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAL_DMA_XFER_ERROR_CB_ID:
|
||||||
hdma->XferErrorCallback = pCallback;
|
hdma->XferErrorCallback = pCallback;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HAL_DMA_XFER_ABORT_CB_ID:
|
case HAL_DMA_XFER_ABORT_CB_ID:
|
||||||
hdma->XferAbortCallback = pCallback;
|
hdma->XferAbortCallback = pCallback;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
status = HAL_ERROR;
|
status = HAL_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
status = HAL_ERROR;
|
status = HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release Lock */
|
/* Release Lock */
|
||||||
__HAL_UNLOCK(hdma);
|
__HAL_UNLOCK(hdma);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief UnRegister callbacks
|
* @brief UnRegister callbacks
|
||||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @param CallbackID: User Callback identifer
|
* @param CallbackID: User Callback identifer
|
||||||
* a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
|
* a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
|
HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID) {
|
||||||
{
|
|
||||||
HAL_StatusTypeDef status = HAL_OK;
|
HAL_StatusTypeDef status = HAL_OK;
|
||||||
|
|
||||||
/* Process locked */
|
/* Process locked */
|
||||||
__HAL_LOCK(hdma);
|
__HAL_LOCK(hdma);
|
||||||
|
|
||||||
if(HAL_DMA_STATE_READY == hdma->State)
|
if (HAL_DMA_STATE_READY == hdma->State) {
|
||||||
{
|
switch (CallbackID) {
|
||||||
switch (CallbackID)
|
case HAL_DMA_XFER_CPLT_CB_ID:
|
||||||
{
|
|
||||||
case HAL_DMA_XFER_CPLT_CB_ID:
|
|
||||||
hdma->XferCpltCallback = NULL;
|
hdma->XferCpltCallback = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HAL_DMA_XFER_HALFCPLT_CB_ID:
|
case HAL_DMA_XFER_HALFCPLT_CB_ID:
|
||||||
hdma->XferHalfCpltCallback = NULL;
|
hdma->XferHalfCpltCallback = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HAL_DMA_XFER_ERROR_CB_ID:
|
case HAL_DMA_XFER_ERROR_CB_ID:
|
||||||
hdma->XferErrorCallback = NULL;
|
hdma->XferErrorCallback = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HAL_DMA_XFER_ABORT_CB_ID:
|
case HAL_DMA_XFER_ABORT_CB_ID:
|
||||||
hdma->XferAbortCallback = NULL;
|
hdma->XferAbortCallback = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HAL_DMA_XFER_ALL_CB_ID:
|
case HAL_DMA_XFER_ALL_CB_ID:
|
||||||
hdma->XferCpltCallback = NULL;
|
hdma->XferCpltCallback = NULL;
|
||||||
hdma->XferHalfCpltCallback = NULL;
|
hdma->XferHalfCpltCallback = NULL;
|
||||||
hdma->XferErrorCallback = NULL;
|
hdma->XferErrorCallback = NULL;
|
||||||
hdma->XferAbortCallback = NULL;
|
hdma->XferAbortCallback = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
status = HAL_ERROR;
|
status = HAL_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
status = HAL_ERROR;
|
status = HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release Lock */
|
/* Release Lock */
|
||||||
__HAL_UNLOCK(hdma);
|
__HAL_UNLOCK(hdma);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
|
/** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
|
||||||
* @brief Peripheral State and Errors functions
|
* @brief Peripheral State and Errors functions
|
||||||
@@ -804,7 +740,7 @@ HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_Ca
|
|||||||
@verbatim
|
@verbatim
|
||||||
===============================================================================
|
===============================================================================
|
||||||
##### Peripheral State and Errors functions #####
|
##### Peripheral State and Errors functions #####
|
||||||
===============================================================================
|
===============================================================================
|
||||||
[..]
|
[..]
|
||||||
This subsection provides functions allowing to
|
This subsection provides functions allowing to
|
||||||
(+) Check the DMA state
|
(+) Check the DMA state
|
||||||
@@ -815,51 +751,46 @@ HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_Ca
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the DMA hande state.
|
* @brief Return the DMA hande state.
|
||||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @retval HAL state
|
* @retval HAL state
|
||||||
*/
|
*/
|
||||||
HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
|
HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma) {
|
||||||
{
|
|
||||||
/* Return DMA handle state */
|
/* Return DMA handle state */
|
||||||
return hdma->State;
|
return hdma->State;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the DMA error code.
|
* @brief Return the DMA error code.
|
||||||
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @retval DMA Error Code
|
* @retval DMA Error Code
|
||||||
*/
|
*/
|
||||||
uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
|
uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma) { return hdma->ErrorCode; }
|
||||||
{
|
|
||||||
return hdma->ErrorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @addtogroup DMA_Private_Functions
|
/** @addtogroup DMA_Private_Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the DMA Transfer parameter.
|
* @brief Sets the DMA Transfer parameter.
|
||||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified DMA Channel.
|
* the configuration information for the specified DMA Channel.
|
||||||
* @param SrcAddress: The source memory Buffer address
|
* @param SrcAddress: The source memory Buffer address
|
||||||
* @param DstAddress: The destination memory Buffer address
|
* @param DstAddress: The destination memory Buffer address
|
||||||
* @param DataLength: The length of data to be transferred from source to destination
|
* @param DataLength: The length of data to be transferred from source to destination
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) {
|
||||||
{
|
|
||||||
/* Clear all flags */
|
/* Clear all flags */
|
||||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
|
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
|
||||||
|
|
||||||
@@ -867,8 +798,7 @@ static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t
|
|||||||
hdma->Instance->CNDTR = DataLength;
|
hdma->Instance->CNDTR = DataLength;
|
||||||
|
|
||||||
/* Memory to Peripheral */
|
/* Memory to Peripheral */
|
||||||
if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
|
if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) {
|
||||||
{
|
|
||||||
/* Configure DMA Channel destination address */
|
/* Configure DMA Channel destination address */
|
||||||
hdma->Instance->CPAR = DstAddress;
|
hdma->Instance->CPAR = DstAddress;
|
||||||
|
|
||||||
@@ -876,8 +806,7 @@ static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t
|
|||||||
hdma->Instance->CMAR = SrcAddress;
|
hdma->Instance->CMAR = SrcAddress;
|
||||||
}
|
}
|
||||||
/* Peripheral to Memory */
|
/* Peripheral to Memory */
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
/* Configure DMA Channel source address */
|
/* Configure DMA Channel source address */
|
||||||
hdma->Instance->CPAR = SrcAddress;
|
hdma->Instance->CPAR = SrcAddress;
|
||||||
|
|
||||||
@@ -887,16 +816,16 @@ static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -121,52 +121,52 @@
|
|||||||
#include "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
|
|
||||||
/** @addtogroup STM32F1xx_HAL_Driver
|
/** @addtogroup STM32F1xx_HAL_Driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup GPIO GPIO
|
/** @defgroup GPIO GPIO
|
||||||
* @brief GPIO HAL module driver
|
* @brief GPIO HAL module driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
/* Private define ------------------------------------------------------------*/
|
/* Private define ------------------------------------------------------------*/
|
||||||
/** @addtogroup GPIO_Private_Constants GPIO Private Constants
|
/** @addtogroup GPIO_Private_Constants GPIO Private Constants
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define GPIO_MODE 0x00000003U
|
#define GPIO_MODE 0x00000003U
|
||||||
#define EXTI_MODE 0x10000000U
|
#define EXTI_MODE 0x10000000U
|
||||||
#define GPIO_MODE_IT 0x00010000U
|
#define GPIO_MODE_IT 0x00010000U
|
||||||
#define GPIO_MODE_EVT 0x00020000U
|
#define GPIO_MODE_EVT 0x00020000U
|
||||||
#define RISING_EDGE 0x00100000U
|
#define RISING_EDGE 0x00100000U
|
||||||
#define FALLING_EDGE 0x00200000U
|
#define FALLING_EDGE 0x00200000U
|
||||||
#define GPIO_OUTPUT_TYPE 0x00000010U
|
#define GPIO_OUTPUT_TYPE 0x00000010U
|
||||||
|
|
||||||
#define GPIO_NUMBER 16U
|
#define GPIO_NUMBER 16U
|
||||||
|
|
||||||
/* Definitions for bit manipulation of CRL and CRH register */
|
/* Definitions for bit manipulation of CRL and CRH register */
|
||||||
#define GPIO_CR_MODE_INPUT 0x00000000U /*!< 00: Input mode (reset state) */
|
#define GPIO_CR_MODE_INPUT 0x00000000U /*!< 00: Input mode (reset state) */
|
||||||
#define GPIO_CR_CNF_ANALOG 0x00000000U /*!< 00: Analog mode */
|
#define GPIO_CR_CNF_ANALOG 0x00000000U /*!< 00: Analog mode */
|
||||||
#define GPIO_CR_CNF_INPUT_FLOATING 0x00000004U /*!< 01: Floating input (reset state) */
|
#define GPIO_CR_CNF_INPUT_FLOATING 0x00000004U /*!< 01: Floating input (reset state) */
|
||||||
#define GPIO_CR_CNF_INPUT_PU_PD 0x00000008U /*!< 10: Input with pull-up / pull-down */
|
#define GPIO_CR_CNF_INPUT_PU_PD 0x00000008U /*!< 10: Input with pull-up / pull-down */
|
||||||
#define GPIO_CR_CNF_GP_OUTPUT_PP 0x00000000U /*!< 00: General purpose output push-pull */
|
#define GPIO_CR_CNF_GP_OUTPUT_PP 0x00000000U /*!< 00: General purpose output push-pull */
|
||||||
#define GPIO_CR_CNF_GP_OUTPUT_OD 0x00000004U /*!< 01: General purpose output Open-drain */
|
#define GPIO_CR_CNF_GP_OUTPUT_OD 0x00000004U /*!< 01: General purpose output Open-drain */
|
||||||
#define GPIO_CR_CNF_AF_OUTPUT_PP 0x00000008U /*!< 10: Alternate function output Push-pull */
|
#define GPIO_CR_CNF_AF_OUTPUT_PP 0x00000008U /*!< 10: Alternate function output Push-pull */
|
||||||
#define GPIO_CR_CNF_AF_OUTPUT_OD 0x0000000CU /*!< 11: Alternate function output Open-drain */
|
#define GPIO_CR_CNF_AF_OUTPUT_OD 0x0000000CU /*!< 11: Alternate function output Open-drain */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
/* Private macro -------------------------------------------------------------*/
|
/* Private macro -------------------------------------------------------------*/
|
||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
/* Private functions ---------------------------------------------------------*/
|
/* Private functions ---------------------------------------------------------*/
|
||||||
/* Exported functions --------------------------------------------------------*/
|
/* Exported functions --------------------------------------------------------*/
|
||||||
/** @defgroup GPIO_Exported_Functions GPIO Exported Functions
|
/** @defgroup GPIO_Exported_Functions GPIO Exported Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions
|
/** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||||
* @brief Initialization and Configuration functions
|
* @brief Initialization and Configuration functions
|
||||||
@@ -183,23 +183,21 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
|
* @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
|
||||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||||
* @param GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
|
* @param GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
|
||||||
* the configuration information for the specified GPIO peripheral.
|
* the configuration information for the specified GPIO peripheral.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
|
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) {
|
||||||
{
|
|
||||||
uint32_t position;
|
uint32_t position;
|
||||||
uint32_t ioposition = 0x00U;
|
uint32_t ioposition = 0x00U;
|
||||||
uint32_t iocurrent = 0x00U;
|
uint32_t iocurrent = 0x00U;
|
||||||
uint32_t temp = 0x00U;
|
uint32_t temp = 0x00U;
|
||||||
uint32_t config = 0x00U;
|
uint32_t config = 0x00U;
|
||||||
__IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
|
__IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
|
||||||
uint32_t registeroffset = 0U; /* offset used during computation of CNF and MODE bits placement inside CRL or CRH register */
|
uint32_t registeroffset = 0U; /* offset used during computation of CNF and MODE bits placement inside CRL or CRH register */
|
||||||
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||||
@@ -207,93 +205,86 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
|
|||||||
assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
|
assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
|
||||||
|
|
||||||
/* Configure the port pins */
|
/* Configure the port pins */
|
||||||
for (position = 0U; position < GPIO_NUMBER; position++)
|
for (position = 0U; position < GPIO_NUMBER; position++) {
|
||||||
{
|
|
||||||
/* Get the IO position */
|
/* Get the IO position */
|
||||||
ioposition = (0x01U << position);
|
ioposition = (0x01U << position);
|
||||||
|
|
||||||
/* Get the current IO position */
|
/* Get the current IO position */
|
||||||
iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
|
iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
|
||||||
|
|
||||||
if (iocurrent == ioposition)
|
if (iocurrent == ioposition) {
|
||||||
{
|
|
||||||
/* Check the Alternate function parameters */
|
/* Check the Alternate function parameters */
|
||||||
assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
|
assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
|
||||||
|
|
||||||
/* Based on the required mode, filling config variable with MODEy[1:0] and CNFy[3:2] corresponding bits */
|
/* Based on the required mode, filling config variable with MODEy[1:0] and CNFy[3:2] corresponding bits */
|
||||||
switch (GPIO_Init->Mode)
|
switch (GPIO_Init->Mode) {
|
||||||
{
|
/* If we are configuring the pin in OUTPUT push-pull mode */
|
||||||
/* If we are configuring the pin in OUTPUT push-pull mode */
|
case GPIO_MODE_OUTPUT_PP:
|
||||||
case GPIO_MODE_OUTPUT_PP:
|
/* Check the GPIO speed parameter */
|
||||||
/* Check the GPIO speed parameter */
|
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP;
|
||||||
config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
/* If we are configuring the pin in OUTPUT open-drain mode */
|
/* If we are configuring the pin in OUTPUT open-drain mode */
|
||||||
case GPIO_MODE_OUTPUT_OD:
|
case GPIO_MODE_OUTPUT_OD:
|
||||||
/* Check the GPIO speed parameter */
|
/* Check the GPIO speed parameter */
|
||||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||||
config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_OD;
|
config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_OD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* If we are configuring the pin in ALTERNATE FUNCTION push-pull mode */
|
/* If we are configuring the pin in ALTERNATE FUNCTION push-pull mode */
|
||||||
case GPIO_MODE_AF_PP:
|
case GPIO_MODE_AF_PP:
|
||||||
/* Check the GPIO speed parameter */
|
/* Check the GPIO speed parameter */
|
||||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||||
config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_PP;
|
config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_PP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* If we are configuring the pin in ALTERNATE FUNCTION open-drain mode */
|
/* If we are configuring the pin in ALTERNATE FUNCTION open-drain mode */
|
||||||
case GPIO_MODE_AF_OD:
|
case GPIO_MODE_AF_OD:
|
||||||
/* Check the GPIO speed parameter */
|
/* Check the GPIO speed parameter */
|
||||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||||
config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_OD;
|
config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_OD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* If we are configuring the pin in INPUT (also applicable to EVENT and IT mode) */
|
/* If we are configuring the pin in INPUT (also applicable to EVENT and IT mode) */
|
||||||
case GPIO_MODE_INPUT:
|
case GPIO_MODE_INPUT:
|
||||||
case GPIO_MODE_IT_RISING:
|
case GPIO_MODE_IT_RISING:
|
||||||
case GPIO_MODE_IT_FALLING:
|
case GPIO_MODE_IT_FALLING:
|
||||||
case GPIO_MODE_IT_RISING_FALLING:
|
case GPIO_MODE_IT_RISING_FALLING:
|
||||||
case GPIO_MODE_EVT_RISING:
|
case GPIO_MODE_EVT_RISING:
|
||||||
case GPIO_MODE_EVT_FALLING:
|
case GPIO_MODE_EVT_FALLING:
|
||||||
case GPIO_MODE_EVT_RISING_FALLING:
|
case GPIO_MODE_EVT_RISING_FALLING:
|
||||||
/* Check the GPIO pull parameter */
|
/* Check the GPIO pull parameter */
|
||||||
assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
|
assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
|
||||||
if (GPIO_Init->Pull == GPIO_NOPULL)
|
if (GPIO_Init->Pull == GPIO_NOPULL) {
|
||||||
{
|
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_FLOATING;
|
||||||
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_FLOATING;
|
} else if (GPIO_Init->Pull == GPIO_PULLUP) {
|
||||||
}
|
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
|
||||||
else if (GPIO_Init->Pull == GPIO_PULLUP)
|
|
||||||
{
|
|
||||||
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
|
|
||||||
|
|
||||||
/* Set the corresponding ODR bit */
|
/* Set the corresponding ODR bit */
|
||||||
GPIOx->BSRR = ioposition;
|
GPIOx->BSRR = ioposition;
|
||||||
}
|
} else /* GPIO_PULLDOWN */
|
||||||
else /* GPIO_PULLDOWN */
|
{
|
||||||
{
|
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
|
||||||
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
|
|
||||||
|
|
||||||
/* Reset the corresponding ODR bit */
|
/* Reset the corresponding ODR bit */
|
||||||
GPIOx->BRR = ioposition;
|
GPIOx->BRR = ioposition;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* If we are configuring the pin in INPUT analog mode */
|
/* If we are configuring the pin in INPUT analog mode */
|
||||||
case GPIO_MODE_ANALOG:
|
case GPIO_MODE_ANALOG:
|
||||||
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_ANALOG;
|
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_ANALOG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Parameters are checked with assert_param */
|
/* Parameters are checked with assert_param */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the current bit belongs to first half or last half of the pin count number
|
/* Check if the current bit belongs to first half or last half of the pin count number
|
||||||
in order to address CRH or CRL register*/
|
in order to address CRH or CRL register*/
|
||||||
configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
|
configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
|
||||||
registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2U) : ((position - 8U) << 2U);
|
registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2U) : ((position - 8U) << 2U);
|
||||||
|
|
||||||
/* Apply the new configuration of the pin to the register */
|
/* Apply the new configuration of the pin to the register */
|
||||||
@@ -301,8 +292,7 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
|
|||||||
|
|
||||||
/*--------------------- EXTI Mode Configuration ------------------------*/
|
/*--------------------- EXTI Mode Configuration ------------------------*/
|
||||||
/* Configure the External Interrupt or event for the current IO */
|
/* Configure the External Interrupt or event for the current IO */
|
||||||
if ((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
|
if ((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) {
|
||||||
{
|
|
||||||
/* Enable AFIO Clock */
|
/* Enable AFIO Clock */
|
||||||
__HAL_RCC_AFIO_CLK_ENABLE();
|
__HAL_RCC_AFIO_CLK_ENABLE();
|
||||||
temp = AFIO->EXTICR[position >> 2U];
|
temp = AFIO->EXTICR[position >> 2U];
|
||||||
@@ -310,44 +300,31 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
|
|||||||
SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U)));
|
SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U)));
|
||||||
AFIO->EXTICR[position >> 2U] = temp;
|
AFIO->EXTICR[position >> 2U] = temp;
|
||||||
|
|
||||||
|
|
||||||
/* Configure the interrupt mask */
|
/* Configure the interrupt mask */
|
||||||
if ((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
|
if ((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) {
|
||||||
{
|
|
||||||
SET_BIT(EXTI->IMR, iocurrent);
|
SET_BIT(EXTI->IMR, iocurrent);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
CLEAR_BIT(EXTI->IMR, iocurrent);
|
CLEAR_BIT(EXTI->IMR, iocurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure the event mask */
|
/* Configure the event mask */
|
||||||
if ((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
|
if ((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) {
|
||||||
{
|
|
||||||
SET_BIT(EXTI->EMR, iocurrent);
|
SET_BIT(EXTI->EMR, iocurrent);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
CLEAR_BIT(EXTI->EMR, iocurrent);
|
CLEAR_BIT(EXTI->EMR, iocurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable or disable the rising trigger */
|
/* Enable or disable the rising trigger */
|
||||||
if ((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
|
if ((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) {
|
||||||
{
|
|
||||||
SET_BIT(EXTI->RTSR, iocurrent);
|
SET_BIT(EXTI->RTSR, iocurrent);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
CLEAR_BIT(EXTI->RTSR, iocurrent);
|
CLEAR_BIT(EXTI->RTSR, iocurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable or disable the falling trigger */
|
/* Enable or disable the falling trigger */
|
||||||
if ((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
|
if ((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) {
|
||||||
{
|
|
||||||
SET_BIT(EXTI->FTSR, iocurrent);
|
SET_BIT(EXTI->FTSR, iocurrent);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
CLEAR_BIT(EXTI->FTSR, iocurrent);
|
CLEAR_BIT(EXTI->FTSR, iocurrent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -356,36 +333,33 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief De-initializes the GPIOx peripheral registers to their default reset values.
|
* @brief De-initializes the GPIOx peripheral registers to their default reset values.
|
||||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||||
* @param GPIO_Pin: specifies the port bit to be written.
|
* @param GPIO_Pin: specifies the port bit to be written.
|
||||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
|
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
|
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) {
|
||||||
{
|
uint32_t position = 0x00U;
|
||||||
uint32_t position = 0x00U;
|
|
||||||
uint32_t iocurrent = 0x00U;
|
uint32_t iocurrent = 0x00U;
|
||||||
uint32_t tmp = 0x00U;
|
uint32_t tmp = 0x00U;
|
||||||
__IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
|
__IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
|
||||||
uint32_t registeroffset = 0U;
|
uint32_t registeroffset = 0U;
|
||||||
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
/* Configure the port pins */
|
/* Configure the port pins */
|
||||||
while ((GPIO_Pin >> position) != 0U)
|
while ((GPIO_Pin >> position) != 0U) {
|
||||||
{
|
|
||||||
/* Get current io position */
|
/* Get current io position */
|
||||||
iocurrent = (GPIO_Pin) & (1U << position);
|
iocurrent = (GPIO_Pin) & (1U << position);
|
||||||
|
|
||||||
if (iocurrent)
|
if (iocurrent) {
|
||||||
{
|
|
||||||
/*------------------------- GPIO Mode Configuration --------------------*/
|
/*------------------------- GPIO Mode Configuration --------------------*/
|
||||||
/* Check if the current bit belongs to first half or last half of the pin count number
|
/* Check if the current bit belongs to first half or last half of the pin count number
|
||||||
in order to address CRH or CRL register */
|
in order to address CRH or CRL register */
|
||||||
configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
|
configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
|
||||||
registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2U) : ((position - 8U) << 2U);
|
registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2U) : ((position - 8U) << 2U);
|
||||||
|
|
||||||
/* CRL/CRH default value is floating input(0x04) shifted to correct position */
|
/* CRL/CRH default value is floating input(0x04) shifted to correct position */
|
||||||
@@ -399,8 +373,7 @@ void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
|
|||||||
|
|
||||||
tmp = AFIO->EXTICR[position >> 2U];
|
tmp = AFIO->EXTICR[position >> 2U];
|
||||||
tmp &= 0x0FU << (4U * (position & 0x03U));
|
tmp &= 0x0FU << (4U * (position & 0x03U));
|
||||||
if (tmp == (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U))))
|
if (tmp == (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U)))) {
|
||||||
{
|
|
||||||
tmp = 0x0FU << (4U * (position & 0x03U));
|
tmp = 0x0FU << (4U * (position & 0x03U));
|
||||||
CLEAR_BIT(AFIO->EXTICR[position >> 2U], tmp);
|
CLEAR_BIT(AFIO->EXTICR[position >> 2U], tmp);
|
||||||
|
|
||||||
@@ -419,8 +392,8 @@ void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
|
/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
|
||||||
* @brief GPIO Read and Write
|
* @brief GPIO Read and Write
|
||||||
@@ -437,70 +410,61 @@ void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads the specified input port pin.
|
* @brief Reads the specified input port pin.
|
||||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||||
* @param GPIO_Pin: specifies the port bit to read.
|
* @param GPIO_Pin: specifies the port bit to read.
|
||||||
* This parameter can be GPIO_PIN_x where x can be (0..15).
|
* This parameter can be GPIO_PIN_x where x can be (0..15).
|
||||||
* @retval The input port pin value.
|
* @retval The input port pin value.
|
||||||
*/
|
*/
|
||||||
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
|
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) {
|
||||||
{
|
|
||||||
GPIO_PinState bitstatus;
|
GPIO_PinState bitstatus;
|
||||||
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
|
if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET) {
|
||||||
{
|
|
||||||
bitstatus = GPIO_PIN_SET;
|
bitstatus = GPIO_PIN_SET;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
bitstatus = GPIO_PIN_RESET;
|
bitstatus = GPIO_PIN_RESET;
|
||||||
}
|
}
|
||||||
return bitstatus;
|
return bitstatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets or clears the selected data port bit.
|
* @brief Sets or clears the selected data port bit.
|
||||||
*
|
*
|
||||||
* @note This function uses GPIOx_BSRR register to allow atomic read/modify
|
* @note This function uses GPIOx_BSRR register to allow atomic read/modify
|
||||||
* accesses. In this way, there is no risk of an IRQ occurring between
|
* accesses. In this way, there is no risk of an IRQ occurring between
|
||||||
* the read and the modify access.
|
* the read and the modify access.
|
||||||
*
|
*
|
||||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||||
* @param GPIO_Pin: specifies the port bit to be written.
|
* @param GPIO_Pin: specifies the port bit to be written.
|
||||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
|
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
|
||||||
* @param PinState: specifies the value to be written to the selected bit.
|
* @param PinState: specifies the value to be written to the selected bit.
|
||||||
* This parameter can be one of the GPIO_PinState enum values:
|
* This parameter can be one of the GPIO_PinState enum values:
|
||||||
* @arg GPIO_PIN_RESET: to clear the port pin
|
* @arg GPIO_PIN_RESET: to clear the port pin
|
||||||
* @arg GPIO_PIN_SET: to set the port pin
|
* @arg GPIO_PIN_SET: to set the port pin
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
|
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
assert_param(IS_GPIO_PIN_ACTION(PinState));
|
assert_param(IS_GPIO_PIN_ACTION(PinState));
|
||||||
|
|
||||||
if (PinState != GPIO_PIN_RESET)
|
if (PinState != GPIO_PIN_RESET) {
|
||||||
{
|
|
||||||
GPIOx->BSRR = GPIO_Pin;
|
GPIOx->BSRR = GPIO_Pin;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
|
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Toggles the specified GPIO pin
|
* @brief Toggles the specified GPIO pin
|
||||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||||
* @param GPIO_Pin: Specifies the pins to be toggled.
|
* @param GPIO_Pin: Specifies the pins to be toggled.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
|
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||||
|
|
||||||
@@ -508,17 +472,16 @@ void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Locks GPIO Pins configuration registers.
|
* @brief Locks GPIO Pins configuration registers.
|
||||||
* @note The locking mechanism allows the IO configuration to be frozen. When the LOCK sequence
|
* @note The locking mechanism allows the IO configuration to be frozen. When the LOCK sequence
|
||||||
* has been applied on a port bit, it is no longer possible to modify the value of the port bit until
|
* has been applied on a port bit, it is no longer possible to modify the value of the port bit until
|
||||||
* the next reset.
|
* the next reset.
|
||||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||||
* @param GPIO_Pin: specifies the port bit to be locked.
|
* @param GPIO_Pin: specifies the port bit to be locked.
|
||||||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
|
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) {
|
||||||
{
|
|
||||||
__IO uint32_t tmp = GPIO_LCKR_LCKK;
|
__IO uint32_t tmp = GPIO_LCKR_LCKK;
|
||||||
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
@@ -536,38 +499,32 @@ HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
|
|||||||
/* Read LCKK bit*/
|
/* Read LCKK bit*/
|
||||||
tmp = GPIOx->LCKR;
|
tmp = GPIOx->LCKR;
|
||||||
|
|
||||||
if ((uint32_t)(GPIOx->LCKR & GPIO_LCKR_LCKK))
|
if ((uint32_t)(GPIOx->LCKR & GPIO_LCKR_LCKK)) {
|
||||||
{
|
|
||||||
return HAL_OK;
|
return HAL_OK;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles EXTI interrupt request.
|
* @brief This function handles EXTI interrupt request.
|
||||||
* @param GPIO_Pin: Specifies the pins connected EXTI line
|
* @param GPIO_Pin: Specifies the pins connected EXTI line
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
|
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) {
|
||||||
{
|
|
||||||
/* EXTI line interrupt detected */
|
/* EXTI line interrupt detected */
|
||||||
if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
|
if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) {
|
||||||
{
|
|
||||||
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
|
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
|
||||||
HAL_GPIO_EXTI_Callback(GPIO_Pin);
|
HAL_GPIO_EXTI_Callback(GPIO_Pin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief EXTI line detection callbacks.
|
* @brief EXTI line detection callbacks.
|
||||||
* @param GPIO_Pin: Specifies the pins connected EXTI line
|
* @param GPIO_Pin: Specifies the pins connected EXTI line
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
|
||||||
{
|
|
||||||
/* Prevent unused argument(s) compilation warning */
|
/* Prevent unused argument(s) compilation warning */
|
||||||
UNUSED(GPIO_Pin);
|
UNUSED(GPIO_Pin);
|
||||||
/* NOTE: This function Should not be modified, when the callback is needed,
|
/* NOTE: This function Should not be modified, when the callback is needed,
|
||||||
@@ -576,20 +533,20 @@ __weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|||||||
@@ -56,19 +56,19 @@
|
|||||||
#include "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
|
|
||||||
/** @addtogroup STM32F1xx_HAL_Driver
|
/** @addtogroup STM32F1xx_HAL_Driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup GPIOEx GPIOEx
|
/** @defgroup GPIOEx GPIOEx
|
||||||
* @brief GPIO HAL module driver
|
* @brief GPIO HAL module driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||||
|
|
||||||
/** @defgroup GPIOEx_Exported_Functions GPIOEx Exported Functions
|
/** @defgroup GPIOEx_Exported_Functions GPIOEx Exported Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup GPIOEx_Exported_Functions_Group1 Extended features functions
|
/** @defgroup GPIOEx_Exported_Functions_Group1 Extended features functions
|
||||||
* @brief Extended features functions
|
* @brief Extended features functions
|
||||||
@@ -87,15 +87,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures the port and pin on which the EVENTOUT Cortex signal will be connected.
|
* @brief Configures the port and pin on which the EVENTOUT Cortex signal will be connected.
|
||||||
* @param GPIO_PortSource Select the port used to output the Cortex EVENTOUT signal.
|
* @param GPIO_PortSource Select the port used to output the Cortex EVENTOUT signal.
|
||||||
* This parameter can be a value of @ref GPIOEx_EVENTOUT_PORT.
|
* This parameter can be a value of @ref GPIOEx_EVENTOUT_PORT.
|
||||||
* @param GPIO_PinSource Select the pin used to output the Cortex EVENTOUT signal.
|
* @param GPIO_PinSource Select the pin used to output the Cortex EVENTOUT signal.
|
||||||
* This parameter can be a value of @ref GPIOEx_EVENTOUT_PIN.
|
* This parameter can be a value of @ref GPIOEx_EVENTOUT_PIN.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource)
|
void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource) {
|
||||||
{
|
|
||||||
/* Verify the parameters */
|
/* Verify the parameters */
|
||||||
assert_param(IS_AFIO_EVENTOUT_PORT(GPIO_PortSource));
|
assert_param(IS_AFIO_EVENTOUT_PORT(GPIO_PortSource));
|
||||||
assert_param(IS_AFIO_EVENTOUT_PIN(GPIO_PinSource));
|
assert_param(IS_AFIO_EVENTOUT_PIN(GPIO_PinSource));
|
||||||
@@ -105,39 +104,33 @@ void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables the Event Output.
|
* @brief Enables the Event Output.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_GPIOEx_EnableEventout(void)
|
void HAL_GPIOEx_EnableEventout(void) { SET_BIT(AFIO->EVCR, AFIO_EVCR_EVOE); }
|
||||||
{
|
|
||||||
SET_BIT(AFIO->EVCR, AFIO_EVCR_EVOE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables the Event Output.
|
* @brief Disables the Event Output.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_GPIOEx_DisableEventout(void)
|
void HAL_GPIOEx_DisableEventout(void) { CLEAR_BIT(AFIO->EVCR, AFIO_EVCR_EVOE); }
|
||||||
{
|
|
||||||
CLEAR_BIT(AFIO->EVCR, AFIO_EVCR_EVOE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -103,27 +103,27 @@
|
|||||||
#include "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
|
|
||||||
/** @addtogroup STM32F1xx_HAL_Driver
|
/** @addtogroup STM32F1xx_HAL_Driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||||
/** @defgroup IWDG IWDG
|
/** @defgroup IWDG IWDG
|
||||||
* @brief IWDG HAL module driver.
|
* @brief IWDG HAL module driver.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
/* Private define ------------------------------------------------------------*/
|
/* Private define ------------------------------------------------------------*/
|
||||||
/** @defgroup IWDG_Private_Defines IWDG Private Defines
|
/** @defgroup IWDG_Private_Defines IWDG Private Defines
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/* Status register need 5 RC LSI divided by prescaler clock to be updated. With
|
/* Status register need 5 RC LSI divided by prescaler clock to be updated. With
|
||||||
higher prescaler (256), and according to HSI variation, we need to wait at
|
higher prescaler (256), and according to HSI variation, we need to wait at
|
||||||
least 6 cycles so 48 ms. */
|
least 6 cycles so 48 ms. */
|
||||||
#define HAL_IWDG_DEFAULT_TIMEOUT 48U
|
#define HAL_IWDG_DEFAULT_TIMEOUT 48U
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
/* Private macro -------------------------------------------------------------*/
|
||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
@@ -131,8 +131,8 @@
|
|||||||
/* Exported functions --------------------------------------------------------*/
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
|
||||||
/** @addtogroup IWDG_Exported_Functions
|
/** @addtogroup IWDG_Exported_Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @addtogroup IWDG_Exported_Functions_Group1
|
/** @addtogroup IWDG_Exported_Functions_Group1
|
||||||
* @brief Initialization and Start functions.
|
* @brief Initialization and Start functions.
|
||||||
@@ -152,20 +152,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the IWDG according to the specified parameters in the
|
* @brief Initialize the IWDG according to the specified parameters in the
|
||||||
* IWDG_InitTypeDef and start watchdog. Before exiting function,
|
* IWDG_InitTypeDef and start watchdog. Before exiting function,
|
||||||
* watchdog is refreshed in order to have correct time base.
|
* watchdog is refreshed in order to have correct time base.
|
||||||
* @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
|
* @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified IWDG module.
|
* the configuration information for the specified IWDG module.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
|
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg) {
|
||||||
{
|
|
||||||
uint32_t tickstart;
|
uint32_t tickstart;
|
||||||
|
|
||||||
/* Check the IWDG handle allocation */
|
/* Check the IWDG handle allocation */
|
||||||
if (hiwdg == NULL)
|
if (hiwdg == NULL) {
|
||||||
{
|
|
||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,17 +179,15 @@ HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
|
|||||||
IWDG_ENABLE_WRITE_ACCESS(hiwdg);
|
IWDG_ENABLE_WRITE_ACCESS(hiwdg);
|
||||||
|
|
||||||
/* Write to IWDG registers the Prescaler & Reload values to work with */
|
/* Write to IWDG registers the Prescaler & Reload values to work with */
|
||||||
hiwdg->Instance->PR = hiwdg->Init.Prescaler;
|
hiwdg->Instance->PR = hiwdg->Init.Prescaler;
|
||||||
hiwdg->Instance->RLR = hiwdg->Init.Reload;
|
hiwdg->Instance->RLR = hiwdg->Init.Reload;
|
||||||
|
|
||||||
/* Check pending flag, if previous update not done, return timeout */
|
/* Check pending flag, if previous update not done, return timeout */
|
||||||
tickstart = HAL_GetTick();
|
tickstart = HAL_GetTick();
|
||||||
|
|
||||||
/* Wait for register to be updated */
|
/* Wait for register to be updated */
|
||||||
while (hiwdg->Instance->SR != RESET)
|
while (hiwdg->Instance->SR != RESET) {
|
||||||
{
|
if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT) {
|
||||||
if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT)
|
|
||||||
{
|
|
||||||
return HAL_TIMEOUT;
|
return HAL_TIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,8 +200,8 @@ HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @addtogroup IWDG_Exported_Functions_Group2
|
/** @addtogroup IWDG_Exported_Functions_Group2
|
||||||
* @brief IO operation functions
|
* @brief IO operation functions
|
||||||
@@ -222,13 +218,12 @@ HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Refresh the IWDG.
|
* @brief Refresh the IWDG.
|
||||||
* @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
|
* @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
|
||||||
* the configuration information for the specified IWDG module.
|
* the configuration information for the specified IWDG module.
|
||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
|
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg) {
|
||||||
{
|
|
||||||
/* Reload IWDG counter with value defined in the reload register */
|
/* Reload IWDG counter with value defined in the reload register */
|
||||||
__HAL_IWDG_RELOAD_COUNTER(hiwdg);
|
__HAL_IWDG_RELOAD_COUNTER(hiwdg);
|
||||||
|
|
||||||
@@ -237,20 +232,20 @@ HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|||||||
@@ -1,55 +1,55 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @file stm32f1xx_hal_pwr.c
|
* @file stm32f1xx_hal_pwr.c
|
||||||
* @author MCD Application Team
|
* @author MCD Application Team
|
||||||
* @brief PWR HAL module driver.
|
* @brief PWR HAL module driver.
|
||||||
*
|
*
|
||||||
* This file provides firmware functions to manage the following
|
* This file provides firmware functions to manage the following
|
||||||
* functionalities of the Power Controller (PWR) peripheral:
|
* functionalities of the Power Controller (PWR) peripheral:
|
||||||
* + Initialization/de-initialization functions
|
* + Initialization/de-initialization functions
|
||||||
* + Peripheral Control functions
|
* + Peripheral Control functions
|
||||||
*
|
*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @attention
|
* @attention
|
||||||
*
|
*
|
||||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
* <h2><center>© COPYRIGHT(c) 2016 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.
|
||||||
*
|
*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
|
|
||||||
/** @addtogroup STM32F1xx_HAL_Driver
|
/** @addtogroup STM32F1xx_HAL_Driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup PWR PWR
|
/** @defgroup PWR PWR
|
||||||
* @brief PWR HAL module driver
|
* @brief PWR HAL module driver
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAL_PWR_MODULE_ENABLED
|
#ifdef HAL_PWR_MODULE_ENABLED
|
||||||
|
|
||||||
@@ -57,68 +57,67 @@
|
|||||||
/* Private define ------------------------------------------------------------*/
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
|
||||||
/** @defgroup PWR_Private_Constants PWR Private Constants
|
/** @defgroup PWR_Private_Constants PWR Private Constants
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define PVD_MODE_IT 0x00010000U
|
|
||||||
#define PVD_MODE_EVT 0x00020000U
|
|
||||||
#define PVD_RISING_EDGE 0x00000001U
|
|
||||||
#define PVD_FALLING_EDGE 0x00000002U
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define PVD_MODE_IT 0x00010000U
|
||||||
|
#define PVD_MODE_EVT 0x00020000U
|
||||||
|
#define PVD_RISING_EDGE 0x00000001U
|
||||||
|
#define PVD_FALLING_EDGE 0x00000002U
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
/** @defgroup PWR_register_alias_address PWR Register alias address
|
/** @defgroup PWR_register_alias_address PWR Register alias address
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/* ------------- PWR registers bit address in the alias region ---------------*/
|
/* ------------- PWR registers bit address in the alias region ---------------*/
|
||||||
#define PWR_OFFSET (PWR_BASE - PERIPH_BASE)
|
#define PWR_OFFSET (PWR_BASE - PERIPH_BASE)
|
||||||
#define PWR_CR_OFFSET 0x00U
|
#define PWR_CR_OFFSET 0x00U
|
||||||
#define PWR_CSR_OFFSET 0x04U
|
#define PWR_CSR_OFFSET 0x04U
|
||||||
#define PWR_CR_OFFSET_BB (PWR_OFFSET + PWR_CR_OFFSET)
|
#define PWR_CR_OFFSET_BB (PWR_OFFSET + PWR_CR_OFFSET)
|
||||||
#define PWR_CSR_OFFSET_BB (PWR_OFFSET + PWR_CSR_OFFSET)
|
#define PWR_CSR_OFFSET_BB (PWR_OFFSET + PWR_CSR_OFFSET)
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup PWR_CR_register_alias PWR CR Register alias address
|
/** @defgroup PWR_CR_register_alias PWR CR Register alias address
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/* --- CR Register ---*/
|
/* --- CR Register ---*/
|
||||||
/* Alias word address of LPSDSR bit */
|
/* Alias word address of LPSDSR bit */
|
||||||
#define LPSDSR_BIT_NUMBER PWR_CR_LPDS_Pos
|
#define LPSDSR_BIT_NUMBER PWR_CR_LPDS_Pos
|
||||||
#define CR_LPSDSR_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (LPSDSR_BIT_NUMBER * 4U)))
|
#define CR_LPSDSR_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (LPSDSR_BIT_NUMBER * 4U)))
|
||||||
|
|
||||||
/* Alias word address of DBP bit */
|
/* Alias word address of DBP bit */
|
||||||
#define DBP_BIT_NUMBER PWR_CR_DBP_Pos
|
#define DBP_BIT_NUMBER PWR_CR_DBP_Pos
|
||||||
#define CR_DBP_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (DBP_BIT_NUMBER * 4U)))
|
#define CR_DBP_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (DBP_BIT_NUMBER * 4U)))
|
||||||
|
|
||||||
/* Alias word address of PVDE bit */
|
/* Alias word address of PVDE bit */
|
||||||
#define PVDE_BIT_NUMBER PWR_CR_PVDE_Pos
|
#define PVDE_BIT_NUMBER PWR_CR_PVDE_Pos
|
||||||
#define CR_PVDE_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (PVDE_BIT_NUMBER * 4U)))
|
#define CR_PVDE_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (PVDE_BIT_NUMBER * 4U)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup PWR_CSR_register_alias PWR CSR Register alias address
|
/** @defgroup PWR_CSR_register_alias PWR CSR Register alias address
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* --- CSR Register ---*/
|
/* --- CSR Register ---*/
|
||||||
/* Alias word address of EWUP1 bit */
|
/* Alias word address of EWUP1 bit */
|
||||||
#define CSR_EWUP_BB(VAL) ((uint32_t)(PERIPH_BB_BASE + (PWR_CSR_OFFSET_BB * 32U) + (POSITION_VAL(VAL) * 4U)))
|
#define CSR_EWUP_BB(VAL) ((uint32_t)(PERIPH_BB_BASE + (PWR_CSR_OFFSET_BB * 32U) + (POSITION_VAL(VAL) * 4U)))
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
@@ -130,22 +129,20 @@ static void PWR_OverloadWfe(void);
|
|||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
/* Private functions ---------------------------------------------------------*/
|
||||||
__NOINLINE
|
__NOINLINE
|
||||||
static void PWR_OverloadWfe(void)
|
static void PWR_OverloadWfe(void) {
|
||||||
{
|
__asm volatile("wfe");
|
||||||
__asm volatile( "wfe" );
|
__asm volatile("nop");
|
||||||
__asm volatile( "nop" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** @defgroup PWR_Exported_Functions PWR Exported Functions
|
/** @defgroup PWR_Exported_Functions PWR Exported Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
|
/** @defgroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||||
* @brief Initialization and de-initialization functions
|
* @brief Initialization and de-initialization functions
|
||||||
*
|
*
|
||||||
@verbatim
|
@verbatim
|
||||||
@@ -166,53 +163,50 @@ static void PWR_OverloadWfe(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deinitializes the PWR peripheral registers to their default reset values.
|
* @brief Deinitializes the PWR peripheral registers to their default reset values.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_DeInit(void)
|
void HAL_PWR_DeInit(void) {
|
||||||
{
|
|
||||||
__HAL_RCC_PWR_FORCE_RESET();
|
__HAL_RCC_PWR_FORCE_RESET();
|
||||||
__HAL_RCC_PWR_RELEASE_RESET();
|
__HAL_RCC_PWR_RELEASE_RESET();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables access to the backup domain (RTC registers, RTC
|
* @brief Enables access to the backup domain (RTC registers, RTC
|
||||||
* backup data registers ).
|
* backup data registers ).
|
||||||
* @note If the HSE divided by 128 is used as the RTC clock, the
|
* @note If the HSE divided by 128 is used as the RTC clock, the
|
||||||
* Backup Domain Access should be kept enabled.
|
* Backup Domain Access should be kept enabled.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_EnableBkUpAccess(void)
|
void HAL_PWR_EnableBkUpAccess(void) {
|
||||||
{
|
|
||||||
/* Enable access to RTC and backup registers */
|
/* Enable access to RTC and backup registers */
|
||||||
*(__IO uint32_t *) CR_DBP_BB = (uint32_t)ENABLE;
|
*(__IO uint32_t *)CR_DBP_BB = (uint32_t)ENABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables access to the backup domain (RTC registers, RTC
|
* @brief Disables access to the backup domain (RTC registers, RTC
|
||||||
* backup data registers).
|
* backup data registers).
|
||||||
* @note If the HSE divided by 128 is used as the RTC clock, the
|
* @note If the HSE divided by 128 is used as the RTC clock, the
|
||||||
* Backup Domain Access should be kept enabled.
|
* Backup Domain Access should be kept enabled.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_DisableBkUpAccess(void)
|
void HAL_PWR_DisableBkUpAccess(void) {
|
||||||
{
|
|
||||||
/* Disable access to RTC and backup registers */
|
/* Disable access to RTC and backup registers */
|
||||||
*(__IO uint32_t *) CR_DBP_BB = (uint32_t)DISABLE;
|
*(__IO uint32_t *)CR_DBP_BB = (uint32_t)DISABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control functions
|
/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control functions
|
||||||
* @brief Low Power modes configuration functions
|
* @brief Low Power modes configuration functions
|
||||||
*
|
*
|
||||||
@verbatim
|
@verbatim
|
||||||
===============================================================================
|
===============================================================================
|
||||||
##### Peripheral Control functions #####
|
##### Peripheral Control functions #####
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
|
||||||
*** PVD configuration ***
|
*** PVD configuration ***
|
||||||
=========================
|
=========================
|
||||||
[..]
|
[..]
|
||||||
@@ -239,12 +233,12 @@ void HAL_PWR_DisableBkUpAccess(void)
|
|||||||
=====================================
|
=====================================
|
||||||
[..]
|
[..]
|
||||||
The device features 3 low-power modes:
|
The device features 3 low-power modes:
|
||||||
(+) Sleep mode: CPU clock off, all peripherals including Cortex-M3 core peripherals like
|
(+) Sleep mode: CPU clock off, all peripherals including Cortex-M3 core peripherals like
|
||||||
NVIC, SysTick, etc. are kept running
|
NVIC, SysTick, etc. are kept running
|
||||||
(+) Stop mode: All clocks are stopped
|
(+) Stop mode: All clocks are stopped
|
||||||
(+) Standby mode: 1.8V domain powered off
|
(+) Standby mode: 1.8V domain powered off
|
||||||
|
|
||||||
|
|
||||||
*** Sleep mode ***
|
*** Sleep mode ***
|
||||||
==================
|
==================
|
||||||
[..]
|
[..]
|
||||||
@@ -253,7 +247,7 @@ void HAL_PWR_DisableBkUpAccess(void)
|
|||||||
functions with
|
functions with
|
||||||
(++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
|
(++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
|
||||||
(++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
|
(++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
|
||||||
|
|
||||||
(+) Exit:
|
(+) Exit:
|
||||||
(++) WFI entry mode, Any peripheral interrupt acknowledged by the nested vectored interrupt
|
(++) WFI entry mode, Any peripheral interrupt acknowledged by the nested vectored interrupt
|
||||||
controller (NVIC) can wake up the device from Sleep mode.
|
controller (NVIC) can wake up the device from Sleep mode.
|
||||||
@@ -266,7 +260,7 @@ void HAL_PWR_DisableBkUpAccess(void)
|
|||||||
[..]
|
[..]
|
||||||
The Stop mode is based on the Cortex-M3 deepsleep mode combined with peripheral
|
The Stop mode is based on the Cortex-M3 deepsleep mode combined with peripheral
|
||||||
clock gating. The voltage regulator can be configured either in normal or low-power mode.
|
clock gating. The voltage regulator can be configured either in normal or low-power mode.
|
||||||
In Stop mode, all clocks in the 1.8 V domain are stopped, the PLL, the HSI and the HSE RC
|
In Stop mode, all clocks in the 1.8 V domain are stopped, the PLL, the HSI and the HSE RC
|
||||||
oscillators are disabled. SRAM and register contents are preserved.
|
oscillators are disabled. SRAM and register contents are preserved.
|
||||||
In Stop mode, all I/O pins keep the same state as in Run mode.
|
In Stop mode, all I/O pins keep the same state as in Run mode.
|
||||||
|
|
||||||
@@ -285,27 +279,27 @@ void HAL_PWR_DisableBkUpAccess(void)
|
|||||||
====================
|
====================
|
||||||
[..]
|
[..]
|
||||||
The Standby mode allows to achieve the lowest power consumption. It is based on the
|
The Standby mode allows to achieve the lowest power consumption. It is based on the
|
||||||
Cortex-M3 deepsleep mode, with the voltage regulator disabled. The 1.8 V domain is
|
Cortex-M3 deepsleep mode, with the voltage regulator disabled. The 1.8 V domain is
|
||||||
consequently powered off. The PLL, the HSI oscillator and the HSE oscillator are also
|
consequently powered off. The PLL, the HSI oscillator and the HSE oscillator are also
|
||||||
switched off. SRAM and register contents are lost except for registers in the Backup domain
|
switched off. SRAM and register contents are lost except for registers in the Backup domain
|
||||||
and Standby circuitry
|
and Standby circuitry
|
||||||
|
|
||||||
(+) Entry:
|
(+) Entry:
|
||||||
(++) The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode() function.
|
(++) The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode() function.
|
||||||
(+) Exit:
|
(+) Exit:
|
||||||
(++) WKUP pin rising edge, RTC alarm event rising edge, external Reset in
|
(++) WKUP pin rising edge, RTC alarm event rising edge, external Reset in
|
||||||
NRSTpin, IWDG Reset
|
NRSTpin, IWDG Reset
|
||||||
|
|
||||||
*** Auto-wakeup (AWU) from low-power mode ***
|
*** Auto-wakeup (AWU) from low-power mode ***
|
||||||
=============================================
|
=============================================
|
||||||
[..]
|
[..]
|
||||||
|
|
||||||
(+) The MCU can be woken up from low-power mode by an RTC Alarm event,
|
(+) The MCU can be woken up from low-power mode by an RTC Alarm event,
|
||||||
without depending on an external interrupt (Auto-wakeup mode).
|
without depending on an external interrupt (Auto-wakeup mode).
|
||||||
|
|
||||||
(+) RTC auto-wakeup (AWU) from the Stop and Standby modes
|
(+) RTC auto-wakeup (AWU) from the Stop and Standby modes
|
||||||
|
|
||||||
(++) To wake up from the Stop mode with an RTC alarm event, it is necessary to
|
(++) To wake up from the Stop mode with an RTC alarm event, it is necessary to
|
||||||
configure the RTC to generate the RTC alarm using the HAL_RTC_SetAlarm_IT() function.
|
configure the RTC to generate the RTC alarm using the HAL_RTC_SetAlarm_IT() function.
|
||||||
|
|
||||||
*** PWR Workarounds linked to Silicon Limitation ***
|
*** PWR Workarounds linked to Silicon Limitation ***
|
||||||
@@ -314,124 +308,114 @@ void HAL_PWR_DisableBkUpAccess(void)
|
|||||||
Below the list of all silicon limitations known on STM32F1xx prouct.
|
Below the list of all silicon limitations known on STM32F1xx prouct.
|
||||||
|
|
||||||
(#)Workarounds Implemented inside PWR HAL Driver
|
(#)Workarounds Implemented inside PWR HAL Driver
|
||||||
(##)Debugging Stop mode with WFE entry - overloaded the WFE by an internal function
|
(##)Debugging Stop mode with WFE entry - overloaded the WFE by an internal function
|
||||||
|
|
||||||
@endverbatim
|
@endverbatim
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD).
|
* @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD).
|
||||||
* @param sConfigPVD: pointer to an PWR_PVDTypeDef structure that contains the configuration
|
* @param sConfigPVD: pointer to an PWR_PVDTypeDef structure that contains the configuration
|
||||||
* information for the PVD.
|
* information for the PVD.
|
||||||
* @note Refer to the electrical characteristics of your device datasheet for
|
* @note Refer to the electrical characteristics of your device datasheet for
|
||||||
* more details about the voltage threshold corresponding to each
|
* more details about the voltage threshold corresponding to each
|
||||||
* detection level.
|
* detection level.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD)
|
void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
|
assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
|
||||||
assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
|
assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
|
||||||
|
|
||||||
/* Set PLS[7:5] bits according to PVDLevel value */
|
/* Set PLS[7:5] bits according to PVDLevel value */
|
||||||
MODIFY_REG(PWR->CR, PWR_CR_PLS, sConfigPVD->PVDLevel);
|
MODIFY_REG(PWR->CR, PWR_CR_PLS, sConfigPVD->PVDLevel);
|
||||||
|
|
||||||
/* Clear any previous config. Keep it clear if no event or IT mode is selected */
|
/* Clear any previous config. Keep it clear if no event or IT mode is selected */
|
||||||
__HAL_PWR_PVD_EXTI_DISABLE_EVENT();
|
__HAL_PWR_PVD_EXTI_DISABLE_EVENT();
|
||||||
__HAL_PWR_PVD_EXTI_DISABLE_IT();
|
__HAL_PWR_PVD_EXTI_DISABLE_IT();
|
||||||
__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
|
__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
|
||||||
__HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
|
__HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
|
||||||
|
|
||||||
/* Configure interrupt mode */
|
/* Configure interrupt mode */
|
||||||
if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
|
if ((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT) {
|
||||||
{
|
|
||||||
__HAL_PWR_PVD_EXTI_ENABLE_IT();
|
__HAL_PWR_PVD_EXTI_ENABLE_IT();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure event mode */
|
/* Configure event mode */
|
||||||
if((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
|
if ((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT) {
|
||||||
{
|
|
||||||
__HAL_PWR_PVD_EXTI_ENABLE_EVENT();
|
__HAL_PWR_PVD_EXTI_ENABLE_EVENT();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure the edge */
|
/* Configure the edge */
|
||||||
if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
|
if ((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE) {
|
||||||
{
|
|
||||||
__HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
|
__HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
|
||||||
}
|
}
|
||||||
|
|
||||||
if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
|
if ((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE) {
|
||||||
{
|
|
||||||
__HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
|
__HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables the Power Voltage Detector(PVD).
|
* @brief Enables the Power Voltage Detector(PVD).
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_EnablePVD(void)
|
void HAL_PWR_EnablePVD(void) {
|
||||||
{
|
|
||||||
/* Enable the power voltage detector */
|
/* Enable the power voltage detector */
|
||||||
*(__IO uint32_t *) CR_PVDE_BB = (uint32_t)ENABLE;
|
*(__IO uint32_t *)CR_PVDE_BB = (uint32_t)ENABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables the Power Voltage Detector(PVD).
|
* @brief Disables the Power Voltage Detector(PVD).
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_DisablePVD(void)
|
void HAL_PWR_DisablePVD(void) {
|
||||||
{
|
|
||||||
/* Disable the power voltage detector */
|
/* Disable the power voltage detector */
|
||||||
*(__IO uint32_t *) CR_PVDE_BB = (uint32_t)DISABLE;
|
*(__IO uint32_t *)CR_PVDE_BB = (uint32_t)DISABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables the WakeUp PINx functionality.
|
* @brief Enables the WakeUp PINx functionality.
|
||||||
* @param WakeUpPinx: Specifies the Power Wake-Up pin to enable.
|
* @param WakeUpPinx: Specifies the Power Wake-Up pin to enable.
|
||||||
* This parameter can be one of the following values:
|
* This parameter can be one of the following values:
|
||||||
* @arg PWR_WAKEUP_PIN1
|
* @arg PWR_WAKEUP_PIN1
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx)
|
void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx) {
|
||||||
{
|
|
||||||
/* Check the parameter */
|
/* Check the parameter */
|
||||||
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
|
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
|
||||||
/* Enable the EWUPx pin */
|
/* Enable the EWUPx pin */
|
||||||
*(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)ENABLE;
|
*(__IO uint32_t *)CSR_EWUP_BB(WakeUpPinx) = (uint32_t)ENABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables the WakeUp PINx functionality.
|
* @brief Disables the WakeUp PINx functionality.
|
||||||
* @param WakeUpPinx: Specifies the Power Wake-Up pin to disable.
|
* @param WakeUpPinx: Specifies the Power Wake-Up pin to disable.
|
||||||
* This parameter can be one of the following values:
|
* This parameter can be one of the following values:
|
||||||
* @arg PWR_WAKEUP_PIN1
|
* @arg PWR_WAKEUP_PIN1
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
|
void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx) {
|
||||||
{
|
|
||||||
/* Check the parameter */
|
/* Check the parameter */
|
||||||
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
|
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
|
||||||
/* Disable the EWUPx pin */
|
/* Disable the EWUPx pin */
|
||||||
*(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)DISABLE;
|
*(__IO uint32_t *)CSR_EWUP_BB(WakeUpPinx) = (uint32_t)DISABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enters Sleep mode.
|
* @brief Enters Sleep mode.
|
||||||
* @note In Sleep mode, all I/O pins keep the same state as in Run mode.
|
* @note In Sleep mode, all I/O pins keep the same state as in Run mode.
|
||||||
* @param Regulator: Regulator state as no effect in SLEEP mode - allows to support portability from legacy software
|
* @param Regulator: Regulator state as no effect in SLEEP mode - allows to support portability from legacy software
|
||||||
* @param SLEEPEntry: Specifies if SLEEP mode is entered with WFI or WFE instruction.
|
* @param SLEEPEntry: Specifies if SLEEP mode is entered with WFI or WFE instruction.
|
||||||
* When WFI entry is used, tick interrupt have to be disabled if not desired as
|
* When WFI entry is used, tick interrupt have to be disabled if not desired as
|
||||||
* the interrupt wake up source.
|
* the interrupt wake up source.
|
||||||
* This parameter can be one of the following values:
|
* This parameter can be one of the following values:
|
||||||
* @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
|
* @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
|
||||||
* @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
|
* @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
|
void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
/* No check on Regulator because parameter not used in SLEEP mode */
|
/* No check on Regulator because parameter not used in SLEEP mode */
|
||||||
/* Prevent unused argument(s) compilation warning */
|
/* Prevent unused argument(s) compilation warning */
|
||||||
@@ -443,13 +427,10 @@ void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
|
|||||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||||
|
|
||||||
/* Select SLEEP mode entry -------------------------------------------------*/
|
/* Select SLEEP mode entry -------------------------------------------------*/
|
||||||
if(SLEEPEntry == PWR_SLEEPENTRY_WFI)
|
if (SLEEPEntry == PWR_SLEEPENTRY_WFI) {
|
||||||
{
|
|
||||||
/* Request Wait For Interrupt */
|
/* Request Wait For Interrupt */
|
||||||
__WFI();
|
__WFI();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Request Wait For Event */
|
/* Request Wait For Event */
|
||||||
__SEV();
|
__SEV();
|
||||||
__WFE();
|
__WFE();
|
||||||
@@ -458,32 +439,31 @@ void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enters Stop mode.
|
* @brief Enters Stop mode.
|
||||||
* @note In Stop mode, all I/O pins keep the same state as in Run mode.
|
* @note In Stop mode, all I/O pins keep the same state as in Run mode.
|
||||||
* @note When exiting Stop mode by using an interrupt or a wakeup event,
|
* @note When exiting Stop mode by using an interrupt or a wakeup event,
|
||||||
* HSI RC oscillator is selected as system clock.
|
* HSI RC oscillator is selected as system clock.
|
||||||
* @note When the voltage regulator operates in low power mode, an additional
|
* @note When the voltage regulator operates in low power mode, an additional
|
||||||
* startup delay is incurred when waking up from Stop mode.
|
* startup delay is incurred when waking up from Stop mode.
|
||||||
* By keeping the internal regulator ON during Stop mode, the consumption
|
* By keeping the internal regulator ON during Stop mode, the consumption
|
||||||
* is higher although the startup time is reduced.
|
* is higher although the startup time is reduced.
|
||||||
* @param Regulator: Specifies the regulator state in Stop mode.
|
* @param Regulator: Specifies the regulator state in Stop mode.
|
||||||
* This parameter can be one of the following values:
|
* This parameter can be one of the following values:
|
||||||
* @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON
|
* @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON
|
||||||
* @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON
|
* @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON
|
||||||
* @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction.
|
* @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction.
|
||||||
* This parameter can be one of the following values:
|
* This parameter can be one of the following values:
|
||||||
* @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction
|
* @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction
|
||||||
* @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction
|
* @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
|
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) {
|
||||||
{
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_PWR_REGULATOR(Regulator));
|
assert_param(IS_PWR_REGULATOR(Regulator));
|
||||||
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
|
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
|
||||||
|
|
||||||
/* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Deepsleep */
|
/* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Deepsleep */
|
||||||
CLEAR_BIT(PWR->CR, PWR_CR_PDDS);
|
CLEAR_BIT(PWR->CR, PWR_CR_PDDS);
|
||||||
|
|
||||||
/* Select the voltage regulator mode by setting LPDS bit in PWR register according to Regulator parameter value */
|
/* Select the voltage regulator mode by setting LPDS bit in PWR register according to Regulator parameter value */
|
||||||
MODIFY_REG(PWR->CR, PWR_CR_LPDS, Regulator);
|
MODIFY_REG(PWR->CR, PWR_CR_LPDS, Regulator);
|
||||||
@@ -492,13 +472,10 @@ void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
|
|||||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||||
|
|
||||||
/* Select Stop mode entry --------------------------------------------------*/
|
/* Select Stop mode entry --------------------------------------------------*/
|
||||||
if(STOPEntry == PWR_STOPENTRY_WFI)
|
if (STOPEntry == PWR_STOPENTRY_WFI) {
|
||||||
{
|
|
||||||
/* Request Wait For Interrupt */
|
/* Request Wait For Interrupt */
|
||||||
__WFI();
|
__WFI();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Request Wait For Event */
|
/* Request Wait For Event */
|
||||||
__SEV();
|
__SEV();
|
||||||
PWR_OverloadWfe(); /* WFE redefine locally */
|
PWR_OverloadWfe(); /* WFE redefine locally */
|
||||||
@@ -509,15 +486,14 @@ void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enters Standby mode.
|
* @brief Enters Standby mode.
|
||||||
* @note In Standby mode, all I/O pins are high impedance except for:
|
* @note In Standby mode, all I/O pins are high impedance except for:
|
||||||
* - Reset pad (still available)
|
* - Reset pad (still available)
|
||||||
* - TAMPER pin if configured for tamper or calibration out.
|
* - TAMPER pin if configured for tamper or calibration out.
|
||||||
* - WKUP pin (PA0) if enabled.
|
* - WKUP pin (PA0) if enabled.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_EnterSTANDBYMode(void)
|
void HAL_PWR_EnterSTANDBYMode(void) {
|
||||||
{
|
|
||||||
/* Select Standby mode */
|
/* Select Standby mode */
|
||||||
SET_BIT(PWR->CR, PWR_CR_PDDS);
|
SET_BIT(PWR->CR, PWR_CR_PDDS);
|
||||||
|
|
||||||
@@ -525,79 +501,67 @@ void HAL_PWR_EnterSTANDBYMode(void)
|
|||||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||||
|
|
||||||
/* This option is used to ensure that store operations are completed */
|
/* This option is used to ensure that store operations are completed */
|
||||||
#if defined ( __CC_ARM)
|
#if defined(__CC_ARM)
|
||||||
__force_stores();
|
__force_stores();
|
||||||
#endif
|
#endif
|
||||||
/* Request Wait For Interrupt */
|
/* Request Wait For Interrupt */
|
||||||
__WFI();
|
__WFI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Indicates Sleep-On-Exit when returning from Handler mode to Thread mode.
|
* @brief Indicates Sleep-On-Exit when returning from Handler mode to Thread mode.
|
||||||
* @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor
|
* @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor
|
||||||
* re-enters SLEEP mode when an interruption handling is over.
|
* re-enters SLEEP mode when an interruption handling is over.
|
||||||
* Setting this bit is useful when the processor is expected to run only on
|
* Setting this bit is useful when the processor is expected to run only on
|
||||||
* interruptions handling.
|
* interruptions handling.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_EnableSleepOnExit(void)
|
void HAL_PWR_EnableSleepOnExit(void) {
|
||||||
{
|
|
||||||
/* Set SLEEPONEXIT bit of Cortex System Control Register */
|
/* Set SLEEPONEXIT bit of Cortex System Control Register */
|
||||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
|
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables Sleep-On-Exit feature when returning from Handler mode to Thread mode.
|
* @brief Disables Sleep-On-Exit feature when returning from Handler mode to Thread mode.
|
||||||
* @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the processor
|
* @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the processor
|
||||||
* re-enters SLEEP mode when an interruption handling is over.
|
* re-enters SLEEP mode when an interruption handling is over.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_DisableSleepOnExit(void)
|
void HAL_PWR_DisableSleepOnExit(void) {
|
||||||
{
|
|
||||||
/* Clear SLEEPONEXIT bit of Cortex System Control Register */
|
/* Clear SLEEPONEXIT bit of Cortex System Control Register */
|
||||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
|
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables CORTEX M3 SEVONPEND bit.
|
* @brief Enables CORTEX M3 SEVONPEND bit.
|
||||||
* @note Sets SEVONPEND bit of SCR register. When this bit is set, this causes
|
* @note Sets SEVONPEND bit of SCR register. When this bit is set, this causes
|
||||||
* WFE to wake up when an interrupt moves from inactive to pended.
|
* WFE to wake up when an interrupt moves from inactive to pended.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_EnableSEVOnPend(void)
|
void HAL_PWR_EnableSEVOnPend(void) {
|
||||||
{
|
|
||||||
/* Set SEVONPEND bit of Cortex System Control Register */
|
/* Set SEVONPEND bit of Cortex System Control Register */
|
||||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
|
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disables CORTEX M3 SEVONPEND bit.
|
* @brief Disables CORTEX M3 SEVONPEND bit.
|
||||||
* @note Clears SEVONPEND bit of SCR register. When this bit is set, this causes
|
* @note Clears SEVONPEND bit of SCR register. When this bit is set, this causes
|
||||||
* WFE to wake up when an interrupt moves from inactive to pended.
|
* WFE to wake up when an interrupt moves from inactive to pended.
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_DisableSEVOnPend(void)
|
void HAL_PWR_DisableSEVOnPend(void) {
|
||||||
{
|
|
||||||
/* Clear SEVONPEND bit of Cortex System Control Register */
|
/* Clear SEVONPEND bit of Cortex System Control Register */
|
||||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
|
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles the PWR PVD interrupt request.
|
* @brief This function handles the PWR PVD interrupt request.
|
||||||
* @note This API should be called under the PVD_IRQHandler().
|
* @note This API should be called under the PVD_IRQHandler().
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_PWR_PVD_IRQHandler(void)
|
void HAL_PWR_PVD_IRQHandler(void) {
|
||||||
{
|
|
||||||
/* Check PWR exti flag */
|
/* Check PWR exti flag */
|
||||||
if(__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET)
|
if (__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET) {
|
||||||
{
|
|
||||||
/* PWR PVD interrupt user callback */
|
/* PWR PVD interrupt user callback */
|
||||||
HAL_PWR_PVDCallback();
|
HAL_PWR_PVDCallback();
|
||||||
|
|
||||||
@@ -607,31 +571,30 @@ void HAL_PWR_PVD_IRQHandler(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief PWR PVD interrupt callback
|
* @brief PWR PVD interrupt callback
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
__weak void HAL_PWR_PVDCallback(void)
|
__weak void HAL_PWR_PVDCallback(void) {
|
||||||
{
|
|
||||||
/* NOTE : This function Should not be modified, when the callback is needed,
|
/* NOTE : This function Should not be modified, when the callback is needed,
|
||||||
the HAL_PWR_PVDCallback could be implemented in the user file
|
the HAL_PWR_PVDCallback could be implemented in the user file
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -5,42 +5,37 @@
|
|||||||
* Author: Ralim
|
* Author: Ralim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "BSP_Flash.h"
|
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "string.h"
|
#include "BSP_Flash.h"
|
||||||
#include "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
static uint16_t settings_page[512] __attribute__ ((section (".settings_page")));
|
static uint16_t settings_page[512] __attribute__((section(".settings_page")));
|
||||||
|
|
||||||
uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
|
uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
|
||||||
FLASH_EraseInitTypeDef pEraseInit;
|
FLASH_EraseInitTypeDef pEraseInit;
|
||||||
pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||||
pEraseInit.Banks = FLASH_BANK_1;
|
pEraseInit.Banks = FLASH_BANK_1;
|
||||||
pEraseInit.NbPages = 1;
|
pEraseInit.NbPages = 1;
|
||||||
pEraseInit.PageAddress = (uint32_t) settings_page;
|
pEraseInit.PageAddress = (uint32_t)settings_page;
|
||||||
uint32_t failingAddress = 0;
|
uint32_t failingAddress = 0;
|
||||||
resetWatchdog();
|
resetWatchdog();
|
||||||
__HAL_FLASH_CLEAR_FLAG(
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_BSY);
|
||||||
FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_BSY);
|
HAL_FLASH_Unlock();
|
||||||
HAL_FLASH_Unlock();
|
HAL_Delay(1);
|
||||||
HAL_Delay(1);
|
resetWatchdog();
|
||||||
resetWatchdog();
|
HAL_FLASHEx_Erase(&pEraseInit, &failingAddress);
|
||||||
HAL_FLASHEx_Erase(&pEraseInit, &failingAddress);
|
//^ Erase the page of flash (1024 bytes on this stm32)
|
||||||
//^ Erase the page of flash (1024 bytes on this stm32)
|
// erased the chunk
|
||||||
// erased the chunk
|
// now we program it
|
||||||
// now we program it
|
uint16_t *data = (uint16_t *)buffer;
|
||||||
uint16_t *data = (uint16_t*) buffer;
|
HAL_FLASH_Unlock();
|
||||||
HAL_FLASH_Unlock();
|
for (uint8_t i = 0; i < (length / 2); i++) {
|
||||||
for (uint8_t i = 0; i < (length / 2); i++) {
|
resetWatchdog();
|
||||||
resetWatchdog();
|
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)&settings_page[i], data[i]);
|
||||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,
|
}
|
||||||
(uint32_t) &settings_page[i], data[i]);
|
HAL_FLASH_Lock();
|
||||||
}
|
return 1;
|
||||||
HAL_FLASH_Lock();
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void flash_read_buffer(uint8_t *buffer, const uint16_t length) {
|
void flash_read_buffer(uint8_t *buffer, const uint16_t length) { memcpy(buffer, settings_page, length); }
|
||||||
|
|
||||||
memcpy(buffer, settings_page, length);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -17,10 +17,10 @@
|
|||||||
#include "Model_Config.h"
|
#include "Model_Config.h"
|
||||||
#ifdef POW_PD
|
#ifdef POW_PD
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "fusb302b.h"
|
|
||||||
#include "I2CBB.hpp"
|
#include "I2CBB.hpp"
|
||||||
#include <pd.h>
|
#include "fusb302b.h"
|
||||||
#include "int_n.h"
|
#include "int_n.h"
|
||||||
|
#include <pd.h>
|
||||||
/*
|
/*
|
||||||
* Read a single byte from the FUSB302B
|
* Read a single byte from the FUSB302B
|
||||||
*
|
*
|
||||||
@@ -30,11 +30,11 @@
|
|||||||
* Returns the value read from addr.
|
* Returns the value read from addr.
|
||||||
*/
|
*/
|
||||||
static uint8_t fusb_read_byte(uint8_t addr) {
|
static uint8_t fusb_read_byte(uint8_t addr) {
|
||||||
uint8_t data[1];
|
uint8_t data[1];
|
||||||
if (!I2CBB::Mem_Read(FUSB302B_ADDR, addr, (uint8_t*) data, 1)) {
|
if (!I2CBB::Mem_Read(FUSB302B_ADDR, addr, (uint8_t *)data, 1)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return data[0];
|
return data[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -45,9 +45,7 @@ static uint8_t fusb_read_byte(uint8_t addr) {
|
|||||||
* size: The number of bytes to read
|
* size: The number of bytes to read
|
||||||
* buf: The buffer into which data will be read
|
* buf: The buffer into which data will be read
|
||||||
*/
|
*/
|
||||||
static bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf) {
|
static bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf) { return I2CBB::Mem_Read(FUSB302B_ADDR, addr, buf, size); }
|
||||||
return I2CBB::Mem_Read(FUSB302B_ADDR, addr, buf, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write a single byte to the FUSB302B
|
* Write a single byte to the FUSB302B
|
||||||
@@ -56,9 +54,7 @@ static bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf) {
|
|||||||
* addr: The memory address to which we will write
|
* addr: The memory address to which we will write
|
||||||
* byte: The value to write
|
* byte: The value to write
|
||||||
*/
|
*/
|
||||||
static bool fusb_write_byte(uint8_t addr, uint8_t byte) {
|
static bool fusb_write_byte(uint8_t addr, uint8_t byte) { return I2CBB::Mem_Write(FUSB302B_ADDR, addr, (uint8_t *)&byte, 1); }
|
||||||
return I2CBB::Mem_Write(FUSB302B_ADDR, addr, (uint8_t*) &byte, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write multiple bytes to the FUSB302B
|
* Write multiple bytes to the FUSB302B
|
||||||
@@ -68,198 +64,183 @@ static bool fusb_write_byte(uint8_t addr, uint8_t byte) {
|
|||||||
* size: The number of bytes to write
|
* size: The number of bytes to write
|
||||||
* buf: The buffer to write
|
* buf: The buffer to write
|
||||||
*/
|
*/
|
||||||
static bool fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf) {
|
static bool fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf) { return I2CBB::Mem_Write(FUSB302B_ADDR, addr, buf, size); }
|
||||||
return I2CBB::Mem_Write(FUSB302B_ADDR, addr, buf, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fusb_send_message(const union pd_msg *msg) {
|
void fusb_send_message(const union pd_msg *msg) {
|
||||||
if (!I2CBB::lock2()) {
|
if (!I2CBB::lock2()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Token sequences for the FUSB302B */
|
/* Token sequences for the FUSB302B */
|
||||||
static uint8_t sop_seq[5] = {
|
static uint8_t sop_seq[5] = {FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP1, FUSB_FIFO_TX_SOP2, FUSB_FIFO_TX_PACKSYM};
|
||||||
FUSB_FIFO_TX_SOP1,
|
static const uint8_t eop_seq[4] = {FUSB_FIFO_TX_JAM_CRC, FUSB_FIFO_TX_EOP, FUSB_FIFO_TX_TXOFF, FUSB_FIFO_TX_TXON};
|
||||||
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 */
|
/* Take the I2C2 mutex now so there can't be a race condition on sop_seq */
|
||||||
/* Get the length of the message: a two-octet header plus NUMOBJ four-octet
|
/* Get the length of the message: a two-octet header plus NUMOBJ four-octet
|
||||||
* data objects */
|
* data objects */
|
||||||
uint8_t msg_len = 2 + 4 * PD_NUMOBJ_GET(msg);
|
uint8_t msg_len = 2 + 4 * PD_NUMOBJ_GET(msg);
|
||||||
|
|
||||||
/* Set the number of bytes to be transmitted in the packet */
|
/* Set the number of bytes to be transmitted in the packet */
|
||||||
sop_seq[4] = FUSB_FIFO_TX_PACKSYM | msg_len;
|
sop_seq[4] = FUSB_FIFO_TX_PACKSYM | msg_len;
|
||||||
|
|
||||||
/* Write all three parts of the message to the TX FIFO */
|
/* Write all three parts of the message to the TX FIFO */
|
||||||
fusb_write_buf( FUSB_FIFOS, 5, sop_seq);
|
fusb_write_buf(FUSB_FIFOS, 5, sop_seq);
|
||||||
fusb_write_buf( FUSB_FIFOS, msg_len, msg->bytes);
|
fusb_write_buf(FUSB_FIFOS, msg_len, msg->bytes);
|
||||||
fusb_write_buf( FUSB_FIFOS, 4, eop_seq);
|
fusb_write_buf(FUSB_FIFOS, 4, eop_seq);
|
||||||
|
|
||||||
I2CBB::unlock2();
|
|
||||||
|
|
||||||
|
I2CBB::unlock2();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t fusb_read_message(union pd_msg *msg) {
|
uint8_t fusb_read_message(union pd_msg *msg) {
|
||||||
if (!I2CBB::lock2()) {
|
if (!I2CBB::lock2()) {
|
||||||
asm("bkpt");
|
asm("bkpt");
|
||||||
}
|
}
|
||||||
static uint8_t garbage[4];
|
static uint8_t garbage[4];
|
||||||
uint8_t numobj;
|
uint8_t numobj;
|
||||||
|
|
||||||
// Read the header. If its not a SOP we dont actually want it at all
|
// Read the header. If its not a SOP we dont actually want it at all
|
||||||
// But on some revisions of the fusb if you dont both pick them up and read them out of the fifo, it gets stuck
|
// But on some revisions of the fusb if you dont both pick them up and read them out of the fifo, it gets stuck
|
||||||
fusb_read_byte( FUSB_FIFOS);
|
fusb_read_byte(FUSB_FIFOS);
|
||||||
/* Read the message header into msg */
|
/* Read the message header into msg */
|
||||||
fusb_read_buf( FUSB_FIFOS, 2, msg->bytes);
|
fusb_read_buf(FUSB_FIFOS, 2, msg->bytes);
|
||||||
/* Get the number of data objects */
|
/* Get the number of data objects */
|
||||||
numobj = PD_NUMOBJ_GET(msg);
|
numobj = PD_NUMOBJ_GET(msg);
|
||||||
/* If there is at least one data object, read the data objects */
|
/* If there is at least one data object, read the data objects */
|
||||||
if (numobj > 0) {
|
if (numobj > 0) {
|
||||||
fusb_read_buf( FUSB_FIFOS, numobj * 4, msg->bytes + 2);
|
fusb_read_buf(FUSB_FIFOS, numobj * 4, msg->bytes + 2);
|
||||||
}
|
}
|
||||||
/* Throw the CRC32 in the garbage, since the PHY already checked it. */
|
/* Throw the CRC32 in the garbage, since the PHY already checked it. */
|
||||||
fusb_read_buf( FUSB_FIFOS, 4, garbage);
|
fusb_read_buf(FUSB_FIFOS, 4, garbage);
|
||||||
|
|
||||||
I2CBB::unlock2();
|
I2CBB::unlock2();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fusb_send_hardrst() {
|
void fusb_send_hardrst() {
|
||||||
|
|
||||||
if (!I2CBB::lock2()) {
|
if (!I2CBB::lock2()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Send a hard reset */
|
/* Send a hard reset */
|
||||||
fusb_write_byte( FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET);
|
fusb_write_byte(FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET);
|
||||||
|
|
||||||
I2CBB::unlock2();
|
I2CBB::unlock2();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fusb_setup() {
|
bool fusb_setup() {
|
||||||
|
|
||||||
if (!I2CBB::lock2()) {
|
if (!I2CBB::lock2()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* Fully reset the FUSB302B */
|
/* Fully reset the FUSB302B */
|
||||||
// fusb_write_byte( FUSB_RESET, FUSB_RESET_SW_RES);
|
// fusb_write_byte( FUSB_RESET, FUSB_RESET_SW_RES);
|
||||||
// osDelay(2);
|
// osDelay(2);
|
||||||
if (!fusb_read_id()) {
|
if (!fusb_read_id()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Turn on all power */
|
/* Turn on all power */
|
||||||
fusb_write_byte( FUSB_POWER, 0x0F);
|
fusb_write_byte(FUSB_POWER, 0x0F);
|
||||||
|
|
||||||
/* Set interrupt masks */
|
/* Set interrupt masks */
|
||||||
//Setting to 0 so interrupts are allowed
|
// Setting to 0 so interrupts are allowed
|
||||||
fusb_write_byte( FUSB_MASK1, 0x00);
|
fusb_write_byte(FUSB_MASK1, 0x00);
|
||||||
fusb_write_byte( FUSB_MASKA, 0x00);
|
fusb_write_byte(FUSB_MASKA, 0x00);
|
||||||
fusb_write_byte( FUSB_MASKB, 0x00);
|
fusb_write_byte(FUSB_MASKB, 0x00);
|
||||||
fusb_write_byte( FUSB_CONTROL0, 0b11 << 2);
|
fusb_write_byte(FUSB_CONTROL0, 0b11 << 2);
|
||||||
|
|
||||||
/* Enable automatic retransmission */
|
/* Enable automatic retransmission */
|
||||||
fusb_write_byte( FUSB_CONTROL3, 0x07);
|
fusb_write_byte(FUSB_CONTROL3, 0x07);
|
||||||
//set defaults
|
// set defaults
|
||||||
fusb_write_byte( FUSB_CONTROL2, 0x00);
|
fusb_write_byte(FUSB_CONTROL2, 0x00);
|
||||||
/* Flush the RX buffer */
|
/* Flush the RX buffer */
|
||||||
fusb_write_byte( FUSB_CONTROL1,
|
fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
|
||||||
FUSB_CONTROL1_RX_FLUSH);
|
|
||||||
|
|
||||||
/* Measure CC1 */
|
/* Measure CC1 */
|
||||||
fusb_write_byte( FUSB_SWITCHES0, 0x07);
|
fusb_write_byte(FUSB_SWITCHES0, 0x07);
|
||||||
osDelay(10);
|
osDelay(10);
|
||||||
uint8_t cc1 = fusb_read_byte( FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
|
uint8_t cc1 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
|
||||||
|
|
||||||
/* Measure CC2 */
|
/* Measure CC2 */
|
||||||
fusb_write_byte( FUSB_SWITCHES0, 0x0B);
|
fusb_write_byte(FUSB_SWITCHES0, 0x0B);
|
||||||
osDelay(10);
|
osDelay(10);
|
||||||
uint8_t cc2 = fusb_read_byte( FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
|
uint8_t cc2 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
|
||||||
|
|
||||||
/* Select the correct CC line for BMC signaling; also enable AUTO_CRC */
|
/* Select the correct CC line for BMC signaling; also enable AUTO_CRC */
|
||||||
if (cc1 > cc2) {
|
if (cc1 > cc2) {
|
||||||
fusb_write_byte( FUSB_SWITCHES1, 0x25);
|
fusb_write_byte(FUSB_SWITCHES1, 0x25);
|
||||||
fusb_write_byte( FUSB_SWITCHES0, 0x07);
|
fusb_write_byte(FUSB_SWITCHES0, 0x07);
|
||||||
} else {
|
} else {
|
||||||
fusb_write_byte( FUSB_SWITCHES1, 0x26);
|
fusb_write_byte(FUSB_SWITCHES1, 0x26);
|
||||||
fusb_write_byte( FUSB_SWITCHES0, 0x0B);
|
fusb_write_byte(FUSB_SWITCHES0, 0x0B);
|
||||||
}
|
}
|
||||||
I2CBB::unlock2();
|
I2CBB::unlock2();
|
||||||
fusb_reset();
|
fusb_reset();
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
|
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
|
||||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 10, 0);
|
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 10, 0);
|
||||||
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
|
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fusb_get_status(union fusb_status *status) {
|
void fusb_get_status(union fusb_status *status) {
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
if (!I2CBB::lock2()) {
|
if (!I2CBB::lock2()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the interrupt and status flags into status */
|
|
||||||
fusb_read_buf( FUSB_STATUS0A, 7, status->bytes);
|
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
|
||||||
I2CBB::unlock2();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* 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() {
|
enum fusb_typec_current fusb_get_typec_current() {
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
if (!I2CBB::lock2()) {
|
if (!I2CBB::lock2()) {
|
||||||
return fusb_tcc_none;
|
return fusb_tcc_none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Read the BC_LVL into a variable */
|
/* Read the BC_LVL into a variable */
|
||||||
enum fusb_typec_current bc_lvl = (enum fusb_typec_current) (fusb_read_byte(
|
enum fusb_typec_current bc_lvl = (enum fusb_typec_current)(fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL);
|
||||||
FUSB_STATUS0) & FUSB_STATUS0_BC_LVL);
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
I2CBB::unlock2();
|
||||||
I2CBB::unlock2();
|
}
|
||||||
}
|
return bc_lvl;
|
||||||
return bc_lvl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fusb_reset() {
|
void fusb_reset() {
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
if (!I2CBB::lock2()) {
|
if (!I2CBB::lock2()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush the TX buffer */
|
/* Flush the TX buffer */
|
||||||
fusb_write_byte( FUSB_CONTROL0, 0x44);
|
fusb_write_byte(FUSB_CONTROL0, 0x44);
|
||||||
/* Flush the RX buffer */
|
/* Flush the RX buffer */
|
||||||
fusb_write_byte( FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
|
fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
I2CBB::unlock2();
|
I2CBB::unlock2();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fusb_read_id() {
|
bool fusb_read_id() {
|
||||||
//Return true if read of the revision ID is sane
|
// Return true if read of the revision ID is sane
|
||||||
uint8_t version = 0;
|
uint8_t version = 0;
|
||||||
fusb_read_buf(FUSB_DEVICE_ID, 1, &version);
|
fusb_read_buf(FUSB_DEVICE_ID, 1, &version);
|
||||||
if (version == 0 || version == 0xFF)
|
if (version == 0 || version == 0xFF)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
uint8_t fusb302_detect() {
|
uint8_t fusb302_detect() {
|
||||||
//Probe the I2C bus for its address
|
// Probe the I2C bus for its address
|
||||||
return I2CBB::probe(FUSB302B_ADDR);
|
return I2CBB::probe(FUSB302B_ADDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,19 +8,18 @@
|
|||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "OLED.hpp"
|
#include "OLED.hpp"
|
||||||
|
|
||||||
static uint8_t logo_page[1024] __attribute__ ((section (".logo_page")));
|
static uint8_t logo_page[1024] __attribute__((section(".logo_page")));
|
||||||
|
|
||||||
// Logo header signature.
|
// Logo header signature.
|
||||||
#define LOGO_HEADER_VALUE 0xF00DAA55
|
#define LOGO_HEADER_VALUE 0xF00DAA55
|
||||||
|
|
||||||
uint8_t showBootLogoIfavailable() {
|
uint8_t showBootLogoIfavailable() {
|
||||||
// Do not show logo data if signature is not found.
|
// Do not show logo data if signature is not found.
|
||||||
if (LOGO_HEADER_VALUE != *(reinterpret_cast<const uint32_t*>(logo_page))) {
|
if (LOGO_HEADER_VALUE != *(reinterpret_cast<const uint32_t *>(logo_page))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
OLED::drawAreaSwapped(0, 0, 96, 16, (uint8_t*) (logo_page + 4));
|
OLED::drawAreaSwapped(0, 0, 96, 16, (uint8_t *)(logo_page + 4));
|
||||||
OLED::refresh();
|
OLED::refresh();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,21 +1,21 @@
|
|||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
#include "I2C_Wrapper.hpp"
|
||||||
#include "QC3.h"
|
#include "QC3.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
|
#include "fusbpd.h"
|
||||||
#include "main.hpp"
|
#include "main.hpp"
|
||||||
#include "power.hpp"
|
#include "power.hpp"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "I2C_Wrapper.hpp"
|
|
||||||
#include "fusbpd.h"
|
|
||||||
|
|
||||||
// Initialisation to be performed with scheduler active
|
// Initialisation to be performed with scheduler active
|
||||||
void postRToSInit() {
|
void postRToSInit() {
|
||||||
#ifdef POW_PD
|
#ifdef POW_PD
|
||||||
if (usb_pd_detect() == true) {
|
if (usb_pd_detect() == true) {
|
||||||
//Spawn all of the USB-C processors
|
// Spawn all of the USB-C processors
|
||||||
fusb302_start_processing();
|
fusb302_start_processing();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,22 +5,22 @@
|
|||||||
* Author: Ralim
|
* Author: Ralim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <I2C_Wrapper.hpp>
|
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "Setup.h"
|
|
||||||
#include "Pins.h"
|
|
||||||
#include "I2CBB.hpp"
|
#include "I2CBB.hpp"
|
||||||
#include "fusbpd.h"
|
|
||||||
#include "Model_Config.h"
|
#include "Model_Config.h"
|
||||||
|
#include "Pins.h"
|
||||||
|
#include "Setup.h"
|
||||||
|
#include "fusbpd.h"
|
||||||
|
#include <I2C_Wrapper.hpp>
|
||||||
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.
|
||||||
*/
|
*/
|
||||||
HAL_Init();
|
HAL_Init();
|
||||||
Setup_HAL(); // Setup all the HAL objects
|
Setup_HAL(); // Setup all the HAL objects
|
||||||
BSPInit();
|
BSPInit();
|
||||||
#ifdef I2C_SOFT
|
#ifdef I2C_SOFT
|
||||||
I2CBB::init();
|
I2CBB::init();
|
||||||
#endif
|
#endif
|
||||||
/* Init the IPC objects */
|
/* Init the IPC objects */
|
||||||
FRToSI2C::FRToSInit();
|
FRToSI2C::FRToSInit();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,141 +1,132 @@
|
|||||||
#include "Pins.h"
|
#include "Pins.h"
|
||||||
#include "stm32f1xx_hal.h"
|
|
||||||
#include "Setup.h"
|
#include "Setup.h"
|
||||||
|
#include "stm32f1xx_hal.h"
|
||||||
/**
|
/**
|
||||||
* Initializes the Global MSP.
|
* Initializes the Global MSP.
|
||||||
*/
|
*/
|
||||||
void HAL_MspInit(void) {
|
void HAL_MspInit(void) {
|
||||||
__HAL_RCC_AFIO_CLK_ENABLE()
|
__HAL_RCC_AFIO_CLK_ENABLE();
|
||||||
;
|
|
||||||
|
|
||||||
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
|
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
|
||||||
|
|
||||||
/* System interrupt init*/
|
|
||||||
/* MemoryManagement_IRQn interrupt configuration */
|
|
||||||
HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
|
|
||||||
/* BusFault_IRQn interrupt configuration */
|
|
||||||
HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
|
|
||||||
/* UsageFault_IRQn interrupt configuration */
|
|
||||||
HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
|
|
||||||
/* SVCall_IRQn interrupt configuration */
|
|
||||||
HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0);
|
|
||||||
/* DebugMonitor_IRQn interrupt configuration */
|
|
||||||
HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
|
|
||||||
/* PendSV_IRQn interrupt configuration */
|
|
||||||
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
|
|
||||||
/* SysTick_IRQn interrupt configuration */
|
|
||||||
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
|
|
||||||
|
|
||||||
|
/* System interrupt init*/
|
||||||
|
/* MemoryManagement_IRQn interrupt configuration */
|
||||||
|
HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
|
||||||
|
/* BusFault_IRQn interrupt configuration */
|
||||||
|
HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
|
||||||
|
/* UsageFault_IRQn interrupt configuration */
|
||||||
|
HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
|
||||||
|
/* SVCall_IRQn interrupt configuration */
|
||||||
|
HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0);
|
||||||
|
/* DebugMonitor_IRQn interrupt configuration */
|
||||||
|
HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
|
||||||
|
/* PendSV_IRQn interrupt configuration */
|
||||||
|
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
|
||||||
|
/* SysTick_IRQn interrupt configuration */
|
||||||
|
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc) {
|
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc) {
|
||||||
|
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
if (hadc->Instance == ADC1) {
|
if (hadc->Instance == ADC1) {
|
||||||
__HAL_RCC_ADC1_CLK_ENABLE()
|
__HAL_RCC_ADC1_CLK_ENABLE();
|
||||||
;
|
|
||||||
|
|
||||||
/* ADC1 DMA Init */
|
/* ADC1 DMA Init */
|
||||||
/* ADC1 Init */
|
/* ADC1 Init */
|
||||||
hdma_adc1.Instance = DMA1_Channel1;
|
hdma_adc1.Instance = DMA1_Channel1;
|
||||||
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||||
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
|
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||||
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
|
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
|
||||||
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
|
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
|
||||||
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
|
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
|
||||||
hdma_adc1.Init.Mode = DMA_CIRCULAR;
|
hdma_adc1.Init.Mode = DMA_CIRCULAR;
|
||||||
hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;
|
hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;
|
||||||
HAL_DMA_Init(&hdma_adc1);
|
HAL_DMA_Init(&hdma_adc1);
|
||||||
|
|
||||||
__HAL_LINKDMA(hadc, DMA_Handle, hdma_adc1);
|
__HAL_LINKDMA(hadc, DMA_Handle, hdma_adc1);
|
||||||
|
|
||||||
/* ADC1 interrupt Init */
|
/* ADC1 interrupt Init */
|
||||||
HAL_NVIC_SetPriority(ADC1_2_IRQn, 15, 0);
|
HAL_NVIC_SetPriority(ADC1_2_IRQn, 15, 0);
|
||||||
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
|
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
|
||||||
} else {
|
} else {
|
||||||
__HAL_RCC_ADC2_CLK_ENABLE()
|
__HAL_RCC_ADC2_CLK_ENABLE();
|
||||||
;
|
|
||||||
|
|
||||||
/**ADC2 GPIO Configuration
|
/**ADC2 GPIO Configuration
|
||||||
PB0 ------> ADC2_IN8
|
PB0 ------> ADC2_IN8
|
||||||
PB1 ------> ADC2_IN9
|
PB1 ------> ADC2_IN9
|
||||||
*/
|
*/
|
||||||
GPIO_InitStruct.Pin = TIP_TEMP_Pin;
|
GPIO_InitStruct.Pin = TIP_TEMP_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||||
HAL_GPIO_Init(TIP_TEMP_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(TIP_TEMP_GPIO_Port, &GPIO_InitStruct);
|
||||||
GPIO_InitStruct.Pin = TMP36_INPUT_Pin;
|
GPIO_InitStruct.Pin = TMP36_INPUT_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||||
HAL_GPIO_Init(TMP36_INPUT_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(TMP36_INPUT_GPIO_Port, &GPIO_InitStruct);
|
||||||
GPIO_InitStruct.Pin = VIN_Pin;
|
GPIO_InitStruct.Pin = VIN_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||||
HAL_GPIO_Init(VIN_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(VIN_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
/* ADC2 interrupt Init */
|
|
||||||
HAL_NVIC_SetPriority(ADC1_2_IRQn, 15, 0);
|
|
||||||
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* ADC2 interrupt Init */
|
||||||
|
HAL_NVIC_SetPriority(ADC1_2_IRQn, 15, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) {
|
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) {
|
||||||
|
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
/**I2C1 GPIO Configuration
|
/**I2C1 GPIO Configuration
|
||||||
PB6 ------> I2C1_SCL
|
PB6 ------> I2C1_SCL
|
||||||
PB7 ------> I2C1_SDA
|
PB7 ------> I2C1_SDA
|
||||||
*/
|
*/
|
||||||
GPIO_InitStruct.Pin = SCL_Pin | SDA_Pin;
|
GPIO_InitStruct.Pin = SCL_Pin | SDA_Pin;
|
||||||
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;
|
||||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
|
|
||||||
/* Peripheral clock enable */
|
/* Peripheral clock enable */
|
||||||
__HAL_RCC_I2C1_CLK_ENABLE()
|
__HAL_RCC_I2C1_CLK_ENABLE();
|
||||||
;
|
/* I2C1 DMA Init */
|
||||||
/* I2C1 DMA Init */
|
/* I2C1_RX Init */
|
||||||
/* I2C1_RX Init */
|
hdma_i2c1_rx.Instance = DMA1_Channel7;
|
||||||
hdma_i2c1_rx.Instance = DMA1_Channel7;
|
hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||||
hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||||
hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||||
hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;
|
hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||||
hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||||
hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
hdma_i2c1_rx.Init.Mode = DMA_NORMAL;
|
||||||
hdma_i2c1_rx.Init.Mode = DMA_NORMAL;
|
hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW;
|
||||||
hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW;
|
HAL_DMA_Init(&hdma_i2c1_rx);
|
||||||
HAL_DMA_Init(&hdma_i2c1_rx);
|
|
||||||
|
|
||||||
__HAL_LINKDMA(hi2c, hdmarx, hdma_i2c1_rx);
|
__HAL_LINKDMA(hi2c, hdmarx, hdma_i2c1_rx);
|
||||||
|
|
||||||
/* I2C1_TX Init */
|
/* I2C1_TX Init */
|
||||||
hdma_i2c1_tx.Instance = DMA1_Channel6;
|
hdma_i2c1_tx.Instance = DMA1_Channel6;
|
||||||
hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||||
hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||||
hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
|
hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||||
hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||||
hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||||
hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
|
hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
|
||||||
hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
|
hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
|
||||||
HAL_DMA_Init(&hdma_i2c1_tx);
|
HAL_DMA_Init(&hdma_i2c1_tx);
|
||||||
|
|
||||||
__HAL_LINKDMA(hi2c, hdmatx, hdma_i2c1_tx);
|
__HAL_LINKDMA(hi2c, hdmatx, hdma_i2c1_tx);
|
||||||
|
|
||||||
/* I2C1 interrupt Init */
|
|
||||||
HAL_NVIC_SetPriority(I2C1_EV_IRQn, 15, 0);
|
|
||||||
HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
|
|
||||||
HAL_NVIC_SetPriority(I2C1_ER_IRQn, 15, 0);
|
|
||||||
HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
|
|
||||||
|
|
||||||
|
/* I2C1 interrupt Init */
|
||||||
|
HAL_NVIC_SetPriority(I2C1_EV_IRQn, 15, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
|
||||||
|
HAL_NVIC_SetPriority(I2C1_ER_IRQn, 15, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim_base) {
|
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim_base) {
|
||||||
if (htim_base->Instance == TIM3) {
|
if (htim_base->Instance == TIM3) {
|
||||||
/* Peripheral clock enable */
|
/* Peripheral clock enable */
|
||||||
__HAL_RCC_TIM3_CLK_ENABLE()
|
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||||
;
|
} else if (htim_base->Instance == TIM2) {
|
||||||
} else if (htim_base->Instance == TIM2) {
|
/* Peripheral clock enable */
|
||||||
/* Peripheral clock enable */
|
__HAL_RCC_TIM2_CLK_ENABLE();
|
||||||
__HAL_RCC_TIM2_CLK_ENABLE()
|
}
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
/* Private macro -------------------------------------------------------------*/
|
/* Private macro -------------------------------------------------------------*/
|
||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
TIM_HandleTypeDef htim1;
|
TIM_HandleTypeDef htim1;
|
||||||
uint32_t uwIncrementState = 0;
|
uint32_t uwIncrementState = 0;
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
/* Private functions ---------------------------------------------------------*/
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -76,49 +76,49 @@ uint32_t uwIncrementState = 0;
|
|||||||
* @retval HAL status
|
* @retval HAL status
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
|
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
|
||||||
RCC_ClkInitTypeDef clkconfig;
|
RCC_ClkInitTypeDef clkconfig;
|
||||||
uint32_t uwTimclock = 0;
|
uint32_t uwTimclock = 0;
|
||||||
uint32_t uwPrescalerValue = 0;
|
uint32_t uwPrescalerValue = 0;
|
||||||
uint32_t pFLatency;
|
uint32_t pFLatency;
|
||||||
|
|
||||||
/*Configure the TIM1 IRQ priority */
|
/*Configure the TIM1 IRQ priority */
|
||||||
HAL_NVIC_SetPriority(TIM1_UP_IRQn, TickPriority, 0);
|
HAL_NVIC_SetPriority(TIM1_UP_IRQn, TickPriority, 0);
|
||||||
|
|
||||||
/* Enable the TIM1 global Interrupt */
|
/* Enable the TIM1 global Interrupt */
|
||||||
HAL_NVIC_EnableIRQ(TIM1_UP_IRQn);
|
HAL_NVIC_EnableIRQ(TIM1_UP_IRQn);
|
||||||
|
|
||||||
/* Enable TIM1 clock */
|
/* Enable TIM1 clock */
|
||||||
__HAL_RCC_TIM1_CLK_ENABLE();
|
__HAL_RCC_TIM1_CLK_ENABLE();
|
||||||
|
|
||||||
/* Get clock configuration */
|
/* Get clock configuration */
|
||||||
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
||||||
|
|
||||||
/* Compute TIM1 clock */
|
/* Compute TIM1 clock */
|
||||||
uwTimclock = HAL_RCC_GetPCLK2Freq();
|
uwTimclock = HAL_RCC_GetPCLK2Freq();
|
||||||
|
|
||||||
/* Compute the prescaler value to have TIM1 counter clock equal to 1MHz */
|
/* Compute the prescaler value to have TIM1 counter clock equal to 1MHz */
|
||||||
uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000) - 1);
|
uwPrescalerValue = (uint32_t)((uwTimclock / 1000000) - 1);
|
||||||
|
|
||||||
/* Initialize TIM1 */
|
/* Initialize TIM1 */
|
||||||
htim1.Instance = TIM1;
|
htim1.Instance = TIM1;
|
||||||
|
|
||||||
/* Initialize TIMx peripheral as follow:
|
/* Initialize TIMx peripheral as follow:
|
||||||
+ Period = [(TIM1CLK/1000) - 1]. to have a (1/1000) s time base.
|
+ Period = [(TIM1CLK/1000) - 1]. to have a (1/1000) s time base.
|
||||||
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
|
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
|
||||||
+ ClockDivision = 0
|
+ ClockDivision = 0
|
||||||
+ Counter direction = Up
|
+ Counter direction = Up
|
||||||
*/
|
*/
|
||||||
htim1.Init.Period = (1000000 / 1000) - 1;
|
htim1.Init.Period = (1000000 / 1000) - 1;
|
||||||
htim1.Init.Prescaler = uwPrescalerValue;
|
htim1.Init.Prescaler = uwPrescalerValue;
|
||||||
htim1.Init.ClockDivision = 0;
|
htim1.Init.ClockDivision = 0;
|
||||||
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
|
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
if (HAL_TIM_Base_Init(&htim1) == HAL_OK) {
|
if (HAL_TIM_Base_Init(&htim1) == HAL_OK) {
|
||||||
/* Start the TIM time Base generation in interrupt mode */
|
/* Start the TIM time Base generation in interrupt mode */
|
||||||
return HAL_TIM_Base_Start_IT(&htim1);
|
return HAL_TIM_Base_Start_IT(&htim1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return function status */
|
/* Return function status */
|
||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,8 +128,8 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
|
|||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_SuspendTick(void) {
|
void HAL_SuspendTick(void) {
|
||||||
/* Disable TIM1 update Interrupt */
|
/* Disable TIM1 update Interrupt */
|
||||||
__HAL_TIM_DISABLE_IT(&htim1, TIM_IT_UPDATE);
|
__HAL_TIM_DISABLE_IT(&htim1, TIM_IT_UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,8 +139,8 @@ void HAL_SuspendTick(void) {
|
|||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void HAL_ResumeTick(void) {
|
void HAL_ResumeTick(void) {
|
||||||
/* Enable TIM1 Update interrupt */
|
/* Enable TIM1 Update interrupt */
|
||||||
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);
|
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,42 +1,34 @@
|
|||||||
// This is the stock standard STM interrupt file full of handlers
|
// This is the stock standard STM interrupt file full of handlers
|
||||||
#include "stm32f1xx_hal.h"
|
|
||||||
#include "stm32f1xx.h"
|
|
||||||
#include "stm32f1xx_it.h"
|
#include "stm32f1xx_it.h"
|
||||||
#include "cmsis_os.h"
|
|
||||||
#include "Setup.h"
|
#include "Setup.h"
|
||||||
|
#include "cmsis_os.h"
|
||||||
|
#include "stm32f1xx.h"
|
||||||
|
#include "stm32f1xx_hal.h"
|
||||||
|
|
||||||
extern TIM_HandleTypeDef htim1; //used for the systick
|
extern TIM_HandleTypeDef htim1; // used for the systick
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Cortex-M3 Processor Interruption and Exception Handlers */
|
/* Cortex-M3 Processor Interruption and Exception Handlers */
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
void NMI_Handler(void) {
|
void NMI_Handler(void) {}
|
||||||
}
|
|
||||||
|
|
||||||
//We have the assembly for a breakpoint trigger here to halt the system when a debugger is connected
|
// We have the assembly for a breakpoint trigger here to halt the system when a debugger is connected
|
||||||
// Hardfault handler, often a screwup in the code
|
// Hardfault handler, often a screwup in the code
|
||||||
void HardFault_Handler(void) {
|
void HardFault_Handler(void) {}
|
||||||
}
|
|
||||||
|
|
||||||
// Memory management unit had an error
|
// Memory management unit had an error
|
||||||
void MemManage_Handler(void) {
|
void MemManage_Handler(void) {}
|
||||||
}
|
|
||||||
|
|
||||||
// Prefetcher or busfault occured
|
// Prefetcher or busfault occured
|
||||||
void BusFault_Handler(void) {
|
void BusFault_Handler(void) {}
|
||||||
}
|
|
||||||
|
|
||||||
void UsageFault_Handler(void) {
|
void UsageFault_Handler(void) {}
|
||||||
}
|
|
||||||
|
|
||||||
void DebugMon_Handler(void) {
|
void DebugMon_Handler(void) {}
|
||||||
}
|
|
||||||
|
|
||||||
// Systick is used by FreeRTOS tick
|
// Systick is used by FreeRTOS tick
|
||||||
void SysTick_Handler(void) {
|
void SysTick_Handler(void) { osSystickHandler(); }
|
||||||
osSystickHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* STM32F1xx Peripheral Interrupt Handlers */
|
/* STM32F1xx Peripheral Interrupt Handlers */
|
||||||
@@ -46,42 +38,22 @@ void SysTick_Handler(void) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// DMA used to move the ADC readings into system ram
|
// DMA used to move the ADC readings into system ram
|
||||||
void DMA1_Channel1_IRQHandler(void) {
|
void DMA1_Channel1_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_adc1); }
|
||||||
HAL_DMA_IRQHandler(&hdma_adc1);
|
// ADC interrupt used for DMA
|
||||||
}
|
void ADC1_2_IRQHandler(void) { HAL_ADC_IRQHandler(&hadc1); }
|
||||||
//ADC interrupt used for DMA
|
|
||||||
void ADC1_2_IRQHandler(void) {
|
|
||||||
HAL_ADC_IRQHandler(&hadc1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Timer 1 has overflowed, used for HAL ticks
|
// Timer 1 has overflowed, used for HAL ticks
|
||||||
void TIM1_UP_IRQHandler(void) {
|
void TIM1_UP_IRQHandler(void) { HAL_TIM_IRQHandler(&htim1); }
|
||||||
HAL_TIM_IRQHandler(&htim1);
|
// Timer 3 is used for the PWM output to the tip
|
||||||
}
|
void TIM3_IRQHandler(void) { HAL_TIM_IRQHandler(&htim3); }
|
||||||
//Timer 3 is used for the PWM output to the tip
|
|
||||||
void TIM3_IRQHandler(void) {
|
|
||||||
HAL_TIM_IRQHandler(&htim3);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Timer 2 is used for co-ordination of PWM & ADC
|
// Timer 2 is used for co-ordination of PWM & ADC
|
||||||
void TIM2_IRQHandler(void) {
|
void TIM2_IRQHandler(void) { HAL_TIM_IRQHandler(&htim2); }
|
||||||
HAL_TIM_IRQHandler(&htim2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void I2C1_EV_IRQHandler(void) {
|
void I2C1_EV_IRQHandler(void) { HAL_I2C_EV_IRQHandler(&hi2c1); }
|
||||||
HAL_I2C_EV_IRQHandler(&hi2c1);
|
void I2C1_ER_IRQHandler(void) { HAL_I2C_ER_IRQHandler(&hi2c1); }
|
||||||
}
|
|
||||||
void I2C1_ER_IRQHandler(void) {
|
|
||||||
HAL_I2C_ER_IRQHandler(&hi2c1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DMA1_Channel6_IRQHandler(void) {
|
void DMA1_Channel6_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_i2c1_tx); }
|
||||||
HAL_DMA_IRQHandler(&hdma_i2c1_tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
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); }
|
||||||
}
|
|
||||||
void EXTI9_5_IRQHandler(void) {
|
|
||||||
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
// And as such, is BSD licneced from STM
|
// And as such, is BSD licneced from STM
|
||||||
#include "stm32f1xx.h"
|
#include "stm32f1xx.h"
|
||||||
|
|
||||||
#if !defined (HSI_VALUE)
|
#if !defined(HSI_VALUE)
|
||||||
#define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
|
#define HSI_VALUE \
|
||||||
This value can be provided and adapted by the user application. */
|
8000000U /*!< Default value of the Internal oscillator in Hz. \
|
||||||
#endif /* HSI_VALUE */
|
This value can be provided and adapted by the user application. */
|
||||||
|
#endif /* HSI_VALUE */
|
||||||
|
|
||||||
/*!< Uncomment the following line if you need to use external SRAM */
|
/*!< Uncomment the following line if you need to use external SRAM */
|
||||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||||
@@ -13,23 +14,23 @@
|
|||||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||||
|
|
||||||
#ifndef VECT_TAB_OFFSET
|
#ifndef VECT_TAB_OFFSET
|
||||||
#define VECT_TAB_OFFSET 0x00004000U /*!< Vector Table base offset field.
|
#define VECT_TAB_OFFSET \
|
||||||
This value must be a multiple of 0x200. */
|
0x00004000U /*!< Vector Table base offset field. \
|
||||||
//We offset this by 0x4000 to because of the bootloader
|
This value must be a multiple of 0x200. */
|
||||||
|
// We offset this by 0x4000 to because of the bootloader
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Clock Definitions
|
* Clock Definitions
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
#if defined(STM32F100xB) ||defined(STM32F100xE)
|
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||||
uint32_t SystemCoreClock = 24000000U; /*!< System Clock Frequency (Core Clock) */
|
uint32_t SystemCoreClock = 24000000U; /*!< System Clock Frequency (Core Clock) */
|
||||||
#else /*!< HSI Selected as System Clock source */
|
#else /*!< HSI Selected as System Clock source */
|
||||||
uint32_t SystemCoreClock = 64000000U; /*!< System Clock Frequency (Core Clock) */
|
uint32_t SystemCoreClock = 64000000U; /*!< System Clock Frequency (Core Clock) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const uint8_t AHBPrescTable[16U] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7,
|
const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||||
8, 9 };
|
const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||||
const uint8_t APBPrescTable[8U] = { 0, 0, 0, 0, 1, 2, 3, 4 };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the microcontroller system
|
* @brief Setup the microcontroller system
|
||||||
@@ -40,57 +41,57 @@ const uint8_t APBPrescTable[8U] = { 0, 0, 0, 0, 1, 2, 3, 4 };
|
|||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void SystemInit(void) {
|
void SystemInit(void) {
|
||||||
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
|
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
|
||||||
/* Set HSION bit */
|
/* Set HSION bit */
|
||||||
RCC->CR |= 0x00000001U;
|
RCC->CR |= 0x00000001U;
|
||||||
|
|
||||||
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
|
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
|
||||||
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
||||||
RCC->CFGR &= 0xF8FF0000U;
|
RCC->CFGR &= 0xF8FF0000U;
|
||||||
#else
|
#else
|
||||||
RCC->CFGR &= 0xF0FF0000U;
|
RCC->CFGR &= 0xF0FF0000U;
|
||||||
#endif /* STM32F105xC */
|
#endif /* STM32F105xC */
|
||||||
|
|
||||||
/* Reset HSEON, CSSON and PLLON bits */
|
/* Reset HSEON, CSSON and PLLON bits */
|
||||||
RCC->CR &= 0xFEF6FFFFU;
|
RCC->CR &= 0xFEF6FFFFU;
|
||||||
|
|
||||||
/* Reset HSEBYP bit */
|
/* Reset HSEBYP bit */
|
||||||
RCC->CR &= 0xFFFBFFFFU;
|
RCC->CR &= 0xFFFBFFFFU;
|
||||||
|
|
||||||
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
|
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
|
||||||
RCC->CFGR &= 0xFF80FFFFU;
|
RCC->CFGR &= 0xFF80FFFFU;
|
||||||
|
|
||||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||||
/* Reset PLL2ON and PLL3ON bits */
|
/* Reset PLL2ON and PLL3ON bits */
|
||||||
RCC->CR &= 0xEBFFFFFFU;
|
RCC->CR &= 0xEBFFFFFFU;
|
||||||
|
|
||||||
/* Disable all interrupts and clear pending bits */
|
/* Disable all interrupts and clear pending bits */
|
||||||
RCC->CIR = 0x00FF0000U;
|
RCC->CIR = 0x00FF0000U;
|
||||||
|
|
||||||
/* Reset CFGR2 register */
|
/* Reset CFGR2 register */
|
||||||
RCC->CFGR2 = 0x00000000U;
|
RCC->CFGR2 = 0x00000000U;
|
||||||
#elif defined(STM32F100xB) || defined(STM32F100xE)
|
#elif defined(STM32F100xB) || defined(STM32F100xE)
|
||||||
/* Disable all interrupts and clear pending bits */
|
/* Disable all interrupts and clear pending bits */
|
||||||
RCC->CIR = 0x009F0000U;
|
RCC->CIR = 0x009F0000U;
|
||||||
|
|
||||||
/* Reset CFGR2 register */
|
/* Reset CFGR2 register */
|
||||||
RCC->CFGR2 = 0x00000000U;
|
RCC->CFGR2 = 0x00000000U;
|
||||||
#else
|
#else
|
||||||
/* Disable all interrupts and clear pending bits */
|
/* Disable all interrupts and clear pending bits */
|
||||||
RCC->CIR = 0x009F0000U;
|
RCC->CIR = 0x009F0000U;
|
||||||
#endif /* STM32F105xC */
|
#endif /* STM32F105xC */
|
||||||
|
|
||||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||||
#ifdef DATA_IN_ExtSRAM
|
#ifdef DATA_IN_ExtSRAM
|
||||||
SystemInit_ExtMemCtl();
|
SystemInit_ExtMemCtl();
|
||||||
#endif /* DATA_IN_ExtSRAM */
|
#endif /* DATA_IN_ExtSRAM */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VECT_TAB_SRAM
|
#ifdef VECT_TAB_SRAM
|
||||||
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
|
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
|
||||||
#else
|
#else
|
||||||
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
|
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,7 +130,7 @@ void SystemInit(void) {
|
|||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void SystemCoreClockUpdate(void) {
|
void SystemCoreClockUpdate(void) {
|
||||||
uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
|
uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
|
||||||
|
|
||||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||||
uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
|
uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
|
||||||
@@ -139,116 +140,106 @@ void SystemCoreClockUpdate(void) {
|
|||||||
uint32_t prediv1factor = 0U;
|
uint32_t prediv1factor = 0U;
|
||||||
#endif /* STM32F100xB or STM32F100xE */
|
#endif /* STM32F100xB or STM32F100xE */
|
||||||
|
|
||||||
/* Get SYSCLK source -------------------------------------------------------*/
|
/* Get SYSCLK source -------------------------------------------------------*/
|
||||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||||
|
|
||||||
switch (tmp) {
|
switch (tmp) {
|
||||||
case 0x00U: /* HSI used as system clock */
|
case 0x00U: /* HSI used as system clock */
|
||||||
SystemCoreClock = HSI_VALUE;
|
SystemCoreClock = HSI_VALUE;
|
||||||
break;
|
break;
|
||||||
case 0x04U: /* HSE used as system clock */
|
case 0x04U: /* HSE used as system clock */
|
||||||
SystemCoreClock = HSE_VALUE;
|
SystemCoreClock = HSE_VALUE;
|
||||||
break;
|
break;
|
||||||
case 0x08U: /* PLL used as system clock */
|
case 0x08U: /* PLL used as system clock */
|
||||||
|
|
||||||
/* Get PLL clock source and multiplication factor ----------------------*/
|
/* Get PLL clock source and multiplication factor ----------------------*/
|
||||||
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
|
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
|
||||||
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
||||||
|
|
||||||
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
||||||
pllmull = (pllmull >> 18U) + 2U;
|
pllmull = (pllmull >> 18U) + 2U;
|
||||||
|
|
||||||
if (pllsource == 0x00U) {
|
if (pllsource == 0x00U) {
|
||||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||||
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||||
} else {
|
} else {
|
||||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||||
#else
|
|
||||||
/* HSE selected as PLL clock entry */
|
|
||||||
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t) RESET) {/* HSE oscillator clock divided by 2 */
|
|
||||||
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
|
|
||||||
} else {
|
|
||||||
SystemCoreClock = HSE_VALUE * pllmull;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
pllmull = pllmull >> 18U;
|
/* HSE selected as PLL clock entry */
|
||||||
|
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET) { /* HSE oscillator clock divided by 2 */
|
||||||
if (pllmull != 0x0DU)
|
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
|
||||||
{
|
} else {
|
||||||
pllmull += 2U;
|
SystemCoreClock = HSE_VALUE * pllmull;
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
{ /* PLL multiplication factor = PLL input clock * 6.5 */
|
}
|
||||||
pllmull = 13U / 2U;
|
#else
|
||||||
}
|
pllmull = pllmull >> 18U;
|
||||||
|
|
||||||
if (pllsource == 0x00U)
|
|
||||||
{
|
|
||||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
|
||||||
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{/* PREDIV1 selected as PLL clock entry */
|
|
||||||
|
|
||||||
/* Get PREDIV1 clock source and division factor */
|
|
||||||
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
|
|
||||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
|
||||||
|
|
||||||
if (prediv1source == 0U)
|
|
||||||
{
|
|
||||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
|
||||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{/* PLL2 clock selected as PREDIV1 clock entry */
|
|
||||||
|
|
||||||
/* Get PREDIV2 division factor and PLL2 multiplication factor */
|
|
||||||
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
|
|
||||||
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
|
|
||||||
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* STM32F105xC */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
if (pllmull != 0x0DU) {
|
||||||
SystemCoreClock = HSI_VALUE;
|
pllmull += 2U;
|
||||||
break;
|
} else { /* PLL multiplication factor = PLL input clock * 6.5 */
|
||||||
}
|
pllmull = 13U / 2U;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute HCLK clock frequency ----------------*/
|
if (pllsource == 0x00U) {
|
||||||
/* Get HCLK prescaler */
|
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
|
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||||
/* HCLK clock frequency */
|
} else { /* PREDIV1 selected as PLL clock entry */
|
||||||
SystemCoreClock >>= tmp;
|
|
||||||
|
/* Get PREDIV1 clock source and division factor */
|
||||||
|
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
|
||||||
|
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||||
|
|
||||||
|
if (prediv1source == 0U) {
|
||||||
|
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||||
|
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||||
|
} else { /* PLL2 clock selected as PREDIV1 clock entry */
|
||||||
|
|
||||||
|
/* Get PREDIV2 division factor and PLL2 multiplication factor */
|
||||||
|
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
|
||||||
|
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
|
||||||
|
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* STM32F105xC */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SystemCoreClock = HSI_VALUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute HCLK clock frequency ----------------*/
|
||||||
|
/* Get HCLK prescaler */
|
||||||
|
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
|
||||||
|
/* HCLK clock frequency */
|
||||||
|
SystemCoreClock >>= tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||||
/**
|
/**
|
||||||
* @brief Setup the external memory controller. Called in startup_stm32f1xx.s
|
* @brief Setup the external memory controller. Called in startup_stm32f1xx.s
|
||||||
* before jump to __main
|
* before jump to __main
|
||||||
* @param None
|
* @param None
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
#ifdef DATA_IN_ExtSRAM
|
#ifdef DATA_IN_ExtSRAM
|
||||||
/**
|
/**
|
||||||
* @brief Setup the external memory controller.
|
* @brief Setup the external memory controller.
|
||||||
* Called in startup_stm32f1xx_xx.s/.c before jump to main.
|
* Called in startup_stm32f1xx_xx.s/.c before jump to main.
|
||||||
* This function configures the external SRAM mounted on STM3210E-EVAL
|
* This function configures the external SRAM mounted on STM3210E-EVAL
|
||||||
* board (STM32 High density devices). This SRAM will be used as program
|
* board (STM32 High density devices). This SRAM will be used as program
|
||||||
* data memory (including heap and stack).
|
* data memory (including heap and stack).
|
||||||
* @param None
|
* @param None
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void SystemInit_ExtMemCtl(void)
|
void SystemInit_ExtMemCtl(void) {
|
||||||
{
|
|
||||||
__IO uint32_t tmpreg;
|
__IO uint32_t tmpreg;
|
||||||
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
|
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
|
||||||
required, then adjust the Register Addresses */
|
required, then adjust the Register Addresses */
|
||||||
|
|
||||||
/* Enable FSMC clock */
|
/* Enable FSMC clock */
|
||||||
@@ -256,36 +247,36 @@ void SystemInit_ExtMemCtl(void)
|
|||||||
|
|
||||||
/* Delay after an RCC peripheral clock enabling */
|
/* Delay after an RCC peripheral clock enabling */
|
||||||
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
|
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
|
||||||
|
|
||||||
/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
|
/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
|
||||||
RCC->APB2ENR = 0x000001E0U;
|
RCC->APB2ENR = 0x000001E0U;
|
||||||
|
|
||||||
/* Delay after an RCC peripheral clock enabling */
|
/* Delay after an RCC peripheral clock enabling */
|
||||||
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
|
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
|
||||||
|
|
||||||
(void)(tmpreg);
|
(void)(tmpreg);
|
||||||
|
|
||||||
/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
|
/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
|
||||||
/*---------------- SRAM Address lines configuration -------------------------*/
|
/*---------------- SRAM Address lines configuration -------------------------*/
|
||||||
/*---------------- NOE and NWE configuration --------------------------------*/
|
/*---------------- NOE and NWE configuration --------------------------------*/
|
||||||
/*---------------- NE3 configuration ----------------------------------------*/
|
/*---------------- NE3 configuration ----------------------------------------*/
|
||||||
/*---------------- NBL0, NBL1 configuration ---------------------------------*/
|
/*---------------- NBL0, NBL1 configuration ---------------------------------*/
|
||||||
|
|
||||||
GPIOD->CRL = 0x44BB44BBU;
|
GPIOD->CRL = 0x44BB44BBU;
|
||||||
GPIOD->CRH = 0xBBBBBBBBU;
|
GPIOD->CRH = 0xBBBBBBBBU;
|
||||||
|
|
||||||
GPIOE->CRL = 0xB44444BBU;
|
GPIOE->CRL = 0xB44444BBU;
|
||||||
GPIOE->CRH = 0xBBBBBBBBU;
|
GPIOE->CRH = 0xBBBBBBBBU;
|
||||||
|
|
||||||
GPIOF->CRL = 0x44BBBBBBU;
|
GPIOF->CRL = 0x44BBBBBBU;
|
||||||
GPIOF->CRH = 0xBBBB4444U;
|
GPIOF->CRH = 0xBBBB4444U;
|
||||||
|
|
||||||
GPIOG->CRL = 0x44BBBBBBU;
|
GPIOG->CRL = 0x44BBBBBBU;
|
||||||
GPIOG->CRH = 0x444B4B44U;
|
GPIOG->CRH = 0x444B4B44U;
|
||||||
|
|
||||||
/*---------------- FSMC Configuration ---------------------------------------*/
|
/*---------------- FSMC Configuration ---------------------------------------*/
|
||||||
/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
|
/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
|
||||||
|
|
||||||
FSMC_Bank1->BTCR[4U] = 0x00001091U;
|
FSMC_Bank1->BTCR[4U] = 0x00001091U;
|
||||||
FSMC_Bank1->BTCR[5U] = 0x00110212U;
|
FSMC_Bank1->BTCR[5U] = 0x00110212U;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,56 +9,55 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
bool BMA223::detect() {
|
bool BMA223::detect() {
|
||||||
if (FRToSI2C::probe(BMA223_ADDRESS)) {
|
if (FRToSI2C::probe(BMA223_ADDRESS)) {
|
||||||
//Read chip id to ensure its not an address collision
|
// Read chip id to ensure its not an address collision
|
||||||
uint8_t id = 0;
|
uint8_t id = 0;
|
||||||
if (FRToSI2C::Mem_Read(BMA223_ADDRESS, BMA223_BGW_CHIPID, &id, 1)) {
|
if (FRToSI2C::Mem_Read(BMA223_ADDRESS, BMA223_BGW_CHIPID, &id, 1)) {
|
||||||
return id == 0b11111000;
|
return id == 0b11111000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const FRToSI2C::I2C_REG i2c_registers[] = { //
|
static const FRToSI2C::I2C_REG i2c_registers[] = {
|
||||||
//
|
//
|
||||||
{ BMA223_PMU_RANGE, 0b00000011, 0 }, //2G range
|
//
|
||||||
{ BMA223_PMU_BW, 0b00001101, 0 }, //250Hz filter
|
{BMA223_PMU_RANGE, 0b00000011, 0}, // 2G range
|
||||||
{ BMA223_PMU_LPW, 0b00000000, 0 }, //Full power
|
{BMA223_PMU_BW, 0b00001101, 0}, // 250Hz filter
|
||||||
{ BMA223_ACCD_HBW, 0b00000000, 0 }, //filtered data out
|
{BMA223_PMU_LPW, 0b00000000, 0}, // Full power
|
||||||
{ BMA223_INT_OUT_CTRL, 0b00001010, 0 }, //interrupt active low and OD to get it hi-z
|
{BMA223_ACCD_HBW, 0b00000000, 0}, // filtered data out
|
||||||
{ BMA223_INT_RST_LATCH, 0b10000000, 0 }, //interrupt active low and OD to get it hi-z
|
{BMA223_INT_OUT_CTRL, 0b00001010, 0}, // interrupt active low and OD to get it hi-z
|
||||||
{ BMA223_INT_EN_0, 0b01000000, 0 }, //Enable orientation
|
{BMA223_INT_RST_LATCH, 0b10000000, 0}, // interrupt active low and OD to get it hi-z
|
||||||
{ BMA223_INT_A, 0b00100111, 0 }, //Setup orientation detection
|
{BMA223_INT_EN_0, 0b01000000, 0}, // Enable orientation
|
||||||
|
{BMA223_INT_A, 0b00100111, 0}, // Setup orientation detection
|
||||||
|
|
||||||
//
|
//
|
||||||
};
|
};
|
||||||
bool BMA223::initalize() {
|
bool BMA223::initalize() {
|
||||||
//Setup acceleration readings
|
// Setup acceleration readings
|
||||||
//2G range
|
// 2G range
|
||||||
//bandwidth = 250Hz
|
// bandwidth = 250Hz
|
||||||
//High pass filter on (Slow compensation)
|
// High pass filter on (Slow compensation)
|
||||||
//Turn off IRQ output pins
|
// Turn off IRQ output pins
|
||||||
//Orientation recognition in symmetrical mode
|
// Orientation recognition in symmetrical mode
|
||||||
// Hysteresis is set to ~ 16 counts
|
// Hysteresis is set to ~ 16 counts
|
||||||
//Theta blocking is set to 0b10
|
// Theta blocking is set to 0b10
|
||||||
|
|
||||||
return FRToSI2C::writeRegistersBulk(BMA223_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
|
||||||
|
|
||||||
|
return FRToSI2C::writeRegistersBulk(BMA223_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BMA223::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
void BMA223::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
||||||
//The BMA is odd in that its output data width is only 8 bits
|
// The BMA is odd in that its output data width is only 8 bits
|
||||||
//And yet there are MSB and LSB registers _sigh_.
|
// And yet there are MSB and LSB registers _sigh_.
|
||||||
uint8_t sensorData[6] = { 0, 0, 0, 0, 0, 0 };
|
uint8_t sensorData[6] = {0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
if (FRToSI2C::Mem_Read(BMA223_ADDRESS, BMA223_ACCD_X_LSB, sensorData, 6) == false) {
|
|
||||||
x = y = z = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//Shift 6 to make its range ~= the other accelerometers
|
|
||||||
x = sensorData[1] << 6;
|
|
||||||
y = sensorData[3] << 6;
|
|
||||||
z = sensorData[5] << 6;
|
|
||||||
|
|
||||||
|
if (FRToSI2C::Mem_Read(BMA223_ADDRESS, BMA223_ACCD_X_LSB, sensorData, 6) == false) {
|
||||||
|
x = y = z = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Shift 6 to make its range ~= the other accelerometers
|
||||||
|
x = sensorData[1] << 6;
|
||||||
|
y = sensorData[3] << 6;
|
||||||
|
z = sensorData[5] << 6;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,112 +4,112 @@
|
|||||||
* Created on: 29 May 2020
|
* Created on: 29 May 2020
|
||||||
* Author: Ralim
|
* Author: Ralim
|
||||||
*/
|
*/
|
||||||
#include <Buttons.hpp>
|
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
|
||||||
#include "gui.hpp"
|
#include "gui.hpp"
|
||||||
|
#include "task.h"
|
||||||
|
#include <Buttons.hpp>
|
||||||
uint32_t lastButtonTime = 0;
|
uint32_t lastButtonTime = 0;
|
||||||
|
|
||||||
ButtonState getButtonState() {
|
ButtonState getButtonState() {
|
||||||
/*
|
/*
|
||||||
* Read in the buttons and then determine if a state change needs to occur
|
* 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
|
* If the previous state was 00 Then we want to latch the new state if
|
||||||
* different & update time
|
* different & update time
|
||||||
* If the previous state was !00 Then we want to search if we trigger long
|
* 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
|
* press (buttons still down), or if release we trigger press
|
||||||
* (downtime>filter)
|
* (downtime>filter)
|
||||||
*/
|
*/
|
||||||
static uint8_t previousState = 0;
|
static uint8_t previousState = 0;
|
||||||
static uint32_t previousStateChange = 0;
|
static uint32_t previousStateChange = 0;
|
||||||
const uint16_t timeout = 400;
|
const uint16_t timeout = 400;
|
||||||
uint8_t currentState;
|
uint8_t currentState;
|
||||||
currentState = (getButtonA()) << 0;
|
currentState = (getButtonA()) << 0;
|
||||||
currentState |= (getButtonB()) << 1;
|
currentState |= (getButtonB()) << 1;
|
||||||
|
|
||||||
if (currentState)
|
if (currentState)
|
||||||
lastButtonTime = xTaskGetTickCount();
|
lastButtonTime = xTaskGetTickCount();
|
||||||
if (currentState == previousState) {
|
if (currentState == previousState) {
|
||||||
if (currentState == 0)
|
if (currentState == 0)
|
||||||
return BUTTON_NONE;
|
return BUTTON_NONE;
|
||||||
if ((xTaskGetTickCount() - previousStateChange) > timeout) {
|
if ((xTaskGetTickCount() - previousStateChange) > timeout) {
|
||||||
// User has been holding the button down
|
// User has been holding the button down
|
||||||
// We want to send a button is held message
|
// We want to send a button is held message
|
||||||
if (currentState == 0x01)
|
if (currentState == 0x01)
|
||||||
return BUTTON_F_LONG;
|
return BUTTON_F_LONG;
|
||||||
else if (currentState == 0x02)
|
else if (currentState == 0x02)
|
||||||
return BUTTON_B_LONG;
|
return BUTTON_B_LONG;
|
||||||
else
|
else
|
||||||
return BUTTON_BOTH_LONG; // Both being held case
|
return BUTTON_BOTH_LONG; // Both being held case
|
||||||
} else
|
} else
|
||||||
return BUTTON_NONE;
|
return BUTTON_NONE;
|
||||||
} else {
|
} else {
|
||||||
// A change in button state has occurred
|
// A change in button state has occurred
|
||||||
ButtonState retVal = BUTTON_NONE;
|
ButtonState retVal = BUTTON_NONE;
|
||||||
if (currentState) {
|
if (currentState) {
|
||||||
// User has pressed a button down (nothing done on down)
|
// User has pressed a button down (nothing done on down)
|
||||||
if (currentState != previousState) {
|
if (currentState != previousState) {
|
||||||
// There has been a change in the button states
|
// There has been a change in the button states
|
||||||
// If there is a rising edge on one of the buttons from double press we
|
// 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
|
// want to mask that out As users are having issues with not release
|
||||||
// both at once
|
// both at once
|
||||||
if (previousState == 0x03)
|
if (previousState == 0x03)
|
||||||
currentState = 0x03;
|
currentState = 0x03;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// User has released buttons
|
// User has released buttons
|
||||||
// If they previously had the buttons down we want to check if they were <
|
// If they previously had the buttons down we want to check if they were <
|
||||||
// long hold and trigger a press
|
// long hold and trigger a press
|
||||||
if ((xTaskGetTickCount() - previousStateChange) < timeout) {
|
if ((xTaskGetTickCount() - previousStateChange) < timeout) {
|
||||||
// The user didn't hold the button for long
|
// The user didn't hold the button for long
|
||||||
// So we send button press
|
// So we send button press
|
||||||
|
|
||||||
if (previousState == 0x01)
|
if (previousState == 0x01)
|
||||||
retVal = BUTTON_F_SHORT;
|
retVal = BUTTON_F_SHORT;
|
||||||
else if (previousState == 0x02)
|
else if (previousState == 0x02)
|
||||||
retVal = BUTTON_B_SHORT;
|
retVal = BUTTON_B_SHORT;
|
||||||
else
|
else
|
||||||
retVal = BUTTON_BOTH; // Both being held case
|
retVal = BUTTON_BOTH; // Both being held case
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
previousState = currentState;
|
previousState = currentState;
|
||||||
previousStateChange = xTaskGetTickCount();
|
previousStateChange = xTaskGetTickCount();
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
return BUTTON_NONE;
|
return BUTTON_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void waitForButtonPress() {
|
void waitForButtonPress() {
|
||||||
// we are just lazy and sleep until user confirms button press
|
// we are just lazy and sleep until user confirms button press
|
||||||
// This also eats the button press event!
|
// This also eats the button press event!
|
||||||
ButtonState buttons = getButtonState();
|
ButtonState buttons = getButtonState();
|
||||||
while (buttons) {
|
while (buttons) {
|
||||||
buttons = getButtonState();
|
buttons = getButtonState();
|
||||||
GUIDelay();
|
GUIDelay();
|
||||||
}
|
}
|
||||||
while (!buttons) {
|
while (!buttons) {
|
||||||
buttons = getButtonState();
|
buttons = getButtonState();
|
||||||
GUIDelay();
|
GUIDelay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waitForButtonPressOrTimeout(uint32_t timeout) {
|
void waitForButtonPressOrTimeout(uint32_t timeout) {
|
||||||
timeout += xTaskGetTickCount();
|
timeout += xTaskGetTickCount();
|
||||||
// calculate the exit point
|
// calculate the exit point
|
||||||
|
|
||||||
ButtonState buttons = getButtonState();
|
ButtonState buttons = getButtonState();
|
||||||
while (buttons) {
|
while (buttons) {
|
||||||
buttons = getButtonState();
|
buttons = getButtonState();
|
||||||
GUIDelay();
|
GUIDelay();
|
||||||
if (xTaskGetTickCount() > timeout)
|
if (xTaskGetTickCount() > timeout)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (!buttons) {
|
while (!buttons) {
|
||||||
buttons = getButtonState();
|
buttons = getButtonState();
|
||||||
GUIDelay();
|
GUIDelay();
|
||||||
if (xTaskGetTickCount() > timeout)
|
if (xTaskGetTickCount() > timeout)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,23 +6,23 @@
|
|||||||
*/
|
*/
|
||||||
#include "Model_Config.h"
|
#include "Model_Config.h"
|
||||||
#ifdef POW_PD
|
#ifdef POW_PD
|
||||||
#include <fusbpd.h>
|
|
||||||
#include <pd.h>
|
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "I2CBB.hpp"
|
#include "I2CBB.hpp"
|
||||||
#include "fusb302b.h"
|
#include "fusb302b.h"
|
||||||
|
#include "int_n.h"
|
||||||
#include "policy_engine.h"
|
#include "policy_engine.h"
|
||||||
#include "protocol_rx.h"
|
#include "protocol_rx.h"
|
||||||
#include "protocol_tx.h"
|
#include "protocol_tx.h"
|
||||||
#include "int_n.h"
|
#include <fusbpd.h>
|
||||||
|
#include <pd.h>
|
||||||
|
|
||||||
void fusb302_start_processing() {
|
void fusb302_start_processing() {
|
||||||
/* Initialize the FUSB302B */
|
/* Initialize the FUSB302B */
|
||||||
if (fusb_setup()) {
|
if (fusb_setup()) {
|
||||||
PolicyEngine::init();
|
PolicyEngine::init();
|
||||||
ProtocolTransmit::init();
|
ProtocolTransmit::init();
|
||||||
ProtocolReceive::init();
|
ProtocolReceive::init();
|
||||||
InterruptHandler::init();
|
InterruptHandler::init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,65 +16,63 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "int_n.h"
|
#include "int_n.h"
|
||||||
#include "fusbpd.h"
|
#include "BSP.h"
|
||||||
#include <pd.h>
|
|
||||||
#include "fusb302b.h"
|
#include "fusb302b.h"
|
||||||
#include "protocol_rx.h"
|
#include "fusbpd.h"
|
||||||
#include "protocol_tx.h"
|
|
||||||
#include "policy_engine.h"
|
#include "policy_engine.h"
|
||||||
#include "protocol_rx.h"
|
#include "protocol_rx.h"
|
||||||
#include "protocol_tx.h"
|
#include "protocol_tx.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "BSP.h"
|
#include <pd.h>
|
||||||
|
|
||||||
osThreadId InterruptHandler::TaskHandle = NULL;
|
osThreadId InterruptHandler::TaskHandle = NULL;
|
||||||
uint32_t InterruptHandler::TaskBuffer[InterruptHandler::TaskStackSize];
|
uint32_t InterruptHandler::TaskBuffer[InterruptHandler::TaskStackSize];
|
||||||
osStaticThreadDef_t InterruptHandler::TaskControlBlock;
|
osStaticThreadDef_t InterruptHandler::TaskControlBlock;
|
||||||
|
|
||||||
void InterruptHandler::init() {
|
void InterruptHandler::init() {
|
||||||
osThreadStaticDef(intTask, Thread, PDB_PRIO_PRL_INT_N, 0, TaskStackSize, TaskBuffer, &TaskControlBlock);
|
osThreadStaticDef(intTask, Thread, PDB_PRIO_PRL_INT_N, 0, TaskStackSize, TaskBuffer, &TaskControlBlock);
|
||||||
TaskHandle = osThreadCreate(osThread(intTask), NULL);
|
TaskHandle = osThreadCreate(osThread(intTask), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterruptHandler::Thread(const void *arg) {
|
void InterruptHandler::Thread(const void *arg) {
|
||||||
(void) arg;
|
(void)arg;
|
||||||
union fusb_status status;
|
union fusb_status status;
|
||||||
while (true) {
|
while (true) {
|
||||||
/* If the INT_N line is low */
|
/* If the INT_N line is low */
|
||||||
if (xTaskNotifyWait(0x00, 0x0F, NULL, PolicyEngine::setupCompleteOrTimedOut() ? 1000 : 10) == pdPASS) {
|
if (xTaskNotifyWait(0x00, 0x0F, NULL, PolicyEngine::setupCompleteOrTimedOut() ? 1000 : 10) == pdPASS) {
|
||||||
//delay slightly so we catch the crc with better timing
|
// delay slightly so we catch the crc with better timing
|
||||||
osDelay(1);
|
osDelay(1);
|
||||||
}
|
}
|
||||||
/* Read the FUSB302B status and interrupt registers */
|
/* Read the FUSB302B status and interrupt registers */
|
||||||
fusb_get_status(&status);
|
fusb_get_status(&status);
|
||||||
/* If the I_TXSENT or I_RETRYFAIL flag is set, tell the Protocol TX
|
/* If the I_TXSENT or I_RETRYFAIL flag is set, tell the Protocol TX
|
||||||
* thread */
|
* thread */
|
||||||
if (status.interrupta & FUSB_INTERRUPTA_I_TXSENT) {
|
if (status.interrupta & FUSB_INTERRUPTA_I_TXSENT) {
|
||||||
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_TXSENT);
|
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_TXSENT);
|
||||||
}
|
}
|
||||||
if (status.interrupta & FUSB_INTERRUPTA_I_RETRYFAIL) {
|
if (status.interrupta & FUSB_INTERRUPTA_I_RETRYFAIL) {
|
||||||
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_RETRYFAIL);
|
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_I_RETRYFAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the I_GCRCSENT flag is set, tell the Protocol RX thread */
|
/* If the I_GCRCSENT flag is set, tell the Protocol RX thread */
|
||||||
//This means a message was recieved with a good CRC
|
// This means a message was recieved with a good CRC
|
||||||
if (status.interruptb & FUSB_INTERRUPTB_I_GCRCSENT) {
|
if (status.interruptb & FUSB_INTERRUPTB_I_GCRCSENT) {
|
||||||
ProtocolReceive::notify(PDB_EVT_PRLRX_I_GCRCSENT);
|
ProtocolReceive::notify(PDB_EVT_PRLRX_I_GCRCSENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the I_OCP_TEMP and OVRTEMP flags are set, tell the Policy
|
/* If the I_OCP_TEMP and OVRTEMP flags are set, tell the Policy
|
||||||
* Engine thread */
|
* Engine thread */
|
||||||
if ((status.interrupta & FUSB_INTERRUPTA_I_OCP_TEMP) && (status.status1 & FUSB_STATUS1_OVRTEMP)) {
|
if ((status.interrupta & FUSB_INTERRUPTA_I_OCP_TEMP) && (status.status1 & FUSB_STATUS1_OVRTEMP)) {
|
||||||
PolicyEngine::notify(PDB_EVT_PE_I_OVRTEMP);
|
PolicyEngine::notify(PDB_EVT_PE_I_OVRTEMP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void InterruptHandler::irqCallback() {
|
void InterruptHandler::irqCallback() {
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
if (TaskHandle != NULL) {
|
if (TaskHandle != NULL) {
|
||||||
BaseType_t taskWoke = pdFALSE;
|
BaseType_t taskWoke = pdFALSE;
|
||||||
xTaskNotifyFromISR(TaskHandle, 0x01, eNotifyAction::eSetBits, &taskWoke);
|
xTaskNotifyFromISR(TaskHandle, 0x01, eNotifyAction::eSetBits, &taskWoke);
|
||||||
portYIELD_FROM_ISR(taskWoke);
|
portYIELD_FROM_ISR(taskWoke);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,9 +4,9 @@
|
|||||||
* Created on: 14 Jun 2020
|
* Created on: 14 Jun 2020
|
||||||
* Author: Ralim
|
* Author: Ralim
|
||||||
*/
|
*/
|
||||||
|
#include "BSP_PD.h"
|
||||||
#include "pd.h"
|
#include "pd.h"
|
||||||
#include "policy_engine.h"
|
#include "policy_engine.h"
|
||||||
#include "BSP_PD.h"
|
|
||||||
/* The current draw when the output is disabled */
|
/* The current draw when the output is disabled */
|
||||||
#define DPM_MIN_CURRENT PD_MA2PDI(50)
|
#define DPM_MIN_CURRENT PD_MA2PDI(50)
|
||||||
/*
|
/*
|
||||||
@@ -16,212 +16,178 @@
|
|||||||
* If there is no such PDO, returns -1 instead.
|
* If there is no such PDO, returns -1 instead.
|
||||||
*/
|
*/
|
||||||
static int8_t dpm_get_range_fixed_pdo_index(const union pd_msg *caps) {
|
static int8_t dpm_get_range_fixed_pdo_index(const union pd_msg *caps) {
|
||||||
/* Get the number of PDOs */
|
/* Get the number of PDOs */
|
||||||
uint8_t numobj = PD_NUMOBJ_GET(caps);
|
uint8_t numobj = PD_NUMOBJ_GET(caps);
|
||||||
|
|
||||||
/* Get ready to iterate over the PDOs */
|
/* Get ready to iterate over the PDOs */
|
||||||
int8_t i;
|
int8_t i;
|
||||||
int8_t step;
|
int8_t step;
|
||||||
i = numobj - 1;
|
i = numobj - 1;
|
||||||
step = -1;
|
step = -1;
|
||||||
uint16_t current = 100; // in centiamps
|
uint16_t current = 100; // in centiamps
|
||||||
uint16_t voltagemin = 8000;
|
uint16_t voltagemin = 8000;
|
||||||
uint16_t voltagemax = 10000;
|
uint16_t voltagemax = 10000;
|
||||||
/* Look at the PDOs to see if one falls in our voltage range. */
|
/* Look at the PDOs to see if one falls in our voltage range. */
|
||||||
while (0 <= i && i < numobj) {
|
while (0 <= i && i < numobj) {
|
||||||
/* If we have a fixed PDO, its V is within our range, and its I is at
|
/* If we have a fixed PDO, its V is within our range, and its I is at
|
||||||
* least our desired I */
|
* least our desired I */
|
||||||
uint16_t v = PD_PDO_SRC_FIXED_VOLTAGE_GET(caps->obj[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 ((caps->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
|
||||||
if ( PD_PDO_SRC_FIXED_CURRENT_GET(caps->obj[i]) >= current) {
|
if (PD_PDO_SRC_FIXED_CURRENT_GET(caps->obj[i]) >= current) {
|
||||||
if (v >= PD_MV2PDV(voltagemin) && v <= PD_MV2PDV(voltagemax)) {
|
if (v >= PD_MV2PDV(voltagemin) && v <= PD_MV2PDV(voltagemax)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i += step;
|
i += step;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
bool PolicyEngine::pdbs_dpm_evaluate_capability(
|
bool PolicyEngine::pdbs_dpm_evaluate_capability(const union pd_msg *capabilities, union pd_msg *request) {
|
||||||
const union pd_msg *capabilities, union pd_msg *request) {
|
|
||||||
|
|
||||||
/* Get the number of PDOs */
|
/* Get the number of PDOs */
|
||||||
uint8_t numobj = PD_NUMOBJ_GET(capabilities);
|
uint8_t numobj = PD_NUMOBJ_GET(capabilities);
|
||||||
|
|
||||||
/* Get whether or not the power supply is constrained */
|
/* Get whether or not the power supply is constrained */
|
||||||
_unconstrained_power =
|
_unconstrained_power = capabilities->obj[0] & PD_PDO_SRC_FIXED_UNCONSTRAINED;
|
||||||
capabilities->obj[0] & PD_PDO_SRC_FIXED_UNCONSTRAINED;
|
|
||||||
|
|
||||||
/* Make sure we have configuration */
|
/* Make sure we have configuration */
|
||||||
/* Look at the PDOs to see if one matches our desires */
|
/* Look at the PDOs to see if one matches our desires */
|
||||||
//Look against USB_PD_Desired_Levels to select in order of preference
|
// Look against USB_PD_Desired_Levels to select in order of preference
|
||||||
for (uint8_t desiredLevel = 0; desiredLevel < USB_PD_Desired_Levels_Len;
|
for (uint8_t desiredLevel = 0; desiredLevel < USB_PD_Desired_Levels_Len; desiredLevel++) {
|
||||||
desiredLevel++) {
|
for (uint8_t i = 0; i < numobj; i++) {
|
||||||
for (uint8_t i = 0; i < numobj; i++) {
|
/* If we have a fixed PDO, its V equals our desired V, and its I is
|
||||||
/* If we have a fixed PDO, its V equals our desired V, and its I is
|
* at least our desired I */
|
||||||
* at least our desired I */
|
if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
|
||||||
if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
|
// This is a fixed PDO entry
|
||||||
//This is a fixed PDO entry
|
int voltage = PD_PDV2MV(PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities->obj[i]));
|
||||||
int voltage = PD_PDV2MV(
|
int current = PD_PDO_SRC_FIXED_CURRENT_GET(capabilities->obj[i]);
|
||||||
PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities->obj[i]));
|
uint16_t desiredVoltage = USB_PD_Desired_Levels[(desiredLevel * 2) + 0];
|
||||||
int current = PD_PDO_SRC_FIXED_CURRENT_GET(
|
uint16_t desiredminCurrent = USB_PD_Desired_Levels[(desiredLevel * 2) + 1];
|
||||||
capabilities->obj[i]);
|
// As pd stores current in 10mA increments, divide by 10
|
||||||
uint16_t desiredVoltage = USB_PD_Desired_Levels[(desiredLevel
|
desiredminCurrent /= 10;
|
||||||
* 2) + 0];
|
if (voltage == desiredVoltage) {
|
||||||
uint16_t desiredminCurrent = USB_PD_Desired_Levels[(desiredLevel
|
if (current >= desiredminCurrent) {
|
||||||
* 2) + 1];
|
/* We got what we wanted, so build a request for that */
|
||||||
//As pd stores current in 10mA increments, divide by 10
|
request->hdr = hdr_template | PD_MSGTYPE_REQUEST | PD_NUMOBJ(1);
|
||||||
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 */
|
/* GiveBack disabled */
|
||||||
request->obj[0] =
|
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);
|
||||||
PD_RDO_FV_MAX_CURRENT_SET(
|
// We support usb comms (ish)
|
||||||
current) | PD_RDO_FV_CURRENT_SET(current)
|
request->obj[0] |= PD_RDO_USB_COMMS;
|
||||||
| 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 */
|
/* Update requested voltage */
|
||||||
_requested_voltage = voltage;
|
_requested_voltage = voltage;
|
||||||
|
|
||||||
return true;
|
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;
|
||||||
|
|
||||||
/* Nothing matched (or no configuration), so get 5 V at low current */
|
/* Update requested voltage */
|
||||||
request->hdr = hdr_template | PD_MSGTYPE_REQUEST | PD_NUMOBJ(1);
|
_requested_voltage = 5000;
|
||||||
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 */
|
return false;
|
||||||
_requested_voltage = 5000;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolicyEngine::pdbs_dpm_get_sink_capability(union pd_msg *cap) {
|
void PolicyEngine::pdbs_dpm_get_sink_capability(union pd_msg *cap) {
|
||||||
/* Keep track of how many PDOs we've added */
|
/* Keep track of how many PDOs we've added */
|
||||||
int numobj = 0;
|
int numobj = 0;
|
||||||
|
|
||||||
/* If we have no configuration or want something other than 5 V, add a PDO
|
/* If we have no configuration or want something other than 5 V, add a PDO
|
||||||
* for vSafe5V */
|
* for vSafe5V */
|
||||||
/* Minimum current, 5 V, and higher capability. */
|
/* Minimum current, 5 V, and higher capability. */
|
||||||
cap->obj[numobj++] =
|
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);
|
||||||
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 */
|
/* Get the current we want */
|
||||||
uint16_t current = USB_PD_Desired_Levels[1] / 10; // In centi-amps
|
uint16_t current = USB_PD_Desired_Levels[1] / 10; // In centi-amps
|
||||||
uint16_t voltage = USB_PD_Desired_Levels[0]; // in mv
|
uint16_t voltage = USB_PD_Desired_Levels[0]; // in mv
|
||||||
/* Add a PDO for the desired power. */
|
/* Add a PDO for the desired power. */
|
||||||
cap->obj[numobj++] = PD_PDO_TYPE_FIXED
|
cap->obj[numobj++] = PD_PDO_TYPE_FIXED | PD_PDO_SNK_FIXED_VOLTAGE_SET(PD_MV2PDV(voltage)) | PD_PDO_SNK_FIXED_CURRENT_SET(current);
|
||||||
| PD_PDO_SNK_FIXED_VOLTAGE_SET(
|
|
||||||
PD_MV2PDV(voltage)) | PD_PDO_SNK_FIXED_CURRENT_SET(current);
|
|
||||||
|
|
||||||
/* Get the PDO from the voltage range */
|
/* Get the PDO from the voltage range */
|
||||||
int8_t i = dpm_get_range_fixed_pdo_index(cap);
|
int8_t i = dpm_get_range_fixed_pdo_index(cap);
|
||||||
|
|
||||||
/* If it's vSafe5V, set our vSafe5V's current to what we want */
|
/* If it's vSafe5V, set our vSafe5V's current to what we want */
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
cap->obj[0] &= ~PD_PDO_SNK_FIXED_CURRENT;
|
cap->obj[0] &= ~PD_PDO_SNK_FIXED_CURRENT;
|
||||||
cap->obj[0] |= PD_PDO_SNK_FIXED_CURRENT_SET(current);
|
cap->obj[0] |= PD_PDO_SNK_FIXED_CURRENT_SET(current);
|
||||||
} else {
|
} else {
|
||||||
/* If we want more than 5 V, set the Higher Capability flag */
|
/* If we want more than 5 V, set the Higher Capability flag */
|
||||||
if (PD_MV2PDV(voltage) != PD_MV2PDV(5000)) {
|
if (PD_MV2PDV(voltage) != PD_MV2PDV(5000)) {
|
||||||
cap->obj[0] |= PD_PDO_SNK_FIXED_HIGHER_CAP;
|
cap->obj[0] |= PD_PDO_SNK_FIXED_HIGHER_CAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the range PDO is a different voltage than the preferred
|
/* If the range PDO is a different voltage than the preferred
|
||||||
* voltage, add it to the array. */
|
* voltage, add it to the array. */
|
||||||
if (i
|
if (i > 0 && PD_PDO_SRC_FIXED_VOLTAGE_GET(cap->obj[i]) != PD_MV2PDV(voltage)) {
|
||||||
> 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]));
|
||||||
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
|
/* If we have three PDOs at this point, make sure the last two are
|
||||||
* sorted by voltage. */
|
* sorted by voltage. */
|
||||||
if (numobj == 3
|
if (numobj == 3 && (cap->obj[1] & PD_PDO_SNK_FIXED_VOLTAGE) > (cap->obj[2] & PD_PDO_SNK_FIXED_VOLTAGE)) {
|
||||||
&& (cap->obj[1] & PD_PDO_SNK_FIXED_VOLTAGE)
|
cap->obj[1] ^= cap->obj[2];
|
||||||
> (cap->obj[2] & PD_PDO_SNK_FIXED_VOLTAGE)) {
|
cap->obj[2] ^= cap->obj[1];
|
||||||
cap->obj[1] ^= cap->obj[2];
|
cap->obj[1] ^= cap->obj[2];
|
||||||
cap->obj[2] ^= cap->obj[1];
|
}
|
||||||
cap->obj[1] ^= cap->obj[2];
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the unconstrained power flag. */
|
/* Set the unconstrained power flag. */
|
||||||
if (_unconstrained_power) {
|
if (_unconstrained_power) {
|
||||||
cap->obj[0] |= PD_PDO_SNK_FIXED_UNCONSTRAINED;
|
cap->obj[0] |= PD_PDO_SNK_FIXED_UNCONSTRAINED;
|
||||||
}
|
}
|
||||||
/* Set the USB communications capable flag. */
|
/* Set the USB communications capable flag. */
|
||||||
cap->obj[0] |= PD_PDO_SNK_FIXED_USB_COMMS;
|
cap->obj[0] |= PD_PDO_SNK_FIXED_USB_COMMS;
|
||||||
|
|
||||||
/* Set the Sink_Capabilities message header */
|
/* Set the Sink_Capabilities message header */
|
||||||
cap->hdr = hdr_template | PD_MSGTYPE_SINK_CAPABILITIES | PD_NUMOBJ(numobj);
|
cap->hdr = hdr_template | PD_MSGTYPE_SINK_CAPABILITIES | PD_NUMOBJ(numobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PolicyEngine::pdbs_dpm_evaluate_typec_current(
|
bool PolicyEngine::pdbs_dpm_evaluate_typec_current(enum fusb_typec_current tcc) {
|
||||||
enum fusb_typec_current tcc) {
|
(void)tcc;
|
||||||
(void) tcc;
|
// This is for evaluating 5V static current advertised by resistors
|
||||||
//This is for evaluating 5V static current advertised by resistors
|
/* We don't control the voltage anymore; it will always be 5 V. */
|
||||||
/* We don't control the voltage anymore; it will always be 5 V. */
|
current_voltage_mv = _requested_voltage = 5000;
|
||||||
current_voltage_mv = _requested_voltage = 5000;
|
// For the soldering iron we accept this as a fallback, but it sucks
|
||||||
//For the soldering iron we accept this as a fallback, but it sucks
|
pdNegotiationComplete = false;
|
||||||
pdNegotiationComplete = false;
|
return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolicyEngine::pdbs_dpm_transition_default() {
|
void PolicyEngine::pdbs_dpm_transition_default() {
|
||||||
/* Cast the dpm_data to the right type */
|
/* Cast the dpm_data to the right type */
|
||||||
|
|
||||||
/* Pretend we requested 5 V */
|
/* Pretend we requested 5 V */
|
||||||
current_voltage_mv = 5000;
|
current_voltage_mv = 5000;
|
||||||
/* Turn the output off */
|
/* Turn the output off */
|
||||||
pdNegotiationComplete = false;
|
pdNegotiationComplete = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolicyEngine::pdbs_dpm_transition_requested() {
|
void PolicyEngine::pdbs_dpm_transition_requested() {
|
||||||
/* Cast the dpm_data to the right type */
|
/* Cast the dpm_data to the right type */
|
||||||
pdNegotiationComplete = true;
|
pdNegotiationComplete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolicyEngine::handleMessage(union pd_msg *msg) {
|
void PolicyEngine::handleMessage(union pd_msg *msg) { xQueueSend(messagesWaiting, msg, 100); }
|
||||||
xQueueSend(messagesWaiting, msg, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PolicyEngine::messageWaiting() {
|
bool PolicyEngine::messageWaiting() { return uxQueueMessagesWaiting(messagesWaiting) > 0; }
|
||||||
return uxQueueMessagesWaiting(messagesWaiting) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PolicyEngine::readMessage() {
|
bool PolicyEngine::readMessage() { return xQueueReceive(messagesWaiting, &tempMessage, 0) == pdTRUE; }
|
||||||
return xQueueReceive(messagesWaiting, &tempMessage, 0) == pdTRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PolicyEngine::pdbs_dpm_transition_typec() {
|
void PolicyEngine::pdbs_dpm_transition_typec() {
|
||||||
//This means PD failed, so we either have a dump 5V only type C or a QC charger
|
// 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
|
// For now; treat this as failed neg
|
||||||
pdNegotiationComplete = false;
|
pdNegotiationComplete = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,173 +17,167 @@
|
|||||||
|
|
||||||
#include "protocol_rx.h"
|
#include "protocol_rx.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include "fusb302b.h"
|
||||||
#include "string.h"
|
|
||||||
#include <pd.h>
|
|
||||||
#include "policy_engine.h"
|
#include "policy_engine.h"
|
||||||
#include "protocol_tx.h"
|
#include "protocol_tx.h"
|
||||||
#include "fusb302b.h"
|
#include "string.h"
|
||||||
osThreadId ProtocolReceive::TaskHandle = NULL;
|
#include <pd.h>
|
||||||
EventGroupHandle_t ProtocolReceive::xEventGroupHandle = NULL;
|
#include <stdlib.h>
|
||||||
StaticEventGroup_t ProtocolReceive::xCreatedEventGroup;
|
osThreadId ProtocolReceive::TaskHandle = NULL;
|
||||||
uint32_t ProtocolReceive::TaskBuffer[ProtocolReceive::TaskStackSize];
|
EventGroupHandle_t ProtocolReceive::xEventGroupHandle = NULL;
|
||||||
|
StaticEventGroup_t ProtocolReceive::xCreatedEventGroup;
|
||||||
|
uint32_t ProtocolReceive::TaskBuffer[ProtocolReceive::TaskStackSize];
|
||||||
osStaticThreadDef_t ProtocolReceive::TaskControlBlock;
|
osStaticThreadDef_t ProtocolReceive::TaskControlBlock;
|
||||||
union pd_msg ProtocolReceive::tempMessage;
|
union pd_msg ProtocolReceive::tempMessage;
|
||||||
uint8_t ProtocolReceive::_rx_messageid;
|
uint8_t ProtocolReceive::_rx_messageid;
|
||||||
uint8_t ProtocolReceive::_tx_messageidcounter;
|
uint8_t ProtocolReceive::_tx_messageidcounter;
|
||||||
/*
|
/*
|
||||||
* PRL_Rx_Wait_for_PHY_Message state
|
* PRL_Rx_Wait_for_PHY_Message state
|
||||||
*/
|
*/
|
||||||
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_wait_phy() {
|
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_wait_phy() {
|
||||||
/* Wait for an event */
|
/* Wait for an event */
|
||||||
_rx_messageid = 0;
|
_rx_messageid = 0;
|
||||||
eventmask_t evt = waitForEvent(
|
eventmask_t evt = waitForEvent(PDB_EVT_PRLRX_RESET | PDB_EVT_PRLRX_I_GCRCSENT | PDB_EVT_PRLRX_I_RXPEND);
|
||||||
PDB_EVT_PRLRX_RESET | PDB_EVT_PRLRX_I_GCRCSENT | PDB_EVT_PRLRX_I_RXPEND);
|
|
||||||
|
|
||||||
/* If we got a reset event, reset */
|
/* If we got a reset event, reset */
|
||||||
if (evt & PDB_EVT_PRLRX_RESET) {
|
if (evt & PDB_EVT_PRLRX_RESET) {
|
||||||
waitForEvent(PDB_EVT_PRLRX_RESET, 0);
|
waitForEvent(PDB_EVT_PRLRX_RESET, 0);
|
||||||
return PRLRxWaitPHY;
|
return PRLRxWaitPHY;
|
||||||
}
|
}
|
||||||
/* If we got an I_GCRCSENT event, read the message and decide what to do */
|
/* If we got an I_GCRCSENT event, read the message and decide what to do */
|
||||||
if (evt & PDB_EVT_PRLRX_I_GCRCSENT) {
|
if (evt & PDB_EVT_PRLRX_I_GCRCSENT) {
|
||||||
/* Get a buffer to read the message into. Guaranteed to not fail
|
/* Get a buffer to read the message into. Guaranteed to not fail
|
||||||
* because we have a big enough pool and are careful. */
|
* because we have a big enough pool and are careful. */
|
||||||
union pd_msg *_rx_message = &tempMessage;
|
union pd_msg *_rx_message = &tempMessage;
|
||||||
memset(&tempMessage, 0, sizeof(tempMessage));
|
memset(&tempMessage, 0, sizeof(tempMessage));
|
||||||
/* Read the message */
|
/* Read the message */
|
||||||
fusb_read_message(_rx_message);
|
fusb_read_message(_rx_message);
|
||||||
/* If it's a Soft_Reset, go to the soft reset state */
|
/* If it's a Soft_Reset, go to the soft reset state */
|
||||||
if (PD_MSGTYPE_GET(_rx_message) == PD_MSGTYPE_SOFT_RESET
|
if (PD_MSGTYPE_GET(_rx_message) == PD_MSGTYPE_SOFT_RESET && PD_NUMOBJ_GET(_rx_message) == 0) {
|
||||||
&& PD_NUMOBJ_GET(_rx_message) == 0) {
|
return PRLRxReset;
|
||||||
return PRLRxReset;
|
} else {
|
||||||
} else {
|
/* Otherwise, check the message ID */
|
||||||
/* Otherwise, check the message ID */
|
return PRLRxCheckMessageID;
|
||||||
return PRLRxCheckMessageID;
|
}
|
||||||
}
|
} else if (evt & PDB_EVT_PRLRX_I_RXPEND) {
|
||||||
} else if (evt & PDB_EVT_PRLRX_I_RXPEND) {
|
// There is an RX message pending that is not a Good CRC
|
||||||
//There is an RX message pending that is not a Good CRC
|
union pd_msg *_rx_message = &tempMessage;
|
||||||
union pd_msg *_rx_message = &tempMessage;
|
/* Read the message */
|
||||||
/* Read the message */
|
fusb_read_message(_rx_message);
|
||||||
fusb_read_message(_rx_message);
|
return PRLRxWaitPHY;
|
||||||
return PRLRxWaitPHY;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return PRLRxWaitPHY;
|
return PRLRxWaitPHY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PRL_Rx_Layer_Reset_for_Receive state
|
* PRL_Rx_Layer_Reset_for_Receive state
|
||||||
*/
|
*/
|
||||||
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_reset() {
|
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_reset() {
|
||||||
/* Reset MessageIDCounter */
|
/* Reset MessageIDCounter */
|
||||||
_tx_messageidcounter = 0;
|
_tx_messageidcounter = 0;
|
||||||
|
|
||||||
/* Clear stored MessageID */
|
/* Clear stored MessageID */
|
||||||
_rx_messageid = -1;
|
_rx_messageid = -1;
|
||||||
|
|
||||||
/* TX transitions to its reset state */
|
/* TX transitions to its reset state */
|
||||||
ProtocolTransmit::notify(
|
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_RESET);
|
||||||
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_RESET);
|
taskYIELD();
|
||||||
taskYIELD();
|
|
||||||
|
|
||||||
/* If we got a RESET signal, reset the machine */
|
/* If we got a RESET signal, reset the machine */
|
||||||
if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) != 0) {
|
if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) != 0) {
|
||||||
return PRLRxWaitPHY;
|
return PRLRxWaitPHY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go to the Check_MessageID state */
|
/* Go to the Check_MessageID state */
|
||||||
return PRLRxCheckMessageID;
|
return PRLRxCheckMessageID;
|
||||||
}
|
}
|
||||||
volatile uint32_t rxCounter = 0;
|
volatile uint32_t rxCounter = 0;
|
||||||
/*
|
/*
|
||||||
* PRL_Rx_Check_MessageID state
|
* PRL_Rx_Check_MessageID state
|
||||||
*/
|
*/
|
||||||
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_check_messageid() {
|
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_check_messageid() {
|
||||||
/* If we got a RESET signal, reset the machine */
|
/* If we got a RESET signal, reset the machine */
|
||||||
// if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) == PDB_EVT_PRLRX_RESET) {
|
// if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) == PDB_EVT_PRLRX_RESET) {
|
||||||
// return PRLRxWaitPHY;
|
// return PRLRxWaitPHY;
|
||||||
// }
|
// }
|
||||||
/* If the message has the stored ID, we've seen this message before. Free
|
/* If the message has the stored ID, we've seen this message before. Free
|
||||||
* it and don't pass it to the policy engine. */
|
* it and don't pass it to the policy engine. */
|
||||||
|
|
||||||
/* Otherwise, there's either no stored ID or this message has an ID we
|
/* Otherwise, there's either no stored ID or this message has an ID we
|
||||||
* haven't just seen. Transition to the Store_MessageID state. */
|
* haven't just seen. Transition to the Store_MessageID state. */
|
||||||
// if (PD_MESSAGEID_GET(&tempMessage) == _rx_messageid) {
|
// if (PD_MESSAGEID_GET(&tempMessage) == _rx_messageid) {
|
||||||
// return PRLRxWaitPHY;
|
// return PRLRxWaitPHY;
|
||||||
// } else
|
// } else
|
||||||
{
|
{
|
||||||
rxCounter++;
|
rxCounter++;
|
||||||
return PRLRxStoreMessageID;
|
return PRLRxStoreMessageID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PRL_Rx_Store_MessageID state
|
* PRL_Rx_Store_MessageID state
|
||||||
*/
|
*/
|
||||||
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_store_messageid() {
|
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_store_messageid() {
|
||||||
/* Tell ProtocolTX to discard the message being transmitted */
|
/* Tell ProtocolTX to discard the message being transmitted */
|
||||||
|
|
||||||
ProtocolTransmit::notify(
|
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_DISCARD);
|
||||||
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_DISCARD);
|
|
||||||
|
|
||||||
/* Update the stored MessageID */
|
/* Update the stored MessageID */
|
||||||
_rx_messageid = PD_MESSAGEID_GET(&tempMessage);
|
_rx_messageid = PD_MESSAGEID_GET(&tempMessage);
|
||||||
|
|
||||||
/* Pass the message to the policy engine. */
|
/* Pass the message to the policy engine. */
|
||||||
|
|
||||||
PolicyEngine::handleMessage(&tempMessage);
|
PolicyEngine::handleMessage(&tempMessage);
|
||||||
PolicyEngine::notify(PDB_EVT_PE_MSG_RX);
|
PolicyEngine::notify(PDB_EVT_PE_MSG_RX);
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
/* Don't check if we got a RESET because we'd do nothing different. */
|
/* Don't check if we got a RESET because we'd do nothing different. */
|
||||||
|
|
||||||
return PRLRxWaitPHY;
|
return PRLRxWaitPHY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolReceive::init() {
|
void ProtocolReceive::init() {
|
||||||
osThreadStaticDef(protRX, thread, PDB_PRIO_PRL, 0, TaskStackSize,
|
osThreadStaticDef(protRX, thread, PDB_PRIO_PRL, 0, TaskStackSize, TaskBuffer, &TaskControlBlock);
|
||||||
TaskBuffer, &TaskControlBlock);
|
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
|
||||||
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
|
TaskHandle = osThreadCreate(osThread(protRX), NULL);
|
||||||
TaskHandle = osThreadCreate(osThread(protRX), NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolReceive::thread(const void *args) {
|
void ProtocolReceive::thread(const void *args) {
|
||||||
(void) args;
|
(void)args;
|
||||||
ProtocolReceive::protocol_rx_state state = PRLRxWaitPHY;
|
ProtocolReceive::protocol_rx_state state = PRLRxWaitPHY;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PRLRxWaitPHY:
|
case PRLRxWaitPHY:
|
||||||
state = protocol_rx_wait_phy();
|
state = protocol_rx_wait_phy();
|
||||||
break;
|
break;
|
||||||
case PRLRxReset:
|
case PRLRxReset:
|
||||||
state = protocol_rx_reset();
|
state = protocol_rx_reset();
|
||||||
break;
|
break;
|
||||||
case PRLRxCheckMessageID:
|
case PRLRxCheckMessageID:
|
||||||
state = protocol_rx_check_messageid();
|
state = protocol_rx_check_messageid();
|
||||||
break;
|
break;
|
||||||
case PRLRxStoreMessageID:
|
case PRLRxStoreMessageID:
|
||||||
state = protocol_rx_store_messageid();
|
state = protocol_rx_store_messageid();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* This is an error. It really shouldn't happen. We might
|
/* This is an error. It really shouldn't happen. We might
|
||||||
* want to handle it anyway, though. */
|
* want to handle it anyway, though. */
|
||||||
state = PRLRxWaitPHY;
|
state = PRLRxWaitPHY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolReceive::notify(uint32_t notification) {
|
void ProtocolReceive::notify(uint32_t notification) {
|
||||||
if (xEventGroupHandle != NULL) {
|
if (xEventGroupHandle != NULL) {
|
||||||
xEventGroupSetBits(xEventGroupHandle, notification);
|
xEventGroupSetBits(xEventGroupHandle, notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ProtocolReceive::waitForEvent(uint32_t mask, TickType_t ticksToWait) {
|
uint32_t ProtocolReceive::waitForEvent(uint32_t mask, TickType_t ticksToWait) {
|
||||||
if (xEventGroupHandle != NULL) {
|
if (xEventGroupHandle != NULL) {
|
||||||
return xEventGroupWaitBits(xEventGroupHandle, mask, mask,
|
return xEventGroupWaitBits(xEventGroupHandle, mask, mask, pdFALSE, ticksToWait);
|
||||||
pdFALSE, ticksToWait);
|
}
|
||||||
}
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,283 +16,268 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "protocol_tx.h"
|
#include "protocol_tx.h"
|
||||||
#include <pd.h>
|
|
||||||
#include "policy_engine.h"
|
|
||||||
#include "protocol_rx.h"
|
|
||||||
#include "fusb302b.h"
|
#include "fusb302b.h"
|
||||||
#include "fusbpd.h"
|
#include "fusbpd.h"
|
||||||
|
#include "policy_engine.h"
|
||||||
|
#include "protocol_rx.h"
|
||||||
|
#include <pd.h>
|
||||||
|
|
||||||
osThreadId ProtocolTransmit::TaskHandle = NULL;
|
osThreadId ProtocolTransmit::TaskHandle = NULL;
|
||||||
uint32_t ProtocolTransmit::TaskBuffer[ProtocolTransmit::TaskStackSize];
|
uint32_t ProtocolTransmit::TaskBuffer[ProtocolTransmit::TaskStackSize];
|
||||||
osStaticThreadDef_t ProtocolTransmit::TaskControlBlock;
|
osStaticThreadDef_t ProtocolTransmit::TaskControlBlock;
|
||||||
StaticQueue_t ProtocolTransmit::xStaticQueue;
|
StaticQueue_t ProtocolTransmit::xStaticQueue;
|
||||||
bool ProtocolTransmit::messageSending = false;
|
bool ProtocolTransmit::messageSending = false;
|
||||||
uint8_t ProtocolTransmit::ucQueueStorageArea[PDB_MSG_POOL_SIZE
|
uint8_t ProtocolTransmit::ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)];
|
||||||
* sizeof(union pd_msg)];
|
QueueHandle_t ProtocolTransmit::messagesWaiting = NULL;
|
||||||
QueueHandle_t ProtocolTransmit::messagesWaiting = NULL;
|
uint8_t ProtocolTransmit::_tx_messageidcounter;
|
||||||
uint8_t ProtocolTransmit::_tx_messageidcounter;
|
union pd_msg ProtocolTransmit::temp_msg;
|
||||||
union pd_msg ProtocolTransmit::temp_msg;
|
EventGroupHandle_t ProtocolTransmit::xEventGroupHandle = NULL;
|
||||||
EventGroupHandle_t ProtocolTransmit::xEventGroupHandle = NULL;
|
StaticEventGroup_t ProtocolTransmit::xCreatedEventGroup;
|
||||||
StaticEventGroup_t ProtocolTransmit::xCreatedEventGroup;
|
|
||||||
/*
|
/*
|
||||||
* PRL_Tx_PHY_Layer_Reset state
|
* PRL_Tx_PHY_Layer_Reset state
|
||||||
*/
|
*/
|
||||||
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_phy_reset() {
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_phy_reset() {
|
||||||
/* Reset the PHY */
|
/* Reset the PHY */
|
||||||
fusb_reset();
|
fusb_reset();
|
||||||
|
|
||||||
/* If a message was pending when we got here, tell the policy engine that
|
/* If a message was pending when we got here, tell the policy engine that
|
||||||
* we failed to send it */
|
* we failed to send it */
|
||||||
if (messagePending()) {
|
if (messagePending()) {
|
||||||
/* Tell the policy engine that we failed */
|
/* Tell the policy engine that we failed */
|
||||||
PolicyEngine::notify( PDB_EVT_PE_TX_ERR);
|
PolicyEngine::notify(PDB_EVT_PE_TX_ERR);
|
||||||
/* Finish failing to send the message */
|
/* Finish failing to send the message */
|
||||||
while (messagePending()) {
|
while (messagePending()) {
|
||||||
getMessage(); //Discard
|
getMessage(); // Discard
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for a message request */
|
/* Wait for a message request */
|
||||||
return PRLTxWaitMessage;
|
return PRLTxWaitMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PRL_Tx_Wait_for_Message_Request state
|
* PRL_Tx_Wait_for_Message_Request state
|
||||||
*/
|
*/
|
||||||
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_message() {
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_message() {
|
||||||
/* Wait for an event */
|
/* Wait for an event */
|
||||||
ProtocolTransmit::Notifications evt = waitForEvent(
|
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);
|
||||||
(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) {
|
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_RESET) {
|
||||||
return PRLTxPHYReset;
|
return PRLTxPHYReset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the policy engine is trying to send a message */
|
/* If the policy engine is trying to send a message */
|
||||||
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_MSG_TX) {
|
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_MSG_TX) {
|
||||||
/* Get the message */
|
/* Get the message */
|
||||||
getMessage();
|
getMessage();
|
||||||
|
|
||||||
/* If it's a Soft_Reset, reset the TX layer first */
|
/* If it's a Soft_Reset, reset the TX layer first */
|
||||||
if (PD_MSGTYPE_GET(&temp_msg) == PD_MSGTYPE_SOFT_RESET
|
if (PD_MSGTYPE_GET(&temp_msg) == PD_MSGTYPE_SOFT_RESET && PD_NUMOBJ_GET(&(temp_msg)) == 0) {
|
||||||
&& PD_NUMOBJ_GET(&(temp_msg)) == 0) {
|
return PRLTxReset;
|
||||||
return PRLTxReset;
|
/* Otherwise, just send the message */
|
||||||
/* Otherwise, just send the message */
|
} else {
|
||||||
} else {
|
return PRLTxConstructMessage;
|
||||||
return PRLTxConstructMessage;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Silence the compiler warning */
|
/* Silence the compiler warning */
|
||||||
return PRLTxWaitMessage;
|
return PRLTxWaitMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_reset() {
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_reset() {
|
||||||
/* Clear MessageIDCounter */
|
/* Clear MessageIDCounter */
|
||||||
_tx_messageidcounter = 0;
|
_tx_messageidcounter = 0;
|
||||||
|
|
||||||
/* Tell the Protocol RX thread to reset */
|
/* Tell the Protocol RX thread to reset */
|
||||||
ProtocolReceive::notify( PDB_EVT_PRLRX_RESET);
|
ProtocolReceive::notify(PDB_EVT_PRLRX_RESET);
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
|
|
||||||
return PRLTxConstructMessage;
|
return PRLTxConstructMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PRL_Tx_Construct_Message state
|
* PRL_Tx_Construct_Message state
|
||||||
*/
|
*/
|
||||||
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_construct_message() {
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_construct_message() {
|
||||||
/* Set the correct MessageID in the message */
|
/* Set the correct MessageID in the message */
|
||||||
temp_msg.hdr &= ~PD_HDR_MESSAGEID;
|
temp_msg.hdr &= ~PD_HDR_MESSAGEID;
|
||||||
temp_msg.hdr |= (_tx_messageidcounter % 8) << PD_HDR_MESSAGEID_SHIFT;
|
temp_msg.hdr |= (_tx_messageidcounter % 8) << PD_HDR_MESSAGEID_SHIFT;
|
||||||
|
|
||||||
/* PD 3.0 collision avoidance */
|
/* PD 3.0 collision avoidance */
|
||||||
// if (PolicyEngine::isPD3_0()) {
|
// if (PolicyEngine::isPD3_0()) {
|
||||||
// /* If we're starting an AMS, wait for permission to transmit */
|
// /* If we're starting an AMS, wait for permission to transmit */
|
||||||
// evt = waitForEvent((uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS,
|
// evt = waitForEvent((uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS,
|
||||||
// 0);
|
// 0);
|
||||||
// if ((uint32_t) evt
|
// if ((uint32_t) evt
|
||||||
// & (uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS) {
|
// & (uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS) {
|
||||||
// while (fusb_get_typec_current() != fusb_sink_tx_ok) {
|
// while (fusb_get_typec_current() != fusb_sink_tx_ok) {
|
||||||
// osDelay(1);
|
// osDelay(1);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
messageSending = true;
|
messageSending = true;
|
||||||
/* Send the message to the PHY */
|
/* Send the message to the PHY */
|
||||||
fusb_send_message(&temp_msg);
|
fusb_send_message(&temp_msg);
|
||||||
|
|
||||||
return PRLTxWaitResponse;
|
return PRLTxWaitResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PRL_Tx_Wait_for_PHY_Response state
|
* PRL_Tx_Wait_for_PHY_Response state
|
||||||
*/
|
*/
|
||||||
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_response() {
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_response() {
|
||||||
/* Wait for an event. There is no need to run CRCReceiveTimer, since the
|
/* Wait for an event. There is no need to run CRCReceiveTimer, since the
|
||||||
* FUSB302B handles that as part of its retry mechanism. */
|
* FUSB302B handles that as part of its retry mechanism. */
|
||||||
ProtocolTransmit::Notifications evt = waitForEvent(
|
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_RESET
|
| (uint32_t)Notifications::PDB_EVT_PRLTX_I_RETRYFAIL);
|
||||||
| (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) {
|
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_RESET) {
|
||||||
return PRLTxPHYReset;
|
return PRLTxPHYReset;
|
||||||
}
|
}
|
||||||
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_DISCARD) {
|
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_DISCARD) {
|
||||||
return PRLTxDiscardMessage;
|
return PRLTxDiscardMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the message was sent successfully */
|
/* If the message was sent successfully */
|
||||||
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_I_TXSENT) {
|
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_I_TXSENT) {
|
||||||
return PRLTxMatchMessageID;
|
return PRLTxMatchMessageID;
|
||||||
}
|
}
|
||||||
/* If the message failed to be sent */
|
/* If the message failed to be sent */
|
||||||
if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_I_RETRYFAIL) {
|
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_I_RETRYFAIL) {
|
||||||
return PRLTxTransmissionError;
|
return PRLTxTransmissionError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Silence the compiler warning */
|
/* Silence the compiler warning */
|
||||||
return PRLTxDiscardMessage;
|
return PRLTxDiscardMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PRL_Tx_Match_MessageID state
|
* PRL_Tx_Match_MessageID state
|
||||||
*/
|
*/
|
||||||
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_match_messageid() {
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_match_messageid() {
|
||||||
union pd_msg goodcrc;
|
union pd_msg goodcrc;
|
||||||
|
|
||||||
/* Read the GoodCRC */
|
/* Read the GoodCRC */
|
||||||
fusb_read_message(&goodcrc);
|
fusb_read_message(&goodcrc);
|
||||||
|
|
||||||
/* Check that the message is correct */
|
/* Check that the message is correct */
|
||||||
if (PD_MSGTYPE_GET(&goodcrc) == PD_MSGTYPE_GOODCRC
|
if (PD_MSGTYPE_GET(&goodcrc) == PD_MSGTYPE_GOODCRC && PD_NUMOBJ_GET(&goodcrc) == 0 && PD_MESSAGEID_GET(&goodcrc) == _tx_messageidcounter) {
|
||||||
&& PD_NUMOBJ_GET(&goodcrc) == 0
|
return PRLTxMessageSent;
|
||||||
&& PD_MESSAGEID_GET(&goodcrc) == _tx_messageidcounter) {
|
} else {
|
||||||
return PRLTxMessageSent;
|
return PRLTxTransmissionError;
|
||||||
} else {
|
}
|
||||||
return PRLTxTransmissionError;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_transmission_error() {
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_transmission_error() {
|
||||||
/* Increment MessageIDCounter */
|
/* Increment MessageIDCounter */
|
||||||
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
|
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
|
||||||
|
|
||||||
/* Tell the policy engine that we failed */
|
/* Tell the policy engine that we failed */
|
||||||
PolicyEngine::notify( PDB_EVT_PE_TX_ERR);
|
PolicyEngine::notify(PDB_EVT_PE_TX_ERR);
|
||||||
|
|
||||||
return PRLTxWaitMessage;
|
return PRLTxWaitMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_message_sent() {
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_message_sent() {
|
||||||
messageSending = false;
|
messageSending = false;
|
||||||
/* Increment MessageIDCounter */
|
/* Increment MessageIDCounter */
|
||||||
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
|
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
|
||||||
|
|
||||||
/* Tell the policy engine that we succeeded */
|
/* Tell the policy engine that we succeeded */
|
||||||
PolicyEngine::notify( PDB_EVT_PE_TX_DONE);
|
PolicyEngine::notify(PDB_EVT_PE_TX_DONE);
|
||||||
|
|
||||||
return PRLTxWaitMessage;
|
return PRLTxWaitMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_discard_message() {
|
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_discard_message() {
|
||||||
/* If we were working on sending a message, increment MessageIDCounter */
|
/* If we were working on sending a message, increment MessageIDCounter */
|
||||||
if (messageSending) {
|
if (messageSending) {
|
||||||
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
|
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
|
||||||
|
|
||||||
return PRLTxPHYReset;
|
return PRLTxPHYReset;
|
||||||
} else {
|
} else {
|
||||||
return PRLTxWaitMessage;
|
return PRLTxWaitMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ProtocolTransmit::thread(const void *args) {
|
void ProtocolTransmit::thread(const void *args) {
|
||||||
(void) args;
|
(void)args;
|
||||||
ProtocolTransmit::protocol_tx_state state = PRLTxPHYReset;
|
ProtocolTransmit::protocol_tx_state state = PRLTxPHYReset;
|
||||||
|
|
||||||
//Init the incoming message queue
|
// Init the incoming message queue
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PRLTxPHYReset:
|
case PRLTxPHYReset:
|
||||||
state = protocol_tx_phy_reset();
|
state = protocol_tx_phy_reset();
|
||||||
break;
|
break;
|
||||||
case PRLTxWaitMessage:
|
case PRLTxWaitMessage:
|
||||||
state = protocol_tx_wait_message();
|
state = protocol_tx_wait_message();
|
||||||
break;
|
break;
|
||||||
case PRLTxReset:
|
case PRLTxReset:
|
||||||
state = protocol_tx_reset();
|
state = protocol_tx_reset();
|
||||||
break;
|
break;
|
||||||
case PRLTxConstructMessage:
|
case PRLTxConstructMessage:
|
||||||
state = protocol_tx_construct_message();
|
state = protocol_tx_construct_message();
|
||||||
break;
|
break;
|
||||||
case PRLTxWaitResponse:
|
case PRLTxWaitResponse:
|
||||||
state = protocol_tx_wait_response();
|
state = protocol_tx_wait_response();
|
||||||
break;
|
break;
|
||||||
case PRLTxMatchMessageID:
|
case PRLTxMatchMessageID:
|
||||||
state = protocol_tx_match_messageid();
|
state = protocol_tx_match_messageid();
|
||||||
break;
|
break;
|
||||||
case PRLTxTransmissionError:
|
case PRLTxTransmissionError:
|
||||||
state = protocol_tx_transmission_error();
|
state = protocol_tx_transmission_error();
|
||||||
break;
|
break;
|
||||||
case PRLTxMessageSent:
|
case PRLTxMessageSent:
|
||||||
state = protocol_tx_message_sent();
|
state = protocol_tx_message_sent();
|
||||||
break;
|
break;
|
||||||
case PRLTxDiscardMessage:
|
case PRLTxDiscardMessage:
|
||||||
state = protocol_tx_discard_message();
|
state = protocol_tx_discard_message();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
state = PRLTxPHYReset;
|
state = PRLTxPHYReset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolTransmit::notify(ProtocolTransmit::Notifications notification) {
|
void ProtocolTransmit::notify(ProtocolTransmit::Notifications notification) {
|
||||||
if (xEventGroupHandle != NULL) {
|
if (xEventGroupHandle != NULL) {
|
||||||
xEventGroupSetBits(xEventGroupHandle, (uint32_t) notification);
|
xEventGroupSetBits(xEventGroupHandle, (uint32_t)notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolTransmit::init() {
|
void ProtocolTransmit::init() {
|
||||||
messagesWaiting = xQueueCreateStatic(PDB_MSG_POOL_SIZE,
|
messagesWaiting = xQueueCreateStatic(PDB_MSG_POOL_SIZE, sizeof(union pd_msg), ucQueueStorageArea, &xStaticQueue);
|
||||||
sizeof(union pd_msg), ucQueueStorageArea, &xStaticQueue);
|
|
||||||
|
|
||||||
osThreadStaticDef(pd_txTask, thread, PDB_PRIO_PRL, 0, TaskStackSize,
|
osThreadStaticDef(pd_txTask, thread, PDB_PRIO_PRL, 0, TaskStackSize, TaskBuffer, &TaskControlBlock);
|
||||||
TaskBuffer, &TaskControlBlock);
|
TaskHandle = osThreadCreate(osThread(pd_txTask), NULL);
|
||||||
TaskHandle = osThreadCreate(osThread(pd_txTask), NULL);
|
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
|
||||||
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolTransmit::pushMessage(union pd_msg *msg) {
|
void ProtocolTransmit::pushMessage(union pd_msg *msg) {
|
||||||
if (messagesWaiting) {
|
if (messagesWaiting) {
|
||||||
xQueueSend(messagesWaiting, msg, 100);
|
xQueueSend(messagesWaiting, msg, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProtocolTransmit::messagePending() {
|
bool ProtocolTransmit::messagePending() {
|
||||||
if (messagesWaiting) {
|
if (messagesWaiting) {
|
||||||
return uxQueueMessagesWaiting(messagesWaiting) > 0;
|
return uxQueueMessagesWaiting(messagesWaiting) > 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolTransmit::getMessage() {
|
void ProtocolTransmit::getMessage() {
|
||||||
//Loads the pending message into the buffer
|
// Loads the pending message into the buffer
|
||||||
if (messagesWaiting) {
|
if (messagesWaiting) {
|
||||||
xQueueReceive(messagesWaiting, &temp_msg, 1);
|
xQueueReceive(messagesWaiting, &temp_msg, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolTransmit::Notifications ProtocolTransmit::waitForEvent(uint32_t mask,
|
ProtocolTransmit::Notifications ProtocolTransmit::waitForEvent(uint32_t mask, TickType_t ticksToWait) {
|
||||||
TickType_t ticksToWait) {
|
if (xEventGroupHandle) {
|
||||||
if (xEventGroupHandle) {
|
return (Notifications)xEventGroupWaitBits(xEventGroupHandle, mask, mask, pdFALSE, ticksToWait);
|
||||||
return (Notifications) xEventGroupWaitBits(xEventGroupHandle, mask,
|
}
|
||||||
mask,
|
return (Notifications)0;
|
||||||
pdFALSE, ticksToWait);
|
|
||||||
}
|
|
||||||
return (Notifications)0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,308 +6,299 @@
|
|||||||
*/
|
*/
|
||||||
#include "Model_Config.h"
|
#include "Model_Config.h"
|
||||||
#ifdef I2C_SOFT
|
#ifdef I2C_SOFT
|
||||||
#include <I2CBB.hpp>
|
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
#include <I2CBB.hpp>
|
||||||
SemaphoreHandle_t I2CBB::I2CSemaphore = NULL;
|
SemaphoreHandle_t I2CBB::I2CSemaphore = NULL;
|
||||||
StaticSemaphore_t I2CBB::xSemaphoreBuffer;
|
StaticSemaphore_t I2CBB::xSemaphoreBuffer;
|
||||||
SemaphoreHandle_t I2CBB::I2CSemaphore2 = NULL;
|
SemaphoreHandle_t I2CBB::I2CSemaphore2 = NULL;
|
||||||
StaticSemaphore_t I2CBB::xSemaphoreBuffer2;
|
StaticSemaphore_t I2CBB::xSemaphoreBuffer2;
|
||||||
void I2CBB::init() {
|
void I2CBB::init() {
|
||||||
//Set GPIO's to output open drain
|
// Set GPIO's to output open drain
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||||
GPIO_InitStruct.Pin = SDA2_Pin;
|
GPIO_InitStruct.Pin = SDA2_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
||||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
HAL_GPIO_Init(SDA2_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(SDA2_GPIO_Port, &GPIO_InitStruct);
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||||
GPIO_InitStruct.Pin = SCL2_Pin;
|
GPIO_InitStruct.Pin = SCL2_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
||||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
HAL_GPIO_Init(SCL2_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(SCL2_GPIO_Port, &GPIO_InitStruct);
|
||||||
SOFT_SDA_HIGH();
|
SOFT_SDA_HIGH();
|
||||||
SOFT_SCL_HIGH();
|
SOFT_SCL_HIGH();
|
||||||
I2CSemaphore = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer);
|
I2CSemaphore = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer);
|
||||||
I2CSemaphore2 = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer2);
|
I2CSemaphore2 = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer2);
|
||||||
unlock();
|
unlock();
|
||||||
unlock2();
|
unlock2();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool I2CBB::probe(uint8_t address) {
|
bool I2CBB::probe(uint8_t address) {
|
||||||
if (!lock())
|
if (!lock())
|
||||||
return false;
|
return false;
|
||||||
start();
|
start();
|
||||||
bool ack = send(address);
|
bool ack = send(address);
|
||||||
stop();
|
stop();
|
||||||
unlock();
|
unlock();
|
||||||
return ack;
|
return ack;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData,
|
bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) {
|
||||||
uint16_t Size) {
|
if (!lock())
|
||||||
if (!lock())
|
return false;
|
||||||
return false;
|
start();
|
||||||
start();
|
bool ack = send(DevAddress);
|
||||||
bool ack = send(DevAddress);
|
if (!ack) {
|
||||||
if (!ack) {
|
stop();
|
||||||
stop();
|
unlock();
|
||||||
unlock();
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
ack = send(MemAddress);
|
||||||
ack = send(MemAddress);
|
if (!ack) {
|
||||||
if (!ack) {
|
stop();
|
||||||
stop();
|
unlock();
|
||||||
unlock();
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
SOFT_SCL_LOW();
|
||||||
SOFT_SCL_LOW();
|
SOFT_I2C_DELAY();
|
||||||
SOFT_I2C_DELAY();
|
// stop();
|
||||||
// stop();
|
start();
|
||||||
start();
|
ack = send(DevAddress | 1);
|
||||||
ack = send(DevAddress | 1);
|
if (!ack) {
|
||||||
if (!ack) {
|
stop();
|
||||||
stop();
|
unlock();
|
||||||
unlock();
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
while (Size) {
|
||||||
while (Size) {
|
pData[0] = read(Size > 1);
|
||||||
pData[0] = read(Size > 1);
|
pData++;
|
||||||
pData++;
|
Size--;
|
||||||
Size--;
|
}
|
||||||
}
|
stop();
|
||||||
stop();
|
unlock();
|
||||||
unlock();
|
return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *pData, uint16_t Size) {
|
||||||
const uint8_t *pData, uint16_t Size) {
|
if (!lock())
|
||||||
if (!lock())
|
return false;
|
||||||
return false;
|
start();
|
||||||
start();
|
bool ack = send(DevAddress);
|
||||||
bool ack = send(DevAddress);
|
if (!ack) {
|
||||||
if (!ack) {
|
stop();
|
||||||
stop();
|
asm("bkpt");
|
||||||
asm("bkpt");
|
unlock();
|
||||||
unlock();
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
ack = send(MemAddress);
|
||||||
ack = send(MemAddress);
|
if (!ack) {
|
||||||
if (!ack) {
|
stop();
|
||||||
stop();
|
asm("bkpt");
|
||||||
asm("bkpt");
|
unlock();
|
||||||
unlock();
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
while (Size) {
|
||||||
while (Size) {
|
resetWatchdog();
|
||||||
resetWatchdog();
|
ack = send(pData[0]);
|
||||||
ack = send(pData[0]);
|
if (!ack) {
|
||||||
if (!ack) {
|
stop();
|
||||||
stop();
|
asm("bkpt");
|
||||||
asm("bkpt");
|
unlock();
|
||||||
unlock();
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
pData++;
|
||||||
pData++;
|
Size--;
|
||||||
Size--;
|
}
|
||||||
}
|
stop();
|
||||||
stop();
|
unlock();
|
||||||
unlock();
|
return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||||
if (!lock())
|
if (!lock())
|
||||||
return;
|
return;
|
||||||
start();
|
start();
|
||||||
bool ack = send(DevAddress);
|
bool ack = send(DevAddress);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
unlock();
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (Size) {
|
while (Size) {
|
||||||
ack = send(pData[0]);
|
ack = send(pData[0]);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
unlock();
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pData++;
|
pData++;
|
||||||
Size--;
|
Size--;
|
||||||
}
|
}
|
||||||
stop();
|
stop();
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||||
if (!lock())
|
if (!lock())
|
||||||
return;
|
return;
|
||||||
start();
|
start();
|
||||||
bool ack = send(DevAddress | 1);
|
bool ack = send(DevAddress | 1);
|
||||||
if (!ack) {
|
if (!ack) {
|
||||||
stop();
|
stop();
|
||||||
unlock();
|
unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (Size) {
|
while (Size) {
|
||||||
pData[0] = read(Size > 1);
|
pData[0] = read(Size > 1);
|
||||||
pData++;
|
pData++;
|
||||||
Size--;
|
Size--;
|
||||||
}
|
}
|
||||||
stop();
|
stop();
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx,
|
void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) {
|
||||||
uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) {
|
if (Size_tx == 0 && Size_rx == 0)
|
||||||
if (Size_tx == 0 && Size_rx == 0)
|
return;
|
||||||
return;
|
if (lock() == false)
|
||||||
if (lock() == false)
|
return;
|
||||||
return;
|
if (Size_tx) {
|
||||||
if (Size_tx) {
|
start();
|
||||||
start();
|
bool ack = send(DevAddress);
|
||||||
bool ack = send(DevAddress);
|
if (!ack) {
|
||||||
if (!ack) {
|
stop();
|
||||||
stop();
|
unlock();
|
||||||
unlock();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
while (Size_tx) {
|
||||||
while (Size_tx) {
|
ack = send(pData_tx[0]);
|
||||||
ack = send(pData_tx[0]);
|
if (!ack) {
|
||||||
if (!ack) {
|
stop();
|
||||||
stop();
|
unlock();
|
||||||
unlock();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
pData_tx++;
|
||||||
pData_tx++;
|
Size_tx--;
|
||||||
Size_tx--;
|
}
|
||||||
}
|
}
|
||||||
}
|
if (Size_rx) {
|
||||||
if (Size_rx) {
|
start();
|
||||||
start();
|
bool ack = send(DevAddress | 1);
|
||||||
bool ack = send(DevAddress | 1);
|
if (!ack) {
|
||||||
if (!ack) {
|
stop();
|
||||||
stop();
|
unlock();
|
||||||
unlock();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
while (Size_rx) {
|
||||||
while (Size_rx) {
|
pData_rx[0] = read(Size_rx > 1);
|
||||||
pData_rx[0] = read(Size_rx > 1);
|
pData_rx++;
|
||||||
pData_rx++;
|
Size_rx--;
|
||||||
Size_rx--;
|
}
|
||||||
}
|
}
|
||||||
}
|
stop();
|
||||||
stop();
|
unlock();
|
||||||
unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::start() {
|
void I2CBB::start() {
|
||||||
/* I2C Start condition, data line goes low when clock is high */
|
/* I2C Start condition, data line goes low when clock is high */
|
||||||
SOFT_SCL_HIGH();
|
SOFT_SCL_HIGH();
|
||||||
SOFT_SDA_HIGH();
|
SOFT_SDA_HIGH();
|
||||||
SOFT_I2C_DELAY();
|
SOFT_I2C_DELAY();
|
||||||
SOFT_SDA_LOW();
|
SOFT_SDA_LOW();
|
||||||
SOFT_I2C_DELAY();
|
SOFT_I2C_DELAY();
|
||||||
SOFT_SCL_LOW();
|
SOFT_SCL_LOW();
|
||||||
SOFT_I2C_DELAY();
|
SOFT_I2C_DELAY();
|
||||||
SOFT_SDA_HIGH();
|
SOFT_SDA_HIGH();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::stop() {
|
void I2CBB::stop() {
|
||||||
/* I2C Stop condition, clock goes high when data is low */
|
/* I2C Stop condition, clock goes high when data is low */
|
||||||
SOFT_SDA_LOW();
|
SOFT_SDA_LOW();
|
||||||
SOFT_I2C_DELAY();
|
SOFT_I2C_DELAY();
|
||||||
SOFT_SCL_HIGH();
|
SOFT_SCL_HIGH();
|
||||||
SOFT_I2C_DELAY();
|
SOFT_I2C_DELAY();
|
||||||
SOFT_SDA_HIGH();
|
SOFT_SDA_HIGH();
|
||||||
SOFT_I2C_DELAY();
|
SOFT_I2C_DELAY();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool I2CBB::send(uint8_t value) {
|
bool I2CBB::send(uint8_t value) {
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 8; i++) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
write_bit(value & 0x80); // write the most-significant bit
|
write_bit(value & 0x80); // write the most-significant bit
|
||||||
value <<= 1;
|
value <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOFT_SDA_HIGH();
|
SOFT_SDA_HIGH();
|
||||||
bool ack = (read_bit() == 0);
|
bool ack = (read_bit() == 0);
|
||||||
return ack;
|
return ack;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t I2CBB::read(bool ack) {
|
uint8_t I2CBB::read(bool ack) {
|
||||||
uint8_t B = 0;
|
uint8_t B = 0;
|
||||||
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
B <<= 1;
|
B <<= 1;
|
||||||
B |= read_bit();
|
B |= read_bit();
|
||||||
}
|
}
|
||||||
|
|
||||||
SOFT_SDA_HIGH();
|
SOFT_SDA_HIGH();
|
||||||
if (ack)
|
if (ack)
|
||||||
write_bit(0);
|
write_bit(0);
|
||||||
else
|
else
|
||||||
write_bit(1);
|
write_bit(1);
|
||||||
return B;
|
return B;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t I2CBB::read_bit() {
|
uint8_t I2CBB::read_bit() {
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
|
|
||||||
SOFT_SDA_HIGH();
|
SOFT_SDA_HIGH();
|
||||||
SOFT_I2C_DELAY();
|
SOFT_I2C_DELAY();
|
||||||
SOFT_SCL_HIGH();
|
SOFT_SCL_HIGH();
|
||||||
SOFT_I2C_DELAY();
|
SOFT_I2C_DELAY();
|
||||||
|
|
||||||
if (SOFT_SDA_READ())
|
if (SOFT_SDA_READ())
|
||||||
b = 1;
|
b = 1;
|
||||||
else
|
else
|
||||||
b = 0;
|
b = 0;
|
||||||
|
|
||||||
SOFT_SCL_LOW();
|
SOFT_SCL_LOW();
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::unlock() {
|
void I2CBB::unlock() { xSemaphoreGive(I2CSemaphore); }
|
||||||
xSemaphoreGive(I2CSemaphore);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool I2CBB::lock() {
|
bool I2CBB::lock() {
|
||||||
if (I2CSemaphore == NULL) {
|
if (I2CSemaphore == NULL) {
|
||||||
asm("bkpt");
|
asm("bkpt");
|
||||||
}
|
}
|
||||||
bool a = xSemaphoreTake(I2CSemaphore, (TickType_t) 100) == pdTRUE;
|
bool a = xSemaphoreTake(I2CSemaphore, (TickType_t)100) == pdTRUE;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::write_bit(uint8_t val) {
|
void I2CBB::write_bit(uint8_t val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
SOFT_SDA_HIGH();
|
SOFT_SDA_HIGH();
|
||||||
} else {
|
} else {
|
||||||
SOFT_SDA_LOW();
|
SOFT_SDA_LOW();
|
||||||
}
|
}
|
||||||
|
|
||||||
SOFT_I2C_DELAY();
|
SOFT_I2C_DELAY();
|
||||||
SOFT_SCL_HIGH();
|
SOFT_SCL_HIGH();
|
||||||
SOFT_I2C_DELAY();
|
SOFT_I2C_DELAY();
|
||||||
SOFT_SCL_LOW();
|
SOFT_SCL_LOW();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CBB::unlock2() {
|
void I2CBB::unlock2() { xSemaphoreGive(I2CSemaphore2); }
|
||||||
xSemaphoreGive(I2CSemaphore2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool I2CBB::lock2() {
|
bool I2CBB::lock2() {
|
||||||
if (I2CSemaphore2 == NULL) {
|
if (I2CSemaphore2 == NULL) {
|
||||||
asm("bkpt");
|
asm("bkpt");
|
||||||
}
|
}
|
||||||
bool a = xSemaphoreTake(I2CSemaphore2, (TickType_t) 500) == pdTRUE;
|
bool a = xSemaphoreTake(I2CSemaphore2, (TickType_t)500) == pdTRUE;
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,34 +10,30 @@
|
|||||||
#include "LIS2DH12.hpp"
|
#include "LIS2DH12.hpp"
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
|
|
||||||
static const FRToSI2C::I2C_REG i2c_registers[] = { { LIS_CTRL_REG1, 0x17, 0 }, // 25Hz
|
static const FRToSI2C::I2C_REG i2c_registers[] = {{LIS_CTRL_REG1, 0x17, 0}, // 25Hz
|
||||||
{ LIS_CTRL_REG2, 0b00001000, 0 }, // Highpass filter off
|
{LIS_CTRL_REG2, 0b00001000, 0}, // Highpass filter off
|
||||||
{ LIS_CTRL_REG3, 0b01100000, 0 }, // Setup interrupt pins
|
{LIS_CTRL_REG3, 0b01100000, 0}, // Setup interrupt pins
|
||||||
{ LIS_CTRL_REG4, 0b00001000, 0 }, // Block update mode off, HR on
|
{LIS_CTRL_REG4, 0b00001000, 0}, // Block update mode off, HR on
|
||||||
{ LIS_CTRL_REG5, 0b00000010, 0 }, //
|
{LIS_CTRL_REG5, 0b00000010, 0}, //
|
||||||
{ LIS_CTRL_REG6, 0b01100010, 0 },
|
{LIS_CTRL_REG6, 0b01100010, 0},
|
||||||
//Basically setup the unit to run, and enable 4D orientation detection
|
// Basically setup the unit to run, and enable 4D orientation detection
|
||||||
{ LIS_INT2_CFG, 0b01111110, 0 }, //setup for movement detection
|
{LIS_INT2_CFG, 0b01111110, 0}, // setup for movement detection
|
||||||
{ LIS_INT2_THS, 0x28, 0 }, //
|
{LIS_INT2_THS, 0x28, 0}, //
|
||||||
{ LIS_INT2_DURATION, 64, 0 }, //
|
{LIS_INT2_DURATION, 64, 0}, //
|
||||||
{ LIS_INT1_CFG, 0b01111110, 0 }, //
|
{LIS_INT1_CFG, 0b01111110, 0}, //
|
||||||
{ LIS_INT1_THS, 0x28, 0 }, //
|
{LIS_INT1_THS, 0x28, 0}, //
|
||||||
{ LIS_INT1_DURATION, 64, 0 } };
|
{LIS_INT1_DURATION, 64, 0}};
|
||||||
|
|
||||||
bool LIS2DH12::initalize() {
|
bool LIS2DH12::initalize() { return FRToSI2C::writeRegistersBulk(LIS2DH_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0])); }
|
||||||
return FRToSI2C::writeRegistersBulk(LIS2DH_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LIS2DH12::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
void LIS2DH12::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
||||||
std::array<int16_t, 3> sensorData;
|
std::array<int16_t, 3> sensorData;
|
||||||
|
|
||||||
FRToSI2C::Mem_Read(LIS2DH_I2C_ADDRESS, 0xA8, reinterpret_cast<uint8_t*>(sensorData.begin()), sensorData.size() * sizeof(int16_t));
|
FRToSI2C::Mem_Read(LIS2DH_I2C_ADDRESS, 0xA8, reinterpret_cast<uint8_t *>(sensorData.begin()), sensorData.size() * sizeof(int16_t));
|
||||||
|
|
||||||
x = sensorData[0];
|
x = sensorData[0];
|
||||||
y = sensorData[1];
|
y = sensorData[1];
|
||||||
z = sensorData[2];
|
z = sensorData[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LIS2DH12::detect() {
|
bool LIS2DH12::detect() { return FRToSI2C::probe(LIS2DH_I2C_ADDRESS); }
|
||||||
return FRToSI2C::probe(LIS2DH_I2C_ADDRESS);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,54 +10,48 @@
|
|||||||
#include "MMA8652FC.hpp"
|
#include "MMA8652FC.hpp"
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
|
|
||||||
|
static const FRToSI2C::I2C_REG i2c_registers[] = {
|
||||||
static const FRToSI2C::I2C_REG i2c_registers[] = { { CTRL_REG2, 0, 0 }, //Normal mode
|
{CTRL_REG2, 0, 0}, // Normal mode
|
||||||
{ CTRL_REG2, 0x40, 2 }, // Reset all registers to POR values
|
{CTRL_REG2, 0x40, 2}, // Reset all registers to POR values
|
||||||
{ FF_MT_CFG_REG, 0x78, 0 }, // Enable motion detection for X, Y, Z axis, latch disabled
|
{FF_MT_CFG_REG, 0x78, 0}, // Enable motion detection for X, Y, Z axis, latch disabled
|
||||||
{ PL_CFG_REG, 0x40, 0 }, //Enable the orientation detection
|
{PL_CFG_REG, 0x40, 0}, // Enable the orientation detection
|
||||||
{ PL_COUNT_REG, 200, 0 }, //200 count debounce
|
{PL_COUNT_REG, 200, 0}, // 200 count debounce
|
||||||
{ PL_BF_ZCOMP_REG, 0b01000111, 0 }, //Set the threshold to 42 degrees
|
{PL_BF_ZCOMP_REG, 0b01000111, 0}, // Set the threshold to 42 degrees
|
||||||
{ P_L_THS_REG, 0b10011100, 0 }, //Up the trip angles
|
{P_L_THS_REG, 0b10011100, 0}, // Up the trip angles
|
||||||
{ CTRL_REG4, 0x01 | (1 << 4), 0 }, // Enable dataready interrupt & orientation interrupt
|
{CTRL_REG4, 0x01 | (1 << 4), 0}, // Enable dataready interrupt & orientation interrupt
|
||||||
{ CTRL_REG5, 0x01, 0 }, // Route data ready interrupts to INT1 ->PB5 ->EXTI5, leaving orientation routed to INT2
|
{CTRL_REG5, 0x01, 0}, // Route data ready interrupts to INT1 ->PB5 ->EXTI5, leaving orientation routed to INT2
|
||||||
{ CTRL_REG2, 0x12, 0 }, //Set maximum resolution oversampling
|
{CTRL_REG2, 0x12, 0}, // Set maximum resolution oversampling
|
||||||
{ XYZ_DATA_CFG_REG, (1 << 4), 0 }, //select high pass filtered data
|
{XYZ_DATA_CFG_REG, (1 << 4), 0}, // select high pass filtered data
|
||||||
{ HP_FILTER_CUTOFF_REG, 0x03, 0 }, //select high pass filtered data
|
{HP_FILTER_CUTOFF_REG, 0x03, 0}, // select high pass filtered data
|
||||||
{ CTRL_REG1, 0x19, 0 } // ODR=12 Hz, Active mode
|
{CTRL_REG1, 0x19, 0} // ODR=12 Hz, Active mode
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MMA8652FC::initalize() {
|
bool MMA8652FC::initalize() { return FRToSI2C::writeRegistersBulk(MMA8652FC_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0])); }
|
||||||
return FRToSI2C::writeRegistersBulk(MMA8652FC_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Orientation MMA8652FC::getOrientation() {
|
Orientation MMA8652FC::getOrientation() {
|
||||||
//First read the PL_STATUS register
|
// First read the PL_STATUS register
|
||||||
uint8_t plStatus = FRToSI2C::I2C_RegisterRead(MMA8652FC_I2C_ADDRESS,
|
uint8_t plStatus = FRToSI2C::I2C_RegisterRead(MMA8652FC_I2C_ADDRESS, PL_STATUS_REG);
|
||||||
PL_STATUS_REG);
|
if ((plStatus & 0b10000000) == 0b10000000) {
|
||||||
if ((plStatus & 0b10000000) == 0b10000000) {
|
plStatus >>= 1; // We don't need the up/down bit
|
||||||
plStatus >>= 1; //We don't need the up/down bit
|
plStatus &= 0x03; // mask to the two lower bits
|
||||||
plStatus &= 0x03; //mask to the two lower bits
|
|
||||||
|
|
||||||
//0 == left handed
|
// 0 == left handed
|
||||||
//1 == right handed
|
// 1 == right handed
|
||||||
|
|
||||||
return static_cast<Orientation>(plStatus);
|
return static_cast<Orientation>(plStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ORIENTATION_FLAT;
|
return ORIENTATION_FLAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMA8652FC::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
void MMA8652FC::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
||||||
std::array<int16_t, 3> sensorData;
|
std::array<int16_t, 3> sensorData;
|
||||||
|
|
||||||
FRToSI2C::Mem_Read(MMA8652FC_I2C_ADDRESS, OUT_X_MSB_REG, reinterpret_cast<uint8_t*>(sensorData.begin()), sensorData.size() * sizeof(int16_t));
|
FRToSI2C::Mem_Read(MMA8652FC_I2C_ADDRESS, OUT_X_MSB_REG, reinterpret_cast<uint8_t *>(sensorData.begin()), sensorData.size() * sizeof(int16_t));
|
||||||
|
|
||||||
x = static_cast<int16_t>(__builtin_bswap16(*reinterpret_cast<uint16_t*>(&sensorData[0])));
|
x = static_cast<int16_t>(__builtin_bswap16(*reinterpret_cast<uint16_t *>(&sensorData[0])));
|
||||||
y = static_cast<int16_t>(__builtin_bswap16(*reinterpret_cast<uint16_t*>(&sensorData[1])));
|
y = static_cast<int16_t>(__builtin_bswap16(*reinterpret_cast<uint16_t *>(&sensorData[1])));
|
||||||
z = static_cast<int16_t>(__builtin_bswap16(*reinterpret_cast<uint16_t*>(&sensorData[2])));
|
z = static_cast<int16_t>(__builtin_bswap16(*reinterpret_cast<uint16_t *>(&sensorData[2])));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMA8652FC::detect() {
|
bool MMA8652FC::detect() { return FRToSI2C::probe(MMA8652FC_I2C_ADDRESS); }
|
||||||
return FRToSI2C::probe(MMA8652FC_I2C_ADDRESS);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,46 +5,42 @@
|
|||||||
* Author: Ralim
|
* Author: Ralim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <MSA301.h>
|
|
||||||
#include "MSA301_defines.h"
|
#include "MSA301_defines.h"
|
||||||
|
#include <MSA301.h>
|
||||||
#define MSA301_I2C_ADDRESS 0x4C
|
#define MSA301_I2C_ADDRESS 0x4C
|
||||||
bool MSA301::detect() {
|
bool MSA301::detect() { return FRToSI2C::probe(MSA301_I2C_ADDRESS); }
|
||||||
return FRToSI2C::probe(MSA301_I2C_ADDRESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const FRToSI2C::I2C_REG i2c_registers[] = { //
|
static const FRToSI2C::I2C_REG i2c_registers[] = {
|
||||||
//
|
//
|
||||||
{ MSA301_REG_ODR, 0b00001000, 1 }, //X/Y/Z enabled @ 250Hz
|
//
|
||||||
{ MSA301_REG_POWERMODE, 0b0001001, 1 }, // Normal mode
|
{MSA301_REG_ODR, 0b00001000, 1}, // X/Y/Z enabled @ 250Hz
|
||||||
{ MSA301_REG_RESRANGE, 0b00000001, 0 }, // 14bit resolution @ 4G range
|
{MSA301_REG_POWERMODE, 0b0001001, 1}, // Normal mode
|
||||||
{ MSA301_REG_ORIENT_HY, 0b01000000, 0 }, // 4*62.5mg hyst, no blocking, symmetrical
|
{MSA301_REG_RESRANGE, 0b00000001, 0}, // 14bit resolution @ 4G range
|
||||||
{ MSA301_REG_INTSET0, 1 << 6, 0 }, // Turn on orientation detection (by enabling its interrupt)
|
{MSA301_REG_ORIENT_HY, 0b01000000, 0}, // 4*62.5mg hyst, no blocking, symmetrical
|
||||||
|
{MSA301_REG_INTSET0, 1 << 6, 0}, // Turn on orientation detection (by enabling its interrupt)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MSA301::initalize() {
|
bool MSA301::initalize() { return FRToSI2C::writeRegistersBulk(MSA301_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0])); }
|
||||||
return FRToSI2C::writeRegistersBulk(MSA301_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
Orientation MSA301::getOrientation() {
|
Orientation MSA301::getOrientation() {
|
||||||
uint8_t temp = 0;
|
uint8_t temp = 0;
|
||||||
FRToSI2C::Mem_Read(MSA301_I2C_ADDRESS, MSA301_REG_ORIENT_STATUS, &temp, 1);
|
FRToSI2C::Mem_Read(MSA301_I2C_ADDRESS, MSA301_REG_ORIENT_STATUS, &temp, 1);
|
||||||
switch (temp) {
|
switch (temp) {
|
||||||
case 112:
|
case 112:
|
||||||
return Orientation::ORIENTATION_LEFT_HAND;
|
return Orientation::ORIENTATION_LEFT_HAND;
|
||||||
case 96:
|
case 96:
|
||||||
return Orientation::ORIENTATION_RIGHT_HAND;
|
return Orientation::ORIENTATION_RIGHT_HAND;
|
||||||
default:
|
default:
|
||||||
return Orientation::ORIENTATION_FLAT;
|
return Orientation::ORIENTATION_FLAT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSA301::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
void MSA301::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
||||||
uint8_t temp[6];
|
uint8_t temp[6];
|
||||||
//Bulk read all 6 regs
|
// Bulk read all 6 regs
|
||||||
FRToSI2C::Mem_Read(MSA301_I2C_ADDRESS, MSA301_REG_OUT_X_L, temp, 6);
|
FRToSI2C::Mem_Read(MSA301_I2C_ADDRESS, MSA301_REG_OUT_X_L, temp, 6);
|
||||||
x = int16_t(((int16_t) temp[1]) << 8 | temp[0]) >> 2;
|
x = int16_t(((int16_t)temp[1]) << 8 | temp[0]) >> 2;
|
||||||
y = int16_t(((int16_t) temp[3]) << 8 | temp[2]) >> 2;
|
y = int16_t(((int16_t)temp[3]) << 8 | temp[2]) >> 2;
|
||||||
z = int16_t(((int16_t) temp[5]) << 8 | temp[4]) >> 2;
|
z = int16_t(((int16_t)temp[5]) << 8 | temp[4]) >> 2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,63 +5,63 @@
|
|||||||
* Author: Ben V. Brown
|
* Author: Ben V. Brown
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include "../../configuration.h"
|
||||||
#include <OLED.hpp>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "Translation.h"
|
#include "Translation.h"
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
#include "../../configuration.h"
|
#include <OLED.hpp>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
const uint8_t *OLED::currentFont; // Pointer to the current font used for
|
const uint8_t *OLED::currentFont; // Pointer to the current font used for
|
||||||
// rendering to the buffer
|
// rendering to the buffer
|
||||||
uint8_t *OLED::firstStripPtr; // Pointers to the strips to allow for buffer
|
uint8_t *OLED::firstStripPtr; // Pointers to the strips to allow for buffer
|
||||||
// having extra content
|
// having extra content
|
||||||
uint8_t *OLED::secondStripPtr; // Pointers to the strips
|
uint8_t *OLED::secondStripPtr; // Pointers to the strips
|
||||||
bool OLED::inLeftHandedMode; // Whether the screen is in left or not (used for
|
bool OLED::inLeftHandedMode; // Whether the screen is in left or not (used for
|
||||||
// offsets in GRAM)
|
// offsets in GRAM)
|
||||||
OLED::DisplayState OLED::displayState;
|
OLED::DisplayState OLED::displayState;
|
||||||
uint8_t OLED::fontWidth, OLED::fontHeight;
|
uint8_t OLED::fontWidth, OLED::fontHeight;
|
||||||
int16_t OLED::cursor_x, OLED::cursor_y;
|
int16_t OLED::cursor_x, OLED::cursor_y;
|
||||||
bool OLED::initDone = false;
|
bool OLED::initDone = false;
|
||||||
uint8_t OLED::displayOffset;
|
uint8_t OLED::displayOffset;
|
||||||
uint8_t OLED::screenBuffer[16 + (OLED_WIDTH * 2) + 10]; // The data buffer
|
uint8_t OLED::screenBuffer[16 + (OLED_WIDTH * 2) + 10]; // The data buffer
|
||||||
uint8_t OLED::secondFrameBuffer[OLED_WIDTH * 2];
|
uint8_t OLED::secondFrameBuffer[OLED_WIDTH * 2];
|
||||||
|
|
||||||
/*Setup params for the OLED screen*/
|
/*Setup params for the OLED screen*/
|
||||||
/*http://www.displayfuture.com/Display/datasheet/controller/SSD1307.pdf*/
|
/*http://www.displayfuture.com/Display/datasheet/controller/SSD1307.pdf*/
|
||||||
/*All commands are prefixed with 0x80*/
|
/*All commands are prefixed with 0x80*/
|
||||||
/*Data packets are prefixed with 0x40*/
|
/*Data packets are prefixed with 0x40*/
|
||||||
FRToSI2C::I2C_REG OLED_Setup_Array[] = {
|
FRToSI2C::I2C_REG OLED_Setup_Array[] = {
|
||||||
/**/
|
/**/
|
||||||
{ 0x80, 0xAE, 0 }, /*Display off*/
|
{0x80, 0xAE, 0}, /*Display off*/
|
||||||
{ 0x80, 0xD5, 0 }, /*Set display clock divide ratio / osc freq*/
|
{0x80, 0xD5, 0}, /*Set display clock divide ratio / osc freq*/
|
||||||
{ 0x80, 0x52, 0 }, /*Divide ratios*/
|
{0x80, 0x52, 0}, /*Divide ratios*/
|
||||||
{ 0x80, 0xA8, 0 }, /*Set Multiplex Ratio*/
|
{0x80, 0xA8, 0}, /*Set Multiplex Ratio*/
|
||||||
{ 0x80, 0x0F, 0 }, /*16 == max brightness,39==dimmest*/
|
{0x80, 0x0F, 0}, /*16 == max brightness,39==dimmest*/
|
||||||
{ 0x80, 0xC0, 0 }, /*Set COM Scan direction*/
|
{0x80, 0xC0, 0}, /*Set COM Scan direction*/
|
||||||
{ 0x80, 0xD3, 0 }, /*Set vertical Display offset*/
|
{0x80, 0xD3, 0}, /*Set vertical Display offset*/
|
||||||
{ 0x80, 0x00, 0 }, /*0 Offset*/
|
{0x80, 0x00, 0}, /*0 Offset*/
|
||||||
{ 0x80, 0x40, 0 }, /*Set Display start line to 0*/
|
{0x80, 0x40, 0}, /*Set Display start line to 0*/
|
||||||
{ 0x80, 0xA0, 0 }, /*Set Segment remap to normal*/
|
{0x80, 0xA0, 0}, /*Set Segment remap to normal*/
|
||||||
{ 0x80, 0x8D, 0 }, /*Charge Pump*/
|
{0x80, 0x8D, 0}, /*Charge Pump*/
|
||||||
{ 0x80, 0x14, 0 }, /*Charge Pump settings*/
|
{0x80, 0x14, 0}, /*Charge Pump settings*/
|
||||||
{ 0x80, 0xDA, 0 }, /*Set VCOM Pins hardware config*/
|
{0x80, 0xDA, 0}, /*Set VCOM Pins hardware config*/
|
||||||
{ 0x80, 0x02, 0 }, /*Combination 2*/
|
{0x80, 0x02, 0}, /*Combination 2*/
|
||||||
{ 0x80, 0x81, 0 }, /*Contrast*/
|
{0x80, 0x81, 0}, /*Contrast*/
|
||||||
{ 0x80, 0x33, 0 }, /*^51*/
|
{0x80, 0x33, 0}, /*^51*/
|
||||||
{ 0x80, 0xD9, 0 }, /*Set pre-charge period*/
|
{0x80, 0xD9, 0}, /*Set pre-charge period*/
|
||||||
{ 0x80, 0xF1, 0 }, /*Pre charge period*/
|
{0x80, 0xF1, 0}, /*Pre charge period*/
|
||||||
{ 0x80, 0xDB, 0 }, /*Adjust VCOMH regulator ouput*/
|
{0x80, 0xDB, 0}, /*Adjust VCOMH regulator ouput*/
|
||||||
{ 0x80, 0x30, 0 }, /*VCOM level*/
|
{0x80, 0x30, 0}, /*VCOM level*/
|
||||||
{ 0x80, 0xA4, 0 }, /*Enable the display GDDR*/
|
{0x80, 0xA4, 0}, /*Enable the display GDDR*/
|
||||||
{ 0x80, 0XA6, 0 }, /*Normal display*/
|
{0x80, 0XA6, 0}, /*Normal display*/
|
||||||
{ 0x80, 0x20, 0 }, /*Memory Mode*/
|
{0x80, 0x20, 0}, /*Memory Mode*/
|
||||||
{ 0x80, 0x00, 0 }, /*Wrap memory*/
|
{0x80, 0x00, 0}, /*Wrap memory*/
|
||||||
{ 0x80, 0xAF, 0 }, /*Display on*/
|
{0x80, 0xAF, 0}, /*Display on*/
|
||||||
};
|
};
|
||||||
// Setup based on the SSD1307 and modified for the SSD1306
|
// Setup based on the SSD1307 and modified for the SSD1306
|
||||||
|
|
||||||
const uint8_t REFRESH_COMMANDS[17] = { 0x80, 0xAF, 0x80, 0x21, 0x80, 0x20, 0x80, 0x7F, 0x80, 0xC0, 0x80, 0x22, 0x80, 0x00, 0x80, 0x01, 0x40 };
|
const uint8_t REFRESH_COMMANDS[17] = {0x80, 0xAF, 0x80, 0x21, 0x80, 0x20, 0x80, 0x7F, 0x80, 0xC0, 0x80, 0x22, 0x80, 0x00, 0x80, 0x01, 0x40};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Animation timing function that follows a bezier curve.
|
* Animation timing function that follows a bezier curve.
|
||||||
@@ -69,9 +69,7 @@ const uint8_t REFRESH_COMMANDS[17] = { 0x80, 0xAF, 0x80, 0x21, 0x80, 0x20, 0x80,
|
|||||||
* Returns a new percentage value with ease in and ease out.
|
* Returns a new percentage value with ease in and ease out.
|
||||||
* Original floating point formula: t * t * (3.0f - 2.0f * t);
|
* Original floating point formula: t * t * (3.0f - 2.0f * t);
|
||||||
*/
|
*/
|
||||||
static uint8_t easeInOutTiming(uint8_t t) {
|
static uint8_t easeInOutTiming(uint8_t t) { return t * t * (300 - 2 * t) / 10000; }
|
||||||
return t * t * (300 - 2 * t) / 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the value between a and b, using a percentage value t.
|
* Returns the value between a and b, using a percentage value t.
|
||||||
@@ -79,41 +77,39 @@ static uint8_t easeInOutTiming(uint8_t t) {
|
|||||||
* @param b The value associated with 100%
|
* @param b The value associated with 100%
|
||||||
* @param t The percentage [0..<100]
|
* @param t The percentage [0..<100]
|
||||||
*/
|
*/
|
||||||
static uint8_t lerp(uint8_t a, uint8_t b, uint8_t t) {
|
static uint8_t lerp(uint8_t a, uint8_t b, uint8_t t) { return a + t * (b - a) / 100; }
|
||||||
return a + t * (b - a) / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OLED::initialize() {
|
void OLED::initialize() {
|
||||||
cursor_x = cursor_y = 0;
|
cursor_x = cursor_y = 0;
|
||||||
currentFont = USER_FONT_12;
|
currentFont = USER_FONT_12;
|
||||||
fontWidth = 12;
|
fontWidth = 12;
|
||||||
inLeftHandedMode = false;
|
inLeftHandedMode = false;
|
||||||
firstStripPtr = &screenBuffer[FRAMEBUFFER_START];
|
firstStripPtr = &screenBuffer[FRAMEBUFFER_START];
|
||||||
secondStripPtr = &screenBuffer[FRAMEBUFFER_START + OLED_WIDTH];
|
secondStripPtr = &screenBuffer[FRAMEBUFFER_START + OLED_WIDTH];
|
||||||
fontHeight = 16;
|
fontHeight = 16;
|
||||||
displayOffset = 0;
|
displayOffset = 0;
|
||||||
memcpy(&screenBuffer[0], &REFRESH_COMMANDS[0], sizeof(REFRESH_COMMANDS));
|
memcpy(&screenBuffer[0], &REFRESH_COMMANDS[0], sizeof(REFRESH_COMMANDS));
|
||||||
|
|
||||||
// Set the display to be ON once the settings block is sent and send the
|
// Set the display to be ON once the settings block is sent and send the
|
||||||
// initialisation data to the OLED.
|
// initialisation data to the OLED.
|
||||||
|
|
||||||
for (int tries = 0; tries < 10; tries++) {
|
for (int tries = 0; tries < 10; tries++) {
|
||||||
if (FRToSI2C::writeRegistersBulk(DEVICEADDR_OLED, OLED_Setup_Array, sizeof(OLED_Setup_Array) / sizeof(OLED_Setup_Array[0]))) {
|
if (FRToSI2C::writeRegistersBulk(DEVICEADDR_OLED, OLED_Setup_Array, sizeof(OLED_Setup_Array) / sizeof(OLED_Setup_Array[0]))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setDisplayState(DisplayState::ON);
|
setDisplayState(DisplayState::ON);
|
||||||
initDone = true;
|
initDone = true;
|
||||||
}
|
}
|
||||||
void OLED::setFramebuffer(uint8_t *buffer) {
|
void OLED::setFramebuffer(uint8_t *buffer) {
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
firstStripPtr = &screenBuffer[FRAMEBUFFER_START];
|
firstStripPtr = &screenBuffer[FRAMEBUFFER_START];
|
||||||
secondStripPtr = &screenBuffer[FRAMEBUFFER_START + OLED_WIDTH];
|
secondStripPtr = &screenBuffer[FRAMEBUFFER_START + OLED_WIDTH];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
firstStripPtr = &buffer[0];
|
firstStripPtr = &buffer[0];
|
||||||
secondStripPtr = &buffer[OLED_WIDTH];
|
secondStripPtr = &buffer[OLED_WIDTH];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -122,18 +118,18 @@ void OLED::setFramebuffer(uint8_t *buffer) {
|
|||||||
* Precursor is the command char that is used to select the table.
|
* Precursor is the command char that is used to select the table.
|
||||||
*/
|
*/
|
||||||
void OLED::drawChar(char c) {
|
void OLED::drawChar(char c) {
|
||||||
if (c == '\x01' && cursor_y == 0) { // 0x01 is used as new line char
|
if (c == '\x01' && cursor_y == 0) { // 0x01 is used as new line char
|
||||||
cursor_x = 0;
|
cursor_x = 0;
|
||||||
cursor_y = 8;
|
cursor_y = 8;
|
||||||
return;
|
return;
|
||||||
} else if (c == 0) {
|
} else if (c == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16_t index = c - 2; //First index is \x02
|
uint16_t index = c - 2; // First index is \x02
|
||||||
uint8_t *charPointer;
|
uint8_t *charPointer;
|
||||||
charPointer = ((uint8_t*) currentFont) + ((fontWidth * (fontHeight / 8)) * index);
|
charPointer = ((uint8_t *)currentFont) + ((fontWidth * (fontHeight / 8)) * index);
|
||||||
drawArea(cursor_x, cursor_y, fontWidth, fontHeight, charPointer);
|
drawArea(cursor_x, cursor_y, fontWidth, fontHeight, charPointer);
|
||||||
cursor_x += fontWidth;
|
cursor_x += fontWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -141,18 +137,18 @@ void OLED::drawChar(char c) {
|
|||||||
* of the indicator in pixels (0..<16).
|
* of the indicator in pixels (0..<16).
|
||||||
*/
|
*/
|
||||||
void OLED::drawScrollIndicator(uint8_t y, uint8_t height) {
|
void OLED::drawScrollIndicator(uint8_t y, uint8_t height) {
|
||||||
union u_type {
|
union u_type {
|
||||||
uint16_t whole;
|
uint16_t whole;
|
||||||
uint8_t strips[2];
|
uint8_t strips[2];
|
||||||
} column;
|
} column;
|
||||||
|
|
||||||
column.whole = (1 << height) - 1;
|
column.whole = (1 << height) - 1;
|
||||||
column.whole <<= y;
|
column.whole <<= y;
|
||||||
|
|
||||||
// Draw a one pixel wide bar to the left with a single pixel as
|
// Draw a one pixel wide bar to the left with a single pixel as
|
||||||
// the scroll indicator.
|
// the scroll indicator.
|
||||||
fillArea(OLED_WIDTH - 1, 0, 1, 8, column.strips[0]);
|
fillArea(OLED_WIDTH - 1, 0, 1, 8, column.strips[0]);
|
||||||
fillArea(OLED_WIDTH - 1, 8, 1, 8, column.strips[1]);
|
fillArea(OLED_WIDTH - 1, 8, 1, 8, column.strips[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -163,327 +159,323 @@ void OLED::drawScrollIndicator(uint8_t y, uint8_t height) {
|
|||||||
* Otherwise a rewinding navigation animation is shown to the second framebuffer contents.
|
* Otherwise a rewinding navigation animation is shown to the second framebuffer contents.
|
||||||
*/
|
*/
|
||||||
void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) {
|
void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) {
|
||||||
uint8_t *firstBackStripPtr = &secondFrameBuffer[0];
|
uint8_t *firstBackStripPtr = &secondFrameBuffer[0];
|
||||||
uint8_t *secondBackStripPtr = &secondFrameBuffer[OLED_WIDTH];
|
uint8_t *secondBackStripPtr = &secondFrameBuffer[OLED_WIDTH];
|
||||||
|
|
||||||
uint32_t totalDuration = 50; // 500ms
|
uint32_t totalDuration = 50; // 500ms
|
||||||
uint32_t duration = 0;
|
uint32_t duration = 0;
|
||||||
uint32_t start = xTaskGetTickCount();
|
uint32_t start = xTaskGetTickCount();
|
||||||
uint8_t offset = 0;
|
uint8_t offset = 0;
|
||||||
|
|
||||||
while (duration <= totalDuration) {
|
while (duration <= totalDuration) {
|
||||||
duration = xTaskGetTickCount() - start;
|
duration = xTaskGetTickCount() - start;
|
||||||
uint8_t progress = duration * TICKS_SECOND / totalDuration;
|
uint8_t progress = duration * TICKS_SECOND / 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) {
|
||||||
progress = OLED_WIDTH;
|
progress = OLED_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When forward, current contents move to the left out.
|
// When forward, current contents move to the left out.
|
||||||
// Otherwise the contents move to the right out.
|
// Otherwise the contents move to the right out.
|
||||||
uint8_t oldStart = forwardNavigation ? 0 : progress;
|
uint8_t oldStart = forwardNavigation ? 0 : progress;
|
||||||
uint8_t oldPrevious = forwardNavigation ? progress - offset : offset;
|
uint8_t oldPrevious = forwardNavigation ? progress - offset : offset;
|
||||||
|
|
||||||
// Content from the second framebuffer moves in from the right (forward)
|
// Content from the second framebuffer moves in from the right (forward)
|
||||||
// or from the left (not forward).
|
// or from the left (not forward).
|
||||||
uint8_t newStart = forwardNavigation ? OLED_WIDTH - progress : 0;
|
uint8_t newStart = forwardNavigation ? OLED_WIDTH - progress : 0;
|
||||||
uint8_t newEnd = forwardNavigation ? 0 : OLED_WIDTH - progress;
|
uint8_t newEnd = forwardNavigation ? 0 : OLED_WIDTH - progress;
|
||||||
|
|
||||||
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], OLED_WIDTH - progress);
|
||||||
memmove(&secondStripPtr[oldStart], &secondStripPtr[oldPrevious],
|
|
||||||
OLED_WIDTH - progress);
|
|
||||||
|
|
||||||
memmove(&firstStripPtr[newStart], &firstBackStripPtr[newEnd], progress);
|
memmove(&firstStripPtr[newStart], &firstBackStripPtr[newEnd], progress);
|
||||||
memmove(&secondStripPtr[newStart], &secondBackStripPtr[newEnd], progress);
|
memmove(&secondStripPtr[newStart], &secondBackStripPtr[newEnd], progress);
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
osDelay(40);
|
osDelay(40);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OLED::useSecondaryFramebuffer(bool useSecondary) {
|
void OLED::useSecondaryFramebuffer(bool useSecondary) {
|
||||||
if (useSecondary) {
|
if (useSecondary) {
|
||||||
setFramebuffer(secondFrameBuffer);
|
setFramebuffer(secondFrameBuffer);
|
||||||
} else {
|
} else {
|
||||||
setFramebuffer(NULL);
|
setFramebuffer(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OLED::setRotation(bool leftHanded) {
|
void OLED::setRotation(bool leftHanded) {
|
||||||
#ifdef OLED_FLIP
|
#ifdef OLED_FLIP
|
||||||
leftHanded = !leftHanded;
|
leftHanded = !leftHanded;
|
||||||
#endif
|
#endif
|
||||||
if (inLeftHandedMode == leftHanded) {
|
if (inLeftHandedMode == leftHanded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send command struct again with changes
|
// send command struct again with changes
|
||||||
if (leftHanded) {
|
if (leftHanded) {
|
||||||
OLED_Setup_Array[5].val = 0xC8; // c1?
|
OLED_Setup_Array[5].val = 0xC8; // c1?
|
||||||
OLED_Setup_Array[9].val = 0xA1;
|
OLED_Setup_Array[9].val = 0xA1;
|
||||||
} else {
|
} else {
|
||||||
OLED_Setup_Array[5].val = 0xC0;
|
OLED_Setup_Array[5].val = 0xC0;
|
||||||
OLED_Setup_Array[9].val = 0xA0;
|
OLED_Setup_Array[9].val = 0xA0;
|
||||||
}
|
}
|
||||||
FRToSI2C::writeRegistersBulk(DEVICEADDR_OLED, OLED_Setup_Array, sizeof(OLED_Setup_Array) / sizeof(OLED_Setup_Array[0]));
|
FRToSI2C::writeRegistersBulk(DEVICEADDR_OLED, OLED_Setup_Array, sizeof(OLED_Setup_Array) / sizeof(OLED_Setup_Array[0]));
|
||||||
|
|
||||||
inLeftHandedMode = leftHanded;
|
inLeftHandedMode = leftHanded;
|
||||||
|
|
||||||
screenBuffer[5] = inLeftHandedMode ? 0 : 32; // display is shifted by 32 in left handed
|
screenBuffer[5] = inLeftHandedMode ? 0 : 32; // display is shifted by 32 in left handed
|
||||||
// mode as driver ram is 128 wide
|
// mode as driver ram is 128 wide
|
||||||
screenBuffer[7] = inLeftHandedMode ? 95 : 0x7F; // End address of the ram segment we are writing to (96 wide)
|
screenBuffer[7] = inLeftHandedMode ? 95 : 0x7F; // End address of the ram segment we are writing to (96 wide)
|
||||||
screenBuffer[9] = inLeftHandedMode ? 0xC8 : 0xC0;
|
screenBuffer[9] = inLeftHandedMode ? 0xC8 : 0xC0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print a string to the current cursor location
|
// print a string to the current cursor location
|
||||||
void OLED::print(const char *str) {
|
void OLED::print(const char *str) {
|
||||||
while (str[0]) {
|
while (str[0]) {
|
||||||
drawChar(str[0]);
|
drawChar(str[0]);
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OLED::setFont(uint8_t fontNumber) {
|
void OLED::setFont(uint8_t fontNumber) {
|
||||||
if (fontNumber == 1) {
|
if (fontNumber == 1) {
|
||||||
// small font
|
// small font
|
||||||
currentFont = USER_FONT_6x8;
|
currentFont = USER_FONT_6x8;
|
||||||
fontHeight = 8;
|
fontHeight = 8;
|
||||||
fontWidth = 6;
|
fontWidth = 6;
|
||||||
} else if (fontNumber == 2) {
|
} else if (fontNumber == 2) {
|
||||||
currentFont = ExtraFontChars;
|
currentFont = ExtraFontChars;
|
||||||
fontHeight = 16;
|
fontHeight = 16;
|
||||||
fontWidth = 12;
|
fontWidth = 12;
|
||||||
} else {
|
} else {
|
||||||
currentFont = USER_FONT_12;
|
currentFont = USER_FONT_12;
|
||||||
fontHeight = 16;
|
fontHeight = 16;
|
||||||
fontWidth = 12;
|
fontWidth = 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint8_t OLED::getFont() {
|
uint8_t OLED::getFont() {
|
||||||
if (currentFont == USER_FONT_6x8)
|
if (currentFont == USER_FONT_6x8)
|
||||||
return 1;
|
return 1;
|
||||||
else if (currentFont == ExtraFontChars)
|
else if (currentFont == ExtraFontChars)
|
||||||
return 2;
|
return 2;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
inline void stripLeaderZeros(char *buffer, uint8_t places) {
|
inline void stripLeaderZeros(char *buffer, uint8_t places) {
|
||||||
//Removing the leading zero's by swapping them to SymbolSpace
|
// Removing the leading zero's by swapping them to SymbolSpace
|
||||||
// Stop 1 short so that we dont blank entire number if its zero
|
// Stop 1 short so that we dont blank entire number if its zero
|
||||||
for (int i = 0; i < (places - 1); i++) {
|
for (int i = 0; i < (places - 1); i++) {
|
||||||
if (buffer[i] == 2) {
|
if (buffer[i] == 2) {
|
||||||
buffer[i] = SymbolSpace[0];
|
buffer[i] = SymbolSpace[0];
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// maximum places is 5
|
// maximum places is 5
|
||||||
void OLED::printNumber(uint16_t number, uint8_t places, bool noLeaderZeros) {
|
void OLED::printNumber(uint16_t number, uint8_t places, bool noLeaderZeros) {
|
||||||
char buffer[7] = { 0 };
|
char buffer[7] = {0};
|
||||||
|
|
||||||
if (places >= 5) {
|
if (places >= 5) {
|
||||||
buffer[5] = 2 + number % 10;
|
buffer[5] = 2 + number % 10;
|
||||||
number /= 10;
|
number /= 10;
|
||||||
}
|
}
|
||||||
if (places > 4) {
|
if (places > 4) {
|
||||||
buffer[4] = 2 + number % 10;
|
buffer[4] = 2 + number % 10;
|
||||||
number /= 10;
|
number /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (places > 3) {
|
if (places > 3) {
|
||||||
buffer[3] = 2 + number % 10;
|
buffer[3] = 2 + number % 10;
|
||||||
number /= 10;
|
number /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (places > 2) {
|
if (places > 2) {
|
||||||
buffer[2] = 2 + number % 10;
|
buffer[2] = 2 + number % 10;
|
||||||
number /= 10;
|
number /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (places > 1) {
|
if (places > 1) {
|
||||||
buffer[1] = 2 + number % 10;
|
buffer[1] = 2 + number % 10;
|
||||||
number /= 10;
|
number /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[0] = 2 + number % 10;
|
buffer[0] = 2 + number % 10;
|
||||||
if (noLeaderZeros)
|
if (noLeaderZeros)
|
||||||
stripLeaderZeros(buffer, places);
|
stripLeaderZeros(buffer, places);
|
||||||
print(buffer);
|
print(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OLED::debugNumber(int32_t val) {
|
void OLED::debugNumber(int32_t val) {
|
||||||
if (abs(val) > 99999) {
|
if (abs(val) > 99999) {
|
||||||
OLED::print(SymbolSpace); // out of bounds
|
OLED::print(SymbolSpace); // out of bounds
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (val >= 0) {
|
if (val >= 0) {
|
||||||
OLED::print(SymbolSpace);
|
OLED::print(SymbolSpace);
|
||||||
OLED::printNumber(val, 5);
|
OLED::printNumber(val, 5);
|
||||||
} else {
|
} else {
|
||||||
OLED::print(SymbolMinus);
|
OLED::print(SymbolMinus);
|
||||||
OLED::printNumber(-val, 5);
|
OLED::printNumber(-val, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OLED::drawSymbol(uint8_t symbolID) {
|
void OLED::drawSymbol(uint8_t symbolID) {
|
||||||
// draw a symbol to the current cursor location
|
// draw a symbol to the current cursor location
|
||||||
setFont(2);
|
setFont(2);
|
||||||
drawChar(symbolID + 2);
|
drawChar(symbolID + 2);
|
||||||
setFont(0);
|
setFont(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw an area, but y must be aligned on 0/8 offset
|
// Draw an area, but y must be aligned on 0/8 offset
|
||||||
void OLED::drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t *ptr) {
|
void OLED::drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t *ptr) {
|
||||||
// Splat this from x->x+wide in two strides
|
// Splat this from x->x+wide in two strides
|
||||||
if (x <= -wide)
|
if (x <= -wide)
|
||||||
return; // cutoffleft
|
return; // cutoffleft
|
||||||
if (x > 96)
|
if (x > 96)
|
||||||
return; // cutoff right
|
return; // cutoff right
|
||||||
|
|
||||||
uint8_t visibleStart = 0;
|
uint8_t visibleStart = 0;
|
||||||
uint8_t visibleEnd = wide;
|
uint8_t visibleEnd = wide;
|
||||||
|
|
||||||
// trimming to draw partials
|
// trimming to draw partials
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
visibleStart -= x; // subtract negative value == add absolute value
|
visibleStart -= x; // subtract negative value == add absolute value
|
||||||
}
|
}
|
||||||
if (x + wide > 96) {
|
if (x + wide > 96) {
|
||||||
visibleEnd = 96 - x;
|
visibleEnd = 96 - x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y == 0) {
|
if (y == 0) {
|
||||||
// Splat first line of data
|
// Splat first line of data
|
||||||
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
|
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
|
||||||
firstStripPtr[xx + x] = ptr[xx];
|
firstStripPtr[xx + x] = ptr[xx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (y == 8 || height == 16) {
|
if (y == 8 || height == 16) {
|
||||||
// Splat the second line
|
// Splat the second line
|
||||||
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
|
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
|
||||||
secondStripPtr[x + xx] = ptr[xx + (height == 16 ? wide : 0)];
|
secondStripPtr[x + xx] = ptr[xx + (height == 16 ? wide : 0)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw an area, but y must be aligned on 0/8 offset
|
// Draw an area, but y must be aligned on 0/8 offset
|
||||||
// For data which has octets swapped in a 16-bit word.
|
// For data which has octets swapped in a 16-bit word.
|
||||||
void OLED::drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t *ptr) {
|
void OLED::drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t *ptr) {
|
||||||
// Splat this from x->x+wide in two strides
|
// Splat this from x->x+wide in two strides
|
||||||
if (x <= -wide)
|
if (x <= -wide)
|
||||||
return; // cutoffleft
|
return; // cutoffleft
|
||||||
if (x > 96)
|
if (x > 96)
|
||||||
return; // cutoff right
|
return; // cutoff right
|
||||||
|
|
||||||
uint8_t visibleStart = 0;
|
uint8_t visibleStart = 0;
|
||||||
uint8_t visibleEnd = wide;
|
uint8_t visibleEnd = wide;
|
||||||
|
|
||||||
// trimming to draw partials
|
// trimming to draw partials
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
visibleStart -= x; // subtract negative value == add absolute value
|
visibleStart -= x; // subtract negative value == add absolute value
|
||||||
}
|
}
|
||||||
if (x + wide > 96) {
|
if (x + wide > 96) {
|
||||||
visibleEnd = 96 - x;
|
visibleEnd = 96 - x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y == 0) {
|
if (y == 0) {
|
||||||
// Splat first line of data
|
// Splat first line of data
|
||||||
for (uint8_t xx = visibleStart; xx < visibleEnd; xx += 2) {
|
for (uint8_t xx = visibleStart; xx < visibleEnd; xx += 2) {
|
||||||
firstStripPtr[xx + x] = ptr[xx + 1];
|
firstStripPtr[xx + x] = ptr[xx + 1];
|
||||||
firstStripPtr[xx + x + 1] = ptr[xx];
|
firstStripPtr[xx + x + 1] = ptr[xx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (y == 8 || height == 16) {
|
if (y == 8 || height == 16) {
|
||||||
// Splat the second line
|
// Splat the second line
|
||||||
for (uint8_t xx = visibleStart; xx < visibleEnd; xx += 2) {
|
for (uint8_t xx = visibleStart; xx < visibleEnd; xx += 2) {
|
||||||
secondStripPtr[x + xx] = ptr[xx + 1 + (height == 16 ? wide : 0)];
|
secondStripPtr[x + xx] = ptr[xx + 1 + (height == 16 ? wide : 0)];
|
||||||
secondStripPtr[x + xx + 1] = ptr[xx + (height == 16 ? wide : 0)];
|
secondStripPtr[x + xx + 1] = ptr[xx + (height == 16 ? wide : 0)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OLED::fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t value) {
|
void OLED::fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t value) {
|
||||||
// Splat this from x->x+wide in two strides
|
// Splat this from x->x+wide in two strides
|
||||||
if (x <= -wide)
|
if (x <= -wide)
|
||||||
return; // cutoffleft
|
return; // cutoffleft
|
||||||
if (x > 96)
|
if (x > 96)
|
||||||
return; // cutoff right
|
return; // cutoff right
|
||||||
|
|
||||||
uint8_t visibleStart = 0;
|
uint8_t visibleStart = 0;
|
||||||
uint8_t visibleEnd = wide;
|
uint8_t visibleEnd = wide;
|
||||||
|
|
||||||
// trimming to draw partials
|
// trimming to draw partials
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
visibleStart -= x; // subtract negative value == add absolute value
|
visibleStart -= x; // subtract negative value == add absolute value
|
||||||
}
|
}
|
||||||
if (x + wide > 96) {
|
if (x + wide > 96) {
|
||||||
visibleEnd = 96 - x;
|
visibleEnd = 96 - x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y == 0) {
|
if (y == 0) {
|
||||||
// Splat first line of data
|
// Splat first line of data
|
||||||
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
|
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
|
||||||
firstStripPtr[xx + x] = value;
|
firstStripPtr[xx + x] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (y == 8 || height == 16) {
|
if (y == 8 || height == 16) {
|
||||||
// Splat the second line
|
// Splat the second line
|
||||||
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
|
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
|
||||||
secondStripPtr[x + xx] = value;
|
secondStripPtr[x + xx] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OLED::drawFilledRect(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, bool clear) {
|
void OLED::drawFilledRect(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, bool clear) {
|
||||||
// Draw this in 3 sections
|
// Draw this in 3 sections
|
||||||
// This is basically a N wide version of vertical line
|
// This is basically a N wide version of vertical line
|
||||||
|
|
||||||
// Step 1 : Draw in the top few pixels that are not /8 aligned
|
// Step 1 : Draw in the top few pixels that are not /8 aligned
|
||||||
// LSB is at the top of the screen
|
// LSB is at the top of the screen
|
||||||
uint8_t mask = 0xFF;
|
uint8_t mask = 0xFF;
|
||||||
if (y0) {
|
if (y0) {
|
||||||
mask = mask << (y0 % 8);
|
mask = mask << (y0 % 8);
|
||||||
for (uint8_t col = x0; col < x1; col++)
|
for (uint8_t col = x0; col < x1; col++)
|
||||||
if (clear)
|
if (clear)
|
||||||
firstStripPtr[(y0 / 8) * 96 + col] &= ~mask;
|
firstStripPtr[(y0 / 8) * 96 + col] &= ~mask;
|
||||||
else
|
else
|
||||||
firstStripPtr[(y0 / 8) * 96 + col] |= mask;
|
firstStripPtr[(y0 / 8) * 96 + col] |= mask;
|
||||||
}
|
}
|
||||||
// Next loop down the line the total number of solids
|
// Next loop down the line the total number of solids
|
||||||
if (y0 / 8 != y1 / 8)
|
if (y0 / 8 != y1 / 8)
|
||||||
for (uint8_t col = x0; col < x1; col++)
|
for (uint8_t col = x0; col < x1; col++)
|
||||||
for (uint8_t r = (y0 / 8); r < (y1 / 8); r++) {
|
for (uint8_t r = (y0 / 8); r < (y1 / 8); r++) {
|
||||||
// This gives us the row index r
|
// This gives us the row index r
|
||||||
if (clear)
|
if (clear)
|
||||||
firstStripPtr[(r * 96) + col] = 0;
|
firstStripPtr[(r * 96) + col] = 0;
|
||||||
else
|
else
|
||||||
firstStripPtr[(r * 96) + col] = 0xFF;
|
firstStripPtr[(r * 96) + col] = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally draw the tail
|
// Finally draw the tail
|
||||||
mask = ~(mask << (y1 % 8));
|
mask = ~(mask << (y1 % 8));
|
||||||
for (uint8_t col = x0; col < x1; col++)
|
for (uint8_t col = x0; col < x1; col++)
|
||||||
if (clear)
|
if (clear)
|
||||||
firstStripPtr[(y1 / 8) * 96 + col] &= ~mask;
|
firstStripPtr[(y1 / 8) * 96 + col] &= ~mask;
|
||||||
else
|
else
|
||||||
firstStripPtr[(y1 / 8) * 96 + col] |= mask;
|
firstStripPtr[(y1 / 8) * 96 + col] |= mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OLED::drawHeatSymbol(uint8_t state) {
|
void OLED::drawHeatSymbol(uint8_t state) {
|
||||||
// Draw symbol 14
|
// Draw symbol 14
|
||||||
// Then draw over it, the bottom 5 pixels always stay. 8 pixels above that are
|
// Then draw over it, the bottom 5 pixels always stay. 8 pixels above that are
|
||||||
// the levels masks the symbol nicely
|
// the levels masks the symbol nicely
|
||||||
state /= 31; // 0-> 8 range
|
state /= 31; // 0-> 8 range
|
||||||
// Then we want to draw down (16-(5+state)
|
// Then we want to draw down (16-(5+state)
|
||||||
uint8_t cursor_x_temp = cursor_x;
|
uint8_t cursor_x_temp = cursor_x;
|
||||||
drawSymbol(14);
|
drawSymbol(14);
|
||||||
drawFilledRect(cursor_x_temp, 0, cursor_x_temp + 12, 2 + (8 - state), true);
|
drawFilledRect(cursor_x_temp, 0, cursor_x_temp + 12, 2 + (8 - state), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OLED::isInitDone() {
|
bool OLED::isInitDone() { return initDone; }
|
||||||
return initDone;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,60 +10,59 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
bool SC7A20::detect() {
|
bool SC7A20::detect() {
|
||||||
if (FRToSI2C::probe(SC7A20_ADDRESS)) {
|
if (FRToSI2C::probe(SC7A20_ADDRESS)) {
|
||||||
//Read chip id to ensure its not an address collision
|
// Read chip id to ensure its not an address collision
|
||||||
uint8_t id = 0;
|
uint8_t id = 0;
|
||||||
if (FRToSI2C::Mem_Read(SC7A20_ADDRESS, SC7A20_WHO_AMI_I, &id, 1)) {
|
if (FRToSI2C::Mem_Read(SC7A20_ADDRESS, SC7A20_WHO_AMI_I, &id, 1)) {
|
||||||
return id == 0b00010001;
|
return id == 0b00010001;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const FRToSI2C::I2C_REG i2c_registers[] = { //
|
static const FRToSI2C::I2C_REG i2c_registers[] = {
|
||||||
//
|
//
|
||||||
{ SC7A20_CTRL_REG1, 0b01100111, 0 }, //200Hz, XYZ enabled
|
//
|
||||||
{ SC7A20_CTRL_REG2, 0b00000000, 0 }, //Setup filter to 0x00 ??
|
{SC7A20_CTRL_REG1, 0b01100111, 0}, // 200Hz, XYZ enabled
|
||||||
{ SC7A20_CTRL_REG3, 0b00000000, 0 }, //int1 off
|
{SC7A20_CTRL_REG2, 0b00000000, 0}, // Setup filter to 0x00 ??
|
||||||
{ SC7A20_CTRL_REG4, 0b01001000, 0 }, //Block mode off,little-endian,2G,High-pres,self test off
|
{SC7A20_CTRL_REG3, 0b00000000, 0}, // int1 off
|
||||||
{ SC7A20_CTRL_REG5, 0b00000100, 0 }, //fifo off, D4D on int1
|
{SC7A20_CTRL_REG4, 0b01001000, 0}, // Block mode off,little-endian,2G,High-pres,self test off
|
||||||
{ SC7A20_CTRL_REG6, 0x00, 0 }, //INT2 off
|
{SC7A20_CTRL_REG5, 0b00000100, 0}, // fifo off, D4D on int1
|
||||||
//Basically setup the unit to run, and enable 4D orientation detection
|
{SC7A20_CTRL_REG6, 0x00, 0}, // INT2 off
|
||||||
{ SC7A20_INT2_CFG, 0b01111110, 0 }, //setup for movement detection
|
// Basically setup the unit to run, and enable 4D orientation detection
|
||||||
{ SC7A20_INT2_THS, 0x28, 0 }, //
|
{SC7A20_INT2_CFG, 0b01111110, 0}, // setup for movement detection
|
||||||
{ SC7A20_INT2_DURATION, 64, 0 }, //
|
{SC7A20_INT2_THS, 0x28, 0}, //
|
||||||
{ SC7A20_INT1_CFG, 0b01111110, 0 }, //
|
{SC7A20_INT2_DURATION, 64, 0}, //
|
||||||
{ SC7A20_INT1_THS, 0x28, 0 }, //
|
{SC7A20_INT1_CFG, 0b01111110, 0}, //
|
||||||
{ SC7A20_INT1_DURATION, 64, 0 }
|
{SC7A20_INT1_THS, 0x28, 0}, //
|
||||||
|
{SC7A20_INT1_DURATION, 64, 0}
|
||||||
|
|
||||||
//
|
//
|
||||||
};
|
};
|
||||||
bool SC7A20::initalize() {
|
bool SC7A20::initalize() {
|
||||||
//Setup acceleration readings
|
// Setup acceleration readings
|
||||||
//2G range
|
// 2G range
|
||||||
//bandwidth = 250Hz
|
// bandwidth = 250Hz
|
||||||
//High pass filter on (Slow compensation)
|
// High pass filter on (Slow compensation)
|
||||||
//Turn off IRQ output pins
|
// Turn off IRQ output pins
|
||||||
//Orientation recognition in symmetrical mode
|
// Orientation recognition in symmetrical mode
|
||||||
// Hysteresis is set to ~ 16 counts
|
// Hysteresis is set to ~ 16 counts
|
||||||
//Theta blocking is set to 0b10
|
// Theta blocking is set to 0b10
|
||||||
|
|
||||||
return FRToSI2C::writeRegistersBulk(SC7A20_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
|
||||||
|
|
||||||
|
return FRToSI2C::writeRegistersBulk(SC7A20_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SC7A20::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
void SC7A20::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
||||||
//We can tell the accelerometer to output in LE mode which makes this simple
|
// We can tell the accelerometer to output in LE mode which makes this simple
|
||||||
uint16_t sensorData[3] = { 0, 0, 0 };
|
uint16_t sensorData[3] = {0, 0, 0};
|
||||||
|
|
||||||
if (FRToSI2C::Mem_Read(SC7A20_ADDRESS, SC7A20_OUT_X_L, (uint8_t*) sensorData, 6) == false) {
|
|
||||||
x = y = z = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//Shift 6 to make its range ~= the other accelerometers
|
|
||||||
x = sensorData[0];
|
|
||||||
y = sensorData[1];
|
|
||||||
z = sensorData[2];
|
|
||||||
|
|
||||||
|
if (FRToSI2C::Mem_Read(SC7A20_ADDRESS, SC7A20_OUT_X_L, (uint8_t *)sensorData, 6) == false) {
|
||||||
|
x = y = z = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Shift 6 to make its range ~= the other accelerometers
|
||||||
|
x = sensorData[0];
|
||||||
|
y = sensorData[1];
|
||||||
|
z = sensorData[2];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,175 +10,168 @@
|
|||||||
* This class is licensed as MIT to match this code base
|
* This class is licensed as MIT to match this code base
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Si7210.h>
|
|
||||||
#include "Si7210_defines.h"
|
|
||||||
#include "I2C_Wrapper.hpp"
|
#include "I2C_Wrapper.hpp"
|
||||||
bool Si7210::detect() {
|
#include "Si7210_defines.h"
|
||||||
return FRToSI2C::wakePart(SI7210_ADDRESS);
|
#include <Si7210.h>
|
||||||
|
bool Si7210::detect() { return FRToSI2C::wakePart(SI7210_ADDRESS); }
|
||||||
}
|
|
||||||
|
|
||||||
bool Si7210::init() {
|
bool Si7210::init() {
|
||||||
//Turn on auto increment and sanity check ID
|
// Turn on auto increment and sanity check ID
|
||||||
//Load OTP cal
|
// Load OTP cal
|
||||||
|
|
||||||
uint8_t temp;
|
uint8_t temp;
|
||||||
if (FRToSI2C::Mem_Read(SI7210_ADDRESS, SI7210_REG_ID, &temp, 1)) {
|
if (FRToSI2C::Mem_Read(SI7210_ADDRESS, SI7210_REG_ID, &temp, 1)) {
|
||||||
// We don't really care what model it is etc, just probing to check its probably this iC
|
// We don't really care what model it is etc, just probing to check its probably this iC
|
||||||
if (temp != 0x00 && temp != 0xFF) {
|
if (temp != 0x00 && temp != 0xFF) {
|
||||||
temp = 0x00;
|
temp = 0x00;
|
||||||
|
|
||||||
/* Set device and internal driver settings */
|
/* Set device and internal driver settings */
|
||||||
if (!write_reg( SI7210_CTRL1, (uint8_t) ~SW_LOW4FIELD_MASK, 0)) {
|
if (!write_reg(SI7210_CTRL1, (uint8_t)~SW_LOW4FIELD_MASK, 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable periodic auto-wakeup by device, and tamper detect. */
|
/* Disable periodic auto-wakeup by device, and tamper detect. */
|
||||||
if ((!write_reg(SI7210_CTRL3, (uint8_t) ~SL_TIMEENA_MASK, 0)))
|
if ((!write_reg(SI7210_CTRL3, (uint8_t)~SL_TIMEENA_MASK, 0)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Disable tamper detection by setting sw_tamper to 63 */
|
/* Disable tamper detection by setting sw_tamper to 63 */
|
||||||
if (!write_reg(SI7210_CTRL3, SL_FAST_MASK | SL_TIMEENA_MASK, 63 << 2))
|
if (!write_reg(SI7210_CTRL3, SL_FAST_MASK | SL_TIMEENA_MASK, 63 << 2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!set_high_range())
|
if (!set_high_range())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Stop the control loop by setting stop bit */
|
/* Stop the control loop by setting stop bit */
|
||||||
if (!write_reg( SI7210_POWER_CTRL, MEAS_MASK | USESTORE_MASK, STOP_MASK)) /* WARNING: Removed USE_STORE MASK */
|
if (!write_reg(SI7210_POWER_CTRL, MEAS_MASK | USESTORE_MASK, STOP_MASK)) /* WARNING: Removed USE_STORE MASK */
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Use a burst size of 128/4096 samples in FIR and IIR modes */
|
/* Use a burst size of 128/4096 samples in FIR and IIR modes */
|
||||||
if (!write_reg(SI7210_CTRL4, 0, DF_BURSTSIZE_128 | DF_BW_4096))
|
if (!write_reg(SI7210_CTRL4, 0, DF_BURSTSIZE_128 | DF_BW_4096))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Select field strength measurement */
|
/* Select field strength measurement */
|
||||||
if (!write_reg( SI7210_DSPSIGSEL, 0, DSP_SIGSEL_FIELD_MASK))
|
if (!write_reg(SI7210_DSPSIGSEL, 0, DSP_SIGSEL_FIELD_MASK))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true; //start_periodic_measurement();
|
return true; // start_periodic_measurement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t Si7210::read() {
|
int16_t Si7210::read() {
|
||||||
//Read the two regs
|
// Read the two regs
|
||||||
int16_t temp = 0;
|
int16_t temp = 0;
|
||||||
if (!get_field_strength(&temp)) {
|
if (!get_field_strength(&temp)) {
|
||||||
temp = 0;
|
temp = 0;
|
||||||
}
|
}
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Si7210::write_reg(const uint8_t reg, const uint8_t mask, const uint8_t val) {
|
bool Si7210::write_reg(const uint8_t reg, const uint8_t mask, const uint8_t val) {
|
||||||
uint8_t temp = 0;
|
uint8_t temp = 0;
|
||||||
if (mask) {
|
if (mask) {
|
||||||
if (!read_reg(reg, &temp)) {
|
if (!read_reg(reg, &temp)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
temp &= mask;
|
temp &= mask;
|
||||||
}
|
}
|
||||||
temp |= val;
|
temp |= val;
|
||||||
return FRToSI2C::Mem_Write(SI7210_ADDRESS, reg, &temp, 1);
|
return FRToSI2C::Mem_Write(SI7210_ADDRESS, reg, &temp, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Si7210::read_reg(const uint8_t reg, uint8_t* val) {
|
bool Si7210::read_reg(const uint8_t reg, uint8_t *val) { return FRToSI2C::Mem_Read(SI7210_ADDRESS, reg, val, 1); }
|
||||||
return FRToSI2C::Mem_Read(SI7210_ADDRESS, reg, val, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Si7210::start_periodic_measurement() {
|
bool Si7210::start_periodic_measurement() {
|
||||||
/* Enable periodic wakeup */
|
/* Enable periodic wakeup */
|
||||||
if (!write_reg(SI7210_CTRL3, (uint8_t) ~SL_TIMEENA_MASK, SL_TIMEENA_MASK))
|
if (!write_reg(SI7210_CTRL3, (uint8_t)~SL_TIMEENA_MASK, SL_TIMEENA_MASK))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Start measurement */
|
|
||||||
/* Change to ~STOP_MASK with STOP_MASK */
|
|
||||||
return write_reg( SI7210_POWER_CTRL, MEAS_MASK | USESTORE_MASK, 0);
|
|
||||||
|
|
||||||
|
/* Start measurement */
|
||||||
|
/* Change to ~STOP_MASK with STOP_MASK */
|
||||||
|
return write_reg(SI7210_POWER_CTRL, MEAS_MASK | USESTORE_MASK, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Si7210::get_field_strength(int16_t* field) {
|
bool Si7210::get_field_strength(int16_t *field) {
|
||||||
*field = 0;
|
*field = 0;
|
||||||
uint8_t val = 0;
|
uint8_t val = 0;
|
||||||
FRToSI2C::wakePart(SI7210_ADDRESS);
|
FRToSI2C::wakePart(SI7210_ADDRESS);
|
||||||
|
|
||||||
if (!write_reg( SI7210_POWER_CTRL, MEAS_MASK | USESTORE_MASK, STOP_MASK))
|
if (!write_reg(SI7210_POWER_CTRL, MEAS_MASK | USESTORE_MASK, STOP_MASK))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Read most-significant byte */
|
/* Read most-significant byte */
|
||||||
if (!read_reg( SI7210_DSPSIGM, &val))
|
if (!read_reg(SI7210_DSPSIGM, &val))
|
||||||
return false;
|
return false;
|
||||||
*field = (val & DSP_SIGM_DATA_MASK) << 8;
|
*field = (val & DSP_SIGM_DATA_MASK) << 8;
|
||||||
|
|
||||||
/* Read least-significant byte of data */
|
/* Read least-significant byte of data */
|
||||||
if (!read_reg( SI7210_DSPSIGL, &val))
|
if (!read_reg(SI7210_DSPSIGL, &val))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*field += val;
|
*field += val;
|
||||||
*field -= 16384U;
|
*field -= 16384U;
|
||||||
//field is now a +- measurement
|
// field is now a +- measurement
|
||||||
//In units of 0.0125 mT
|
// In units of 0.0125 mT
|
||||||
// Aka 12.5uT
|
// Aka 12.5uT
|
||||||
//Clear flags
|
// Clear flags
|
||||||
read_reg( SI7210_CTRL1, &val);
|
read_reg(SI7210_CTRL1, &val);
|
||||||
read_reg( SI7210_CTRL2, &val);
|
read_reg(SI7210_CTRL2, &val);
|
||||||
//Start next one
|
// Start next one
|
||||||
|
|
||||||
/* Use a burst size of 128/4096 samples in FIR and IIR modes */
|
/* Use a burst size of 128/4096 samples in FIR and IIR modes */
|
||||||
write_reg( SI7210_CTRL4, 0, DF_BURSTSIZE_128 | DF_BW_4096);
|
write_reg(SI7210_CTRL4, 0, DF_BURSTSIZE_128 | DF_BW_4096);
|
||||||
|
|
||||||
/* Selet field strength measurement */
|
/* Selet field strength measurement */
|
||||||
write_reg( SI7210_DSPSIGSEL, 0, DSP_SIGSEL_FIELD_MASK);
|
write_reg(SI7210_DSPSIGSEL, 0, DSP_SIGSEL_FIELD_MASK);
|
||||||
|
|
||||||
/* Start measurement */
|
/* Start measurement */
|
||||||
write_reg( SI7210_POWER_CTRL, MEAS_MASK | USESTORE_MASK, ONEBURST_MASK);
|
write_reg(SI7210_POWER_CTRL, MEAS_MASK | USESTORE_MASK, ONEBURST_MASK);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Si7210::set_high_range() {
|
bool Si7210::set_high_range() {
|
||||||
//To set the unit into 200mT range, no magnet temperature calibration
|
// To set the unit into 200mT range, no magnet temperature calibration
|
||||||
// We want to copy OTP 0x27->0x2C into a0->a5
|
// We want to copy OTP 0x27->0x2C into a0->a5
|
||||||
uint8_t base_addr = 0x27; // You can change this to pick the temp calibration
|
uint8_t base_addr = 0x27; // You can change this to pick the temp calibration
|
||||||
bool worked = true;
|
bool worked = true;
|
||||||
uint8_t val = 0;
|
uint8_t val = 0;
|
||||||
|
|
||||||
/* Load A0 register */
|
/* Load A0 register */
|
||||||
worked &= write_reg( SI7210_OTP_ADDR, 0, base_addr);
|
worked &= write_reg(SI7210_OTP_ADDR, 0, base_addr);
|
||||||
worked &= write_reg( SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
worked &= write_reg(SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
||||||
worked &= read_reg( SI7210_OTP_DATA, &val);
|
worked &= read_reg(SI7210_OTP_DATA, &val);
|
||||||
worked &= write_reg( SI7210_A0, 0, val);
|
worked &= write_reg(SI7210_A0, 0, val);
|
||||||
|
|
||||||
/* Load A1 register */
|
/* Load A1 register */
|
||||||
worked &= write_reg( SI7210_OTP_ADDR, 0, base_addr + 1);
|
worked &= write_reg(SI7210_OTP_ADDR, 0, base_addr + 1);
|
||||||
worked &= write_reg( SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
worked &= write_reg(SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
||||||
worked &= read_reg( SI7210_OTP_DATA, &val);
|
worked &= read_reg(SI7210_OTP_DATA, &val);
|
||||||
worked &= write_reg( SI7210_A1, 0, val);
|
worked &= write_reg(SI7210_A1, 0, val);
|
||||||
|
|
||||||
/* Load A2 register */
|
/* Load A2 register */
|
||||||
worked &= write_reg( SI7210_OTP_ADDR, 0, base_addr + 2);
|
worked &= write_reg(SI7210_OTP_ADDR, 0, base_addr + 2);
|
||||||
worked &= write_reg( SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
worked &= write_reg(SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
||||||
worked &= read_reg( SI7210_OTP_DATA, &val);
|
worked &= read_reg(SI7210_OTP_DATA, &val);
|
||||||
worked &= write_reg( SI7210_A2, 0, val);
|
worked &= write_reg(SI7210_A2, 0, val);
|
||||||
|
|
||||||
/* Load A3 register */
|
/* Load A3 register */
|
||||||
worked &= write_reg( SI7210_OTP_ADDR, 0, base_addr + 3);
|
worked &= write_reg(SI7210_OTP_ADDR, 0, base_addr + 3);
|
||||||
worked &= write_reg( SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
worked &= write_reg(SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
||||||
worked &= read_reg( SI7210_OTP_DATA, &val);
|
worked &= read_reg(SI7210_OTP_DATA, &val);
|
||||||
worked &= write_reg( SI7210_A3, 0, val);
|
worked &= write_reg(SI7210_A3, 0, val);
|
||||||
|
|
||||||
/* Load A4 register */
|
/* Load A4 register */
|
||||||
worked &= write_reg( SI7210_OTP_ADDR, 0, base_addr + 4);
|
worked &= write_reg(SI7210_OTP_ADDR, 0, base_addr + 4);
|
||||||
worked &= write_reg( SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
worked &= write_reg(SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
||||||
worked &= read_reg( SI7210_OTP_DATA, &val);
|
worked &= read_reg(SI7210_OTP_DATA, &val);
|
||||||
worked &= write_reg( SI7210_A4, 0, val);
|
worked &= write_reg(SI7210_A4, 0, val);
|
||||||
|
|
||||||
/* Load A5 register */
|
/* Load A5 register */
|
||||||
worked &= write_reg( SI7210_OTP_ADDR, 0, base_addr + 5);
|
worked &= write_reg(SI7210_OTP_ADDR, 0, base_addr + 5);
|
||||||
worked &= write_reg( SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
worked &= write_reg(SI7210_OTP_CTRL, 0, OTP_READ_EN_MASK);
|
||||||
worked &= read_reg( SI7210_OTP_DATA, &val);
|
worked &= read_reg(SI7210_OTP_DATA, &val);
|
||||||
worked &= write_reg( SI7210_A5, 0, val);
|
worked &= write_reg(SI7210_A5, 0, val);
|
||||||
return worked;
|
return worked;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TipThermoModel.h"
|
#include "TipThermoModel.h"
|
||||||
#include "Settings.h"
|
|
||||||
#include "BSP.h"
|
|
||||||
#include "power.hpp"
|
|
||||||
#include "../../configuration.h"
|
#include "../../configuration.h"
|
||||||
|
#include "BSP.h"
|
||||||
|
#include "Settings.h"
|
||||||
#include "main.hpp"
|
#include "main.hpp"
|
||||||
|
#include "power.hpp"
|
||||||
/*
|
/*
|
||||||
* The hardware is laid out as a non-inverting op-amp
|
* The hardware is laid out as a non-inverting op-amp
|
||||||
* There is a pullup of 39k(TS100) from the +ve input to 3.9V (1M pulup on TS100)
|
* There is a pullup of 39k(TS100) from the +ve input to 3.9V (1M pulup on TS100)
|
||||||
@@ -29,217 +29,211 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
uint32_t valueuV = rawInputmVX10 * 100; // shift into uV
|
uint32_t valueuV = rawInputmVX10 * 100; // shift into uV
|
||||||
//Now to divide this down by the gain
|
// Now to divide this down by the gain
|
||||||
valueuV /= OP_AMP_GAIN_STAGE;
|
valueuV /= OP_AMP_GAIN_STAGE;
|
||||||
|
|
||||||
if (systemSettings.CalibrationOffset) {
|
if (systemSettings.CalibrationOffset) {
|
||||||
//Remove uV tipOffset
|
// Remove uV tipOffset
|
||||||
if (valueuV >= systemSettings.CalibrationOffset)
|
if (valueuV >= systemSettings.CalibrationOffset)
|
||||||
valueuV -= systemSettings.CalibrationOffset;
|
valueuV -= systemSettings.CalibrationOffset;
|
||||||
else
|
else
|
||||||
valueuV = 0;
|
valueuV = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return valueuV;
|
return valueuV;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t TipThermoModel::convertTipRawADCToDegC(uint16_t rawADC) {
|
uint32_t TipThermoModel::convertTipRawADCToDegC(uint16_t rawADC) { return convertuVToDegC(convertTipRawADCTouV(rawADC)); }
|
||||||
return convertuVToDegC(convertTipRawADCTouV(rawADC));
|
|
||||||
}
|
|
||||||
#ifdef ENABLED_FAHRENHEIT_SUPPORT
|
#ifdef ENABLED_FAHRENHEIT_SUPPORT
|
||||||
uint32_t TipThermoModel::convertTipRawADCToDegF(uint16_t rawADC) {
|
uint32_t TipThermoModel::convertTipRawADCToDegF(uint16_t rawADC) { return convertuVToDegF(convertTipRawADCTouV(rawADC)); }
|
||||||
return convertuVToDegF(convertTipRawADCTouV(rawADC));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Table that is designed to be walked to find the best sample for the lookup
|
// Table that is designed to be walked to find the best sample for the lookup
|
||||||
|
|
||||||
//Extrapolate between two points
|
// Extrapolate between two points
|
||||||
// [x1, y1] = point 1
|
// [x1, y1] = point 1
|
||||||
// [x2, y2] = point 2
|
// [x2, y2] = point 2
|
||||||
// x = input value
|
// x = input value
|
||||||
// output is x's interpolated y value
|
// output is x's interpolated y value
|
||||||
int32_t LinearInterpolate(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x) {
|
int32_t LinearInterpolate(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x) { return y1 + (((((x - x1) * 1000) / (x2 - x1)) * (y2 - y1))) / 1000; }
|
||||||
return y1 + (((((x - x1) * 1000) / (x2 - x1)) * (y2 - y1))) / 1000;
|
|
||||||
}
|
|
||||||
#ifdef TEMP_uV_LOOKUP_HAKKO
|
#ifdef TEMP_uV_LOOKUP_HAKKO
|
||||||
const uint16_t uVtoDegC[] = { //
|
const uint16_t uVtoDegC[] = {
|
||||||
//
|
//
|
||||||
0, 0, //
|
//
|
||||||
266, 10, //
|
0, 0, //
|
||||||
522, 20, //
|
266, 10, //
|
||||||
770, 30, //
|
522, 20, //
|
||||||
1010, 40, //
|
770, 30, //
|
||||||
1244, 50, //
|
1010, 40, //
|
||||||
1473, 60, //
|
1244, 50, //
|
||||||
1697, 70, //
|
1473, 60, //
|
||||||
1917, 80, //
|
1697, 70, //
|
||||||
2135, 90, //
|
1917, 80, //
|
||||||
2351, 100, //
|
2135, 90, //
|
||||||
2566, 110, //
|
2351, 100, //
|
||||||
2780, 120, //
|
2566, 110, //
|
||||||
2994, 130, //
|
2780, 120, //
|
||||||
3209, 140, //
|
2994, 130, //
|
||||||
3426, 150, //
|
3209, 140, //
|
||||||
3644, 160, //
|
3426, 150, //
|
||||||
3865, 170, //
|
3644, 160, //
|
||||||
4088, 180, //
|
3865, 170, //
|
||||||
4314, 190, //
|
4088, 180, //
|
||||||
4544, 200, //
|
4314, 190, //
|
||||||
4777, 210, //
|
4544, 200, //
|
||||||
5014, 220, //
|
4777, 210, //
|
||||||
5255, 230, //
|
5014, 220, //
|
||||||
5500, 240, //
|
5255, 230, //
|
||||||
5750, 250, //
|
5500, 240, //
|
||||||
6003, 260, //
|
5750, 250, //
|
||||||
6261, 270, //
|
6003, 260, //
|
||||||
6523, 280, //
|
6261, 270, //
|
||||||
6789, 290, //
|
6523, 280, //
|
||||||
7059, 300, //
|
6789, 290, //
|
||||||
7332, 310, //
|
7059, 300, //
|
||||||
7609, 320, //
|
7332, 310, //
|
||||||
7889, 330, //
|
7609, 320, //
|
||||||
8171, 340, //
|
7889, 330, //
|
||||||
8456, 350, //
|
8171, 340, //
|
||||||
8742, 360, //
|
8456, 350, //
|
||||||
9030, 370, //
|
8742, 360, //
|
||||||
9319, 380, //
|
9030, 370, //
|
||||||
9607, 390, //
|
9319, 380, //
|
||||||
9896, 400, //
|
9607, 390, //
|
||||||
10183, 410, //
|
9896, 400, //
|
||||||
10468, 420, //
|
10183, 410, //
|
||||||
10750, 430, //
|
10468, 420, //
|
||||||
11029, 440, //
|
10750, 430, //
|
||||||
11304, 450, //
|
11029, 440, //
|
||||||
11573, 460, //
|
11304, 450, //
|
||||||
11835, 470, //
|
11573, 460, //
|
||||||
12091, 480, //
|
11835, 470, //
|
||||||
12337, 490, //
|
12091, 480, //
|
||||||
12575, 500, //
|
12337, 490, //
|
||||||
|
12575, 500, //
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TEMP_uV_LOOKUP_TS80
|
#ifdef TEMP_uV_LOOKUP_TS80
|
||||||
|
|
||||||
const uint16_t uVtoDegC[] = { //
|
const uint16_t uVtoDegC[] = {
|
||||||
//
|
//
|
||||||
530 , 0, //
|
//
|
||||||
1282 , 10, //
|
530, 0, //
|
||||||
2034 , 20, //
|
1282, 10, //
|
||||||
2786 , 30, //
|
2034, 20, //
|
||||||
3538 , 40, //
|
2786, 30, //
|
||||||
4290 , 50, //
|
3538, 40, //
|
||||||
5043 , 60, //
|
4290, 50, //
|
||||||
5795 , 70, //
|
5043, 60, //
|
||||||
6547 , 80, //
|
5795, 70, //
|
||||||
7299 , 90, //
|
6547, 80, //
|
||||||
8051 , 100, //
|
7299, 90, //
|
||||||
8803 , 110, //
|
8051, 100, //
|
||||||
9555 , 120, //
|
8803, 110, //
|
||||||
10308 , 130, //
|
9555, 120, //
|
||||||
11060 , 140, //
|
10308, 130, //
|
||||||
11812 , 150, //
|
11060, 140, //
|
||||||
12564 , 160, //
|
11812, 150, //
|
||||||
13316 , 170, //
|
12564, 160, //
|
||||||
14068 , 180, //
|
13316, 170, //
|
||||||
14820 , 190, //
|
14068, 180, //
|
||||||
15573 , 200, //
|
14820, 190, //
|
||||||
16325 , 210, //
|
15573, 200, //
|
||||||
17077 , 220, //
|
16325, 210, //
|
||||||
17829 , 230, //
|
17077, 220, //
|
||||||
18581 , 240, //
|
17829, 230, //
|
||||||
19333 , 250, //
|
18581, 240, //
|
||||||
20085 , 260, //
|
19333, 250, //
|
||||||
20838 , 270, //
|
20085, 260, //
|
||||||
21590 , 280, //
|
20838, 270, //
|
||||||
22342 , 290, //
|
21590, 280, //
|
||||||
23094 , 300, //
|
22342, 290, //
|
||||||
23846 , 310, //
|
23094, 300, //
|
||||||
24598 , 320, //
|
23846, 310, //
|
||||||
25350 , 330, //
|
24598, 320, //
|
||||||
26103 , 340, //
|
25350, 330, //
|
||||||
26855 , 350, //
|
26103, 340, //
|
||||||
27607 , 360, //
|
26855, 350, //
|
||||||
28359 , 370, //
|
27607, 360, //
|
||||||
29111 , 380, //
|
28359, 370, //
|
||||||
29863 , 390, //
|
29111, 380, //
|
||||||
30615 , 400, //
|
29863, 390, //
|
||||||
31368 , 410, //
|
30615, 400, //
|
||||||
32120 , 420, //
|
31368, 410, //
|
||||||
32872 , 430, //
|
32120, 420, //
|
||||||
33624 , 440, //
|
32872, 430, //
|
||||||
34376 , 450, //
|
33624, 440, //
|
||||||
35128 , 460, //
|
34376, 450, //
|
||||||
35880 , 470, //
|
35128, 460, //
|
||||||
36632 , 480, //
|
35880, 470, //
|
||||||
37385 , 490, //
|
36632, 480, //
|
||||||
38137 , 500, //
|
37385, 490, //
|
||||||
};
|
38137, 500, //
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
uint32_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) {
|
uint32_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) {
|
||||||
if (tipuVDelta) {
|
if (tipuVDelta) {
|
||||||
int noItems = sizeof(uVtoDegC) / (2 * sizeof(uint16_t));
|
int noItems = sizeof(uVtoDegC) / (2 * sizeof(uint16_t));
|
||||||
for (int i = 1; i < (noItems - 1); i++) {
|
for (int i = 1; i < (noItems - 1); i++) {
|
||||||
//If current tip temp is less than current lookup, then this current lookup is the higher point to interpolate
|
// If current tip temp is less than current lookup, then this current lookup is the higher point to interpolate
|
||||||
if (tipuVDelta < uVtoDegC[i * 2]) {
|
if (tipuVDelta < uVtoDegC[i * 2]) {
|
||||||
return LinearInterpolate(uVtoDegC[(i - 1) * 2], uVtoDegC[((i - 1) * 2) + 1], uVtoDegC[i * 2], uVtoDegC[(i * 2) + 1], tipuVDelta);
|
return LinearInterpolate(uVtoDegC[(i - 1) * 2], uVtoDegC[((i - 1) * 2) + 1], uVtoDegC[i * 2], uVtoDegC[(i * 2) + 1], tipuVDelta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return LinearInterpolate(uVtoDegC[(noItems - 2) * 2], uVtoDegC[((noItems - 2) * 2) + 1], uVtoDegC[(noItems - 1) * 2], uVtoDegC[((noItems - 1) * 2) + 1], tipuVDelta);
|
return LinearInterpolate(uVtoDegC[(noItems - 2) * 2], uVtoDegC[((noItems - 2) * 2) + 1], uVtoDegC[(noItems - 1) * 2], uVtoDegC[((noItems - 1) * 2) + 1], tipuVDelta);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLED_FAHRENHEIT_SUPPORT
|
#ifdef ENABLED_FAHRENHEIT_SUPPORT
|
||||||
uint32_t TipThermoModel::convertuVToDegF(uint32_t tipuVDelta) {
|
uint32_t TipThermoModel::convertuVToDegF(uint32_t tipuVDelta) { return convertCtoF(convertuVToDegC(tipuVDelta)); }
|
||||||
return convertCtoF(convertuVToDegC(tipuVDelta));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t TipThermoModel::convertCtoF(uint32_t degC) {
|
uint32_t TipThermoModel::convertCtoF(uint32_t degC) {
|
||||||
//(Y °C × 9/5) + 32 =Y°F
|
//(Y °C × 9/5) + 32 =Y°F
|
||||||
return (32 + ((degC * 9) / 5));
|
return (32 + ((degC * 9) / 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t TipThermoModel::convertFtoC(uint32_t degF) {
|
uint32_t TipThermoModel::convertFtoC(uint32_t degF) {
|
||||||
//(Y°F − 32) × 5/9 = Y°C
|
//(Y°F − 32) × 5/9 = Y°C
|
||||||
if (degF < 32) {
|
if (degF < 32) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ((degF - 32) * 5) / 9;
|
return ((degF - 32) * 5) / 9;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t TipThermoModel::getTipInC(bool sampleNow) {
|
uint32_t TipThermoModel::getTipInC(bool sampleNow) {
|
||||||
int32_t currentTipTempInC = TipThermoModel::convertTipRawADCToDegC(getTipRawTemp(sampleNow));
|
int32_t currentTipTempInC = TipThermoModel::convertTipRawADCToDegC(getTipRawTemp(sampleNow));
|
||||||
currentTipTempInC += getHandleTemperature() / 10; //Add handle offset
|
currentTipTempInC += getHandleTemperature() / 10; // Add handle offset
|
||||||
// Power usage indicates that our tip temp is lower than our thermocouple temp.
|
// Power usage indicates that our tip temp is lower than our thermocouple temp.
|
||||||
// I found a number that doesn't unbalance the existing PID, causing overshoot.
|
// I found a number that doesn't unbalance the existing PID, causing overshoot.
|
||||||
// This could be tuned in concert with PID parameters...
|
// This could be tuned in concert with PID parameters...
|
||||||
currentTipTempInC -= x10WattHistory.average() / 25;
|
currentTipTempInC -= x10WattHistory.average() / 25;
|
||||||
if (currentTipTempInC < 0)
|
if (currentTipTempInC < 0)
|
||||||
return 0;
|
return 0;
|
||||||
return currentTipTempInC;
|
return currentTipTempInC;
|
||||||
}
|
}
|
||||||
#ifdef ENABLED_FAHRENHEIT_SUPPORT
|
#ifdef ENABLED_FAHRENHEIT_SUPPORT
|
||||||
uint32_t TipThermoModel::getTipInF(bool sampleNow) {
|
uint32_t TipThermoModel::getTipInF(bool sampleNow) {
|
||||||
uint32_t currentTipTempInF = getTipInC(sampleNow);
|
uint32_t currentTipTempInF = getTipInC(sampleNow);
|
||||||
currentTipTempInF = convertCtoF(currentTipTempInF);
|
currentTipTempInF = convertCtoF(currentTipTempInF);
|
||||||
return currentTipTempInF;
|
return currentTipTempInF;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t TipThermoModel::getTipMaxInC() {
|
uint32_t TipThermoModel::getTipMaxInC() {
|
||||||
uint32_t maximumTipTemp = TipThermoModel::convertTipRawADCToDegC(0x7FFF - (21 * 5)); //back off approx 5 deg c from ADC max
|
uint32_t maximumTipTemp = TipThermoModel::convertTipRawADCToDegC(0x7FFF - (21 * 5)); // back off approx 5 deg c from ADC max
|
||||||
maximumTipTemp += getHandleTemperature() / 10; //Add handle offset
|
maximumTipTemp += getHandleTemperature() / 10; // Add handle offset
|
||||||
return maximumTipTemp - 1;
|
return maximumTipTemp - 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,28 +7,23 @@
|
|||||||
|
|
||||||
#include "FreeRTOSHooks.h"
|
#include "FreeRTOSHooks.h"
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
void vApplicationIdleHook(void) {
|
void vApplicationIdleHook(void) { resetWatchdog(); }
|
||||||
resetWatchdog();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
|
/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
|
||||||
static StaticTask_t xIdleTaskTCBBuffer;
|
static StaticTask_t xIdleTaskTCBBuffer;
|
||||||
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];
|
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];
|
||||||
|
|
||||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
|
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
|
||||||
StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
|
*ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
|
||||||
*ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
|
*ppxIdleTaskStackBuffer = &xIdleStack[0];
|
||||||
*ppxIdleTaskStackBuffer = &xIdleStack[0];
|
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
/* place for user code */
|
||||||
/* place for user code */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vApplicationStackOverflowHook(TaskHandle_t *pxTask, signed portCHAR *pcTaskName) {
|
||||||
|
(void)pxTask;
|
||||||
|
(void)pcTaskName;
|
||||||
|
|
||||||
void vApplicationStackOverflowHook(TaskHandle_t *pxTask,
|
// We dont have a good way to handle a stack overflow at this point in time
|
||||||
signed portCHAR *pcTaskName) {
|
reboot();
|
||||||
(void) pxTask;
|
|
||||||
(void) pcTaskName;
|
|
||||||
|
|
||||||
// We dont have a good way to handle a stack overflow at this point in time
|
|
||||||
reboot();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,172 +12,169 @@
|
|||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
enum QCState {
|
enum QCState {
|
||||||
NOT_STARTED = 0, // Have not checked
|
NOT_STARTED = 0, // Have not checked
|
||||||
QC_3 = 1,
|
QC_3 = 1,
|
||||||
QC_2 = 2,
|
QC_2 = 2,
|
||||||
NO_QC = 3,
|
NO_QC = 3,
|
||||||
|
|
||||||
};
|
};
|
||||||
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();
|
||||||
osDelay(30);
|
osDelay(30);
|
||||||
QC_Seek20V();
|
QC_Seek20V();
|
||||||
osDelay(10);
|
osDelay(10);
|
||||||
QC_SeekContMode();
|
QC_SeekContMode();
|
||||||
}
|
}
|
||||||
void QC_SeekContNeg() {
|
void QC_SeekContNeg() {
|
||||||
QC_SeekContMode();
|
QC_SeekContMode();
|
||||||
osDelay(30);
|
osDelay(30);
|
||||||
QC_Seek12V();
|
QC_Seek12V();
|
||||||
osDelay(10);
|
osDelay(10);
|
||||||
QC_SeekContMode();
|
QC_SeekContMode();
|
||||||
}
|
}
|
||||||
QCState QCMode = QCState::NOT_STARTED;
|
QCState QCMode = QCState::NOT_STARTED;
|
||||||
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 == QCState::NOT_STARTED)
|
if (QCMode == QCState::NOT_STARTED)
|
||||||
startQC(divisor);
|
startQC(divisor);
|
||||||
|
|
||||||
if (Vx10 < 45)
|
if (Vx10 < 45)
|
||||||
return;
|
return;
|
||||||
if (xTaskGetTickCount() < TICKS_SECOND)
|
if (xTaskGetTickCount() < TICKS_SECOND)
|
||||||
return;
|
return;
|
||||||
#ifdef POW_QC_20V
|
#ifdef POW_QC_20V
|
||||||
if (Vx10 > 200)
|
if (Vx10 > 200)
|
||||||
Vx10 = 200; // Cap max value at 20V
|
Vx10 = 200; // Cap max value at 20V
|
||||||
#else
|
#else
|
||||||
if (Vx10 > 130)
|
if (Vx10 > 130)
|
||||||
Vx10 = 130; // Cap max value at 13V
|
Vx10 = 130; // Cap max value at 13V
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// Seek the QC to the Voltage given if this adapter supports continuous mode
|
// Seek the QC to the Voltage given if this adapter supports continuous mode
|
||||||
// try and step towards the wanted value
|
// 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 == QCState::QC_3) {
|
if (QCMode == QCState::QC_3) {
|
||||||
if (steps > -2 && steps < 2)
|
if (steps > -2 && steps < 2)
|
||||||
return; // dont bother with small steps
|
return; // dont bother with small steps
|
||||||
while (steps < 0) {
|
while (steps < 0) {
|
||||||
QC_SeekContNeg();
|
QC_SeekContNeg();
|
||||||
osDelay(30);
|
osDelay(30);
|
||||||
steps++;
|
steps++;
|
||||||
}
|
}
|
||||||
while (steps > 0) {
|
while (steps > 0) {
|
||||||
QC_SeekContPlus();
|
QC_SeekContPlus();
|
||||||
osDelay(30);
|
osDelay(30);
|
||||||
steps--;
|
steps--;
|
||||||
}
|
}
|
||||||
osDelay(100);
|
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*/
|
||||||
steps = vStart - getInputVoltageX10(divisor, 1);
|
steps = vStart - getInputVoltageX10(divisor, 1);
|
||||||
if (steps < 0)
|
if (steps < 0)
|
||||||
steps = -steps;
|
steps = -steps;
|
||||||
if (steps > 4) {
|
if (steps > 4) {
|
||||||
// No continuous mode, so QC2
|
// No continuous mode, so QC2
|
||||||
QCMode = QCState::QC_2;
|
QCMode = QCState::QC_2;
|
||||||
// Goto nearest
|
// Goto nearest
|
||||||
if (Vx10 > 190) {
|
if (Vx10 > 190) {
|
||||||
// request 20V
|
// request 20V
|
||||||
QC_Seek20V();
|
QC_Seek20V();
|
||||||
} else if (Vx10 > 110) {
|
} else if (Vx10 > 110) {
|
||||||
// request 12V
|
// request 12V
|
||||||
QC_Seek12V();
|
QC_Seek12V();
|
||||||
} else {
|
} else {
|
||||||
// request 9V
|
// request 9V
|
||||||
QC_Seek9V();
|
QC_Seek9V();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// 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
|
||||||
if (getInputVoltageX10(divisor, 1) > 80) {
|
if (getInputVoltageX10(divisor, 1) > 80) {
|
||||||
QCTries = 11;
|
QCTries = 11;
|
||||||
QCMode = QCState::NO_QC;
|
QCMode = QCState::NO_QC;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (QCTries > 10) {
|
if (QCTries > 10) {
|
||||||
QCMode = QCState::NO_QC;
|
QCMode = QCState::NO_QC;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QCMode = QCState::NOT_STARTED;
|
QCMode = QCState::NOT_STARTED;
|
||||||
QC_Init_GPIO();
|
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
|
// Delay 1.25 seconds
|
||||||
uint8_t enteredQC = 0;
|
uint8_t enteredQC = 0;
|
||||||
for (uint16_t i = 0; i < 200 && enteredQC == 0; i++) {
|
for (uint16_t i = 0; i < 200 && enteredQC == 0; i++) {
|
||||||
osDelay(10); // 10mS pause
|
osDelay(10); // 10mS pause
|
||||||
if (i > 130) {
|
if (i > 130) {
|
||||||
if (QC_DM_PulledDown()) {
|
if (QC_DM_PulledDown()) {
|
||||||
enteredQC = 1;
|
enteredQC = 1;
|
||||||
}
|
}
|
||||||
if (i == 140) {
|
if (i == 140) {
|
||||||
// For some marginal QC chargers, we try adding a pulldown
|
// For some marginal QC chargers, we try adding a pulldown
|
||||||
QC_DM_PullDown();
|
QC_DM_PullDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QC_DM_No_PullDown();
|
QC_DM_No_PullDown();
|
||||||
if (enteredQC) {
|
if (enteredQC) {
|
||||||
// We have a QC capable charger
|
// We have a QC capable charger
|
||||||
QC_Seek9V();
|
QC_Seek9V();
|
||||||
QC_Post_Probe_En();
|
QC_Post_Probe_En();
|
||||||
QC_Seek9V();
|
QC_Seek9V();
|
||||||
// Wait for frontend ADC to stabilise
|
// Wait for frontend ADC to stabilise
|
||||||
QCMode = QCState::QC_2;
|
QCMode = QCState::QC_2;
|
||||||
for (uint8_t i = 0; i < 10; i++) {
|
for (uint8_t i = 0; i < 10; i++) {
|
||||||
if (getInputVoltageX10(divisor, 1) > 80) {
|
if (getInputVoltageX10(divisor, 1) > 80) {
|
||||||
// yay we have at least QC2.0 or QC3.0
|
// yay we have at least QC2.0 or QC3.0
|
||||||
QCMode = QCState::QC_3; // We have at least QC2, pray for 3
|
QCMode = QCState::QC_3; // We have at least QC2, pray for 3
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
osDelay(100); // 100mS
|
osDelay(100); // 100mS
|
||||||
}
|
}
|
||||||
QCMode = QCState::NOT_STARTED;
|
QCMode = QCState::NOT_STARTED;
|
||||||
QCTries++;
|
QCTries++;
|
||||||
|
|
||||||
} else {
|
|
||||||
// no QC
|
|
||||||
QCTries++;
|
|
||||||
QCMode = QCState::NO_QC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// no QC
|
||||||
|
QCTries++;
|
||||||
|
QCMode = QCState::NO_QC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasQCNegotiated() {
|
bool hasQCNegotiated() { return QCMode == QCState::QC_3 || QCMode == QCState::QC_2; }
|
||||||
return QCMode == QCState::QC_3 || QCMode == QCState::QC_2;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,30 +9,30 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "Setup.h"
|
|
||||||
#include "../../configuration.h"
|
#include "../../configuration.h"
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
|
#include "Setup.h"
|
||||||
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
volatile systemSettingsType systemSettings;
|
volatile systemSettingsType systemSettings;
|
||||||
|
|
||||||
void saveSettings() {
|
void saveSettings() {
|
||||||
// First we erase the flash
|
// First we erase the flash
|
||||||
flash_save_buffer((uint8_t*) &systemSettings, sizeof(systemSettingsType));
|
flash_save_buffer((uint8_t *)&systemSettings, sizeof(systemSettingsType));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool restoreSettings() {
|
bool restoreSettings() {
|
||||||
// We read the flash
|
// We read the flash
|
||||||
flash_read_buffer((uint8_t*) &systemSettings, sizeof(systemSettingsType));
|
flash_read_buffer((uint8_t *)&systemSettings, sizeof(systemSettingsType));
|
||||||
|
|
||||||
// if the version is correct were done
|
// if the version is correct were done
|
||||||
// if not we reset and save
|
// if not we reset and save
|
||||||
if (systemSettings.version != SETTINGSVERSION) {
|
if (systemSettings.version != SETTINGSVERSION) {
|
||||||
// probably not setup
|
// probably not setup
|
||||||
resetSettings();
|
resetSettings();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Lookup function for cutoff setting -> X10 voltage
|
// Lookup function for cutoff setting -> X10 voltage
|
||||||
/*
|
/*
|
||||||
@@ -43,59 +43,59 @@ bool restoreSettings() {
|
|||||||
* 4=6S
|
* 4=6S
|
||||||
*/
|
*/
|
||||||
uint8_t lookupVoltageLevel() {
|
uint8_t lookupVoltageLevel() {
|
||||||
if (systemSettings.minDCVoltageCells == 0)
|
if (systemSettings.minDCVoltageCells == 0)
|
||||||
return 90; // 9V since iron does not function effectively below this
|
return 90; // 9V since iron does not function effectively below this
|
||||||
else
|
else
|
||||||
return (systemSettings.minDCVoltageCells * 33) + (33 * 2);
|
return (systemSettings.minDCVoltageCells * 33) + (33 * 2);
|
||||||
}
|
}
|
||||||
void resetSettings() {
|
void resetSettings() {
|
||||||
memset((void*) &systemSettings, 0, sizeof(systemSettingsType));
|
memset((void *)&systemSettings, 0, sizeof(systemSettingsType));
|
||||||
systemSettings.SleepTemp = SLEEP_TEMP; // Temperature the iron sleeps at - default 150.0 C
|
systemSettings.SleepTemp = SLEEP_TEMP; // Temperature the iron sleeps at - default 150.0 C
|
||||||
systemSettings.SleepTime = SLEEP_TIME; // How many seconds/minutes we wait until going
|
systemSettings.SleepTime = SLEEP_TIME; // How many seconds/minutes we wait until going
|
||||||
// to sleep - default 1 min
|
// to sleep - default 1 min
|
||||||
systemSettings.SolderingTemp = SOLDERING_TEMP; // Default soldering temp is 320.0 C
|
systemSettings.SolderingTemp = SOLDERING_TEMP; // Default soldering temp is 320.0 C
|
||||||
systemSettings.minDCVoltageCells = CUT_OUT_SETTING; // default to no cut-off voltage
|
systemSettings.minDCVoltageCells = CUT_OUT_SETTING; // default to no cut-off voltage
|
||||||
systemSettings.QCIdealVoltage = 0; // Default to 9V for QC3.0 Voltage
|
systemSettings.QCIdealVoltage = 0; // Default to 9V for QC3.0 Voltage
|
||||||
systemSettings.version = SETTINGSVERSION; // Store the version number to allow for easier upgrades
|
systemSettings.version = SETTINGSVERSION; // Store the version number to allow for easier upgrades
|
||||||
systemSettings.detailedSoldering = DETAILED_SOLDERING; // Detailed soldering screen
|
systemSettings.detailedSoldering = DETAILED_SOLDERING; // Detailed soldering screen
|
||||||
systemSettings.detailedIDLE = DETAILED_IDLE; // Detailed idle screen (off for first time users)
|
systemSettings.detailedIDLE = DETAILED_IDLE; // Detailed idle screen (off for first time users)
|
||||||
systemSettings.OrientationMode = ORIENTATION_MODE; // Default to automatic
|
systemSettings.OrientationMode = ORIENTATION_MODE; // Default to automatic
|
||||||
systemSettings.sensitivity = SENSITIVITY; // Default high sensitivity
|
systemSettings.sensitivity = SENSITIVITY; // Default high sensitivity
|
||||||
systemSettings.voltageDiv = VOLTAGE_DIV; // Default divider from schematic
|
systemSettings.voltageDiv = VOLTAGE_DIV; // Default divider from schematic
|
||||||
systemSettings.ShutdownTime = SHUTDOWN_TIME; // How many minutes until the unit turns itself off
|
systemSettings.ShutdownTime = SHUTDOWN_TIME; // How many minutes until the unit turns itself off
|
||||||
systemSettings.BoostTemp = BOOST_TEMP; // default to 400C
|
systemSettings.BoostTemp = BOOST_TEMP; // default to 400C
|
||||||
systemSettings.autoStartMode = AUTO_START_MODE; // Auto start off for safety
|
systemSettings.autoStartMode = AUTO_START_MODE; // Auto start off for safety
|
||||||
systemSettings.lockingMode = LOCKING_MODE; // Disable locking for safety
|
systemSettings.lockingMode = LOCKING_MODE; // Disable locking for safety
|
||||||
systemSettings.coolingTempBlink = COOLING_TEMP_BLINK; // Blink the temperature on the cooling screen when its > 50C
|
systemSettings.coolingTempBlink = COOLING_TEMP_BLINK; // Blink the temperature on the cooling screen when its > 50C
|
||||||
#ifdef ENABLED_FAHRENHEIT_SUPPORT
|
#ifdef ENABLED_FAHRENHEIT_SUPPORT
|
||||||
systemSettings.temperatureInF = TEMPERATURE_INF; // default to 0
|
systemSettings.temperatureInF = TEMPERATURE_INF; // default to 0
|
||||||
#endif
|
#endif
|
||||||
systemSettings.descriptionScrollSpeed = DESCRIPTION_SCROLL_SPEED; // default to slow
|
systemSettings.descriptionScrollSpeed = DESCRIPTION_SCROLL_SPEED; // default to slow
|
||||||
systemSettings.CalibrationOffset = CALIBRATION_OFFSET; // the adc offset in uV
|
systemSettings.CalibrationOffset = CALIBRATION_OFFSET; // the adc offset in uV
|
||||||
systemSettings.powerLimit = POWER_LIMIT; // 30 watts default limit
|
systemSettings.powerLimit = POWER_LIMIT; // 30 watts default limit
|
||||||
systemSettings.ReverseButtonTempChangeEnabled = REVERSE_BUTTON_TEMP_CHANGE; //
|
systemSettings.ReverseButtonTempChangeEnabled = REVERSE_BUTTON_TEMP_CHANGE; //
|
||||||
systemSettings.TempChangeShortStep = TEMP_CHANGE_SHORT_STEP; //
|
systemSettings.TempChangeShortStep = TEMP_CHANGE_SHORT_STEP; //
|
||||||
systemSettings.TempChangeLongStep = TEMP_CHANGE_LONG_STEP; //
|
systemSettings.TempChangeLongStep = TEMP_CHANGE_LONG_STEP; //
|
||||||
systemSettings.KeepAwakePulse = POWER_PULSE_DEFAULT;
|
systemSettings.KeepAwakePulse = POWER_PULSE_DEFAULT;
|
||||||
systemSettings.hallEffectSensitivity = 1;
|
systemSettings.hallEffectSensitivity = 1;
|
||||||
systemSettings.accelMissingWarningCounter = 0;
|
systemSettings.accelMissingWarningCounter = 0;
|
||||||
systemSettings.pdMissingWarningCounter = 0;
|
systemSettings.pdMissingWarningCounter = 0;
|
||||||
|
|
||||||
saveSettings(); // Save defaults
|
saveSettings(); // Save defaults
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t lookupHallEffectThreshold() {
|
uint16_t lookupHallEffectThreshold() {
|
||||||
// Return the threshold above which the hall effect sensor is "activated"
|
// Return the threshold above which the hall effect sensor is "activated"
|
||||||
switch (systemSettings.hallEffectSensitivity) {
|
switch (systemSettings.hallEffectSensitivity) {
|
||||||
case 0:
|
case 0:
|
||||||
return 0;
|
return 0;
|
||||||
case 1: //Low
|
case 1: // Low
|
||||||
return 1000;
|
return 1000;
|
||||||
case 2: //Medium
|
case 2: // Medium
|
||||||
return 500;
|
return 500;
|
||||||
case 3: //High
|
case 3: // High
|
||||||
return 100;
|
return 100;
|
||||||
default:
|
default:
|
||||||
return 0; //Off
|
return 0; // Off
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* File Name : freertos.c
|
* File Name : freertos.c
|
||||||
* Description : Code for freertos applications
|
* Description : Code for freertos applications
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* This notice applies to any and all portions of this file
|
* This notice applies to any and all portions of this file
|
||||||
* that are not between comment pairs USER CODE BEGIN and
|
* that are not between comment pairs USER CODE BEGIN and
|
||||||
* USER CODE END. Other portions of this file, whether
|
* USER CODE END. Other portions of this file, whether
|
||||||
* inserted by the user or by software development tools
|
* inserted by the user or by software development tools
|
||||||
* are owned by their respective copyright owners.
|
* are owned by their respective copyright owners.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017 STMicroelectronics International N.V.
|
* Copyright (c) 2017 STMicroelectronics International N.V.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted, provided that the following conditions are met:
|
* modification, are permitted, provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistribution of source code must retain the above copyright notice,
|
* 1. Redistribution 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 other
|
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||||
* contributors to this software may be used to endorse or promote products
|
* contributors to this software may be used to endorse or promote products
|
||||||
* derived from this software without specific written permission.
|
* derived from this software without specific written permission.
|
||||||
* 4. This software, including modifications and/or derivative works of this
|
* 4. This software, including modifications and/or derivative works of this
|
||||||
* software, must execute solely and exclusively on microcontroller or
|
* software, must execute solely and exclusively on microcontroller or
|
||||||
* microprocessor devices manufactured by or for STMicroelectronics.
|
* microprocessor devices manufactured by or for STMicroelectronics.
|
||||||
* 5. Redistribution and use of this software other than as permitted under
|
* 5. Redistribution and use of this software other than as permitted under
|
||||||
* this license is void and will automatically terminate your rights under
|
* this license is void and will automatically terminate your rights under
|
||||||
* this license.
|
* this license.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
|
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
|
||||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,67 +5,66 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include <main.hpp>
|
|
||||||
#include "LIS2DH12.hpp"
|
#include "LIS2DH12.hpp"
|
||||||
#include <MMA8652FC.hpp>
|
|
||||||
#include <power.hpp>
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
|
#include <MMA8652FC.hpp>
|
||||||
|
#include <main.hpp>
|
||||||
|
#include <power.hpp>
|
||||||
uint8_t DetectedAccelerometerVersion = 0;
|
uint8_t DetectedAccelerometerVersion = 0;
|
||||||
bool settingsWereReset = false;
|
bool settingsWereReset = false;
|
||||||
// FreeRTOS variables
|
// FreeRTOS variables
|
||||||
|
|
||||||
osThreadId GUITaskHandle;
|
osThreadId GUITaskHandle;
|
||||||
static const size_t GUITaskStackSize = 1024 / 4;
|
static const size_t GUITaskStackSize = 1024 / 4;
|
||||||
uint32_t GUITaskBuffer[GUITaskStackSize];
|
uint32_t GUITaskBuffer[GUITaskStackSize];
|
||||||
osStaticThreadDef_t GUITaskControlBlock;
|
osStaticThreadDef_t GUITaskControlBlock;
|
||||||
|
|
||||||
osThreadId PIDTaskHandle;
|
osThreadId PIDTaskHandle;
|
||||||
static const size_t PIDTaskStackSize = 512 / 4;
|
static const size_t PIDTaskStackSize = 512 / 4;
|
||||||
uint32_t PIDTaskBuffer[PIDTaskStackSize];
|
uint32_t PIDTaskBuffer[PIDTaskStackSize];
|
||||||
osStaticThreadDef_t PIDTaskControlBlock;
|
osStaticThreadDef_t PIDTaskControlBlock;
|
||||||
|
|
||||||
osThreadId MOVTaskHandle;
|
osThreadId MOVTaskHandle;
|
||||||
static const size_t MOVTaskStackSize = 1024 / 4;
|
static const size_t MOVTaskStackSize = 1024 / 4;
|
||||||
uint32_t MOVTaskBuffer[MOVTaskStackSize];
|
uint32_t MOVTaskBuffer[MOVTaskStackSize];
|
||||||
osStaticThreadDef_t MOVTaskControlBlock;
|
osStaticThreadDef_t MOVTaskControlBlock;
|
||||||
|
|
||||||
osThreadId POWTaskHandle;
|
osThreadId POWTaskHandle;
|
||||||
static const size_t POWTaskStackSize = 512 / 4;
|
static const size_t POWTaskStackSize = 512 / 4;
|
||||||
uint32_t POWTaskBuffer[POWTaskStackSize];
|
uint32_t POWTaskBuffer[POWTaskStackSize];
|
||||||
osStaticThreadDef_t POWTaskControlBlock;
|
osStaticThreadDef_t POWTaskControlBlock;
|
||||||
|
|
||||||
// End FreeRTOS
|
// End FreeRTOS
|
||||||
// Main sets up the hardware then hands over to the FreeRTOS kernel
|
// Main sets up the hardware then hands over to the FreeRTOS kernel
|
||||||
int main(void) {
|
int main(void) {
|
||||||
preRToSInit();
|
preRToSInit();
|
||||||
setTipX10Watts(0); // force tip off
|
setTipX10Watts(0); // force tip off
|
||||||
resetWatchdog();
|
resetWatchdog();
|
||||||
OLED::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
|
||||||
settingsWereReset = restoreSettings(); // load the settings from flash
|
settingsWereReset = restoreSettings(); // load the settings from flash
|
||||||
resetWatchdog();
|
resetWatchdog();
|
||||||
/* Create the thread(s) */
|
/* Create the thread(s) */
|
||||||
/* definition and creation of POWTask - Power management for QC */
|
/* definition and creation of POWTask - Power management for QC */
|
||||||
osThreadStaticDef(POWTask, startPOWTask, osPriorityAboveNormal, 0, POWTaskStackSize, POWTaskBuffer, &POWTaskControlBlock);
|
osThreadStaticDef(POWTask, startPOWTask, osPriorityAboveNormal, 0, POWTaskStackSize, POWTaskBuffer, &POWTaskControlBlock);
|
||||||
POWTaskHandle = osThreadCreate(osThread(POWTask), NULL);
|
POWTaskHandle = osThreadCreate(osThread(POWTask), NULL);
|
||||||
|
|
||||||
/* definition and creation of GUITask - The OLED control & update*/
|
/* definition and creation of GUITask - The OLED control & update*/
|
||||||
osThreadStaticDef(GUITask, startGUITask, osPriorityBelowNormal, 0, GUITaskStackSize, GUITaskBuffer, &GUITaskControlBlock);
|
osThreadStaticDef(GUITask, startGUITask, osPriorityBelowNormal, 0, GUITaskStackSize, GUITaskBuffer, &GUITaskControlBlock);
|
||||||
GUITaskHandle = osThreadCreate(osThread(GUITask), NULL);
|
GUITaskHandle = osThreadCreate(osThread(GUITask), NULL);
|
||||||
|
|
||||||
/* definition and creation of PIDTask - Heating control*/
|
/* definition and creation of PIDTask - Heating control*/
|
||||||
osThreadStaticDef(PIDTask, startPIDTask, osPriorityRealtime, 0, PIDTaskStackSize, PIDTaskBuffer, &PIDTaskControlBlock);
|
osThreadStaticDef(PIDTask, startPIDTask, osPriorityRealtime, 0, PIDTaskStackSize, PIDTaskBuffer, &PIDTaskControlBlock);
|
||||||
PIDTaskHandle = osThreadCreate(osThread(PIDTask), NULL);
|
PIDTaskHandle = osThreadCreate(osThread(PIDTask), NULL);
|
||||||
|
|
||||||
/* definition and creation of MOVTask - Accelerometer management */
|
/* definition and creation of MOVTask - Accelerometer management */
|
||||||
osThreadStaticDef(MOVTask, startMOVTask, osPriorityNormal, 0, MOVTaskStackSize, MOVTaskBuffer, &MOVTaskControlBlock);
|
osThreadStaticDef(MOVTask, startMOVTask, osPriorityNormal, 0, MOVTaskStackSize, MOVTaskBuffer, &MOVTaskControlBlock);
|
||||||
MOVTaskHandle = osThreadCreate(osThread(MOVTask), NULL);
|
MOVTaskHandle = osThreadCreate(osThread(MOVTask), NULL);
|
||||||
resetWatchdog();
|
resetWatchdog();
|
||||||
|
|
||||||
/* Start scheduler */
|
/* Start scheduler */
|
||||||
osKernelStart();
|
osKernelStart();
|
||||||
/* We should never get here as control is now taken by the scheduler */
|
/* We should never get here as control is now taken by the scheduler */
|
||||||
for (;;) {
|
for (;;) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,71 +5,71 @@
|
|||||||
* Authors: Ben V. Brown, David Hilton <- Mostly David
|
* Authors: Ben V. Brown, David Hilton <- Mostly David
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <power.hpp>
|
|
||||||
#include <Settings.h>
|
|
||||||
#include <BSP.h>
|
#include <BSP.h>
|
||||||
|
#include <Settings.h>
|
||||||
|
#include <power.hpp>
|
||||||
|
|
||||||
static int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample);
|
static int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample);
|
||||||
|
|
||||||
expMovingAverage<uint32_t, wattHistoryFilter> x10WattHistory = { 0 };
|
expMovingAverage<uint32_t, wattHistoryFilter> x10WattHistory = {0};
|
||||||
|
|
||||||
int32_t tempToX10Watts(int32_t rawTemp) {
|
int32_t tempToX10Watts(int32_t rawTemp) {
|
||||||
// mass is in milliJ/*C, rawC is raw per degree C
|
// mass is in milliJ/*C, rawC is raw per degree C
|
||||||
// returns milliWatts needed to raise/lower a mass by rawTemp
|
// returns milliWatts needed to raise/lower a mass by rawTemp
|
||||||
// degrees in one cycle.
|
// degrees in one cycle.
|
||||||
int32_t milliJoules = tipMass * rawTemp;
|
int32_t milliJoules = tipMass * rawTemp;
|
||||||
return milliJoules;
|
return milliJoules;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTipX10Watts(int32_t mw) {
|
void setTipX10Watts(int32_t mw) {
|
||||||
int32_t output = X10WattsToPWM(mw, 1);
|
int32_t output = X10WattsToPWM(mw, 1);
|
||||||
setTipPWM(output);
|
setTipPWM(output);
|
||||||
uint32_t actualMilliWatts = PWMToX10Watts(output, 0);
|
uint32_t actualMilliWatts = PWMToX10Watts(output, 0);
|
||||||
|
|
||||||
x10WattHistory.update(actualMilliWatts);
|
x10WattHistory.update(actualMilliWatts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t availableW10(uint8_t sample) {
|
static uint32_t availableW10(uint8_t sample) {
|
||||||
//P = V^2 / R, v*v = v^2 * 100
|
// P = V^2 / R, v*v = v^2 * 100
|
||||||
// R = R*10
|
// R = R*10
|
||||||
// P therefore is in V^2*100/R*10 = W*10.
|
// P therefore is in V^2*100/R*10 = W*10.
|
||||||
uint32_t v = getInputVoltageX10(systemSettings.voltageDiv, sample); // 100 = 10v
|
uint32_t v = getInputVoltageX10(systemSettings.voltageDiv, sample); // 100 = 10v
|
||||||
uint32_t availableWattsX10 = (v * v) / tipResistance;
|
uint32_t availableWattsX10 = (v * v) / tipResistance;
|
||||||
//However, 100% duty cycle is not possible as there is a dead time while the ADC takes a reading
|
// However, 100% duty cycle is not possible as there is a dead time while the ADC takes a reading
|
||||||
//Therefore need to scale available milliwats by this
|
// Therefore need to scale available milliwats by this
|
||||||
|
|
||||||
// avMw=(AvMw*powerPWM)/totalPWM.
|
// avMw=(AvMw*powerPWM)/totalPWM.
|
||||||
availableWattsX10 = availableWattsX10 * powerPWM;
|
availableWattsX10 = availableWattsX10 * powerPWM;
|
||||||
availableWattsX10 /= totalPWM;
|
availableWattsX10 /= totalPWM;
|
||||||
|
|
||||||
//availableMilliWattsX10 is now an accurate representation
|
// availableMilliWattsX10 is now an accurate representation
|
||||||
return availableWattsX10;
|
return availableWattsX10;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample) {
|
uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample) {
|
||||||
// Scale input milliWatts to the pwm range available
|
// Scale input milliWatts to the pwm range available
|
||||||
if (milliWatts < 1) {
|
if (milliWatts < 1) {
|
||||||
//keep the battery voltage updating the filter
|
// keep the battery voltage updating the filter
|
||||||
getInputVoltageX10(systemSettings.voltageDiv, sample);
|
getInputVoltageX10(systemSettings.voltageDiv, sample);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Calculate desired milliwatts as a percentage of availableW10
|
// Calculate desired milliwatts as a percentage of availableW10
|
||||||
uint32_t pwm;
|
uint32_t pwm;
|
||||||
do {
|
do {
|
||||||
pwm = (powerPWM * milliWatts) / availableW10(sample);
|
pwm = (powerPWM * milliWatts) / availableW10(sample);
|
||||||
if (pwm > powerPWM) {
|
if (pwm > powerPWM) {
|
||||||
// constrain to max PWM counter, shouldn't be possible,
|
// constrain to max PWM counter, shouldn't be possible,
|
||||||
// but small cost for safety to avoid wraps
|
// but small cost for safety to avoid wraps
|
||||||
pwm = powerPWM;
|
pwm = powerPWM;
|
||||||
}
|
}
|
||||||
} while (tryBetterPWM(pwm));
|
} while (tryBetterPWM(pwm));
|
||||||
|
|
||||||
return pwm;
|
return pwm;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample) {
|
static int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample) {
|
||||||
uint32_t maxMW = availableW10(sample); //Get the milliwatts for the max pwm period
|
uint32_t maxMW = availableW10(sample); // Get the milliwatts for the max pwm period
|
||||||
//Then convert pwm into percentage of powerPWM to get the percentage of the max mw
|
// Then convert pwm into percentage of powerPWM to get the percentage of the max mw
|
||||||
return (((uint32_t) pwm) * maxMW) / powerPWM;
|
return (((uint32_t)pwm) * maxMW) / powerPWM;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
/* Includes */
|
/* Includes */
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/times.h>
|
#include <sys/times.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
void initialise_monitor_handles() {
|
void initialise_monitor_handles() {}
|
||||||
}
|
|
||||||
|
|
||||||
int _getpid(void) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int _getpid(void) { return 1; }
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "BMA223.hpp"
|
#include "BMA223.hpp"
|
||||||
#include "SC7A20.hpp"
|
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "I2C_Wrapper.hpp"
|
#include "I2C_Wrapper.hpp"
|
||||||
@@ -14,6 +13,7 @@
|
|||||||
#include "MMA8652FC.hpp"
|
#include "MMA8652FC.hpp"
|
||||||
#include "MSA301.h"
|
#include "MSA301.h"
|
||||||
#include "QC3.h"
|
#include "QC3.h"
|
||||||
|
#include "SC7A20.hpp"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "TipThermoModel.h"
|
#include "TipThermoModel.h"
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
@@ -23,60 +23,60 @@
|
|||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#define MOVFilter 8
|
#define MOVFilter 8
|
||||||
uint8_t accelInit = 0;
|
uint8_t accelInit = 0;
|
||||||
TickType_t lastMovementTime = 0;
|
TickType_t lastMovementTime = 0;
|
||||||
void detectAccelerometerVersion() {
|
void detectAccelerometerVersion() {
|
||||||
DetectedAccelerometerVersion = 99;
|
DetectedAccelerometerVersion = 99;
|
||||||
#ifdef ACCEL_MMA
|
#ifdef ACCEL_MMA
|
||||||
if (MMA8652FC::detect()) {
|
if (MMA8652FC::detect()) {
|
||||||
if (MMA8652FC::initalize()) {
|
if (MMA8652FC::initalize()) {
|
||||||
DetectedAccelerometerVersion = 1;
|
DetectedAccelerometerVersion = 1;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef ACCEL_LIS
|
#ifdef ACCEL_LIS
|
||||||
if (LIS2DH12::detect()) {
|
if (LIS2DH12::detect()) {
|
||||||
// Setup the ST Accelerometer
|
// Setup the ST Accelerometer
|
||||||
if (LIS2DH12::initalize()) {
|
if (LIS2DH12::initalize()) {
|
||||||
DetectedAccelerometerVersion = 2;
|
DetectedAccelerometerVersion = 2;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef ACCEL_BMA
|
#ifdef ACCEL_BMA
|
||||||
if (BMA223::detect()) {
|
if (BMA223::detect()) {
|
||||||
// Setup the ST Accelerometer
|
// Setup the ST Accelerometer
|
||||||
if (BMA223::initalize()) {
|
if (BMA223::initalize()) {
|
||||||
DetectedAccelerometerVersion = 3;
|
DetectedAccelerometerVersion = 3;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef ACCEL_MSA
|
#ifdef ACCEL_MSA
|
||||||
if (MSA301::detect()) {
|
if (MSA301::detect()) {
|
||||||
// Setup the MSA301 Accelerometer
|
// Setup the MSA301 Accelerometer
|
||||||
if (MSA301::initalize()) {
|
if (MSA301::initalize()) {
|
||||||
DetectedAccelerometerVersion = 4;
|
DetectedAccelerometerVersion = 4;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef ACCEL_SC7
|
#ifdef ACCEL_SC7
|
||||||
if (SC7A20::detect()) {
|
if (SC7A20::detect()) {
|
||||||
// Setup the SC7A20 Accelerometer
|
// Setup the SC7A20 Accelerometer
|
||||||
if (SC7A20::initalize()) {
|
if (SC7A20::initalize()) {
|
||||||
DetectedAccelerometerVersion = 5;
|
DetectedAccelerometerVersion = 5;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// disable imu sensitivity
|
// disable imu sensitivity
|
||||||
systemSettings.sensitivity = 0;
|
systemSettings.sensitivity = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline void readAccelerometer(int16_t &tx, int16_t &ty, int16_t &tz, Orientation &rotation) {
|
inline void readAccelerometer(int16_t &tx, int16_t &ty, int16_t &tz, Orientation &rotation) {
|
||||||
#ifdef ACCEL_LIS
|
#ifdef ACCEL_LIS
|
||||||
if (DetectedAccelerometerVersion == 2) {
|
if (DetectedAccelerometerVersion == 2) {
|
||||||
LIS2DH12::getAxisReadings(tx, ty, tz);
|
LIS2DH12::getAxisReadings(tx, ty, tz);
|
||||||
rotation = LIS2DH12::getOrientation();
|
rotation = LIS2DH12::getOrientation();
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef ACCEL_MMA
|
#ifdef ACCEL_MMA
|
||||||
if (DetectedAccelerometerVersion == 1) {
|
if (DetectedAccelerometerVersion == 1) {
|
||||||
@@ -91,81 +91,81 @@ inline void readAccelerometer(int16_t &tx, int16_t &ty, int16_t &tz, Orientation
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef ACCEL_MSA
|
#ifdef ACCEL_MSA
|
||||||
if (DetectedAccelerometerVersion == 4) {
|
if (DetectedAccelerometerVersion == 4) {
|
||||||
MSA301::getAxisReadings(tx, ty, tz);
|
MSA301::getAxisReadings(tx, ty, tz);
|
||||||
rotation = MSA301::getOrientation();
|
rotation = MSA301::getOrientation();
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef ACCEL_SC7
|
#ifdef ACCEL_SC7
|
||||||
if (DetectedAccelerometerVersion == 5) {
|
if (DetectedAccelerometerVersion == 5) {
|
||||||
SC7A20::getAxisReadings(tx, ty, tz);
|
SC7A20::getAxisReadings(tx, ty, tz);
|
||||||
rotation = SC7A20::getOrientation();
|
rotation = SC7A20::getOrientation();
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// do nothing :(
|
// do nothing :(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void startMOVTask(void const *argument __unused) {
|
void startMOVTask(void const *argument __unused) {
|
||||||
detectAccelerometerVersion();
|
detectAccelerometerVersion();
|
||||||
osDelay(TICKS_100MS / 2); // wait ~50ms for setup of accel to finalise
|
osDelay(TICKS_100MS / 2); // wait ~50ms for setup of accel to finalise
|
||||||
lastMovementTime = 0;
|
lastMovementTime = 0;
|
||||||
// Mask 2 seconds if we are in autostart so that if user is plugging in and
|
// Mask 2 seconds if we are in autostart so that if user is plugging in and
|
||||||
// then putting in stand it doesnt wake instantly
|
// then putting in stand it doesnt wake instantly
|
||||||
if (systemSettings.autoStartMode)
|
if (systemSettings.autoStartMode)
|
||||||
osDelay(2 * TICKS_SECOND);
|
osDelay(2 * TICKS_SECOND);
|
||||||
|
|
||||||
int16_t datax[MOVFilter] = { 0 };
|
int16_t datax[MOVFilter] = {0};
|
||||||
int16_t datay[MOVFilter] = { 0 };
|
int16_t datay[MOVFilter] = {0};
|
||||||
int16_t dataz[MOVFilter] = { 0 };
|
int16_t dataz[MOVFilter] = {0};
|
||||||
uint8_t currentPointer = 0;
|
uint8_t currentPointer = 0;
|
||||||
int16_t tx = 0, ty = 0, tz = 0;
|
int16_t tx = 0, ty = 0, tz = 0;
|
||||||
int32_t avgx, avgy, avgz;
|
int32_t avgx, avgy, avgz;
|
||||||
if (systemSettings.sensitivity > 9)
|
if (systemSettings.sensitivity > 9)
|
||||||
systemSettings.sensitivity = 9;
|
systemSettings.sensitivity = 9;
|
||||||
Orientation rotation = ORIENTATION_FLAT;
|
Orientation rotation = ORIENTATION_FLAT;
|
||||||
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
|
||||||
readAccelerometer(tx, ty, tz, rotation);
|
readAccelerometer(tx, ty, tz, rotation);
|
||||||
if (systemSettings.OrientationMode == 2) {
|
if (systemSettings.OrientationMode == 2) {
|
||||||
if (rotation != ORIENTATION_FLAT) {
|
if (rotation != ORIENTATION_FLAT) {
|
||||||
OLED::setRotation(rotation == ORIENTATION_LEFT_HAND); // link the data through
|
OLED::setRotation(rotation == ORIENTATION_LEFT_HAND); // link the data through
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
datax[currentPointer] = (int32_t) tx;
|
datax[currentPointer] = (int32_t)tx;
|
||||||
datay[currentPointer] = (int32_t) ty;
|
datay[currentPointer] = (int32_t)ty;
|
||||||
dataz[currentPointer] = (int32_t) tz;
|
dataz[currentPointer] = (int32_t)tz;
|
||||||
if (!accelInit) {
|
if (!accelInit) {
|
||||||
for (uint8_t i = currentPointer + 1; i < MOVFilter; i++) {
|
for (uint8_t i = currentPointer + 1; i < MOVFilter; i++) {
|
||||||
datax[i] = (int32_t) tx;
|
datax[i] = (int32_t)tx;
|
||||||
datay[i] = (int32_t) ty;
|
datay[i] = (int32_t)ty;
|
||||||
dataz[i] = (int32_t) tz;
|
dataz[i] = (int32_t)tz;
|
||||||
}
|
}
|
||||||
accelInit = 1;
|
accelInit = 1;
|
||||||
}
|
}
|
||||||
currentPointer = (currentPointer + 1) % MOVFilter;
|
currentPointer = (currentPointer + 1) % MOVFilter;
|
||||||
avgx = avgy = avgz = 0;
|
avgx = avgy = avgz = 0;
|
||||||
// calculate averages
|
// calculate averages
|
||||||
for (uint8_t i = 0; i < MOVFilter; i++) {
|
for (uint8_t i = 0; i < MOVFilter; i++) {
|
||||||
avgx += datax[i];
|
avgx += datax[i];
|
||||||
avgy += datay[i];
|
avgy += datay[i];
|
||||||
avgz += dataz[i];
|
avgz += dataz[i];
|
||||||
}
|
}
|
||||||
avgx /= MOVFilter;
|
avgx /= MOVFilter;
|
||||||
avgy /= MOVFilter;
|
avgy /= MOVFilter;
|
||||||
avgz /= MOVFilter;
|
avgz /= MOVFilter;
|
||||||
|
|
||||||
// Sum the deltas
|
// Sum the deltas
|
||||||
int32_t error = (abs(avgx - tx) + abs(avgy - ty) + abs(avgz - tz));
|
int32_t error = (abs(avgx - tx) + abs(avgy - ty) + abs(avgz - tz));
|
||||||
// So now we have averages, we want to look if these are different by more
|
// So now we have averages, we want to look if these are different by more
|
||||||
// than the threshold
|
// than the threshold
|
||||||
|
|
||||||
// If movement has occurred then we update the tick timer
|
// If movement has occurred then we update the tick timer
|
||||||
if (error > threshold) {
|
if (error > threshold) {
|
||||||
lastMovementTime = xTaskGetTickCount();
|
lastMovementTime = xTaskGetTickCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
osDelay(TICKS_100MS); // Slow down update rate
|
osDelay(TICKS_100MS); // Slow down update rate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,124 +5,119 @@
|
|||||||
* Author: Ralim
|
* Author: Ralim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "main.hpp"
|
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "power.hpp"
|
#include "FreeRTOS.h"
|
||||||
#include "history.hpp"
|
#include "Settings.h"
|
||||||
#include "TipThermoModel.h"
|
#include "TipThermoModel.h"
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
#include "FreeRTOS.h"
|
#include "history.hpp"
|
||||||
|
#include "main.hpp"
|
||||||
|
#include "power.hpp"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "Settings.h"
|
static TickType_t powerPulseRate = 10000;
|
||||||
static TickType_t powerPulseRate = 10000;
|
static TickType_t powerPulseDuration = 250;
|
||||||
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
|
|
||||||
|
|
||||||
/* StartPIDTask function */
|
/* StartPIDTask function */
|
||||||
void startPIDTask(void const *argument __unused) {
|
void startPIDTask(void const *argument __unused) {
|
||||||
/*
|
/*
|
||||||
* We take the current tip temperature & evaluate the next step for the tip
|
* We take the current tip temperature & evaluate the next step for the tip
|
||||||
* control PWM.
|
* control PWM.
|
||||||
*/
|
*/
|
||||||
setTipX10Watts(0); // disable the output driver if the output is set to be off
|
setTipX10Watts(0); // disable the output driver if the output is set to be off
|
||||||
TickType_t lastPowerPulseStart = 0;
|
TickType_t lastPowerPulseStart = 0;
|
||||||
TickType_t lastPowerPulseEnd = 0;
|
TickType_t lastPowerPulseEnd = 0;
|
||||||
|
|
||||||
history<int32_t, PID_TIM_HZ> tempError = { { 0 }, 0, 0 };
|
history<int32_t, PID_TIM_HZ> tempError = {{0}, 0, 0};
|
||||||
currentTempTargetDegC = 0; // Force start with no output (off). If in sleep / soldering this will
|
currentTempTargetDegC = 0; // Force start with no output (off). If in sleep / soldering this will
|
||||||
// be over-ridden rapidly
|
// be over-ridden rapidly
|
||||||
pidTaskNotification = xTaskGetCurrentTaskHandle();
|
pidTaskNotification = xTaskGetCurrentTaskHandle();
|
||||||
uint32_t PIDTempTarget = 0;
|
uint32_t PIDTempTarget = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (ulTaskNotifyTake(pdTRUE, 2000)) {
|
if (ulTaskNotifyTake(pdTRUE, 2000)) {
|
||||||
// This is a call to block this thread until the ADC does its samples
|
// This is a call to block this thread until the ADC does its samples
|
||||||
int32_t x10WattsOut = 0;
|
int32_t x10WattsOut = 0;
|
||||||
// Do the reading here to keep the temp calculations churning along
|
// Do the reading here to keep the temp calculations churning along
|
||||||
uint32_t currentTipTempInC = TipThermoModel::getTipInC(true);
|
uint32_t currentTipTempInC = TipThermoModel::getTipInC(true);
|
||||||
PIDTempTarget = currentTempTargetDegC;
|
PIDTempTarget = currentTempTargetDegC;
|
||||||
if (PIDTempTarget) {
|
if (PIDTempTarget) {
|
||||||
// Cap the max set point to 450C
|
// Cap the max set point to 450C
|
||||||
if (PIDTempTarget > (450)) {
|
if (PIDTempTarget > (450)) {
|
||||||
//Maximum allowed output
|
// Maximum allowed output
|
||||||
PIDTempTarget = (450);
|
PIDTempTarget = (450);
|
||||||
}
|
}
|
||||||
//Safety check that not aiming higher than current tip can measure
|
// Safety check that not aiming higher than current tip can measure
|
||||||
if (PIDTempTarget > TipThermoModel::getTipMaxInC()) {
|
if (PIDTempTarget > TipThermoModel::getTipMaxInC()) {
|
||||||
PIDTempTarget = TipThermoModel::getTipMaxInC();
|
PIDTempTarget = TipThermoModel::getTipMaxInC();
|
||||||
}
|
}
|
||||||
// Convert the current tip to degree's C
|
// Convert the current tip to degree's C
|
||||||
|
|
||||||
// As we get close to our target, temp noise causes the system
|
// As we get close to our target, temp noise causes the system
|
||||||
// to be unstable. Use a rolling average to dampen it.
|
// to be unstable. Use a rolling average to dampen it.
|
||||||
// We overshoot by roughly 1 degree C.
|
// We overshoot by roughly 1 degree C.
|
||||||
// This helps stabilize the display.
|
// This helps stabilize the display.
|
||||||
int32_t tError = PIDTempTarget - currentTipTempInC + 1;
|
int32_t tError = PIDTempTarget - currentTipTempInC + 1;
|
||||||
tError = tError > INT16_MAX ? INT16_MAX : tError;
|
tError = tError > INT16_MAX ? INT16_MAX : tError;
|
||||||
tError = tError < INT16_MIN ? INT16_MIN : tError;
|
tError = tError < INT16_MIN ? INT16_MIN : tError;
|
||||||
tempError.update(tError);
|
tempError.update(tError);
|
||||||
|
|
||||||
// Now for the PID!
|
// Now for the PID!
|
||||||
|
|
||||||
// P term - total power needed to hit target temp next cycle.
|
// P term - total power needed to hit target temp next cycle.
|
||||||
// thermal mass = 1690 milliJ/*C for my tip.
|
// thermal mass = 1690 milliJ/*C for my tip.
|
||||||
// = Watts*Seconds to raise Temp from room temp to +100*C, divided by 100*C.
|
// = Watts*Seconds to raise Temp from room temp to +100*C, divided by 100*C.
|
||||||
// we divide milliWattsNeeded by 20 to let the I term dominate near the set point.
|
// we divide milliWattsNeeded by 20 to let the I term dominate near the set point.
|
||||||
// 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.
|
||||||
|
|
||||||
int32_t x10WattsNeeded = tempToX10Watts(tError);
|
int32_t x10WattsNeeded = tempToX10Watts(tError);
|
||||||
// tempError.average());
|
// tempError.average());
|
||||||
// note that milliWattsNeeded is sometimes negative, this counters overshoot
|
// note that milliWattsNeeded is sometimes negative, this counters overshoot
|
||||||
// from I term's inertia.
|
// from I term's inertia.
|
||||||
x10WattsOut += x10WattsNeeded;
|
x10WattsOut += x10WattsNeeded;
|
||||||
|
|
||||||
// I term - energy needed to compensate for heat loss.
|
// I term - energy needed to compensate for heat loss.
|
||||||
// We track energy put into the system over some window.
|
// We track energy put into the system over some window.
|
||||||
// Assuming the temp is stable, energy in = energy transfered.
|
// Assuming the temp is stable, energy in = energy transfered.
|
||||||
// (If it isn't, P will dominate).
|
// (If it isn't, P will dominate).
|
||||||
x10WattsOut += x10WattHistory.average();
|
x10WattsOut += x10WattHistory.average();
|
||||||
|
|
||||||
// D term - use sudden temp change to counter fast cooling/heating.
|
// D term - use sudden temp change to counter fast cooling/heating.
|
||||||
// In practice, this provides an early boost if temp is dropping
|
// In practice, this provides an early boost if temp is dropping
|
||||||
// and counters extra power if the iron is no longer losing temp.
|
// and counters extra power if the iron is no longer losing temp.
|
||||||
// basically: temp - lastTemp
|
// basically: temp - lastTemp
|
||||||
// Unfortunately, our temp signal is too noisy to really help.
|
// Unfortunately, our temp signal is too noisy to really help.
|
||||||
|
}
|
||||||
|
// If the user turns on the option of using an occasional pulse to keep the power bank on
|
||||||
|
if (systemSettings.KeepAwakePulse) {
|
||||||
|
|
||||||
}
|
if (xTaskGetTickCount() - lastPowerPulseStart > powerPulseRate) {
|
||||||
//If the user turns on the option of using an occasional pulse to keep the power bank on
|
lastPowerPulseStart = xTaskGetTickCount();
|
||||||
if (systemSettings.KeepAwakePulse) {
|
lastPowerPulseEnd = lastPowerPulseStart + powerPulseDuration;
|
||||||
|
}
|
||||||
|
|
||||||
if (xTaskGetTickCount() - lastPowerPulseStart
|
// If current PID is less than the pulse level, check if we want to constrain to the pulse as the floor
|
||||||
> powerPulseRate) {
|
if (x10WattsOut < systemSettings.KeepAwakePulse && xTaskGetTickCount() < lastPowerPulseEnd) {
|
||||||
lastPowerPulseStart = xTaskGetTickCount();
|
x10WattsOut = systemSettings.KeepAwakePulse;
|
||||||
lastPowerPulseEnd = lastPowerPulseStart
|
}
|
||||||
+ powerPulseDuration;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//If current PID is less than the pulse level, check if we want to constrain to the pulse as the floor
|
// Secondary safety check to forcefully disable header when within ADC noise of top of ADC
|
||||||
if (x10WattsOut < systemSettings.KeepAwakePulse
|
if (getTipRawTemp(0) > (0x7FFF - 150)) {
|
||||||
&& xTaskGetTickCount() < lastPowerPulseEnd) {
|
x10WattsOut = 0;
|
||||||
x10WattsOut = systemSettings.KeepAwakePulse;
|
}
|
||||||
}
|
if (systemSettings.powerLimit && x10WattsOut > (systemSettings.powerLimit * 10)) {
|
||||||
}
|
setTipX10Watts(systemSettings.powerLimit * 10);
|
||||||
|
} else {
|
||||||
|
setTipX10Watts(x10WattsOut);
|
||||||
|
}
|
||||||
|
|
||||||
//Secondary safety check to forcefully disable header when within ADC noise of top of ADC
|
resetWatchdog();
|
||||||
if (getTipRawTemp(0) > (0x7FFF - 150)) {
|
} else {
|
||||||
x10WattsOut = 0;
|
// ADC interrupt timeout
|
||||||
}
|
setTipPWM(0);
|
||||||
if (systemSettings.powerLimit
|
}
|
||||||
&& x10WattsOut > (systemSettings.powerLimit * 10)) {
|
}
|
||||||
setTipX10Watts(systemSettings.powerLimit * 10);
|
|
||||||
} else {
|
|
||||||
setTipX10Watts(x10WattsOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
resetWatchdog();
|
|
||||||
} else {
|
|
||||||
//ADC interrupt timeout
|
|
||||||
setTipPWM(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
// Small worker thread to handle power (mostly QC) related steps
|
// Small worker thread to handle power (mostly QC) related steps
|
||||||
|
|
||||||
void startPOWTask(void const *argument __unused) {
|
void startPOWTask(void const *argument __unused) {
|
||||||
postRToSInit();
|
postRToSInit();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
osDelay(TICKS_100MS); // Slow down update rate
|
osDelay(TICKS_100MS); // Slow down update rate
|
||||||
power_check();
|
power_check();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,37 +25,37 @@
|
|||||||
* 1 tab == 4 spaces!
|
* 1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "croutine.h"
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "croutine.h"
|
|
||||||
|
|
||||||
/* Remove the whole file is co-routines are not being used. */
|
/* Remove the whole file is co-routines are not being used. */
|
||||||
#if( configUSE_CO_ROUTINES != 0 )
|
#if (configUSE_CO_ROUTINES != 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some kernel aware debuggers require data to be viewed to be global, rather
|
* Some kernel aware debuggers require data to be viewed to be global, rather
|
||||||
* than file scope.
|
* than file scope.
|
||||||
*/
|
*/
|
||||||
#ifdef portREMOVE_STATIC_QUALIFIER
|
#ifdef portREMOVE_STATIC_QUALIFIER
|
||||||
#define static
|
#define static
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Lists for ready and blocked co-routines. --------------------*/
|
/* Lists for ready and blocked co-routines. --------------------*/
|
||||||
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
static List_t pxReadyCoRoutineLists[configMAX_CO_ROUTINE_PRIORITIES]; /*< Prioritised ready co-routines. */
|
||||||
static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
||||||
static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
||||||
static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
|
static List_t *pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
|
||||||
static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
static List_t *pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
||||||
static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
|
static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by
|
||||||
|
interrupts. */
|
||||||
|
|
||||||
/* Other file private variables. --------------------------------*/
|
/* Other file private variables. --------------------------------*/
|
||||||
CRCB_t * pxCurrentCoRoutine = NULL;
|
CRCB_t * pxCurrentCoRoutine = NULL;
|
||||||
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
|
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
|
||||||
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||||
|
|
||||||
/* The initial state of the co-routine when it is created. */
|
/* The initial state of the co-routine when it is created. */
|
||||||
#define corINITIAL_STATE ( 0 )
|
#define corINITIAL_STATE (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Place the co-routine represented by pxCRCB into the appropriate ready queue
|
* Place the co-routine represented by pxCRCB into the appropriate ready queue
|
||||||
@@ -64,20 +64,19 @@ static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
|||||||
* This macro accesses the co-routine ready lists and therefore must not be
|
* This macro accesses the co-routine ready lists and therefore must not be
|
||||||
* used from within an ISR.
|
* used from within an ISR.
|
||||||
*/
|
*/
|
||||||
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
|
#define prvAddCoRoutineToReadyQueue(pxCRCB) \
|
||||||
{ \
|
{ \
|
||||||
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
|
if (pxCRCB->uxPriority > uxTopCoRoutineReadyPriority) { \
|
||||||
{ \
|
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
||||||
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
} \
|
||||||
} \
|
vListInsertEnd((List_t *)&(pxReadyCoRoutineLists[pxCRCB->uxPriority]), &(pxCRCB->xGenericListItem)); \
|
||||||
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility to ready all the lists used by the scheduler. This is called
|
* Utility to ready all the lists used by the scheduler. This is called
|
||||||
* automatically upon the creation of the first co-routine.
|
* automatically upon the creation of the first co-routine.
|
||||||
*/
|
*/
|
||||||
static void prvInitialiseCoRoutineLists( void );
|
static void prvInitialiseCoRoutineLists(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Co-routines that are readied by an interrupt cannot be placed directly into
|
* Co-routines that are readied by an interrupt cannot be placed directly into
|
||||||
@@ -85,7 +84,7 @@ static void prvInitialiseCoRoutineLists( void );
|
|||||||
* in the pending ready list in order that they can later be moved to the ready
|
* in the pending ready list in order that they can later be moved to the ready
|
||||||
* list by the co-routine scheduler.
|
* list by the co-routine scheduler.
|
||||||
*/
|
*/
|
||||||
static void prvCheckPendingReadyList( void );
|
static void prvCheckPendingReadyList(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro that looks at the list of co-routines that are currently delayed to
|
* Macro that looks at the list of co-routines that are currently delayed to
|
||||||
@@ -95,259 +94,230 @@ static void prvCheckPendingReadyList( void );
|
|||||||
* meaning once one co-routine has been found whose timer has not expired
|
* meaning once one co-routine has been found whose timer has not expired
|
||||||
* we need not look any further down the list.
|
* we need not look any further down the list.
|
||||||
*/
|
*/
|
||||||
static void prvCheckDelayedList( void );
|
static void prvCheckDelayedList(void);
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
|
BaseType_t xCoRoutineCreate(crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex) {
|
||||||
{
|
BaseType_t xReturn;
|
||||||
BaseType_t xReturn;
|
CRCB_t * pxCoRoutine;
|
||||||
CRCB_t *pxCoRoutine;
|
|
||||||
|
|
||||||
/* Allocate the memory that will store the co-routine control block. */
|
/* Allocate the memory that will store the co-routine control block. */
|
||||||
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
pxCoRoutine = (CRCB_t *)pvPortMalloc(sizeof(CRCB_t));
|
||||||
if( pxCoRoutine )
|
if (pxCoRoutine) {
|
||||||
{
|
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
||||||
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
be created and the co-routine data structures need initialising. */
|
||||||
be created and the co-routine data structures need initialising. */
|
if (pxCurrentCoRoutine == NULL) {
|
||||||
if( pxCurrentCoRoutine == NULL )
|
pxCurrentCoRoutine = pxCoRoutine;
|
||||||
{
|
prvInitialiseCoRoutineLists();
|
||||||
pxCurrentCoRoutine = pxCoRoutine;
|
}
|
||||||
prvInitialiseCoRoutineLists();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the priority is within limits. */
|
/* Check the priority is within limits. */
|
||||||
if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
|
if (uxPriority >= configMAX_CO_ROUTINE_PRIORITIES) {
|
||||||
{
|
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
|
||||||
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill out the co-routine control block from the function parameters. */
|
/* Fill out the co-routine control block from the function parameters. */
|
||||||
pxCoRoutine->uxState = corINITIAL_STATE;
|
pxCoRoutine->uxState = corINITIAL_STATE;
|
||||||
pxCoRoutine->uxPriority = uxPriority;
|
pxCoRoutine->uxPriority = uxPriority;
|
||||||
pxCoRoutine->uxIndex = uxIndex;
|
pxCoRoutine->uxIndex = uxIndex;
|
||||||
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
|
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
|
||||||
|
|
||||||
/* Initialise all the other co-routine control block parameters. */
|
/* Initialise all the other co-routine control block parameters. */
|
||||||
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
|
vListInitialiseItem(&(pxCoRoutine->xGenericListItem));
|
||||||
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
vListInitialiseItem(&(pxCoRoutine->xEventListItem));
|
||||||
|
|
||||||
/* Set the co-routine control block as a link back from the ListItem_t.
|
/* Set the co-routine control block as a link back from the ListItem_t.
|
||||||
This is so we can get back to the containing CRCB from a generic item
|
This is so we can get back to the containing CRCB from a generic item
|
||||||
in a list. */
|
in a list. */
|
||||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
listSET_LIST_ITEM_OWNER(&(pxCoRoutine->xGenericListItem), pxCoRoutine);
|
||||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
listSET_LIST_ITEM_OWNER(&(pxCoRoutine->xEventListItem), pxCoRoutine);
|
||||||
|
|
||||||
/* Event lists are always in priority order. */
|
/* Event lists are always in priority order. */
|
||||||
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
|
listSET_LIST_ITEM_VALUE(&(pxCoRoutine->xEventListItem), ((TickType_t)configMAX_CO_ROUTINE_PRIORITIES - (TickType_t)uxPriority));
|
||||||
|
|
||||||
/* Now the co-routine has been initialised it can be added to the ready
|
/* Now the co-routine has been initialised it can be added to the ready
|
||||||
list at the correct priority. */
|
list at the correct priority. */
|
||||||
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
prvAddCoRoutineToReadyQueue(pxCoRoutine);
|
||||||
|
|
||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
}
|
} else {
|
||||||
else
|
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||||
{
|
}
|
||||||
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
|
void vCoRoutineAddToDelayedList(TickType_t xTicksToDelay, List_t *pxEventList) {
|
||||||
{
|
TickType_t xTimeToWake;
|
||||||
TickType_t xTimeToWake;
|
|
||||||
|
|
||||||
/* Calculate the time to wake - this may overflow but this is
|
/* Calculate the time to wake - this may overflow but this is
|
||||||
not a problem. */
|
not a problem. */
|
||||||
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
||||||
|
|
||||||
/* We must remove ourselves from the ready list before adding
|
/* We must remove ourselves from the ready list before adding
|
||||||
ourselves to the blocked list as the same list item is used for
|
ourselves to the blocked list as the same list item is used for
|
||||||
both lists. */
|
both lists. */
|
||||||
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
(void)uxListRemove((ListItem_t *)&(pxCurrentCoRoutine->xGenericListItem));
|
||||||
|
|
||||||
/* The list item will be inserted in wake time order. */
|
/* The list item will be inserted in wake time order. */
|
||||||
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
|
listSET_LIST_ITEM_VALUE(&(pxCurrentCoRoutine->xGenericListItem), xTimeToWake);
|
||||||
|
|
||||||
if( xTimeToWake < xCoRoutineTickCount )
|
if (xTimeToWake < xCoRoutineTickCount) {
|
||||||
{
|
/* Wake time has overflowed. Place this item in the
|
||||||
/* Wake time has overflowed. Place this item in the
|
overflow list. */
|
||||||
overflow list. */
|
vListInsert((List_t *)pxOverflowDelayedCoRoutineList, (ListItem_t *)&(pxCurrentCoRoutine->xGenericListItem));
|
||||||
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
} else {
|
||||||
}
|
/* The wake time has not overflowed, so we can use the
|
||||||
else
|
current block list. */
|
||||||
{
|
vListInsert((List_t *)pxDelayedCoRoutineList, (ListItem_t *)&(pxCurrentCoRoutine->xGenericListItem));
|
||||||
/* The wake time has not overflowed, so we can use the
|
}
|
||||||
current block list. */
|
|
||||||
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pxEventList )
|
if (pxEventList) {
|
||||||
{
|
/* Also add the co-routine to an event list. If this is done then the
|
||||||
/* Also add the co-routine to an event list. If this is done then the
|
function must be called with interrupts disabled. */
|
||||||
function must be called with interrupts disabled. */
|
vListInsert(pxEventList, &(pxCurrentCoRoutine->xEventListItem));
|
||||||
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvCheckPendingReadyList( void )
|
static void prvCheckPendingReadyList(void) {
|
||||||
{
|
/* Are there any co-routines waiting to get moved to the ready list? These
|
||||||
/* Are there any co-routines waiting to get moved to the ready list? These
|
are co-routines that have been readied by an ISR. The ISR cannot access
|
||||||
are co-routines that have been readied by an ISR. The ISR cannot access
|
the ready lists itself. */
|
||||||
the ready lists itself. */
|
while (listLIST_IS_EMPTY(&xPendingReadyCoRoutineList) == pdFALSE) {
|
||||||
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
CRCB_t *pxUnblockedCRCB;
|
||||||
{
|
|
||||||
CRCB_t *pxUnblockedCRCB;
|
|
||||||
|
|
||||||
/* The pending ready list can be accessed by an ISR. */
|
/* The pending ready list can be accessed by an ISR. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
|
pxUnblockedCRCB = (CRCB_t *)listGET_OWNER_OF_HEAD_ENTRY((&xPendingReadyCoRoutineList));
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
(void)uxListRemove(&(pxUnblockedCRCB->xEventListItem));
|
||||||
}
|
}
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
(void)uxListRemove(&(pxUnblockedCRCB->xGenericListItem));
|
||||||
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
prvAddCoRoutineToReadyQueue(pxUnblockedCRCB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvCheckDelayedList( void )
|
static void prvCheckDelayedList(void) {
|
||||||
{
|
CRCB_t *pxCRCB;
|
||||||
CRCB_t *pxCRCB;
|
|
||||||
|
|
||||||
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
||||||
while( xPassedTicks )
|
while (xPassedTicks) {
|
||||||
{
|
xCoRoutineTickCount++;
|
||||||
xCoRoutineTickCount++;
|
xPassedTicks--;
|
||||||
xPassedTicks--;
|
|
||||||
|
|
||||||
/* If the tick count has overflowed we need to swap the ready lists. */
|
/* If the tick count has overflowed we need to swap the ready lists. */
|
||||||
if( xCoRoutineTickCount == 0 )
|
if (xCoRoutineTickCount == 0) {
|
||||||
{
|
List_t *pxTemp;
|
||||||
List_t * pxTemp;
|
|
||||||
|
|
||||||
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
||||||
any items in pxDelayedCoRoutineList here then there is an error! */
|
any items in pxDelayedCoRoutineList here then there is an error! */
|
||||||
pxTemp = pxDelayedCoRoutineList;
|
pxTemp = pxDelayedCoRoutineList;
|
||||||
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
||||||
pxOverflowDelayedCoRoutineList = pxTemp;
|
pxOverflowDelayedCoRoutineList = pxTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if this tick has made a timeout expire. */
|
/* See if this tick has made a timeout expire. */
|
||||||
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
|
while (listLIST_IS_EMPTY(pxDelayedCoRoutineList) == pdFALSE) {
|
||||||
{
|
pxCRCB = (CRCB_t *)listGET_OWNER_OF_HEAD_ENTRY(pxDelayedCoRoutineList);
|
||||||
pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
|
|
||||||
|
|
||||||
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
|
if (xCoRoutineTickCount < listGET_LIST_ITEM_VALUE(&(pxCRCB->xGenericListItem))) {
|
||||||
{
|
/* Timeout not yet expired. */
|
||||||
/* Timeout not yet expired. */
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
/* The event could have occurred just before this critical
|
/* The event could have occurred just before this critical
|
||||||
section. If this is the case then the generic list item will
|
section. If this is the case then the generic list item will
|
||||||
have been moved to the pending ready list and the following
|
have been moved to the pending ready list and the following
|
||||||
line is still valid. Also the pvContainer parameter will have
|
line is still valid. Also the pvContainer parameter will have
|
||||||
been set to NULL so the following lines are also valid. */
|
been set to NULL so the following lines are also valid. */
|
||||||
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
|
(void)uxListRemove(&(pxCRCB->xGenericListItem));
|
||||||
|
|
||||||
/* Is the co-routine waiting on an event also? */
|
/* Is the co-routine waiting on an event also? */
|
||||||
if( pxCRCB->xEventListItem.pxContainer )
|
if (pxCRCB->xEventListItem.pxContainer) {
|
||||||
{
|
(void)uxListRemove(&(pxCRCB->xEventListItem));
|
||||||
( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
|
}
|
||||||
}
|
}
|
||||||
}
|
portENABLE_INTERRUPTS();
|
||||||
portENABLE_INTERRUPTS();
|
|
||||||
|
|
||||||
prvAddCoRoutineToReadyQueue( pxCRCB );
|
prvAddCoRoutineToReadyQueue(pxCRCB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xLastTickCount = xCoRoutineTickCount;
|
xLastTickCount = xCoRoutineTickCount;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vCoRoutineSchedule( void )
|
void vCoRoutineSchedule(void) {
|
||||||
{
|
/* See if any co-routines readied by events need moving to the ready lists. */
|
||||||
/* See if any co-routines readied by events need moving to the ready lists. */
|
prvCheckPendingReadyList();
|
||||||
prvCheckPendingReadyList();
|
|
||||||
|
|
||||||
/* See if any delayed co-routines have timed out. */
|
/* See if any delayed co-routines have timed out. */
|
||||||
prvCheckDelayedList();
|
prvCheckDelayedList();
|
||||||
|
|
||||||
/* Find the highest priority queue that contains ready co-routines. */
|
/* Find the highest priority queue that contains ready co-routines. */
|
||||||
while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
|
while (listLIST_IS_EMPTY(&(pxReadyCoRoutineLists[uxTopCoRoutineReadyPriority]))) {
|
||||||
{
|
if (uxTopCoRoutineReadyPriority == 0) {
|
||||||
if( uxTopCoRoutineReadyPriority == 0 )
|
/* No more co-routines to check. */
|
||||||
{
|
return;
|
||||||
/* No more co-routines to check. */
|
}
|
||||||
return;
|
--uxTopCoRoutineReadyPriority;
|
||||||
}
|
}
|
||||||
--uxTopCoRoutineReadyPriority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
||||||
of the same priority get an equal share of the processor time. */
|
of the same priority get an equal share of the processor time. */
|
||||||
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
|
listGET_OWNER_OF_NEXT_ENTRY(pxCurrentCoRoutine, &(pxReadyCoRoutineLists[uxTopCoRoutineReadyPriority]));
|
||||||
|
|
||||||
/* Call the co-routine. */
|
/* Call the co-routine. */
|
||||||
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
|
(pxCurrentCoRoutine->pxCoRoutineFunction)(pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvInitialiseCoRoutineLists( void )
|
static void prvInitialiseCoRoutineLists(void) {
|
||||||
{
|
UBaseType_t uxPriority;
|
||||||
UBaseType_t uxPriority;
|
|
||||||
|
|
||||||
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
for (uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++) {
|
||||||
{
|
vListInitialise((List_t *)&(pxReadyCoRoutineLists[uxPriority]));
|
||||||
vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
|
}
|
||||||
}
|
|
||||||
|
|
||||||
vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
|
vListInitialise((List_t *)&xDelayedCoRoutineList1);
|
||||||
vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
|
vListInitialise((List_t *)&xDelayedCoRoutineList2);
|
||||||
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
|
vListInitialise((List_t *)&xPendingReadyCoRoutineList);
|
||||||
|
|
||||||
/* Start with pxDelayedCoRoutineList using list1 and the
|
/* Start with pxDelayedCoRoutineList using list1 and the
|
||||||
pxOverflowDelayedCoRoutineList using list2. */
|
pxOverflowDelayedCoRoutineList using list2. */
|
||||||
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
||||||
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList )
|
BaseType_t xCoRoutineRemoveFromEventList(const List_t *pxEventList) {
|
||||||
{
|
CRCB_t * pxUnblockedCRCB;
|
||||||
CRCB_t *pxUnblockedCRCB;
|
BaseType_t xReturn;
|
||||||
BaseType_t xReturn;
|
|
||||||
|
|
||||||
/* This function is called from within an interrupt. It can only access
|
/* This function is called from within an interrupt. It can only access
|
||||||
event lists and the pending ready list. This function assumes that a
|
event lists and the pending ready list. This function assumes that a
|
||||||
check has already been made to ensure pxEventList is not empty. */
|
check has already been made to ensure pxEventList is not empty. */
|
||||||
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
pxUnblockedCRCB = (CRCB_t *)listGET_OWNER_OF_HEAD_ENTRY(pxEventList);
|
||||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
(void)uxListRemove(&(pxUnblockedCRCB->xEventListItem));
|
||||||
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
vListInsertEnd((List_t *)&(xPendingReadyCoRoutineList), &(pxUnblockedCRCB->xEventListItem));
|
||||||
|
|
||||||
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
|
if (pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority) {
|
||||||
{
|
xReturn = pdTRUE;
|
||||||
xReturn = pdTRUE;
|
} else {
|
||||||
}
|
xReturn = pdFALSE;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
xReturn = pdFALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_CO_ROUTINES == 0 */
|
#endif /* configUSE_CO_ROUTINES == 0 */
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,174 +25,164 @@
|
|||||||
* 1 tab == 4 spaces!
|
* 1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* PUBLIC LIST API documented in list.h
|
* PUBLIC LIST API documented in list.h
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialise( List_t * const pxList )
|
void vListInitialise(List_t *const pxList) {
|
||||||
{
|
/* The list structure contains a list item which is used to mark the
|
||||||
/* The list structure contains a list item which is used to mark the
|
end of the list. To initialise the list the list end is inserted
|
||||||
end of the list. To initialise the list the list end is inserted
|
as the only list entry. */
|
||||||
as the only list entry. */
|
pxList->pxIndex = (ListItem_t *)&(pxList->xListEnd); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
|
||||||
|
|
||||||
/* The list end value is the highest possible value in the list to
|
/* The list end value is the highest possible value in the list to
|
||||||
ensure it remains at the end of the list. */
|
ensure it remains at the end of the list. */
|
||||||
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
||||||
|
|
||||||
/* The list end next and previous pointers point to itself so we know
|
/* The list end next and previous pointers point to itself so we know
|
||||||
when the list is empty. */
|
when the list is empty. */
|
||||||
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->xListEnd.pxNext = (ListItem_t *)&(pxList->xListEnd); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->xListEnd.pxPrevious = (ListItem_t *)&(pxList->xListEnd); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
|
||||||
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
pxList->uxNumberOfItems = (UBaseType_t)0U;
|
||||||
|
|
||||||
/* Write known values into the list if
|
/* Write known values into the list if
|
||||||
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
listSET_LIST_INTEGRITY_CHECK_1_VALUE(pxList);
|
||||||
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
listSET_LIST_INTEGRITY_CHECK_2_VALUE(pxList);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialiseItem( ListItem_t * const pxItem )
|
void vListInitialiseItem(ListItem_t *const pxItem) {
|
||||||
{
|
/* Make sure the list item is not recorded as being on a list. */
|
||||||
/* Make sure the list item is not recorded as being on a list. */
|
pxItem->pxContainer = NULL;
|
||||||
pxItem->pxContainer = NULL;
|
|
||||||
|
|
||||||
/* Write known values into the list item if
|
/* Write known values into the list item if
|
||||||
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||||
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem);
|
||||||
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
|
void vListInsertEnd(List_t *const pxList, ListItem_t *const pxNewListItem) {
|
||||||
{
|
ListItem_t *const pxIndex = pxList->pxIndex;
|
||||||
ListItem_t * const pxIndex = pxList->pxIndex;
|
|
||||||
|
|
||||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||||
the list data structures being overwritten in memory. They will not catch
|
the list data structures being overwritten in memory. They will not catch
|
||||||
data errors caused by incorrect configuration or use of FreeRTOS. */
|
data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||||
listTEST_LIST_INTEGRITY( pxList );
|
listTEST_LIST_INTEGRITY(pxList);
|
||||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
listTEST_LIST_ITEM_INTEGRITY(pxNewListItem);
|
||||||
|
|
||||||
/* Insert a new list item into pxList, but rather than sort the list,
|
/* Insert a new list item into pxList, but rather than sort the list,
|
||||||
makes the new list item the last item to be removed by a call to
|
makes the new list item the last item to be removed by a call to
|
||||||
listGET_OWNER_OF_NEXT_ENTRY(). */
|
listGET_OWNER_OF_NEXT_ENTRY(). */
|
||||||
pxNewListItem->pxNext = pxIndex;
|
pxNewListItem->pxNext = pxIndex;
|
||||||
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
||||||
|
|
||||||
/* Only used during decision coverage testing. */
|
/* Only used during decision coverage testing. */
|
||||||
mtCOVERAGE_TEST_DELAY();
|
mtCOVERAGE_TEST_DELAY();
|
||||||
|
|
||||||
pxIndex->pxPrevious->pxNext = pxNewListItem;
|
pxIndex->pxPrevious->pxNext = pxNewListItem;
|
||||||
pxIndex->pxPrevious = pxNewListItem;
|
pxIndex->pxPrevious = pxNewListItem;
|
||||||
|
|
||||||
/* Remember which list the item is in. */
|
/* Remember which list the item is in. */
|
||||||
pxNewListItem->pxContainer = pxList;
|
pxNewListItem->pxContainer = pxList;
|
||||||
|
|
||||||
( pxList->uxNumberOfItems )++;
|
(pxList->uxNumberOfItems)++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
|
void vListInsert(List_t *const pxList, ListItem_t *const pxNewListItem) {
|
||||||
{
|
ListItem_t * pxIterator;
|
||||||
ListItem_t *pxIterator;
|
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
|
||||||
|
|
||||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||||
the list data structures being overwritten in memory. They will not catch
|
the list data structures being overwritten in memory. They will not catch
|
||||||
data errors caused by incorrect configuration or use of FreeRTOS. */
|
data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||||
listTEST_LIST_INTEGRITY( pxList );
|
listTEST_LIST_INTEGRITY(pxList);
|
||||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
listTEST_LIST_ITEM_INTEGRITY(pxNewListItem);
|
||||||
|
|
||||||
/* Insert the new list item into the list, sorted in xItemValue order.
|
/* Insert the new list item into the list, sorted in xItemValue order.
|
||||||
|
|
||||||
If the list already contains a list item with the same item value then the
|
If the list already contains a list item with the same item value then the
|
||||||
new list item should be placed after it. This ensures that TCBs which are
|
new list item should be placed after it. This ensures that TCBs which are
|
||||||
stored in ready lists (all of which have the same xItemValue value) get a
|
stored in ready lists (all of which have the same xItemValue value) get a
|
||||||
share of the CPU. However, if the xItemValue is the same as the back marker
|
share of the CPU. However, if the xItemValue is the same as the back marker
|
||||||
the iteration loop below will not end. Therefore the value is checked
|
the iteration loop below will not end. Therefore the value is checked
|
||||||
first, and the algorithm slightly modified if necessary. */
|
first, and the algorithm slightly modified if necessary. */
|
||||||
if( xValueOfInsertion == portMAX_DELAY )
|
if (xValueOfInsertion == portMAX_DELAY) {
|
||||||
{
|
pxIterator = pxList->xListEnd.pxPrevious;
|
||||||
pxIterator = pxList->xListEnd.pxPrevious;
|
} else {
|
||||||
}
|
/* *** NOTE ***********************************************************
|
||||||
else
|
If you find your application is crashing here then likely causes are
|
||||||
{
|
listed below. In addition see https://www.freertos.org/FAQHelp.html for
|
||||||
/* *** NOTE ***********************************************************
|
more tips, and ensure configASSERT() is defined!
|
||||||
If you find your application is crashing here then likely causes are
|
https://www.freertos.org/a00110.html#configASSERT
|
||||||
listed below. In addition see https://www.freertos.org/FAQHelp.html for
|
|
||||||
more tips, and ensure configASSERT() is defined!
|
|
||||||
https://www.freertos.org/a00110.html#configASSERT
|
|
||||||
|
|
||||||
1) Stack overflow -
|
1) Stack overflow -
|
||||||
see https://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
see https://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||||
2) Incorrect interrupt priority assignment, especially on Cortex-M
|
2) Incorrect interrupt priority assignment, especially on Cortex-M
|
||||||
parts where numerically high priority values denote low actual
|
parts where numerically high priority values denote low actual
|
||||||
interrupt priorities, which can seem counter intuitive. See
|
interrupt priorities, which can seem counter intuitive. See
|
||||||
https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
||||||
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
||||||
https://www.freertos.org/a00110.html
|
https://www.freertos.org/a00110.html
|
||||||
3) Calling an API function from within a critical section or when
|
3) Calling an API function from within a critical section or when
|
||||||
the scheduler is suspended, or calling an API function that does
|
the scheduler is suspended, or calling an API function that does
|
||||||
not end in "FromISR" from an interrupt.
|
not end in "FromISR" from an interrupt.
|
||||||
4) Using a queue or semaphore before it has been initialised or
|
4) Using a queue or semaphore before it has been initialised or
|
||||||
before the scheduler has been started (are interrupts firing
|
before the scheduler has been started (are interrupts firing
|
||||||
before vTaskStartScheduler() has been called?).
|
before vTaskStartScheduler() has been called?).
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
for (pxIterator = (ListItem_t *)&(pxList->xListEnd); pxIterator->pxNext->xItemValue <= xValueOfInsertion;
|
||||||
{
|
pxIterator
|
||||||
/* There is nothing to do here, just iterating to the wanted
|
= pxIterator->pxNext) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ /*lint !e440 The iterator moves to a
|
||||||
insertion position. */
|
different value, not xValueOfInsertion. */
|
||||||
}
|
{
|
||||||
}
|
/* There is nothing to do here, just iterating to the wanted
|
||||||
|
insertion position. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pxNewListItem->pxNext = pxIterator->pxNext;
|
pxNewListItem->pxNext = pxIterator->pxNext;
|
||||||
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
|
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
|
||||||
pxNewListItem->pxPrevious = pxIterator;
|
pxNewListItem->pxPrevious = pxIterator;
|
||||||
pxIterator->pxNext = pxNewListItem;
|
pxIterator->pxNext = pxNewListItem;
|
||||||
|
|
||||||
/* Remember which list the item is in. This allows fast removal of the
|
/* Remember which list the item is in. This allows fast removal of the
|
||||||
item later. */
|
item later. */
|
||||||
pxNewListItem->pxContainer = pxList;
|
pxNewListItem->pxContainer = pxList;
|
||||||
|
|
||||||
( pxList->uxNumberOfItems )++;
|
(pxList->uxNumberOfItems)++;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
UBaseType_t uxListRemove(ListItem_t *const pxItemToRemove) {
|
||||||
{
|
/* The list item knows which list it is in. Obtain the list from the list
|
||||||
/* The list item knows which list it is in. Obtain the list from the list
|
item. */
|
||||||
item. */
|
List_t *const pxList = pxItemToRemove->pxContainer;
|
||||||
List_t * const pxList = pxItemToRemove->pxContainer;
|
|
||||||
|
|
||||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||||
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||||
|
|
||||||
/* Only used during decision coverage testing. */
|
/* Only used during decision coverage testing. */
|
||||||
mtCOVERAGE_TEST_DELAY();
|
mtCOVERAGE_TEST_DELAY();
|
||||||
|
|
||||||
/* Make sure the index is left pointing to a valid item. */
|
/* Make sure the index is left pointing to a valid item. */
|
||||||
if( pxList->pxIndex == pxItemToRemove )
|
if (pxList->pxIndex == pxItemToRemove) {
|
||||||
{
|
pxList->pxIndex = pxItemToRemove->pxPrevious;
|
||||||
pxList->pxIndex = pxItemToRemove->pxPrevious;
|
} else {
|
||||||
}
|
mtCOVERAGE_TEST_MARKER();
|
||||||
else
|
}
|
||||||
{
|
|
||||||
mtCOVERAGE_TEST_MARKER();
|
|
||||||
}
|
|
||||||
|
|
||||||
pxItemToRemove->pxContainer = NULL;
|
pxItemToRemove->pxContainer = NULL;
|
||||||
( pxList->uxNumberOfItems )--;
|
(pxList->uxNumberOfItems)--;
|
||||||
|
|
||||||
return pxList->uxNumberOfItems;
|
return pxList->uxNumberOfItems;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|||||||
4339
source/Middlewares/Third_Party/FreeRTOS/Source/queue.c
vendored
4339
source/Middlewares/Third_Party/FreeRTOS/Source/queue.c
vendored
File diff suppressed because it is too large
Load Diff
7544
source/Middlewares/Third_Party/FreeRTOS/Source/tasks.c
vendored
7544
source/Middlewares/Third_Party/FreeRTOS/Source/tasks.c
vendored
File diff suppressed because it is too large
Load Diff
1416
source/Middlewares/Third_Party/FreeRTOS/Source/timers.c
vendored
1416
source/Middlewares/Third_Party/FreeRTOS/Source/timers.c
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user