mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
Bulk format
This commit is contained in:
@@ -21,92 +21,88 @@ 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)));
|
for (uint32_t i = 0; i < (sizeof(NTCHandleLookup) / (2 * sizeof(uint16_t)));
|
||||||
i++)
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,8 +126,7 @@ uint16_t getHandleTemperature()
|
|||||||
#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.
|
||||||
@@ -146,29 +141,23 @@ uint16_t getTipInstantTemperature()
|
|||||||
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) {
|
||||||
{
|
|
||||||
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
|
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
|
||||||
// Therefore we can divide down from there
|
// Therefore we can divide down from there
|
||||||
// Multiplying ADC max by 4 for additional calibration options,
|
// Multiplying ADC max by 4 for additional calibration options,
|
||||||
@@ -182,14 +171,12 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@@ -199,23 +186,20 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample)
|
|||||||
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;
|
totalPWM = powerPWM + tempMeasureTicks * 2;
|
||||||
htim2.Instance->ARR = totalPWM;
|
htim2.Instance->ARR = totalPWM;
|
||||||
@@ -225,8 +209,7 @@ static void switchToFastPWM(void)
|
|||||||
htim2.Instance->PSC = 2000;
|
htim2.Instance->PSC = 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void switchToSlowPWM(void)
|
static void switchToSlowPWM(void) {
|
||||||
{
|
|
||||||
fastPWM = false;
|
fastPWM = false;
|
||||||
totalPWM = powerPWM + tempMeasureTicks;
|
totalPWM = powerPWM + tempMeasureTicks;
|
||||||
htim2.Instance->ARR = totalPWM;
|
htim2.Instance->ARR = totalPWM;
|
||||||
@@ -236,16 +219,12 @@ static void switchToSlowPWM(void)
|
|||||||
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)
|
||||||
@@ -258,11 +237,9 @@ bool tryBetterPWM(uint8_t pwm)
|
|||||||
// 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
|
||||||
@@ -271,32 +248,24 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
|||||||
// 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;
|
||||||
@@ -320,8 +289,7 @@ void unstick_I2C()
|
|||||||
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");
|
||||||
@@ -366,26 +334,23 @@ void unstick_I2C()
|
|||||||
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 ?
|
||||||
return HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ? 1 : 0;
|
1 : 0;
|
||||||
}
|
}
|
||||||
uint8_t getButtonB()
|
uint8_t getButtonB() {
|
||||||
{
|
return HAL_GPIO_ReadPin(KEY_B_GPIO_Port, KEY_B_Pin) == GPIO_PIN_RESET ?
|
||||||
return HAL_GPIO_ReadPin(KEY_B_GPIO_Port, KEY_B_Pin) == GPIO_PIN_RESET ? 1 : 0;
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,89 +11,97 @@ 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, uint8_t *pData, uint16_t Size) {
|
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
|
||||||
|
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, pData, Size, 500) != HAL_OK) {
|
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT,
|
||||||
|
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) {
|
bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
|
||||||
return Mem_Write(address, reg, &data, 1);
|
return Mem_Write(address, reg, &data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
|
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
|
||||||
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, uint8_t *pData, uint16_t Size) {
|
bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||||
|
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, pData, Size, 500) != HAL_OK) {
|
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT,
|
||||||
|
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) != HAL_OK) {
|
if (HAL_I2C_Master_Transmit_DMA(&hi2c1, DevAddress, pData, Size)
|
||||||
I2C_Unstick();
|
!= HAL_OK) {
|
||||||
unlock();
|
I2C_Unstick();
|
||||||
return false;
|
unlock();
|
||||||
}
|
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, I2C_MEMADD_SIZE_8BIT, buffer, 1, 1000) == HAL_OK;
|
bool worked = HAL_I2C_Mem_Read(&hi2c1, DevAddress, 0x0F,
|
||||||
unlock();
|
I2C_MEMADD_SIZE_8BIT, buffer, 1, 1000) == HAL_OK;
|
||||||
return worked;
|
unlock();
|
||||||
|
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, const I2C_REG *registers, const uint8_t registersLength) {
|
bool FRToSI2C::writeRegistersBulk(const uint8_t address,
|
||||||
for (int index = 0; index < registersLength; index++) {
|
const I2C_REG *registers, const uint8_t registersLength) {
|
||||||
if (!I2C_RegisterWrite(address, registers[index].reg, registers[index].val)) {
|
for (int index = 0; index < registersLength; index++) {
|
||||||
return false;
|
if (!I2C_RegisterWrite(address, registers[index].reg,
|
||||||
}
|
registers[index].val)) {
|
||||||
if (registers[index].pause_ms)
|
return false;
|
||||||
delay_ms(registers[index].pause_ms);
|
}
|
||||||
}
|
if (registers[index].pause_ms)
|
||||||
return true;
|
delay_ms(registers[index].pause_ms);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,6 @@ void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,65 +12,67 @@
|
|||||||
#include "Model_Config.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() { return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET ? 1 : 0; }
|
uint8_t QC_DM_PulledDown() {
|
||||||
|
return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET ? 1 : 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
void QC_resync() {
|
void QC_resync() {
|
||||||
#ifdef POW_QC
|
#ifdef POW_QC
|
||||||
seekQC((systemSettings.cutoutSetting) ? 120 : 90,
|
seekQC((systemSettings.cutoutSetting) ? 120 : 90,
|
||||||
systemSettings.voltageDiv); // Run the QC seek again if we have drifted too much
|
systemSettings.voltageDiv); // Run the QC seek again if we have drifted too much
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ static void MX_TIM2_Init(void) {
|
|||||||
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);
|
||||||
|
|||||||
@@ -22,6 +22,4 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BSP_MINIWARE_SOFTWARE_I2C_H_ */
|
#endif /* BSP_MINIWARE_SOFTWARE_I2C_H_ */
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
|
|||||||
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(
|
||||||
@@ -33,8 +33,8 @@ uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
|
|||||||
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],
|
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,
|
||||||
data[i]);
|
(uint32_t) &settings_page[i], data[i]);
|
||||||
}
|
}
|
||||||
HAL_FLASH_Lock();
|
HAL_FLASH_Lock();
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -78,16 +78,16 @@ void fusb_send_message(const union pd_msg *msg) {
|
|||||||
}
|
}
|
||||||
/* Token sequences for the FUSB302B */
|
/* Token sequences for the FUSB302B */
|
||||||
static uint8_t sop_seq[5] = {
|
static uint8_t sop_seq[5] = {
|
||||||
FUSB_FIFO_TX_SOP1,
|
FUSB_FIFO_TX_SOP1,
|
||||||
FUSB_FIFO_TX_SOP1,
|
FUSB_FIFO_TX_SOP1,
|
||||||
FUSB_FIFO_TX_SOP1,
|
FUSB_FIFO_TX_SOP1,
|
||||||
FUSB_FIFO_TX_SOP2,
|
FUSB_FIFO_TX_SOP2,
|
||||||
FUSB_FIFO_TX_PACKSYM};
|
FUSB_FIFO_TX_PACKSYM };
|
||||||
static const uint8_t eop_seq[4] = {
|
static const uint8_t eop_seq[4] = {
|
||||||
FUSB_FIFO_TX_JAM_CRC,
|
FUSB_FIFO_TX_JAM_CRC,
|
||||||
FUSB_FIFO_TX_EOP,
|
FUSB_FIFO_TX_EOP,
|
||||||
FUSB_FIFO_TX_TXOFF,
|
FUSB_FIFO_TX_TXOFF,
|
||||||
FUSB_FIFO_TX_TXON};
|
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
|
||||||
@@ -170,7 +170,7 @@ bool fusb_setup() {
|
|||||||
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);
|
||||||
@@ -226,7 +226,7 @@ enum fusb_typec_current fusb_get_typec_current() {
|
|||||||
}
|
}
|
||||||
/* Read the BC_LVL into a variable */
|
/* Read the BC_LVL into a variable */
|
||||||
enum fusb_typec_current bc_lvl = (enum fusb_typec_current) (fusb_read_byte(
|
enum fusb_typec_current bc_lvl = (enum fusb_typec_current) (fusb_read_byte(
|
||||||
FUSB_STATUS0) & FUSB_STATUS0_BC_LVL);
|
FUSB_STATUS0) & FUSB_STATUS0_BC_LVL);
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
I2CBB::unlock2();
|
I2CBB::unlock2();
|
||||||
}
|
}
|
||||||
@@ -256,7 +256,7 @@ bool fusb_read_id() {
|
|||||||
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() {
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ static uint8_t logo_page[1024] __attribute__ ((section (".logo_page")));
|
|||||||
|
|
||||||
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
|
if (LOGO_HEADER_VALUE != *(reinterpret_cast<const uint32_t*>(logo_page))) {
|
||||||
!= *(reinterpret_cast<const uint32_t*>(logo_page))) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,16 +34,16 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
|
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
|
||||||
defined. The value should also ensure backward compatibility.
|
defined. The value should also ensure backward compatibility.
|
||||||
FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
||||||
#ifndef configKERNEL_INTERRUPT_PRIORITY
|
#ifndef configKERNEL_INTERRUPT_PRIORITY
|
||||||
#define configKERNEL_INTERRUPT_PRIORITY 255
|
#define configKERNEL_INTERRUPT_PRIORITY 255
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configSYSTICK_CLOCK_HZ
|
#ifndef configSYSTICK_CLOCK_HZ
|
||||||
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
|
||||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||||
#else
|
#else
|
||||||
/* The way the SysTick is clocked is not modified in case it is not the same
|
/* The way the SysTick is clocked is not modified in case it is not the same
|
||||||
as the core. */
|
as the core. */
|
||||||
@@ -85,21 +85,21 @@ FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
|||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||||
|
|
||||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||||
occurred while the SysTick counter is stopped during tickless idle
|
occurred while the SysTick counter is stopped during tickless idle
|
||||||
calculations. */
|
calculations. */
|
||||||
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
||||||
|
|
||||||
/* For strict compliance with the Cortex-M spec the task start address should
|
/* For strict compliance with the Cortex-M spec the task start address should
|
||||||
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
|
||||||
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL )
|
||||||
|
|
||||||
/* Let the user override the pre-loading of the initial LR with the address of
|
/* Let the user override the pre-loading of the initial LR with the address of
|
||||||
prvTaskExitError() in case it messes up unwinding of the stack in the
|
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||||
debugger. */
|
debugger. */
|
||||||
#ifdef configTASK_RETURN_ADDRESS
|
#ifdef configTASK_RETURN_ADDRESS
|
||||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||||
#else
|
#else
|
||||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -107,29 +107,29 @@ debugger. */
|
|||||||
* file is weak to allow application writers to change the timer used to
|
* file is weak to allow application writers to change the timer used to
|
||||||
* generate the tick interrupt.
|
* generate the tick interrupt.
|
||||||
*/
|
*/
|
||||||
void vPortSetupTimerInterrupt( void );
|
void vPortSetupTimerInterrupt(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exception handlers.
|
* Exception handlers.
|
||||||
*/
|
*/
|
||||||
void xPortPendSVHandler( void ) __attribute__ (( naked ));
|
void xPortPendSVHandler(void) __attribute__ (( naked ));
|
||||||
void xPortSysTickHandler( void );
|
void xPortSysTickHandler(void);
|
||||||
void vPortSVCHandler( void ) __attribute__ (( naked ));
|
void vPortSVCHandler(void) __attribute__ (( naked ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start first task is a separate function so it can be tested in isolation.
|
* Start first task is a separate function so it can be tested in isolation.
|
||||||
*/
|
*/
|
||||||
static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
|
static void prvPortStartFirstTask(void) __attribute__ (( naked ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to catch tasks that attempt to return from their implementing function.
|
* Used to catch tasks that attempt to return from their implementing function.
|
||||||
*/
|
*/
|
||||||
static void prvTaskExitError( void );
|
static void prvTaskExitError(void);
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Each task maintains its own interrupt status in the critical nesting
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
variable. */
|
variable. */
|
||||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -161,9 +161,10 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
|||||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
*/
|
*/
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
static uint8_t ucMaxSysCallPriority = 0;
|
static uint8_t ucMaxSysCallPriority = 0;
|
||||||
static uint32_t ulMaxPRIGROUPValue = 0;
|
static uint32_t ulMaxPRIGROUPValue = 0;
|
||||||
static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
static const volatile uint8_t *const pcInterruptPriorityRegisters =
|
||||||
|
(const volatile uint8_t* const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
@@ -171,129 +172,126 @@ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
|||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
StackType_t* pxPortInitialiseStack(StackType_t *pxTopOfStack,
|
||||||
{
|
TaskFunction_t pxCode, void *pvParameters) {
|
||||||
/* Simulate the stack frame as it would be created by a context switch
|
/* Simulate the stack frame as it would be created by a context switch
|
||||||
interrupt. */
|
interrupt. */
|
||||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */
|
*pxTopOfStack = ((StackType_t) pxCode) & portSTART_ADDRESS_MASK; /* PC */
|
||||||
pxTopOfStack--;
|
pxTopOfStack--;
|
||||||
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */
|
*pxTopOfStack = (StackType_t) portTASK_RETURN_ADDRESS; /* LR */
|
||||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
*pxTopOfStack = (StackType_t) pvParameters; /* R0 */
|
||||||
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvTaskExitError( void )
|
static void prvTaskExitError(void) {
|
||||||
{
|
volatile uint32_t ulDummy = 0UL;
|
||||||
volatile uint32_t ulDummy = 0UL;
|
|
||||||
|
|
||||||
/* A function that implements a task must not exit or attempt to return to
|
/* A function that implements a task must not exit or attempt to return to
|
||||||
its caller as there is nothing to return to. If a task wants to exit it
|
its caller as there is nothing to return to. If a task wants to exit it
|
||||||
should instead call vTaskDelete( NULL ).
|
should instead call vTaskDelete( NULL ).
|
||||||
|
|
||||||
Artificially force an assert() to be triggered if configASSERT() is
|
Artificially force an assert() to be triggered if configASSERT() is
|
||||||
defined, then stop here so application writers can catch the error. */
|
defined, then stop here so application writers can catch the error. */
|
||||||
configASSERT( uxCriticalNesting == ~0UL );
|
configASSERT(uxCriticalNesting == ~0UL);
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
while( ulDummy == 0 )
|
while (ulDummy == 0) {
|
||||||
{
|
|
||||||
/* This file calls prvTaskExitError() after the scheduler has been
|
/* This file calls prvTaskExitError() after the scheduler has been
|
||||||
started to remove a compiler warning about the function being defined
|
started to remove a compiler warning about the function being defined
|
||||||
but never called. ulDummy is used purely to quieten other warnings
|
but never called. ulDummy is used purely to quieten other warnings
|
||||||
about code appearing after this function is called - making ulDummy
|
about code appearing after this function is called - making ulDummy
|
||||||
volatile makes the compiler think the function could return and
|
volatile makes the compiler think the function could return and
|
||||||
therefore not output an 'unreachable code' warning for code that appears
|
therefore not output an 'unreachable code' warning for code that appears
|
||||||
after it. */
|
after it. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortSVCHandler( void )
|
void vPortSVCHandler(void) {
|
||||||
{
|
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
" ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
|
" ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
|
||||||
" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
|
" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
" ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
|
||||||
" msr psp, r0 \n" /* Restore the task stack pointer. */
|
" msr psp, r0 \n" /* Restore the task stack pointer. */
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
" orr r14, #0xd \n"
|
" orr r14, #0xd \n"
|
||||||
" bx r14 \n"
|
" bx r14 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvPortStartFirstTask( void )
|
static void prvPortStartFirstTask(void) {
|
||||||
{
|
|
||||||
__asm volatile(
|
__asm volatile(
|
||||||
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
|
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
" ldr r0, [r0] \n"
|
" ldr r0, [r0] \n"
|
||||||
" ldr r0, [r0] \n"
|
" ldr r0, [r0] \n"
|
||||||
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
|
||||||
" cpsie i \n" /* Globally enable interrupts. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
" cpsie f \n"
|
" cpsie f \n"
|
||||||
" dsb \n"
|
" dsb \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" svc 0 \n" /* System call to start first task. */
|
" svc 0 \n" /* System call to start first task. */
|
||||||
" nop \n"
|
" nop \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
BaseType_t xPortStartScheduler( void )
|
BaseType_t xPortStartScheduler(void) {
|
||||||
{
|
|
||||||
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
||||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
|
||||||
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
|
configASSERT(configMAX_SYSCALL_INTERRUPT_PRIORITY);
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
{
|
{
|
||||||
volatile uint32_t ulOriginalPriority;
|
volatile uint32_t ulOriginalPriority;
|
||||||
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
|
volatile uint8_t *const pucFirstUserPriorityRegister =
|
||||||
|
(volatile uint8_t* const ) ( portNVIC_IP_REGISTERS_OFFSET_16
|
||||||
|
+ portFIRST_USER_INTERRUPT_NUMBER);
|
||||||
volatile uint8_t ucMaxPriorityValue;
|
volatile uint8_t ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
/* Determine the maximum priority from which ISR safe FreeRTOS API
|
||||||
functions can be called. ISR safe functions are those that end in
|
functions can be called. ISR safe functions are those that end in
|
||||||
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
|
||||||
ensure interrupt entry is as fast and simple as possible.
|
ensure interrupt entry is as fast and simple as possible.
|
||||||
|
|
||||||
Save the interrupt priority value that is about to be clobbered. */
|
Save the interrupt priority value that is about to be clobbered. */
|
||||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Determine the number of priority bits available. First write to all
|
/* Determine the number of priority bits available. First write to all
|
||||||
possible bits. */
|
possible bits. */
|
||||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||||
|
|
||||||
/* Read the value back to see how many bits stuck. */
|
/* Read the value back to see how many bits stuck. */
|
||||||
ucMaxPriorityValue = *pucFirstUserPriorityRegister;
|
ucMaxPriorityValue = *pucFirstUserPriorityRegister;
|
||||||
|
|
||||||
/* Use the same mask on the maximum system call priority. */
|
/* Use the same mask on the maximum system call priority. */
|
||||||
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
|
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
|
& ucMaxPriorityValue;
|
||||||
|
|
||||||
/* Calculate the maximum acceptable priority group value for the number
|
/* Calculate the maximum acceptable priority group value for the number
|
||||||
of bits read back. */
|
of bits read back. */
|
||||||
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
|
||||||
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
|
while ((ucMaxPriorityValue & portTOP_BIT_OF_BYTE) == portTOP_BIT_OF_BYTE) {
|
||||||
{
|
|
||||||
ulMaxPRIGROUPValue--;
|
ulMaxPRIGROUPValue--;
|
||||||
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
|
ucMaxPriorityValue <<= (uint8_t) 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __NVIC_PRIO_BITS
|
#ifdef __NVIC_PRIO_BITS
|
||||||
{
|
{
|
||||||
/* Check the CMSIS configuration that defines the number of
|
/* Check the CMSIS configuration that defines the number of
|
||||||
priority bits matches the number of priority bits actually queried
|
priority bits matches the number of priority bits actually queried
|
||||||
@@ -302,7 +300,7 @@ BaseType_t xPortStartScheduler( void )
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef configPRIO_BITS
|
#ifdef configPRIO_BITS
|
||||||
{
|
{
|
||||||
/* Check the FreeRTOS configuration that defines the number of
|
/* Check the FreeRTOS configuration that defines the number of
|
||||||
priority bits matches the number of priority bits actually queried
|
priority bits matches the number of priority bits actually queried
|
||||||
@@ -312,22 +310,22 @@ BaseType_t xPortStartScheduler( void )
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Shift the priority group value back to its position within the AIRCR
|
/* Shift the priority group value back to its position within the AIRCR
|
||||||
register. */
|
register. */
|
||||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||||
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
|
||||||
|
|
||||||
/* Restore the clobbered interrupt priority register to its original
|
/* Restore the clobbered interrupt priority register to its original
|
||||||
value. */
|
value. */
|
||||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||||
}
|
}
|
||||||
#endif /* conifgASSERT_DEFINED */
|
#endif /* conifgASSERT_DEFINED */
|
||||||
|
|
||||||
/* Make PendSV and SysTick the lowest priority interrupts. */
|
/* Make PendSV and SysTick the lowest priority interrupts. */
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
|
||||||
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
|
||||||
|
|
||||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||||
here already. */
|
here already. */
|
||||||
vPortSetupTimerInterrupt();
|
vPortSetupTimerInterrupt();
|
||||||
|
|
||||||
/* Initialise the critical nesting count ready for the first task. */
|
/* Initialise the critical nesting count ready for the first task. */
|
||||||
@@ -337,11 +335,11 @@ BaseType_t xPortStartScheduler( void )
|
|||||||
prvPortStartFirstTask();
|
prvPortStartFirstTask();
|
||||||
|
|
||||||
/* Should never get here as the tasks will now be executing! Call the task
|
/* Should never get here as the tasks will now be executing! Call the task
|
||||||
exit error function to prevent compiler warnings about a static function
|
exit error function to prevent compiler warnings about a static function
|
||||||
not being called in the case that the application writer overrides this
|
not being called in the case that the application writer overrides this
|
||||||
functionality by defining configTASK_RETURN_ADDRESS. Call
|
functionality by defining configTASK_RETURN_ADDRESS. Call
|
||||||
vTaskSwitchContext() so link time optimisation does not remove the
|
vTaskSwitchContext() so link time optimisation does not remove the
|
||||||
symbol. */
|
symbol. */
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
prvTaskExitError();
|
prvTaskExitError();
|
||||||
|
|
||||||
@@ -350,92 +348,84 @@ BaseType_t xPortStartScheduler( void )
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler(void) {
|
||||||
{
|
|
||||||
/* Not implemented in ports where there is nothing to return to.
|
/* Not implemented in ports where there is nothing to return to.
|
||||||
Artificially force an assert. */
|
Artificially force an assert. */
|
||||||
configASSERT( uxCriticalNesting == 1000UL );
|
configASSERT(uxCriticalNesting == 1000UL);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical(void) {
|
||||||
{
|
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
uxCriticalNesting++;
|
uxCriticalNesting++;
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
assert() if it is being called from an interrupt context. Only API
|
||||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||||
the critical nesting count is 1 to protect against recursive calls if the
|
the critical nesting count is 1 to protect against recursive calls if the
|
||||||
assert function also uses a critical section. */
|
assert function also uses a critical section. */
|
||||||
if( uxCriticalNesting == 1 )
|
if (uxCriticalNesting == 1) {
|
||||||
{
|
configASSERT(( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) == 0);
|
||||||
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortExitCritical( void )
|
void vPortExitCritical(void) {
|
||||||
{
|
configASSERT(uxCriticalNesting);
|
||||||
configASSERT( uxCriticalNesting );
|
|
||||||
uxCriticalNesting--;
|
uxCriticalNesting--;
|
||||||
if( uxCriticalNesting == 0 )
|
if (uxCriticalNesting == 0) {
|
||||||
{
|
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void xPortPendSVHandler( void )
|
void xPortPendSVHandler(void) {
|
||||||
{
|
|
||||||
/* This is a naked function. */
|
/* This is a naked function. */
|
||||||
|
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs r0, psp \n"
|
" mrs r0, psp \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" \n"
|
" \n"
|
||||||
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
||||||
" ldr r2, [r3] \n"
|
" ldr r2, [r3] \n"
|
||||||
" \n"
|
" \n"
|
||||||
" stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */
|
" stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */
|
||||||
" str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
|
" str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
|
||||||
" \n"
|
" \n"
|
||||||
" stmdb sp!, {r3, r14} \n"
|
" stmdb sp!, {r3, r14} \n"
|
||||||
" mov r0, %0 \n"
|
" mov r0, %0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
" ldmia sp!, {r3, r14} \n"
|
" ldmia sp!, {r3, r14} \n"
|
||||||
" \n" /* Restore the context, including the critical nesting count. */
|
" \n" /* Restore the context, including the critical nesting count. */
|
||||||
" ldr r1, [r3] \n"
|
" ldr r1, [r3] \n"
|
||||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
|
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
|
||||||
" msr psp, r0 \n"
|
" msr psp, r0 \n"
|
||||||
" isb \n"
|
" isb \n"
|
||||||
" bx r14 \n"
|
" bx r14 \n"
|
||||||
" \n"
|
" \n"
|
||||||
" .align 4 \n"
|
" .align 4 \n"
|
||||||
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
"pxCurrentTCBConst: .word pxCurrentTCB \n"
|
||||||
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
|
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void xPortSysTickHandler( void )
|
void xPortSysTickHandler(void) {
|
||||||
{
|
|
||||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
||||||
executes all interrupts must be unmasked. There is therefore no need to
|
executes all interrupts must be unmasked. There is therefore no need to
|
||||||
save and then restore the interrupt mask value as its value is already
|
save and then restore the interrupt mask value as its value is already
|
||||||
known. */
|
known. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
/* Increment the RTOS tick. */
|
/* Increment the RTOS tick. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if (xTaskIncrementTick() != pdFALSE) {
|
||||||
{
|
|
||||||
/* A context switch is required. Context switching is performed in
|
/* A context switch is required. Context switching is performed in
|
||||||
the PendSV interrupt. Pend the PendSV interrupt. */
|
the PendSV interrupt. Pend the PendSV interrupt. */
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -614,10 +604,9 @@ void xPortSysTickHandler( void )
|
|||||||
* Setup the systick timer to generate the tick interrupts at the required
|
* Setup the systick timer to generate the tick interrupts at the required
|
||||||
* frequency.
|
* frequency.
|
||||||
*/
|
*/
|
||||||
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
__attribute__(( weak )) void vPortSetupTimerInterrupt(void) {
|
||||||
{
|
|
||||||
/* Calculate the constants required to configure the tick interrupt. */
|
/* Calculate the constants required to configure the tick interrupt. */
|
||||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
{
|
{
|
||||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||||
@@ -630,88 +619,69 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
|||||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||||
|
|
||||||
/* Configure SysTick to interrupt at the requested rate. */
|
/* Configure SysTick to interrupt at the requested rate. */
|
||||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ)
|
||||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
- 1UL;
|
||||||
|
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT
|
||||||
|
| portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if( configASSERT_DEFINED == 1 )
|
#if( configASSERT_DEFINED == 1 )
|
||||||
|
|
||||||
void vPortValidateInterruptPriority( void )
|
void vPortValidateInterruptPriority(void) {
|
||||||
{
|
|
||||||
uint32_t ulCurrentInterrupt;
|
uint32_t ulCurrentInterrupt;
|
||||||
uint8_t ucCurrentPriority;
|
uint8_t ucCurrentPriority;
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. */
|
/* Obtain the number of the currently executing interrupt. */
|
||||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
||||||
|
|
||||||
/* Is the interrupt number a user defined interrupt? */
|
/* Is the interrupt number a user defined interrupt? */
|
||||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
if (ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER) {
|
||||||
{
|
/* Look up the interrupt's priority. */
|
||||||
/* Look up the interrupt's priority. */
|
ucCurrentPriority = pcInterruptPriorityRegisters[ulCurrentInterrupt];
|
||||||
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
|
|
||||||
|
|
||||||
/* The following assertion will fail if a service routine (ISR) for
|
/* The following assertion will fail if a service routine (ISR) for
|
||||||
an interrupt that has been assigned a priority above
|
an interrupt that has been assigned a priority above
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||||
function. ISR safe FreeRTOS API functions must *only* be called
|
function. ISR safe FreeRTOS API functions must *only* be called
|
||||||
from interrupts that have been assigned a priority at or below
|
from interrupts that have been assigned a priority at or below
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
|
||||||
Numerically low interrupt priority numbers represent logically high
|
Numerically low interrupt priority numbers represent logically high
|
||||||
interrupt priorities, therefore the priority of the interrupt must
|
interrupt priorities, therefore the priority of the interrupt must
|
||||||
be set to a value equal to or numerically *higher* than
|
be set to a value equal to or numerically *higher* than
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
|
|
||||||
Interrupts that use the FreeRTOS API must not be left at their
|
Interrupts that use the FreeRTOS API must not be left at their
|
||||||
default priority of zero as that is the highest possible priority,
|
default priority of zero as that is the highest possible priority,
|
||||||
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
|
||||||
and therefore also guaranteed to be invalid.
|
and therefore also guaranteed to be invalid.
|
||||||
|
|
||||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||||
interrupt entry is as fast and simple as possible.
|
interrupt entry is as fast and simple as possible.
|
||||||
|
|
||||||
The following links provide detailed information:
|
The following links provide detailed information:
|
||||||
http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
http://www.freertos.org/RTOS-Cortex-M3-M4.html
|
||||||
http://www.freertos.org/FAQHelp.html */
|
http://www.freertos.org/FAQHelp.html */
|
||||||
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
|
configASSERT(ucCurrentPriority >= ucMaxSysCallPriority);
|
||||||
}
|
|
||||||
|
|
||||||
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
|
||||||
that define each interrupt's priority to be split between bits that
|
|
||||||
define the interrupt's pre-emption priority bits and bits that define
|
|
||||||
the interrupt's sub-priority. For simplicity all bits must be defined
|
|
||||||
to be pre-emption priority bits. The following assertion will fail if
|
|
||||||
this is not the case (if some bits represent a sub-priority).
|
|
||||||
|
|
||||||
If the application only uses CMSIS libraries for interrupt
|
|
||||||
configuration then the correct setting can be achieved on all Cortex-M
|
|
||||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
|
||||||
scheduler. Note however that some vendor specific peripheral libraries
|
|
||||||
assume a non-zero priority group setting, in which cases using a value
|
|
||||||
of zero will result in unpredictable behaviour. */
|
|
||||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Priority grouping: The interrupt controller (NVIC) allows the bits
|
||||||
|
that define each interrupt's priority to be split between bits that
|
||||||
|
define the interrupt's pre-emption priority bits and bits that define
|
||||||
|
the interrupt's sub-priority. For simplicity all bits must be defined
|
||||||
|
to be pre-emption priority bits. The following assertion will fail if
|
||||||
|
this is not the case (if some bits represent a sub-priority).
|
||||||
|
|
||||||
|
If the application only uses CMSIS libraries for interrupt
|
||||||
|
configuration then the correct setting can be achieved on all Cortex-M
|
||||||
|
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||||
|
scheduler. Note however that some vendor specific peripheral libraries
|
||||||
|
assume a non-zero priority group setting, in which cases using a value
|
||||||
|
of zero will result in unpredictable behaviour. */
|
||||||
|
configASSERT(
|
||||||
|
( portAIRCR_REG & portPRIORITY_GROUP_MASK) <= ulMaxPRIGROUPValue);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
* 1 tab == 4 spaces!
|
* 1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORTMACRO_H
|
#ifndef PORTMACRO_H
|
||||||
#define PORTMACRO_H
|
#define PORTMACRO_H
|
||||||
|
|
||||||
@@ -60,12 +59,12 @@ typedef unsigned long UBaseType_t;
|
|||||||
typedef uint16_t TickType_t;
|
typedef uint16_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
#else
|
#else
|
||||||
typedef uint32_t TickType_t;
|
typedef uint32_t TickType_t;
|
||||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
not need to be guarded with a critical section. */
|
not need to be guarded with a critical section. */
|
||||||
#define portTICK_TYPE_IS_ATOMIC 1
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -94,8 +93,8 @@ typedef unsigned long UBaseType_t;
|
|||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical(void);
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical(void);
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
||||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||||
@@ -106,55 +105,55 @@ extern void vPortExitCritical( void );
|
|||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||||
not necessary for to use this port. They are defined so the common demo files
|
not necessary for to use this port. They are defined so the common demo files
|
||||||
(which build with all the ports) will build. */
|
(which build with all the ports) will build. */
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
extern void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime);
|
||||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Architecture specific optimisations. */
|
/* Architecture specific optimisations. */
|
||||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||||
|
|
||||||
/* Generic helper function. */
|
/* Generic helper function. */
|
||||||
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
|
__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros(
|
||||||
{
|
uint32_t ulBitmap) {
|
||||||
uint8_t ucReturn;
|
uint8_t ucReturn;
|
||||||
|
|
||||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
return ucReturn;
|
return ucReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the configuration. */
|
/* Check the configuration. */
|
||||||
#if( configMAX_PRIORITIES > 32 )
|
#if( configMAX_PRIORITIES > 32 )
|
||||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Store/clear the ready priorities in a bit map. */
|
/* Store/clear the ready priorities in a bit map. */
|
||||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef configASSERT
|
#ifdef configASSERT
|
||||||
void vPortValidateInterruptPriority( void );
|
void vPortValidateInterruptPriority( void );
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
@@ -163,25 +162,21 @@ not necessary for to use this port. They are defined so the common demo files
|
|||||||
#define portINLINE __inline
|
#define portINLINE __inline
|
||||||
|
|
||||||
#ifndef portFORCE_INLINE
|
#ifndef portFORCE_INLINE
|
||||||
#define portFORCE_INLINE inline __attribute__(( always_inline))
|
#define portFORCE_INLINE inline __attribute__(( always_inline))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt(void) {
|
||||||
{
|
uint32_t ulCurrentInterrupt;
|
||||||
uint32_t ulCurrentInterrupt;
|
BaseType_t xReturn;
|
||||||
BaseType_t xReturn;
|
|
||||||
|
|
||||||
/* Obtain the number of the currently executing interrupt. */
|
/* Obtain the number of the currently executing interrupt. */
|
||||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
||||||
|
|
||||||
if( ulCurrentInterrupt == 0 )
|
if (ulCurrentInterrupt == 0) {
|
||||||
{
|
|
||||||
xReturn = pdFALSE;
|
xReturn = pdFALSE;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
xReturn = pdTRUE;
|
xReturn = pdTRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,47 +185,44 @@ BaseType_t xReturn;
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
portFORCE_INLINE static void vPortRaiseBASEPRI( void )
|
portFORCE_INLINE static void vPortRaiseBASEPRI(void) {
|
||||||
{
|
uint32_t ulNewBASEPRI;
|
||||||
uint32_t ulNewBASEPRI;
|
|
||||||
|
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mov %0, %1 \n" \
|
" mov %0, %1 \n"
|
||||||
" msr basepri, %0 \n" \
|
" msr basepri, %0 \n"
|
||||||
" isb \n" \
|
" isb \n"
|
||||||
" dsb \n" \
|
" dsb \n"
|
||||||
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI(void) {
|
||||||
{
|
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||||
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
|
||||||
|
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" mrs %0, basepri \n" \
|
" mrs %0, basepri \n"
|
||||||
" mov %1, %2 \n" \
|
" mov %1, %2 \n"
|
||||||
" msr basepri, %1 \n" \
|
" msr basepri, %1 \n"
|
||||||
" isb \n" \
|
" isb \n"
|
||||||
" dsb \n" \
|
" dsb \n"
|
||||||
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
);
|
);
|
||||||
|
|
||||||
/* This return will not be reached but is necessary to prevent compiler
|
/* This return will not be reached but is necessary to prevent compiler
|
||||||
warnings. */
|
warnings. */
|
||||||
return ulOriginalBASEPRI;
|
return ulOriginalBASEPRI;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
portFORCE_INLINE static void vPortSetBASEPRI(uint32_t ulNewMaskValue) {
|
||||||
{
|
|
||||||
__asm volatile
|
__asm volatile
|
||||||
(
|
(
|
||||||
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
|
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|||||||
@@ -26,10 +26,9 @@ void HAL_MspInit(void) {
|
|||||||
/* SysTick_IRQn interrupt configuration */
|
/* SysTick_IRQn interrupt configuration */
|
||||||
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
|
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) {
|
||||||
@@ -72,7 +71,7 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
@@ -123,7 +122,7 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
||||||
|
|||||||
@@ -1,158 +1,154 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @file stm32f1xx_hal_timebase_TIM.c
|
* @file stm32f1xx_hal_timebase_TIM.c
|
||||||
* @brief HAL time base based on the hardware TIM.
|
* @brief HAL time base based on the hardware TIM.
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* 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 "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
#include "stm32f1xx_hal_tim.h"
|
#include "stm32f1xx_hal_tim.h"
|
||||||
/** @addtogroup STM32F7xx_HAL_Examples
|
/** @addtogroup STM32F7xx_HAL_Examples
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @addtogroup HAL_TimeBase
|
/** @addtogroup HAL_TimeBase
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
/* Private define ------------------------------------------------------------*/
|
/* Private define ------------------------------------------------------------*/
|
||||||
/* 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 ---------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function configures the TIM1 as a time base source.
|
* @brief This function configures the TIM1 as a time base source.
|
||||||
* 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 configured, by HAL_RCC_ClockConfig().
|
* reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
|
||||||
* @param TickPriority: Tick interrupt priorty.
|
* @param TickPriority: Tick interrupt priorty.
|
||||||
* @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 */
|
||||||
{
|
return HAL_TIM_Base_Start_IT(&htim1);
|
||||||
/* Start the TIM time Base generation in interrupt mode */
|
}
|
||||||
return HAL_TIM_Base_Start_IT(&htim1);
|
|
||||||
}
|
/* Return function status */
|
||||||
|
return HAL_ERROR;
|
||||||
/* Return function status */
|
|
||||||
return HAL_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Suspend Tick increment.
|
* @brief Suspend Tick increment.
|
||||||
* @note Disable the tick increment by disabling TIM1 update interrupt.
|
* @note Disable the tick increment by disabling TIM1 update interrupt.
|
||||||
* @param None
|
* @param None
|
||||||
* @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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resume Tick increment.
|
* @brief Resume Tick increment.
|
||||||
* @note Enable the tick increment by Enabling TIM1 update interrupt.
|
* @note Enable the tick increment by Enabling TIM1 update interrupt.
|
||||||
* @param None
|
* @param None
|
||||||
* @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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|||||||
@@ -82,6 +82,6 @@ void DMA1_Channel6_IRQHandler(void) {
|
|||||||
void DMA1_Channel7_IRQHandler(void) {
|
void DMA1_Channel7_IRQHandler(void) {
|
||||||
HAL_DMA_IRQHandler(&hdma_i2c1_rx);
|
HAL_DMA_IRQHandler(&hdma_i2c1_rx);
|
||||||
}
|
}
|
||||||
void EXTI9_5_IRQHandler(void){
|
void EXTI9_5_IRQHandler(void) {
|
||||||
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
|
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
This value can be provided and adapted by the user application. */
|
This value can be provided and adapted by the user application. */
|
||||||
#endif /* HSI_VALUE */
|
#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)
|
||||||
/* #define DATA_IN_ExtSRAM */
|
/* #define DATA_IN_ExtSRAM */
|
||||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||||
@@ -19,68 +19,67 @@
|
|||||||
#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, 8, 9};
|
const uint8_t AHBPrescTable[16U] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7,
|
||||||
const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
|
8, 9 };
|
||||||
|
const uint8_t APBPrescTable[8U] = { 0, 0, 0, 0, 1, 2, 3, 4 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the microcontroller system
|
* @brief Setup the microcontroller system
|
||||||
* Initialize the Embedded Flash Interface, the PLL and update the
|
* Initialize the Embedded Flash Interface, the PLL and update the
|
||||||
* SystemCoreClock variable.
|
* SystemCoreClock variable.
|
||||||
* @note This function should be used only after reset.
|
* @note This function should be used only after reset.
|
||||||
* @param None
|
* @param None
|
||||||
* @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 */
|
|
||||||
RCC->CR &= 0xFEF6FFFFU;
|
|
||||||
|
|
||||||
/* Reset HSEBYP bit */
|
/* Reset HSEON, CSSON and PLLON bits */
|
||||||
RCC->CR &= 0xFFFBFFFFU;
|
RCC->CR &= 0xFEF6FFFFU;
|
||||||
|
|
||||||
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
|
/* Reset HSEBYP bit */
|
||||||
RCC->CFGR &= 0xFF80FFFFU;
|
RCC->CR &= 0xFFFBFFFFU;
|
||||||
|
|
||||||
|
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
|
||||||
|
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();
|
||||||
@@ -90,48 +89,47 @@ void SystemInit (void)
|
|||||||
#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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||||
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||||
* be used by the user application to setup the SysTick timer or configure
|
* be used by the user application to setup the SysTick timer or configure
|
||||||
* other parameters.
|
* other parameters.
|
||||||
*
|
*
|
||||||
* @note Each time the core clock (HCLK) changes, this function must be called
|
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||||
* based on this variable will be incorrect.
|
* based on this variable will be incorrect.
|
||||||
*
|
*
|
||||||
* @note - The system frequency computed by this function is not the real
|
* @note - The system frequency computed by this function is not the real
|
||||||
* frequency in the chip. It is calculated based on the predefined
|
* frequency in the chip. It is calculated based on the predefined
|
||||||
* constant and the selected clock source:
|
* constant and the selected clock source:
|
||||||
*
|
*
|
||||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||||
*
|
*
|
||||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
|
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
|
||||||
*
|
*
|
||||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
|
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
|
||||||
* or HSI_VALUE(*) multiplied by the PLL factors.
|
* or HSI_VALUE(*) multiplied by the PLL factors.
|
||||||
*
|
*
|
||||||
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
|
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||||
* 8 MHz) but the real value may vary depending on the variations
|
* 8 MHz) but the real value may vary depending on the variations
|
||||||
* in voltage and temperature.
|
* in voltage and temperature.
|
||||||
*
|
*
|
||||||
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
|
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||||
* 8 MHz or 25 MHz, depending on the product used), user has to ensure
|
* 8 MHz or 25 MHz, depending on the product used), user has to ensure
|
||||||
* that HSE_VALUE is same as the real frequency of the crystal used.
|
* that HSE_VALUE is same as the real frequency of the crystal used.
|
||||||
* Otherwise, this function may have wrong result.
|
* Otherwise, this function may have wrong result.
|
||||||
*
|
*
|
||||||
* - The result of this function could be not correct when using fractional
|
* - The result of this function could be not correct when using fractional
|
||||||
* value for HSE crystal.
|
* value for HSE crystal.
|
||||||
* @param None
|
* @param None
|
||||||
* @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;
|
||||||
@@ -140,50 +138,43 @@ void SystemCoreClockUpdate (void)
|
|||||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||||
uint32_t prediv1factor = 0U;
|
uint32_t prediv1factor = 0U;
|
||||||
#endif /* STM32F100xB or STM32F100xE */
|
#endif /* STM32F100xB or STM32F100xE */
|
||||||
|
|
||||||
/* Get SYSCLK source -------------------------------------------------------*/
|
|
||||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
|
||||||
|
|
||||||
switch (tmp)
|
|
||||||
{
|
|
||||||
case 0x00U: /* HSI used as system clock */
|
|
||||||
SystemCoreClock = HSI_VALUE;
|
|
||||||
break;
|
|
||||||
case 0x04U: /* HSE used as system clock */
|
|
||||||
SystemCoreClock = HSE_VALUE;
|
|
||||||
break;
|
|
||||||
case 0x08U: /* PLL used as system clock */
|
|
||||||
|
|
||||||
/* Get PLL clock source and multiplication factor ----------------------*/
|
/* Get SYSCLK source -------------------------------------------------------*/
|
||||||
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
|
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||||
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
|
||||||
|
switch (tmp) {
|
||||||
|
case 0x00U: /* HSI used as system clock */
|
||||||
|
SystemCoreClock = HSI_VALUE;
|
||||||
|
break;
|
||||||
|
case 0x04U: /* HSE used as system clock */
|
||||||
|
SystemCoreClock = HSE_VALUE;
|
||||||
|
break;
|
||||||
|
case 0x08U: /* PLL used as system clock */
|
||||||
|
|
||||||
|
/* Get PLL clock source and multiplication factor ----------------------*/
|
||||||
|
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
|
||||||
|
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 {
|
||||||
}
|
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||||
else
|
|
||||||
{
|
|
||||||
#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
|
#else
|
||||||
/* HSE selected as PLL clock entry */
|
/* HSE selected as PLL clock entry */
|
||||||
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
|
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t) RESET) {/* HSE oscillator clock divided by 2 */
|
||||||
{/* HSE oscillator clock divided by 2 */
|
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
|
||||||
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
|
} else {
|
||||||
}
|
SystemCoreClock = HSE_VALUE * pllmull;
|
||||||
else
|
}
|
||||||
{
|
#endif
|
||||||
SystemCoreClock = HSE_VALUE * pllmull;
|
}
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
pllmull = pllmull >> 18U;
|
pllmull = pllmull >> 18U;
|
||||||
|
|
||||||
@@ -223,18 +214,18 @@ void SystemCoreClockUpdate (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* STM32F105xC */
|
#endif /* STM32F105xC */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
SystemCoreClock = HSI_VALUE;
|
SystemCoreClock = HSI_VALUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute HCLK clock frequency ----------------*/
|
/* Compute HCLK clock frequency ----------------*/
|
||||||
/* Get HCLK prescaler */
|
/* Get HCLK prescaler */
|
||||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
|
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
|
||||||
/* HCLK clock frequency */
|
/* HCLK clock frequency */
|
||||||
SystemCoreClock >>= tmp;
|
SystemCoreClock >>= tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||||
@@ -302,14 +293,14 @@ void SystemInit_ExtMemCtl(void)
|
|||||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|||||||
Reference in New Issue
Block a user