Merge pull request #323 from WestberryTech/chibios-21.11.x-wb
Added support for WB32 MCU of ADC and DMAC.
This commit is contained in:
commit
a4072ada3b
|
@ -164,5 +164,11 @@
|
|||
#define WB32_USB_USB1_IRQ_PRIORITY 13
|
||||
#define WB32_USB_HOST_WAKEUP_DURATION 10
|
||||
|
||||
/*
|
||||
* ADC driver system settings.
|
||||
*/
|
||||
#define WB32_ADC_USE_ADC1 FALSE
|
||||
#define WB32_ADC_ADC1_DMA_PRIORITY 2
|
||||
#define WB32_ADC_ADC1_IRQ_PRIORITY 6
|
||||
|
||||
#endif /* MCUCONF_H */
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
ifeq ($(USE_SMART_BUILD),yes)
|
||||
ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
|
||||
PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c
|
||||
endif
|
||||
else
|
||||
PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c
|
||||
endif
|
||||
|
||||
PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/ADCv1
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
Copyright (C) 2022 Westberry Technology (ChangZhou) Corp., Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ADCv1/hal_adc_lld.c
|
||||
* @brief WB32 ADC subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define SARENR_SAREN_BB BIT_BAND_ADDR(&ANCTL->SARENR, 0)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief ADC driver identifier.*/
|
||||
#if WB32_ADC_USE_ADC1 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Shared ADC DMA ISR service routine.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
* @param[in] flags pre-shifted content of the ISR register
|
||||
*/
|
||||
static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
|
||||
|
||||
/* DMA errors handling.*/
|
||||
if ((flags & WB32_DMAC_IT_ERR) != 0) {
|
||||
/* DMA, this could help only if the DMA tries to access an unmapped
|
||||
address space or violates alignment rules.*/
|
||||
_adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
|
||||
}
|
||||
else {
|
||||
if ((flags & WB32_DMAC_IT_TFR) != 0) {
|
||||
/* Transfer complete processing.*/
|
||||
_adc_isr_full_code(adcp);
|
||||
}
|
||||
/* Because WB32 DMAC hasn't half transfer interrupt,
|
||||
so it use transfer complete interrupt. */
|
||||
else if ((flags & WB32_DMAC_IT_TFR) != 0) {
|
||||
/* Half transfer processing.*/
|
||||
_adc_isr_half_code(adcp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level ADC driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_init(void) {
|
||||
uint32_t tmpreg1 = 0;
|
||||
|
||||
#if WB32_ADC_USE_ADC1
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD1);
|
||||
ADCD1.adc = ADC;
|
||||
ADCD1.dmastp = NULL;
|
||||
ADCD1.dmamode = WB32_DMA_CHCFG_HWHIF(WB32_DMAC_HWHIF_ADC_Regular) | \
|
||||
WB32_DMA_CHCFG_PL(WB32_ADC_ADC1_DMA_PRIORITY) | \
|
||||
WB32_DMA_CHCFG_PSIZE_HWORD | \
|
||||
WB32_DMA_CHCFG_MSIZE_HWORD | \
|
||||
WB32_DMA_CHCFG_DIR_P2M | \
|
||||
WB32_DMA_CHCFG_MINC | \
|
||||
WB32_DMA_CHCFG_CIRC;
|
||||
|
||||
/* Temporary activation.*/
|
||||
rccEnableADC();
|
||||
|
||||
PWR->ANAKEY1 = 0x03;
|
||||
PWR->ANAKEY2 = 0x0C;
|
||||
|
||||
*(__IO uint32_t*) SARENR_SAREN_BB = (uint32_t)ENABLE;
|
||||
|
||||
PWR->ANAKEY1 = 0x00;
|
||||
PWR->ANAKEY2 = 0x00;
|
||||
|
||||
tmpreg1 = (uint8_t)(((WB32_PCLK1 / 6000000) >> 1) - 1);
|
||||
ADC->CR3 = ((tmpreg1 << 8) | ADC_CR3_12BIT);
|
||||
|
||||
ADC->CR1 = 0;
|
||||
ADC->CR2 = ADC_CR2_ADON;
|
||||
|
||||
/* Calibration.*/
|
||||
ADC->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
|
||||
while ((ADC->CR2 & ADC_CR2_CAL) != 0)
|
||||
;
|
||||
|
||||
/* Reset calibration just to be safe.*/
|
||||
ADC->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
|
||||
while ((ADC->CR2 & ADC_CR2_RSTCAL) != 0)
|
||||
;
|
||||
|
||||
/* Return the ADC in low power mode.*/
|
||||
ADC->CR2 = 0;
|
||||
rccDisableADC();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the ADC peripheral.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_start(ADCDriver *adcp) {
|
||||
|
||||
/* If in stopped state then enables the ADC clocks.*/
|
||||
if (adcp->state == ADC_STOP) {
|
||||
#if WB32_ADC_USE_ADC1
|
||||
if (&ADCD1 == adcp) {
|
||||
adcp->dmastp = dmaStreamAllocI(WB32_ADC_ADC1_DMA_STREAM,
|
||||
WB32_ADC_ADC1_IRQ_PRIORITY,
|
||||
(wb32_dmaisr_t)adc_lld_serve_rx_interrupt,
|
||||
(void *)adcp);
|
||||
osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
|
||||
dmaStreamSetSource(adcp->dmastp, &ADC->DR);
|
||||
dmaStreamEnableInterrupt(adcp->dmastp, WB32_DMAC_IT_TFR);
|
||||
|
||||
PWR->ANAKEY1 = 0x03;
|
||||
PWR->ANAKEY2 = 0x0C;
|
||||
*(__IO uint32_t*) SARENR_SAREN_BB = (uint32_t)ENABLE;
|
||||
PWR->ANAKEY1 = 0x00;
|
||||
PWR->ANAKEY2 = 0x00;
|
||||
|
||||
rccEnableADC();
|
||||
}
|
||||
#endif /* WB32_ADC_USE_ADC1 */
|
||||
|
||||
/* ADC setup, the calibration procedure has already been performed
|
||||
during initialization.*/
|
||||
adcp->adc->CR1 = 0;
|
||||
adcp->adc->CR2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the ADC peripheral.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_stop(ADCDriver *adcp) {
|
||||
|
||||
/* If in ready state then disables the ADC clock.*/
|
||||
if (adcp->state == ADC_READY) {
|
||||
#if WB32_ADC_USE_ADC1
|
||||
if (&ADCD1 == adcp) {
|
||||
ADC->CR1 = 0;
|
||||
ADC->CR2 = 0;
|
||||
|
||||
dmaStreamFreeI(adcp->dmastp);
|
||||
adcp->dmastp = NULL;
|
||||
|
||||
rccDisableADC();
|
||||
|
||||
PWR->ANAKEY1 = 0x03;
|
||||
PWR->ANAKEY2 = 0x0C;
|
||||
*(__IO uint32_t*) SARENR_SAREN_BB = (uint32_t)DISABLE;
|
||||
PWR->ANAKEY1 = 0x00;
|
||||
PWR->ANAKEY2 = 0x00;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts an ADC conversion.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_start_conversion(ADCDriver *adcp) {
|
||||
uint32_t cr2, mode;
|
||||
uint32_t tmpreg1 = 0;
|
||||
const ADCConversionGroup *grpp = adcp->grpp;
|
||||
|
||||
/* DMA setup.*/
|
||||
mode = adcp->dmamode;
|
||||
if (grpp->circular) {
|
||||
mode |= WB32_DMA_CHCFG_CIRC;
|
||||
if (adcp->depth > 1) {
|
||||
/* If circular buffer depth > 1, then the half transfer interrupt
|
||||
is enabled in order to allow streaming processing.*/
|
||||
mode |= WB32_DMA_CHCFG_TCIE;
|
||||
}
|
||||
}
|
||||
dmaStreamSetDestination(adcp->dmastp, adcp->samples);
|
||||
dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
|
||||
(uint32_t)adcp->depth);
|
||||
dmaStreamSetMode(adcp->dmastp, mode);
|
||||
dmaStreamEnable(adcp->dmastp);
|
||||
|
||||
/* ADC setup.*/
|
||||
adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN;
|
||||
cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_ADON;
|
||||
if ((cr2 & (ADC_CR2_EXTTRIG | ADC_CR2_JEXTTRIG)) == 0)
|
||||
cr2 |= ADC_CR2_CONT;
|
||||
tmpreg1 = (uint8_t)(((WB32_PCLK1 / 6000000) >> 1) - 1);
|
||||
adcp->adc->CR2 = grpp->cr2 | cr2;
|
||||
adcp->adc->SMPR1 = grpp->smpr1;
|
||||
adcp->adc->SMPR2 = grpp->smpr2;
|
||||
adcp->adc->SQR1 = grpp->sqr1;
|
||||
adcp->adc->SQR2 = grpp->sqr2;
|
||||
adcp->adc->SQR3 = grpp->sqr3;
|
||||
adcp->adc->CR3 = ((tmpreg1 << 8) | ADC_CR3_12BIT);
|
||||
|
||||
/* ADC start by writing ADC_CR2_ADON a second time.*/
|
||||
adcp->adc->CR2 = cr2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops an ongoing conversion.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_stop_conversion(ADCDriver *adcp) {
|
||||
|
||||
dmaStreamDisable(adcp->dmastp);
|
||||
adcp->adc->CR2 = 0;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_ADC */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
Copyright (C) 2022 Westberry Technology (ChangZhou) Corp., Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ADCv1/hal_adc_lld.h
|
||||
* @brief WB32 ADC subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_ADC_LLD_H
|
||||
#define HAL_ADC_LLD_H
|
||||
|
||||
#if HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Triggers selection
|
||||
* @{
|
||||
*/
|
||||
#define ADC_CR2_EXTSEL_SRC(n) ((n) << 17) /**< @brief Trigger source. */
|
||||
#define ADC_CR2_EXTSEL_SWSTART (7 << 17) /**< @brief Software trigger. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Available analog channels
|
||||
* @{
|
||||
*/
|
||||
#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
|
||||
#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
|
||||
#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
|
||||
#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
|
||||
#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
|
||||
#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
|
||||
#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
|
||||
#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
|
||||
#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
|
||||
#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
|
||||
#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
|
||||
#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
|
||||
#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
|
||||
#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
|
||||
#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
|
||||
#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
|
||||
#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
|
||||
#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Sampling rates
|
||||
* @{
|
||||
*/
|
||||
#define ADC_SAMPLE_1P5 0 /**< @brief 1.5 cycles sampling time. */
|
||||
#define ADC_SAMPLE_7P5 1 /**< @brief 7.5 cycles sampling time. */
|
||||
#define ADC_SAMPLE_13P5 2 /**< @brief 13.5 cycles sampling time. */
|
||||
#define ADC_SAMPLE_28P5 3 /**< @brief 28.5 cycles sampling time. */
|
||||
#define ADC_SAMPLE_41P5 4 /**< @brief 41.5 cycles sampling time. */
|
||||
#define ADC_SAMPLE_55P5 5 /**< @brief 55.5 cycles sampling time. */
|
||||
#define ADC_SAMPLE_71P5 6 /**< @brief 71.5 cycles sampling time. */
|
||||
#define ADC_SAMPLE_239P5 7 /**< @brief 239.5 cycles sampling time. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Bit definition for ADC_CR2 register
|
||||
* @{
|
||||
*/
|
||||
#define ADC_CR2_DMA (0x1U << 8) /**< @brief ADC DMA transfer enable. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief ADC driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(WB32_ADC_USE_ADC1) || defined(__DOXYGEN__)
|
||||
#define WB32_ADC_USE_ADC1 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(WB32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define WB32_ADC_ADC1_IRQ_PRIORITY 5
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ADC usbed DMAC channel setting.
|
||||
*/
|
||||
#if !defined(WB32_ADC_ADC1_DMA_STREAM) || defined(__DOXYGEN__)
|
||||
#define WB32_ADC_ADC1_DMA_STREAM WB32_DMA_STREAM_ID(1, 0)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ADC usbed DMAC channel priority setting.
|
||||
*/
|
||||
#if !defined(WB32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define WB32_ADC_ADC1_DMA_PRIORITY 2
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if WB32_ADC_USE_ADC1 && !WB32_HAS_ADC
|
||||
#error "ADC not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !WB32_ADC_USE_ADC1
|
||||
#error "ADC driver activated but no ADC peripheral assigned"
|
||||
#endif
|
||||
|
||||
#if !defined(WB32_DMA_REQUIRED)
|
||||
#define WB32_DMA_REQUIRED
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief ADC sample data type.
|
||||
*/
|
||||
typedef uint16_t adcsample_t;
|
||||
|
||||
/**
|
||||
* @brief Channels number in a conversion group.
|
||||
*/
|
||||
typedef uint16_t adc_channels_num_t;
|
||||
|
||||
/**
|
||||
* @brief Possible ADC failure causes.
|
||||
* @note Error codes are architecture dependent and should not relied
|
||||
* upon.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ERR_DMAFAILURE = 0 /**< DMA operations failure. */
|
||||
} adcerror_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the ADC driver structure.
|
||||
*/
|
||||
#define adc_lld_driver_fields \
|
||||
/* Pointer to the ADCx registers block.*/ \
|
||||
ADC_TypeDef *adc; \
|
||||
/* Pointer to associated DMA channel.*/ \
|
||||
const wb32_dma_stream_t *dmastp; \
|
||||
/* DMA mode bit mask.*/ \
|
||||
uint32_t dmamode \
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the ADC configuration structure.
|
||||
*/
|
||||
#define adc_lld_config_fields \
|
||||
/* Dummy configuration, it is not needed.*/ \
|
||||
uint32_t dummy
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the ADC configuration structure.
|
||||
*/
|
||||
#define adc_lld_configuration_group_fields \
|
||||
/* ADC CR1 register initialization data. \
|
||||
NOTE: All the required bits must be defined into this field except \
|
||||
@p ADC_CR1_SCAN that is enforced inside the driver.*/ \
|
||||
uint32_t cr1; \
|
||||
/* ADC CR2 register initialization data. \
|
||||
NOTE: All the required bits must be defined into this field except \
|
||||
@p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
|
||||
enforced inside the driver.*/ \
|
||||
uint32_t cr2; \
|
||||
/* ADC SMPR1 register initialization data. \
|
||||
NOTE: In this field must be specified the sample times for channels \
|
||||
10...17.*/ \
|
||||
uint32_t smpr1; \
|
||||
/* ADC SMPR2 register initialization data. \
|
||||
NOTE: In this field must be specified the sample times for channels \
|
||||
0...9.*/ \
|
||||
uint32_t smpr2; \
|
||||
/* ADC SQR1 register initialization data. \
|
||||
NOTE: Conversion group sequence 13...16 + sequence length.*/ \
|
||||
uint32_t sqr1; \
|
||||
/* ADC SQR2 register initialization data. \
|
||||
NOTE: Conversion group sequence 7...12.*/ \
|
||||
uint32_t sqr2; \
|
||||
/* ADC SQR3 register initialization data. \
|
||||
NOTE: Conversion group sequence 1...6.*/ \
|
||||
uint32_t sqr3
|
||||
|
||||
/**
|
||||
* @name Sequences building helper macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Number of channels in a conversion sequence.
|
||||
*/
|
||||
#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
|
||||
|
||||
#define ADC_SQR3_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
|
||||
#define ADC_SQR3_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
|
||||
#define ADC_SQR3_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
|
||||
#define ADC_SQR3_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
|
||||
#define ADC_SQR3_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
|
||||
#define ADC_SQR3_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
|
||||
|
||||
#define ADC_SQR2_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
|
||||
#define ADC_SQR2_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
|
||||
#define ADC_SQR2_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
|
||||
#define ADC_SQR2_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
|
||||
#define ADC_SQR2_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
|
||||
#define ADC_SQR2_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
|
||||
|
||||
#define ADC_SQR1_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
|
||||
#define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
|
||||
#define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
|
||||
#define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Sampling rate settings helper macros
|
||||
* @{
|
||||
*/
|
||||
#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
|
||||
#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
|
||||
#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
|
||||
#define ADC_SMPR2_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
|
||||
#define ADC_SMPR2_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
|
||||
#define ADC_SMPR2_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
|
||||
#define ADC_SMPR2_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
|
||||
#define ADC_SMPR2_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
|
||||
#define ADC_SMPR2_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
|
||||
#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
|
||||
|
||||
#define ADC_SMPR1_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
|
||||
#define ADC_SMPR1_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
|
||||
#define ADC_SMPR1_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
|
||||
#define ADC_SMPR1_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
|
||||
#define ADC_SMPR1_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
|
||||
#define ADC_SMPR1_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
|
||||
#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
|
||||
sampling time. */
|
||||
#define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
|
||||
sampling time. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if WB32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
|
||||
extern ADCDriver ADCD1;
|
||||
#endif
|
||||
|
||||
#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);
|
||||
void adc_lld_stop_conversion(ADCDriver *adcp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_ADC */
|
||||
|
||||
#endif /* HAL_ADC_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,2 @@
|
|||
PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c
|
||||
PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/DMAv1
|
|
@ -0,0 +1,473 @@
|
|||
/*
|
||||
Copyright (C) 2022 Westberry Technology (ChangZhou) Corp., Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file DMAv1/wb32_dma.c
|
||||
* @brief DMA helper driver code.
|
||||
*
|
||||
* @addtogroup WB32_DMA
|
||||
* @details DMA sharing helper driver. In the WB32 the DMA streams are a
|
||||
* shared resource, this driver allows to allocate and free DMA
|
||||
* streams at runtime in order to allow all the other device
|
||||
* drivers to coordinate the access to the resource.
|
||||
* @note The DMA ISR handlers are all declared into this module because
|
||||
* sharing, the various device drivers can associate a callback to
|
||||
* ISRs when allocating streams.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
/* The following macro is only defined if some driver requiring DMA services
|
||||
has been enabled.*/
|
||||
#if defined(WB32_DMA_REQUIRED) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Mask of the DMA1 streams in @p dma_streams_mask.
|
||||
*/
|
||||
#define WB32_DMA1_STREAMS_MASK ((1U << WB32_DMAC1_NUM_CHANNELS) - 1U)
|
||||
|
||||
/**
|
||||
* @brief Mask of the DMA2 streams in @p dma_streams_mask.
|
||||
*/
|
||||
#define WB32_DMA2_STREAMS_MASK (((1U << WB32_DMAC2_NUM_CHANNELS) - 1U) \
|
||||
<< WB32_DMAC1_NUM_CHANNELS)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Default ISR collision masks.
|
||||
*/
|
||||
#if !defined(WB32_DMAC1_CH0_CMASK)
|
||||
#define WB32_DMAC1_CH0_CMASK (1U << 0U)
|
||||
#endif
|
||||
|
||||
#if !defined(WB32_DMAC1_CH1_CMASK)
|
||||
#define WB32_DMAC1_CH1_CMASK (1U << 1U)
|
||||
#endif
|
||||
|
||||
#if !defined(WB32_DMAC1_CH2_CMASK)
|
||||
#define WB32_DMAC1_CH2_CMASK (1U << 2U)
|
||||
#endif
|
||||
|
||||
#if !defined(WB32_DMAC2_CH0_CMASK)
|
||||
#define WB32_DMAC2_CH0_CMASK (1U << (WB32_DMAC1_NUM_CHANNELS + 0U))
|
||||
#endif
|
||||
|
||||
#if !defined(WB32_DMAC2_CH1_CMASK)
|
||||
#define WB32_DMAC2_CH1_CMASK (1U << (WB32_DMAC1_NUM_CHANNELS + 1U))
|
||||
#endif
|
||||
|
||||
#if !defined(WB32_DMAC2_CH2_CMASK)
|
||||
#define WB32_DMAC2_CH2_CMASK (1U << (WB32_DMAC1_NUM_CHANNELS + 2U))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief DMA streams descriptors.
|
||||
* @details This table keeps the association between an unique stream
|
||||
* identifier and the involved physical registers.
|
||||
* @note Don't use this array directly, use the appropriate wrapper macros
|
||||
* instead: @p WB32_DMA1_STREAM1, @p WB32_DMA1_STREAM2 etc.
|
||||
*/
|
||||
const wb32_dma_stream_t _WB32_DMAC_CHANNELS[WB32_DMAC_CHANNELS] = {
|
||||
#if WB32_DMAC1_NUM_CHANNELS > 0
|
||||
{DMAC1, WB32_DMAC_CH0, WB32_DMAC1_CH0_CMASK, 0, WB32_DMAC1_NUMBER},
|
||||
#endif
|
||||
#if WB32_DMAC1_NUM_CHANNELS > 1
|
||||
{DMAC1, WB32_DMAC_CH1, WB32_DMAC1_CH1_CMASK, 1, WB32_DMAC1_NUMBER},
|
||||
#endif
|
||||
#if WB32_DMAC1_NUM_CHANNELS > 2
|
||||
{DMAC1, WB32_DMAC_CH2, WB32_DMAC1_CH2_CMASK, 2, WB32_DMAC1_NUMBER},
|
||||
#endif
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 0
|
||||
{DMAC2, WB32_DMAC_CH0, WB32_DMAC2_CH0_CMASK, 0 + WB32_DMAC1_NUM_CHANNELS, WB32_DMAC2_NUMBER},
|
||||
#endif
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 1
|
||||
{DMAC2, WB32_DMAC_CH1, WB32_DMAC2_CH1_CMASK, 1 + WB32_DMAC1_NUM_CHANNELS, WB32_DMAC2_NUMBER},
|
||||
#endif
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 2
|
||||
{DMAC2, WB32_DMAC_CH2, WB32_DMAC2_CH2_CMASK, 2 + WB32_DMAC1_NUM_CHANNELS, WB32_DMAC2_NUMBER},
|
||||
#endif
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Global DMA-related data structures.
|
||||
*/
|
||||
static struct {
|
||||
/**
|
||||
* @brief Mask of the allocated streams.
|
||||
*/
|
||||
uint32_t allocated_mask;
|
||||
/**
|
||||
* @brief Mask of the enabled streams ISRs.
|
||||
*/
|
||||
uint32_t isr_mask;
|
||||
/**
|
||||
* @brief DMA IRQ redirectors.
|
||||
*/
|
||||
struct {
|
||||
/**
|
||||
* @brief DMA callback function.
|
||||
*/
|
||||
wb32_dmaisr_t func;
|
||||
/**
|
||||
* @brief DMA callback parameter.
|
||||
*/
|
||||
void *param;
|
||||
} streams[WB32_DMAC_CHANNELS];
|
||||
} dma;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(WB32_DMAC1_IRQ_VECTOR) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA1 stream x shared ISR.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
OSAL_IRQ_HANDLER(WB32_DMAC1_IRQ_VECTOR) {
|
||||
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
|
||||
#if WB32_DMAC1_NUM_CHANNELS > 0
|
||||
dmaServeInterrupt(WB32_DMA1_STREAM1);
|
||||
#endif
|
||||
|
||||
#if WB32_DMAC1_NUM_CHANNELS > 1
|
||||
dmaServeInterrupt(WB32_DMA1_STREAM2);
|
||||
#endif
|
||||
|
||||
#if WB32_DMAC1_NUM_CHANNELS > 2
|
||||
dmaServeInterrupt(WB32_DMA1_STREAM3);
|
||||
#endif
|
||||
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WB32_DMAC2_IRQ_VECTOR) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA2 stream x shared ISR.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
OSAL_IRQ_HANDLER(WB32_DMAC2_IRQ_VECTOR) {
|
||||
|
||||
OSAL_IRQ_PROLOGUE();
|
||||
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 0
|
||||
dmaServeInterrupt(WB32_DMA2_STREAM1);
|
||||
#endif
|
||||
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 0
|
||||
dmaServeInterrupt(WB32_DMA2_STREAM2);
|
||||
#endif
|
||||
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 0
|
||||
dmaServeInterrupt(WB32_DMA2_STREAM3);
|
||||
#endif
|
||||
|
||||
OSAL_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief WB32 DMA helper initialization.
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
void dmaInit(void) {
|
||||
int i;
|
||||
|
||||
dma.allocated_mask = 0U;
|
||||
dma.isr_mask = 0U;
|
||||
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 0
|
||||
rccResetDMAC1();
|
||||
#endif
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 0
|
||||
rccResetDMAC2();
|
||||
#endif
|
||||
|
||||
for (i = 0; i < WB32_DMAC_CHANNELS; i++) {
|
||||
dma.streams[i].func = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a DMA stream.
|
||||
* @details The stream is allocated and, if required, the DMA clock enabled.
|
||||
* The function also enables the IRQ vector associated to the stream
|
||||
* and initializes its priority.
|
||||
*
|
||||
* @param[in] id numeric identifiers of a specific stream or:
|
||||
* - @p WB32_DMA_STREAM_ID_ANY for any stream.
|
||||
* - @p WB32_DMA_STREAM_ID_ANY_DMA1 for any stream
|
||||
* on DMA1.
|
||||
* - @p WB32_DMA_STREAM_ID_ANY_DMA2 for any stream
|
||||
* on DMA2.
|
||||
* .
|
||||
* @param[in] priority IRQ priority for the DMA stream
|
||||
* @param[in] func handling function pointer, can be @p NULL
|
||||
* @param[in] param a parameter to be passed to the handling function
|
||||
* @return Pointer to the allocated @p wb32_dma_stream_t
|
||||
* structure.
|
||||
* @retval NULL if a/the stream is not available.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
const wb32_dma_stream_t *dmaStreamAllocI(uint32_t id,
|
||||
uint32_t priority,
|
||||
wb32_dmaisr_t func,
|
||||
void *param) {
|
||||
uint32_t i, startid, endid;
|
||||
|
||||
osalDbgCheckClassI();
|
||||
|
||||
if (id < WB32_DMAC_CHANNELS) {
|
||||
startid = id;
|
||||
endid = id;
|
||||
} else {
|
||||
osalDbgCheck(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = startid; i <= endid; i++) {
|
||||
uint32_t mask = (1U << i);
|
||||
|
||||
if ((dma.allocated_mask & mask) == 0U) {
|
||||
const wb32_dma_stream_t *dmastp = WB32_DMA_STREAM(i);
|
||||
|
||||
/* Installs the DMA handler.*/
|
||||
dma.streams[i].func = func;
|
||||
dma.streams[i].param = param;
|
||||
dma.allocated_mask |= mask;
|
||||
|
||||
/* Enabling DMA clocks required by the current streams set.*/
|
||||
if ((WB32_DMA1_STREAMS_MASK & mask) != 0U) {
|
||||
/* Enable DMAC1 clock */
|
||||
rccEnableDMAC1();
|
||||
/* DMAC1 DeInit */
|
||||
rccResetDMAC1();
|
||||
}
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 0
|
||||
if ((WB32_DMA2_STREAMS_MASK & mask) != 0U) {
|
||||
/* Enable DMAC2 clock */
|
||||
rccEnableDMAC2();
|
||||
/* DMAC2 DeInit */
|
||||
rccResetDMAC2();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* enable dmac */
|
||||
dmastp->dmac->DmaCfgReg = 0x01;
|
||||
|
||||
/* Enables the associated IRQ vector if not already enabled and if a
|
||||
callback is defined.*/
|
||||
if (func != NULL) {
|
||||
if ((dma.isr_mask & dmastp->cmask) == 0U) {
|
||||
nvicEnableVector(dmastp->vector, priority);
|
||||
}
|
||||
dma.isr_mask |= mask;
|
||||
}
|
||||
|
||||
/* Putting the stream in a known state.*/
|
||||
dmaStreamDisable(dmastp);
|
||||
|
||||
return dmastp;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a DMA stream.
|
||||
* @details The stream is allocated and, if required, the DMA clock enabled.
|
||||
* The function also enables the IRQ vector associated to the stream
|
||||
* and initializes its priority.
|
||||
*
|
||||
* @param[in] id numeric identifiers of a specific stream or:
|
||||
* - @p WB32_DMA_STREAM_ID_ANY for any stream.
|
||||
* - @p WB32_DMA_STREAM_ID_ANY_DMA1 for any stream
|
||||
* on DMA1.
|
||||
* - @p WB32_DMA_STREAM_ID_ANY_DMA2 for any stream
|
||||
* on DMA2.
|
||||
* .
|
||||
* @param[in] priority IRQ priority for the DMA stream
|
||||
* @param[in] func handling function pointer, can be @p NULL
|
||||
* @param[in] param a parameter to be passed to the handling function
|
||||
* @return Pointer to the allocated @p wb32_dma_stream_t
|
||||
* structure.
|
||||
* @retval NULL if a/the stream is not available.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
const wb32_dma_stream_t *dmaStreamAlloc(uint32_t id,
|
||||
uint32_t priority,
|
||||
wb32_dmaisr_t func,
|
||||
void *param) {
|
||||
const wb32_dma_stream_t *dmastp;
|
||||
|
||||
osalSysLock();
|
||||
dmastp = dmaStreamAllocI(id, priority, func, param);
|
||||
osalSysUnlock();
|
||||
|
||||
return dmastp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases a DMA stream.
|
||||
* @details The stream is freed and, if required, the DMA clock disabled.
|
||||
* Trying to release a unallocated stream is an illegal operation
|
||||
* and is trapped if assertions are enabled.
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void dmaStreamFreeI(const wb32_dma_stream_t *dmastp) {
|
||||
uint32_t selfindex = (uint32_t)dmastp->selfindex;
|
||||
|
||||
osalDbgCheck(dmastp != NULL);
|
||||
|
||||
/* Check if the streams is not taken.*/
|
||||
osalDbgAssert((dma.allocated_mask & (1 << selfindex)) != 0U,
|
||||
"not allocated");
|
||||
|
||||
/* Marks the stream as not allocated.*/
|
||||
dma.allocated_mask &= ~(1U << selfindex);
|
||||
dma.isr_mask &= ~(1U << selfindex);
|
||||
|
||||
/* Disables the associated IRQ vector if it is no more in use.*/
|
||||
if ((dma.isr_mask & dmastp->cmask) == 0U) {
|
||||
nvicDisableVector(dmastp->vector);
|
||||
}
|
||||
|
||||
/* Removes the DMA handler.*/
|
||||
dma.streams[selfindex].func = NULL;
|
||||
dma.streams[selfindex].param = NULL;
|
||||
|
||||
/* Shutting down clocks that are no more required, if any.*/
|
||||
if ((dma.allocated_mask & WB32_DMA1_STREAMS_MASK) == 0U) {
|
||||
/* Disable DMAC1 clock */
|
||||
rccDisableDMAC1();
|
||||
}
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 0
|
||||
if ((dma.allocated_mask & WB32_DMA2_STREAMS_MASK) == 0U) {
|
||||
/* Disable DMAC2 clock */
|
||||
rccDisableDMAC2();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases a DMA stream.
|
||||
* @details The stream is freed and, if required, the DMA clock disabled.
|
||||
* Trying to release a unallocated stream is an illegal operation
|
||||
* and is trapped if assertions are enabled.
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void dmaStreamFree(const wb32_dma_stream_t *dmastp) {
|
||||
|
||||
osalSysLock();
|
||||
dmaStreamFreeI(dmastp);
|
||||
osalSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Serves a DMA IRQ.
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void dmaServeInterrupt(const wb32_dma_stream_t *dmastp) {
|
||||
uint32_t IT_flag;
|
||||
uint32_t selfindex = (uint32_t)dmastp->selfindex;
|
||||
uint32_t mask = (uint32_t)(0x01U << ((dmastp)->channel));
|
||||
uint32_t regaddr = ((uint32_t)(&((dmastp)->dmac->StatusTfr)) + WB32_DMAC_IT_TFR);
|
||||
|
||||
if ((*((__I uint32_t *)(regaddr))) & mask) {
|
||||
IT_flag = WB32_DMAC_IT_TFR;
|
||||
if (dma.streams[selfindex].func) {
|
||||
dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag);
|
||||
}
|
||||
}
|
||||
|
||||
regaddr = ((uint32_t)(&((dmastp)->dmac->StatusTfr)) + WB32_DMAC_IT_BLOCK);
|
||||
|
||||
if ((*((__I uint32_t *)(regaddr))) & mask) {
|
||||
IT_flag = WB32_DMAC_IT_BLOCK;
|
||||
if (dma.streams[selfindex].func) {
|
||||
dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag);
|
||||
}
|
||||
}
|
||||
|
||||
regaddr = ((uint32_t)(&((dmastp)->dmac->StatusTfr)) + WB32_DMAC_IT_SRCTRAN);
|
||||
|
||||
if ((*((__I uint32_t *)(regaddr))) & mask) {
|
||||
IT_flag = WB32_DMAC_IT_SRCTRAN;
|
||||
if (dma.streams[selfindex].func) {
|
||||
dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag);
|
||||
}
|
||||
}
|
||||
|
||||
regaddr = ((uint32_t)(&((dmastp)->dmac->StatusTfr)) + WB32_DMAC_IT_DSTTRAN);
|
||||
|
||||
if ((*((__I uint32_t *)(regaddr))) & mask) {
|
||||
IT_flag = WB32_DMAC_IT_DSTTRAN;
|
||||
if (dma.streams[selfindex].func) {
|
||||
dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag);
|
||||
}
|
||||
}
|
||||
|
||||
regaddr = ((uint32_t)(&((dmastp)->dmac->StatusTfr)) + WB32_DMAC_IT_ERR);
|
||||
|
||||
if ((*((__I uint32_t *)(regaddr))) & mask) {
|
||||
IT_flag = WB32_DMAC_IT_ERR;
|
||||
if (dma.streams[selfindex].func) {
|
||||
dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WB32_DMA_REQUIRED */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,884 @@
|
|||
/*
|
||||
Copyright (C) 2022 Westberry Technology (ChangZhou) Corp., Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file DMAv1/wb32_dma.h
|
||||
* @brief DMA helper driver header.
|
||||
*
|
||||
* @addtogroup WB32_DMA
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef WB32_DMA_H
|
||||
#define WB32_DMA_H
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Total number of DMA streams.
|
||||
* @details This is the total number of streams among all the DMA units.
|
||||
*/
|
||||
#define WB32_DMAC_CHANNELS (WB32_DMAC1_NUM_CHANNELS + \
|
||||
WB32_DMAC2_NUM_CHANNELS)
|
||||
|
||||
/**
|
||||
* @brief Mask of the ISR bits passed to the DMA callback functions.
|
||||
*/
|
||||
#define WB32_DMA_ISR_MASK 0x0E
|
||||
|
||||
/**
|
||||
* @brief Returns the request line associated to the specified stream.
|
||||
*
|
||||
* @param[in] id the unique numeric stream identifier
|
||||
* @param[in] c a stream/request association word, one request per
|
||||
* nibble
|
||||
* @return Returns the request associated to the stream.
|
||||
*/
|
||||
#define WB32_DMA_GETCHANNEL(id, c) \
|
||||
(((uint32_t)(c) >> (((uint32_t)(id) % (uint32_t)WB32_DMAC1_NUM_CHANNELS) * 4U)) & 15U)
|
||||
|
||||
/**
|
||||
* @brief Checks if a DMA priority is within the valid range.
|
||||
* @param[in] prio DMA priority
|
||||
*
|
||||
* @retval The check result.
|
||||
* @retval false invalid DMA priority.
|
||||
* @retval true correct DMA priority.
|
||||
*/
|
||||
#define WB32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 7U))
|
||||
|
||||
/**
|
||||
* @brief Checks if a DMA stream id is within the valid range.
|
||||
*
|
||||
* @param[in] id DMA stream id
|
||||
* @retval The check result.
|
||||
* @retval false invalid DMA channel.
|
||||
* @retval true correct DMA channel.
|
||||
*/
|
||||
#define WB32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
|
||||
((id) < WB32_DMAC_CHANNELS))
|
||||
|
||||
/**
|
||||
* @brief Returns an unique numeric identifier for a DMA stream.
|
||||
*
|
||||
* @param[in] dma the DMA unit number
|
||||
* @param[in] stream the stream number
|
||||
* @return An unique numeric stream identifier.
|
||||
*/
|
||||
#define WB32_DMA_STREAM_ID(dma, stream) \
|
||||
((((dma)-1) * WB32_DMAC1_NUM_CHANNELS) + (stream))
|
||||
|
||||
/**
|
||||
* @brief Returns a DMA stream identifier mask.
|
||||
*
|
||||
*
|
||||
* @param[in] dma the DMA unit number
|
||||
* @param[in] stream the stream number
|
||||
* @return A DMA stream identifier mask.
|
||||
*/
|
||||
#define WB32_DMA_STREAM_ID_MSK(dma, stream) \
|
||||
(1U << WB32_DMA_STREAM_ID(dma, stream))
|
||||
|
||||
/**
|
||||
* @brief Checks if a DMA stream unique identifier belongs to a mask.
|
||||
*
|
||||
* @param[in] id the stream numeric identifier
|
||||
* @param[in] mask the stream numeric identifiers mask
|
||||
*
|
||||
* @retval The check result.
|
||||
* @retval false id does not belong to the mask.
|
||||
* @retval true id belongs to the mask.
|
||||
*/
|
||||
#define WB32_DMA_IS_VALID_ID(id, mask) (((1U << (id)) & (mask)))
|
||||
|
||||
/**
|
||||
* @name DMA streams identifiers
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns a pointer to a wb32_dma_stream_t structure.
|
||||
*
|
||||
* @param[in] id the stream numeric identifier
|
||||
* @return A pointer to the wb32_dma_stream_t constant structure
|
||||
* associated to the DMA stream.
|
||||
*/
|
||||
#define WB32_DMA_STREAM(id) (&_WB32_DMAC_CHANNELS[id])
|
||||
|
||||
#if WB32_DMAC1_NUM_CHANNELS > 0
|
||||
#define WB32_DMA1_STREAM1 WB32_DMA_STREAM(0)
|
||||
#endif
|
||||
#if WB32_DMAC1_NUM_CHANNELS > 1
|
||||
#define WB32_DMA1_STREAM2 WB32_DMA_STREAM(1)
|
||||
#endif
|
||||
#if WB32_DMAC1_NUM_CHANNELS > 2
|
||||
#define WB32_DMA1_STREAM3 WB32_DMA_STREAM(2)
|
||||
#endif
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 0
|
||||
#define WB32_DMA2_STREAM1 WB32_DMA_STREAM(WB32_DMAC1_NUM_CHANNELS + 0)
|
||||
#endif
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 1
|
||||
#define WB32_DMA2_STREAM2 WB32_DMA_STREAM(WB32_DMAC1_NUM_CHANNELS + 1)
|
||||
#endif
|
||||
#if WB32_DMAC2_NUM_CHANNELS > 2
|
||||
#define WB32_DMA2_STREAM3 WB32_DMA_STREAM(WB32_DMAC1_NUM_CHANNELS + 2)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/** @defgroup DMAC_Interrupt
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_INTERRUPT_EN (0x1U << 0)
|
||||
#define WB32_DMAC_INTERRUPT_DIS (0x0U << 0)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_DestinationTransferWidth
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_DST_WIDTH_BYTE (0x0U << 1)
|
||||
#define WB32_DMAC_DST_WIDTH_HWORD (0x1U << 1)
|
||||
#define WB32_DMAC_DST_WIDTH_WORD (0x2U << 1)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_SourceTransferWidth
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_SRC_WIDTH_BYTE (0x0U << 4)
|
||||
#define WB32_DMAC_SRC_WIDTH_HWORD (0x1U << 4)
|
||||
#define WB32_DMAC_SRC_WIDTH_WORD (0x2U << 4)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_DestinationAddrInc
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_DST_ADDR_INC (0x0U << 7)
|
||||
#define WB32_DMAC_DST_ADDR_DEC (0x1U << 7)
|
||||
#define WB32_DMAC_DST_ADDR_NOC (0x2U << 7)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_SourceAddrInc
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_SRC_ADDR_INC (0x0U << 9)
|
||||
#define WB32_DMAC_SRC_ADDR_DEC (0x1U << 9)
|
||||
#define WB32_DMAC_SRC_ADDR_NOC (0x2U << 9)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_DestinationTransactionLength
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_DST_TRS_LEN_1 (0x0U << 11)
|
||||
#define WB32_DMAC_DST_TRS_LEN_4 (0x1U << 11)
|
||||
#define WB32_DMAC_DST_TRS_LEN_8 (0x2U << 11)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_SourceTransactionLength
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_SRC_TRS_LEN_1 (0x0U << 14)
|
||||
#define WB32_DMAC_SRC_TRS_LEN_4 (0x1U << 14)
|
||||
#define WB32_DMAC_SRC_TRS_LEN_8 (0x2U << 14)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_TransferTypeAndFlowControl
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_TRF_TFC_M2MD (0x0U << 20)
|
||||
#define WB32_DMAC_TRF_TFC_M2PD (0x1U << 20)
|
||||
#define WB32_DMAC_TRF_TFC_P2MD (0x2U << 20)
|
||||
#define WB32_DMAC_TRF_TFC_P2PD (0x3U << 20)
|
||||
/* The following definitions is only used for DMACx channel0. */
|
||||
#define WB32_DMAC_TRF_TFC_P2MP (0x4U << 20)
|
||||
#define WB32_DMAC_TRF_TFC_P2PSP (0x5U << 20)
|
||||
#define WB32_DMAC_TRF_TFC_M2PP (0x6U << 20)
|
||||
#define WB32_DMAC_TRF_TFC_P2PDP (0x7U << 20)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_DestinationMasterInterface
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_SRC_MASTER_IF_APB (0x0U << 25)
|
||||
#define WB32_DMAC_SRC_MASTER_IF_AHB (0x1U << 25)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_SourceMasterInterface
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_DST_MASTER_IF_APB (0x0U << 23)
|
||||
#define WB32_DMAC_DST_MASTER_IF_AHB (0x1U << 23)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_SourceHandshakingInterfaceSelect
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_SRC_HIFS_HW (0x0U << 11)
|
||||
#define WB32_DMAC_SRC_HIFS_SW (0x1U << 11)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_DestinationHandshakingInterfaceSelect
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_DST_HIFS_HW (0x0U << 10)
|
||||
#define WB32_DMAC_DST_HIFS_SW (0x1U << 10)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_SourceHandshakingInterfacePolarity
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_SRC_HIFP_HIGH (0x0U << 19)
|
||||
#define WB32_DMAC_SRC_HIFP_LOW (0x1U << 19)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_DestinationHandshakingInterfacePolarity
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_DST_HIFP_HIGH (0x0U << 18)
|
||||
#define WB32_DMAC_DST_HIFP_LOW (0x1U << 18)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_AutomaticSourceReload
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_SRC_AUTO_RELOAD_EN (0x1U << 30)
|
||||
#define WB32_DMAC_SRC_AUTO_RELOAD_DIS (0x0U << 30)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_AutomaticDestinationReload
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_DST_AUTO_RELOAD_EN (0x1U << 31)
|
||||
#define WB32_DMAC_DST_AUTO_RELOAD_DIS (0x0U << 30)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_FlowControlMode
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_FC_MODE0 (0x0U << 0)
|
||||
#define WB32_DMAC_FC_MODE1 (0x1U << 0)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_FIFOMode
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_FIFO_MODE0 (0x0U << 1)
|
||||
#define WB32_DMAC_FIFO_MODE1 (0x1U << 1)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_interrupts_definitions
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_IT_TFR (0x0U << 3)
|
||||
#define WB32_DMAC_IT_BLOCK (0x1U << 3)
|
||||
#define WB32_DMAC_IT_SRCTRAN (0x2U << 3)
|
||||
#define WB32_DMAC_IT_DSTTRAN (0x3U << 3)
|
||||
#define WB32_DMAC_IT_ERR (0x4U << 3)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_channel
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMAC_CH0 (0x0U << 0)
|
||||
#define WB32_DMAC_CH1 (0x0U << 1)
|
||||
#define WB32_DMAC_CH2 (0x0U << 2)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC_HardwareHandshakingInterface
|
||||
* @{
|
||||
*/
|
||||
/* The following definitions is only used for DMAC1. */
|
||||
#define WB32_DMAC_HWHIF_TIM1_UP 2
|
||||
#define WB32_DMAC_HWHIF_TIM1_COM 1
|
||||
#define WB32_DMAC_HWHIF_TIM1_CH1 0
|
||||
#define WB32_DMAC_HWHIF_TIM1_CH2 6
|
||||
#define WB32_DMAC_HWHIF_TIM1_CH3 3
|
||||
#define WB32_DMAC_HWHIF_TIM1_CH4 1
|
||||
#define WB32_DMAC_HWHIF_TIM1_TRIG 1
|
||||
|
||||
#define WB32_DMAC_HWHIF_TIM2_UP 0
|
||||
#define WB32_DMAC_HWHIF_TIM2_CH1 2
|
||||
#define WB32_DMAC_HWHIF_TIM2_CH2 5
|
||||
#define WB32_DMAC_HWHIF_TIM2_CH3 4
|
||||
#define WB32_DMAC_HWHIF_TIM2_CH4 5
|
||||
|
||||
#define WB32_DMAC_HWHIF_TIM3_UP 6
|
||||
#define WB32_DMAC_HWHIF_TIM3_CH1 3
|
||||
#define WB32_DMAC_HWHIF_TIM3_CH3 0
|
||||
#define WB32_DMAC_HWHIF_TIM3_CH4 6
|
||||
#define WB32_DMAC_HWHIF_TIM3_TRIG 3
|
||||
|
||||
#define WB32_DMAC_HWHIF_TIM4_UP 5
|
||||
#define WB32_DMAC_HWHIF_TIM4_CH1 4
|
||||
#define WB32_DMAC_HWHIF_TIM4_CH2 1
|
||||
#define WB32_DMAC_HWHIF_TIM4_CH3 2
|
||||
|
||||
#define WB32_DMAC_HWHIF_QSPI_RX 7
|
||||
#define WB32_DMAC_HWHIF_QSPI_TX 8
|
||||
#define WB32_DMAC_HWHIF_SPIS1_RX 9
|
||||
#define WB32_DMAC_HWHIF_SPIS1_TX 10
|
||||
#define WB32_DMAC_HWHIF_UART1_RX 11
|
||||
#define WB32_DMAC_HWHIF_UART1_TX 12
|
||||
#define WB32_DMAC_HWHIF_ADC_Regular 13
|
||||
#define WB32_DMAC_HWHIF_ADC_Injected 14
|
||||
|
||||
/* The following definitions is only used for DMAC2. */
|
||||
#define WB32_DMAC_HWHIF_SPIM2_RX 0
|
||||
#define WB32_DMAC_HWHIF_SPIM2_TX 1
|
||||
#define WB32_DMAC_HWHIF_SPIS2_RX 2
|
||||
#define WB32_DMAC_HWHIF_SPIS2_TX 3
|
||||
#define WB32_DMAC_HWHIF_UART2_RX 4
|
||||
#define WB32_DMAC_HWHIF_UART2_TX 5
|
||||
#define WB32_DMAC_HWHIF_UART3_RX 6
|
||||
#define WB32_DMAC_HWHIF_UART3_TX 7
|
||||
#define WB32_DMAC_HWHIF_I2C1_RX 8
|
||||
#define WB32_DMAC_HWHIF_I2C1_TX 9
|
||||
#define WB32_DMAC_HWHIF_I2C2_RX 10
|
||||
#define WB32_DMAC_HWHIF_I2C2_TX 11
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMAC configuration parameters for use simple config.
|
||||
* @{
|
||||
*/
|
||||
#define WB32_DMA_CHCFG_SIZE_MASK (0x1FFU)
|
||||
#define WB32_DMA_CHCFG_EN (0x01U << 0)
|
||||
#define WB32_DMA_CHCFG_TCIE (0x01U << 1)
|
||||
#define WB32_DMA_CHCFG_HTIE (0x01U << 2)
|
||||
#define WB32_DMA_CHCFG_TEIE (0x01U << 3)
|
||||
#define WB32_DMA_CHCFG_DIR_MASK (0x03U << 4)
|
||||
#define WB32_DMA_CHCFG_DIR_M2M (0x00U << 4)
|
||||
#define WB32_DMA_CHCFG_DIR_M2P (0x01U << 4)
|
||||
#define WB32_DMA_CHCFG_DIR_P2M (0x02U << 4)
|
||||
#define WB32_DMA_CHCFG_CIRC (0x01U << 6)
|
||||
#define WB32_DMA_CHCFG_PINC (0x01U << 7)
|
||||
#define WB32_DMA_CHCFG_MINC (0x01U << 8)
|
||||
#define WB32_DMA_CHCFG_PSIZE_MASK (0x03U << 9)
|
||||
#define WB32_DMA_CHCFG_PSIZE_BYTE (0x00U << 9)
|
||||
#define WB32_DMA_CHCFG_PSIZE_HWORD (0x01U << 9)
|
||||
#define WB32_DMA_CHCFG_PSIZE_WORD (0x02U << 9)
|
||||
#define WB32_DMA_CHCFG_MSIZE_MASK (0x03U << 11)
|
||||
#define WB32_DMA_CHCFG_MSIZE_BYTE (0x00U << 11)
|
||||
#define WB32_DMA_CHCFG_MSIZE_HWORD (0x01U << 11)
|
||||
#define WB32_DMA_CHCFG_MSIZE_WORD (0x02U << 11)
|
||||
#define WB32_DMA_CHCFG_PL_MASK (0x07U << 13)
|
||||
#define WB32_DMA_CHCFG_PL(n) ((n) << 13)
|
||||
#define WB32_DMA_CHCFG_HWHIF_MASK (0xFFU << 16)
|
||||
#define WB32_DMA_CHCFG_HWHIF(n) ((n) << 16)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(WB32_DMAC1_NUM_CHANNELS)
|
||||
#error "WB32_DMAC1_NUM_CHANNELS not defined in registry"
|
||||
#endif
|
||||
|
||||
#if !defined(WB32_DMAC2_NUM_CHANNELS)
|
||||
#error "WB32_DMAC2_NUM_CHANNELS not defined in registry"
|
||||
#endif
|
||||
|
||||
#if (WB32_DMAC1_NUM_CHANNELS < 0) || (WB32_DMAC1_NUM_CHANNELS > 3)
|
||||
#error "unsupported channels configuration"
|
||||
#endif
|
||||
|
||||
#if (WB32_DMAC2_NUM_CHANNELS < 0) || (WB32_DMAC2_NUM_CHANNELS > 3)
|
||||
#error "unsupported channels configuration"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of a DMA callback.
|
||||
*
|
||||
* @param[in] p parameter for the registered function
|
||||
* @param[in] flags pre-shifted content of the ISR register, the bits
|
||||
* are aligned to bit zero
|
||||
*/
|
||||
typedef void (*wb32_dmaisr_t)(void *p, uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief WB32 DMA stream descriptor structure.
|
||||
*/
|
||||
typedef struct {
|
||||
DMAC_TypeDef *dmac; /**< @brief Associated DMA. */
|
||||
uint8_t channel; /**< @brief Associated DMA channel. */
|
||||
uint32_t cmask; /**< @brief Mask of streams sharing
|
||||
the same ISR. */
|
||||
uint8_t selfindex; /**< @brief Index to self in array. */
|
||||
uint8_t vector; /**< @brief Associated IRQ vector. */
|
||||
} wb32_dma_stream_t;
|
||||
|
||||
/**
|
||||
* @brief WB32 DMA channel configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t dst_addr; /**< @brief Set the destination base address. */
|
||||
uint32_t src_addr; /**< @brief Set the source base address. */
|
||||
uint32_t interrupt; /**< @brief Set the channel interrupt is enable
|
||||
or not. */
|
||||
uint32_t dst_width; /**< @brief Set the destination transfer width. */
|
||||
uint32_t src_width; /**< @brief Set the source transfer width. */
|
||||
uint32_t dst_addr_inc; /**< @brief Set whether to increment or decrement
|
||||
the destination address on every destination
|
||||
transfer. */
|
||||
uint32_t src_addr_inc; /**< @brief Set whether to increment or decrement
|
||||
the source address on every source transfer. */
|
||||
uint32_t trf_tfc; /**< @brief Set the transfer type and flow control. */
|
||||
uint32_t dst_master_if; /**< @brief Set the Master Interface layer where the
|
||||
destination device (peripheral or memory) resides. */
|
||||
uint32_t src_master_if; /**< @brief Set the Master Interface layer from which
|
||||
the source device (peripheral or memory) is
|
||||
accessed. */
|
||||
uint32_t dst_auto_reload; /**< @brief Set the automatic destination reload feature
|
||||
enable or not. */
|
||||
uint32_t src_auto_reload; /**< @brief Set the automatic source reload feature
|
||||
enable or not. */
|
||||
uint8_t dst_hwhif; /**< @brief Set the hardware handshaking interface to
|
||||
the source of this channel. */
|
||||
uint8_t src_hwhif; /**< @brief Set the hardware handshaking interface to
|
||||
the source of this channel. */
|
||||
uint8_t ch_priority; /**< @brief Set the channel priority. A priority of 2
|
||||
is the highest priority, and 0 is the lowest. */
|
||||
uint8_t prot_ctl; /**< @brief Set the protection control, used to drive
|
||||
the AHB HPROT[3:1] bus. The default value must be 1.*/
|
||||
/* Generally, the default value of the following parameters is 0. */
|
||||
uint32_t dst_trs_len; /**< @brief Set the destination burst transaction
|
||||
length. */
|
||||
uint32_t src_trs_len; /**< @brief Set the source burst transaction length. */
|
||||
uint32_t dst_hifs; /**< @brief Set which of the handshaking interfaces-hardware
|
||||
or software - is active for destination requests on
|
||||
this channel. */
|
||||
uint32_t src_hifs; /**< @brief Set which of the handshaking interfaces-hardware
|
||||
or software - is active for source requests on this
|
||||
channel. */
|
||||
uint32_t dst_hifp; /**< @brief Set the destination handshaking interface
|
||||
polarity. */
|
||||
uint32_t src_hifp; /**< @brief Set the source handshaking interface polarity. */
|
||||
uint32_t fc_mode; /**< @brief Set the flow control mode. */
|
||||
uint32_t fifo_mode; /**< @brief Set the FIFO mode. */
|
||||
uint16_t brs_maxlen; /**< @brief Set the Maximum AMBA burst length that is
|
||||
used for DMA transfers on this channel. */
|
||||
} wb32_dmac_chinit_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Associates a peripheral data register to a DMA stream.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
* @param[in] addr value to be written in the SAR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetSource(dmastp, addr) { \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].SAR = (uint32_t)(addr); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Associates a memory destination to a DMA stream.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
* @param[in] addr value to be written in the DAR register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetDestination(dmastp, addr) { \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].DAR = (uint32_t)(addr); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the number of transfers to be performed.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
* @param[in] size value to be written in the CTLH register Size must be less than 511
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetTransactionSize(dmastp, size) { \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CTLH = (uint32_t)((size) & 0x1FF); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of transfers to be performed.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
* @return The number of transfers to be performed.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->dmac->Ch[(dmastp)->channel].CTLH))
|
||||
|
||||
/**
|
||||
* @brief Programs the stream mode settings.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
* @param[in] mode value to be written in that CTLL/CFGL/CFGH register
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamSetMode(dmastp, mode) { \
|
||||
switch ((uint32_t)(mode) & WB32_DMA_CHCFG_DIR_MASK) { \
|
||||
case WB32_DMA_CHCFG_DIR_M2M: /* M2M */ \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CFGL = WB32_DMAC_TRF_TFC_M2MD | \
|
||||
WB32_DMAC_SRC_MASTER_IF_AHB | \
|
||||
WB32_DMAC_DST_MASTER_IF_AHB | \
|
||||
(((mode) & WB32_DMA_CHCFG_PSIZE_MASK) >> 5) | \
|
||||
(((mode) & WB32_DMA_CHCFG_MSIZE_MASK) >> 10) | \
|
||||
((!((mode) & WB32_DMA_CHCFG_PINC)) << 10) | \
|
||||
((!((mode) & WB32_DMA_CHCFG_MINC)) << 8); \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CFGH = (1U << 2); \
|
||||
break; \
|
||||
case WB32_DMA_CHCFG_DIR_M2P: /* M2P */ \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CTLL = WB32_DMAC_TRF_TFC_M2PD | \
|
||||
WB32_DMAC_SRC_MASTER_IF_AHB | \
|
||||
WB32_DMAC_DST_MASTER_IF_APB | \
|
||||
(((mode) & WB32_DMA_CHCFG_MSIZE_MASK) >> 7) | \
|
||||
(((mode) & WB32_DMA_CHCFG_PSIZE_MASK) >> 8) | \
|
||||
((!((mode) & WB32_DMA_CHCFG_MINC)) << 10) | \
|
||||
((!((mode) & WB32_DMA_CHCFG_PINC)) << 8); \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CFGH = (((mode) & WB32_DMA_CHCFG_HWHIF_MASK) >> 5) | \
|
||||
(1U << 2); \
|
||||
break; \
|
||||
case WB32_DMA_CHCFG_DIR_P2M: /* P2M */ \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CTLL = WB32_DMAC_TRF_TFC_P2MD | \
|
||||
WB32_DMAC_SRC_MASTER_IF_APB | \
|
||||
WB32_DMAC_DST_MASTER_IF_AHB | \
|
||||
(((mode) & WB32_DMA_CHCFG_PSIZE_MASK) >> 5) | \
|
||||
(((mode) & WB32_DMA_CHCFG_MSIZE_MASK) >> 10) | \
|
||||
((!((mode) & WB32_DMA_CHCFG_PINC)) << 10) | \
|
||||
((!((mode) & WB32_DMA_CHCFG_MINC)) << 8); \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CFGH = (((mode) & WB32_DMA_CHCFG_HWHIF_MASK) >> 9) | \
|
||||
(1U << 2); \
|
||||
break; \
|
||||
} \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CFGL = (((mode) & WB32_DMA_CHCFG_PL_MASK) >> 8) | \
|
||||
(((mode) & WB32_DMA_CHCFG_CIRC) << 24) | \
|
||||
(((mode) & WB32_DMA_CHCFG_CIRC) << 25); \
|
||||
if ((mode) & (WB32_DMA_CHCFG_TCIE | WB32_DMA_CHCFG_HTIE)) { \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CTLL |= WB32_DMAC_INTERRUPT_EN; \
|
||||
dmaStreamEnableInterrupt(dmastp, WB32_DMAC_IT_TFR); \
|
||||
} \
|
||||
if ((mode) & WB32_DMA_CHCFG_TEIE) { \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CTLL |= WB32_DMAC_INTERRUPT_EN; \
|
||||
dmaStreamEnableInterrupt(dmastp, WB32_DMAC_IT_ERR); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define dmaStreamSetModeI(dmastp, mode) { \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CTLL = (mode).interrupt | \
|
||||
(mode).dst_width | \
|
||||
(mode).src_width | \
|
||||
(mode).dst_addr_inc | \
|
||||
(mode).src_addr_inc | \
|
||||
(mode).dst_trs_len | \
|
||||
(mode).src_trs_len | \
|
||||
(mode).trf_tfc | \
|
||||
(mode).dst_master_if | \
|
||||
(mode).src_master_if; \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CFGL = ((mode).ch_priority << 5) | \
|
||||
(mode).dst_hifs | \
|
||||
(mode).src_hifs | \
|
||||
(mode).dst_hifp | \
|
||||
(mode).src_hifp | \
|
||||
((mode).brs_maxlen << 20) | \
|
||||
(mode).src_auto_reload | \
|
||||
(mode).dst_auto_reload; \
|
||||
(dmastp)->dmac->Ch[(dmastp)->channel].CFGH = (mode).fc_mode | \
|
||||
(mode).fifo_mode | \
|
||||
((mode).prot_ctl << 2) | \
|
||||
((mode).src_hwhif << 7) | \
|
||||
((mode).dst_hwhif << 11); \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief DMA stream enable interrupt configuration.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
* @param[in] it_flag specifies the DMAC interrupt source to be enabled or disabled.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamEnableInterrupt(dmastp, it_flag) { \
|
||||
uint32_t mask = (uint32_t)(0x01U << ((dmastp)->channel)); \
|
||||
uint32_t regaddr = ((uint32_t)(&((dmastp)->dmac->MaskTfr)) + it_flag); \
|
||||
*((__O uint32_t *)(regaddr)) = (mask << 8) | mask; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA stream disable interrupt configuration.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
* @param[in] it_flag specifies the DMAC interrupt source to be enabled or disabled.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamDisableInterrupt(dmastp, it_flag) { \
|
||||
uint32_t mask = (uint32_t)(0x01U << ((dmastp)->channel)); \
|
||||
uint32_t regaddr = ((uint32_t)(&((dmastp)->dmac->MaskTfr)) + it_flag); \
|
||||
*((__O uint32_t *)(regaddr)) = (mask << 8); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA stream enable interrupt configuration all.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamEnableInterruptAll(dmastp) { \
|
||||
dmaStreamEnableInterrupt(dmastp, WB32_DMAC_IT_TFR); \
|
||||
dmaStreamEnableInterrupt(dmastp, WB32_DMAC_IT_BLOCK); \
|
||||
dmaStreamEnableInterrupt(dmastp, WB32_DMAC_IT_SRCTRAN); \
|
||||
dmaStreamEnableInterrupt(dmastp, WB32_DMAC_IT_DSTTRAN); \
|
||||
dmaStreamEnableInterrupt(dmastp, WB32_DMAC_IT_ERR); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA stream disable interrupt configuration all.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamDisableInterruptAll(dmastp) { \
|
||||
dmaStreamDisableInterrupt(dmastp, WB32_DMAC_IT_TFR); \
|
||||
dmaStreamDisableInterrupt(dmastp, WB32_DMAC_IT_BLOCK); \
|
||||
dmaStreamDisableInterrupt(dmastp, WB32_DMAC_IT_SRCTRAN); \
|
||||
dmaStreamDisableInterrupt(dmastp, WB32_DMAC_IT_DSTTRAN); \
|
||||
dmaStreamDisableInterrupt(dmastp, WB32_DMAC_IT_ERR); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA stream interrupt sources clear.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamClearInterrupt(dmastp) { \
|
||||
uint32_t mask = (uint32_t)(0x01U << ((dmastp)->channel)); \
|
||||
uint32_t regaddr = ((uint32_t)(&((dmastp)->dmac->ClearTfr)) + WB32_DMAC_IT_TFR); \
|
||||
*((__O uint32_t *)(regaddr)) = mask; \
|
||||
regaddr = ((uint32_t)(&((dmastp)->dmac->ClearTfr)) + WB32_DMAC_IT_BLOCK); \
|
||||
*((__O uint32_t *)(regaddr)) = mask; \
|
||||
regaddr = ((uint32_t)(&((dmastp)->dmac->ClearTfr)) + WB32_DMAC_IT_SRCTRAN); \
|
||||
*((__O uint32_t *)(regaddr)) = mask; \
|
||||
regaddr = ((uint32_t)(&((dmastp)->dmac->ClearTfr)) + WB32_DMAC_IT_DSTTRAN); \
|
||||
*((__O uint32_t *)(regaddr)) = mask; \
|
||||
regaddr = ((uint32_t)(&((dmastp)->dmac->ClearTfr)) + WB32_DMAC_IT_ERR); \
|
||||
*((__O uint32_t *)(regaddr)) = mask; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA stream enable.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamEnable(dmastp) { \
|
||||
uint32_t mask = (uint32_t)(0x01U << ((dmastp)->channel)); \
|
||||
(dmastp)->dmac->ChEnReg = (mask << 8) | mask; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA stream disable.
|
||||
* @details The function disables the specified stream and then clears any
|
||||
* pending interrupt.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @note Interrupts enabling flags are set to zero after this call, see
|
||||
* bug 3607518.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamDisable(dmastp) { \
|
||||
uint32_t mask = (uint32_t)(0x01U << ((dmastp)->channel)); \
|
||||
(dmastp)->dmac->ChEnReg = (mask << 8); \
|
||||
dmaStreamDisableInterruptAll(dmastp); \
|
||||
dmaStreamClearInterrupt(dmastp); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts a memory to memory operation using the specified stream.
|
||||
* @note The default transfer data mode is "byte to byte" but it can be
|
||||
* changed by specifying extra options in the @p mode parameter.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
* @param[in] mode value to be written in the CCR register, this value
|
||||
* is implicitly ORed with:
|
||||
* - @p WB32_DMAC_SRC_ADDR_INC
|
||||
* - @p WB32_DMAC_DST_ADDR_INC
|
||||
* - @p WB32_DMAC_TRF_TFC_M2MD
|
||||
* .
|
||||
* @param[in] src source address
|
||||
* @param[in] dst destination address
|
||||
* @param[in] n number of data units to copy
|
||||
*/
|
||||
#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \
|
||||
(mode).src_addr_inc = WB32_DMAC_SRC_ADDR_INC; \
|
||||
(mode).dst_addr_inc = WB32_DMAC_DST_ADDR_INC; \
|
||||
(mode).trf_tfc = WB32_DMAC_TRF_TFC_M2MD; \
|
||||
dmaStreamSetSource(dmastp, src); \
|
||||
dmaStreamSetDestination(dmastp, dst); \
|
||||
dmaStreamSetTransactionSize(dmastp, n); \
|
||||
dmaStreamSetMode(dmastp, mode); \
|
||||
dmaStreamEnable(dmastp); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Polled wait for DMA transfer end.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAlloc().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a wb32_dma_stream_t structure
|
||||
*/
|
||||
#define dmaWaitCompletion(dmastp) { \
|
||||
while (((dmastp)->dmac->Ch[(dmastp)->channel].CTLH & 0x00000FFFU) > 0U) \
|
||||
; \
|
||||
dmaStreamDisable(dmastp); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern const wb32_dma_stream_t _WB32_DMAC_CHANNELS[WB32_DMAC_CHANNELS];
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
void dmaInit(void);
|
||||
const wb32_dma_stream_t *dmaStreamAllocI(uint32_t id,
|
||||
uint32_t priority,
|
||||
wb32_dmaisr_t func,
|
||||
void *param);
|
||||
const wb32_dma_stream_t *dmaStreamAlloc(uint32_t id,
|
||||
uint32_t priority,
|
||||
wb32_dmaisr_t func,
|
||||
void *param);
|
||||
void dmaStreamFreeI(const wb32_dma_stream_t *dmastp);
|
||||
void dmaStreamFree(const wb32_dma_stream_t *dmastp);
|
||||
void dmaServeInterrupt(const wb32_dma_stream_t *dmastp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WB32_DMA_H */
|
||||
|
||||
/** @} */
|
|
@ -71,10 +71,10 @@
|
|||
#define PAL_WB32_ALTERNATE(n) ((n) << 7U)
|
||||
|
||||
#define PAL_WB32_CURRENT_MASK (3U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL0 (0U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL1 (1U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL2 (2U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL3 (3U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL0 (0U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL1 (1U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL2 (2U << 11U)
|
||||
#define PAL_WB32_CURRENT_LEVEL3 (3U << 11U)
|
||||
|
||||
/**
|
||||
* @brief Alternate function.
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "wb32_registry.h"
|
||||
#include "wb32_tim.h"
|
||||
#include "wb32_dma.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
|
|
|
@ -24,11 +24,13 @@ endif #ifeq ($(USE_SMART_BUILD), yes)
|
|||
|
||||
# Drivers compatible with the platform.
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/WB32/LLD/GPIOv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/DMAv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/TIMv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/I2Cv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/UARTv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/SPIv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/USBv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/ADCv1/driver.mk
|
||||
|
||||
# Shared variables
|
||||
ALLCSRC += $(PLATFORMSRC_CONTRIB)
|
||||
|
|
|
@ -133,8 +133,8 @@
|
|||
* @api
|
||||
*/
|
||||
#define rccEnableAHB(mask) { \
|
||||
RCC->AHBENR |= (mask); \
|
||||
(void)RCC->AHBENR; \
|
||||
RCC->AHBENR1 |= (mask); \
|
||||
(void)RCC->AHBENR1; \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,8 +145,8 @@
|
|||
* @api
|
||||
*/
|
||||
#define rccDisableAHB(mask) { \
|
||||
RCC->AHBENR &= ~(mask); \
|
||||
(void)RCC->AHBENR; \
|
||||
RCC->AHBENR1 &= ~(mask); \
|
||||
(void)RCC->AHBENR1; \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,8 +157,8 @@
|
|||
* @api
|
||||
*/
|
||||
#define rccResetAHB(mask) { \
|
||||
RCC->AHBRSTR |= (mask); \
|
||||
RCC->AHBRSTR &= ~(mask); \
|
||||
RCC->AHBRSTR1 |= (mask); \
|
||||
RCC->AHBRSTR1 &= ~(mask); \
|
||||
(void)RCC->AHBRSTR; \
|
||||
}
|
||||
/** @} */
|
||||
|
@ -502,6 +502,93 @@
|
|||
#define rccResetUART3() rccResetAPB2(RCC_APB2RSTR_UART3RST)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name ADC peripherals specific RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the ADC peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableADC() rccEnableAPB1(RCC_APB1ENR_ADCEN)
|
||||
|
||||
/**
|
||||
* @brief Disables the ADC peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableADC() rccDisableAPB1(RCC_APB1ENR_ADCEN)
|
||||
|
||||
/**
|
||||
* @brief Resets the ADC peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetADC() rccResetAPB1(RCC_APB1RSTR_ADCRST)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name DMAC peripherals specific RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the DMAC1 peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableDMAC1() do { \
|
||||
rccEnableAHB(RCC_AHBENR1_DMAC1BREN); \
|
||||
rccEnableAPB1(RCC_APB1ENR_DMAC1EN); \
|
||||
} while (false)
|
||||
|
||||
/**
|
||||
* @brief Disables the DMAC1 peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableDMAC1() do { \
|
||||
rccDisableAHB(RCC_AHBENR1_DMAC1BREN); \
|
||||
rccDisableAPB1(RCC_APB1ENR_DMAC1EN); \
|
||||
} while (false)
|
||||
|
||||
/**
|
||||
* @brief Resets the DMAC1 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetDMAC1() rccResetAPB1(RCC_APB1RSTR_DMAC1RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the DMAC2 peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableDMAC2() do { \
|
||||
rccEnableAHB(RCC_AHBENR1_DMAC2BREN); \
|
||||
rccEnableAPB2(RCC_APB2ENR_DMAC2EN); \
|
||||
} while (false)
|
||||
|
||||
/**
|
||||
* @brief Disables the DMAC2 peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableDMAC2() do { \
|
||||
rccDisableAHB(RCC_AHBENR1_DMAC2BREN); \
|
||||
rccDisableAPB2(RCC_APB2ENR_DMAC2EN); \
|
||||
} while (false)
|
||||
|
||||
/**
|
||||
* @brief Resets the DMAC2 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetDMAC2() rccResetAPB2(RCC_APB2RSTR_DMAC2RST)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "wb32_registry.h"
|
||||
#include "wb32_tim.h"
|
||||
#include "wb32_dma.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
|
|
|
@ -24,11 +24,13 @@ endif #ifeq ($(USE_SMART_BUILD), yes)
|
|||
|
||||
# Drivers compatible with the platform.
|
||||
include ${CHIBIOS_CONTRIB}/os/hal/ports/WB32/LLD/GPIOv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/DMAv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/TIMv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/I2Cv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/UARTv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/SPIv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/USBv1/driver.mk
|
||||
include $(CHIBIOS_CONTRIB)/os/hal/ports/WB32/LLD/ADCv1/driver.mk
|
||||
|
||||
# Shared variables
|
||||
ALLCSRC += $(PLATFORMSRC_CONTRIB)
|
||||
|
|
|
@ -133,8 +133,8 @@
|
|||
* @api
|
||||
*/
|
||||
#define rccEnableAHB(mask) { \
|
||||
RCC->AHBENR |= (mask); \
|
||||
(void)RCC->AHBENR; \
|
||||
RCC->AHBENR1 |= (mask); \
|
||||
(void)RCC->AHBENR1; \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,8 +145,8 @@
|
|||
* @api
|
||||
*/
|
||||
#define rccDisableAHB(mask) { \
|
||||
RCC->AHBENR &= ~(mask); \
|
||||
(void)RCC->AHBENR; \
|
||||
RCC->AHBENR1 &= ~(mask); \
|
||||
(void)RCC->AHBENR1; \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,8 +157,8 @@
|
|||
* @api
|
||||
*/
|
||||
#define rccResetAHB(mask) { \
|
||||
RCC->AHBRSTR |= (mask); \
|
||||
RCC->AHBRSTR &= ~(mask); \
|
||||
RCC->AHBRSTR1 |= (mask); \
|
||||
RCC->AHBRSTR1 &= ~(mask); \
|
||||
(void)RCC->AHBRSTR; \
|
||||
}
|
||||
/** @} */
|
||||
|
@ -502,6 +502,93 @@
|
|||
#define rccResetUART3() rccResetAPB2(RCC_APB2RSTR_UART3RST)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name ADC peripherals specific RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the ADC peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableADC() rccEnableAPB1(RCC_APB1ENR_ADCEN)
|
||||
|
||||
/**
|
||||
* @brief Disables the ADC peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableADC() rccDisableAPB1(RCC_APB1ENR_ADCEN)
|
||||
|
||||
/**
|
||||
* @brief Resets the ADC peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetADC() rccResetAPB1(RCC_APB1RSTR_ADCRST)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name DMAC peripherals specific RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the DMAC1 peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableDMAC1() do { \
|
||||
rccEnableAHB(RCC_AHBENR1_DMAC1BREN); \
|
||||
rccEnableAPB1(RCC_APB1ENR_DMAC1EN); \
|
||||
} while (false)
|
||||
|
||||
/**
|
||||
* @brief Disables the DMAC1 peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableDMAC1() do { \
|
||||
rccDisableAHB(RCC_AHBENR1_DMAC1BREN); \
|
||||
rccDisableAPB1(RCC_APB1ENR_DMAC1EN); \
|
||||
} while (false)
|
||||
|
||||
/**
|
||||
* @brief Resets the DMAC1 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetDMAC1() rccResetAPB1(RCC_APB1RSTR_DMAC1RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the DMAC2 peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableDMAC2() do { \
|
||||
rccEnableAHB(RCC_AHBENR1_DMAC2BREN); \
|
||||
rccEnableAPB2(RCC_APB2ENR_DMAC2EN); \
|
||||
} while (false)
|
||||
|
||||
/**
|
||||
* @brief Disables the DMAC2 peripheral clock.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableDMAC2() do { \
|
||||
rccDisableAHB(RCC_AHBENR1_DMAC2BREN); \
|
||||
rccDisableAPB2(RCC_APB2ENR_DMAC2EN); \
|
||||
} while (false)
|
||||
|
||||
/**
|
||||
* @brief Resets the DMAC2 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetDMAC2() rccResetAPB2(RCC_APB2RSTR_DMAC2RST)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
|
Loading…
Reference in New Issue