aboutsummaryrefslogtreecommitdiffhomepage
path: root/workspace/TS100/src/hardware.c
blob: 53654ad090400622897e345bc514e51da74faa25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * 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;
		}
	}
}