Provisional STM32F2xx support.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3649 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
3d37f49059
commit
da9678f49a
|
@ -59,7 +59,7 @@
|
|||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
|
||||
|
|
|
@ -0,0 +1,416 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file STM32F2xx/adc_lld.c
|
||||
* @brief STM32F2xx ADC subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define ADC1_DMA_CHANNEL \
|
||||
STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
|
||||
|
||||
#define ADC2_DMA_CHANNEL \
|
||||
STM32_DMA_GETCHANNEL(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_CHN)
|
||||
|
||||
#define ADC3_DMA_CHANNEL \
|
||||
STM32_DMA_GETCHANNEL(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_CHN)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief ADC1 driver identifier.*/
|
||||
#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD1;
|
||||
#endif
|
||||
|
||||
/** @brief ADC2 driver identifier.*/
|
||||
#if STM32_ADC_USE_ADC2 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD2;
|
||||
#endif
|
||||
|
||||
/** @brief ADC3 driver identifier.*/
|
||||
#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD3;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief 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 & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 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 {
|
||||
/* It is possible that the conversion group has already be reset by the
|
||||
ADC error handler, in this case this interrupt is spurious.*/
|
||||
if (adcp->grpp != NULL) {
|
||||
if ((flags & STM32_DMA_ISR_HTIF) != 0) {
|
||||
/* Half transfer processing.*/
|
||||
_adc_isr_half_code(adcp);
|
||||
}
|
||||
if ((flags & STM32_DMA_ISR_TCIF) != 0) {
|
||||
/* Transfer complete processing.*/
|
||||
_adc_isr_full_code(adcp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 || STM32_ADC_USE_ADC3 || \
|
||||
defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief ADC interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(ADC1_2_3_IRQHandler) {
|
||||
uint32_t sr;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
#if STM32_ADC_USE_ADC1
|
||||
sr = ADC1->SR;
|
||||
ADC1->SR = 0;
|
||||
/* Note, an overflow may occur after the conversion ended before the driver
|
||||
is able to stop the ADC, this is why the DMA channel is checked too.*/
|
||||
if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD1.dmastp) > 0)) {
|
||||
/* ADC overflow condition, this could happen only if the DMA is unable
|
||||
to read data fast enough.*/
|
||||
if (ADCD1.grpp != NULL)
|
||||
_adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW);
|
||||
}
|
||||
/* TODO: Add here analog watchdog handling.*/
|
||||
#endif /* STM32_ADC_USE_ADC1 */
|
||||
|
||||
#if STM32_ADC_USE_ADC2
|
||||
sr = ADC2->SR;
|
||||
ADC2->SR = 0;
|
||||
/* Note, an overflow may occur after the conversion ended before the driver
|
||||
is able to stop the ADC, this is why the DMA channel is checked too.*/
|
||||
if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD2.dmastp) > 0)) {
|
||||
/* ADC overflow condition, this could happen only if the DMA is unable
|
||||
to read data fast enough.*/
|
||||
if (ADCD2.grpp != NULL)
|
||||
_adc_isr_error_code(&ADCD2, ADC_ERR_OVERFLOW);
|
||||
}
|
||||
/* TODO: Add here analog watchdog handling.*/
|
||||
#endif /* STM32_ADC_USE_ADC2 */
|
||||
|
||||
#if STM32_ADC_USE_ADC3
|
||||
sr = ADC3->SR;
|
||||
ADC3->SR = 0;
|
||||
/* Note, an overflow may occur after the conversion ended before the driver
|
||||
is able to stop the ADC, this is why the DMA channel is checked too.*/
|
||||
if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD3.dmastp) > 0)) {
|
||||
/* ADC overflow condition, this could happen only if the DMA is unable
|
||||
to read data fast enough.*/
|
||||
if (ADCD3.grpp != NULL)
|
||||
_adc_isr_error_code(&ADCD3, ADC_ERR_OVERFLOW);
|
||||
}
|
||||
/* TODO: Add here analog watchdog handling.*/
|
||||
#endif /* STM32_ADC_USE_ADC3 */
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level ADC driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_init(void) {
|
||||
|
||||
ADC->CCR = STM32_ADC_ADCPRE;
|
||||
|
||||
#if STM32_ADC_USE_ADC1
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD1);
|
||||
ADCD1.adc = ADC1;
|
||||
ADCD1.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC1_DMA_STREAM);
|
||||
ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) |
|
||||
STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
|
||||
STM32_DMA_CR_DIR_P2M |
|
||||
STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
|
||||
STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
|
||||
STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE |
|
||||
STM32_DMA_CR_EN;
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC2
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD2);
|
||||
ADCD2.adc = ADC2;
|
||||
ADCD2.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC2_DMA_STREAM);
|
||||
ADCD2.dmamode = STM32_DMA_CR_CHSEL(ADC2_DMA_CHANNEL) |
|
||||
STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) |
|
||||
STM32_DMA_CR_DIR_P2M |
|
||||
STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
|
||||
STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
|
||||
STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE |
|
||||
STM32_DMA_CR_EN;
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC3
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD3);
|
||||
ADCD3.adc = ADC3;
|
||||
ADCD3.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC3_DMA_STREAM);
|
||||
ADCD3.dmamode = STM32_DMA_CR_CHSEL(ADC3_DMA_CHANNEL) |
|
||||
STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) |
|
||||
STM32_DMA_CR_DIR_P2M |
|
||||
STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
|
||||
STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
|
||||
STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE |
|
||||
STM32_DMA_CR_EN;
|
||||
#endif
|
||||
|
||||
/* The shared vector is initialized on driver initialization and never
|
||||
disabled.*/
|
||||
nvicEnableVector(ADC_IRQn, CORTEX_PRIORITY_MASK(STM32_ADC_IRQ_PRIORITY));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 and DMA clocks.*/
|
||||
if (adcp->state == ADC_STOP) {
|
||||
#if STM32_ADC_USE_ADC1
|
||||
if (&ADCD1 == adcp) {
|
||||
bool_t b;
|
||||
b = dmaStreamAllocate(adcp->dmastp,
|
||||
STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
|
||||
(void *)adcp);
|
||||
chDbgAssert(!b, "adc_lld_start(), #1", "stream already allocated");
|
||||
dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
|
||||
rccEnableADC1(FALSE);
|
||||
}
|
||||
#endif /* STM32_ADC_USE_ADC1 */
|
||||
|
||||
#if STM32_ADC_USE_ADC2
|
||||
if (&ADCD2 == adcp) {
|
||||
bool_t b;
|
||||
b = dmaStreamAllocate(adcp->dmastp,
|
||||
STM32_ADC_ADC2_DMA_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
|
||||
(void *)adcp);
|
||||
chDbgAssert(!b, "adc_lld_start(), #2", "stream already allocated");
|
||||
dmaStreamSetPeripheral(adcp->dmastp, &ADC2->DR);
|
||||
rccEnableADC2(FALSE);
|
||||
}
|
||||
#endif /* STM32_ADC_USE_ADC2 */
|
||||
|
||||
#if STM32_ADC_USE_ADC3
|
||||
if (&ADCD3 == adcp) {
|
||||
bool_t b;
|
||||
b = dmaStreamAllocate(adcp->dmastp,
|
||||
STM32_ADC_ADC3_DMA_IRQ_PRIORITY,
|
||||
(stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
|
||||
(void *)adcp);
|
||||
chDbgAssert(!b, "adc_lld_start(), #3", "stream already allocated");
|
||||
dmaStreamSetPeripheral(adcp->dmastp, &ADC3->DR);
|
||||
rccEnableADC3(FALSE);
|
||||
}
|
||||
#endif /* STM32_ADC_USE_ADC3 */
|
||||
|
||||
/* ADC initial setup, starting the analog part here in order to reduce
|
||||
the latency when starting a conversion.*/
|
||||
adcp->adc->CR1 = 0;
|
||||
adcp->adc->CR2 = 0;
|
||||
adcp->adc->CR2 = ADC_CR2_ADON;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
dmaStreamRelease(adcp->dmastp);
|
||||
adcp->adc->CR1 = 0;
|
||||
adcp->adc->CR2 = 0;
|
||||
|
||||
#if STM32_ADC_USE_ADC1
|
||||
if (&ADCD1 == adcp)
|
||||
rccDisableADC1(FALSE);
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC2
|
||||
if (&ADCD2 == adcp)
|
||||
rccDisableADC2(FALSE);
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC3
|
||||
if (&ADCD3 == adcp)
|
||||
rccDisableADC3(FALSE);
|
||||
#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 mode;
|
||||
const ADCConversionGroup *grpp = adcp->grpp;
|
||||
|
||||
/* DMA setup.*/
|
||||
mode = adcp->dmamode;
|
||||
if (grpp->circular) {
|
||||
mode |= STM32_DMA_CR_CIRC;
|
||||
}
|
||||
if (adcp->depth > 1) {
|
||||
/* If the buffer depth is greater than one then the half transfer interrupt
|
||||
interrupt is enabled in order to allows streaming processing.*/
|
||||
mode |= STM32_DMA_CR_HTIE;
|
||||
}
|
||||
dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
|
||||
dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
|
||||
(uint32_t)adcp->depth);
|
||||
dmaStreamSetMode(adcp->dmastp, mode);
|
||||
|
||||
/* ADC setup.*/
|
||||
adcp->adc->SR = 0;
|
||||
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;
|
||||
|
||||
/* ADC configuration and start, the start is performed using the method
|
||||
specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/
|
||||
adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN;
|
||||
adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA |
|
||||
ADC_CR2_DDS | ADC_CR2_ADON;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->CR1 = 0;
|
||||
adcp->adc->CR2 = 0;
|
||||
adcp->adc->CR2 = ADC_CR2_ADON;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the TSVREFE bit.
|
||||
* @details The TSVREFE bit is required in order to sample the internal
|
||||
* temperature sensor and internal reference voltage.
|
||||
* @note This is an STM32-only functionality.
|
||||
*/
|
||||
void adcSTM32EnableTSVREFE(void) {
|
||||
|
||||
ADC->CCR |= ADC_CCR_TSVREFE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the TSVREFE bit.
|
||||
* @details The TSVREFE bit is required in order to sample the internal
|
||||
* temperature sensor and internal reference voltage.
|
||||
* @note This is an STM32-only functionality.
|
||||
*/
|
||||
void adcSTM32DisableTSVREFE(void) {
|
||||
|
||||
ADC->CCR &= ~ADC_CCR_TSVREFE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the VBATE bit.
|
||||
* @details The VBATE bit is required in order to sample the VBAT channel.
|
||||
* @note This is an STM32-only functionality.
|
||||
*/
|
||||
void adcSTM32EnableVBATE(void) {
|
||||
|
||||
ADC->CCR |= ADC_CCR_VBATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the VBATE bit.
|
||||
* @details The VBATE bit is required in order to sample the VBAT channel.
|
||||
* @note This is an STM32-only functionality.
|
||||
*/
|
||||
void adcSTM32DisableVBATE(void) {
|
||||
|
||||
ADC->CCR &= ~ADC_CCR_VBATE;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_ADC */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,569 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file STM32F2xx/adc_lld.h
|
||||
* @brief STM32F2xx ADC subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _ADC_LLD_H_
|
||||
#define _ADC_LLD_H_
|
||||
|
||||
#if HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Absolute Maximum Ratings
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Maximum HSE clock frequency.
|
||||
*/
|
||||
#define STM32_ADCCLK_MIN 600000
|
||||
|
||||
/**
|
||||
* @brief Maximum HSE clock frequency.
|
||||
* @note This value is arbitrary defined, the current datasheet does not
|
||||
* define a maximum value (it is TBD). A value of 36MHz is mentioned
|
||||
* but without relationship to VDD ranges.
|
||||
*/
|
||||
#define STM32_ADCCLK_MAX 42000000
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Triggers selection
|
||||
* @{
|
||||
*/
|
||||
#define ADC_CR2_EXTSEL_SRC(n) ((n) << 24) /**< @brief Trigger source. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name ADC clock divider settings
|
||||
* @{
|
||||
*/
|
||||
#define ADC_CCR_ADCPRE_DIV2 0
|
||||
#define ADC_CCR_ADCPRE_DIV4 1
|
||||
#define ADC_CCR_ADCPRE_DIV6 2
|
||||
#define ADC_CCR_ADCPRE_DIV8 3
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @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.
|
||||
@note Available onADC1 only. */
|
||||
#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference.
|
||||
@note Available onADC1 only. */
|
||||
#define ADC_CHANNEL_VBAT 18 /**< @brief VBAT.
|
||||
@note Available onADC1 only. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Sampling rates
|
||||
* @{
|
||||
*/
|
||||
#define ADC_SAMPLE_3 0 /**< @brief 3 cycles sampling time. */
|
||||
#define ADC_SAMPLE_15 1 /**< @brief 15 cycles sampling time. */
|
||||
#define ADC_SAMPLE_28 2 /**< @brief 28 cycles sampling time. */
|
||||
#define ADC_SAMPLE_56 3 /**< @brief 56 cycles sampling time. */
|
||||
#define ADC_SAMPLE_84 4 /**< @brief 84 cycles sampling time. */
|
||||
#define ADC_SAMPLE_112 5 /**< @brief 112 cycles sampling time. */
|
||||
#define ADC_SAMPLE_144 6 /**< @brief 144 cycles sampling time. */
|
||||
#define ADC_SAMPLE_480 7 /**< @brief 480 cycles sampling time. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief ADC common clock divider.
|
||||
* @note This setting is influenced by the VDDA voltage and other
|
||||
* external conditions, please refer to the STM32L15x datasheet
|
||||
* for more info.<br>
|
||||
* See section 6.3.15 "12-bit ADC characteristics".
|
||||
*/
|
||||
#if !defined(STM32_ADC_ADCPRE) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC1 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_USE_ADC1 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC2 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC2 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(STM32_ADC_USE_ADC2) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_USE_ADC2 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC3 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC3 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(STM32_ADC_USE_ADC3) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_USE_ADC3 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief DMA stream used for ADC1 operations.
|
||||
*/
|
||||
#if !defined(STM32_ADC_ADC1_DMA_STREAM) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief DMA stream used for ADC2 operations.
|
||||
*/
|
||||
#if !defined(STM32_ADC_ADC2_DMA_STREAM) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief DMA stream used for ADC3 operations.
|
||||
*/
|
||||
#if !defined(STM32_ADC_ADC3_DMA_STREAM) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC1 DMA priority (0..3|lowest..highest).
|
||||
*/
|
||||
#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_ADC1_DMA_PRIORITY 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC2 DMA priority (0..3|lowest..highest).
|
||||
*/
|
||||
#if !defined(STM32_ADC_ADC2_DMA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_ADC2_DMA_PRIORITY 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC3 DMA priority (0..3|lowest..highest).
|
||||
*/
|
||||
#if !defined(STM32_ADC_ADC3_DMA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_ADC3_DMA_PRIORITY 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC interrupt priority level setting.
|
||||
* @note This setting is shared among ADC1, ADC2 and ADC3 because
|
||||
* all ADCs share the same vector.
|
||||
*/
|
||||
#if !defined(STM32_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_IRQ_PRIORITY 5
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC1 DMA interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC2 DMA interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(STM32_ADC_ADC2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC3 DMA interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(STM32_ADC_ADC3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
|
||||
#error "ADC1 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC2 && !STM32_HAS_ADC2
|
||||
#error "ADC2 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC3 && !STM32_HAS_ADC3
|
||||
#error "ADC3 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !STM32_ADC_USE_ADC1 && !STM32_ADC_USE_ADC2 && !STM32_ADC_USE_ADC3
|
||||
#error "ADC driver activated but no ADC peripheral assigned"
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC1 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_MSK)
|
||||
#error "invalid DMA stream associated to ADC1"
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC2 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_MSK)
|
||||
#error "invalid DMA stream associated to ADC2"
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC3 && \
|
||||
!STM32_DMA_IS_VALID_ID(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_MSK)
|
||||
#error "invalid DMA stream associated to ADC3"
|
||||
#endif
|
||||
|
||||
/* ADC clock related settings and checks.*/
|
||||
#if STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV2
|
||||
#define STM32_ADCCLK (STM32_PCLK2 / 2)
|
||||
#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV4
|
||||
#define STM32_ADCCLK (STM32_PCLK2 / 4)
|
||||
#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV6
|
||||
#define STM32_ADCCLK (STM32_PCLK2 / 6)
|
||||
#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV8
|
||||
#define STM32_ADCCLK (STM32_PCLK2 / 8)
|
||||
#else
|
||||
#error "invalid STM32_ADC_ADCPRE value specified"
|
||||
#endif
|
||||
|
||||
#if (STM32_ADCCLK < STM32_ADCCLK_MIN) || (STM32_ADCCLK > STM32_ADCCLK_MAX)
|
||||
#error "STM32_ADCCLK outside acceptable range (STM32_ADCCLK_MIN...STM32_ADCCLK_MAX)"
|
||||
#endif
|
||||
|
||||
#if !defined(STM32_DMA_REQUIRED)
|
||||
#define STM32_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. */
|
||||
ADC_ERR_OVERFLOW = 1 /**< ADC overflow condition. */
|
||||
} adcerror_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an ADC driver.
|
||||
*/
|
||||
typedef struct ADCDriver ADCDriver;
|
||||
|
||||
/**
|
||||
* @brief ADC notification callback type.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object triggering the
|
||||
* callback
|
||||
* @param[in] buffer pointer to the most recent samples data
|
||||
* @param[in] n number of buffer rows available starting from @p buffer
|
||||
*/
|
||||
typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n);
|
||||
|
||||
/**
|
||||
* @brief ADC error callback type.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object triggering the
|
||||
* callback
|
||||
*/
|
||||
typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err);
|
||||
|
||||
/**
|
||||
* @brief Conversion group configuration structure.
|
||||
* @details This implementation-dependent structure describes a conversion
|
||||
* operation.
|
||||
* @note The use of this configuration structure requires knowledge of
|
||||
* STM32 ADC cell registers interface, please refer to the STM32
|
||||
* reference manual for details.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Enables the circular buffer mode for the group.
|
||||
*/
|
||||
bool_t circular;
|
||||
/**
|
||||
* @brief Number of the analog channels belonging to the conversion group.
|
||||
*/
|
||||
adc_channels_num_t num_channels;
|
||||
/**
|
||||
* @brief Callback function associated to the group or @p NULL.
|
||||
*/
|
||||
adccallback_t end_cb;
|
||||
/**
|
||||
* @brief Error callback or @p NULL.
|
||||
*/
|
||||
adcerrorcallback_t error_cb;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief 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;
|
||||
/**
|
||||
* @brief 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;
|
||||
/**
|
||||
* @brief ADC SMPR1 register initialization data.
|
||||
* @details In this field must be specified the sample times for channels
|
||||
* 10...18.
|
||||
*/
|
||||
uint32_t smpr1;
|
||||
/**
|
||||
* @brief ADC SMPR2 register initialization data.
|
||||
* @details In this field must be specified the sample times for channels
|
||||
* 0...9.
|
||||
*/
|
||||
uint32_t smpr2;
|
||||
/**
|
||||
* @brief ADC SQR1 register initialization data.
|
||||
* @details Conversion group sequence 13...16 + sequence length.
|
||||
*/
|
||||
uint32_t sqr1;
|
||||
/**
|
||||
* @brief ADC SQR2 register initialization data.
|
||||
* @details Conversion group sequence 7...12.
|
||||
*/
|
||||
uint32_t sqr2;
|
||||
/**
|
||||
* @brief ADC SQR3 register initialization data.
|
||||
* @details Conversion group sequence 1...6.
|
||||
*/
|
||||
uint32_t sqr3;
|
||||
} ADCConversionGroup;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t dummy;
|
||||
} ADCConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an ADC driver.
|
||||
*/
|
||||
struct ADCDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
adcstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const ADCConfig *config;
|
||||
/**
|
||||
* @brief Current samples buffer pointer or @p NULL.
|
||||
*/
|
||||
adcsample_t *samples;
|
||||
/**
|
||||
* @brief Current samples buffer depth or @p 0.
|
||||
*/
|
||||
size_t depth;
|
||||
/**
|
||||
* @brief Current conversion group pointer or @p NULL.
|
||||
*/
|
||||
const ADCConversionGroup *grpp;
|
||||
#if ADC_USE_WAIT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waiting thread.
|
||||
*/
|
||||
Thread *thread;
|
||||
#endif
|
||||
#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mutex protecting the peripheral.
|
||||
*/
|
||||
Mutex mutex;
|
||||
#elif CH_USE_SEMAPHORES
|
||||
Semaphore semaphore;
|
||||
#endif
|
||||
#endif /* ADC_USE_MUTUAL_EXCLUSION */
|
||||
#if defined(ADC_DRIVER_EXT_FIELDS)
|
||||
ADC_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Pointer to the ADCx registers block.
|
||||
*/
|
||||
ADC_TypeDef *adc;
|
||||
/**
|
||||
* @brief Pointer to associated SMA channel.
|
||||
*/
|
||||
const stm32_dma_stream_t *dmastp;
|
||||
/**
|
||||
* @brief DMA mode bit mask.
|
||||
*/
|
||||
uint32_t dmamode;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @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. */
|
||||
#define ADC_SMPR1_SMP_VBAT(n) ((n) << 24) /**< @brief VBAT sampling time. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
|
||||
extern ADCDriver ADCD1;
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC2 && !defined(__DOXYGEN__)
|
||||
extern ADCDriver ADCD2;
|
||||
#endif
|
||||
|
||||
#if STM32_ADC_USE_ADC3 && !defined(__DOXYGEN__)
|
||||
extern ADCDriver ADCD3;
|
||||
#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);
|
||||
void adcSTM32EnableTSVREFE(void);
|
||||
void adcSTM32DisableTSVREFE(void);
|
||||
void adcSTM32EnableVBATE(void);
|
||||
void adcSTM32DisableVBATE(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_ADC */
|
||||
|
||||
#endif /* _ADC_LLD_H_ */
|
||||
|
||||
/** @} */
|
|
@ -19,8 +19,8 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file STM32F2xx/hal_lld.c
|
||||
* @brief STM32F2xx HAL subsystem low level driver source.
|
||||
* @file STM32F4xx/hal_lld.c
|
||||
* @brief STM32F4xx HAL subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
|
@ -56,11 +56,13 @@
|
|||
*/
|
||||
void hal_lld_init(void) {
|
||||
|
||||
/* Reset of all peripherals.*/
|
||||
// RCC->APB1RSTR = 0xFFFFFFFF;
|
||||
// RCC->APB2RSTR = 0xFFFFFFFF;
|
||||
// RCC->APB1RSTR = 0;
|
||||
// RCC->APB2RSTR = 0;
|
||||
/* Reset of all peripherals. AHB3 is not reseted because it could have
|
||||
been initialized in the board initialization file (board.c).*/
|
||||
rccResetAHB1(!0);
|
||||
rccResetAHB2(!0);
|
||||
rccResetAHB3(!0);
|
||||
rccResetAPB1(!RCC_APB1RSTR_PWRRST);
|
||||
rccResetAPB2(!0);
|
||||
|
||||
/* SysTick initialization using the system clock.*/
|
||||
SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1;
|
||||
|
@ -69,7 +71,10 @@ void hal_lld_init(void) {
|
|||
SysTick_CTRL_ENABLE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk;
|
||||
|
||||
|
||||
#if STM32_PVD_ENABLE
|
||||
/* Programmable voltage detector initialization */
|
||||
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
|
||||
#endif /* STM32_PVD_ENABLE */
|
||||
|
||||
#if defined(STM32_DMA_REQUIRED)
|
||||
dmaInit();
|
||||
|
@ -83,16 +88,15 @@ void hal_lld_init(void) {
|
|||
*
|
||||
* @special
|
||||
*/
|
||||
#if defined(STM32F2XX) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Clocks and internal voltage initialization.
|
||||
*/
|
||||
void stm32_clock_init(void) {
|
||||
|
||||
#if !STM32_NO_INIT
|
||||
/* PWR clock enable.*/
|
||||
RCC->APB1ENR = RCC_APB1ENR_PWREN;
|
||||
|
||||
/* PWR initialization.*/
|
||||
PWR->CR = 0;
|
||||
|
||||
/* Initial clocks setup and wait for HSI stabilization, the MSI clock is
|
||||
always enabled because it is the fallback clock when PLL the fails.*/
|
||||
RCC->CR |= RCC_CR_HSION;
|
||||
|
@ -134,7 +138,7 @@ void stm32_clock_init(void) {
|
|||
|
||||
#if STM32_ACTIVATE_PLLI2S
|
||||
/* PLLI2S activation.*/
|
||||
RCC->PLLI2SCFGR = STM32_PLI2SR_VALUE | STM32_PLLI2SN_VALUE;
|
||||
RCC->PLLI2SCFGR = STM32_PLLI2SR_VALUE | STM32_PLLI2SN_VALUE;
|
||||
RCC->CR |= RCC_CR_PLLI2SON;
|
||||
while (!(RCC->CR & RCC_CR_PLLI2SRDY))
|
||||
; /* Waits until PLLI2S is stable. */
|
||||
|
@ -144,19 +148,21 @@ void stm32_clock_init(void) {
|
|||
RCC->CFGR |= STM32_MCO2PRE | STM32_MCO2SEL | STM32_MCO1PRE | STM32_MCO1SEL |
|
||||
STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
|
||||
|
||||
/* Flash setup. */
|
||||
FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | STM32_FLASHBITS;
|
||||
/* Flash setup.*/
|
||||
FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN |
|
||||
STM32_FLASHBITS;
|
||||
|
||||
/* Switching to the configured clock source if it is different from MSI. */
|
||||
/* Switching to the configured clock source if it is different from MSI.*/
|
||||
#if (STM32_SW != STM32_SW_HSI)
|
||||
RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */
|
||||
RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
|
||||
;
|
||||
#endif
|
||||
#endif /* STM32_NO_INIT */
|
||||
|
||||
/* SYSCFG clock enabled here because it is a multi-functional unit shared
|
||||
among multiple drivers.*/
|
||||
rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, TRUE);
|
||||
}
|
||||
#else
|
||||
void stm32_clock_init(void) {}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_DRIVERS STM32F2xx Drivers
|
||||
* @details This section describes all the supported drivers on the STM32F2xx
|
||||
* platform and the implementation details of the single drivers.
|
||||
*
|
||||
* @ingroup platforms
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_HAL STM32F2xx Initialization Support
|
||||
* @details The STM32F2xx HAL support is responsible for system initialization.
|
||||
*
|
||||
* @section stm32f2xx_hal_1 Supported HW resources
|
||||
* - PLL1.
|
||||
* - PLL2.
|
||||
* - RCC.
|
||||
* - Flash.
|
||||
* .
|
||||
* @section stm32f2xx_hal_2 STM32F2xx HAL driver implementation features
|
||||
* - PLL startup and stabilization.
|
||||
* - Clock tree initialization.
|
||||
* - Clock source selection.
|
||||
* - Flash wait states initialization based on the selected clock options.
|
||||
* - SYSTICK initialization based on current clock and kernel required rate.
|
||||
* - DMA support initialization.
|
||||
* .
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_ADC STM32F2xx ADC Support
|
||||
* @details The STM32F2xx ADC driver supports the ADC peripherals using DMA
|
||||
* channels for maximum performance.
|
||||
*
|
||||
* @section stm32f2xx_adc_1 Supported HW resources
|
||||
* - ADC1.
|
||||
* - ADC2.
|
||||
* - ADC3.
|
||||
* - DMA2.
|
||||
* .
|
||||
* @section stm32f2xx_adc_2 STM32F2xx ADC driver implementation features
|
||||
* - Clock stop for reduced power usage when the driver is in stop state.
|
||||
* - Streaming conversion using DMA for maximum performance.
|
||||
* - Programmable ADC interrupt priority level.
|
||||
* - Programmable DMA bus priority for each DMA channel.
|
||||
* - Programmable DMA interrupt priority for each DMA channel.
|
||||
* - DMA and ADC errors detection.
|
||||
* .
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_EXT STM32F2xx EXT Support
|
||||
* @details The STM32F2xx EXT driver uses the EXTI peripheral.
|
||||
*
|
||||
* @section stm32f2xx_ext_1 Supported HW resources
|
||||
* - EXTI.
|
||||
* .
|
||||
* @section stm32f2xx_ext_2 STM32F2xx EXT driver implementation features
|
||||
* - Each EXTI channel can be independently enabled and programmed.
|
||||
* - Programmable EXTI interrupts priority level.
|
||||
* - Capability to work as event sources (WFE) rather than interrupt sources.
|
||||
* .
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_GPT STM32F2xx GPT Support
|
||||
* @details The STM32F2xx GPT driver uses the TIMx peripherals.
|
||||
*
|
||||
* @section stm32f2xx_gpt_1 Supported HW resources
|
||||
* - TIM1.
|
||||
* - TIM2.
|
||||
* - TIM3.
|
||||
* - TIM4.
|
||||
* - TIM5.
|
||||
* - TIM8.
|
||||
* .
|
||||
* @section stm32f2xx_gpt_2 STM32F2xx GPT driver implementation features
|
||||
* - Each timer can be independently enabled and programmed. Unused
|
||||
* peripherals are left in low power mode.
|
||||
* - Programmable TIMx interrupts priority level.
|
||||
* .
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_ICU STM32F2xx ICU Support
|
||||
* @details The STM32F2xx ICU driver uses the TIMx peripherals.
|
||||
*
|
||||
* @section stm32f2xx_icu_1 Supported HW resources
|
||||
* - TIM1.
|
||||
* - TIM2.
|
||||
* - TIM3.
|
||||
* - TIM4.
|
||||
* - TIM5.
|
||||
* - TIM8.
|
||||
* .
|
||||
* @section stm32f2xx_icu_2 STM32F2xx ICU driver implementation features
|
||||
* - Each timer can be independently enabled and programmed. Unused
|
||||
* peripherals are left in low power mode.
|
||||
* - Programmable TIMx interrupts priority level.
|
||||
* .
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_PAL STM32F2xx PAL Support
|
||||
* @details The STM32F2xx PAL driver uses the GPIO peripherals.
|
||||
*
|
||||
* @section stm32f2xx_pal_1 Supported HW resources
|
||||
* - GPIOA.
|
||||
* - GPIOB.
|
||||
* - GPIOC.
|
||||
* - GPIOD.
|
||||
* - GPIOE.
|
||||
* - GPIOF.
|
||||
* - GPIOG.
|
||||
* - GPIOH.
|
||||
* - GPIOI.
|
||||
* .
|
||||
* @section stm32f2xx_pal_2 STM32F2xx PAL driver implementation features
|
||||
* The PAL driver implementation fully supports the following hardware
|
||||
* capabilities:
|
||||
* - 16 bits wide ports.
|
||||
* - Atomic set/reset functions.
|
||||
* - Atomic set+reset function (atomic bus operations).
|
||||
* - Output latched regardless of the pad setting.
|
||||
* - Direct read of input pads regardless of the pad setting.
|
||||
* .
|
||||
* @section stm32f2xx_pal_3 Supported PAL setup modes
|
||||
* The STM32F2xx PAL driver supports the following I/O modes:
|
||||
* - @p PAL_MODE_RESET.
|
||||
* - @p PAL_MODE_UNCONNECTED.
|
||||
* - @p PAL_MODE_INPUT.
|
||||
* - @p PAL_MODE_INPUT_PULLUP.
|
||||
* - @p PAL_MODE_INPUT_PULLDOWN.
|
||||
* - @p PAL_MODE_INPUT_ANALOG.
|
||||
* - @p PAL_MODE_OUTPUT_PUSHPULL.
|
||||
* - @p PAL_MODE_OUTPUT_OPENDRAIN.
|
||||
* - @p PAL_MODE_ALTERNATE (non standard).
|
||||
* .
|
||||
* Any attempt to setup an invalid mode is ignored.
|
||||
*
|
||||
* @section stm32f2xx_pal_4 Suboptimal behavior
|
||||
* The STM32F2xx GPIO is less than optimal in several areas, the limitations
|
||||
* should be taken in account while using the PAL driver:
|
||||
* - Pad/port toggling operations are not atomic.
|
||||
* - Pad/group mode setup is not atomic.
|
||||
* .
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_PWM STM32F2xx PWM Support
|
||||
* @details The STM32F2xx PWM driver uses the TIMx peripherals.
|
||||
*
|
||||
* @section stm32f2xx_pwm_1 Supported HW resources
|
||||
* - TIM1.
|
||||
* - TIM2.
|
||||
* - TIM3.
|
||||
* - TIM4.
|
||||
* - TIM5.
|
||||
* - TIM8.
|
||||
* .
|
||||
* @section stm32f2xx_pwm_2 STM32F2xx PWM driver implementation features
|
||||
* - Each timer can be independently enabled and programmed. Unused
|
||||
* peripherals are left in low power mode.
|
||||
* - Four independent PWM channels per timer.
|
||||
* - Programmable TIMx interrupts priority level.
|
||||
* .
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_SERIAL STM32F2xx Serial Support
|
||||
* @details The STM32F2xx Serial driver uses the USART/UART peripherals in a
|
||||
* buffered, interrupt driven, implementation.
|
||||
*
|
||||
* @section stm32f2xx_serial_1 Supported HW resources
|
||||
* The serial driver can support any of the following hardware resources:
|
||||
* - USART1.
|
||||
* - USART2.
|
||||
* - USART3.
|
||||
* - UART4.
|
||||
* - UART5.
|
||||
* - USART6.
|
||||
* .
|
||||
* @section stm32f2xx_serial_2 STM32F2xx Serial driver implementation features
|
||||
* - Clock stop for reduced power usage when the driver is in stop state.
|
||||
* - Each UART/USART can be independently enabled and programmed. Unused
|
||||
* peripherals are left in low power mode.
|
||||
* - Fully interrupt driven.
|
||||
* - Programmable priority levels for each UART/USART.
|
||||
* .
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_SPI STM32F2xx SPI Support
|
||||
* @details The SPI driver supports the STM32F2xx SPI peripherals using DMA
|
||||
* channels for maximum performance.
|
||||
*
|
||||
* @section stm32f2xx_spi_1 Supported HW resources
|
||||
* - SPI1.
|
||||
* - SPI2.
|
||||
* - SPI3.
|
||||
* - DMA1.
|
||||
* - DMA2.
|
||||
* .
|
||||
* @section stm32f2xx_spi_2 STM32F2xx SPI driver implementation features
|
||||
* - Clock stop for reduced power usage when the driver is in stop state.
|
||||
* - Each SPI can be independently enabled and programmed. Unused
|
||||
* peripherals are left in low power mode.
|
||||
* - Programmable interrupt priority levels for each SPI.
|
||||
* - DMA is used for receiving and transmitting.
|
||||
* - Programmable DMA bus priority for each DMA channel.
|
||||
* - Programmable DMA interrupt priority for each DMA channel.
|
||||
* - Programmable DMA error hook.
|
||||
* .
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_UART STM32F2xx UART Support
|
||||
* @details The UART driver supports the STM32F2xx USART peripherals using DMA
|
||||
* channels for maximum performance.
|
||||
*
|
||||
* @section stm32f2xx_uart_1 Supported HW resources
|
||||
* The UART driver can support any of the following hardware resources:
|
||||
* - USART1.
|
||||
* - USART2.
|
||||
* - USART3.
|
||||
* - DMA1.
|
||||
* - DMA2.
|
||||
* .
|
||||
* @section stm32f2xx_uart_2 STM32F2xx UART driver implementation features
|
||||
* - Clock stop for reduced power usage when the driver is in stop state.
|
||||
* - Each UART/USART can be independently enabled and programmed. Unused
|
||||
* peripherals are left in low power mode.
|
||||
* - Programmable interrupt priority levels for each UART/USART.
|
||||
* - DMA is used for receiving and transmitting.
|
||||
* - Programmable DMA bus priority for each DMA channel.
|
||||
* - Programmable DMA interrupt priority for each DMA channel.
|
||||
* - Programmable DMA error hook.
|
||||
* .
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_PLATFORM_DRIVERS STM32F2xx Platform Drivers
|
||||
* @details Platform support drivers. Platform drivers do not implement HAL
|
||||
* standard driver templates, their role is to support platform
|
||||
* specific functionalities.
|
||||
*
|
||||
* @ingroup STM32F2xx_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_DMA STM32F2xx DMA Support
|
||||
* @details This DMA helper driver is used by the other drivers in order to
|
||||
* access the shared DMA resources in a consistent way.
|
||||
*
|
||||
* @section stm32f2xx_dma_1 Supported HW resources
|
||||
* The DMA driver can support any of the following hardware resources:
|
||||
* - DMA1.
|
||||
* - DMA2.
|
||||
* .
|
||||
* @section stm32f2xx_dma_2 STM32F2xx DMA driver implementation features
|
||||
* - Exports helper functions/macros to the other drivers that share the
|
||||
* DMA resource.
|
||||
* - Automatic DMA clock stop when not in use by any driver.
|
||||
* - DMA streams and interrupt vectors sharing among multiple drivers.
|
||||
* .
|
||||
* @ingroup STM32F2xx_PLATFORM_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup STM32F2xx_RCC STM32F2xx RCC Support
|
||||
* @details This RCC helper driver is used by the other drivers in order to
|
||||
* access the shared RCC resources in a consistent way.
|
||||
*
|
||||
* @section stm32f1xx_rcc_1 Supported HW resources
|
||||
* - RCC.
|
||||
* .
|
||||
* @section stm32f2xx_rcc_2 STM32F2xx RCC driver implementation features
|
||||
* - Peripherals reset.
|
||||
* - Peripherals clock enable.
|
||||
* - Periplerals clock disable.
|
||||
* .
|
||||
* @ingroup STM32F2xx_PLATFORM_DRIVERS
|
||||
*/
|
|
@ -1,12 +1,22 @@
|
|||
# List of all the STM32L1xx platform files.
|
||||
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F2xx/hal_lld.c \
|
||||
# List of all the STM32F2xx platform files.
|
||||
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F2xx/stm32_dma.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32F2xx/hal_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32F2xx/adc_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/gpt_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/icu_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/pwm_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c
|
||||
${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/i2c_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/RTCv2/rtc_lld.c \
|
||||
|
||||
# Required include directories
|
||||
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F2xx \
|
||||
${CHIBIOS}/os/hal/platforms/STM32 \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2
|
||||
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 \
|
||||
${CHIBIOS}/os/hal/platforms/STM32/RTCv2 \
|
||||
|
||||
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file DMAv2/stm32_dma.c
|
||||
* @file STM32F2xx/stm32_dma.c
|
||||
* @brief Enhanced DMA helper driver code.
|
||||
*
|
||||
* @addtogroup STM32_DMA
|
||||
* @addtogroup STM32F2xx_DMA
|
||||
* @details DMA sharing helper driver. In the STM32 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
|
||||
|
@ -76,22 +76,22 @@
|
|||
* instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc.
|
||||
*/
|
||||
const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
|
||||
{0, DMA1, DMA1_Stream0, &DMA1->LIFCR, 0},
|
||||
{1, DMA1, DMA1_Stream1, &DMA1->LIFCR, 6},
|
||||
{2, DMA1, DMA1_Stream2, &DMA1->LIFCR, 16},
|
||||
{3, DMA1, DMA1_Stream3, &DMA1->LIFCR, 22},
|
||||
{4, DMA1, DMA1_Stream4, &DMA1->HIFCR, 0},
|
||||
{5, DMA1, DMA1_Stream5, &DMA1->HIFCR, 6},
|
||||
{6, DMA1, DMA1_Stream6, &DMA1->HIFCR, 16},
|
||||
{7, DMA1, DMA1_Stream7, &DMA1->HIFCR, 22},
|
||||
{8, DMA2, DMA2_Stream0, &DMA2->LIFCR, 0},
|
||||
{9, DMA2, DMA2_Stream1, &DMA2->LIFCR, 6},
|
||||
{10, DMA2, DMA2_Stream2, &DMA2->LIFCR, 16},
|
||||
{11, DMA2, DMA2_Stream3, &DMA2->LIFCR, 22},
|
||||
{12, DMA2, DMA2_Stream4, &DMA2->HIFCR, 0},
|
||||
{13, DMA2, DMA2_Stream5, &DMA2->HIFCR, 6},
|
||||
{14, DMA2, DMA2_Stream6, &DMA2->HIFCR, 16},
|
||||
{15, DMA2, DMA2_Stream7, &DMA2->HIFCR, 22},
|
||||
{DMA1_Stream0, &DMA1->LIFCR, 0, 0, DMA1_Stream0_IRQn},
|
||||
{DMA1_Stream1, &DMA1->LIFCR, 6, 1, DMA1_Stream1_IRQn},
|
||||
{DMA1_Stream2, &DMA1->LIFCR, 16, 2, DMA1_Stream2_IRQn},
|
||||
{DMA1_Stream3, &DMA1->LIFCR, 22, 3, DMA1_Stream3_IRQn},
|
||||
{DMA1_Stream4, &DMA1->HIFCR, 0, 4, DMA1_Stream4_IRQn},
|
||||
{DMA1_Stream5, &DMA1->HIFCR, 6, 5, DMA1_Stream5_IRQn},
|
||||
{DMA1_Stream6, &DMA1->HIFCR, 16, 6, DMA1_Stream6_IRQn},
|
||||
{DMA1_Stream7, &DMA1->HIFCR, 22, 7, DMA1_Stream7_IRQn},
|
||||
{DMA2_Stream0, &DMA2->LIFCR, 0, 8, DMA2_Stream0_IRQn},
|
||||
{DMA2_Stream1, &DMA2->LIFCR, 6, 9, DMA2_Stream1_IRQn},
|
||||
{DMA2_Stream2, &DMA2->LIFCR, 16, 10, DMA2_Stream2_IRQn},
|
||||
{DMA2_Stream3, &DMA2->LIFCR, 22, 11, DMA2_Stream3_IRQn},
|
||||
{DMA2_Stream4, &DMA2->HIFCR, 0, 12, DMA2_Stream4_IRQn},
|
||||
{DMA2_Stream5, &DMA2->HIFCR, 6, 13, DMA2_Stream5_IRQn},
|
||||
{DMA2_Stream6, &DMA2->HIFCR, 16, 14, DMA2_Stream6_IRQn},
|
||||
{DMA2_Stream7, &DMA2->HIFCR, 22, 15, DMA2_Stream7_IRQn},
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -102,8 +102,8 @@ const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
|
|||
* @brief DMA ISR redirector type.
|
||||
*/
|
||||
typedef struct {
|
||||
stm32_dmaisr_t dma_func;
|
||||
void *dma_param;
|
||||
stm32_dmaisr_t dma_func; /**< @brief DMA callback function. */
|
||||
void *dma_param; /**< @brief DMA callback parameter. */
|
||||
} dma_isr_redir_t;
|
||||
|
||||
/**
|
||||
|
@ -467,7 +467,7 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
|
|||
chDbgCheck(dmastp != NULL, "dmaAllocate");
|
||||
|
||||
/* Checks if the stream is already taken.*/
|
||||
if ((dma_streams_mask & dmastp->mask) != 0)
|
||||
if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0)
|
||||
return TRUE;
|
||||
|
||||
/* Marks the stream as allocated.*/
|
||||
|
@ -476,20 +476,16 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
|
|||
dma_streams_mask |= (1 << dmastp->selfindex);
|
||||
|
||||
/* Enabling DMA clocks required by the current streams set.*/
|
||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) {
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
|
||||
RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN;
|
||||
}
|
||||
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) {
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
|
||||
RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN;
|
||||
}
|
||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0)
|
||||
rccEnableDMA1(FALSE);
|
||||
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0)
|
||||
rccEnableDMA2(FALSE);
|
||||
|
||||
/* Putting the stream in a safe state.*/
|
||||
dmaStreamDisable(dmastp);
|
||||
dmaStreamClearInterrupt(dmastp);
|
||||
dmastp->channel->CR = STM32_DMA_CR_RESET_VALUE;
|
||||
dmastp->channel->FCR = STM32_DMA_FCR_RESET_VALUE;
|
||||
dmastp->stream->CR = STM32_DMA_CR_RESET_VALUE;
|
||||
dmastp->stream->FCR = STM32_DMA_FCR_RESET_VALUE;
|
||||
|
||||
/* Enables the associated IRQ vector if a callback is defined.*/
|
||||
if (func != NULL)
|
||||
|
@ -516,7 +512,7 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
|
|||
chDbgCheck(dmastp != NULL, "dmaRelease");
|
||||
|
||||
/* Check if the streams is not taken.*/
|
||||
chDbgAssert((dma_streams_mask & dmastp->mask) != 0,
|
||||
chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
|
||||
"dmaRelease(), #1", "not allocated");
|
||||
|
||||
/* Disables the associated IRQ vector.*/
|
||||
|
@ -526,14 +522,10 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
|
|||
dma_streams_mask &= ~(1 << dmastp->selfindex);
|
||||
|
||||
/* Shutting down clocks that are no more required, if any.*/
|
||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) {
|
||||
RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN;
|
||||
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA1LPEN;
|
||||
}
|
||||
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) {
|
||||
RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN;
|
||||
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA2LPEN;
|
||||
}
|
||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0)
|
||||
rccDisableDMA1(FALSE);
|
||||
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
|
||||
rccDisableDMA2(FALSE);
|
||||
}
|
||||
|
||||
#endif /* STM32_DMA_REQUIRED */
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file DMAv2/stm32_dma.h
|
||||
* @file STM32F2xx/stm32_dma.h
|
||||
* @brief Enhanced-DMA helper driver header.
|
||||
* @note This file requires definitions from the ST STM32F2xx header file
|
||||
* stm32f2xx.h.
|
||||
*
|
||||
* @addtogroup STM32_DMA
|
||||
* @addtogroup STM32F2xx_DMA
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
@ -46,30 +46,81 @@
|
|||
*/
|
||||
#define STM32_DMA_ISR_MASK 0x3D
|
||||
|
||||
/**
|
||||
* @brief Returns the channel associated to the specified stream.
|
||||
*
|
||||
* @param[in] id the unique numeric stream identifier
|
||||
* @param[in] c a stream/channel association word, one channel per
|
||||
* nibble
|
||||
* @return Returns the channel associated to the stream.
|
||||
*/
|
||||
#define STM32_DMA_GETCHANNEL(id, c) ((c) >> (((id) & 7) * 4))
|
||||
|
||||
/**
|
||||
* @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 STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1) * 8) + (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 STM32_DMA_STREAM_ID_MSK(dma, stream) \
|
||||
(1 << STM32_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 STM32_DMA_IS_VALID_ID(id, mask) (((1 << (id)) & (mask)))
|
||||
|
||||
/**
|
||||
* @name DMA streams identifiers
|
||||
* @{
|
||||
*/
|
||||
#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0])
|
||||
#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1])
|
||||
#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2])
|
||||
#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3])
|
||||
#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4])
|
||||
#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5])
|
||||
#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6])
|
||||
#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7])
|
||||
#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8])
|
||||
#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9])
|
||||
#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10])
|
||||
#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11])
|
||||
#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12])
|
||||
#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13])
|
||||
#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14])
|
||||
#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15])
|
||||
/**
|
||||
* @brief Returns a pointer to a stm32_dma_stream_t structure.
|
||||
*
|
||||
* @param[in] id the stream numeric identifier
|
||||
* @return A pointer to the stm32_dma_stream_t constant structure
|
||||
* associated to the DMA stream.
|
||||
*/
|
||||
#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id])
|
||||
|
||||
#define STM32_DMA1_STREAM0 STM32_DMA_STREAM(0)
|
||||
#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(1)
|
||||
#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(2)
|
||||
#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(3)
|
||||
#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(4)
|
||||
#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(5)
|
||||
#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(6)
|
||||
#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(7)
|
||||
#define STM32_DMA2_STREAM0 STM32_DMA_STREAM(8)
|
||||
#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(9)
|
||||
#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(10)
|
||||
#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(11)
|
||||
#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(12)
|
||||
#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(13)
|
||||
#define STM32_DMA2_STREAM6 STM32_DMA_STREAM(14)
|
||||
#define STM32_DMA2_STREAM7 STM32_DMA_STREAM(15)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name CR register constants common to all DMA types
|
||||
* @{
|
||||
*/
|
||||
#define STM32_DMA_CR_EN DMA_SxCR_EN
|
||||
#define STM32_DMA_CR_TEIE DMA_SxCR_TEIE
|
||||
|
@ -90,12 +141,15 @@
|
|||
#define STM32_DMA_CR_MSIZE_BYTE 0
|
||||
#define STM32_DMA_CR_MSIZE_HWORD DMA_SxCR_MSIZE_0
|
||||
#define STM32_DMA_CR_MSIZE_WORD DMA_SxCR_MSIZE_1
|
||||
#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_MSIZE_MASK | \
|
||||
STM32_DMA_CR_MSIZE_MASK)
|
||||
#define STM32_DMA_CR_PL_MASK DMA_SxCR_PL
|
||||
#define STM32_DMA_CR_PL(n) ((n) << 16)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name CR register constants only found in STM32F2xx
|
||||
* @name CR register constants only found in STM32F2xx/STM32F2xx
|
||||
* @{
|
||||
*/
|
||||
#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE
|
||||
#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL
|
||||
|
@ -117,7 +171,8 @@
|
|||
/** @} */
|
||||
|
||||
/**
|
||||
* @name FCR register constants only found in STM32F2xx
|
||||
* @name FCR register constants only found in STM32F2xx/STM32F2xx
|
||||
* @{
|
||||
*/
|
||||
#define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE
|
||||
#define STM32_DMA_FCR_FS_MASK DMA_SxFCR_FS
|
||||
|
@ -155,7 +210,7 @@
|
|||
* @brief STM32 DMA stream descriptor structure.
|
||||
*/
|
||||
typedef struct {
|
||||
DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
|
||||
DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */
|
||||
volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
|
||||
uint8_t ishift; /**< @brief Bits offset in xIFCR
|
||||
register. */
|
||||
|
@ -176,9 +231,15 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/* 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 dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] addr value to be written in the PAR register
|
||||
|
@ -192,6 +253,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/**
|
||||
* @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 dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] addr value to be written in the M0AR register
|
||||
|
@ -218,6 +281,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/**
|
||||
* @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 dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] size value to be written in the CNDTR register
|
||||
|
@ -231,6 +296,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/**
|
||||
* @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 dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @return The number of transfers to be performed.
|
||||
|
@ -242,6 +309,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/**
|
||||
* @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 dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] mode value to be written in the CR register
|
||||
|
@ -255,6 +324,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/**
|
||||
* @brief Programs the stream FIFO settings.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] mode value to be written in the FCR register
|
||||
|
@ -268,18 +339,22 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/**
|
||||
* @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 dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmachp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define dmaStreamEnable(dmachp) { \
|
||||
#define dmaStreamEnable(dmastp) { \
|
||||
(dmastp)->stream->CR |= STM32_DMA_CR_EN; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA stream disable.
|
||||
* @note This function can be invoked in both ISR or thread context.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
|
@ -292,6 +367,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
/**
|
||||
* @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 dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
*
|
||||
|
@ -301,6 +378,46 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
|||
*(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
* @param[in] mode value to be written in the CCR register, this value
|
||||
* is implicitly ORed with:
|
||||
* - @p STM32_DMA_CR_MINC
|
||||
* - @p STM32_DMA_CR_PINC
|
||||
* - @p STM32_DMA_CR_DIR_M2M
|
||||
* - @p STM32_DMA_CR_EN
|
||||
* .
|
||||
* @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) { \
|
||||
dmaStreamSetPeripheral(dmastp, src); \
|
||||
dmaStreamSetMemory0(dmastp, dst); \
|
||||
dmaStreamSetTransactionSize(dmastp, n); \
|
||||
dmaStreamSetMode(dmastp, (mode) | \
|
||||
STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \
|
||||
STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Polled wait for DMA transfer end.
|
||||
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||
*
|
||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||
*/
|
||||
#define dmaWaitCompletion(dmastp) \
|
||||
while (((dmastp)->stream->CNDTR > 0) && \
|
||||
((dmastp)->stream->CCR & STM32_DMA_CR_EN))
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -0,0 +1,886 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS/RT.
|
||||
|
||||
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file STM32F2xx/stm32_rcc.h
|
||||
* @brief RCC helper driver header.
|
||||
* @note This file requires definitions from the ST header file
|
||||
* @p stm32f2xx.h.
|
||||
*
|
||||
* @addtogroup STM32F2xx_RCC
|
||||
* @{
|
||||
*/
|
||||
#ifndef _STM32_RCC_
|
||||
#define _STM32_RCC_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Generic RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the clock of one or more peripheral on the APB1 bus.
|
||||
*
|
||||
* @param[in] mask APB1 peripherals mask
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableAPB1(mask, lp) { \
|
||||
RCC->APB1ENR |= (mask); \
|
||||
if (lp) \
|
||||
RCC->APB1LPENR |= (mask); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the clock of one or more peripheral on the APB1 bus.
|
||||
*
|
||||
* @param[in] mask APB1 peripherals mask
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableAPB1(mask, lp) { \
|
||||
RCC->APB1ENR &= ~(mask); \
|
||||
if (lp) \
|
||||
RCC->APB1LPENR &= ~(mask); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets one or more peripheral on the APB1 bus.
|
||||
*
|
||||
* @param[in] mask APB1 peripherals mask
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetAPB1(mask) { \
|
||||
RCC->APB1RSTR |= (mask); \
|
||||
RCC->APB1RSTR = 0; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the clock of one or more peripheral on the APB2 bus.
|
||||
*
|
||||
* @param[in] mask APB2 peripherals mask
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableAPB2(mask, lp) { \
|
||||
RCC->APB2ENR |= (mask); \
|
||||
if (lp) \
|
||||
RCC->APB2LPENR |= (mask); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the clock of one or more peripheral on the APB2 bus.
|
||||
*
|
||||
* @param[in] mask APB2 peripherals mask
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableAPB2(mask, lp) { \
|
||||
RCC->APB2ENR &= ~(mask); \
|
||||
if (lp) \
|
||||
RCC->APB2LPENR &= ~(mask); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets one or more peripheral on the APB2 bus.
|
||||
*
|
||||
* @param[in] mask APB2 peripherals mask
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetAPB2(mask) { \
|
||||
RCC->APB2RSTR |= (mask); \
|
||||
RCC->APB2RSTR = 0; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the clock of one or more peripheral on the AHB1 bus.
|
||||
*
|
||||
* @param[in] mask AHB1 peripherals mask
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableAHB1(mask, lp) { \
|
||||
RCC->AHB1ENR |= (mask); \
|
||||
if (lp) \
|
||||
RCC->AHB1LPENR |= (mask); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the clock of one or more peripheral on the AHB1 bus.
|
||||
*
|
||||
* @param[in] mask AHB1 peripherals mask
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableAHB1(mask, lp) { \
|
||||
RCC->AHB1ENR &= ~(mask); \
|
||||
if (lp) \
|
||||
RCC->AHB1LPENR &= ~(mask); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets one or more peripheral on the AHB1 bus.
|
||||
*
|
||||
* @param[in] mask AHB1 peripherals mask
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetAHB1(mask) { \
|
||||
RCC->AHB1RSTR |= (mask); \
|
||||
RCC->AHB1RSTR = 0; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the clock of one or more peripheral on the AHB2 bus.
|
||||
*
|
||||
* @param[in] mask AHB2 peripherals mask
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableAHB2(mask, lp) { \
|
||||
RCC->AHB2ENR |= (mask); \
|
||||
if (lp) \
|
||||
RCC->AHB2LPENR |= (mask); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the clock of one or more peripheral on the AHB2 bus.
|
||||
*
|
||||
* @param[in] mask AHB2 peripherals mask
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableAHB2(mask, lp) { \
|
||||
RCC->AHB2ENR &= ~(mask); \
|
||||
if (lp) \
|
||||
RCC->AHB2LPENR &= ~(mask); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets one or more peripheral on the AHB2 bus.
|
||||
*
|
||||
* @param[in] mask AHB2 peripherals mask
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetAHB2(mask) { \
|
||||
RCC->AHB2RSTR |= (mask); \
|
||||
RCC->AHB2RSTR = 0; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the clock of one or more peripheral on the AHB3 (FSMC) bus.
|
||||
*
|
||||
* @param[in] mask AHB3 peripherals mask
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableAHB3(mask, lp) { \
|
||||
RCC->AHB3ENR |= (mask); \
|
||||
if (lp) \
|
||||
RCC->AHB3LPENR |= (mask); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the clock of one or more peripheral on the AHB3 (FSMC) bus.
|
||||
*
|
||||
* @param[in] mask AHB3 peripherals mask
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableAHB3(mask, lp) { \
|
||||
RCC->AHB3ENR &= ~(mask); \
|
||||
if (lp) \
|
||||
RCC->AHB3LPENR &= ~(mask); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets one or more peripheral on the AHB3 (FSMC) bus.
|
||||
*
|
||||
* @param[in] mask AHB3 peripherals mask
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetAHB3(mask) { \
|
||||
RCC->AHB3RSTR |= (mask); \
|
||||
RCC->AHB3RSTR = 0; \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ADC peripherals specific RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the ADC1 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableADC1(lp) rccEnableAPB2(RCC_APB2ENR_ADC1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the ADC1 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableADC1(lp) rccDisableAPB2(RCC_APB2ENR_ADC1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the ADC1 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the ADC2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableADC2(lp) rccEnableAPB2(RCC_APB2ENR_ADC2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the ADC2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableADC2(lp) rccDisableAPB2(RCC_APB2ENR_ADC2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the ADC2 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetADC2() rccResetAPB2(RCC_APB2RSTR_ADC2RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the ADC3 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableADC3(lp) rccEnableAPB2(RCC_APB2ENR_ADC3EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the ADC3 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableADC3(lp) rccDisableAPB2(RCC_APB2ENR_ADC3EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the ADC3 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetADC3() rccResetAPB2(RCC_APB2RSTR_ADC3RST)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief DMA peripheral specific RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the DMA1 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableDMA1(lp) rccEnableAHB1(RCC_AHB1ENR_DMA1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the DMA1 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableDMA1(lp) rccDisableAHB1(RCC_AHB1ENR_DMA1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the DMA1 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetDMA1() rccResetAHB1(RCC_AHB1RSTR_DMA1RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the DMA2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableDMA2(lp) rccEnableAHB1(RCC_AHB1ENR_DMA2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the DMA2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableDMA2(lp) rccDisableAHB1(RCC_AHB1ENR_DMA2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the DMA2 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetDMA2() rccResetAHB1(RCC_AHB1RSTR_DMA2RST)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief I2C peripherals specific RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the I2C1 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableI2C1(lp) rccEnableAPB1(RCC_APB1ENR_I2C1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the I2C1 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableI2C1(lp) rccDisableAPB1(RCC_APB1ENR_I2C1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the I2C1 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetI2C1() rccResetAPB1(RCC_APB1RSTR_I2C1RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the I2C2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableI2C2(lp) rccEnableAPB1(RCC_APB1ENR_I2C2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the I2C2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableI2C2(lp) rccDisableAPB1(RCC_APB1ENR_I2C2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the I2C2 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetI2C2() rccResetAPB1(RCC_APB1RSTR_I2C2RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the I2C3 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableI2C3(lp) rccEnableAPB1(RCC_APB1ENR_I2C3EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the I2C3 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableI2C3(lp) rccDisableAPB1(RCC_APB1ENR_I2C3EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the I2C3 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetI2C3() rccResetAPB1(RCC_APB1RSTR_I2C3RST)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief SPI peripherals specific RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the SPI1 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableSPI1(lp) rccEnableAPB2(RCC_APB2ENR_SPI1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the SPI1 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableSPI1(lp) rccDisableAPB2(RCC_APB2ENR_SPI1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the SPI1 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetSPI1() rccResetAPB2(RCC_APB2RSTR_SPI1RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the SPI2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableSPI2(lp) rccEnableAPB1(RCC_APB1ENR_SPI2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the SPI2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableSPI2(lp) rccDisableAPB1(RCC_APB1ENR_SPI2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the SPI2 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetSPI2() rccResetAPB1(RCC_APB1RSTR_SPI2RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the SPI3 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableSPI3(lp) rccEnableAPB1(RCC_APB1ENR_SPI3EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the SPI3 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableSPI3(lp) rccDisableAPB1(RCC_APB1ENR_SPI3EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the SPI3 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetSPI3() rccResetAPB1(RCC_APB1RSTR_SPI3RST)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief TIM peripherals specific RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the TIM1 peripheral clock.
|
||||
* @note The @p lp parameter is ignored in this family.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableTIM1(lp) rccEnableAPB2(RCC_APB2ENR_TIM1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the TIM1 peripheral clock.
|
||||
* @note The @p lp parameter is ignored in this family.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableTIM1(lp) rccDisableAPB2(RCC_APB2ENR_TIM1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the TIM1 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetTIM1() rccResetAPB2(RCC_APB2RSTR_TIM1RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the TIM2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableTIM2(lp) rccEnableAPB1(RCC_APB1ENR_TIM2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the TIM2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableTIM2(lp) rccDisableAPB1(RCC_APB1ENR_TIM2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the TIM2 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetTIM2() rccResetAPB1(RCC_APB1RSTR_TIM2RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the TIM3 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableTIM3(lp) rccEnableAPB1(RCC_APB1ENR_TIM3EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the TIM3 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableTIM3(lp) rccDisableAPB1(RCC_APB1ENR_TIM3EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the TIM3 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetTIM3() rccResetAPB1(RCC_APB1RSTR_TIM3RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the TIM4 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableTIM4(lp) rccEnableAPB1(RCC_APB1ENR_TIM4EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the TIM4 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableTIM4(lp) rccDisableAPB1(RCC_APB1ENR_TIM4EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the TIM4 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetTIM4() rccResetAPB1(RCC_APB1RSTR_TIM4RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the TIM5 peripheral clock.
|
||||
* @note The @p lp parameter is ignored in this family.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableTIM5(lp) rccEnableAPB1(RCC_APB1ENR_TIM5EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the TIM5 peripheral clock.
|
||||
* @note The @p lp parameter is ignored in this family.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableTIM5(lp) rccDisableAPB1(RCC_APB1ENR_TIM5EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the TIM5 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetTIM5() rccResetAPB1(RCC_APB1RSTR_TIM5RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the TIM8 peripheral clock.
|
||||
* @note The @p lp parameter is ignored in this family.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableTIM8(lp) rccEnableAPB2(RCC_APB2ENR_TIM8EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the TIM8 peripheral clock.
|
||||
* @note The @p lp parameter is ignored in this family.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableTIM8(lp) rccDisableAPB2(RCC_APB2ENR_TIM8EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the TIM8 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetTIM8() rccResetAPB2(RCC_APB2RSTR_TIM8RST)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USART/UART peripherals specific RCC operations
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the USART1 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableUSART1(lp) rccEnableAPB2(RCC_APB2ENR_USART1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the USART1 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableUSART1(lp) rccDisableAPB2(RCC_APB2ENR_USART1EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the USART1 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetUSART1() rccResetAPB2(RCC_APB2RSTR_USART1RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the USART2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableUSART2(lp) rccEnableAPB1(RCC_APB1ENR_USART2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the USART2 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableUSART2(lp) rccDisableAPB1(RCC_APB1ENR_USART2EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the USART2 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetUSART2() rccResetAPB1(RCC_APB1RSTR_USART2RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the USART3 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableUSART3(lp) rccEnableAPB1(RCC_APB1ENR_USART3EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the USART3 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableUSART3(lp) rccDisableAPB1(RCC_APB1ENR_USART3EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the USART3 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetUSART3() rccResetAPB1(RCC_APB1RSTR_USART3RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the USART6 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableUSART6(lp) rccEnableAPB2(RCC_APB2ENR_USART6EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the USART6 peripheral clock.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableUSART6(lp) rccDisableAPB2(RCC_APB2ENR_USART6EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Enables the UART4 peripheral clock.
|
||||
* @note The @p lp parameter is ignored in this family.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableUART4(lp) rccEnableAPB1(RCC_APB1ENR_UART4EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the UART4 peripheral clock.
|
||||
* @note The @p lp parameter is ignored in this family.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableUART4(lp) rccDisableAPB1(RCC_APB1ENR_UART4EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the UART4 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetUART4() rccResetAPB1(RCC_APB1RSTR_UART4RST)
|
||||
|
||||
/**
|
||||
* @brief Enables the UART5 peripheral clock.
|
||||
* @note The @p lp parameter is ignored in this family.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccEnableUART5(lp) rccEnableAPB1(RCC_APB1ENR_UART5EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Disables the UART5 peripheral clock.
|
||||
* @note The @p lp parameter is ignored in this family.
|
||||
*
|
||||
* @param[in] lp low power enable flag
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccDisableUART5(lp) rccDisableAPB1(RCC_APB1ENR_UART5EN, lp)
|
||||
|
||||
/**
|
||||
* @brief Resets the UART5 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetUART5() rccResetAPB1(RCC_APB1RSTR_UART5RST)
|
||||
|
||||
/**
|
||||
* @brief Resets the USART6 peripheral.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define rccResetUSART6() rccResetAPB2(RCC_APB2RSTR_USART6RST)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _STM32_RCC_ */
|
||||
|
||||
/** @} */
|
|
@ -94,6 +94,11 @@ void stm32_clock_init(void) {
|
|||
/* PWR clock enable.*/
|
||||
RCC->APB1ENR = RCC_APB1ENR_PWREN;
|
||||
|
||||
/* PWR initialization.*/
|
||||
PWR->CR = STM32_VOS;
|
||||
while (PWR->CSR & PWR_CSR_VOSRDY)
|
||||
; /* Waits until power regulator is stable. */
|
||||
|
||||
/* Initial clocks setup and wait for HSI stabilization, the MSI clock is
|
||||
always enabled because it is the fallback clock when PLL the fails.*/
|
||||
RCC->CR |= RCC_CR_HSION;
|
||||
|
|
|
@ -56,24 +56,24 @@
|
|||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Maximum HSE clock frequency.
|
||||
* @brief Maximum HSE clock frequency.
|
||||
*/
|
||||
#define STM32_HSECLK_MAX 26000000
|
||||
|
||||
/**
|
||||
* @brief Minimum HSE clock frequency.
|
||||
* @brief Minimum HSE clock frequency.
|
||||
*/
|
||||
#define STM32_HSECLK_MIN 1000000
|
||||
|
||||
/**
|
||||
* @brief Maximum LSE clock frequency.
|
||||
* @brief Maximum LSE clock frequency.
|
||||
*/
|
||||
#define STM32_LSECLK_MAX 1000000
|
||||
|
||||
/**
|
||||
* @brief Minimum LSE clock frequency.
|
||||
* @brief Minimum LSE clock frequency.
|
||||
*/
|
||||
#define STM32_LSECLK_MIN 1000
|
||||
#define STM32_LSECLK_MIN 32768
|
||||
|
||||
/**
|
||||
* @brief Maximum PLLs input clock frequency.
|
||||
|
@ -126,7 +126,7 @@
|
|||
* @{
|
||||
*/
|
||||
#define STM32_HSICLK 16000000 /**< High speed internal clock. */
|
||||
#define STM32_LSICLK 38000 /**< Low speed internal clock. */
|
||||
#define STM32_LSICLK 32000 /**< Low speed internal clock. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -204,9 +204,9 @@
|
|||
#define STM32_MCO1SEL_HSE (2 << 21) /**< HSE clock on MCO1 pin. */
|
||||
#define STM32_MCO1SEL_PLL (3 << 21) /**< PLL clock on MCO1 pin. */
|
||||
|
||||
#define STM32_I2CSRC_MASK (1 << 23) /**< I2CSRC mask. */
|
||||
#define STM32_I2CSRC_PLLI2S (0 << 23) /**< I2SSRC is PLLI2S. */
|
||||
#define STM32_I2CSRC_CKIN (1 << 23) /**< I2S_CKIN is PLLI2S. */
|
||||
#define STM32_I2SSRC_MASK (1 << 23) /**< I2CSRC mask. */
|
||||
#define STM32_I2SSRC_PLLI2S (0 << 23) /**< I2SSRC is PLLI2S. */
|
||||
#define STM32_I2SSRC_CKIN (1 << 23) /**< I2S_CKIN is PLLI2S. */
|
||||
|
||||
#define STM32_MCO1PRE_MASK (7 << 24) /**< MCO1PRE mask. */
|
||||
#define STM32_MCO1PRE_DIV1 (0 << 24) /**< MCO1 divided by 1. */
|
||||
|
@ -732,7 +732,7 @@
|
|||
* @brief I2S clock source.
|
||||
*/
|
||||
#if !defined(STM32_I2SSRC) || defined(__DOXYGEN__)
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -836,7 +836,7 @@
|
|||
#error "HSI not enabled, required by STM32_MCO2SEL"
|
||||
#endif
|
||||
|
||||
#if (STM32_I2SSRC == STM32_I2CSRC_PLLI2S) && \
|
||||
#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \
|
||||
(STM32_PLLSRC == STM32_PLLSRC_HSI)
|
||||
#error "HSI not enabled, required by STM32_I2SSRC"
|
||||
#endif
|
||||
|
@ -876,7 +876,7 @@
|
|||
#error "HSE not enabled, required by STM32_MCO2SEL"
|
||||
#endif
|
||||
|
||||
#if (STM32_I2SSRC == STM32_I2CSRC_PLLI2S) && \
|
||||
#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \
|
||||
(STM32_PLLSRC == STM32_PLLSRC_HSE)
|
||||
#error "HSE not enabled, required by STM32_I2SSRC"
|
||||
#endif
|
||||
|
@ -1126,7 +1126,7 @@
|
|||
/*
|
||||
* PLLI2S enable check.
|
||||
*/
|
||||
#if (STM32_I2CSRC == STM32_I2CSRC_PLLI2S) || defined(__DOXYGEN__)
|
||||
#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief PLL activation flag.
|
||||
*/
|
||||
|
|
|
@ -176,82 +176,34 @@
|
|||
|
||||
#include "nvic.h"
|
||||
|
||||
/* The following declarations are there just for Doxygen documentation, the
|
||||
real declarations are inside the sub-headers.*/
|
||||
#if defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief Stack and memory alignment enforcement.
|
||||
* @note In this architecture the stack alignment is enforced to 64 bits,
|
||||
* 32 bits alignment is supported by hardware but deprecated by ARM,
|
||||
* the implementation choice is to not offer the option.
|
||||
*/
|
||||
#if defined(__DOXYGEN__)
|
||||
/* Dummy declaration, for Doxygen only.*/
|
||||
typedef uint64_t stkalign_t;
|
||||
#else
|
||||
typedef uint64_t stkalign_t __attribute__ ((aligned (8)));
|
||||
#endif
|
||||
|
||||
#if defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Interrupt saved context.
|
||||
* @details This structure represents the stack frame saved during a
|
||||
* preemption-capable interrupt handler.
|
||||
* @note It is implemented to match the Cortex-Mx exception context.
|
||||
*/
|
||||
struct extctx {
|
||||
/* Dummy definition, just for Doxygen.*/
|
||||
};
|
||||
struct extctx {};
|
||||
|
||||
/**
|
||||
* @brief System saved context.
|
||||
* @details This structure represents the inner stack frame during a context
|
||||
* switching.
|
||||
*/
|
||||
struct intctx {
|
||||
/* Dummy definition, just for Doxygen.*/
|
||||
};
|
||||
#endif
|
||||
struct intctx {};
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p Thread structure.
|
||||
* @details In this port the structure just holds a pointer to the @p intctx
|
||||
* structure representing the stack pointer at context switch time.
|
||||
*/
|
||||
struct context {
|
||||
struct intctx *r13;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p chThdCreateI() API.
|
||||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p intctx structure.
|
||||
*/
|
||||
#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
|
||||
tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
|
||||
wsize - \
|
||||
sizeof(struct intctx)); \
|
||||
tp->p_ctx.r13->r4 = pf; \
|
||||
tp->p_ctx.r13->r5 = arg; \
|
||||
tp->p_ctx.r13->lr = _port_thread_start; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enforces a correct alignment for a stack area size value.
|
||||
*/
|
||||
#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
|
||||
|
||||
/**
|
||||
* @brief Computes the thread working area global size.
|
||||
*/
|
||||
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
|
||||
sizeof(struct intctx) + \
|
||||
sizeof(struct extctx) + \
|
||||
(n) + (PORT_INT_REQUIRED_STACK))
|
||||
|
||||
/**
|
||||
* @brief Static working area allocation.
|
||||
* @details This macro is used to allocate a static thread working area
|
||||
* aligned as both position and size.
|
||||
*/
|
||||
#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]
|
||||
#endif /* defined(__DOXYGEN__) */
|
||||
|
||||
#endif /* _FROM_ASM_ */
|
||||
|
||||
|
|
|
@ -41,10 +41,61 @@
|
|||
*/
|
||||
#define CORTEX_PRIORITY_PENDSV 0
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Port macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Port configurable parameters. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Stack size for the system idle thread.
|
||||
* @details This size depends on the idle thread implementation, usually
|
||||
* the idle thread should take no more space than those reserved
|
||||
* by @p PORT_INT_REQUIRED_STACK.
|
||||
* @note In this port it is set to 16 because the idle thread does have
|
||||
* a stack frame when compiling without optimizations. You may
|
||||
* reduce this value to zero when compiling with optimizations.
|
||||
*/
|
||||
#if !defined(PORT_IDLE_THREAD_STACK_SIZE)
|
||||
#define PORT_IDLE_THREAD_STACK_SIZE 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
* area size.
|
||||
* This value can be zero on those architecture where there is a
|
||||
* separate interrupt stack and the stack space between @p intctx and
|
||||
* @p extctx is known to be zero.
|
||||
* @note In this port it is conservatively set to 16 because the function
|
||||
* @p chSchDoReschedule() can have a stack frame, expecially with
|
||||
* compiler optimizations disabled.
|
||||
*/
|
||||
#if !defined(PORT_INT_REQUIRED_STACK)
|
||||
#define PORT_INT_REQUIRED_STACK 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the use of the WFI instruction in the idle thread loop.
|
||||
*/
|
||||
#if !defined(CORTEX_ENABLE_WFI_IDLE)
|
||||
#define CORTEX_ENABLE_WFI_IDLE FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SYSTICK handler priority.
|
||||
* @note The default SYSTICK handler priority is calculated as the priority
|
||||
* level in the middle of the numeric priorities range.
|
||||
*/
|
||||
#if !defined(CORTEX_PRIORITY_SYSTICK)
|
||||
#define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1)
|
||||
#elif !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
|
||||
/* If it is externally redefined then better perform a validity check on it.*/
|
||||
#error "invalid priority level specified for CORTEX_PRIORITY_SYSTICK"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Alternate preemption method.
|
||||
* @details Activating this option will make the Kernel use the PendSV
|
||||
|
@ -101,7 +152,12 @@
|
|||
*/
|
||||
typedef void *regarm_t;
|
||||
|
||||
/* The documentation of the following declarations is in chconf.h in order
|
||||
to not have duplicated structure names into the documentation.*/
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
typedef uint64_t stkalign_t __attribute__ ((aligned (8)));
|
||||
|
||||
struct extctx {
|
||||
regarm_t r0;
|
||||
regarm_t r1;
|
||||
|
@ -124,7 +180,51 @@ struct intctx {
|
|||
regarm_t r7;
|
||||
regarm_t lr;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p Thread structure.
|
||||
* @details In this port the structure just holds a pointer to the @p intctx
|
||||
* structure representing the stack pointer at context switch time.
|
||||
*/
|
||||
struct context {
|
||||
struct intctx *r13;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p chThdCreateI() API.
|
||||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p intctx structure.
|
||||
*/
|
||||
#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
|
||||
tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
|
||||
wsize - \
|
||||
sizeof(struct intctx)); \
|
||||
tp->p_ctx.r13->r4 = pf; \
|
||||
tp->p_ctx.r13->r5 = arg; \
|
||||
tp->p_ctx.r13->lr = _port_thread_start; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enforces a correct alignment for a stack area size value.
|
||||
*/
|
||||
#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
|
||||
|
||||
/**
|
||||
* @brief Computes the thread working area global size.
|
||||
*/
|
||||
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
|
||||
sizeof(struct intctx) + \
|
||||
sizeof(struct extctx) + \
|
||||
(n) + (PORT_INT_REQUIRED_STACK))
|
||||
|
||||
/**
|
||||
* @brief Static working area allocation.
|
||||
* @details This macro is used to allocate a static thread working area
|
||||
* aligned as both position and size.
|
||||
*/
|
||||
#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]
|
||||
|
||||
/**
|
||||
* @brief IRQ prologue code.
|
||||
|
|
|
@ -38,10 +38,61 @@
|
|||
*/
|
||||
#define CORTEX_BASEPRI_DISABLED 0
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Port macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Port configurable parameters. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Stack size for the system idle thread.
|
||||
* @details This size depends on the idle thread implementation, usually
|
||||
* the idle thread should take no more space than those reserved
|
||||
* by @p PORT_INT_REQUIRED_STACK.
|
||||
* @note In this port it is set to 16 because the idle thread does have
|
||||
* a stack frame when compiling without optimizations. You may
|
||||
* reduce this value to zero when compiling with optimizations.
|
||||
*/
|
||||
#if !defined(PORT_IDLE_THREAD_STACK_SIZE)
|
||||
#define PORT_IDLE_THREAD_STACK_SIZE 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
* area size.
|
||||
* This value can be zero on those architecture where there is a
|
||||
* separate interrupt stack and the stack space between @p intctx and
|
||||
* @p extctx is known to be zero.
|
||||
* @note In this port it is conservatively set to 16 because the function
|
||||
* @p chSchDoReschedule() can have a stack frame, expecially with
|
||||
* compiler optimizations disabled.
|
||||
*/
|
||||
#if !defined(PORT_INT_REQUIRED_STACK)
|
||||
#define PORT_INT_REQUIRED_STACK 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the use of the WFI instruction in the idle thread loop.
|
||||
*/
|
||||
#if !defined(CORTEX_ENABLE_WFI_IDLE)
|
||||
#define CORTEX_ENABLE_WFI_IDLE FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SYSTICK handler priority.
|
||||
* @note The default SYSTICK handler priority is calculated as the priority
|
||||
* level in the middle of the numeric priorities range.
|
||||
*/
|
||||
#if !defined(CORTEX_PRIORITY_SYSTICK)
|
||||
#define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1)
|
||||
#elif !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
|
||||
/* If it is externally redefined then better perform a validity check on it.*/
|
||||
#error "invalid priority level specified for CORTEX_PRIORITY_SYSTICK"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Simplified priority handling flag.
|
||||
* @details Activating this option will make the Kernel work in compact mode.
|
||||
|
@ -156,7 +207,12 @@
|
|||
*/
|
||||
typedef void *regarm_t;
|
||||
|
||||
/* The documentation of the following declarations is in chconf.h in order
|
||||
to not have duplicated structure names into the documentation.*/
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
typedef uint64_t stkalign_t __attribute__ ((aligned (8)));
|
||||
|
||||
struct extctx {
|
||||
regarm_t r0;
|
||||
regarm_t r1;
|
||||
|
@ -166,7 +222,7 @@ struct extctx {
|
|||
regarm_t lr_thd;
|
||||
regarm_t pc;
|
||||
regarm_t xpsr;
|
||||
#if CORTEX_USE_FPU || defined(__DOXYGEN__)
|
||||
#if CORTEX_USE_FPU
|
||||
regarm_t s0;
|
||||
regarm_t s1;
|
||||
regarm_t s2;
|
||||
|
@ -189,7 +245,7 @@ struct extctx {
|
|||
};
|
||||
|
||||
struct intctx {
|
||||
#if CORTEX_USE_FPU || defined(__DOXYGEN__)
|
||||
#if CORTEX_USE_FPU
|
||||
regarm_t s16;
|
||||
regarm_t s17;
|
||||
regarm_t s18;
|
||||
|
@ -217,7 +273,51 @@ struct intctx {
|
|||
regarm_t r11;
|
||||
regarm_t lr;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p Thread structure.
|
||||
* @details In this port the structure just holds a pointer to the @p intctx
|
||||
* structure representing the stack pointer at context switch time.
|
||||
*/
|
||||
struct context {
|
||||
struct intctx *r13;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p chThdCreateI() API.
|
||||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p intctx structure.
|
||||
*/
|
||||
#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
|
||||
tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
|
||||
wsize - \
|
||||
sizeof(struct intctx)); \
|
||||
tp->p_ctx.r13->r4 = pf; \
|
||||
tp->p_ctx.r13->r5 = arg; \
|
||||
tp->p_ctx.r13->lr = _port_thread_start; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enforces a correct alignment for a stack area size value.
|
||||
*/
|
||||
#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
|
||||
|
||||
/**
|
||||
* @brief Computes the thread working area global size.
|
||||
*/
|
||||
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
|
||||
sizeof(struct intctx) + \
|
||||
sizeof(struct extctx) + \
|
||||
(n) + (PORT_INT_REQUIRED_STACK))
|
||||
|
||||
/**
|
||||
* @brief Static working area allocation.
|
||||
* @details This macro is used to allocate a static thread working area
|
||||
* aligned as both position and size.
|
||||
*/
|
||||
#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]
|
||||
|
||||
/**
|
||||
* @brief IRQ prologue code.
|
||||
|
|
|
@ -77,9 +77,12 @@
|
|||
- FIX: Fixed PWM with TIM1 and TIM8 broken in STM32 HAL (bug 3458947).
|
||||
- FIX: Fixed SYSCFG clock not started in STM32L1/F4 HALs (bug 3449139).
|
||||
- FIX: Fixed wrong definitions in STM32L-Discovery board file (bug 3449076).
|
||||
- NEW: Updated STM32F2xx support by inheriting the work done on the STM32F4xx,
|
||||
the whole thing is untested because lack of hardware.
|
||||
- NEW: Files nvic.c and nvic.h moved under ./os/ports/common/ARMCMx, removed
|
||||
the duplicated instances under the GCC, IAR and Keil ports. Function names
|
||||
prefixes changed from "NVIC" to "nvic" because style conventions.
|
||||
- NEW: Added voltage regulator initialization to the STM32F4xx HAL.
|
||||
- NEW: Modified the STM32F4-Discovery demo to put critical kernel data
|
||||
structures and stacks in the CCM RAM instead normal RAM. It is done using
|
||||
a special .ld file that can be customized to decide how to allocate data
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
|
||||
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
|
||||
#define STM32_I2SSRC STM32_I2CSRC_CKIN
|
||||
#define STM32_I2SSRC STM32_I2SSRC_CKIN
|
||||
#define STM32_PLLI2SN_VALUE 192
|
||||
#define STM32_PLLI2SR_VALUE 5
|
||||
|
||||
|
|
25
todo.txt
25
todo.txt
|
@ -6,33 +6,31 @@ X = In progress, some work done.
|
|||
N = Decided against.
|
||||
|
||||
Current Pipeline (2.3.x):
|
||||
* Improved Makefile system.
|
||||
* USB driver enhancements.
|
||||
* USB and USB_SERIAL APIs reclassification.
|
||||
* Incorporate the USB bus attach/detach handling in usbStart()/usbStop().
|
||||
* Fix zero size packets handling in USB_SERIAL driver.
|
||||
? USB double buffering support for STM32 implementation.
|
||||
X Evaluate using DMA channels for buffer copy.
|
||||
X I2C device driver class support and at least one implementation.
|
||||
X Evaluate a modified I2C API where the synchronous mode is default and the
|
||||
callback mode optional.
|
||||
- Software I2C implementation using a GPT instance for timings.
|
||||
* STM32F2xx/STM32F4xx support (adapt and re-verify all drivers).
|
||||
* New STM32 DMA helper driver abstracting differences between
|
||||
STM32F2xx/STM32F4xx and other sub-families.
|
||||
* Specific ADC driver for STM32F2xx/STM32F4xx.
|
||||
- STM32F2xx support.
|
||||
- MMC_SPI driver revision and speedup.
|
||||
- FatFs 0.9x integration.
|
||||
- FPU support in CM4 port.
|
||||
- STM32F2xx support.
|
||||
- Nios II support.
|
||||
- LPC17xx support.
|
||||
- NUC120 support.
|
||||
- Static memory allocation hook macros in kernel code.
|
||||
? Revision of scheduling strategy for threads at equal priority.
|
||||
- MAC driver for STM32F107, STM32F2xx, STM32F4xx.
|
||||
- Update C++ wrapper.
|
||||
|
||||
Within 2.x.x
|
||||
- USB driver model revision.
|
||||
? USB double buffering support for STM32 implementation.
|
||||
X Evaluate using DMA channels for buffer copy.
|
||||
X File System infrastructure.
|
||||
X Implement the "transmission end" serial driver event on those platforms
|
||||
supporting the feature, so far only done in STM32 driver.
|
||||
- Revision of scheduling strategy for threads at equal priority.
|
||||
- Add a chSysIntegrityCheck() API.
|
||||
- Add a CH_THREAD macro for threads declaration in order to hide
|
||||
compiler-specific optimizations for thread functions. All demos will have
|
||||
to be updated.
|
||||
|
@ -40,7 +38,6 @@ X Implement the "transmission end" serial driver event on those platforms
|
|||
with different subsystems and not just the kernel.
|
||||
- Reduce number of demos globally, add demos to a repository or on web site.
|
||||
Required in order to reduce support effort.
|
||||
- MAC driver for STM32F107.
|
||||
- FatFs wrapper.
|
||||
- New device driver models: Clock, Systick, RTC, WDG, DAC, Power Monitor.
|
||||
- Add UART4 support to the STM32 UART driver (CL line only, HD has a nasty
|
||||
|
@ -59,7 +56,6 @@ X Transactional flash file system implementation.
|
|||
- Official segmented interrupts support and abstraction in CMx port.
|
||||
- MAC driver revision in order to support copy-less operations, this will
|
||||
require changes to lwIP or a new TCP/IP stack however.
|
||||
- Update C++ wrapper (Heap, Pools, Mailboxes and any new feature).
|
||||
- Threads Pools manager in the library.
|
||||
- Dedicated TCP/IP stack.
|
||||
? Evaluate if change thread functions to return void is worthwhile.
|
||||
|
@ -78,4 +74,3 @@ Ideas for 3.x.x:
|
|||
Side projects:
|
||||
X ChibiOS Wizard, UML modeling and ChibiOS applications code and
|
||||
documentation generator.
|
||||
- Visual debugger/monitor interfaced through OpenOCD.
|
||||
|
|
Loading…
Reference in New Issue