1
0
forked from me/IronOS
Files
IronOS/workspace/TS100/src/hardware.c
2017-10-22 21:07:33 +11:00

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