ADC PT1000 Measurement progress
This commit is contained in:
		| @@ -1,30 +1,98 @@ | |||||||
| #include <adc-meas.h> | #include <adc-meas.h> | ||||||
| #include <stm32f4xx.h> | #include <stm32f4xx.h> | ||||||
|  | #include <core_cm4.h> | ||||||
| #include <stm32-gpio-macros.h> | #include <stm32-gpio-macros.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
| static float pt1000_offset; | static float pt1000_offset; | ||||||
| static float pt1000_sens_dev; | static float pt1000_sens_dev; | ||||||
| static bool calibration_active; | static bool calibration_active; | ||||||
| static float filter_alpha; | static float filter_alpha; | ||||||
| static float pt1000_adc_raw_lf; | static volatile float pt1000_res_raw_lf; | ||||||
| static bool streaming_active; | static volatile bool streaming_active; | ||||||
| static volatile bool filter_ready; | static volatile bool filter_ready; | ||||||
| static volatile enum adc_p1000_error pt1000_error; | static volatile enum adc_pt1000_error pt1000_error; | ||||||
|  | static volatile uint8_t *dma_flag_ptr = NULL; | ||||||
|  | static uint32_t filter_startup_cnt; | ||||||
|  |  | ||||||
| #define ADC_TO_RES(adc) ((float)(adc) / 4096.0f * 2500.0f) | #define ADC_TO_RES(adc) ((float)(adc) / 4096.0f * 2500.0f) | ||||||
|  |  | ||||||
|  | static inline void adc_pt1000_stop_sample_frequency_timer() | ||||||
|  | { | ||||||
|  | 	TIM2->CR1 &= ~TIM_CR1_CEN; | ||||||
|  | 	RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void adc_pt1000_setup_sample_frequency_timer() | ||||||
|  | { | ||||||
|  | 	RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; | ||||||
|  |  | ||||||
|  | 	/* Divide 42 MHz peripheral clock by 42 */ | ||||||
|  | 	TIM2->PSC = (42UL-1UL); | ||||||
|  |  | ||||||
|  | 	/* Reload value */ | ||||||
|  | 	TIM2->ARR = ADC_PT1000_SAMPLE_CNT_DELAY; | ||||||
|  |  | ||||||
|  | 	/* Trigger output at update event */ | ||||||
|  | 	TIM2->CR2 = TIM_CR2_MMS_1; | ||||||
|  |  | ||||||
|  | 	/* Start Timer in downcounting mode with autoreload */ | ||||||
|  | 	TIM2->CR1 = TIM_CR1_DIR | TIM_CR1_CEN; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void adc_pt1000_disable_adc() | ||||||
|  | { | ||||||
|  | 	ADC1->CR2 &= ~ADC_CR2_ADON; | ||||||
|  | 	DMA2_Stream0->CR = 0; | ||||||
|  | 	RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN; | ||||||
|  | } | ||||||
|  |  | ||||||
| void adc_pt1000_setup_meas() | void adc_pt1000_setup_meas() | ||||||
| { | { | ||||||
| 	RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; | 	RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; | ||||||
| 	RCC->AHB1ENR |= ADC_PT1000_PORT_RCC_MASK; | 	RCC->AHB1ENR |= ADC_PT1000_PORT_RCC_MASK; | ||||||
| 	ADC_PT1000_PORT->MODER |= ANALOG(ADC_PT1000_PIN); | 	ADC_PT1000_PORT->MODER |= ANALOG(ADC_PT1000_PIN); | ||||||
|  |  | ||||||
|  | 	/* Set S&H time for PT1000 ADC channel */ | ||||||
|  | #if ADC_PT1000_CHANNEL < 10 | ||||||
|  | 	ADC1->SMPR2 |= (7U << (3*ADC_PT1000_CHANNEL)); | ||||||
|  | #else | ||||||
|  | 	ADC1->SMPR1 |= (7U << (3*(ADC_PT1000_CHANNEL-10))); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	ADC->CCR |= (0x2<<16); | ||||||
|  |  | ||||||
|  | 	/* Set watchdog limits */ | ||||||
|  | 	ADC1->HTR = ADC_PT1000_UPPER_WATCHDOG; | ||||||
|  | 	ADC1->LTR = ADC_PT1000_LOWER_WATCHDOG; | ||||||
|  |  | ||||||
|  | 	/* Set length of sequence to 1 */ | ||||||
|  | 	ADC1->SQR1 = (0UL<<20); | ||||||
|  |  | ||||||
|  | 	/* Set channel as 1st element in sequence */ | ||||||
|  | 	ADC1->SQR3 = (ADC_PT1000_CHANNEL<<0); | ||||||
|  |  | ||||||
|  | 	ADC1->CR1 = ADC_CR1_OVRIE | ADC_CR1_AWDEN | ADC_CR1_EOCIE; | ||||||
|  | 	ADC1->CR2 = ADC_CR2_EXTEN_0 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_CR2_ADON; | ||||||
|  |  | ||||||
|  | 	adc_pt1000_set_moving_average_filter_param(ADC_PT1000_FILTER_WEIGHT); | ||||||
|  | 	adc_pt1000_set_resistance_calibration(0, 0, false); | ||||||
|  | 	streaming_active = false; | ||||||
|  | 	pt1000_res_raw_lf = 0.0f; | ||||||
|  |  | ||||||
|  | 	NVIC_EnableIRQ(ADC_IRQn); | ||||||
|  |  | ||||||
|  | 	RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; | ||||||
|  |  | ||||||
|  | 	adc_pt1000_setup_sample_frequency_timer(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void adc_pt1000_set_moving_average_filter_param(float alpha) | void adc_pt1000_set_moving_average_filter_param(float alpha) | ||||||
| { | { | ||||||
| 	filter_alpha = alpha; | 	filter_alpha = alpha; | ||||||
|  | 	filter_ready = false; | ||||||
|  | 	filter_startup_cnt = ADC_FILTER_STARTUP_CYCLES; | ||||||
| } | } | ||||||
|  |  | ||||||
| void adc_pt1000_set_resistance_calibration(float offset, float sensitivity_deviation, bool active) | void adc_pt1000_set_resistance_calibration(float offset, float sensitivity_deviation, bool active) | ||||||
| @@ -44,6 +112,15 @@ void adc_pt1000_get_resistance_calibration(float *offset, float *sensitivity_dev | |||||||
| 	*active = calibration_active; | 	*active = calibration_active; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static inline float adc_pt1000_apply_calibration(float raw_resistance) | ||||||
|  | { | ||||||
|  | 	if (calibration_active) | ||||||
|  | 		return pt1000_res_raw_lf * (1.0f + pt1000_sens_dev) + pt1000_offset; | ||||||
|  | 	else | ||||||
|  | 		return raw_resistance; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| int adc_pt1000_get_current_resistance(float *resistance) | int adc_pt1000_get_current_resistance(float *resistance) | ||||||
| { | { | ||||||
| 	int ret_val = 0; | 	int ret_val = 0; | ||||||
| @@ -51,24 +128,22 @@ int adc_pt1000_get_current_resistance(float *resistance) | |||||||
| 	if (!resistance) | 	if (!resistance) | ||||||
| 		return -1001; | 		return -1001; | ||||||
|  |  | ||||||
| 	if (calibration_active) | 	*resistance = adc_pt1000_apply_calibration(pt1000_res_raw_lf); | ||||||
| 		*resistance = ADC_TO_RES(pt1000_adc_raw_lf) * (1 + pt1000_sens_dev) + pt1000_offset; |  | ||||||
| 	else |  | ||||||
| 		*resistance = ADC_TO_RES(pt1000_adc_raw_lf); |  | ||||||
|  |  | ||||||
| 	if (adc_pt1000_check_error()) { | 	if (adc_pt1000_check_error()) { | ||||||
| 		ret_val = -100; | 		ret_val = -100; | ||||||
| 		goto return_value; | 		goto return_value; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (!filter_ready) { | ||||||
|  | 		ret_val = 2; | ||||||
|  | 		goto return_value; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (streaming_active) { | 	if (streaming_active) { | ||||||
| 		ret_val = 1; | 		ret_val = 1; | ||||||
| 		goto return_value; | 		goto return_value; | ||||||
| 	} | 	} | ||||||
| 	if (!filter_ready) |  | ||||||
| 	{ |  | ||||||
| 		ret_val = 2; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| return_value: | return_value: | ||||||
| 	return ret_val; | 	return ret_val; | ||||||
| @@ -76,7 +151,44 @@ return_value: | |||||||
|  |  | ||||||
| int adc_pt1000_stream_raw_value_to_memory(uint16_t *adc_array, uint32_t length, volatile uint8_t *flag_to_set) | int adc_pt1000_stream_raw_value_to_memory(uint16_t *adc_array, uint32_t length, volatile uint8_t *flag_to_set) | ||||||
| { | { | ||||||
|  | 	static volatile uint8_t alt_flag; | ||||||
|  | 	int ret_val = 0; | ||||||
|  |  | ||||||
|  | 	if (!(ADC1->CR2 & ADC_CR2_ADON)) | ||||||
|  | 		return -1; | ||||||
|  |  | ||||||
|  | 	if (!adc_array || !length) | ||||||
|  | 		return -1000; | ||||||
|  |  | ||||||
|  | 	if (flag_to_set) | ||||||
|  | 		dma_flag_ptr = flag_to_set; | ||||||
|  | 	else | ||||||
|  | 		dma_flag_ptr = &alt_flag; | ||||||
|  |  | ||||||
|  | 	*dma_flag_ptr = 0; | ||||||
|  | 	streaming_active = true; | ||||||
|  |  | ||||||
|  | 	ADC1->CR2 &= ~ADC_CR2_ADON; | ||||||
|  | 	DMA2_Stream0->CR &= ~DMA_SxCR_EN; | ||||||
|  |  | ||||||
|  | 	DMA2_Stream0->M0AR = (uint32_t)adc_array; | ||||||
|  | 	DMA2_Stream0->PAR = (uint32_t)&ADC1->DR; | ||||||
|  |  | ||||||
|  | 	DMA2_Stream0->CR = DMA_SxCR_PL_1 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_TCIE; | ||||||
|  | 	DMA2_Stream0->NDTR = length; | ||||||
|  | 	NVIC_EnableIRQ(DMA2_Stream0_IRQn); | ||||||
|  |  | ||||||
|  | 	DMA2_Stream0->CR |= DMA_SxCR_EN; | ||||||
|  | 	ADC1->CR2 |= ADC_CR2_ADON | ADC_CR2_DMA; | ||||||
|  |  | ||||||
|  | 	if (!flag_to_set) { | ||||||
|  | 		while(!alt_flag); | ||||||
|  |  | ||||||
|  | 		if (alt_flag < 0) | ||||||
|  | 			ret_val = -alt_flag; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return ret_val; | ||||||
| } | } | ||||||
|  |  | ||||||
| void adc_pt1000_convert_raw_value_array_to_resistance(float *resistance_dest, uint16_t *raw_source, uint32_t count) | void adc_pt1000_convert_raw_value_array_to_resistance(float *resistance_dest, uint16_t *raw_source, uint32_t count) | ||||||
| @@ -84,7 +196,7 @@ void adc_pt1000_convert_raw_value_array_to_resistance(float *resistance_dest, ui | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| enum adc_p1000_error adc_pt1000_check_error() | enum adc_pt1000_error adc_pt1000_check_error() | ||||||
| { | { | ||||||
| 	return pt1000_error; | 	return pt1000_error; | ||||||
| } | } | ||||||
| @@ -94,9 +206,20 @@ void adc_pt1000_clear_error() | |||||||
| 	pt1000_error = ADC_PT1000_NO_ERR; | 	pt1000_error = ADC_PT1000_NO_ERR; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void adc_pt1000_filter(uint16_t adc_value) | void adc_pt1000_disable() | ||||||
| { | { | ||||||
| 	pt1000_adc_raw_lf = (1-filter_alpha) * pt1000_adc_raw_lf + filter_alpha * (float)adc_value; | 	adc_pt1000_disable_adc(); | ||||||
|  | 	adc_pt1000_stop_sample_frequency_timer(); | ||||||
|  | 	filter_ready = false; | ||||||
|  | 	pt1000_res_raw_lf = 0.0f; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline __attribute__((optimize("O3"))) void adc_pt1000_filter(uint16_t adc_value) | ||||||
|  | { | ||||||
|  | 	if (!filter_ready && --filter_startup_cnt <= 0) | ||||||
|  | 		filter_ready = true; | ||||||
|  |  | ||||||
|  | 	pt1000_res_raw_lf = (1-filter_alpha) * pt1000_res_raw_lf + filter_alpha * ADC_TO_RES((float)adc_value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ADC_IRQHandler(void) | void ADC_IRQHandler(void) | ||||||
| @@ -111,13 +234,38 @@ void ADC_IRQHandler(void) | |||||||
|  |  | ||||||
| 	if (adc1_sr & ADC_SR_OVR) { | 	if (adc1_sr & ADC_SR_OVR) { | ||||||
| 		ADC1->SR &= ~ADC_SR_OVR; | 		ADC1->SR &= ~ADC_SR_OVR; | ||||||
| 		pt1000_error = ADC_PT1000_OVERFLOW; | 		pt1000_error |= ADC_PT1000_OVERFLOW; | ||||||
| 		/* Disable ADC  in case of overrrun*/ | 		/* Disable ADC  in case of overrrun*/ | ||||||
| 		ADC1->CR2 &= ADC_CR2_ADON; | 		adc_pt1000_disable(); | ||||||
|  | 		if (streaming_active) { | ||||||
|  | 			streaming_active = false; | ||||||
|  | 			*dma_flag_ptr = -1; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (adc1_sr & ADC_SR_AWD) { | 	if (adc1_sr & ADC_SR_AWD) { | ||||||
| 		ADC1->SR &= ~ADC_SR_AWD; | 		ADC1->SR &= ~ADC_SR_AWD; | ||||||
| 		pt1000_error = ADC_PT1000_WATCHDOG_ERROR; | 		pt1000_error |= ADC_PT1000_WATCHDOG_ERROR; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void DMA2_Stream0_IRQHandler() | ||||||
|  | { | ||||||
|  | 	uint32_t lisr; | ||||||
|  |  | ||||||
|  | 	lisr = DMA2->LISR; | ||||||
|  | 	DMA2->LIFCR = lisr; | ||||||
|  |  | ||||||
|  | 	if (lisr & DMA_LISR_TCIF0) { | ||||||
|  | 		*dma_flag_ptr = 1; | ||||||
|  | 		ADC1->CR2 &= ~ADC_CR2_DMA; | ||||||
|  | 		streaming_active = false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (lisr & DMA_LISR_TEIF0) { | ||||||
|  | 		*dma_flag_ptr = -2; | ||||||
|  | 		ADC1->CR2 &= ~ADC_CR2_DMA; | ||||||
|  | 		streaming_active = false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
|   | |||||||
| @@ -19,7 +19,9 @@ | |||||||
|  |  | ||||||
| #define ADC_PT1000_PIN 2 | #define ADC_PT1000_PIN 2 | ||||||
|  |  | ||||||
| #define ADC_FILTER_STARTUP_CYCLES 200 | #define ADC_FILTER_STARTUP_CYCLES 800 | ||||||
|  |  | ||||||
|  | #define ADC_PT1000_SAMPLE_CNT_DELAY 2000 | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief Lower value for valid input range for PT1000 measurement |  * @brief Lower value for valid input range for PT1000 measurement | ||||||
| @@ -35,7 +37,7 @@ | |||||||
|  */ |  */ | ||||||
| #define ADC_PT1000_UPPER_WATCHDOG 4000 | #define ADC_PT1000_UPPER_WATCHDOG 4000 | ||||||
|  |  | ||||||
| enum adc_p1000_error {ADC_PT1000_NO_ERR= 0, ADC_PT1000_WATCHDOG_ERROR=-1, ADC_PT1000_OVERFLOW=2}; | enum adc_pt1000_error {ADC_PT1000_NO_ERR= 0, ADC_PT1000_WATCHDOG_ERROR=(1UL<<0), ADC_PT1000_OVERFLOW=(1UL<<1)}; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief This function sets up the ADC measurement fo the external PT1000 temperature sensor |  * @brief This function sets up the ADC measurement fo the external PT1000 temperature sensor | ||||||
| @@ -86,8 +88,7 @@ void adc_pt1000_get_resistance_calibration(float *offset, float *sensitivity_dev | |||||||
|  * If the reistance calibration is enabled, this function applies the calculations of the raw reistance reading and |  * If the reistance calibration is enabled, this function applies the calculations of the raw reistance reading and | ||||||
|  * returns the corrected value. |  * returns the corrected value. | ||||||
|  * |  * | ||||||
|  * If an ADC error is set, the status is negative. If the ADC is in streaming mode, the reistance reading is disabled and |  * If an ADC error is set, the status is negative. The status is 2 during the first measurements with a given filter setting. Technically, the resistance value is | ||||||
|  * the status is 1. The status is 2 during the first measurements with a given filter setting. Technically, the resistance value is |  | ||||||
|  * correct but the filter is not stable yet. |  * correct but the filter is not stable yet. | ||||||
|  * Use adc_pt1000_check_error to check the error and reinitialize the ADC. |  * Use adc_pt1000_check_error to check the error and reinitialize the ADC. | ||||||
|  * |  * | ||||||
| @@ -102,7 +103,6 @@ int adc_pt1000_get_current_resistance(float *resistance); | |||||||
|  * |  * | ||||||
|  * Streaming is done using DMA2 Stream0. |  * Streaming is done using DMA2 Stream0. | ||||||
|  * This function is used for gathering fullspeed sampling data for external interfaces or calibration |  * This function is used for gathering fullspeed sampling data for external interfaces or calibration | ||||||
|  * During streaming, the adc_pt1000_get_current_resistance() function will return an error |  | ||||||
|  * |  * | ||||||
|  * @param adc_array Array to stream data to |  * @param adc_array Array to stream data to | ||||||
|  * @param length Amount of data points to be measured |  * @param length Amount of data points to be measured | ||||||
| @@ -118,8 +118,10 @@ void adc_pt1000_convert_raw_value_array_to_resistance(float *resistance_dest, ui | |||||||
|  * |  * | ||||||
|  * In case of an error, it may be necessary to call adc_pt1000_setup_meas() again in order to recover from the error |  * In case of an error, it may be necessary to call adc_pt1000_setup_meas() again in order to recover from the error | ||||||
|  */ |  */ | ||||||
| enum adc_p1000_error adc_pt1000_check_error(); | enum adc_pt1000_error adc_pt1000_check_error(); | ||||||
|  |  | ||||||
| void adc_pt1000_clear_error(); | void adc_pt1000_clear_error(); | ||||||
|  |  | ||||||
|  | void adc_pt1000_disable(); | ||||||
|  |  | ||||||
| #endif // __ADCMEAS_H__ | #endif // __ADCMEAS_H__ | ||||||
|   | |||||||
| @@ -7,120 +7,39 @@ | |||||||
| #include <stm32f4xx.h> | #include <stm32f4xx.h> | ||||||
| #include <systick.h> | #include <systick.h> | ||||||
| //#include <arm_math.h> | //#include <arm_math.h> | ||||||
|  | #include <stm32-gpio-macros.h> | ||||||
| #include <system_stm32f4xx.h> | #include <system_stm32f4xx.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <adc-meas.h> | #include <adc-meas.h> | ||||||
|  |  | ||||||
| #define OUTPUT(pin)  (0b01 << (pin * 2)) | static void setup_nvic_priorities() | ||||||
| #define ANALOG(pin)  (0x03 << (pin * 2)) |  | ||||||
|  |  | ||||||
| struct adc_conversions { |  | ||||||
| 	uint16_t pa2_raw; |  | ||||||
| 	uint16_t ref_raw; |  | ||||||
| 	uint16_t temp_raw; |  | ||||||
| 	uint16_t vbat_raw; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static volatile struct adc_conversions adc_results; |  | ||||||
|  |  | ||||||
| volatile uint64_t sample_count = 0; |  | ||||||
| volatile uint8_t new_data = 0; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void DMA2_Stream0_IRQHandler() |  | ||||||
| { | { | ||||||
| 	uint32_t lisr; | 	/* No sub priorities */ | ||||||
|  | 	NVIC_SetPriorityGrouping(2); | ||||||
|  |  | ||||||
| 	lisr = DMA2->LISR; | 	/* Setup Priorities */ | ||||||
| 	DMA2->LIFCR = lisr; | 	NVIC_SetPriority(ADC_IRQn, 1); | ||||||
|  | 	NVIC_SetPriority(DMA2_Stream0_IRQn, 2); | ||||||
| 	if (lisr & DMA_LISR_TCIF0) { |  | ||||||
| 		if (new_data) |  | ||||||
| 			new_data = 2; |  | ||||||
| 		new_data = 1; |  | ||||||
| 		sample_count++; |  | ||||||
|  |  | ||||||
| 		GPIOB->ODR ^= (1<<3); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void setup_dma(void *dest, size_t size) |  | ||||||
| { |  | ||||||
| 	RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; |  | ||||||
|  |  | ||||||
| 	DMA2_Stream0->M0AR = (uint32_t)dest; |  | ||||||
| 	DMA2_Stream0->PAR = (uint32_t)&ADC1->DR; |  | ||||||
| 	DMA2_Stream0->CR = DMA_SxCR_PL_1 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | |  | ||||||
| 			DMA_SxCR_CIRC | DMA_SxCR_TCIE; |  | ||||||
| 	DMA2_Stream0->NDTR = size; |  | ||||||
| 	NVIC_EnableIRQ(DMA2_Stream0_IRQn); |  | ||||||
|  |  | ||||||
| 	DMA2_Stream0->CR |= DMA_SxCR_EN; |  | ||||||
| 	new_data = 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| float ext_lf_corr; |  | ||||||
|  |  | ||||||
| float temp_lf_corr; |  | ||||||
|  |  | ||||||
| float ref_lf; |  | ||||||
| float vdd_calculated = 3.3f; |  | ||||||
|  |  | ||||||
| float vbat_lf_corr; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static void setup_timers(void) |  | ||||||
| { |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static float pt1000_value; | ||||||
|  | static volatile int pt1000_value_status; | ||||||
|  |  | ||||||
| int main() { | int main() { | ||||||
| 	struct adc_conversions working; |  | ||||||
|  |  | ||||||
| 	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; |  | ||||||
| 	RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; |  | ||||||
| 	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; | 	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; | ||||||
| 	__DSB(); | 	__DSB(); | ||||||
| 	GPIOB->MODER = OUTPUT(2) | OUTPUT(3); | 	GPIOB->MODER = OUTPUT(2) | OUTPUT(3); | ||||||
| 	GPIOA->MODER |= ANALOG(2); |  | ||||||
| 	GPIOB->ODR |= (1<<2); | 	GPIOB->ODR |= (1<<2); | ||||||
|  |  | ||||||
| 	ADC1->SMPR2 = (7U<<(3*2)); | 	setup_nvic_priorities(); | ||||||
| 	ADC1->SMPR1 = (7U<<18) | (7U<<21) | (7U<<24); |  | ||||||
| 	ADC1->SQR1 = (2<<20); |  | ||||||
| 	ADC1->SQR3 = (2<<0) | (16<<(5*2)) | (17<<(5*1)); |  | ||||||
|  |  | ||||||
| 	ADC->CCR |= (0x2<<16) | ADC_CCR_TSVREFE; |  | ||||||
| 	ADC1->CR1 = ADC_CR1_SCAN; |  | ||||||
| 	ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS; |  | ||||||
| 	 |  | ||||||
| 	//while(1); |  | ||||||
|  |  | ||||||
| 	systick_setup(); | 	systick_setup(); | ||||||
|  |  | ||||||
| 	setup_dma(&adc_results, 3); | 	//setup_dma(&adc_results, 3); | ||||||
| 	adc_pt1000_setup_meas(); | 	adc_pt1000_setup_meas(); | ||||||
|  |  | ||||||
| 	ADC1->CR2 |= ADC_CR2_SWSTART; |  | ||||||
|  |  | ||||||
| 	while(1) { | 	while(1) { | ||||||
| 		if (!new_data) { | 		pt1000_value_status = adc_pt1000_get_current_resistance(&pt1000_value); | ||||||
| 			continue; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		 |  | ||||||
| 		memcpy(&working, &adc_results, sizeof(adc_results)); |  | ||||||
| 		new_data = 0; |  | ||||||
| 		//ref_lf = 0.995f * ref_lf + 0.005f * (float)working.ref_raw; |  | ||||||
| 		//vdd_calculated = ((1.21f * 4096)/ ref_lf); |  | ||||||
|  |  | ||||||
| 		//temp_lf_corr = 0.99f * temp_lf_corr + 0.01 * (float)working.temp_raw * vdd_calculated / 2.495f; |  | ||||||
| 		ext_lf_corr = 0.995f * ext_lf_corr + 0.005f * (float)working.pa2_raw / 4096 * 2500.0f; // * vdd_calculated / 2.495f; |  | ||||||
|  |  | ||||||
| 		//vbat_lf_corr = 0.99 * vbat_lf_corr + 0.01 * (float)working.vbat_raw / 4096 * vdd_calculated * 2.0f; |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user