git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1315 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
a943eaecc7
commit
2ab27d3c01
21
os/io/adc.c
21
os/io/adc.c
|
@ -42,9 +42,12 @@ void adcInit(void) {
|
|||
*/
|
||||
void adcObjectInit(ADCDriver *adcp) {
|
||||
|
||||
adcp->ad_state = ADC_STOP;
|
||||
adcp->ad_config = NULL;
|
||||
adcp->ad_state = ADC_STOP;
|
||||
adcp->ad_config = NULL;
|
||||
adcp->ad_callback = NULL;
|
||||
adcp->ad_samples = NULL;
|
||||
adcp->ad_depth = 0;
|
||||
adcp->ad_grpp = NULL;
|
||||
chSemInit(&adcp->ad_sem, 0);
|
||||
}
|
||||
|
||||
|
@ -119,7 +122,7 @@ void adcStop(ADCDriver *adcp) {
|
|||
*/
|
||||
bool_t adcStartConversion(ADCDriver *adcp,
|
||||
ADCConversionGroup *grpp,
|
||||
void *samples,
|
||||
adcsample_t *samples,
|
||||
size_t depth,
|
||||
adccallback_t callback) {
|
||||
|
||||
|
@ -137,7 +140,10 @@ bool_t adcStartConversion(ADCDriver *adcp,
|
|||
return TRUE;
|
||||
}
|
||||
adcp->ad_callback = callback;
|
||||
adc_lld_start_conversion(adcp, grpp, samples, depth);
|
||||
adcp->ad_samples = samples;
|
||||
adcp->ad_depth = depth;
|
||||
adcp->ad_grpp = grpp;
|
||||
adc_lld_start_conversion(adcp);
|
||||
adcp->ad_state = ADC_RUNNING;
|
||||
chSysUnlock();
|
||||
return FALSE;
|
||||
|
@ -157,8 +163,11 @@ void adcStopConversion(ADCDriver *adcp) {
|
|||
(adcp->ad_state == ADC_RUNNING),
|
||||
"adcStopConversion(), #1",
|
||||
"invalid state");
|
||||
adc_lld_stop_conversion(adcp);
|
||||
adcp->ad_state = ADC_READY;
|
||||
if (adcp->ad_state == ADC_RUNNING) {
|
||||
adc_lld_stop_conversion(adcp);
|
||||
adcp->ad_grpp = NULL;
|
||||
adcp->ad_state = ADC_READY;
|
||||
}
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ typedef enum {
|
|||
ADC_UNINIT = 0, /**< @brief Not initialized. */
|
||||
ADC_STOP = 1, /**< @brief Stopped. */
|
||||
ADC_READY = 2, /**< @brief Ready. */
|
||||
ADC_RUNNING = 3 /**< @brief Conversion complete.*/
|
||||
ADC_RUNNING = 3 /**< @brief Conversion running. */
|
||||
} adcstate_t;
|
||||
|
||||
#include "adc_lld.h"
|
||||
|
@ -52,7 +52,7 @@ extern "C" {
|
|||
void adcStop(ADCDriver *adcp);
|
||||
bool_t adcStartConversion(ADCDriver *adcp,
|
||||
ADCConversionGroup *grpp,
|
||||
void *samples,
|
||||
adcsample_t *samples,
|
||||
size_t depth,
|
||||
adccallback_t callback);
|
||||
void adcStopConversion(ADCDriver *adcp);
|
||||
|
|
|
@ -29,11 +29,19 @@
|
|||
#include <stm32_dma.h>
|
||||
#include <nvic.h>
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if USE_STM32_ADC1 || defined(__DOXYGEN__)
|
||||
/** @brief ADC1 driver identifier.*/
|
||||
ADCDriver ADCD1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -47,13 +55,43 @@ ADCDriver ADCD1;
|
|||
* @brief ADC1 DMA interrupt handler (channel 1).
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector6C) {
|
||||
uint32_t isr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
if ((DMA1->ISR & DMA_ISR_TEIF1) != 0)
|
||||
isr = DMA1->ISR;
|
||||
if ((isr & DMA_ISR_HTIF1) != 0) {
|
||||
/* Half transfer processing.*/
|
||||
if (ADCD1.ad_callback != NULL) {
|
||||
/* Invokes the callback passing the 1st half of the buffer.*/
|
||||
ADCD1.ad_callback(ADCD1.ad_samples, ADCD1.ad_depth / 2);
|
||||
}
|
||||
}
|
||||
if ((isr & DMA_ISR_TCIF1) != 0) {
|
||||
/* Transfer complete processing.*/
|
||||
if (!ADCD1.ad_grpp->acg_circular) {
|
||||
/* End conversion.*/
|
||||
adc_lld_stop_conversion(&ADCD1);
|
||||
ADCD1.ad_grpp = NULL;
|
||||
ADCD1.ad_state = ADC_READY;
|
||||
chSemResetI(&ADCD1.ad_sem, 0);
|
||||
}
|
||||
/* Callback handling.*/
|
||||
if (ADCD1.ad_callback != NULL) {
|
||||
if (ADCD1.ad_depth > 1) {
|
||||
/* Invokes the callback passing the 2nd half of the buffer.*/
|
||||
size_t half = ADCD1.ad_depth / 2;
|
||||
ADCD1.ad_callback(ADCD1.ad_samples + half, half);
|
||||
}
|
||||
else {
|
||||
/* Invokes the callback passing the while buffer.*/
|
||||
ADCD1.ad_callback(ADCD1.ad_samples, ADCD1.ad_depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((isr & DMA_ISR_TEIF1) != 0) {
|
||||
/* DMA error processing.*/
|
||||
STM32_ADC1_DMA_ERROR_HOOK();
|
||||
else {
|
||||
/* */
|
||||
}
|
||||
DMA1->IFCR |= DMA_IFCR_CGIF1 | DMA_IFCR_CTCIF1 |
|
||||
DMA_IFCR_CHTIF1 | DMA_IFCR_CTEIF1;
|
||||
|
@ -72,10 +110,28 @@ CH_IRQ_HANDLER(Vector6C) {
|
|||
void adc_lld_init(void) {
|
||||
|
||||
#if USE_STM32_ADC1
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD1);
|
||||
ADCD1.ad_adc = ADC1;
|
||||
ADCD1.ad_dma = DMA1_Channel1;
|
||||
ADCD1.ad_dmaprio = STM32_ADC1_DMA_PRIORITY << 12;
|
||||
|
||||
/* Temporary activation.*/
|
||||
ADC1->CR1 = 0;
|
||||
ADC1->CR2 = ADC_CR2_ADON;
|
||||
|
||||
/* Reset calibration just to be safe.*/
|
||||
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
|
||||
while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
|
||||
;
|
||||
|
||||
/* Calibration.*/
|
||||
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
|
||||
while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
|
||||
;
|
||||
|
||||
/* Return the ADC in low power mode.*/
|
||||
ADC1->CR2 = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -90,8 +146,8 @@ void adc_lld_start(ADCDriver *adcp) {
|
|||
if (adcp->ad_state == ADC_STOP) {
|
||||
#if USE_STM32_ADC1
|
||||
if (&ADCD1 == adcp) {
|
||||
dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
|
||||
NVICEnableVector(DMA1_Channel1_IRQn, STM32_ADC1_IRQ_PRIORITY);
|
||||
dmaEnable(DMA1_ID);
|
||||
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;
|
||||
/* RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_ADCPRE) |
|
||||
adcp->ad_config->ac_prescaler;*/
|
||||
|
@ -99,19 +155,10 @@ void adc_lld_start(ADCDriver *adcp) {
|
|||
}
|
||||
#endif
|
||||
|
||||
/* ADC activation.*/
|
||||
adcp->ad_adc->CR1 = 0;
|
||||
/* ADC activation, the calibration procedure has already been performed
|
||||
during initialization.*/
|
||||
adcp->ad_adc->CR1 = ADC_CR1_SCAN;
|
||||
adcp->ad_adc->CR2 = ADC_CR2_ADON;
|
||||
|
||||
/* Reset calibration just to be safe.*/
|
||||
adcp->ad_adc->CR2 |= ADC_CR2_RSTCAL;
|
||||
while ((adcp->ad_adc->CR2 & ADC_CR2_RSTCAL) != 0)
|
||||
;
|
||||
|
||||
/* Calibration.*/
|
||||
adcp->ad_adc->CR2 |= ADC_CR2_CAL;
|
||||
while ((adcp->ad_adc->CR2 & ADC_CR2_CAL) != 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,7 +177,6 @@ void adc_lld_stop(ADCDriver *adcp) {
|
|||
ADC1->CR2 = 0;
|
||||
NVICDisableVector(DMA1_Channel1_IRQn);
|
||||
dmaDisable(DMA1_ID);
|
||||
/* RCC->CFGR &= ~RCC_CFGR_ADCPRE;*/
|
||||
RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN;
|
||||
}
|
||||
#endif
|
||||
|
@ -141,35 +187,27 @@ void adc_lld_stop(ADCDriver *adcp) {
|
|||
* @brief Starts an ADC conversion.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
* @param[in] grpp pointer to a @p ADCConversionGroup object
|
||||
* @param[out] samples pointer to the samples buffer
|
||||
* @param[in] depth buffer depth (matrix rows number). The buffer depth
|
||||
* must be one or an even number.
|
||||
*
|
||||
* @note The buffer is organized as a matrix of M*N elements where M is the
|
||||
* channels number configured into the conversion group and N is the
|
||||
* buffer depth. The samples are sequentially written into the buffer
|
||||
* with no gaps.
|
||||
*/
|
||||
void adc_lld_start_conversion(ADCDriver *adcp,
|
||||
ADCConversionGroup *grpp,
|
||||
void *samples,
|
||||
size_t depth) {
|
||||
void adc_lld_start_conversion(ADCDriver *adcp) {
|
||||
uint32_t ccr, n;
|
||||
ADCConversionGroup *grpp = adcp->ad_grpp;
|
||||
|
||||
/* DMA setup.*/
|
||||
adcp->ad_dma->CMAR = (uint32_t)samples;
|
||||
if (depth > 1) {
|
||||
adcp->ad_dma->CNDTR = (uint32_t)grpp->acg_num_channels * (uint32_t)depth;
|
||||
adcp->ad_dma->CCR = adcp->ad_dmaprio |
|
||||
DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 | DMA_CCR1_MINC |
|
||||
DMA_CCR1_TCIE | DMA_CCR1_TEIE | DMA_CCR1_HTIE;
|
||||
}
|
||||
else {
|
||||
adcp->ad_dma->CNDTR = (uint32_t)grpp->acg_num_channels;
|
||||
adcp->ad_dma->CCR = adcp->ad_dmaprio |
|
||||
DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 | DMA_CCR1_MINC |
|
||||
DMA_CCR1_TCIE | DMA_CCR1_TEIE;
|
||||
adcp->ad_dma->CMAR = (uint32_t)adcp->ad_samples;
|
||||
ccr = adcp->ad_dmaprio | DMA_CCR1_EN | DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 |
|
||||
DMA_CCR1_MINC | DMA_CCR1_TCIE | DMA_CCR1_TEIE;
|
||||
if (grpp->acg_circular)
|
||||
ccr |= DMA_CCR1_CIRC;
|
||||
if (adcp->ad_depth > 1) {
|
||||
/* If the buffer depth is greater than one then the half transfer interrupt
|
||||
interrupt is enabled in order to allows streaming processing.*/
|
||||
ccr |= DMA_CCR1_HTIE;
|
||||
n = (uint32_t)grpp->acg_num_channels * (uint32_t)adcp->ad_depth;
|
||||
}
|
||||
else
|
||||
n = (uint32_t)grpp->acg_num_channels;
|
||||
adcp->ad_dma->CNDTR = n;
|
||||
adcp->ad_dma->CCR = ccr;
|
||||
|
||||
/* ADC setup.*/
|
||||
adcp->ad_adc->SMPR1 = grpp->acg_smpr1;
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
|
||||
/**
|
||||
* @brief ADC1 DMA error hook.
|
||||
* @note The default action for DMA errors is a system halt because DMA error
|
||||
* can only happen because programming errors.
|
||||
*/
|
||||
#if !defined(STM32_ADC1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt()
|
||||
|
@ -99,6 +101,11 @@ typedef void (*adccallback_t)(adcsample_t *buffer, size_t n);
|
|||
* operation.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Enables the circular buffer mode for the group.
|
||||
*/
|
||||
bool_t acg_circular;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Number of the analog channels belonging to the conversion group.
|
||||
*/
|
||||
|
@ -140,6 +147,7 @@ typedef struct {
|
|||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
/* * <----------
|
||||
|
@ -164,13 +172,25 @@ typedef struct {
|
|||
*/
|
||||
const ADCConfig *ad_config;
|
||||
/**
|
||||
* @brief Semaphore for completion synchronization.
|
||||
* @brief Synchronization semaphore.
|
||||
*/
|
||||
Semaphore ad_sem;
|
||||
/**
|
||||
* @brief Current callback function or @p NULL.
|
||||
*/
|
||||
adccallback_t ad_callback;
|
||||
/**
|
||||
* @brief Current samples buffer pointer or @p NULL.
|
||||
*/
|
||||
adcsample_t *ad_samples;
|
||||
/**
|
||||
* @brief Current samples buffer depth or @p 0.
|
||||
*/
|
||||
size_t ad_depth;
|
||||
/**
|
||||
* @brief Current conversion group pointer or @p NULL.
|
||||
*/
|
||||
ADCConversionGroup *ad_grpp;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Pointer to the ADCx registers block.
|
||||
|
@ -190,20 +210,19 @@ typedef struct {
|
|||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @cond never*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void adc_lld_init(void);
|
||||
void adc_lld_start(ADCDriver *adcp);
|
||||
void adc_lld_stop(ADCDriver *adcp);
|
||||
void adc_lld_start_conversion(ADCDriver *adcp,
|
||||
ADCConversionGroup *grpp,
|
||||
void *samples,
|
||||
size_t depth);
|
||||
void adc_lld_start_conversion(ADCDriver *adcp);
|
||||
void adc_lld_stop_conversion(ADCDriver *adcp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/** @endcond*/
|
||||
|
||||
#endif /* _ADC_LLD_H_ */
|
||||
|
||||
|
|
|
@ -34,11 +34,19 @@
|
|||
SPIDriver SPID1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if USE_STM32_SPI2 || defined(__DOXYGEN__)
|
||||
/** @brief SPI2 driver identifier.*/
|
||||
SPIDriver SPID2;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static uint16_t dummyrx;
|
||||
static uint16_t dummytx;
|
||||
|
||||
|
@ -107,8 +115,9 @@ CH_IRQ_HANDLER(Vector70) {
|
|||
CH_IRQ_PROLOGUE();
|
||||
|
||||
spi_stop(&SPID1);
|
||||
if ((DMA1->ISR & DMA_ISR_TEIF2) != 0)
|
||||
chEvtBroadcastI(&SPID1.spd_dmaerror);
|
||||
if ((DMA1->ISR & DMA_ISR_TEIF2) != 0) {
|
||||
STM32_SPI1_DMA_ERROR_HOOK();
|
||||
}
|
||||
DMA1->IFCR |= DMA_IFCR_CGIF2 | DMA_IFCR_CTCIF2 |
|
||||
DMA_IFCR_CHTIF2 | DMA_IFCR_CTEIF2;
|
||||
|
||||
|
@ -122,7 +131,7 @@ CH_IRQ_HANDLER(Vector74) {
|
|||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
chEvtBroadcastI(&SPID1.spd_dmaerror);
|
||||
STM32_SPI1_DMA_ERROR_HOOK();
|
||||
DMA1->IFCR |= DMA_IFCR_CGIF3 | DMA_IFCR_CTCIF3 |
|
||||
DMA_IFCR_CHTIF3 | DMA_IFCR_CTEIF3;
|
||||
|
||||
|
@ -139,8 +148,9 @@ CH_IRQ_HANDLER(Vector78) {
|
|||
CH_IRQ_PROLOGUE();
|
||||
|
||||
spi_stop(&SPID2);
|
||||
if ((DMA1->ISR & DMA_ISR_TEIF4) != 0)
|
||||
chEvtBroadcastI(&SPID2.spd_dmaerror);
|
||||
if ((DMA1->ISR & DMA_ISR_TEIF4) != 0) {
|
||||
STM32_SPI2_DMA_ERROR_HOOK();
|
||||
}
|
||||
DMA1->IFCR |= DMA_IFCR_CGIF4 | DMA_IFCR_CTCIF4 |
|
||||
DMA_IFCR_CHTIF4 | DMA_IFCR_CTEIF4;
|
||||
|
||||
|
@ -154,7 +164,7 @@ CH_IRQ_HANDLER(Vector7C) {
|
|||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
chEvtBroadcastI(&SPID2.spd_dmaerror);
|
||||
STM32_SPI2_DMA_ERROR_HOOK();
|
||||
DMA1->IFCR |= DMA_IFCR_CGIF5 | DMA_IFCR_CTCIF5 |
|
||||
DMA_IFCR_CHTIF5 | DMA_IFCR_CTEIF5;
|
||||
|
||||
|
@ -180,7 +190,6 @@ void spi_lld_init(void) {
|
|||
SPID1.spd_dmarx = DMA1_Channel2;
|
||||
SPID1.spd_dmatx = DMA1_Channel3;
|
||||
SPID1.spd_dmaprio = STM32_SPI1_DMA_PRIORITY << 12;
|
||||
chEvtInit(&SPID1.spd_dmaerror);
|
||||
GPIOA->CRL = (GPIOA->CRL & 0x000FFFFF) | 0xB4B00000;
|
||||
#endif
|
||||
|
||||
|
@ -191,7 +200,6 @@ void spi_lld_init(void) {
|
|||
SPID2.spd_dmarx = DMA1_Channel4;
|
||||
SPID2.spd_dmatx = DMA1_Channel5;
|
||||
SPID2.spd_dmaprio = STM32_SPI2_DMA_PRIORITY << 12;
|
||||
chEvtInit(&SPID2.spd_dmaerror);
|
||||
GPIOB->CRH = (GPIOB->CRH & 0x000FFFFF) | 0xB4B00000;
|
||||
#endif
|
||||
}
|
||||
|
@ -207,7 +215,7 @@ void spi_lld_start(SPIDriver *spip) {
|
|||
if (spip->spd_state == SPI_STOP) {
|
||||
#if USE_STM32_SPI1
|
||||
if (&SPID1 == spip) {
|
||||
dmaEnable(DMA1_ID);
|
||||
dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
|
||||
NVICEnableVector(DMA1_Channel2_IRQn, STM32_SPI1_IRQ_PRIORITY);
|
||||
NVICEnableVector(DMA1_Channel3_IRQn, STM32_SPI1_IRQ_PRIORITY);
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
||||
|
@ -215,7 +223,7 @@ void spi_lld_start(SPIDriver *spip) {
|
|||
#endif
|
||||
#if USE_STM32_SPI2
|
||||
if (&SPID2 == spip) {
|
||||
dmaEnable(DMA1_ID);
|
||||
dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
|
||||
NVICEnableVector(DMA1_Channel4_IRQn, STM32_SPI2_IRQ_PRIORITY);
|
||||
NVICEnableVector(DMA1_Channel5_IRQn, STM32_SPI2_IRQ_PRIORITY);
|
||||
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
|
||||
|
|
|
@ -93,6 +93,24 @@
|
|||
#define STM32_SPI2_IRQ_PRIORITY 0x60
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI1 DMA error hook.
|
||||
* @note The default action for DMA errors is a system halt because DMA error
|
||||
* can only happen because programming errors.
|
||||
*/
|
||||
#if !defined(STM32_SPI1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI1_DMA_ERROR_HOOK() chSysHalt()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI2 DMA error hook.
|
||||
* @note The default action for DMA errors is a system halt because DMA error
|
||||
* can only happen because programming errors.
|
||||
*/
|
||||
#if !defined(STM32_SPI2_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define STM32_SPI2_DMA_ERROR_HOOK() chSysHalt()
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
@ -158,10 +176,6 @@ typedef struct {
|
|||
* @brief DMA priority bit mask.
|
||||
*/
|
||||
uint32_t spd_dmaprio;
|
||||
/**
|
||||
* @brief DMA error event.
|
||||
*/
|
||||
EventSource spd_dmaerror;
|
||||
} SPIDriver;
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -27,6 +27,14 @@
|
|||
#include <ch.h>
|
||||
#include <adc.h>
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -49,7 +57,7 @@ void adc_lld_init(void) {
|
|||
/**
|
||||
* @brief Configures and activates the ADC peripheral.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*/
|
||||
void adc_lld_start(ADCDriver *adcp) {
|
||||
|
||||
|
@ -62,7 +70,7 @@ void adc_lld_start(ADCDriver *adcp) {
|
|||
/**
|
||||
* @brief Deactivates the ADC peripheral.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*/
|
||||
void adc_lld_stop(ADCDriver *adcp) {
|
||||
|
||||
|
@ -71,28 +79,16 @@ void adc_lld_stop(ADCDriver *adcp) {
|
|||
/**
|
||||
* @brief Starts an ADC conversion.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
* @param[in] grpp pointer to a @p ADCConversionGroup object
|
||||
* @param[out] samples pointer to the samples buffer
|
||||
* @param[in] depth buffer depth (matrix rows number). The buffer depth
|
||||
* must be one or an even number.
|
||||
*
|
||||
* @note The buffer is organized as a matrix of M*N elements where M is the
|
||||
* channels number configured into the conversion group and N is the
|
||||
* buffer depth. The samples are sequentially written into the buffer
|
||||
* with no gaps.
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*/
|
||||
void adc_lld_start_conversion(ADCDriver *adcp,
|
||||
ADCConversionGroup *grpp,
|
||||
void *samples,
|
||||
size_t depth) {
|
||||
void adc_lld_start_conversion(ADCDriver *adcp) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops an ongoing conversion.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*/
|
||||
void adc_lld_stop_conversion(ADCDriver *adcp) {
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ typedef struct {
|
|||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
|
@ -88,13 +89,25 @@ typedef struct {
|
|||
*/
|
||||
const ADCConfig *ad_config;
|
||||
/**
|
||||
* @brief Semaphore for completion synchronization.
|
||||
* @brief Synchronization semaphore.
|
||||
*/
|
||||
Semaphore ac_sem;
|
||||
Semaphore ad_sem;
|
||||
/**
|
||||
* @brief Current callback function or @p NULL.
|
||||
*/
|
||||
adccallback_t ad_callback;
|
||||
/**
|
||||
* @brief Current samples buffer pointer or @p NULL.
|
||||
*/
|
||||
adcsample_t *ad_samples;
|
||||
/**
|
||||
* @brief Current samples buffer depth or @p 0.
|
||||
*/
|
||||
size_t ad_depth;
|
||||
/**
|
||||
* @brief Current conversion group pointer or @p NULL.
|
||||
*/
|
||||
ADCConversionGroup *ad_grpp;
|
||||
/* End of the mandatory fields.*/
|
||||
} ADCDriver;
|
||||
|
||||
|
@ -108,10 +121,7 @@ extern "C" {
|
|||
void adc_lld_init(void);
|
||||
void adc_lld_start(ADCDriver *adcp);
|
||||
void adc_lld_stop(ADCDriver *adcp);
|
||||
void adc_lld_start_conversion(ADCDriver *adcp,
|
||||
ADCConversionGroup *grpp,
|
||||
void *samples,
|
||||
size_t depth);
|
||||
void adc_lld_start_conversion(ADCDriver *adcp);
|
||||
void adc_lld_stop_conversion(ADCDriver *adcp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -27,6 +27,14 @@
|
|||
#include <ch.h>
|
||||
#include <spi.h>
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -3,8 +3,13 @@
|
|||
*****************************************************************************
|
||||
|
||||
*** 1.3.5 ***
|
||||
- NEW: STM32 ADC driver implementation with DMA support.
|
||||
- CHANGE: In the STM32 drivers now the DMA errors are handled by hook macros
|
||||
rather than by events. The default action is to halt the system but users
|
||||
are able to override this and define custom handling.
|
||||
- CHANGE: In the Cortex-M3 port, modified the NVICEnableVector() function
|
||||
to make it clear pending interrupts.
|
||||
- CHANGE: Minor changes to the ADC driver model.
|
||||
|
||||
*** 1.3.4 ***
|
||||
- FIX: Fixed bug in STM32 PAL port driver (bug 2897636).
|
||||
|
|
Loading…
Reference in New Issue