Move safety ADC to safety subfolder
This commit is contained in:
		
							
								
								
									
										188
									
								
								stm-firmware/safety/safety-adc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								stm-firmware/safety/safety-adc.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,188 @@
 | 
			
		||||
/* Reflow Oven Controller
 | 
			
		||||
*
 | 
			
		||||
* Copyright (C) 2020  Mario Hüttel <mario.huettel@gmx.net>
 | 
			
		||||
*
 | 
			
		||||
* This file is part of the Reflow Oven Controller Project.
 | 
			
		||||
*
 | 
			
		||||
* The reflow oven controller is free software: you can redistribute it and/or modify
 | 
			
		||||
* it under the terms of the GNU General Public License version 2 as
 | 
			
		||||
* published by the Free Software Foundation.
 | 
			
		||||
*
 | 
			
		||||
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
 | 
			
		||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | 
			
		||||
* GNU General Public License for more details.
 | 
			
		||||
*
 | 
			
		||||
* You should have received a copy of the GNU General Public License
 | 
			
		||||
* along with the reflow oven controller project.
 | 
			
		||||
* If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <reflow-controller/safety/safety-adc.h>
 | 
			
		||||
#include <reflow-controller/periph-config/safety-adc-hwcfg.h>
 | 
			
		||||
#include <helper-macros/helper-macros.h>
 | 
			
		||||
#include <stm-periph/clock-enable-manager.h>
 | 
			
		||||
 | 
			
		||||
enum safety_adc_check_result global_safety_adc_status;
 | 
			
		||||
 | 
			
		||||
enum safety_adc_check_result safety_adc_get_errors()
 | 
			
		||||
{
 | 
			
		||||
	return global_safety_adc_status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void safety_adc_clear_errors(void)
 | 
			
		||||
{
 | 
			
		||||
	global_safety_adc_status = SAFETY_ADC_CHECK_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void safety_adc_init()
 | 
			
		||||
{
 | 
			
		||||
	rcc_manager_enable_clock(&RCC->APB2ENR, BITMASK_TO_BITNO(SAFETY_ADC_ADC_RCC_MASK));
 | 
			
		||||
 | 
			
		||||
	safety_adc_clear_errors();
 | 
			
		||||
 | 
			
		||||
	/* Enable temperature and VREFINT measurement */
 | 
			
		||||
	ADC->CCR |= ADC_CCR_TSVREFE;
 | 
			
		||||
 | 
			
		||||
	/* Set sample time for channels 16 and 17 */
 | 
			
		||||
	SAFETY_ADC_ADC_PERIPHERAL->SMPR1 |= ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16;
 | 
			
		||||
 | 
			
		||||
	/* Standard sequence. One measurement */
 | 
			
		||||
	SAFETY_ADC_ADC_PERIPHERAL->SQR1 = 0UL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void safety_adc_deinit()
 | 
			
		||||
{
 | 
			
		||||
	SAFETY_ADC_ADC_PERIPHERAL->CR1 = 0UL;
 | 
			
		||||
	SAFETY_ADC_ADC_PERIPHERAL->CR2 = 0UL;
 | 
			
		||||
	SAFETY_ADC_ADC_PERIPHERAL->SMPR1  = 0UL;
 | 
			
		||||
	rcc_manager_enable_clock(&RCC->APB1ENR, BITMASK_TO_BITNO(RCC_APB2ENR_ADC2EN));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum safety_adc_check_result safety_adc_check_results(uint16_t vref_result, uint16_t temp_result,
 | 
			
		||||
						      float *vref_calculated, float *temp_calculated)
 | 
			
		||||
{
 | 
			
		||||
	enum safety_adc_check_result res = SAFETY_ADC_CHECK_OK;
 | 
			
		||||
	float vref;
 | 
			
		||||
	float temp;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	vref = (SAFETY_ADC_INT_REF_MV * 4095.0f) / (float)vref_result;
 | 
			
		||||
	if (vref_calculated) {
 | 
			
		||||
		*vref_calculated = vref;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	temp = (((float)temp_result / 4095.0f * 2500.0f -
 | 
			
		||||
			     SAFETY_ADC_TEMP_NOM_MV) / SAFETY_ADC_TEMP_MV_SLOPE) + SAFETY_ADC_TEMP_NOM;
 | 
			
		||||
	if (temp_calculated) {
 | 
			
		||||
		*temp_calculated = temp;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ABS(vref - SAFETY_ADC_VREF_MVOLT) > SAFETY_ADC_VREF_TOL_MVOLT) {
 | 
			
		||||
		if (vref > SAFETY_ADC_VREF_MVOLT)
 | 
			
		||||
			res |= SAFETY_ADC_CHECK_VREF_HIGH;
 | 
			
		||||
		else
 | 
			
		||||
			res |= SAFETY_ADC_CHECK_VREF_LOW;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (temp < SAFETY_ADC_TEMP_LOW_LIM)
 | 
			
		||||
		res |= SAFETY_ADC_CHECK_TEMP_LOW;
 | 
			
		||||
	else if (temp < SAFETY_ADC_CHECK_TEMP_HIGH)
 | 
			
		||||
		res |= SAFETY_ADC_CHECK_TEMP_HIGH;
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int safety_adc_poll_result(uint16_t *adc_result)
 | 
			
		||||
{
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
 | 
			
		||||
	if (!adc_result)
 | 
			
		||||
		return -1000;
 | 
			
		||||
 | 
			
		||||
	if (!(SAFETY_ADC_ADC_PERIPHERAL->CR2 & ADC_CR2_ADON)) {
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (SAFETY_ADC_ADC_PERIPHERAL->SR & ADC_SR_EOC) {
 | 
			
		||||
		*adc_result = (uint16_t)SAFETY_ADC_ADC_PERIPHERAL->DR;
 | 
			
		||||
		SAFETY_ADC_ADC_PERIPHERAL->CR2 &= ~ADC_CR2_ADON;
 | 
			
		||||
		ret = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void safety_adc_trigger_meas(enum safety_adc_meas_channel measurement)
 | 
			
		||||
{
 | 
			
		||||
	switch (measurement) {
 | 
			
		||||
	case SAFETY_ADC_MEAS_TEMP:
 | 
			
		||||
		SAFETY_ADC_ADC_PERIPHERAL->SQR3 = TEMP_CHANNEL_NUM;
 | 
			
		||||
		break;
 | 
			
		||||
	case SAFETY_ADC_MEAS_VREF:
 | 
			
		||||
		SAFETY_ADC_ADC_PERIPHERAL->SQR3 = INT_REF_CHANNEL_NUM;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SAFETY_ADC_ADC_PERIPHERAL->CR2 |= ADC_CR2_ADON;
 | 
			
		||||
	SAFETY_ADC_ADC_PERIPHERAL->CR2 |= ADC_CR2_SWSTART;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint16_t safety_vref_meas_raw;
 | 
			
		||||
static bool safety_vref_valid = false;
 | 
			
		||||
static uint16_t safety_temp_meas_raw;
 | 
			
		||||
static bool safety_temp_valid = false;
 | 
			
		||||
static float safety_vref;
 | 
			
		||||
static float safety_temp;
 | 
			
		||||
 | 
			
		||||
enum safety_adc_check_result handle_safety_adc()
 | 
			
		||||
{
 | 
			
		||||
	static enum safety_adc_meas_channel safety_meas_channel = SAFETY_ADC_MEAS_VREF;
 | 
			
		||||
	enum safety_adc_check_result check_result;
 | 
			
		||||
	uint16_t result;
 | 
			
		||||
	int poll_status;
 | 
			
		||||
 | 
			
		||||
	poll_status = safety_adc_poll_result(&result);
 | 
			
		||||
 | 
			
		||||
	if (poll_status < 0) {
 | 
			
		||||
		safety_adc_trigger_meas(safety_meas_channel);
 | 
			
		||||
	} else if (poll_status > 0) {
 | 
			
		||||
		switch (safety_meas_channel) {
 | 
			
		||||
		case SAFETY_ADC_MEAS_TEMP:
 | 
			
		||||
			safety_temp_meas_raw = result;
 | 
			
		||||
			safety_temp_valid = true;
 | 
			
		||||
			safety_meas_channel = SAFETY_ADC_MEAS_VREF;
 | 
			
		||||
			break;
 | 
			
		||||
		case SAFETY_ADC_MEAS_VREF:
 | 
			
		||||
			safety_vref_meas_raw = result;
 | 
			
		||||
			safety_vref_valid = true;
 | 
			
		||||
			safety_meas_channel = SAFETY_ADC_MEAS_TEMP;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			safety_meas_channel = SAFETY_ADC_MEAS_VREF;
 | 
			
		||||
			return SAFETY_ADC_INTERNAL_ERROR;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (safety_temp_valid && safety_vref_valid) {
 | 
			
		||||
		check_result = safety_adc_check_results(safety_vref_meas_raw, safety_temp_meas_raw, &safety_vref, &safety_temp);
 | 
			
		||||
		global_safety_adc_status |= check_result;
 | 
			
		||||
	} else {
 | 
			
		||||
		check_result = SAFETY_ADC_CHECK_OK;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return check_result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float safety_adc_get_temp()
 | 
			
		||||
{
 | 
			
		||||
	return safety_temp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float safety_adc_get_vref()
 | 
			
		||||
{
 | 
			
		||||
	return safety_vref;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user