/* Reflow Oven Controller * * Copyright (C) 2020 Mario Hüttel * * 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 . */ /** * @addtogroup safety-adc * @{ */ #include #include #include #include void safety_adc_init() { rcc_manager_enable_clock(&RCC->APB2ENR, BITMASK_TO_BITNO(SAFETY_ADC_ADC_RCC_MASK)); /* 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)); } float safety_adc_convert_channel(enum safety_adc_meas_channel channel, uint16_t analog_value) { float converted_val; switch (channel) { case SAFETY_ADC_MEAS_TEMP: converted_val = (((float)analog_value / 4095.0f * 2500.0f - SAFETY_ADC_TEMP_NOM_MV) / SAFETY_ADC_TEMP_MV_SLOPE) + SAFETY_ADC_TEMP_NOM; break; case SAFETY_ADC_MEAS_VREF: converted_val = (SAFETY_ADC_INT_REF_MV * 4095.0f) / (float)analog_value; break; default: /* Generate NaN value as default return */ converted_val = 0.0f / 0.0f; break; } return converted_val; } 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; } /** @} */