| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -22,20 +22,23 @@ static volatile uint16_t adc_values[4]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					const float V_REFINT = 1.23f; | 
					 | 
					 | 
					 | 
					const float V_REFINT = 1.23f; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define AVERAGEBUF_DEPTH 32 | 
					 | 
					 | 
					 | 
					#define AVERAGEBUF_DEPTH 16 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					#define OVENTEMP_HISTORY_DEPTH 10 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static struct App { | 
					 | 
					 | 
					 | 
					static struct App { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  bool heating; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  int16_t set_temp; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  int16_t wheel_normed; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  float oven_temp; | 
					 | 
					 | 
					 | 
					  float oven_temp; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  float soc_temp; | 
					 | 
					 | 
					 | 
					  float soc_temp; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  float v_sensor; | 
					 | 
					 | 
					 | 
					  float v_sensor; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//  float v_current_reference;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//  float sensor_current;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//  float r_sensor;
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uint16_t wheel; | 
					 | 
					 | 
					 | 
					  uint16_t wheel; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  bool push; | 
					 | 
					 | 
					 | 
					  bool push; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uint16_t adc_averagebuf[AVERAGEBUF_DEPTH * 4]; | 
					 | 
					 | 
					 | 
					  uint16_t adc_averagebuf[AVERAGEBUF_DEPTH * 4]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  uint8_t averagebuf_ptr; | 
					 | 
					 | 
					 | 
					  uint8_t averagebuf_ptr; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  float adc_averages[4]; | 
					 | 
					 | 
					 | 
					  float adc_averages[4]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  float oventemp_history[OVENTEMP_HISTORY_DEPTH]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  uint8_t oventemp_history_ptr; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} s_app = {}; | 
					 | 
					 | 
					 | 
					} s_app = {}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#define TSENSE_LOOKUP_LEN 101 | 
					 | 
					 | 
					 | 
					#define TSENSE_LOOKUP_LEN 101 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -146,12 +149,13 @@ static const float TSENSE_LOOKUP[TSENSE_LOOKUP_LEN] = { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        0.223001998051553f, | 
					 | 
					 | 
					 | 
					        0.223001998051553f, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}; | 
					 | 
					 | 
					 | 
					}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static float val_to_c(float val){ | 
					 | 
					 | 
					 | 
					static float val_to_c(float val) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // TODO use binary search.. lol
 | 
					 | 
					 | 
					 | 
					    // TODO use binary search.. lol
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for (int i = 1; i < TSENSE_LOOKUP_LEN; i++) { | 
					 | 
					 | 
					 | 
					    for (int i = 1; i < TSENSE_LOOKUP_LEN; i++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        float cur = TSENSE_LOOKUP[i]; | 
					 | 
					 | 
					 | 
					        float cur = TSENSE_LOOKUP[i]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (cur >= val) { | 
					 | 
					 | 
					 | 
					        if (cur >= val) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            float prev = TSENSE_LOOKUP[i-1]; | 
					 | 
					 | 
					 | 
					            float prev = TSENSE_LOOKUP[i - 1]; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            float ratio = (val - prev) / (cur - prev); | 
					 | 
					 | 
					 | 
					            float ratio = (val - prev) / (cur - prev); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return TSENSE_T_MIN + ((float) i + ratio) * TSENSE_T_STEP; | 
					 | 
					 | 
					 | 
					            return TSENSE_T_MIN + ((float) i + ratio) * TSENSE_T_STEP; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -160,7 +164,8 @@ static float val_to_c(float val){ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return TSENSE_T_MAX; | 
					 | 
					 | 
					 | 
					    return TSENSE_T_MAX; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void calculate_analog_values() { | 
					 | 
					 | 
					 | 
					void calculate_analog_values() | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    uint32_t sums[4] = {}; | 
					 | 
					 | 
					 | 
					    uint32_t sums[4] = {}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for (int i = 0; i < AVERAGEBUF_DEPTH * 4; i += 4) { | 
					 | 
					 | 
					 | 
					    for (int i = 0; i < AVERAGEBUF_DEPTH * 4; i += 4) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        sums[0] += s_app.adc_averagebuf[i]; | 
					 | 
					 | 
					 | 
					        sums[0] += s_app.adc_averagebuf[i]; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -168,10 +173,10 @@ void calculate_analog_values() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        sums[2] += s_app.adc_averagebuf[i + 2]; | 
					 | 
					 | 
					 | 
					        sums[2] += s_app.adc_averagebuf[i + 2]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        sums[3] += s_app.adc_averagebuf[i + 3]; | 
					 | 
					 | 
					 | 
					        sums[3] += s_app.adc_averagebuf[i + 3]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    s_app.adc_averages[0] = (float)sums[0] / AVERAGEBUF_DEPTH; | 
					 | 
					 | 
					 | 
					    s_app.adc_averages[0] = (float) sums[0] / AVERAGEBUF_DEPTH; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    s_app.adc_averages[1] = (float)sums[1] / AVERAGEBUF_DEPTH; | 
					 | 
					 | 
					 | 
					    s_app.adc_averages[1] = (float) sums[1] / AVERAGEBUF_DEPTH; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    s_app.adc_averages[2] = (float)sums[2] / AVERAGEBUF_DEPTH; | 
					 | 
					 | 
					 | 
					    s_app.adc_averages[2] = (float) sums[2] / AVERAGEBUF_DEPTH; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    s_app.adc_averages[3] = (float)sums[3] / AVERAGEBUF_DEPTH; | 
					 | 
					 | 
					 | 
					    s_app.adc_averages[3] = (float) sums[3] / AVERAGEBUF_DEPTH; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    /* r_pt100, r_ref, internal_temp, v_ref_int */ | 
					 | 
					 | 
					 | 
					    /* r_pt100, r_ref, internal_temp, v_ref_int */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    float refint = s_app.adc_averages[3]; | 
					 | 
					 | 
					 | 
					    float refint = s_app.adc_averages[3]; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -184,15 +189,26 @@ void calculate_analog_values() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    s_app.soc_temp = (v25 - v_tsen) / avg_slope + 25.f; | 
					 | 
					 | 
					 | 
					    s_app.soc_temp = (v25 - v_tsen) / avg_slope + 25.f; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    s_app.v_sensor = s_app.adc_averages[0] * scale; // good for debug/tuning
 | 
					 | 
					 | 
					 | 
					    s_app.v_sensor = s_app.adc_averages[0] * scale; // good for debug/tuning
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // using a voltage divider, so assuming the reference resistor is measured well,
 | 
					 | 
					 | 
					 | 
					    // using a voltage divider, so assuming the reference resistor is measured well,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // we can just use the ratio and the exact voltage value is not important.
 | 
					 | 
					 | 
					 | 
					    // we can just use the ratio and the exact voltage value is not important.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    s_app.oven_temp = val_to_c(s_app.adc_averages[0] / s_app.adc_averages[1]); | 
					 | 
					 | 
					 | 
					    float actual_temp = val_to_c(s_app.adc_averages[0] / s_app.adc_averages[1]); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    s_app.oventemp_history[s_app.oventemp_history_ptr] = actual_temp; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    s_app.oventemp_history_ptr = (s_app.oventemp_history_ptr + 1) % OVENTEMP_HISTORY_DEPTH; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    float sum = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    for (int i = 0; i < OVENTEMP_HISTORY_DEPTH; i++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        sum += s_app.oventemp_history[i]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    sum /= OVENTEMP_HISTORY_DEPTH; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    s_app.oven_temp = sum; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) | 
					 | 
					 | 
					 | 
					void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // notify
 | 
					 | 
					 | 
					 | 
					    // notify
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    memcpy((void*) &s_app.adc_averagebuf[s_app.averagebuf_ptr * 4], (const void*) adc_values, 8); | 
					 | 
					 | 
					 | 
					    memcpy((void *) &s_app.adc_averagebuf[s_app.averagebuf_ptr * 4], (const void *) adc_values, 8); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    s_app.averagebuf_ptr = (s_app.averagebuf_ptr + 1) % AVERAGEBUF_DEPTH; | 
					 | 
					 | 
					 | 
					    s_app.averagebuf_ptr = (s_app.averagebuf_ptr + 1) % AVERAGEBUF_DEPTH; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -201,7 +217,7 @@ static void hw_init() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    HAL_ADCEx_Calibration_Start(&hadc1); | 
					 | 
					 | 
					 | 
					    HAL_ADCEx_Calibration_Start(&hadc1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    /* Start periodic reading of the ADC channels */ | 
					 | 
					 | 
					 | 
					    /* Start periodic reading of the ADC channels */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)(void*)adc_values, 4); | 
					 | 
					 | 
					 | 
					    HAL_ADC_Start_DMA(&hadc1, (uint32_t *) (void *) adc_values, 4); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    /* Enable the rotary encoder */ | 
					 | 
					 | 
					 | 
					    /* Enable the rotary encoder */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL); | 
					 | 
					 | 
					 | 
					    HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -219,15 +235,8 @@ void app_main_task(void *argument) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    hw_init(); | 
					 | 
					 | 
					 | 
					    hw_init(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    /* Infinite loop */ | 
					 | 
					 | 
					 | 
					    /* Infinite loop */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    bool invert = 0; | 
					 | 
					 | 
					 | 
					    for (;;) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for(;;) | 
					 | 
					 | 
					 | 
					        //HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        s_app.wheel = htim4.Instance->CNT; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        s_app.push = 0 == HAL_GPIO_ReadPin(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        calculate_analog_values(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//        printf("Knob %d (P=%d), ADC %.2f %.2f %.2f %.2f, oven %.2f°C, soc %.2f°C, divider %.3f V  \r\n",
 | 
					 | 
					 | 
					 | 
					//        printf("Knob %d (P=%d), ADC %.2f %.2f %.2f %.2f, oven %.2f°C, soc %.2f°C, divider %.3f V  \r\n",
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//               (int) s_app.wheel, s_app.push,
 | 
					 | 
					 | 
					 | 
					//               (int) s_app.wheel, s_app.push,
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -238,33 +247,69 @@ void app_main_task(void *argument) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//                s_app.v_sensor
 | 
					 | 
					 | 
					 | 
					//                s_app.v_sensor
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					//        );
 | 
					 | 
					 | 
					 | 
					//        );
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        invert = !invert; | 
					 | 
					 | 
					 | 
					        calculate_analog_values(); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        fb_clear(); | 
					 | 
					 | 
					 | 
					        for (int i = 0; i < 50; i++) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if (s_app.push) { | 
					 | 
					 | 
					 | 
					            uint16_t old_wheel = s_app.wheel; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            fb_rect(s_app.wheel % FBW, 0, 15, 15, 1); | 
					 | 
					 | 
					 | 
					            s_app.wheel = htim4.Instance->CNT; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } else { | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if (invert) { | 
					 | 
					 | 
					 | 
					            int16_t wheel_change = (int16_t)(s_app.wheel - old_wheel); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                fb_frame(s_app.wheel % FBW, 0, 15, 15, 2, 1); | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } else { | 
					 | 
					 | 
					 | 
					            if (wheel_change != 0) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                fb_frame(s_app.wheel % FBW, 0, 15, 15, 1, 1); | 
					 | 
					 | 
					 | 
					                s_app.wheel_normed += wheel_change; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                if (s_app.wheel_normed < 0) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    s_app.wheel_normed = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                if (s_app.wheel_normed > 500) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    s_app.wheel_normed = 500; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                } | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                s_app.set_temp = (s_app.wheel_normed / 2) * 5; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            s_app.push = 0 == HAL_GPIO_ReadPin(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (wheel_change != 0 || i == 0) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                fb_clear(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                char tmp[100]; | 
					 | 
					 | 
					 | 
					                char tmp[100]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        sprintf(tmp, "%d°C", (int) s_app.oven_temp); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        fb_text(0, 20, tmp, 0, 1); | 
					 | 
					 | 
					 | 
					                sprintf(tmp, "Mereni: %d°C", (int) s_app.oven_temp); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                fb_text(10, 10, tmp, 0, 1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                sprintf(tmp, "   Cil: %d°C", s_app.set_temp); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                fb_text(10, 25, tmp, 0, 1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                if (s_app.heating) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    fb_frame(0, 0, FBW, FBH, 2, 1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                fb_blit(); | 
					 | 
					 | 
					 | 
					                fb_blit(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        vTaskDelay(100); | 
					 | 
					 | 
					 | 
					            vTaskDelay(10); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        // regulation
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        float set_f = (float) s_app.set_temp; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (!s_app.heating && s_app.oven_temp < set_f - 5.0f) { /* hysteresis */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            s_app.heating = true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (s_app.heating && s_app.oven_temp >= set_f) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            s_app.heating = false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        HAL_GPIO_WritePin(HEATER_GPIO_Port, HEATER_Pin, s_app.heating); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        /*
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // beep
 | 
					 | 
					 | 
					 | 
					        // beep
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        htim2.Instance->ARR = 12000 + (int16_t)s_app.wheel * 100; | 
					 | 
					 | 
					 | 
					        htim2.Instance->ARR = 12000 + (int16_t)s_app.wheel * 100; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        htim2.Instance->CCR1 = htim2.Instance->ARR/2; | 
					 | 
					 | 
					 | 
					        htim2.Instance->CCR1 = htim2.Instance->ARR/2; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        vTaskDelay(50); | 
					 | 
					 | 
					 | 
					        vTaskDelay(50); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        htim2.Instance->ARR = 0; | 
					 | 
					 | 
					 | 
					        htim2.Instance->ARR = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					         */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // feed dogs
 | 
					 | 
					 | 
					 | 
					        // feed dogs
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        HAL_IWDG_Refresh(&hiwdg); | 
					 | 
					 | 
					 | 
					        HAL_IWDG_Refresh(&hiwdg); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |