STM32F411: implement analog-stm32.c

It's not that easy like LPC. We need later an DMA to control all ADCs, because there is only one register to read the ADC.
This commit is contained in:
Nico Tonnhofer 2015-12-02 00:32:48 +01:00
parent c3a8b7fd06
commit 4cb6f85e3c
3 changed files with 118 additions and 5 deletions

96
analog-stm32.c Normal file
View File

@ -0,0 +1,96 @@
/** \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__ */

View File

@ -36,6 +36,7 @@ static uint8_t adc_channel[NUM_TEMP_SENSORS] = {
#define TEACUP_C_INCLUDE #define TEACUP_C_INCLUDE
#include "analog-avr.c" #include "analog-avr.c"
#include "analog-lpc.c" #include "analog-lpc.c"
#include "analog-stm32.c"
#undef TEACUP_C_INCLUDE #undef TEACUP_C_INCLUDE
// No common code so far. // No common code so far.

View File

@ -11,7 +11,7 @@
functions, spread over various files, slow execution (pin toggling about functions, spread over various files, slow execution (pin toggling about
15 times slower than what we have here). 15 times slower than what we have here).
FASTIO by setting the BSRR (bit set/reset register), FASTIO by setting the BSRR (bit set/reset register),
- Bit0-15 to set - Bit0-15 to set
- Bit16-31 to reset. - Bit16-31 to reset.
@ -24,10 +24,10 @@
/** Pins for UART, the serial port. /** Pins for UART, the serial port.
*/ */
#define RXD_PORT PIOA_3_PORT #define RXD_PORT PA_3_PORT
#define RXD_PIN PIOA_3_PIN #define RXD_PIN PA_3_PIN
#define TXD_PORT PIOA_2_PORT #define TXD_PORT PA_2_PORT
#define TXD_PIN PIOA_2_PIN #define TXD_PIN PA_2_PIN
/** /**
We define only pins available on the Nucleo F411RE here. We define only pins available on the Nucleo F411RE here.
@ -36,27 +36,35 @@
#define PA_0_PIN 0 #define PA_0_PIN 0
#define PA_0_PORT GPIOA #define PA_0_PORT GPIOA
#define PA_0_ADC 0
#define PA_1_PIN 1 #define PA_1_PIN 1
#define PA_1_PORT GPIOA #define PA_1_PORT GPIOA
#define PA_1_ADC 1
#define PA_2_PIN 2 #define PA_2_PIN 2
#define PA_2_PORT GPIOA #define PA_2_PORT GPIOA
#define PA_2_ADC 2
#define PA_3_PIN 3 #define PA_3_PIN 3
#define PA_3_PORT GPIOA #define PA_3_PORT GPIOA
#define PA_3_ADC 3
#define PA_4_PIN 4 #define PA_4_PIN 4
#define PA_4_PORT GPIOA #define PA_4_PORT GPIOA
#define PA_4_ADC 4
#define PA_5_PIN 5 #define PA_5_PIN 5
#define PA_5_PORT GPIOA #define PA_5_PORT GPIOA
#define PA_5_ADC 5
#define PA_6_PIN 6 #define PA_6_PIN 6
#define PA_6_PORT GPIOA #define PA_6_PORT GPIOA
#define PA_6_ADC 6
#define PA_7_PIN 7 #define PA_7_PIN 7
#define PA_7_PORT GPIOA #define PA_7_PORT GPIOA
#define PA_7_ADC 7
#define PA_8_PIN 8 #define PA_8_PIN 8
#define PA_8_PORT GPIOA #define PA_8_PORT GPIOA
@ -84,9 +92,11 @@
#define PB_0_PIN 0 #define PB_0_PIN 0
#define PB_0_PORT GPIOB #define PB_0_PORT GPIOB
#define PB_0_ADC 8
#define PB_1_PIN 1 #define PB_1_PIN 1
#define PB_1_PORT GPIOB #define PB_1_PORT GPIOB
#define PB_1_ADC 9
#define PB_2_PIN 2 #define PB_2_PIN 2
#define PB_2_PORT GPIOB #define PB_2_PORT GPIOB
@ -129,21 +139,27 @@
#define PC_0_PIN 0 #define PC_0_PIN 0
#define PC_0_PORT GPIOC #define PC_0_PORT GPIOC
#define PC_0_ADC 10
#define PC_1_PIN 1 #define PC_1_PIN 1
#define PC_1_PORT GPIOC #define PC_1_PORT GPIOC
#define PC_1_ADC 11
#define PC_2_PIN 2 #define PC_2_PIN 2
#define PC_2_PORT GPIOC #define PC_2_PORT GPIOC
#define PC_2_ADC 12
#define PC_3_PIN 3 #define PC_3_PIN 3
#define PC_3_PORT GPIOC #define PC_3_PORT GPIOC
#define PC_3_ADC 13
#define PC_4_PIN 4 #define PC_4_PIN 4
#define PC_4_PORT GPIOC #define PC_4_PORT GPIOC
#define PC_4_ADC 14
#define PC_5_PIN 5 #define PC_5_PIN 5
#define PC_5_PORT GPIOC #define PC_5_PORT GPIOC
#define PC_5_ADC 15
#define PC_6_PIN 6 #define PC_6_PIN 6
#define PC_6_PORT GPIOC #define PC_6_PORT GPIOC