Bulk format

This commit is contained in:
Ben V. Brown
2020-10-13 19:04:16 +11:00
parent 03afdcdf20
commit 2e4168be73
15 changed files with 730 additions and 810 deletions

View File

@@ -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);
} }

View File

@@ -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;
} }

View File

@@ -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();
} }

View File

@@ -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
} }

View File

@@ -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);

View File

@@ -22,6 +22,4 @@
#endif #endif
#endif /* BSP_MINIWARE_SOFTWARE_I2C_H_ */ #endif /* BSP_MINIWARE_SOFTWARE_I2C_H_ */

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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;
} }

View File

@@ -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 */

View File

@@ -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"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View File

@@ -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()

View File

@@ -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****/

View 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);
} }

View File

@@ -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****/