1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Trying to get F4 PIOS_ADC working. Changed from previous implementation timed

by another timer to running continuously.  May go back to the previous since no
need to get tons of data.
This commit is contained in:
James Cotton 2012-05-15 03:08:58 -05:00
parent 39ce3cea17
commit bbb14f5f14
5 changed files with 83 additions and 22 deletions

View File

@ -230,8 +230,25 @@ extern uint32_t pios_com_vcp_id;
//-------------------------
// ADC
// None.
// PIOS_ADC_PinGet(0) = Current sensor
// PIOS_ADC_PinGet(1) = Voltage sensor
// PIOS_ADC_PinGet(4) = VREF
// PIOS_ADC_PinGet(5) = Temperature sensor
//-------------------------
#define PIOS_DMA_PIN_CONFIG \
{ \
{GPIOC, GPIO_Pin_0, ADC_Channel_10}, \
{GPIOC, GPIO_Pin_1, ADC_Channel_11}, \
{NULL, 0, ADC_Channel_Vrefint}, /* Voltage reference */ \
{NULL, 0, ADC_Channel_TempSensor} /* Temperature sensor */ \
}
/* we have to do all this to satisfy the PIOS_ADC_MAX_SAMPLES define in pios_adc.h */
/* which is annoying because this then determines the rate at which we generate buffer turnover events */
/* the objective here is to get enough buffer space to support 100Hz averaging rate */
#define PIOS_ADC_NUM_CHANNELS 4
#define PIOS_ADC_MAX_OVERSAMPLING 10
#define PIOS_ADC_USE_ADC2 0
//-------------------------
// USB

View File

