152 lines
4.5 KiB
C
152 lines
4.5 KiB
C
/*
|
|
* hardware.c
|
|
*
|
|
* Created on: 2Sep.,2017
|
|
* Author: Ben V. Brown
|
|
*/
|
|
|
|
//These are all the functions for interacting with the hardware
|
|
#include "hardware.h"
|
|
volatile uint16_t PWMSafetyTimer = 0;
|
|
volatile int16_t CalibrationTempOffset = 0;
|
|
void setCalibrationOffset(int16_t offSet) {
|
|
CalibrationTempOffset = offSet;
|
|
}
|
|
uint16_t getHandleTemperature() {
|
|
// We return the current handle temperature in X10 C
|
|
// TMP36 in handle, 0.5V offset and then 10mV per deg C (0.75V @ 25C for example)
|
|
// STM32 = 4096 count @ 3.3V input -> But
|
|
// We oversample by 32/(2^2) = 8 times oversampling
|
|
// Therefore 32768 is the 3.3V input, so 0.201416015625 mV per count
|
|
// So we need to subtract an offset of 0.5V to center on 0C (2482 counts)
|
|
//
|
|
uint16_t result = getADC(0);
|
|
if (result < 4964)
|
|
return 0;
|
|
result -= 4964; //remove 0.5V offset
|
|
result /= 10; //convert to X10 C
|
|
return result;
|
|
|
|
}
|
|
uint16_t tipMeasurementToC(uint16_t raw) {
|
|
return ((raw - 532) / 33) + (getHandleTemperature() / 10) - CalibrationTempOffset;
|
|
//Surprisingly that appears to be a fairly good linear best fit
|
|
}
|
|
uint16_t ctoTipMeasurement(uint16_t temp) {
|
|
//We need to compensate for cold junction temp
|
|
return ((temp - (getHandleTemperature() / 10) + CalibrationTempOffset) * 33) + 532;
|
|
}
|
|
|
|
uint16_t tipMeasurementToF(uint16_t raw) {
|
|
return ((((raw - 532) / 33) + (getHandleTemperature() / 10) - CalibrationTempOffset) * 9) / 5 + 32;
|
|
|
|
}
|
|
uint16_t ftoTipMeasurement(uint16_t temp) {
|
|
|
|
return (((((temp - 32) * 5) / 9) - (getHandleTemperature() / 10) + CalibrationTempOffset) * 33) + 532;
|
|
}
|
|
|
|
uint16_t getTipInstantTemperature() {
|
|
uint16_t sum;
|
|
sum = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_1);
|
|
sum += HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_2);
|
|
sum += HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_3);
|
|
sum += HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_4);
|
|
return sum;
|
|
|
|
}
|
|
uint16_t getTipRawTemp(uint8_t instant) {
|
|
#define filterDepth1 1
|
|
/*Pre filter used before PID*/
|
|
#define filterDepth2 16
|
|
/*Post filter used for UI display*/
|
|
static uint16_t filterLayer1[filterDepth1];
|
|
static uint16_t filterLayer2[filterDepth2];
|
|
static uint8_t index = 0;
|
|
static uint8_t indexFilter = 0;
|
|
|
|
if (instant) {
|
|
uint16_t itemp = getTipInstantTemperature();
|
|
filterLayer1[index] = itemp;
|
|
index = (index + 1) % filterDepth1;
|
|
uint32_t total = 0;
|
|
for (uint8_t i = 0; i < filterDepth1; i++)
|
|
total += filterLayer1[i];
|
|
|
|
return total / filterDepth1;
|
|
} else {
|
|
uint32_t total = 0;
|
|
for (uint8_t i = 0; i < filterDepth1; i++)
|
|
total += filterLayer1[i];
|
|
filterLayer2[indexFilter] = total / filterDepth1;
|
|
indexFilter = (indexFilter + 1) % filterDepth2;
|
|
total = 0;
|
|
for (uint8_t i = 0; i < filterDepth2; i++)
|
|
total += filterLayer2[i];
|
|
|
|
return total / filterDepth2;
|
|
}
|
|
}
|
|
uint16_t getInputVoltageX10(uint8_t divisor) {
|
|
//ADC maximum is 16384 == 3.3V at input == 28V at VIN
|
|
//Therefore we can divide down from there
|
|
//Ideal term is 117
|
|
#define BATTFILTERDEPTH 64
|
|
static uint32_t samples[BATTFILTERDEPTH];
|
|
static uint8_t index = 0;
|
|
samples[index] = getADC(1);
|
|
index = (index + 1) % BATTFILTERDEPTH;
|
|
uint32_t sum = 0;
|
|
|
|
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
|
|
sum += samples[i];
|
|
|
|
sum /= BATTFILTERDEPTH;
|
|
|
|
return sum / divisor;
|
|
}
|
|
uint8_t getTipPWM() {
|
|
return htim2.Instance->CCR4;
|
|
}
|
|
void setTipPWM(uint8_t pulse) {
|
|
PWMSafetyTimer = 100; //This is decremented in the handler for PWM so that the tip pwm is disabled if the PID task is not scheduled often enough.
|
|
if (pulse > 100)
|
|
pulse = 100;
|
|
if (pulse) {
|
|
htim2.Instance->CCR4 = pulse;
|
|
} else {
|
|
htim2.Instance->CCR4 = 0;
|
|
}
|
|
|
|
}
|
|
|
|
//Thse are called by the HAL after the corresponding events from the system timers.
|
|
|
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
|
//Period has elapsed
|
|
if (htim->Instance == TIM2) {
|
|
//we want to turn on the output again
|
|
PWMSafetyTimer--; //We decrement this safety value so that lockups in the scheduler will not cause the PWM to become locked in an active driving state.
|
|
//While we could assume this could never happened, its a small price for increased safety
|
|
if (htim2.Instance->CCR4 && PWMSafetyTimer) {
|
|
htim3.Instance->CCR1 = 50;
|
|
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
|
|
} else {
|
|
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
|
|
htim3.Instance->CCR1 = 0;
|
|
}
|
|
} else if (htim->Instance == TIM1) {
|
|
HAL_IncTick();
|
|
}
|
|
}
|
|
|
|
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) {
|
|
if (htim->Instance == TIM2) {
|
|
//This was a pulse event
|
|
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) {
|
|
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
|
|
htim3.Instance->CCR1 = 0;
|
|
}
|
|
}
|
|
}
|