First files added

This commit is contained in:
2023-01-24 20:41:43 +03:00
parent 1055809523
commit bc058cabc3
177 changed files with 394297 additions and 0 deletions

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

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

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

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

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

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

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