Teacup_Firmware/analog-stm32.c

97 lines
2.6 KiB
C

/** \file
\brief Analog subsystem, ARM specific part.
*/
#if defined TEACUP_C_INCLUDE && defined __ARM_STM32F411__
#include "cmsis-stm32f4xx.h"
#include "arduino.h"
#include "temp.h"
/** Inititalise the analog subsystem.
Initialise the ADC and start hardware scan loop for all used sensors.
*/
void analog_init() {
if (NUM_TEMP_SENSORS) { // At least one channel in use.
PIOC_2_PORT->MODER |= (GPIO_MODER_MODER0 << ((PIOC_2_PIN) << 1)); // analog mode
PIOC_2_PORT->PUPDR &= ~(3 << ((PIOC_2_PIN) << 1)); // no pullup
PIOC_2_PORT->OSPEEDR |= (3 << ((PIOC_2_PIN) << 1)); // high speed
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //Enable clock
/* Set ADC parameters */
/* Set the ADC clock prescaler */
/* Datasheet says max. ADC-clock is 36MHz
We don't need that much. 12MHz is slowest possible.
*/
ADC->CCR |= (ADC_CCR_ADCPRE);
/* Set ADC scan mode */
// scan mode disabled
// reset resolution
// discontinous mode disabled
ADC1->CR1 &= ~( ADC_CR1_SCAN |
ADC_CR1_RES |
ADC_CR1_DISCEN);
/* Set ADC resolution */
// resoltion 10bit
ADC1->CR1 |= ADC_CR1_RES_0;
/* Set ADC data alignment */
// reset = right align
// reset external trigger
//
// disable continous conversion mode
// disable ADC DMA continuous request
// disable ADC end of conversion selection
ADC1->CR2 &= ~( ADC_CR2_ALIGN |
ADC_CR2_EXTSEL |
ADC_CR2_EXTEN |
ADC_CR2_CONT |
ADC_CR2_DDS |
ADC_CR2_EOCS);
/* Set ADC number of conversion */
// 1 conversion
ADC1->SQR1 &= ~(ADC_SQR1_L);
}
}
/** Read analog value.
\param channel Channel to be read.
\return Analog reading, 10-bit right aligned.
STM32F4 goes a different way. The ADC don't have a register for
each channel. We need a DMA soon to convert and hold all datas.
*/
//#include "delay.h"
uint16_t analog_read(uint8_t index) {
// 11.8.2 Managing a sequence of conversions without using the DMA
// page 220
ADC1->SMPR1 &= ~(ADC_SMPR1_SMP12); // PIOC_2_ADC 12
// 3 CYCLES
ADC1->SQR3 &= ~(ADC_SQR3_SQ1); // rank 1
ADC1->SQR3 |= PIOC_2_ADC; // << (5 * (rank - 1))
ADC1->CR2 |= ADC_CR2_ADON // A/D Converter ON / OFF
| ADC_CR2_SWSTART; // Start Conversion of regular channels
while (!(ADC1->SR & ADC_SR_EOC) == ADC_SR_EOC);
return ADC1->DR;
}
#endif /* defined TEACUP_C_INCLUDE && defined __ARM_STM32F411__ */