@ -77,7 +77,7 @@ struct pios_adc_dev {
uint8_t dma_block_size;
uint16_t dma_half_buffer_size;
int16_t fir_coeffs[PIOS_ADC_MAX_SAMPLES+1] __attribute__ ((aligned(4)));
volatile int16_t raw_data_buffer[PIOS_ADC_MAX_SAMPLES] __attribute__ ((aligned(4))); // Double buffer that DMA just used
volatile int16_t raw_data_buffer[PIOS_ADC_MAX_SAMPLES] __attribute__ ((aligned(4)));
float downsampled_buffer[PIOS_ADC_NUM_CHANNELS] __attribute__ ((aligned(4)));
enum pios_adc_dev_magic magic;
};
@ -113,11 +113,11 @@ static struct dma_config config[] = PIOS_DMA_PIN_CONFIG;
static struct adc_accumulator accumulator[PIOS_ADC_NUM_PINS];
// Two buffers here for double buffering
static uint16_t adc_raw_buffer[2][PIOS_ADC_MAX_SAMPLES][PIOS_ADC_NUM_PINS];
#endif
#define PIOS_ADC_TIMER TIM3 /* might want this to come from the config */
#define PIOS_LOWRATE_ADC ADC1
#if defined(PIOS_INCLUDE_ADC)
static void
@ -130,6 +130,8 @@ init_pins(void)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
for (int32_t i = 0; i < PIOS_ADC_NUM_PINS; i++) {
if (config[i].port == NULL)
continue;
GPIO_InitStructure.GPIO_Pin = config[i].pin;
GPIO_Init(config[i].port, &GPIO_InitStructure);
}
@ -164,15 +166,13 @@ init_dma(void)
DMA_DoubleBufferModeConfig(pios_adc_dev->cfg->dma.rx.channel, (uint32_t)&adc_raw_buffer[1], DMA_Memory_0);
DMA_DoubleBufferModeCmd(pios_adc_dev->cfg->dma.rx.channel, ENABLE);
DMA_ITConfig(pios_adc_dev->cfg->dma.rx.channel, DMA_IT_TC, ENABLE);
//DMA_ITConfig(pios_adc_dev->cfg->dma.rx.channel, DMA_IT_HT, ENABLE);
/* enable DMA */
DMA_Cmd(pios_adc_dev->cfg->dma.rx.channel, ENABLE);
/* Configure DMA interrupt */
NVIC_InitTypeDef NVICInit = pios_adc_dev->cfg->dma.irq.init;
NVICInit.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW;
NVICInit.NVIC_IRQChannelSubPriority = 0;
NVICInit.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVICInit);
}
@ -196,8 +196,6 @@ init_timer(void)
TIMInit.TIM_ClockDivision = TIM_CKD_DIV1; /* no additional divisor */
TIM_TimeBaseInit(PIOS_ADC_TIMER, &TIMInit);
PIOS_COM_SendFormattedString(PIOS_COM_DEBUG, "TIM_Prescaler %d\r\n",TIMInit.TIM_Prescaler);
/* configure trigger output on reload */
TIM_SelectOutputTrigger(PIOS_ADC_TIMER, TIM_TRGOSource_Update);
TIM_Cmd(PIOS_ADC_TIMER, ENABLE);
@ -206,6 +204,8 @@ init_timer(void)
static void
init_adc(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC_DeInit();
/* turn on VREFInt in case we need it */
@ -215,7 +215,7 @@ init_adc(void)
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_CommonStructInit(&ADC_CommonInitStructure);
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
@ -224,28 +224,29 @@ init_adc(void)
ADC_StructInit(&ADC_InitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = ((PIOS_ADC_NUM_PINS)/* >> 1*/);
ADC_Init(PIOS_LOWRATE_ADC, &ADC_InitStructure);
ADC_Init(pios_adc_dev->cfg->adc_dev, &ADC_InitStructure);
/* Enable PIOS_LOWRATE_ADC->DMA request */
ADC_DMACmd(PIOS_LOWRATE_ADC, ENABLE);
/* Enable DMA request */
ADC_DMACmd(pios_adc_dev->cfg->adc_dev, ENABLE);
/* Configure input scan */
for (int32_t i = 0; i < PIOS_ADC_NUM_PINS; i++) {
ADC_RegularChannelConfig(PIOS_LOWRATE_ADC,
ADC_RegularChannelConfig(pios_adc_dev->cfg->adc_dev,
config[i].channel,
i+1,
ADC_SampleTime_56Cycles); /* XXX this is totally arbitrary... */
}
ADC_DMARequestAfterLastTransferCmd(PIOS_LOWRATE_ADC, ENABLE);
ADC_DMARequestAfterLastTransferCmd(pios_adc_dev->cfg->adc_dev, ENABLE);
/* Finally start initial conversion */
ADC_Cmd(PIOS_LOWRATE_ADC, ENABLE);
ADC_Cmd(pios_adc_dev->cfg->adc_dev, ENABLE);
ADC_ContinuousModeCmd(pios_adc_dev->cfg->adc_dev, ENABLE);
ADC_SoftwareStartConv(pios_adc_dev->cfg->adc_dev);
}
#endif
@ -297,7 +298,7 @@ int32_t PIOS_ADC_Init(const struct pios_adc_cfg * cfg)
#if defined(PIOS_INCLUDE_ADC)
init_pins();
init_dma();
init_timer();
//init_timer();
init_adc();
#endif
@ -319,6 +320,7 @@ void PIOS_ADC_Config(uint32_t oversampling)
* @return ADC pin value averaged over the set of samples since the last reading.
* @return -1 if pin doesn't exist
*/
int32_t last_conv_value;
int32_t PIOS_ADC_PinGet(uint32_t pin)
{
#if defined(PIOS_INCLUDE_ADC)

View File

@ -37,6 +37,7 @@
#include <fifo_buffer.h>
struct pios_adc_cfg {
ADC_TypeDef* adc_dev;
struct stm32_dma dma;
uint32_t half_flag;
uint32_t full_flag;

View File

@ -39,7 +39,7 @@
#define PIOS_INCLUDE_BL_HELPER
/* Enable/Disable PiOS Modules */
//#define PIOS_INCLUDE_ADC
#define PIOS_INCLUDE_ADC
#define PIOS_INCLUDE_DELAY
#define PIOS_INCLUDE_I2C
#define PIOS_INCLUDE_IRQ

View File

@ -39,6 +39,43 @@
/**
* Sensor configurations
*/
#if defined(PIOS_INCLUDE_ADC)
#include "pios_adc_priv.h"
void PIOS_ADC_DMC_irq_handler(void);
void DMA2_Stream4_IRQHandler(void) __attribute__((alias("PIOS_ADC_DMC_irq_handler")));
struct pios_adc_cfg pios_adc_cfg = {
.adc_dev = ADC1,
.dma = {
.irq = {
.flags = (DMA_FLAG_TCIF4 | DMA_FLAG_TEIF4 | DMA_FLAG_HTIF4),
.init = {
.NVIC_IRQChannel = DMA2_Stream4_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_LOW,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
},
},
.rx = {
.channel = DMA2_Stream4,
.init = {
.DMA_Channel = DMA_Channel_0,
.DMA_PeripheralBaseAddr = (uint32_t) & ADC1->DR
},
}
},
.half_flag = DMA_IT_HTIF4,
.full_flag = DMA_IT_TCIF4,
};
void PIOS_ADC_DMC_irq_handler(void)
{
/* Call into the generic code to handle the IRQ for this specific device */
PIOS_ADC_DMA_Handler();
}
#endif
#if defined(PIOS_INCLUDE_HMC5883)
#include "pios_hmc5883.h"
static const struct pios_exti_cfg pios_exti_hmc5883_cfg __exti_config = {
@ -795,6 +832,10 @@ void PIOS_Board_Init(void) {
PIOS_DELAY_WaitmS(50);
#if defined(PIOS_INCLUDE_ADC)
PIOS_ADC_Init(&pios_adc_cfg);
#endif
#if defined(PIOS_INCLUDE_HMC5883)
PIOS_HMC5883_Init(&pios_hmc5883_cfg);
#endif