First files added
This commit is contained in:
663
firmware/Core/Src/app_freertos.c
Normal file
663
firmware/Core/Src/app_freertos.c
Normal file
@@ -0,0 +1,663 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : app_freertos.c
|
||||
* Description : Code for freertos applications
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "main.h"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "BME280_STM32.h"
|
||||
#include "pid.h"
|
||||
#include "icons.h"
|
||||
#include "ssd1306.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
typedef struct {
|
||||
char text[6];
|
||||
uint8_t drytemp;
|
||||
uint32_t drytime;
|
||||
} MenuItem;
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Variables */
|
||||
float aimTemperature, Temperature, Pressure, aimHumidity, Humidity; //BME280 results and aim values
|
||||
uint8_t powerFan = 0, powerHeater = 0; //Set fan/heater power 0 - 100
|
||||
|
||||
//PID settings
|
||||
PIDController pid = {
|
||||
.Kp = 5.0f,
|
||||
.Ki = 2.0f,
|
||||
.Kd = 1.0f,
|
||||
.T = 0.25f, //4 times per second
|
||||
.tau = 0.2f, //Low-pass filter (0 - no filter)
|
||||
.limMin = 0.0f,
|
||||
.limMax = 100.0f
|
||||
};
|
||||
|
||||
MenuItem menuProg[] = {
|
||||
// text temp time in seconds
|
||||
{"PLA", 45, 4*3600},
|
||||
{"ABS", 60, 2*3600},
|
||||
{"PETG", 65, 2*3600},
|
||||
{"TPU", 50, 4*3600},
|
||||
{"NYLON", 70, 8*3600},
|
||||
{"PVA", 45, 4*3600},
|
||||
{"ASA", 60, 4*3600},
|
||||
{"PP", 55, 6*3600},
|
||||
{"SILIC", 65, 3*3600},
|
||||
{"TEST", 27, 30}
|
||||
};
|
||||
|
||||
uint8_t menuMax = 9; // Max menu index
|
||||
uint8_t prog = 0; // Selected program
|
||||
uint8_t menuFrame = 0; // Menu list frame index
|
||||
uint8_t mode = 0; // Current mode: 0 - Idle menu; 1 - Drying; 2 - Drying stop question; 3 - Keeping;
|
||||
// 4 - Keeping stop question; 98 - Thermal runout; 99 - sensor error;
|
||||
uint8_t qConfirm = 0; // Question menu (Yes/No) selected answer
|
||||
uint32_t time_cnt = 0; // Time counter for Drying / Keeping action
|
||||
|
||||
/* USER CODE END Variables */
|
||||
/* Definitions for defaultTask */
|
||||
osThreadId_t defaultTaskHandle;
|
||||
const osThreadAttr_t defaultTask_attributes = {
|
||||
.name = "defaultTask",
|
||||
.priority = (osPriority_t) osPriorityNormal,
|
||||
.stack_size = 128 * 4
|
||||
};
|
||||
/* Definitions for svcDisplay */
|
||||
osThreadId_t svcDisplayHandle;
|
||||
const osThreadAttr_t svcDisplay_attributes = {
|
||||
.name = "svcDisplay",
|
||||
.priority = (osPriority_t) osPriorityLow,
|
||||
.stack_size = 128 * 4
|
||||
};
|
||||
/* Definitions for svcSensors */
|
||||
osThreadId_t svcSensorsHandle;
|
||||
const osThreadAttr_t svcSensors_attributes = {
|
||||
.name = "svcSensors",
|
||||
.priority = (osPriority_t) osPriorityLow,
|
||||
.stack_size = 128 * 4
|
||||
};
|
||||
/* Definitions for svcKeys */
|
||||
osThreadId_t svcKeysHandle;
|
||||
const osThreadAttr_t svcKeys_attributes = {
|
||||
.name = "svcKeys",
|
||||
.priority = (osPriority_t) osPriorityLow,
|
||||
.stack_size = 128 * 4
|
||||
};
|
||||
/* Definitions for qKeysPressed */
|
||||
osMessageQueueId_t qKeysPressedHandle;
|
||||
const osMessageQueueAttr_t qKeysPressed_attributes = {
|
||||
.name = "qKeysPressed"
|
||||
};
|
||||
/* Definitions for qDisplay */
|
||||
osMessageQueueId_t qDisplayHandle;
|
||||
const osMessageQueueAttr_t qDisplay_attributes = {
|
||||
.name = "qDisplay"
|
||||
};
|
||||
/* Definitions for timeCounter */
|
||||
osTimerId_t timeCounterHandle;
|
||||
const osTimerAttr_t timeCounter_attributes = {
|
||||
.name = "timeCounter"
|
||||
};
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN FunctionPrototypes */
|
||||
void update_ui(void); //update display main function
|
||||
void draw_info_frame(void); //draw frame and pics for info frame
|
||||
void draw_info(void); //update drying/keeping info
|
||||
void draw_time_info(void); //update drying/keeping timers
|
||||
void draw_header(void); //update display header lines
|
||||
void draw_menu(void); //Draw program select menu
|
||||
void draw_question(void); //Draw STOP? question
|
||||
void draw_error(void); //Draw sensor error message
|
||||
|
||||
void setPWMs(void); //set Timer values according to requested settings
|
||||
/* USER CODE END FunctionPrototypes */
|
||||
|
||||
void StartDefaultTask(void *argument);
|
||||
void svc_display(void *argument);
|
||||
void svc_sensors(void *argument);
|
||||
void svc_keys(void *argument);
|
||||
void clock_tick(void *argument);
|
||||
|
||||
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
||||
|
||||
/**
|
||||
* @brief FreeRTOS initialization
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void MX_FREERTOS_Init(void) {
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* USER CODE BEGIN RTOS_MUTEX */
|
||||
/* add mutexes, ... */
|
||||
/* USER CODE END RTOS_MUTEX */
|
||||
|
||||
/* USER CODE BEGIN RTOS_SEMAPHORES */
|
||||
/* add semaphores, ... */
|
||||
/* USER CODE END RTOS_SEMAPHORES */
|
||||
|
||||
/* Create the timer(s) */
|
||||
/* creation of timeCounter */
|
||||
timeCounterHandle = osTimerNew(clock_tick, osTimerPeriodic, NULL, &timeCounter_attributes);
|
||||
|
||||
/* USER CODE BEGIN RTOS_TIMERS */
|
||||
/* start timers, add new ones, ... */
|
||||
/* USER CODE END RTOS_TIMERS */
|
||||
|
||||
/* Create the queue(s) */
|
||||
/* creation of qKeysPressed */
|
||||
qKeysPressedHandle = osMessageQueueNew (16, sizeof(uint8_t), &qKeysPressed_attributes);
|
||||
|
||||
/* creation of qDisplay */
|
||||
qDisplayHandle = osMessageQueueNew (16, sizeof(uint8_t), &qDisplay_attributes);
|
||||
|
||||
/* USER CODE BEGIN RTOS_QUEUES */
|
||||
/* add queues, ... */
|
||||
/* USER CODE END RTOS_QUEUES */
|
||||
|
||||
/* Create the thread(s) */
|
||||
/* creation of defaultTask */
|
||||
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
|
||||
|
||||
/* creation of svcDisplay */
|
||||
svcDisplayHandle = osThreadNew(svc_display, NULL, &svcDisplay_attributes);
|
||||
|
||||
/* creation of svcSensors */
|
||||
svcSensorsHandle = osThreadNew(svc_sensors, NULL, &svcSensors_attributes);
|
||||
|
||||
/* creation of svcKeys */
|
||||
svcKeysHandle = osThreadNew(svc_keys, NULL, &svcKeys_attributes);
|
||||
|
||||
/* USER CODE BEGIN RTOS_THREADS */
|
||||
/* add threads, ... */
|
||||
/* USER CODE END RTOS_THREADS */
|
||||
|
||||
/* USER CODE BEGIN RTOS_EVENTS */
|
||||
/* add events, ... */
|
||||
/* USER CODE END RTOS_EVENTS */
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Header_StartDefaultTask */
|
||||
/**
|
||||
* @brief Function implementing the defaultTask thread.
|
||||
* @param argument: Not used
|
||||
* @retval None
|
||||
*/
|
||||
/* USER CODE END Header_StartDefaultTask */
|
||||
void StartDefaultTask(void *argument)
|
||||
{
|
||||
/* USER CODE BEGIN StartDefaultTask */
|
||||
|
||||
osTimerStart(timeCounterHandle, 1000);
|
||||
|
||||
/* Infinite loop */
|
||||
uint8_t key; //pressed key id
|
||||
for(;;)
|
||||
{
|
||||
//Check if there is a key pressed
|
||||
if (osMessageQueueGetCount(qKeysPressedHandle) > 0) {
|
||||
osMessageQueueGet(qKeysPressedHandle, &key, NULL, 50);
|
||||
|
||||
switch (key) {
|
||||
case 0: // Down button
|
||||
switch (mode) {
|
||||
case 0:
|
||||
if (prog < menuMax) prog++;
|
||||
if (prog > menuFrame + 2) menuFrame = prog - 2;
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
qConfirm = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // OK button
|
||||
switch (mode) {
|
||||
case 0: //Program has been chosen, lets start heating
|
||||
time_cnt = menuProg[prog].drytime;
|
||||
aimTemperature = menuProg[prog].drytemp;
|
||||
pid.integrator = 0;
|
||||
powerFan = 100;
|
||||
mode = 1;
|
||||
break;
|
||||
case 1: //Ask for confirmation to stop drying
|
||||
mode = 2;
|
||||
qConfirm = 0;
|
||||
break;
|
||||
case 3: //Ask for confirmation to stop keeping
|
||||
mode = 4;
|
||||
qConfirm = 0;
|
||||
break;
|
||||
case 2: //resume heating or stop and go to idle mode
|
||||
if (qConfirm) {
|
||||
aimTemperature = 0;
|
||||
mode = 0;
|
||||
} else {
|
||||
mode = 1;
|
||||
}
|
||||
break;
|
||||
case 4: //resume keeping or stop and go to idle mode
|
||||
if (qConfirm) {
|
||||
aimTemperature = 0;
|
||||
aimHumidity = 0;
|
||||
mode = 0;
|
||||
} else {
|
||||
mode = 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // Up button
|
||||
switch (mode) {
|
||||
case 0:
|
||||
if (prog > 0) prog--;
|
||||
if (prog < menuFrame) menuFrame = prog;
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
qConfirm = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} //switch key
|
||||
update_ui();
|
||||
} //key queue check
|
||||
|
||||
osDelay(1);
|
||||
}
|
||||
/* USER CODE END StartDefaultTask */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Header_svc_display */
|
||||
/**
|
||||
* @brief Function implementing the svcDisplay thread.
|
||||
* @param argument: Not used
|
||||
* @retval None
|
||||
*/
|
||||
/* USER CODE END Header_svc_display */
|
||||
void svc_display(void *argument)
|
||||
{
|
||||
/* USER CODE BEGIN svc_display */
|
||||
|
||||
/* Infinite loop */
|
||||
for(;;)
|
||||
{
|
||||
|
||||
if (mode == 1 || mode == 3) {
|
||||
draw_info();
|
||||
}
|
||||
|
||||
osDelay(500);
|
||||
}
|
||||
/* USER CODE END svc_display */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Header_svc_sensors */
|
||||
/**
|
||||
* @brief Function implementing the svcSensors thread.
|
||||
* @param argument: Not used
|
||||
* @retval None
|
||||
*/
|
||||
/* USER CODE END Header_svc_sensors */
|
||||
void svc_sensors(void *argument)
|
||||
{
|
||||
/* USER CODE BEGIN svc_sensors */
|
||||
|
||||
uint16_t tro = 0; //counter for thermal runout protection
|
||||
|
||||
aimTemperature = Temperature = Pressure = aimHumidity = Humidity = 0.0f;
|
||||
PID_Init(&pid);
|
||||
|
||||
/* Infinite loop */
|
||||
for(;;)
|
||||
{
|
||||
if (mode < 98) {
|
||||
BME280_Measure();
|
||||
if (Temperature == 0.0f && Humidity == 0.0f) {
|
||||
//Some sensor malfunction
|
||||
mode = 99;
|
||||
aimTemperature = 0;
|
||||
aimHumidity = 0;
|
||||
powerFan = 100;
|
||||
powerHeater = 0;
|
||||
update_ui();
|
||||
} else {
|
||||
switch (mode) { //update fan/heater settings here.
|
||||
case 0:
|
||||
if (powerHeater > 0) powerHeater = 0;
|
||||
if (Temperature >= 35) powerFan = 100;
|
||||
else powerFan = 0;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
powerHeater = PID_Update(&pid, aimTemperature, Temperature);
|
||||
if (powerHeater > 0) powerFan = 100;
|
||||
else powerFan = 85;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
if (Humidity > 12) powerHeater = PID_Update(&pid, aimTemperature, Temperature);
|
||||
else powerHeater = 0;
|
||||
break;
|
||||
} //switch (mode)
|
||||
} //else
|
||||
|
||||
//Simple thermal runout protection
|
||||
if (Temperature > aimTemperature && Temperature > 45) tro++;
|
||||
else if (tro != 0) tro = 0;
|
||||
if (tro > 480) { //480 - 2 minutes (120 sec * 4 as this task runs 4 times per second)
|
||||
mode = 98;
|
||||
aimTemperature = 0;
|
||||
aimHumidity = 0;
|
||||
powerFan = 100;
|
||||
powerHeater = 0;
|
||||
update_ui();
|
||||
}
|
||||
} //if (mode < 98)
|
||||
|
||||
setPWMs();
|
||||
|
||||
osDelay(250);
|
||||
}
|
||||
/* USER CODE END svc_sensors */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Header_svc_keys */
|
||||
/**
|
||||
* @brief Function implementing the svcKeys thread.
|
||||
* @param argument: Not used
|
||||
* @retval None
|
||||
*/
|
||||
/* USER CODE END Header_svc_keys */
|
||||
void svc_keys(void *argument)
|
||||
{
|
||||
/* USER CODE BEGIN svc_keys */
|
||||
uint8_t bBuff[3] = {0xFF}; // buttons are grounded when pressed
|
||||
uint8_t bState[3] = {0xFF}; //last reported state. We need this to prevent repeated reports
|
||||
uint8_t read, i;
|
||||
|
||||
/* Infinite loop */
|
||||
for(;;)
|
||||
{
|
||||
read = KEY_DN_GPIO_Port->IDR & 0x00000007; //Read 3 bits of buttons port (PB0, PB1, PB2)
|
||||
// check every button and shift its values to the array
|
||||
for (i=0; i<3; i++) {
|
||||
bBuff[i] = (bBuff[i]<<1) | ((read >> i) & 1); //Shift button buffer left and assign a button bit from the read data
|
||||
if ( ((bBuff[i] & 0x0F) == 0b00000000) && (bState[i] == 1) ) { //if we read 0 last 4 times and last report was 1 then the button has been pressed
|
||||
bState[i] = 0;
|
||||
osMessageQueuePut(qKeysPressedHandle, &i, 0, 50); //Put the pressed button id to the key queue
|
||||
}
|
||||
if ( ((bBuff[i] & 0x0F) == 0b00001111) && (bState[i] == 0) ) { //if we read 1 last 4 times and last report was 0 then the button has been released
|
||||
bState[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
osDelay(4);
|
||||
}
|
||||
/* USER CODE END svc_keys */
|
||||
}
|
||||
|
||||
/* clock_tick function */
|
||||
void clock_tick(void *argument)
|
||||
{
|
||||
/* USER CODE BEGIN clock_tick */
|
||||
|
||||
//time counters here. Happens every second
|
||||
switch (mode) {
|
||||
case 1:
|
||||
case 2:
|
||||
time_cnt--;
|
||||
if (time_cnt == 0) {
|
||||
aimTemperature = 35;
|
||||
pid.integrator = 0;
|
||||
powerFan = 85;
|
||||
mode = 3;
|
||||
update_ui();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
time_cnt++;
|
||||
break;
|
||||
}
|
||||
draw_time_info();
|
||||
|
||||
|
||||
/* USER CODE END clock_tick */
|
||||
}
|
||||
|
||||
/* Private application code --------------------------------------------------*/
|
||||
/* USER CODE BEGIN Application */
|
||||
|
||||
//update display main function
|
||||
void update_ui(void) {
|
||||
ssd1306_Fill(Black);
|
||||
draw_header();
|
||||
switch (mode) {
|
||||
case 0:
|
||||
draw_menu();
|
||||
break;
|
||||
case 1:
|
||||
case 3:
|
||||
draw_info_frame();
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
draw_question();
|
||||
break;
|
||||
case 98:
|
||||
case 99:
|
||||
draw_error();
|
||||
break;
|
||||
} //switch (mode)
|
||||
ssd1306_UpdateScreen();
|
||||
}
|
||||
|
||||
//draw frame and pics for info frame
|
||||
void draw_info_frame(void) {
|
||||
ssd1306_DrawBitmap(4, 16, humidity16, 16, 16, White);
|
||||
ssd1306_DrawBitmap(0, 32, temperature24, 24, 24, White);
|
||||
ssd1306_DrawBitmap(26, 54, heat_icon, 18, 8, White);
|
||||
ssd1306_DrawBitmap(80, 54, fan_icon, 16, 8, White);
|
||||
}
|
||||
|
||||
//update drying/keeping info
|
||||
void draw_info(void) {
|
||||
char num[8];
|
||||
|
||||
//Humidity
|
||||
ssd1306_DrawRectangle(26, 16, 61, 26, Black, 1);
|
||||
sprintf(num, "%.1f%%", Humidity);
|
||||
ssd1306_SetCursor(26, 16);
|
||||
ssd1306_WriteString(num, Font_7x10, White);
|
||||
|
||||
//Temperature
|
||||
ssd1306_DrawRectangle(26, 32, 122, 58, Black, 1);
|
||||
sprintf(num, "%.1f*C", Temperature);
|
||||
ssd1306_SetCursor(26, 32);
|
||||
ssd1306_WriteString(num, Font_16x26, White);
|
||||
|
||||
//PWM Heater
|
||||
ssd1306_DrawRectangle(47, 55, 65, 63, Black, 1);
|
||||
sprintf(num, "%u", powerHeater);
|
||||
ssd1306_SetCursor(47, 55);
|
||||
ssd1306_WriteString(num, Font_6x8, White);
|
||||
//PWM Fan
|
||||
ssd1306_DrawRectangle(98, 55, 116, 63, Black, 1);
|
||||
sprintf(num, "%u", powerFan);
|
||||
ssd1306_SetCursor(98, 55);
|
||||
ssd1306_WriteString(num, Font_6x8, White);
|
||||
|
||||
ssd1306_UpdateScreen();
|
||||
}
|
||||
|
||||
//update drying/keeping timers
|
||||
void draw_time_info(void) {
|
||||
if (mode < 98) {
|
||||
ssd1306_SetCursor(78, 8);
|
||||
if (mode > 0) {
|
||||
uint8_t hrs, mins, secs;
|
||||
uint32_t rem;
|
||||
hrs = time_cnt / 3600;
|
||||
rem = time_cnt % 3600;
|
||||
mins = rem / 60;
|
||||
secs = rem % 60;
|
||||
char ts[9];
|
||||
sprintf(ts, "%02d:%02d:%02d", hrs, mins, secs);
|
||||
ssd1306_DrawRectangle(78, 8, 128, 16, Black, 1);
|
||||
ssd1306_WriteString(ts, Font_6x8, White);
|
||||
} else {
|
||||
ssd1306_WriteString("00:00:00", Font_6x8, White);
|
||||
}
|
||||
ssd1306_UpdateScreen();
|
||||
}// if mode < 98
|
||||
}
|
||||
|
||||
//update display header lines
|
||||
void draw_header(void) {
|
||||
char header[6], action[8];
|
||||
|
||||
switch (mode) {
|
||||
case 0:
|
||||
strcpy(header, "MENU");
|
||||
strcpy(action, "Idle");
|
||||
break;
|
||||
case 1:
|
||||
strcpy(header, menuProg[prog].text);
|
||||
strcpy(action, "Drying");
|
||||
break;
|
||||
case 2:
|
||||
strcpy(header, "STOP?");
|
||||
strcpy(action, "Drying");
|
||||
break;
|
||||
case 3:
|
||||
strcpy(header, "DONE!");
|
||||
strcpy(action, "Keeping");
|
||||
break;
|
||||
case 4:
|
||||
strcpy(header, "STOP?");
|
||||
strcpy(action, "Keeping");
|
||||
break;
|
||||
case 98:
|
||||
case 99:
|
||||
strcpy(header, "ERROR");
|
||||
break;
|
||||
} //Switch (mode)
|
||||
ssd1306_SetCursor(0, 0);
|
||||
ssd1306_WriteString(header, Font_7x10, White);
|
||||
|
||||
if (mode < 98) {
|
||||
ssd1306_SetCursor(78, 0);
|
||||
ssd1306_WriteString(action, Font_6x8, White);
|
||||
}// if mode < 98
|
||||
|
||||
}
|
||||
|
||||
//Draw program select menu
|
||||
void draw_menu(void) {
|
||||
char str[7];
|
||||
for (uint8_t i=0; i<3; i++) {
|
||||
if (prog == i + menuFrame) {
|
||||
ssd1306_Line(0, i*15 + 16, 127, i*15 + 16, White);
|
||||
ssd1306_Line(0, i*15 + 31, 127, i*15 + 31, White);
|
||||
}
|
||||
ssd1306_SetCursor(0, i*15 + 17);
|
||||
ssd1306_WriteString(menuProg[i + menuFrame].text, Font_7x10, White);
|
||||
ssd1306_SetCursor(78, i*15 + 16);
|
||||
sprintf(str, "%u *c", menuProg[i + menuFrame].drytemp);
|
||||
ssd1306_WriteString(str, Font_6x8, White);
|
||||
ssd1306_SetCursor(78, i*15 + 24);
|
||||
sprintf(str, "%luh%lum", menuProg[i + menuFrame].drytime/3600, menuProg[i + menuFrame].drytime%3600/60);
|
||||
ssd1306_WriteString(str, Font_6x8, White);
|
||||
} //for
|
||||
}
|
||||
|
||||
//Draw STOP? question
|
||||
void draw_question(void) {
|
||||
ssd1306_DrawRoundRectangle(4, 20, 123, 60, White);
|
||||
ssd1306_SetCursor(20, 33);
|
||||
ssd1306_WriteString("YES NO", Font_7x10, White);
|
||||
if (qConfirm) {
|
||||
ssd1306_DrawRoundRectangle(17, 30, 56, 49, White);
|
||||
} else {
|
||||
ssd1306_DrawRoundRectangle(77, 30, 104, 49, White);
|
||||
}
|
||||
}
|
||||
|
||||
//Draw sensor error message
|
||||
void draw_error(void) {
|
||||
char str1[8], str2[7];
|
||||
|
||||
if (mode == 99) {
|
||||
strcpy(str1, "SENSOR");
|
||||
strcpy(str2, "FAIL");
|
||||
}
|
||||
if (mode == 98) {
|
||||
strcpy(str1, "THERMAL");
|
||||
strcpy(str2, "RUNOUT");
|
||||
}
|
||||
ssd1306_DrawBitmap(111, 0, error_icon, 14, 16, White);
|
||||
ssd1306_SetCursor(26, 24);
|
||||
ssd1306_WriteString(str1, Font_7x10, White);
|
||||
ssd1306_SetCursor(38, 40);
|
||||
ssd1306_WriteString(str2, Font_7x10, White);
|
||||
}
|
||||
|
||||
//set Timer values according to requested settings
|
||||
void setPWMs(void) {
|
||||
TIM3->CCR1 = powerHeater;
|
||||
TIM3->CCR2 = powerFan;
|
||||
if (powerHeater < powerFan) {
|
||||
TIM3->ARR = powerHeater - 10;
|
||||
} else {
|
||||
TIM3->ARR = powerFan - 10;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE END Application */
|
||||
|
63
firmware/Core/Src/gpio.c
Normal file
63
firmware/Core/Src/gpio.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file gpio.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of all used GPIO pins.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "gpio.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Configure GPIO */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/** Configure pins as
|
||||
* Analog
|
||||
* Input
|
||||
* Output
|
||||
* EVENT_OUT
|
||||
* EXTI
|
||||
*/
|
||||
void MX_GPIO_Init(void)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pins : PBPin PBPin PBPin */
|
||||
GPIO_InitStruct.Pin = KEY_DN_Pin|KEY_OK_Pin|KEY_UP_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
228
firmware/Core/Src/i2c.c
Normal file
228
firmware/Core/Src/i2c.c
Normal file
@@ -0,0 +1,228 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file i2c.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the I2C instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "i2c.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
I2C_HandleTypeDef hi2c1;
|
||||
I2C_HandleTypeDef hi2c2;
|
||||
|
||||
/* I2C1 init function */
|
||||
void MX_I2C1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN I2C1_Init 0 */
|
||||
|
||||
/* USER CODE END I2C1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN I2C1_Init 1 */
|
||||
|
||||
/* USER CODE END I2C1_Init 1 */
|
||||
hi2c1.Instance = I2C1;
|
||||
hi2c1.Init.Timing = 0x10707DBC;
|
||||
hi2c1.Init.OwnAddress1 = 0;
|
||||
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||||
hi2c1.Init.OwnAddress2 = 0;
|
||||
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
|
||||
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||||
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Analogue filter
|
||||
*/
|
||||
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Digital filter
|
||||
*/
|
||||
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN I2C1_Init 2 */
|
||||
|
||||
/* USER CODE END I2C1_Init 2 */
|
||||
|
||||
}
|
||||
/* I2C2 init function */
|
||||
void MX_I2C2_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN I2C2_Init 0 */
|
||||
|
||||
/* USER CODE END I2C2_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN I2C2_Init 1 */
|
||||
|
||||
/* USER CODE END I2C2_Init 1 */
|
||||
hi2c2.Instance = I2C2;
|
||||
hi2c2.Init.Timing = 0x10707DBC;
|
||||
hi2c2.Init.OwnAddress1 = 0;
|
||||
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||||
hi2c2.Init.OwnAddress2 = 0;
|
||||
hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
|
||||
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||||
if (HAL_I2C_Init(&hi2c2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Analogue filter
|
||||
*/
|
||||
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Digital filter
|
||||
*/
|
||||
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN I2C2_Init 2 */
|
||||
|
||||
/* USER CODE END I2C2_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
if(i2cHandle->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspInit 0 */
|
||||
|
||||
/* USER CODE END I2C1_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clocks
|
||||
*/
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
|
||||
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**I2C1 GPIO Configuration
|
||||
PB8 ------> I2C1_SCL
|
||||
PB9 ------> I2C1_SDA
|
||||
*/
|
||||
GPIO_InitStruct.Pin = I2C1_SCL_BME_Pin|I2C1_SDA_BME_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF6_I2C1;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* I2C1 clock enable */
|
||||
__HAL_RCC_I2C1_CLK_ENABLE();
|
||||
/* USER CODE BEGIN I2C1_MspInit 1 */
|
||||
|
||||
/* USER CODE END I2C1_MspInit 1 */
|
||||
}
|
||||
else if(i2cHandle->Instance==I2C2)
|
||||
{
|
||||
/* USER CODE BEGIN I2C2_MspInit 0 */
|
||||
|
||||
/* USER CODE END I2C2_MspInit 0 */
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**I2C2 GPIO Configuration
|
||||
PB10 ------> I2C2_SCL
|
||||
PB11 ------> I2C2_SDA
|
||||
*/
|
||||
GPIO_InitStruct.Pin = I2C2_SCL_OLED_Pin|I2C2_SDA_OLED_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF6_I2C2;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* I2C2 clock enable */
|
||||
__HAL_RCC_I2C2_CLK_ENABLE();
|
||||
/* USER CODE BEGIN I2C2_MspInit 1 */
|
||||
|
||||
/* USER CODE END I2C2_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
|
||||
{
|
||||
|
||||
if(i2cHandle->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END I2C1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_I2C1_CLK_DISABLE();
|
||||
|
||||
/**I2C1 GPIO Configuration
|
||||
PB8 ------> I2C1_SCL
|
||||
PB9 ------> I2C1_SDA
|
||||
*/
|
||||
HAL_GPIO_DeInit(I2C1_SCL_BME_GPIO_Port, I2C1_SCL_BME_Pin);
|
||||
|
||||
HAL_GPIO_DeInit(I2C1_SDA_BME_GPIO_Port, I2C1_SDA_BME_Pin);
|
||||
|
||||
/* USER CODE BEGIN I2C1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END I2C1_MspDeInit 1 */
|
||||
}
|
||||
else if(i2cHandle->Instance==I2C2)
|
||||
{
|
||||
/* USER CODE BEGIN I2C2_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END I2C2_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_I2C2_CLK_DISABLE();
|
||||
|
||||
/**I2C2 GPIO Configuration
|
||||
PB10 ------> I2C2_SCL
|
||||
PB11 ------> I2C2_SDA
|
||||
*/
|
||||
HAL_GPIO_DeInit(I2C2_SCL_OLED_GPIO_Port, I2C2_SCL_OLED_Pin);
|
||||
|
||||
HAL_GPIO_DeInit(I2C2_SDA_OLED_GPIO_Port, I2C2_SDA_OLED_Pin);
|
||||
|
||||
/* USER CODE BEGIN I2C2_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END I2C2_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
220
firmware/Core/Src/main.c
Normal file
220
firmware/Core/Src/main.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.c
|
||||
* @brief : Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "cmsis_os.h"
|
||||
#include "i2c.h"
|
||||
#include "tim.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "ssd1306.h"
|
||||
#include "BME280_STM32.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
void MX_FREERTOS_Init(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_I2C1_Init();
|
||||
MX_I2C2_Init();
|
||||
MX_TIM3_Init();
|
||||
MX_TIM17_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
ssd1306_Init();
|
||||
BME280_Config (OSRS_2, OSRS_OFF, OSRS_1, MODE_NORMAL, T_SB_250, IIR_4);
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Init scheduler */
|
||||
osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */
|
||||
MX_FREERTOS_Init();
|
||||
|
||||
/* Start scheduler */
|
||||
osKernelStart();
|
||||
|
||||
/* We should never get here as control is now taken by the scheduler */
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
|
||||
/** Configure the main internal regulator output voltage
|
||||
*/
|
||||
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
|
||||
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
|
||||
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
|
||||
RCC_OscInitStruct.PLL.PLLN = 8;
|
||||
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
||||
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief Period elapsed callback in non blocking mode
|
||||
* @note This function is called when TIM6 interrupt took place, inside
|
||||
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
|
||||
* a global variable "uwTick" used as application time base.
|
||||
* @param htim : TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* USER CODE BEGIN Callback 0 */
|
||||
|
||||
/* USER CODE END Callback 0 */
|
||||
if (htim->Instance == TIM6) {
|
||||
HAL_IncTick();
|
||||
}
|
||||
/* USER CODE BEGIN Callback 1 */
|
||||
|
||||
/* USER CODE END Callback 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is executed in case of error occurrence.
|
||||
* @retval None
|
||||
*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
/* USER CODE BEGIN 6 */
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
83
firmware/Core/Src/pid.c
Normal file
83
firmware/Core/Src/pid.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* pid.c
|
||||
*
|
||||
* Created on: Jan 18, 2022
|
||||
* Author: mcfly
|
||||
*/
|
||||
|
||||
#include "pid.h"
|
||||
|
||||
void PID_Init(PIDController *pid) {
|
||||
//Clear controller values
|
||||
pid->integrator = 0.0f;
|
||||
pid->prevError = 0.0f;
|
||||
|
||||
pid->differentiator = 0.0f;
|
||||
pid->prevMeasurement = 0.0f;
|
||||
|
||||
pid->out = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
float PID_Update(PIDController *pid, float setpoint, float measurement) {
|
||||
// PID = Kp + Ki * 1/s + Kd * s/(s*tau+1)
|
||||
|
||||
// e = error tothe setpoint
|
||||
// p[n] = Kp * e[n]
|
||||
// i[n] = Ki*T/2 * (e[n]+e[n-1]) + i[n-1]
|
||||
// d[n] = 2*Kd/(2*tau+T) * (e[n]-e[n-1]) + (2*tau-T)/(2*tau+T) * d[n-1]
|
||||
// PID = p[n]+i[n]+d[n]
|
||||
|
||||
|
||||
//Error signal
|
||||
float error = setpoint - measurement;
|
||||
|
||||
//Proportional
|
||||
float proportional = pid->Kp * error;
|
||||
|
||||
//Integral
|
||||
pid->integrator += 0.5f * pid->Ki * pid->T * (error + pid->prevError);
|
||||
|
||||
//Anti-wind-up via dynamic integrator clamping
|
||||
float limMinInt, limMaxInt;
|
||||
|
||||
//Compute integrator limits
|
||||
if (pid->limMax > proportional) {
|
||||
limMaxInt = pid->limMax - proportional;
|
||||
} else {
|
||||
limMaxInt = 0.0f;
|
||||
}
|
||||
if (pid->limMin < proportional) {
|
||||
limMinInt = pid->limMin - proportional;
|
||||
} else {
|
||||
limMinInt = 0.0f;
|
||||
}
|
||||
|
||||
//Clamp integrator
|
||||
if (pid->integrator > limMaxInt) {
|
||||
pid->integrator = limMaxInt;
|
||||
} else if (pid->integrator < limMinInt) {
|
||||
pid->integrator = limMinInt;
|
||||
}
|
||||
|
||||
//Derivative (band-limited differentiator)
|
||||
pid->differentiator = (2.0f * pid->Kd * (measurement - pid->prevMeasurement) //Note: derivative on measurement
|
||||
+ (2.0f * pid->tau - pid->T) * pid->differentiator)
|
||||
/ (2.0f * pid->tau + pid->T);
|
||||
|
||||
//Compute output and apply limits
|
||||
pid->out = proportional + pid->integrator + pid->differentiator;
|
||||
if (pid->out > pid->limMax) {
|
||||
pid->out = pid->limMax;
|
||||
} else if (pid->out < pid->limMin) {
|
||||
pid->out = pid->limMin;
|
||||
}
|
||||
|
||||
//Store error and measurement for later use
|
||||
pid->prevError = error;
|
||||
pid->prevMeasurement = measurement;
|
||||
|
||||
//Return controller output
|
||||
return pid->out;
|
||||
|
||||
}
|
87
firmware/Core/Src/stm32g0xx_hal_msp.c
Normal file
87
firmware/Core/Src/stm32g0xx_hal_msp.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32g0xx_hal_msp.c
|
||||
* @brief This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Define */
|
||||
|
||||
/* USER CODE END Define */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Macro */
|
||||
|
||||
/* USER CODE END Macro */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* External functions --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ExternalFunctions */
|
||||
|
||||
/* USER CODE END ExternalFunctions */
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
/**
|
||||
* Initializes the Global MSP.
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
/* USER CODE BEGIN MspInit 0 */
|
||||
|
||||
/* USER CODE END MspInit 0 */
|
||||
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
|
||||
/* System interrupt init*/
|
||||
/* PendSV_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(PendSV_IRQn, 3, 0);
|
||||
|
||||
/** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
|
||||
*/
|
||||
HAL_SYSCFG_StrobeDBattpinsConfig(SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE);
|
||||
|
||||
/* USER CODE BEGIN MspInit 1 */
|
||||
|
||||
/* USER CODE END MspInit 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
136
firmware/Core/Src/stm32g0xx_hal_timebase_tim.c
Normal file
136
firmware/Core/Src/stm32g0xx_hal_timebase_tim.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32g0xx_hal_timebase_TIM.c
|
||||
* @brief HAL time base based on the hardware TIM.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32g0xx_hal.h"
|
||||
#include "stm32g0xx_hal_tim.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
TIM_HandleTypeDef htim6;
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief This function configures the TIM6 as a time base source.
|
||||
* The time source is configured to have 1ms time base with a dedicated
|
||||
* Tick interrupt priority.
|
||||
* @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().
|
||||
* @param TickPriority: Tick interrupt priority.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||
{
|
||||
RCC_ClkInitTypeDef clkconfig;
|
||||
uint32_t uwTimclock, uwAPB1Prescaler;
|
||||
|
||||
uint32_t uwPrescalerValue;
|
||||
uint32_t pFLatency;
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Enable TIM6 clock */
|
||||
__HAL_RCC_TIM6_CLK_ENABLE();
|
||||
|
||||
/* Get clock configuration */
|
||||
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
||||
|
||||
/* Get APB1 prescaler */
|
||||
uwAPB1Prescaler = clkconfig.APB1CLKDivider;
|
||||
/* Compute TIM6 clock */
|
||||
if (uwAPB1Prescaler == RCC_HCLK_DIV1)
|
||||
{
|
||||
uwTimclock = HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
else
|
||||
{
|
||||
uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
|
||||
/* Compute the prescaler value to have TIM6 counter clock equal to 1MHz */
|
||||
uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
|
||||
|
||||
/* Initialize TIM6 */
|
||||
htim6.Instance = TIM6;
|
||||
|
||||
/* Initialize TIMx peripheral as follow:
|
||||
+ Period = [(TIM6CLK/1000) - 1]. to have a (1/1000) s time base.
|
||||
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
|
||||
+ ClockDivision = 0
|
||||
+ Counter direction = Up
|
||||
*/
|
||||
htim6.Init.Period = (1000000U / 1000U) - 1U;
|
||||
htim6.Init.Prescaler = uwPrescalerValue;
|
||||
htim6.Init.ClockDivision = 0;
|
||||
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
|
||||
status = HAL_TIM_Base_Init(&htim6);
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Start the TIM time Base generation in interrupt mode */
|
||||
status = HAL_TIM_Base_Start_IT(&htim6);
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Enable the TIM6 global Interrupt */
|
||||
HAL_NVIC_EnableIRQ(TIM6_IRQn);
|
||||
/* Configure the SysTick IRQ priority */
|
||||
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
|
||||
{
|
||||
/* Configure the TIM IRQ priority */
|
||||
HAL_NVIC_SetPriority(TIM6_IRQn, TickPriority, 0U);
|
||||
uwTickPrio = TickPriority;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend Tick increment.
|
||||
* @note Disable the tick increment by disabling TIM6 update interrupt.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SuspendTick(void)
|
||||
{
|
||||
/* Disable TIM6 update Interrupt */
|
||||
__HAL_TIM_DISABLE_IT(&htim6, TIM_IT_UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume Tick increment.
|
||||
* @note Enable the tick increment by Enabling TIM6 update interrupt.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ResumeTick(void)
|
||||
{
|
||||
/* Enable TIM6 Update interrupt */
|
||||
__HAL_TIM_ENABLE_IT(&htim6, TIM_IT_UPDATE);
|
||||
}
|
||||
|
120
firmware/Core/Src/stm32g0xx_it.c
Normal file
120
firmware/Core/Src/stm32g0xx_it.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32g0xx_it.c
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "stm32g0xx_it.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
extern TIM_HandleTypeDef htim6;
|
||||
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M0+ Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @brief This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
||||
|
||||
/* USER CODE END NonMaskableInt_IRQn 0 */
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END HardFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32G0xx Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
/* For the available peripheral interrupt handler names, */
|
||||
/* please refer to the startup file (startup_stm32g0xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function handles TIM6 global interrupt.
|
||||
*/
|
||||
void TIM6_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN TIM6_IRQn 0 */
|
||||
|
||||
/* USER CODE END TIM6_IRQn 0 */
|
||||
HAL_TIM_IRQHandler(&htim6);
|
||||
/* USER CODE BEGIN TIM6_IRQn 1 */
|
||||
|
||||
/* USER CODE END TIM6_IRQn 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
155
firmware/Core/Src/syscalls.c
Normal file
155
firmware/Core/Src/syscalls.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file syscalls.c
|
||||
* @author Auto-generated by STM32CubeIDE
|
||||
* @brief STM32CubeIDE Minimal System calls file
|
||||
*
|
||||
* For more information about which c-functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the Newlib libc-manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
|
||||
/* Variables */
|
||||
extern int __io_putchar(int ch) __attribute__((weak));
|
||||
extern int __io_getchar(void) __attribute__((weak));
|
||||
|
||||
|
||||
char *__env[1] = { 0 };
|
||||
char **environ = __env;
|
||||
|
||||
|
||||
/* Functions */
|
||||
void initialise_monitor_handles()
|
||||
{
|
||||
}
|
||||
|
||||
int _getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _kill(int pid, int sig)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void _exit (int status)
|
||||
{
|
||||
_kill(status, -1);
|
||||
while (1) {} /* Make sure we hang here */
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _read(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
*ptr++ = __io_getchar();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int _close(int file)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int _fstat(int file, struct stat *st)
|
||||
{
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _isatty(int file)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _open(char *path, int flags, ...)
|
||||
{
|
||||
/* Pretend like we always fail */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _wait(int *status)
|
||||
{
|
||||
errno = ECHILD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _unlink(char *name)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _times(struct tms *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _stat(char *file, struct stat *st)
|
||||
{
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _link(char *old, char *new)
|
||||
{
|
||||
errno = EMLINK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fork(void)
|
||||
{
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _execve(char *name, char **argv, char **env)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
79
firmware/Core/Src/sysmem.c
Normal file
79
firmware/Core/Src/sysmem.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file sysmem.c
|
||||
* @author Generated by STM32CubeIDE
|
||||
* @brief STM32CubeIDE System Memory calls file
|
||||
*
|
||||
* For more information about which C functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the newlib libc manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Pointer to the current high watermark of the heap usage
|
||||
*/
|
||||
static uint8_t *__sbrk_heap_end = NULL;
|
||||
|
||||
/**
|
||||
* @brief _sbrk() allocates memory to the newlib heap and is used by malloc
|
||||
* and others from the C library
|
||||
*
|
||||
* @verbatim
|
||||
* ############################################################################
|
||||
* # .data # .bss # newlib heap # MSP stack #
|
||||
* # # # # Reserved by _Min_Stack_Size #
|
||||
* ############################################################################
|
||||
* ^-- RAM start ^-- _end _estack, RAM end --^
|
||||
* @endverbatim
|
||||
*
|
||||
* This implementation starts allocating at the '_end' linker symbol
|
||||
* The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
|
||||
* The implementation considers '_estack' linker symbol to be RAM end
|
||||
* NOTE: If the MSP stack, at any point during execution, grows larger than the
|
||||
* reserved size, please increase the '_Min_Stack_Size'.
|
||||
*
|
||||
* @param incr Memory size
|
||||
* @return Pointer to allocated memory
|
||||
*/
|
||||
void *_sbrk(ptrdiff_t incr)
|
||||
{
|
||||
extern uint8_t _end; /* Symbol defined in the linker script */
|
||||
extern uint8_t _estack; /* Symbol defined in the linker script */
|
||||
extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
|
||||
const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
|
||||
const uint8_t *max_heap = (uint8_t *)stack_limit;
|
||||
uint8_t *prev_heap_end;
|
||||
|
||||
/* Initialize heap end at first call */
|
||||
if (NULL == __sbrk_heap_end)
|
||||
{
|
||||
__sbrk_heap_end = &_end;
|
||||
}
|
||||
|
||||
/* Protect heap from growing into the reserved MSP stack */
|
||||
if (__sbrk_heap_end + incr > max_heap)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
prev_heap_end = __sbrk_heap_end;
|
||||
__sbrk_heap_end += incr;
|
||||
|
||||
return (void *)prev_heap_end;
|
||||
}
|
304
firmware/Core/Src/system_stm32g0xx.c
Normal file
304
firmware/Core/Src/system_stm32g0xx.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32g0xx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File
|
||||
*
|
||||
* This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32g0xx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
|
||||
* by the user application to setup the SysTick
|
||||
* timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
* After each device reset the HSI (8 MHz then 16 MHz) is used as system clock source.
|
||||
* Then SystemInit() function is called, in "startup_stm32g0xx.s" file, to
|
||||
* configure the system clock before to branch to main program.
|
||||
*
|
||||
* This file configures the system clock as follows:
|
||||
*=============================================================================
|
||||
*-----------------------------------------------------------------------------
|
||||
* System Clock source | HSI
|
||||
*-----------------------------------------------------------------------------
|
||||
* SYSCLK(Hz) | 16000000
|
||||
*-----------------------------------------------------------------------------
|
||||
* HCLK(Hz) | 16000000
|
||||
*-----------------------------------------------------------------------------
|
||||
* AHB Prescaler | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
* APB Prescaler | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
* HSI Division factor | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL_M | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL_N | 8
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL_P | 7
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL_Q | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL_R | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* Require 48MHz for RNG | Disabled
|
||||
*-----------------------------------------------------------------------------
|
||||
*=============================================================================
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32g0xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32G0xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32g0xx.h"
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE (8000000UL) /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/
|
||||
#endif /* LSI_VALUE */
|
||||
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE (32768UL) /*!< Value of LSE in Hz*/
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32G0xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32G0xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/************************* Miscellaneous Configuration ************************/
|
||||
/* Note: Following vector table addresses must be defined in line with linker
|
||||
configuration. */
|
||||
/*!< Uncomment the following line if you need to relocate the vector table
|
||||
anywhere in Flash or Sram, else the vector table is kept at the automatic
|
||||
remap of boot address selected */
|
||||
/* #define USER_VECT_TAB_ADDRESS */
|
||||
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table
|
||||
in Sram else user remap will be done in Flash. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#if defined(VECT_TAB_SRAM)
|
||||
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#else
|
||||
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#endif /* VECT_TAB_SRAM */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32G0xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32G0xx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/* The SystemCoreClock variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = 16000000UL;
|
||||
|
||||
const uint32_t AHBPrescTable[16UL] = {0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL, 6UL, 7UL, 8UL, 9UL};
|
||||
const uint32_t APBPrescTable[8UL] = {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32G0xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32G0xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* Configure the Vector Table location -------------------------------------*/
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @note - The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) / HSI division factor
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
|
||||
*
|
||||
* - If SYSCLK source is LSI, SystemCoreClock will contain the LSI_VALUE
|
||||
*
|
||||
* - If SYSCLK source is LSE, SystemCoreClock will contain the LSE_VALUE
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
|
||||
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
|
||||
*
|
||||
* (**) HSI_VALUE is a constant defined in stm32g0xx_hal_conf.h file (default value
|
||||
* 16 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (***) HSE_VALUE is a constant defined in stm32g0xx_hal_conf.h file (default value
|
||||
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
*
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
uint32_t tmp;
|
||||
uint32_t pllvco;
|
||||
uint32_t pllr;
|
||||
uint32_t pllsource;
|
||||
uint32_t pllm;
|
||||
uint32_t hsidiv;
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
switch (RCC->CFGR & RCC_CFGR_SWS)
|
||||
{
|
||||
case RCC_CFGR_SWS_0: /* HSE used as system clock */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
|
||||
case (RCC_CFGR_SWS_1 | RCC_CFGR_SWS_0): /* LSI used as system clock */
|
||||
SystemCoreClock = LSI_VALUE;
|
||||
break;
|
||||
|
||||
case RCC_CFGR_SWS_2: /* LSE used as system clock */
|
||||
SystemCoreClock = LSE_VALUE;
|
||||
break;
|
||||
|
||||
case RCC_CFGR_SWS_1: /* PLL used as system clock */
|
||||
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
|
||||
SYSCLK = PLL_VCO / PLLR
|
||||
*/
|
||||
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
|
||||
pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL;
|
||||
|
||||
if(pllsource == 0x03UL) /* HSE used as PLL clock source */
|
||||
{
|
||||
pllvco = (HSE_VALUE / pllm);
|
||||
}
|
||||
else /* HSI used as PLL clock source */
|
||||
{
|
||||
pllvco = (HSI_VALUE / pllm);
|
||||
}
|
||||
pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
|
||||
pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL);
|
||||
|
||||
SystemCoreClock = pllvco/pllr;
|
||||
break;
|
||||
|
||||
case 0x00000000U: /* HSI used as system clock */
|
||||
default: /* HSI used as system clock */
|
||||
hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV))>> RCC_CR_HSIDIV_Pos));
|
||||
SystemCoreClock = (HSI_VALUE/hsidiv);
|
||||
break;
|
||||
}
|
||||
/* Compute HCLK clock frequency --------------------------------------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
282
firmware/Core/Src/tim.c
Normal file
282
firmware/Core/Src/tim.c
Normal file
@@ -0,0 +1,282 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tim.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the TIM instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "tim.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
TIM_HandleTypeDef htim3;
|
||||
TIM_HandleTypeDef htim17;
|
||||
|
||||
/* TIM3 init function */
|
||||
void MX_TIM3_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN TIM3_Init 0 */
|
||||
|
||||
/* USER CODE END TIM3_Init 0 */
|
||||
|
||||
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
/* USER CODE BEGIN TIM3_Init 1 */
|
||||
|
||||
/* USER CODE END TIM3_Init 1 */
|
||||
htim3.Instance = TIM3;
|
||||
htim3.Init.Prescaler = 639;
|
||||
htim3.Init.CounterMode = TIM_COUNTERMODE_DOWN;
|
||||
htim3.Init.Period = 1000;
|
||||
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
|
||||
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_OnePulse_Init(&htim3, TIM_OPMODE_SINGLE) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
|
||||
sSlaveConfig.InputTrigger = TIM_TS_ETRF;
|
||||
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_NONINVERTED;
|
||||
sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
|
||||
sSlaveConfig.TriggerFilter = 0;
|
||||
if (HAL_TIM_SlaveConfigSynchro(&htim3, &sSlaveConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM2;
|
||||
sConfigOC.Pulse = 500;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM3_Init 2 */
|
||||
|
||||
/* USER CODE END TIM3_Init 2 */
|
||||
HAL_TIM_MspPostInit(&htim3);
|
||||
|
||||
}
|
||||
/* TIM17 init function */
|
||||
void MX_TIM17_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN TIM17_Init 0 */
|
||||
|
||||
/* USER CODE END TIM17_Init 0 */
|
||||
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
|
||||
|
||||
/* USER CODE BEGIN TIM17_Init 1 */
|
||||
|
||||
/* USER CODE END TIM17_Init 1 */
|
||||
htim17.Instance = TIM17;
|
||||
htim17.Init.Prescaler = 3199;
|
||||
htim17.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim17.Init.Period = 20000;
|
||||
htim17.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim17.Init.RepetitionCounter = 0;
|
||||
htim17.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_Base_Init(&htim17) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_Init(&htim17) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM2;
|
||||
sConfigOC.Pulse = 0;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
|
||||
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim17, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
|
||||
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
|
||||
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
|
||||
sBreakDeadTimeConfig.DeadTime = 0;
|
||||
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
|
||||
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
|
||||
sBreakDeadTimeConfig.BreakFilter = 0;
|
||||
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
|
||||
if (HAL_TIMEx_ConfigBreakDeadTime(&htim17, &sBreakDeadTimeConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM17_Init 2 */
|
||||
|
||||
/* USER CODE END TIM17_Init 2 */
|
||||
HAL_TIM_MspPostInit(&htim17);
|
||||
|
||||
}
|
||||
|
||||
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(tim_baseHandle->Instance==TIM3)
|
||||
{
|
||||
/* USER CODE BEGIN TIM3_MspInit 0 */
|
||||
|
||||
/* USER CODE END TIM3_MspInit 0 */
|
||||
/* TIM3 clock enable */
|
||||
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
/**TIM3 GPIO Configuration
|
||||
PD2 ------> TIM3_ETR
|
||||
*/
|
||||
GPIO_InitStruct.Pin = TIM3_ZeroCross_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;
|
||||
HAL_GPIO_Init(TIM3_ZeroCross_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN TIM3_MspInit 1 */
|
||||
|
||||
/* USER CODE END TIM3_MspInit 1 */
|
||||
}
|
||||
else if(tim_baseHandle->Instance==TIM17)
|
||||
{
|
||||
/* USER CODE BEGIN TIM17_MspInit 0 */
|
||||
|
||||
/* USER CODE END TIM17_MspInit 0 */
|
||||
/* TIM17 clock enable */
|
||||
__HAL_RCC_TIM17_CLK_ENABLE();
|
||||
/* USER CODE BEGIN TIM17_MspInit 1 */
|
||||
|
||||
/* USER CODE END TIM17_MspInit 1 */
|
||||
}
|
||||
}
|
||||
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(timHandle->Instance==TIM3)
|
||||
{
|
||||
/* USER CODE BEGIN TIM3_MspPostInit 0 */
|
||||
|
||||
/* USER CODE END TIM3_MspPostInit 0 */
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**TIM3 GPIO Configuration
|
||||
PB4 ------> TIM3_CH1
|
||||
PB5 ------> TIM3_CH2
|
||||
*/
|
||||
GPIO_InitStruct.Pin = TIM3_Heater_Pin|TIM3_Fan_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN TIM3_MspPostInit 1 */
|
||||
|
||||
/* USER CODE END TIM3_MspPostInit 1 */
|
||||
}
|
||||
else if(timHandle->Instance==TIM17)
|
||||
{
|
||||
/* USER CODE BEGIN TIM17_MspPostInit 0 */
|
||||
|
||||
/* USER CODE END TIM17_MspPostInit 0 */
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**TIM17 GPIO Configuration
|
||||
PA7 ------> TIM17_CH1
|
||||
*/
|
||||
GPIO_InitStruct.Pin = TIM17_BUZZER_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_TIM17;
|
||||
HAL_GPIO_Init(TIM17_BUZZER_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN TIM17_MspPostInit 1 */
|
||||
|
||||
/* USER CODE END TIM17_MspPostInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||
{
|
||||
|
||||
if(tim_baseHandle->Instance==TIM3)
|
||||
{
|
||||
/* USER CODE BEGIN TIM3_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END TIM3_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_TIM3_CLK_DISABLE();
|
||||
|
||||
/**TIM3 GPIO Configuration
|
||||
PD2 ------> TIM3_ETR
|
||||
PB4 ------> TIM3_CH1
|
||||
PB5 ------> TIM3_CH2
|
||||
*/
|
||||
HAL_GPIO_DeInit(TIM3_ZeroCross_GPIO_Port, TIM3_ZeroCross_Pin);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOB, TIM3_Heater_Pin|TIM3_Fan_Pin);
|
||||
|
||||
/* USER CODE BEGIN TIM3_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END TIM3_MspDeInit 1 */
|
||||
}
|
||||
else if(tim_baseHandle->Instance==TIM17)
|
||||
{
|
||||
/* USER CODE BEGIN TIM17_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END TIM17_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_TIM17_CLK_DISABLE();
|
||||
/* USER CODE BEGIN TIM17_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END TIM17_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
Reference in New Issue
Block a user