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:
parent
39ce3cea17
commit
bbb14f5f14
@ -230,8 +230,25 @@ extern uint32_t pios_com_vcp_id;
|
|||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
// ADC
|
// 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
|
// USB
|
||||||
|
@ -77,7 +77,7 @@ struct pios_adc_dev {
|
|||||||
uint8_t dma_block_size;
|
uint8_t dma_block_size;
|
||||||
uint16_t dma_half_buffer_size;
|
uint16_t dma_half_buffer_size;
|
||||||
int16_t fir_coeffs[PIOS_ADC_MAX_SAMPLES+1] __attribute__ ((aligned(4)));
|
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)));
|
float downsampled_buffer[PIOS_ADC_NUM_CHANNELS] __attribute__ ((aligned(4)));
|
||||||
enum pios_adc_dev_magic magic;
|
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];
|
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];
|
static uint16_t adc_raw_buffer[2][PIOS_ADC_MAX_SAMPLES][PIOS_ADC_NUM_PINS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PIOS_ADC_TIMER TIM3 /* might want this to come from the config */
|
#define PIOS_ADC_TIMER TIM3 /* might want this to come from the config */
|
||||||
#define PIOS_LOWRATE_ADC ADC1
|
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_ADC)
|
#if defined(PIOS_INCLUDE_ADC)
|
||||||
static void
|
static void
|
||||||
@ -130,6 +130,8 @@ init_pins(void)
|
|||||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
|
||||||
|
|
||||||
for (int32_t i = 0; i < PIOS_ADC_NUM_PINS; i++) {
|
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_InitStructure.GPIO_Pin = config[i].pin;
|
||||||
GPIO_Init(config[i].port, &GPIO_InitStructure);
|
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_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_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_TC, ENABLE);
|
||||||
|
//DMA_ITConfig(pios_adc_dev->cfg->dma.rx.channel, DMA_IT_HT, ENABLE);
|
||||||
|
|
||||||
/* enable DMA */
|
/* enable DMA */
|
||||||
DMA_Cmd(pios_adc_dev->cfg->dma.rx.channel, ENABLE);
|
DMA_Cmd(pios_adc_dev->cfg->dma.rx.channel, ENABLE);
|
||||||
|
|
||||||
/* Configure DMA interrupt */
|
/* Configure DMA interrupt */
|
||||||
NVIC_InitTypeDef NVICInit = pios_adc_dev->cfg->dma.irq.init;
|
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);
|
NVIC_Init(&NVICInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,8 +196,6 @@ init_timer(void)
|
|||||||
TIMInit.TIM_ClockDivision = TIM_CKD_DIV1; /* no additional divisor */
|
TIMInit.TIM_ClockDivision = TIM_CKD_DIV1; /* no additional divisor */
|
||||||
TIM_TimeBaseInit(PIOS_ADC_TIMER, &TIMInit);
|
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 */
|
/* configure trigger output on reload */
|
||||||
TIM_SelectOutputTrigger(PIOS_ADC_TIMER, TIM_TRGOSource_Update);
|
TIM_SelectOutputTrigger(PIOS_ADC_TIMER, TIM_TRGOSource_Update);
|
||||||
TIM_Cmd(PIOS_ADC_TIMER, ENABLE);
|
TIM_Cmd(PIOS_ADC_TIMER, ENABLE);
|
||||||
@ -206,6 +204,8 @@ init_timer(void)
|
|||||||
static void
|
static void
|
||||||
init_adc(void)
|
init_adc(void)
|
||||||
{
|
{
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
|
||||||
|
|
||||||
ADC_DeInit();
|
ADC_DeInit();
|
||||||
|
|
||||||
/* turn on VREFInt in case we need it */
|
/* turn on VREFInt in case we need it */
|
||||||
@ -215,7 +215,7 @@ init_adc(void)
|
|||||||
ADC_CommonInitTypeDef ADC_CommonInitStructure;
|
ADC_CommonInitTypeDef ADC_CommonInitStructure;
|
||||||
ADC_CommonStructInit(&ADC_CommonInitStructure);
|
ADC_CommonStructInit(&ADC_CommonInitStructure);
|
||||||
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
|
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_DMAAccessMode = ADC_DMAAccessMode_Disabled;
|
||||||
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
|
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
|
||||||
ADC_CommonInit(&ADC_CommonInitStructure);
|
ADC_CommonInit(&ADC_CommonInitStructure);
|
||||||
@ -224,28 +224,29 @@ init_adc(void)
|
|||||||
ADC_StructInit(&ADC_InitStructure);
|
ADC_StructInit(&ADC_InitStructure);
|
||||||
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
|
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
|
||||||
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
|
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
|
||||||
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
|
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
|
||||||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;
|
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
|
||||||
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
|
|
||||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
||||||
ADC_InitStructure.ADC_NbrOfConversion = ((PIOS_ADC_NUM_PINS)/* >> 1*/);
|
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 */
|
/* Enable DMA request */
|
||||||
ADC_DMACmd(PIOS_LOWRATE_ADC, ENABLE);
|
ADC_DMACmd(pios_adc_dev->cfg->adc_dev, ENABLE);
|
||||||
|
|
||||||
/* Configure input scan */
|
/* Configure input scan */
|
||||||
for (int32_t i = 0; i < PIOS_ADC_NUM_PINS; i++) {
|
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,
|
config[i].channel,
|
||||||
i+1,
|
i+1,
|
||||||
ADC_SampleTime_56Cycles); /* XXX this is totally arbitrary... */
|
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 */
|
/* 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
|
#endif
|
||||||
|
|
||||||
@ -297,7 +298,7 @@ int32_t PIOS_ADC_Init(const struct pios_adc_cfg * cfg)
|
|||||||
#if defined(PIOS_INCLUDE_ADC)
|
#if defined(PIOS_INCLUDE_ADC)
|
||||||
init_pins();
|
init_pins();
|
||||||
init_dma();
|
init_dma();
|
||||||
init_timer();
|
//init_timer();
|
||||||
init_adc();
|
init_adc();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -319,16 +320,17 @@ void PIOS_ADC_Config(uint32_t oversampling)
|
|||||||
* @return ADC pin value averaged over the set of samples since the last reading.
|
* @return ADC pin value averaged over the set of samples since the last reading.
|
||||||
* @return -1 if pin doesn't exist
|
* @return -1 if pin doesn't exist
|
||||||
*/
|
*/
|
||||||
|
int32_t last_conv_value;
|
||||||
int32_t PIOS_ADC_PinGet(uint32_t pin)
|
int32_t PIOS_ADC_PinGet(uint32_t pin)
|
||||||
{
|
{
|
||||||
#if defined(PIOS_INCLUDE_ADC)
|
#if defined(PIOS_INCLUDE_ADC)
|
||||||
int32_t result;
|
int32_t result;
|
||||||
|
|
||||||
/* Check if pin exists */
|
/* Check if pin exists */
|
||||||
if (pin >= PIOS_ADC_NUM_PINS) {
|
if (pin >= PIOS_ADC_NUM_PINS) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return accumulated result and clear accumulator */
|
/* return accumulated result and clear accumulator */
|
||||||
result = accumulator[pin].accumulator / (accumulator[pin].count ?: 1);
|
result = accumulator[pin].accumulator / (accumulator[pin].count ?: 1);
|
||||||
accumulator[pin].accumulator = 0;
|
accumulator[pin].accumulator = 0;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <fifo_buffer.h>
|
#include <fifo_buffer.h>
|
||||||
|
|
||||||
struct pios_adc_cfg {
|
struct pios_adc_cfg {
|
||||||
|
ADC_TypeDef* adc_dev;
|
||||||
struct stm32_dma dma;
|
struct stm32_dma dma;
|
||||||
uint32_t half_flag;
|
uint32_t half_flag;
|
||||||
uint32_t full_flag;
|
uint32_t full_flag;
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#define PIOS_INCLUDE_BL_HELPER
|
#define PIOS_INCLUDE_BL_HELPER
|
||||||
|
|
||||||
/* Enable/Disable PiOS Modules */
|
/* Enable/Disable PiOS Modules */
|
||||||
//#define PIOS_INCLUDE_ADC
|
#define PIOS_INCLUDE_ADC
|
||||||
#define PIOS_INCLUDE_DELAY
|
#define PIOS_INCLUDE_DELAY
|
||||||
#define PIOS_INCLUDE_I2C
|
#define PIOS_INCLUDE_I2C
|
||||||
#define PIOS_INCLUDE_IRQ
|
#define PIOS_INCLUDE_IRQ
|
||||||
|
@ -39,6 +39,43 @@
|
|||||||
/**
|
/**
|
||||||
* Sensor configurations
|
* 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)
|
#if defined(PIOS_INCLUDE_HMC5883)
|
||||||
#include "pios_hmc5883.h"
|
#include "pios_hmc5883.h"
|
||||||
static const struct pios_exti_cfg pios_exti_hmc5883_cfg __exti_config = {
|
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);
|
PIOS_DELAY_WaitmS(50);
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_ADC)
|
||||||
|
PIOS_ADC_Init(&pios_adc_cfg);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_HMC5883)
|
#if defined(PIOS_INCLUDE_HMC5883)
|
||||||
PIOS_HMC5883_Init(&pios_hmc5883_cfg);
|
PIOS_HMC5883_Init(&pios_hmc5883_cfg);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user