git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6273 35acf78f-673a-0410-8e92-d51de3d6d3f4

master
gdisirio 2013-09-08 08:28:27 +00:00
parent 15a54ae359
commit 5ba0abd185
38 changed files with 21828 additions and 27 deletions

View File

@ -22,7 +22,7 @@
* ST32F051x8 memory setup. * ST32F051x8 memory setup.
*/ */
__main_stack_size__ = 0x0400; __main_stack_size__ = 0x0400;
__process_stack_size__ = 0x0400; __process_stack_size__ = 0x0200;
MEMORY MEMORY
{ {

View File

@ -22,7 +22,7 @@
* ST32F303xC memory setup. * ST32F303xC memory setup.
*/ */
__main_stack_size__ = 0x0400; __main_stack_size__ = 0x0400;
__process_stack_size__ = 0x0400; __process_stack_size__ = 0x0200;
MEMORY MEMORY
{ {

View File

@ -22,7 +22,7 @@
* ST32F373xC memory setup. * ST32F373xC memory setup.
*/ */
__main_stack_size__ = 0x0400; __main_stack_size__ = 0x0400;
__process_stack_size__ = 0x0400; __process_stack_size__ = 0x0200;
MEMORY MEMORY
{ {

View File

@ -16,20 +16,13 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/ */
/* /*
* ST32F405xG memory setup. * ST32F405xG memory setup.
*/ */
__main_stack_size__ = 0x0400; __main_stack_size__ = 0x0400;
__process_stack_size__ = 0x0400; __process_stack_size__ = 0x0200;
MEMORY MEMORY
{ {

View File

@ -16,20 +16,13 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/ */
/* /*
* ST32F407xG memory setup. * ST32F407xG memory setup.
*/ */
__main_stack_size__ = 0x0400; __main_stack_size__ = 0x0400;
__process_stack_size__ = 0x0400; __process_stack_size__ = 0x0200;
MEMORY MEMORY
{ {

View File

@ -16,20 +16,13 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/ */
/* /*
* ST32F407xG memory setup. * ST32F407xG memory setup.
*/ */
__main_stack_size__ = 0x0400; __main_stack_size__ = 0x0400;
__process_stack_size__ = 0x0400; __process_stack_size__ = 0x0200;
MEMORY MEMORY
{ {

View File

@ -0,0 +1,87 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012,2013 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 STM32F37x/cmparams.h
* @brief ARM Cortex-M4 parameters for the STM32F37x.
*
* @defgroup ARMCMx_STM32F37x STM32F37x Specific Parameters
* @ingroup ARMCMx_SPECIFIC
* @details This file contains the Cortex-M4 specific parameters for the
* STM32F37x platform.
* @{
*/
#ifndef _CMPARAMS_H_
#define _CMPARAMS_H_
/**
* @brief Cortex core model.
*/
#define CORTEX_MODEL CORTEX_M4
/**
* @brief Memory Protection unit presence.
*/
#define CORTEX_HAS_MPU 1
/**
* @brief Floating Point unit presence.
*/
#define CORTEX_HAS_FPU 1
/**
* @brief Number of bits in priority masks.
*/
#define CORTEX_PRIORITY_BITS 4
/**
* @brief Number of interrupt vectors.
* @note This number does not include the 16 system vectors and must be
* rounded to a multiple of 4.
*/
#define CORTEX_NUM_VECTORS 88
/* The following code is not processed when the file is included from an
asm module.*/
#if !defined(_FROM_ASM_)
/* Including the device CMSIS header. Note, we are not using the definitions
from this header because we need this file to be usable also from
assembler source files. We verify that the info matches instead.*/
#include "stm32f37x.h"
#if !CORTEX_HAS_MPU != !__MPU_PRESENT
#error "CMSIS __MPU_PRESENT mismatch"
#endif
#if !CORTEX_HAS_FPU != !__FPU_PRESENT
#error "CMSIS __FPU_PRESENT mismatch"
#endif
#if CORTEX_PRIORITY_BITS != __NVIC_PRIO_BITS
#error "CMSIS __NVIC_PRIO_BITS mismatch"
#endif
#endif /* !defined(_FROM_ASM_) */
#endif /* _CMPARAMS_H_ */
/** @} */

5438
os/ext/CMSIS/ST/stm32f37x.h Normal file

File diff suppressed because it is too large Load Diff

6355
os/ext/CMSIS/ST/stm32l1xx.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
/**
******************************************************************************
* @file system_stm32f37x.h
* @author MCD Application Team
* @version V1.0.0
* @date 20-September-2012
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Header File.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f37x_system
* @{
*/
/**
* @brief Define to prevent recursive inclusion
*/
#ifndef __SYSTEM_STM32F37X_H
#define __SYSTEM_STM32F37X_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup STM32F37x_System_Includes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F37x_System_Exported_types
* @{
*/
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* @}
*/
/** @addtogroup STM32F37x_System_Exported_Constants
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F37x_System_Exported_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F37x_System_Exported_Functions
* @{
*/
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /*__SYSTEM_STM32F37X_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,104 @@
/**
******************************************************************************
* @file system_stm32l1xx.h
* @author MCD Application Team
* @version V1.2.0
* @date 22-February-2013
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32l1xx_system
* @{
*/
/**
* @brief Define to prevent recursive inclusion
*/
#ifndef __SYSTEM_STM32L1XX_H
#define __SYSTEM_STM32L1XX_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup STM32L1xx_System_Includes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32L1xx_System_Exported_types
* @{
*/
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* @}
*/
/** @addtogroup STM32L1xx_System_Exported_Constants
* @{
*/
/**
* @}
*/
/** @addtogroup STM32L1xx_System_Exported_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32L1xx_System_Exported_Functions
* @{
*/
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /*__SYSTEM_STM32L1XX_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,735 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32F4xx/adc_lld.c
* @brief STM32F4xx/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 SDADC_FORBIDDEN_CR1_FLAGS (SDADC_CR1_INIT | SDADC_CR1_RDMAEN | \
SDADC_CR1_RSYNC | SDADC_CR1_JSYNC | \
SDADC_CR1_ROVRIE | SDADC_CR1_REOCIE | \
SDADC_CR1_JEOCIE | SDADC_CR1_EOCALIE)
#define SDADC_ENFORCED_CR1_FLAGS (SDADC_CR1_JDMAEN | SDADC_CR1_JOVRIE)
#define SDADC_FORBIDDEN_CR2_FLAGS (SDADC_CR2_RSWSTART | \
SDADC_CR2_RCONT | \
SDADC_CR2_RCH | \
SDADC_CR2_JCONT | \
SDADC_CR2_STARTCALIB | \
SDADC_CR2_CALIBCNT)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/** @brief ADC1 driver identifier.*/
#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
ADCDriver ADCD1;
#endif
/** @brief SDADC1 driver identifier.*/
#if STM32_ADC_USE_SDADC1 || defined(__DOXYGEN__)
ADCDriver SDADCD1;
#endif
/** @brief SDADC2 driver identifier.*/
#if STM32_ADC_USE_SDADC2 || defined(__DOXYGEN__)
ADCDriver SDADCD2;
#endif
/** @brief SDADC3 driver identifier.*/
#if STM32_ADC_USE_SDADC3 || defined(__DOXYGEN__)
ADCDriver SDADCD3;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
static const ADCConfig adc_lld_default_config = {
#if STM32_ADC_USE_SDADC
0,
{
0,
0,
0
}
#else /* !STM32_ADC_USE_SDADC */
0
#endif /* !STM32_ADC_USE_SDADC */
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Stops, reconfigures and restarts an ADC/SDADC.
*
* @param[in] adcp pointer to the @p ADCDriver object
*/
static void adc_lld_reconfig(ADCDriver *adcp) {
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
if (adcp->adc != NULL)
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_ADC
{
/* ADC initial setup, starting the analog part here in order to reduce
the latency when starting a conversion.*/
uint32_t cr2 = adcp->adc->CR2 & ADC_CR2_TSVREFE;
adcp->adc->CR2 = cr2;
adcp->adc->CR1 = 0;
adcp->adc->CR2 = cr2 | ADC_CR2_ADON;
}
#endif /* STM32_ADC_USE_ADC */
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
else if (adcp->sdadc != NULL)
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_SDADC
{
/* SDADC initial setup, starting the analog part here in order to reduce
the latency when starting a conversion.*/
adcp->sdadc->CR2 = 0;
adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
~SDADC_FORBIDDEN_CR1_FLAGS;
adcp->sdadc->CONF0R = (adcp->sdadc->CONF0R & SDADC_CONFR_OFFSET_MASK) |
adcp->config->confxr[0];
adcp->sdadc->CONF1R = (adcp->sdadc->CONF1R & SDADC_CONFR_OFFSET_MASK) |
adcp->config->confxr[1];
adcp->sdadc->CONF2R = (adcp->sdadc->CONF2R & SDADC_CONFR_OFFSET_MASK) |
adcp->config->confxr[2];
adcp->sdadc->CR2 = SDADC_CR2_ADON;
}
#endif /* STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
else {
chDbgAssert(FALSE, "adc_lld_start(), #5", "invalid state");
}
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
}
/**
* @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
*
* @notapi
*/
static void adc_lld_serve_dma_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);
}
}
}
}
#if STM32_ADC_USE_ADC || defined(__DOXYGEN__)
/**
* @brief ADC ISR service routine.
*
* @param[in] adcp pointer to the @p ADCDriver object
* @param[in] sr content of the ISR register
*
* @notapi
*/
static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t sr) {
/* It could be a spurious interrupt caused by overflows after DMA disabling,
just ignore it in this case.*/
if (adcp->grpp != NULL) {
if (sr & ADC_SR_AWD) {
/* Analog watchdog error.*/
_adc_isr_error_code(adcp, ADC_ERR_AWD1);
}
}
}
#endif /* STM32_ADC_USE_ADC */
#if STM32_ADC_USE_SDADC || defined(__DOXYGEN__)
/**
* @brief ADC ISR service routine.
*
* @param[in] adcp pointer to the @p ADCDriver object
* @param[in] isr content of the ISR register
*
* @notapi
*/
static void sdadc_lld_serve_interrupt(ADCDriver *adcp, uint32_t isr) {
/* It could be a spurious interrupt caused by overflows after DMA disabling,
just ignore it in this case.*/
if (adcp->grpp != NULL) {
/* 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 ((isr & SDADC_ISR_JOVRF) &&
(dmaStreamGetTransactionSize(adcp->dmastp) > 0)) {
/* ADC overflow condition, this could happen only if the DMA is unable
to read data fast enough.*/
_adc_isr_error_code(adcp, ADC_ERR_OVERFLOW);
}
}
}
#endif /* STM32_ADC_USE_SDADC */
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
/**
* @brief ADC1 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector88) {
uint32_t sr;
CH_IRQ_PROLOGUE();
sr = ADC1->SR;
ADC1->SR = 0;
adc_lld_serve_interrupt(&ADCD1, sr);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_ADC_USE_ADC1 */
#if STM32_ADC_USE_SDADC1 || defined(__DOXYGEN__)
/**
* @brief SDADC1 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector134) {
uint32_t isr;
CH_IRQ_PROLOGUE();
isr = SDADC1->ISR;
SDADC1->CLRISR = isr;
sdadc_lld_serve_interrupt(&SDADCD1, isr);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_ADC_USE_SDADC1 */
#if STM32_ADC_USE_SDADC2 || defined(__DOXYGEN__)
/**
* @brief SDADC2 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector138) {
uint32_t isr;
CH_IRQ_PROLOGUE();
isr = SDADC2->ISR;
SDADC2->CLRISR = isr;
sdadc_lld_serve_interrupt(&SDADCD2, isr);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_ADC_USE_SDADC2 */
#if STM32_ADC_USE_SDADC3 || defined(__DOXYGEN__)
/**
* @brief SDADC3 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector13C) {
uint32_t isr;
CH_IRQ_PROLOGUE();
isr = SDADC3->ISR;
SDADC3->CLRISR = isr;
sdadc_lld_serve_interrupt(&SDADCD3, isr);
CH_IRQ_EPILOGUE();
}
#endif /* STM32_ADC_USE_SDADC3 */
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level ADC driver initialization.
*
* @notapi
*/
void adc_lld_init(void) {
#if STM32_ADC_USE_ADC1
/* Driver initialization.*/
adcObjectInit(&ADCD1);
ADCD1.adc = ADC1;
#if STM32_ADC_USE_SDADC
ADCD1.sdadc = NULL;
#endif
ADCD1.dmastp = STM32_DMA1_STREAM1;
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;
nvicEnableVector(ADC1_IRQn, CORTEX_PRIORITY_MASK(STM32_ADC_IRQ_PRIORITY));
#endif
#if STM32_ADC_USE_SDADC1
/* Driver initialization.*/
adcObjectInit(&SDADCD1);
#if STM32_ADC_USE_ADC
SDADCD1.adc = NULL;
#endif
SDADCD1.sdadc = SDADC1;
SDADCD1.dmastp = STM32_DMA2_STREAM3;
SDADCD1.dmamode = STM32_DMA_CR_CHSEL(SDADC1_DMA_CHANNEL) |
STM32_DMA_CR_PL(STM32_ADC_SDADC1_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;
nvicEnableVector(SDADC1_IRQn,
CORTEX_PRIORITY_MASK(STM32_ADC_SDADC1_IRQ_PRIORITY));
#endif
#if STM32_ADC_USE_SDADC2
/* Driver initialization.*/
adcObjectInit(&SDADCD2);
#if STM32_ADC_USE_ADC
SDADCD2.adc = NULL;
#endif
SDADCD2.sdadc = SDADC2;
SDADCD2.dmastp = STM32_DMA2_STREAM4;
SDADCD2.dmamode = STM32_DMA_CR_CHSEL(SDADC2_DMA_CHANNEL) |
STM32_DMA_CR_PL(STM32_ADC_SDADC2_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;
nvicEnableVector(SDADC2_IRQn,
CORTEX_PRIORITY_MASK(STM32_ADC_SDADC2_IRQ_PRIORITY));
#endif
#if STM32_ADC_USE_SDADC3
/* Driver initialization.*/
adcObjectInit(&SDADCD3);
#if STM32_ADC_USE_ADC
SDADCD3.adc = NULL;
#endif
SDADCD3.sdadc = SDADC3;
SDADCD3.dmastp = STM32_DMA2_STREAM5;
SDADCD3.dmamode = STM32_DMA_CR_CHSEL(SDADC3_DMA_CHANNEL) |
STM32_DMA_CR_PL(STM32_ADC_SDADC3_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;
nvicEnableVector(SDADC3_IRQn,
CORTEX_PRIORITY_MASK(STM32_ADC_SDADC3_IRQ_PRIORITY));
#endif
}
/**
* @brief Configures and activates the ADC peripheral.
*
* @param[in] adcp pointer to the @p ADCDriver object
*
* @notapi
*/
void adc_lld_start(ADCDriver *adcp) {
if (adcp->config == NULL)
adcp->config = &adc_lld_default_config;
/* 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_dma_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_SDADC1
if (&SDADCD1 == adcp) {
bool_t b = dmaStreamAllocate(adcp->dmastp,
STM32_ADC_SDADC1_DMA_IRQ_PRIORITY,
(stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
(void *)adcp);
chDbgAssert(!b, "adc_lld_start(), #2", "stream already allocated");
dmaStreamSetPeripheral(adcp->dmastp, &SDADC1->JDATAR);
rccEnableSDADC1(FALSE);
PWR->CR |= PWR_CR_SDADC1EN;
adcp->sdadc->CR2 = 0;
adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
~SDADC_FORBIDDEN_CR1_FLAGS;
adcp->sdadc->CR2 = SDADC_CR2_ADON;
}
#endif /* STM32_ADC_USE_SDADC1 */
#if STM32_ADC_USE_SDADC2
if (&SDADCD2 == adcp) {
bool_t b = dmaStreamAllocate(adcp->dmastp,
STM32_ADC_SDADC2_DMA_IRQ_PRIORITY,
(stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
(void *)adcp);
chDbgAssert(!b, "adc_lld_start(), #3", "stream already allocated");
dmaStreamSetPeripheral(adcp->dmastp, &SDADC2->JDATAR);
rccEnableSDADC1(FALSE);
PWR->CR |= PWR_CR_SDADC2EN;
adcp->sdadc->CR2 = 0;
adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
~SDADC_FORBIDDEN_CR1_FLAGS;
adcp->sdadc->CR2 = SDADC_CR2_ADON;
}
#endif /* STM32_ADC_USE_SDADC2 */
#if STM32_ADC_USE_SDADC3
if (&SDADCD3 == adcp) {
bool_t b = dmaStreamAllocate(adcp->dmastp,
STM32_ADC_SDADC3_DMA_IRQ_PRIORITY,
(stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
(void *)adcp);
chDbgAssert(!b, "adc_lld_start(), #4", "stream already allocated");
dmaStreamSetPeripheral(adcp->dmastp, &SDADC3->JDATAR);
rccEnableSDADC1(FALSE);
PWR->CR |= PWR_CR_SDADC3EN;
adcp->sdadc->CR2 = 0;
adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
~SDADC_FORBIDDEN_CR1_FLAGS;
adcp->sdadc->CR2 = SDADC_CR2_ADON;
}
#endif /* STM32_ADC_USE_SDADC3 */
}
adc_lld_reconfig(adcp);
}
/**
* @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);
#if STM32_ADC_USE_ADC1
if (&ADCD1 == adcp) {
adcp->adc->CR1 = 0;
adcp->adc->CR2 = 0;
rccDisableADC1(FALSE);
}
#endif
#if STM32_ADC_USE_SDADC1
if (&SDADCD1 == adcp) {
adcp->sdadc->CR1 = 0;
adcp->sdadc->CR2 = 0;
rccDisableSDADC1(FALSE);
PWR->CR &= ~PWR_CR_SDADC1EN;
}
#endif
#if STM32_ADC_USE_SDADC2
if (&SDADCD2 == adcp) {
adcp->sdadc->CR1 = 0;
adcp->sdadc->CR2 = 0;
rccDisableSDADC2(FALSE);
PWR->CR &= ~PWR_CR_SDADC2EN;
}
#endif
#if STM32_ADC_USE_SDADC3
if (&SDADCD3 == adcp) {
adcp->sdadc->CR1 = 0;
adcp->sdadc->CR2 = 0;
rccDisableSDADC3(FALSE);
PWR->CR &= ~PWR_CR_SDADC3EN;
}
#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);
dmaStreamEnable(adcp->dmastp);
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
if (adcp->adc != NULL)
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_ADC
{
uint32_t cr2 = adcp->adc->CR2 & ADC_CR2_TSVREFE;
cr2 |= grpp->u.adc.cr2 | ADC_CR2_DMA | ADC_CR2_ADON;
if ((cr2 & ADC_CR2_SWSTART) != 0)
cr2 |= ADC_CR2_CONT;
adcp->adc->CR2 = cr2;
/* ADC setup.*/
adcp->adc->SR = 0;
adcp->adc->LTR = grpp->u.adc.ltr;
adcp->adc->HTR = grpp->u.adc.htr;
adcp->adc->SMPR1 = grpp->u.adc.smpr[0];
adcp->adc->SMPR2 = grpp->u.adc.smpr[1];
adcp->adc->SQR1 = grpp->u.adc.sqr[0] |
ADC_SQR1_NUM_CH(grpp->num_channels);
adcp->adc->SQR2 = grpp->u.adc.sqr[1];
adcp->adc->SQR3 = grpp->u.adc.sqr[2];
/* ADC conversion start, the start is performed using the method
specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/
adcp->adc->CR1 = grpp->u.adc.cr1 | ADC_CR1_AWDIE | ADC_CR1_SCAN;
adcp->adc->CR2 = adcp->adc->CR2; /* Triggers the conversion start.*/
}
#endif /* STM32_ADC_USE_ADC */
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
else if (adcp->sdadc != NULL)
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_SDADC
{
uint32_t cr2 = (grpp->u.sdadc.cr2 & ~SDADC_FORBIDDEN_CR2_FLAGS) |
SDADC_CR2_ADON;
if ((grpp->u.sdadc.cr2 & SDADC_CR2_JSWSTART) != 0)
cr2 |= SDADC_CR2_JCONT;
/* Entering initialization mode.*/
adcp->sdadc->CR1 |= SDADC_CR1_INIT;
while ((adcp->sdadc->ISR & SDADC_ISR_INITRDY) == 0)
;
/* SDADC setup.*/
adcp->sdadc->JCHGR = grpp->u.sdadc.jchgr;
adcp->sdadc->CONFCHR1 = grpp->u.sdadc.confchr[0];
adcp->sdadc->CONFCHR2 = grpp->u.sdadc.confchr[1];
/* Leaving initialization mode.*/
adcp->sdadc->CR1 &= ~SDADC_CR1_INIT;
/* SDADC conversion start, the start is performed using the method
specified in the CR2 configuration, usually SDADC_CR2_JSWSTART.*/
adcp->sdadc->CR2 = cr2;
}
#endif /* STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
else {
chDbgAssert(FALSE, "adc_lld_start_conversion(), #1", "invalid state");
}
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
}
/**
* @brief Stops an ongoing conversion.
*
* @param[in] adcp pointer to the @p ADCDriver object
*
* @notapi
*/
void adc_lld_stop_conversion(ADCDriver *adcp) {
/* Disabling the associated DMA stream.*/
dmaStreamDisable(adcp->dmastp);
/* Stopping and restarting the whole ADC, apparently the only way to stop
a conversion.*/
adc_lld_reconfig(adcp);
}
/**
* @brief Calibrates an ADC unit.
* @note The calibration must be performed after calling @p adcStart().
* @note For SDADC units it is assumed that the field SDADC_CR2_CALIBCNT
* has been
*
* @param[in] adcp pointer to the @p ADCDriver object
*
* @api
*/
void adcSTM32Calibrate(ADCDriver *adcp) {
chDbgAssert((adcp->state == ADC_READY) ||
(adcp->state == ADC_COMPLETE) ||
(adcp->state == ADC_ERROR),
"adcSTM32Calibrate(), #1", "not ready");
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
if (adcp->adc != NULL)
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_ADC
{
/* Resetting calibration just to be safe.*/
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
;
/* Calibration.*/
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
;
}
#endif /* STM32_ADC_USE_ADC */
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
else if (adcp->sdadc != NULL)
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_SDADC
{
/* Selecting a full calibration in three steps.*/
adcp->sdadc->CR2 = (adcp->sdadc->CR2 & ~SDADC_CR2_CALIBCNT) |
SDADC_CR2_CALIBCNT_1;
/* Calibration.*/
adcp->sdadc->CR2 |= SDADC_CR2_STARTCALIB;
while ((adcp->sdadc->ISR & SDADC_ISR_EOCALF) == 0)
;
/* Clearing the EOCALF flag.*/
adcp->sdadc->CLRISR |= SDADC_ISR_CLREOCALF;
}
#endif /* STM32_ADC_USE_SDADC */
#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
else {
chDbgAssert(FALSE, "adcSTM32Calibrate(), #2", "invalid state");
}
#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
}
#if STM32_ADC_USE_ADC || defined(__DOXYGEN__)
/**
* @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.
*
* @api
*/
void adcSTM32EnableTSVREFE(void) {
ADC1->CR2 |= ADC_CR2_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.
*
* @api
*/
void adcSTM32DisableTSVREFE(void) {
ADC1->CR2 &= ~ADC_CR2_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.
*
* @api
*/
void adcSTM32EnableVBATE(void) {
SYSCFG->CFGR1 |= SYSCFG_CFGR1_VBAT;
}
/**
* @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.
*
* @api
*/
void adcSTM32DisableVBATE(void) {
SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_VBAT;
}
#endif /* STM32_ADC_USE_ADC */
#endif /* HAL_USE_ADC */
/** @} */

View File

@ -0,0 +1,711 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32F37x/adc_lld.h
* @brief STM32F37x 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 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.*/
#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
#define ADC_CHANNEL_VBAT 18 /**< @brief VBAT. */
/** @} */
/**
* @name Sampling rates
* @{
*/
#define ADC_SAMPLE_1P5 0 /**< @brief 1.5 cycles sampling time. */
#define ADC_SAMPLE_7P5 1 /**< @brief 7.5 cycles sampling time. */
#define ADC_SAMPLE_13P5 2 /**< @brief 13.5 cycles sampling time. */
#define ADC_SAMPLE_28P5 3 /**< @brief 28.5 cycles sampling time. */
#define ADC_SAMPLE_41P5 4 /**< @brief 41.5 cycles sampling time. */
#define ADC_SAMPLE_55P5 5 /**< @brief 55.5 cycles sampling time. */
#define ADC_SAMPLE_71P5 6 /**< @brief 71.5 cycles sampling time. */
#define ADC_SAMPLE_239P5 7 /**< @brief 239.5 cycles sampling time. */
/** @} */
/**
* @name SDADC JCHGR bit definitions
* @{
*/
#define SDADC_JCHG_MASK (511U << 0)
#define SDADC_JCHG(n) (1U << (n))
/** @} */
/**
* @name SDADC channels definitions
* @{
*/
#define SDADC_CHANNEL_0 SDADC_JCHG(0)
#define SDADC_CHANNEL_1 SDADC_JCHG(1)
#define SDADC_CHANNEL_2 SDADC_JCHG(2)
#define SDADC_CHANNEL_3 SDADC_JCHG(3)
#define SDADC_CHANNEL_4 SDADC_JCHG(4)
#define SDADC_CHANNEL_5 SDADC_JCHG(5)
#define SDADC_CHANNEL_6 SDADC_JCHG(6)
#define SDADC_CHANNEL_7 SDADC_JCHG(7)
#define SDADC_CHANNEL_8 SDADC_JCHG(8)
#define SDADC_CHANNEL_9 SDADC_JCHG(9)
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief ADC1 driver enable switch.
* @details If set to @p TRUE the support for ADC1 is included.
*/
#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
#define STM32_ADC_USE_ADC1 FALSE
#endif
/**
* @brief SDADC1 driver enable switch.
* @details If set to @p TRUE the support for SDADC1 is included.
*/
#if !defined(STM32_ADC_USE_SDADC1) || defined(__DOXYGEN__)
#define STM32_ADC_USE_SDADC1 FALSE
#endif
/**
* @brief SDADC2 driver enable switch.
* @details If set to @p TRUE the support for SDADC2 is included.
*/
#if !defined(STM32_ADC_USE_SDADC2) || defined(__DOXYGEN__)
#define STM32_ADC_USE_SDADC2 FALSE
#endif
/**
* @brief SDADC3 driver enable switch.
* @details If set to @p TRUE the support for SDADC3 is included.
*/
#if !defined(STM32_ADC_USE_SDADC3) || defined(__DOXYGEN__)
#define STM32_ADC_USE_SDADC3 FALSE
#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 SDADC1 DMA priority (0..3|lowest..highest).
*/
#if !defined(STM32_ADC_SDADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_SDADC1_DMA_PRIORITY 2
#endif
/**
* @brief SDADC2 DMA priority (0..3|lowest..highest).
*/
#if !defined(STM32_ADC_SDADC2_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_SDADC2_DMA_PRIORITY 2
#endif
/**
* @brief SDADC3 DMA priority (0..3|lowest..highest).
*/
#if !defined(STM32_ADC_SDADC3_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_SDADC3_DMA_PRIORITY 2
#endif
/**
* @brief ADC interrupt priority level setting.
*/
#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
#endif
/**
* @brief ADC 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 SDADC1 interrupt priority level setting.
*/
#if !defined(STM32_ADC_SDADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_SDADC1_IRQ_PRIORITY 5
#endif
/**
* @brief SDADC2 interrupt priority level setting.
*/
#if !defined(STM32_ADC_SDADC2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_SDADC2_IRQ_PRIORITY 5
#endif
/**
* @brief SDADC3 interrupt priority level setting.
*/
#if !defined(STM32_ADC_SDADC3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_SDADC3_IRQ_PRIORITY 5
#endif
/**
* @brief SDADC1 DMA interrupt priority level setting.
*/
#if !defined(STM32_ADC_SDADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_SDADC1_DMA_IRQ_PRIORITY 5
#endif
/**
* @brief SDADC2 DMA interrupt priority level setting.
*/
#if !defined(STM32_ADC_SDADC2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_SDADC2_DMA_IRQ_PRIORITY 5
#endif
/**
* @brief SDADC3 DMA interrupt priority level setting.
*/
#if !defined(STM32_ADC_SDADC3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC_SDADC3_DMA_IRQ_PRIORITY 5
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/**
* @brief At least an ADC unit is in use.
*/
#define STM32_ADC_USE_ADC STM32_ADC_USE_ADC1
/**
* @brief At least an SDADC unit is in use.
*/
#define STM32_ADC_USE_SDADC (STM32_ADC_USE_SDADC1 || \
STM32_ADC_USE_SDADC2 || \
STM32_ADC_USE_SDADC3)
#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
#error "ADC1 not present in the selected device"
#endif
#if STM32_ADC_USE_SDADC1 && !STM32_HAS_SDADC1
#error "SDADC1 not present in the selected device"
#endif
#if STM32_ADC_USE_SDADC2 && !STM32_HAS_SDADC2
#error "SDADC2 not present in the selected device"
#endif
#if STM32_ADC_USE_SDADC3 && !STM32_HAS_SDADC3
#error "SDADC3 not present in the selected device"
#endif
#if !STM32_ADC_USE_ADC && !STM32_ADC_USE_SDADC
#error "ADC driver activated but no ADC/SDADC peripheral assigned"
#endif
#if STM32_ADC_USE_ADC1 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ADC_ADC1_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to ADC1"
#endif
#if STM32_ADC_USE_ADC1 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to ADC1 DMA"
#endif
#if STM32_ADC_USE_ADC1 && \
!STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
#error "Invalid DMA priority assigned to ADC1"
#endif
#if STM32_ADC_USE_SDADC1 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ADC_SDADC1_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SDADC1"
#endif
#if STM32_ADC_USE_SDADC1 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ADC_SDADC1_DMA_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SDADC1 DMA"
#endif
#if STM32_ADC_USE_SDADC1 && \
!STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_SDADC1_DMA_PRIORITY)
#error "Invalid DMA priority assigned to SDADC1"
#endif
#if STM32_ADC_USE_SDADC2 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ADC_SDADC2_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SDADC2"
#endif
#if STM32_ADC_USE_SDADC2 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ADC_SDADC2_DMA_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SDADC2 DMA"
#endif
#if STM32_ADC_USE_SDADC2 && \
!STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_SDADC2_DMA_PRIORITY)
#error "Invalid DMA priority assigned to SDADC2"
#endif
#if STM32_ADC_USE_SDADC3 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ADC_SDADC3_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SDADC3"
#endif
#if STM32_ADC_USE_SDADC3 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ADC_SDADC3_DMA_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to SDADC3 DMA"
#endif
#if STM32_ADC_USE_SDADC3 && \
!STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_SDADC3_DMA_PRIORITY)
#error "Invalid DMA priority assigned to SDADC3"
#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. */
ADC_ERR_AWD1 = 2 /**< Watchdog 1 triggered. */
} 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
* @param[in] err ADC error code
*/
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 Union of ADC and SDADC config parms. The decision of which struct
* union to use is determined by the ADCDriver. If the ADCDriver adc parm
* is not NULL, then use the adc struct, otherwise if the ADCDriver sdadc parm
* is not NULL, then use the sdadc struct.
*/
union {
#if STM32_ADC_USE_ADC || defined(__DOXYGEN__)
struct {
/**
* @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 LTR register initialization data.
*/
uint32_t ltr;
/**
* @brief ADC HTR register initialization data.
*/
uint32_t htr;
/**
* @brief ADC SMPRx registers initialization data.
*/
uint32_t smpr[2];
/**
* @brief ADC SQRx register initialization data.
*/
uint32_t sqr[3];
} adc;
#endif /* STM32_ADC_USE_ADC */
#if STM32_ADC_USE_SDADC || defined(__DOXYGEN__)
struct {
/**
* @brief SDADC CR2 register initialization data.
* @note Only the @p SDADC_CR2_JSWSTART, @p SDADC_CR2_JEXTSEL
* and @p SDADC_CR2_JEXTEN can be specified in this field.
*/
uint32_t cr2;
/**
* @brief SDADC JCHGR register initialization data.
*/
uint32_t jchgr;
/**
* @brief SDADC CONFCHxR registers initialization data.
*/
uint32_t confchr[2];
} sdadc;
#endif /* STM32_ADC_USE_SDADC */
} u;
} ADCConversionGroup;
/**
* @brief Driver configuration structure.
* @note It could be empty on some architectures.
*/
typedef struct {
#if STM32_ADC_USE_SDADC
/**
* @brief SDADC CR1 register initialization data.
*/
uint32_t cr1;
/**
* @brief SDADC CONFxR registers initialization data.
*/
uint32_t confxr[3];
#else /* !STM32_ADC_USE_SDADC */
uint32_t dummy;
#endif /* !STM32_ADC_USE_SDADC */
} 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.*/
#if STM32_ADC_USE_ADC || defined(__DOXYGEN__)
/**
* @brief Pointer to the ADCx registers block.
*/
ADC_TypeDef *adc;
#endif
#if STM32_ADC_USE_SDADC || defined(__DOXYGEN__)
/**
* @brief Pointer to the SDADCx registers block.
*/
SDADC_TypeDef *sdadc;
#endif
/**
* @brief Pointer to associated DMA channel.
*/
const stm32_dma_stream_t *dmastp;
/**
* @brief DMA mode bit mask.
*/
uint32_t dmamode;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @name Sequences building helper macros for ADC
* @{
*/
/**
* @brief Number of channels in a conversion sequence.
*/
#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
#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.*/
#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_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. */
/** @} */
/**
* @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. */
/** @} */
/**
* @name Sequences building helper macros for SDADC
* @{
*/
#define SDADC_JCHGR_CH(n) (1U << (n))
/** @} */
/**
* @name Channel configuration number helper macros for SDADC
* @{
*/
#define SDADC_CONFCHR1_CH0(n) ((n) << 0)
#define SDADC_CONFCHR1_CH1(n) ((n) << 4)
#define SDADC_CONFCHR1_CH2(n) ((n) << 8)
#define SDADC_CONFCHR1_CH3(n) ((n) << 12)
#define SDADC_CONFCHR1_CH4(n) ((n) << 16)
#define SDADC_CONFCHR1_CH5(n) ((n) << 20)
#define SDADC_CONFCHR1_CH6(n) ((n) << 24)
#define SDADC_CONFCHR1_CH7(n) ((n) << 28)
#define SDADC_CONFCHR2_CH8(n) ((n) << 0)
/** @} */
/**
* @name Configuration registers helper macros for SDADC
* @{
*/
#define SDADC_CONFR_OFFSET_MASK (0xFFFU << 0)
#define SDADC_CONFR_OFFSET(n) ((n) << 0)
#define SDADC_CONFR_GAIN_MASK (7U << 20)
#define SDADC_CONFR_GAIN_1X (0U << 20)
#define SDADC_CONFR_GAIN_2X (1U << 20)
#define SDADC_CONFR_GAIN_4X (2U << 20)
#define SDADC_CONFR_GAIN_8X (3U << 20)
#define SDADC_CONFR_GAIN_16X (4U << 20)
#define SDADC_CONFR_GAIN_32X (5U << 20)
#define SDADC_CONFR_GAIN_0P5X (7U << 20)
#define SDADC_CONFR_SE_MASK (3U << 26)
#define SDADC_CONFR_SE_DIFF (0U << 26)
#define SDADC_CONFR_SE_OFFSET (1U << 26)
#define SDADC_CONFR_SE_ZERO_VOLT (3U << 26)
#define SDADC_CONFR_COMMON_MASK (3U << 30)
#define SDADC_CONFR_COMMON_VSSSD (0U << 30)
#define SDADC_CONFR_COMMON_VDDSD2 (1U << 30)
#define SDADC_CONFR_COMMON_VDDSD (2U << 30)
/** @} */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
extern ADCDriver ADCD1;
#endif
#if STM32_ADC_USE_SDADC1 && !defined(__DOXYGEN__)
extern ADCDriver SDADCD1;
#endif
#if STM32_ADC_USE_SDADC2 && !defined(__DOXYGEN__)
extern ADCDriver SDADCD2;
#endif
#if STM32_ADC_USE_SDADC3 && !defined(__DOXYGEN__)
extern ADCDriver SDADCD3;
#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 adcSTM32Calibrate(ADCDriver *adcdp);
#if STM32_ADC_USE_ADC
void adcSTM32EnableTSVREFE(void);
void adcSTM32DisableTSVREFE(void);
void adcSTM32EnableVBATE(void);
void adcSTM32DisableVBATE(void);
#endif /* STM32_ADC_USE_ADC */
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_ADC */
#endif /* _ADC_LLD_H_ */
/** @} */

View File

@ -0,0 +1,366 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32F37x/ext_lld_isr.c
* @brief STM32F37x EXT subsystem low level driver ISR code.
*
* @addtogroup EXT
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_EXT || defined(__DOXYGEN__)
#include "ext_lld_isr.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if !defined(STM32_DISABLE_EXTI0_HANDLER)
/**
* @brief EXTI[0] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector58) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 0);
EXTD1.config->channels[0].cb(&EXTD1, 0);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI1_HANDLER)
/**
* @brief EXTI[1] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector5C) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 1);
EXTD1.config->channels[1].cb(&EXTD1, 1);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI2_HANDLER)
/**
* @brief EXTI[2] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector60) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 2);
EXTD1.config->channels[2].cb(&EXTD1, 2);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI3_HANDLER)
/**
* @brief EXTI[3] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector64) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 3);
EXTD1.config->channels[3].cb(&EXTD1, 3);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI4_HANDLER)
/**
* @brief EXTI[4] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector68) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 4);
EXTD1.config->channels[4].cb(&EXTD1, 4);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI5_9_HANDLER)
/**
* @brief EXTI[5]...EXTI[9] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector9C) {
uint32_t pr;
CH_IRQ_PROLOGUE();
pr = EXTI->PR & ((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9));
EXTI->PR = pr;
if (pr & (1 << 5))
EXTD1.config->channels[5].cb(&EXTD1, 5);
if (pr & (1 << 6))
EXTD1.config->channels[6].cb(&EXTD1, 6);
if (pr & (1 << 7))
EXTD1.config->channels[7].cb(&EXTD1, 7);
if (pr & (1 << 8))
EXTD1.config->channels[8].cb(&EXTD1, 8);
if (pr & (1 << 9))
EXTD1.config->channels[9].cb(&EXTD1, 9);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI10_15_HANDLER)
/**
* @brief EXTI[10]...EXTI[15] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(VectorE0) {
uint32_t pr;
CH_IRQ_PROLOGUE();
pr = EXTI->PR & ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | (1 << 14) |
(1 << 15));
EXTI->PR = pr;
if (pr & (1 << 10))
EXTD1.config->channels[10].cb(&EXTD1, 10);
if (pr & (1 << 11))
EXTD1.config->channels[11].cb(&EXTD1, 11);
if (pr & (1 << 12))
EXTD1.config->channels[12].cb(&EXTD1, 12);
if (pr & (1 << 13))
EXTD1.config->channels[13].cb(&EXTD1, 13);
if (pr & (1 << 14))
EXTD1.config->channels[14].cb(&EXTD1, 14);
if (pr & (1 << 15))
EXTD1.config->channels[15].cb(&EXTD1, 15);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI16_HANDLER)
/**
* @brief EXTI[16] interrupt handler (PVD).
*
* @isr
*/
CH_IRQ_HANDLER(Vector44) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 16);
EXTD1.config->channels[16].cb(&EXTD1, 16);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI17_HANDLER)
/**
* @brief EXTI[17] interrupt handler (RTC Alarm).
*
* @isr
*/
CH_IRQ_HANDLER(VectorE4) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 17);
EXTD1.config->channels[17].cb(&EXTD1, 17);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI18_HANDLER)
/**
* @brief EXTI[18] interrupt handler (USB Wakeup).
*
* @isr
*/
CH_IRQ_HANDLER(VectorE8) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 18);
EXTD1.config->channels[18].cb(&EXTD1, 18);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI19_HANDLER)
/**
* @brief EXTI[19] interrupt handler (Tamper TimeStamp).
*
* @isr
*/
CH_IRQ_HANDLER(Vector48) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 19);
EXTD1.config->channels[19].cb(&EXTD1, 19);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI20_HANDLER)
/**
* @brief EXTI[20] interrupt handler (RTC Wakeup).
*
* @isr
*/
CH_IRQ_HANDLER(Vector4C) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 20);
EXTD1.config->channels[20].cb(&EXTD1, 20);
CH_IRQ_EPILOGUE();
}
#endif
#if !defined(STM32_DISABLE_EXTI21_22_HANDLER)
/**
* @brief EXTI[21]..EXTI[22] interrupt handler (COMP1, COMP2).
*
* @isr
*/
CH_IRQ_HANDLER(Vector140) {
uint32_t pr;
CH_IRQ_PROLOGUE();
pr = EXTI->PR & ((1 << 21) | (1 << 22));
EXTI->PR = pr;
if (pr & (1 << 21))
EXTD1.config->channels[21].cb(&EXTD1, 21);
if (pr & (1 << 22))
EXTD1.config->channels[22].cb(&EXTD1, 22);
CH_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Enables EXTI IRQ sources.
*
* @notapi
*/
void ext_lld_exti_irq_enable(void) {
nvicEnableVector(EXTI0_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI0_IRQ_PRIORITY));
nvicEnableVector(EXTI1_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI1_IRQ_PRIORITY));
nvicEnableVector(EXTI2_TS_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI2_IRQ_PRIORITY));
nvicEnableVector(EXTI3_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI3_IRQ_PRIORITY));
nvicEnableVector(EXTI4_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI4_IRQ_PRIORITY));
nvicEnableVector(EXTI9_5_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI5_9_IRQ_PRIORITY));
nvicEnableVector(EXTI15_10_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI10_15_IRQ_PRIORITY));
nvicEnableVector(PVD_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI16_IRQ_PRIORITY));
nvicEnableVector(RTC_Alarm_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI17_IRQ_PRIORITY));
nvicEnableVector(USBWakeUp_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY));
nvicEnableVector(TAMPER_STAMP_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI19_IRQ_PRIORITY));
nvicEnableVector(RTC_WKUP_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI20_IRQ_PRIORITY));
nvicEnableVector(COMP_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI21_22_IRQ_PRIORITY));
}
/**
* @brief Disables EXTI IRQ sources.
*
* @notapi
*/
void ext_lld_exti_irq_disable(void) {
nvicDisableVector(EXTI0_IRQn);
nvicDisableVector(EXTI1_IRQn);
nvicDisableVector(EXTI2_TS_IRQn);
nvicDisableVector(EXTI3_IRQn);
nvicDisableVector(EXTI4_IRQn);
nvicDisableVector(EXTI9_5_IRQn);
nvicDisableVector(EXTI15_10_IRQn);
nvicDisableVector(PVD_IRQn);
nvicDisableVector(RTC_Alarm_IRQn);
nvicDisableVector(USBWakeUp_IRQn);
nvicDisableVector(TAMPER_STAMP_IRQn);
nvicDisableVector(RTC_WKUP_IRQn);
nvicDisableVector(COMP_IRQn);
}
#endif /* HAL_USE_EXT */
/** @} */

View File

@ -0,0 +1,163 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32F37x/ext_lld_isr.h
* @brief STM32F37x EXT subsystem low level driver ISR header.
*
* @addtogroup EXT
* @{
*/
#ifndef _EXT_LLD_ISR_H_
#define _EXT_LLD_ISR_H_
#if HAL_USE_EXT || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief EXTI0 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI0_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI1 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI1_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI2 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI2_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI3 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI3_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI4 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI4_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI5..9 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI5_9_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI10..15 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI10_15_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI16 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI16_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI16_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI17 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI17_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI17_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI18 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI18_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI18_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI19 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI19_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI19_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI20 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI20_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI20_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI21..22 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI21_22_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI21_22_IRQ_PRIORITY 6
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void ext_lld_exti_irq_enable(void);
void ext_lld_exti_irq_disable(void);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_EXT */
#endif /* _EXT_LLD_ISR_H_ */
/** @} */

View File

@ -0,0 +1,205 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32F37x/hal_lld.c
* @brief STM32F37x HAL subsystem low level driver source.
*
* @addtogroup HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Initializes the backup domain.
* @note WARNING! Changing clock source impossible without resetting
* of the whole BKP domain.
*/
static void hal_lld_backup_domain_init(void) {
/* Backup domain access enabled and left open.*/
PWR->CR |= PWR_CR_DBP;
/* Reset BKP domain if different clock source selected.*/
if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL){
/* Backup domain reset.*/
RCC->BDCR = RCC_BDCR_BDRST;
RCC->BDCR = 0;
}
/* If enabled then the LSE is started.*/
#if STM32_LSE_ENABLED
#if defined(STM32_LSE_BYPASS)
/* LSE Bypass.*/
RCC->BDCR = STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP;
#else
/* No LSE Bypass.*/
RCC->BDCR = STM32_LSEDRV | RCC_BDCR_LSEON;
#endif
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
; /* Waits until LSE is stable. */
#endif
#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK
/* If the backup domain hasn't been initialized yet then proceed with
initialization.*/
if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) {
/* Selects clock source.*/
RCC->BDCR |= STM32_RTCSEL;
/* RTC clock enabled.*/
RCC->BDCR |= RCC_BDCR_RTCEN;
}
#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*
* @notapi
*/
void hal_lld_init(void) {
/* Reset of all peripherals.*/
rccResetAPB1(0xFFFFFFFF);
rccResetAPB2(0xFFFFFFFF);
/* SysTick initialization using the system clock.*/
SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
/* DWT cycle counter enable.*/
SCS_DEMCR |= SCS_DEMCR_TRCENA;
DWT_CTRL |= DWT_CTRL_CYCCNTENA;
/* PWR clock enabled.*/
rccEnablePWRInterface(FALSE);
/* Initializes the backup domain.*/
hal_lld_backup_domain_init();
#if defined(STM32_DMA_REQUIRED)
dmaInit();
#endif
/* Programmable voltage detector enable.*/
#if STM32_PVD_ENABLE
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
#endif /* STM32_PVD_ENABLE */
/* SYSCFG clock enabled here because it is a multi-functional unit shared
among multiple drivers.*/
rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, TRUE);
}
/**
* @brief STM32 clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h.
* @note This function should be invoked just after the system reset.
*
* @special
*/
void stm32_clock_init(void) {
#if !STM32_NO_INIT
/* HSI setup, it enforces the reset situation in order to handle possible
problems with JTAG probes and re-initializations.*/
RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */
while (!(RCC->CR & RCC_CR_HSIRDY))
; /* Wait until HSI is stable. */
RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */
RCC->CFGR = 0; /* CFGR reset value. */
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
; /* Waits until HSI is selected. */
#if STM32_HSE_ENABLED
/* HSE activation.*/
#if defined(STM32_HSE_BYPASS)
/* HSE Bypass.*/
RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP;
#else
/* No HSE Bypass.*/
RCC->CR |= RCC_CR_HSEON;
#endif
while (!(RCC->CR & RCC_CR_HSERDY))
; /* Waits until HSE is stable. */
#endif
#if STM32_LSI_ENABLED
/* LSI activation.*/
RCC->CSR |= RCC_CSR_LSION;
while ((RCC->CSR & RCC_CSR_LSIRDY) == 0)
; /* Waits until LSI is stable. */
#endif
/* Clock settings.*/
RCC->CFGR = STM32_SDPRE | STM32_MCOSEL | STM32_USBPRE |
STM32_PLLMUL | STM32_PLLSRC | STM32_ADCPRE |
STM32_PPRE1 | STM32_PPRE2 | STM32_HPRE;
RCC->CFGR2 = STM32_PREDIV;
RCC->CFGR3 = STM32_USART3SW | STM32_USART2SW | STM32_I2C2SW |
STM32_I2C1SW | STM32_USART1SW;
#if STM32_ACTIVATE_PLL
/* PLL activation.*/
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
; /* Waits until PLL is stable. */
#endif
/* Flash setup and final clock selection. */
FLASH->ACR = STM32_FLASHBITS;
/* Switching to the configured clock source if it is different from HSI.*/
#if (STM32_SW != STM32_SW_HSI)
/* Switches clock source.*/
RCC->CFGR |= STM32_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
; /* Waits selection complete. */
#endif
#endif /* !STM32_NO_INIT */
}
/** @} */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
# List of all the STM32F37x platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/ports/STM32F37x/stm32_dma.c \
${CHIBIOS}/os/hal/ports/STM32F37x/hal_lld.c \
${CHIBIOS}/os/hal/ports/STM32F37x/adc_lld.c \
${CHIBIOS}/os/hal/ports/STM32F37x/ext_lld_isr.c \
${CHIBIOS}/os/hal/ports/STM32/can_lld.c \
${CHIBIOS}/os/hal/ports/STM32/ext_lld.c \
${CHIBIOS}/os/hal/ports/STM32/GPIOv2/pal_lld.c \
${CHIBIOS}/os/hal/ports/STM32/I2Cv2/i2c_lld.c \
${CHIBIOS}/os/hal/ports/STM32/RTCv2/rtc_lld.c \
${CHIBIOS}/os/hal/ports/STM32/SPIv2/spi_lld.c \
${CHIBIOS}/os/hal/ports/STM32/TIMv1/gpt_lld.c \
${CHIBIOS}/os/hal/ports/STM32/TIMv1/icu_lld.c \
${CHIBIOS}/os/hal/ports/STM32/TIMv1/pwm_lld.c \
${CHIBIOS}/os/hal/ports/STM32/USARTv2/serial_lld.c \
${CHIBIOS}/os/hal/ports/STM32/USARTv2/uart_lld.c \
${CHIBIOS}/os/hal/ports/STM32/USBv1/usb_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/ports/STM32F37x \
${CHIBIOS}/os/hal/ports/STM32 \
${CHIBIOS}/os/hal/ports/STM32/GPIOv2 \
${CHIBIOS}/os/hal/ports/STM32/I2Cv2 \
${CHIBIOS}/os/hal/ports/STM32/RTCv2 \
${CHIBIOS}/os/hal/ports/STM32/SPIv2 \
${CHIBIOS}/os/hal/ports/STM32/TIMv1 \
${CHIBIOS}/os/hal/ports/STM32/USARTv2 \
${CHIBIOS}/os/hal/ports/STM32/USBv1

View File

@ -0,0 +1,450 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32F37x/stm32_dma.c
* @brief DMA helper driver code.
*
* @addtogroup STM32F37x_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
* drivers to coordinate the access to the resource.
* @note The DMA ISR handlers are all declared into this module because
* sharing, the various device drivers can associate a callback to
* ISRs when allocating streams.
* @{
*/
#include "ch.h"
#include "hal.h"
/* The following macro is only defined if some driver requiring DMA services
has been enabled.*/
#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/**
* @brief Mask of the DMA1 streams in @p dma_streams_mask.
*/
#define STM32_DMA1_STREAMS_MASK 0x0000007F
/**
* @brief Mask of the DMA2 streams in @p dma_streams_mask.
*/
#define STM32_DMA2_STREAMS_MASK 0x00000F80
/**
* @brief Post-reset value of the stream CCR register.
*/
#define STM32_DMA_CCR_RESET_VALUE 0x00000000
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief DMA streams descriptors.
* @details This table keeps the association between an unique stream
* identifier and the involved physical registers.
* @note Don't use this array directly, use the appropriate wrapper macros
* instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc.
*/
const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
{DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn},
{DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn},
{DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn},
{DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn},
{DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn},
{DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn},
{DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn},
{DMA2_Channel1, &DMA2->IFCR, 0, 7, DMA2_Channel1_IRQn},
{DMA2_Channel2, &DMA2->IFCR, 4, 8, DMA2_Channel2_IRQn},
{DMA2_Channel3, &DMA2->IFCR, 8, 9, DMA2_Channel3_IRQn},
{DMA2_Channel4, &DMA2->IFCR, 12, 10, DMA2_Channel4_IRQn},
{DMA2_Channel5, &DMA2->IFCR, 16, 11, DMA2_Channel5_IRQn},
};
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/**
* @brief DMA ISR redirector type.
*/
typedef struct {
stm32_dmaisr_t dma_func; /**< @brief DMA callback function. */
void *dma_param; /**< @brief DMA callback parameter. */
} dma_isr_redir_t;
/**
* @brief Mask of the allocated streams.
*/
static uint32_t dma_streams_mask;
/**
* @brief DMA IRQ redirectors.
*/
static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS];
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief DMA1 stream 1 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector6C) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 0;
if (dma_isr_redir[0].dma_func)
dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 2 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector70) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 4;
if (dma_isr_redir[1].dma_func)
dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 3 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector74) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 8;
if (dma_isr_redir[2].dma_func)
dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 4 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector78) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 12;
if (dma_isr_redir[3].dma_func)
dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 5 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector7C) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 16;
if (dma_isr_redir[4].dma_func)
dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 6 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector80) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 20;
if (dma_isr_redir[5].dma_func)
dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 7 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector84) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 24;
if (dma_isr_redir[6].dma_func)
dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA2 stream 1 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector120) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA2->ISR >> 0) & STM32_DMA_ISR_MASK;
DMA2->IFCR = STM32_DMA_ISR_MASK << 0;
if (dma_isr_redir[7].dma_func)
dma_isr_redir[7].dma_func(dma_isr_redir[7].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA2 stream 2 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector124) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA2->ISR >> 4) & STM32_DMA_ISR_MASK;
DMA2->IFCR = STM32_DMA_ISR_MASK << 4;
if (dma_isr_redir[8].dma_func)
dma_isr_redir[8].dma_func(dma_isr_redir[8].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA2 stream 3 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector128) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA2->ISR >> 8) & STM32_DMA_ISR_MASK;
DMA2->IFCR = STM32_DMA_ISR_MASK << 8;
if (dma_isr_redir[9].dma_func)
dma_isr_redir[9].dma_func(dma_isr_redir[9].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA2 stream 4 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector12C) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA2->ISR >> 12) & STM32_DMA_ISR_MASK;
DMA2->IFCR = STM32_DMA_ISR_MASK << 12;
if (dma_isr_redir[10].dma_func)
dma_isr_redir[10].dma_func(dma_isr_redir[10].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA2 stream 5 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(Vector130) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA2->ISR >> 16) & STM32_DMA_ISR_MASK;
DMA2->IFCR = STM32_DMA_ISR_MASK << 16;
if (dma_isr_redir[11].dma_func)
dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief STM32 DMA helper initialization.
*
* @init
*/
void dmaInit(void) {
int i;
dma_streams_mask = 0;
for (i = 0; i < STM32_DMA_STREAMS; i++) {
_stm32_dma_streams[i].channel->CCR = 0;
dma_isr_redir[i].dma_func = NULL;
}
DMA1->IFCR = 0xFFFFFFFF;
#if STM32_HAS_DMA2
DMA2->IFCR = 0xFFFFFFFF;
#endif
}
/**
* @brief Allocates a DMA stream.
* @details The stream is allocated and, if required, the DMA clock enabled.
* The function also enables the IRQ vector associated to the stream
* and initializes its priority.
* @pre The stream must not be already in use or an error is returned.
* @post The stream is allocated and the default ISR handler redirected
* to the specified function.
* @post The stream ISR vector is enabled and its priority configured.
* @post The stream must be freed using @p dmaStreamRelease() before it can
* be reused with another peripheral.
* @post The stream is in its post-reset state.
* @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
* @param[in] priority IRQ priority mask for the DMA stream
* @param[in] func handling function pointer, can be @p NULL
* @param[in] param a parameter to be passed to the handling function
* @return The operation status.
* @retval FALSE no error, stream taken.
* @retval TRUE error, stream already taken.
*
* @special
*/
bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
uint32_t priority,
stm32_dmaisr_t func,
void *param) {
chDbgCheck(dmastp != NULL, "dmaStreamAllocate");
/* Checks if the stream is already taken.*/
if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0)
return TRUE;
/* Marks the stream as allocated.*/
dma_isr_redir[dmastp->selfindex].dma_func = func;
dma_isr_redir[dmastp->selfindex].dma_param = param;
dma_streams_mask |= (1 << dmastp->selfindex);
/* Enabling DMA clocks required by the current streams set.*/
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0)
rccEnableDMA1(FALSE);
#if STM32_HAS_DMA2
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0)
rccEnableDMA2(FALSE);
#endif
/* Putting the stream in a safe state.*/
dmaStreamDisable(dmastp);
dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE;
/* Enables the associated IRQ vector if a callback is defined.*/
if (func != NULL)
nvicEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority));
return FALSE;
}
/**
* @brief Releases a DMA stream.
* @details The stream is freed and, if required, the DMA clock disabled.
* Trying to release a unallocated stream is an illegal operation
* and is trapped if assertions are enabled.
* @pre The stream must have been allocated using @p dmaStreamAllocate().
* @post The stream is again available.
* @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
*
* @special
*/
void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
chDbgCheck(dmastp != NULL, "dmaStreamRelease");
/* Check if the streams is not taken.*/
chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
"dmaStreamRelease(), #1", "not allocated");
/* Disables the associated IRQ vector.*/
nvicDisableVector(dmastp->vector);
/* Marks the stream as not allocated.*/
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)
rccDisableDMA1(FALSE);
#if STM32_HAS_DMA2
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
rccDisableDMA2(FALSE);
#endif
}
#endif /* STM32_DMA_REQUIRED */
/** @} */

View File

@ -0,0 +1,406 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32F37x/stm32_dma.h
* @brief DMA helper driver header.
* @note This file requires definitions from the ST header file stm32f30x.h.
* @note This driver uses the new naming convention used for the STM32F2xx
* so the "DMA channels" are referred as "DMA streams".
*
* @addtogroup STM32F37x_DMA
* @{
*/
#ifndef _STM32_DMA_H_
#define _STM32_DMA_H_
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Total number of DMA streams.
* @note This is the total number of streams among all the DMA units.
*/
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
#define STM32_DMA_STREAMS 12
#else
#define STM32_DMA_STREAMS 7
#endif
/**
* @brief Mask of the ISR bits passed to the DMA callback functions.
*/
#define STM32_DMA_ISR_MASK 0x0F
/**
* @brief Returns the channel associated to the specified stream.
*
* @param[in] n the stream number (0...STM32_DMA_STREAMS-1)
* @param[in] c a stream/channel association word, one channel per
* nibble, not associated channels must be set to 0xF
* @return Always zero, in this platform there is no dynamic
* association between streams and channels.
*/
#define STM32_DMA_GETCHANNEL(n, c) 0
/**
* @brief Checks if a DMA priority is within the valid range.
* @param[in] prio DMA priority
*
* @retval The check result.
* @retval FALSE invalid DMA priority.
* @retval TRUE correct DMA priority.
*/
#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0) && ((prio) <= 3))
/**
* @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) * 7) + ((stream) - 1))
/**
* @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
* @{
*/
/**
* @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_STREAM1 STM32_DMA_STREAM(0)
#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1)
#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(2)
#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(3)
#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4)
#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(5)
#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(6)
#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(7)
#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(8)
#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(9)
#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(10)
#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(11)
/** @} */
/**
* @name CR register constants common to all DMA types
* @{
*/
#define STM32_DMA_CR_EN DMA_CCR_EN
#define STM32_DMA_CR_TEIE DMA_CCR_TEIE
#define STM32_DMA_CR_HTIE DMA_CCR_HTIE
#define STM32_DMA_CR_TCIE DMA_CCR_TCIE
#define STM32_DMA_CR_DIR_MASK (DMA_CCR_DIR | DMA_CCR_MEM2MEM)
#define STM32_DMA_CR_DIR_P2M 0
#define STM32_DMA_CR_DIR_M2P DMA_CCR_DIR
#define STM32_DMA_CR_DIR_M2M DMA_CCR_MEM2MEM
#define STM32_DMA_CR_CIRC DMA_CCR_CIRC
#define STM32_DMA_CR_PINC DMA_CCR_PINC
#define STM32_DMA_CR_MINC DMA_CCR_MINC
#define STM32_DMA_CR_PSIZE_MASK DMA_CCR_PSIZE
#define STM32_DMA_CR_PSIZE_BYTE 0
#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR_PSIZE_0
#define STM32_DMA_CR_PSIZE_WORD DMA_CCR_PSIZE_1
#define STM32_DMA_CR_MSIZE_MASK DMA_CCR_MSIZE
#define STM32_DMA_CR_MSIZE_BYTE 0
#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR_MSIZE_0
#define STM32_DMA_CR_MSIZE_WORD DMA_CCR_MSIZE_1
#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_PSIZE_MASK | \
STM32_DMA_CR_MSIZE_MASK)
#define STM32_DMA_CR_PL_MASK DMA_CCR_PL
#define STM32_DMA_CR_PL(n) ((n) << 12)
/** @} */
/**
* @name CR register constants only found in enhanced DMA
* @{
*/
#define STM32_DMA_CR_DMEIE 0 /**< @brief Ignored by normal DMA. */
#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */
#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */
/** @} */
/**
* @name Status flags passed to the ISR callbacks
* @{
*/
#define STM32_DMA_ISR_FEIF 0
#define STM32_DMA_ISR_DMEIF 0
#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1
#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1
#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief STM32 DMA stream descriptor structure.
*/
typedef struct {
DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
uint8_t ishift; /**< @brief Bits offset in xIFCR
register. */
uint8_t selfindex; /**< @brief Index to self in array. */
uint8_t vector; /**< @brief Associated IRQ vector. */
} stm32_dma_stream_t;
/**
* @brief STM32 DMA ISR function type.
*
* @param[in] p parameter for the registered function
* @param[in] flags pre-shifted content of the ISR register, the bits
* are aligned to bit zero
*/
typedef void (*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 CPAR register
*
* @special
*/
#define dmaStreamSetPeripheral(dmastp, addr) { \
(dmastp)->channel->CPAR = (uint32_t)(addr); \
}
/**
* @brief Associates a memory destination to a DMA stream.
* @note This function can be invoked in both ISR or thread context.
* @pre The stream must have been allocated using @p 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 CMAR register
*
* @special
*/
#define dmaStreamSetMemory0(dmastp, addr) { \
(dmastp)->channel->CMAR = (uint32_t)(addr); \
}
/**
* @brief Sets the number of transfers to be performed.
* @note This function can be invoked in both ISR or thread context.
* @pre The stream must have been allocated using @p 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
*
* @special
*/
#define dmaStreamSetTransactionSize(dmastp, size) { \
(dmastp)->channel->CNDTR = (uint32_t)(size); \
}
/**
* @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.
*
* @special
*/
#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR))
/**
* @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 CCR register
*
* @special
*/
#define dmaStreamSetMode(dmastp, mode) { \
(dmastp)->channel->CCR = (uint32_t)(mode); \
}
/**
* @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] dmastp pointer to a stm32_dma_stream_t structure
*
* @special
*/
#define dmaStreamEnable(dmastp) { \
(dmastp)->channel->CCR |= STM32_DMA_CR_EN; \
}
/**
* @brief DMA stream disable.
* @details The function disables the specified stream and then clears any
* pending interrupt.
* @note This function can be invoked in both ISR or thread context.
* @note Interrupts enabling flags are set to zero after this call, see
* bug 3607518.
* @pre The stream must have been allocated using @p dmaStreamAllocate().
* @post After use the stream can be released using @p dmaStreamRelease().
*
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
*
* @special
*/
#define dmaStreamDisable(dmastp) { \
(dmastp)->channel->CCR &= ~(STM32_DMA_CR_TCIE | STM32_DMA_CR_HTIE | \
STM32_DMA_CR_TEIE | STM32_DMA_CR_EN); \
dmaStreamClearInterrupt(dmastp); \
}
/**
* @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
*
* @special
*/
#define dmaStreamClearInterrupt(dmastp) { \
*(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)->channel->CNDTR > 0) \
; \
dmaStreamDisable(dmastp); \
}
/** @} */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if !defined(__DOXYGEN__)
extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
#endif
#ifdef __cplusplus
extern "C" {
#endif
void dmaInit(void);
bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
uint32_t priority,
stm32_dmaisr_t func,
void *param);
void dmaStreamRelease(const stm32_dma_stream_t *dmastp);
#ifdef __cplusplus
}
#endif
#endif /* _STM32_DMA_H_ */
/** @} */

View File

@ -0,0 +1,126 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32F37x/stm32_isr.h
* @brief ISR remapper driver header.
*
* @addtogroup STM32F37x_ISR
* @{
*/
#ifndef _STM32_ISR_H_
#define _STM32_ISR_H_
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name ISR names and numbers remapping
* @{
*/
/*
* CAN units.
*/
#define STM32_CAN1_TX_HANDLER Vector8C
#define STM32_CAN1_RX0_HANDLER Vector90
#define STM32_CAN1_RX1_HANDLER Vector94
#define STM32_CAN1_SCE_HANDLER Vector98
#define STM32_CAN1_TX_NUMBER 19
#define STM32_CAN1_RX0_NUMBER 20
#define STM32_CAN1_RX1_NUMBER 21
#define STM32_CAN1_SCE_NUMBER 22
/*
* I2C units.
*/
#define STM32_I2C1_EVENT_HANDLER VectorBC
#define STM32_I2C1_ERROR_HANDLER VectorC0
#define STM32_I2C1_EVENT_NUMBER 31
#define STM32_I2C1_ERROR_NUMBER 32
#define STM32_I2C2_EVENT_HANDLER VectorC4
#define STM32_I2C2_ERROR_HANDLER VectorC8
#define STM32_I2C2_EVENT_NUMBER 33
#define STM32_I2C2_ERROR_NUMBER 34
/*
* TIM units.
*/
#define STM32_TIM2_HANDLER VectorB0
#define STM32_TIM3_HANDLER VectorB4
#define STM32_TIM4_HANDLER VectorB8
#define STM32_TIM5_HANDLER Vector108
#define STM32_TIM6_HANDLER Vector118
#define STM32_TIM7_HANDLER Vector11C
#define STM32_TIM12_HANDLER VectorEC
#define STM32_TIM14_HANDLER VectorF4
#define STM32_TIM2_NUMBER 28
#define STM32_TIM3_NUMBER 29
#define STM32_TIM4_NUMBER 30
#define STM32_TIM5_NUMBER 50
#define STM32_TIM6_NUMBER 54
#define STM32_TIM7_NUMBER 55
#define STM32_TIM12_NUMBER 43
#define STM32_TIM14_NUMBER 45
/*
* USART units.
*/
#define STM32_USART1_HANDLER VectorD4
#define STM32_USART2_HANDLER VectorD8
#define STM32_USART3_HANDLER VectorDC
#define STM32_USART1_NUMBER 37
#define STM32_USART2_NUMBER 38
#define STM32_USART3_NUMBER 39
/*
* USB units.
*/
#define STM32_USB1_HP_HANDLER Vector168
#define STM32_USB1_LP_HANDLER Vector16C
#define STM32_USB1_HP_NUMBER 74
#define STM32_USB1_LP_NUMBER 75
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#endif /* _STM32_ISR_H_ */
/** @} */

View File

@ -0,0 +1,860 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32F37x/stm32_rcc.h
* @brief RCC helper driver header.
* @note This file requires definitions from the ST header file
* @p stm32f30x.h.
*
* @addtogroup STM32F37x_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); \
}
/**
* @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); \
}
/**
* @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); \
}
/**
* @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); \
}
/**
* @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 AHB bus.
*
* @param[in] mask AHB peripherals mask
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableAHB(mask, lp) { \
RCC->AHBENR |= (mask); \
}
/**
* @brief Disables the clock of one or more peripheral on the AHB bus.
*
* @param[in] mask AHB peripherals mask
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableAHB(mask, lp) { \
RCC->AHBENR &= ~(mask); \
}
/**
* @brief Resets one or more peripheral on the AHB bus.
*
* @param[in] mask AHB peripherals mask
*
* @api
*/
#define rccResetAHB(mask) { \
RCC->AHBRSTR |= (mask); \
RCC->AHBRSTR = 0; \
}
/** @} */
/**
* @name ADC1 peripheral specific RCC operations
* @{
*/
/**
* @brief Enables the ADC 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)
/** @} */
/**
* @name CAN peripherals specific RCC operations
* @{
*/
/**
* @brief Enables the CAN1 peripheral clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableCAN1(lp) rccEnableAPB1(RCC_APB1ENR_CAN1EN, lp)
/**
* @brief Disables the CAN1 peripheral clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableCAN1(lp) rccDisableAPB1(RCC_APB1ENR_CAN1EN, lp)
/**
* @brief Resets the CAN1 peripheral.
*
* @api
*/
#define rccResetCAN1() rccResetAPB1(RCC_APB1RSTR_CAN1RST)
/** @} */
/**
* @name DMA peripheral specific RCC operations
* @{
*/
/**
* @brief Enables the DMA1 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
/**
* @brief Disables the DMA1 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableDMA1(lp) rccDisableAHB(RCC_AHBENR_DMA1EN, lp)
/**
* @brief Resets the DMA1 peripheral.
*
* @api
*/
#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
/**
* @brief Enables the DMA2 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
/**
* @brief Disables the DMA2 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableDMA2(lp) rccDisableAHB(RCC_AHBENR_DMA2EN, lp)
/**
* @brief Resets the DMA2 peripheral.
*
* @api
*/
#define rccResetDMA2() rccResetAHB(RCC_AHBRSTR_DMA2RST)
/** @} */
/**
* @name PWR interface specific RCC operations
* @{
*/
/**
* @brief Enables the PWR interface clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnablePWRInterface(lp) rccEnableAPB1(RCC_APB1ENR_PWREN, lp)
/**
* @brief Disables PWR interface clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisablePWRInterface(lp) rccDisableAPB1(RCC_APB1ENR_PWREN, lp)
/**
* @brief Resets the PWR interface.
*
* @api
*/
#define rccResetPWRInterface() rccResetAPB1(RCC_APB1RSTR_PWRRST)
/** @} */
/**
* @name 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)
/** @} */
/**
* @name SDADC peripherals specific RCC operations
* @{
*/
/**
* @brief Enables the SDADC1 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableSDADC1(lp) rccEnableAPB2(RCC_APB2ENR_SDADC1EN, lp)
/**
* @brief Disables the SDADC1 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableSDADC1(lp) rccDisableAPB2(RCC_APB2ENR_SDADC1EN, lp)
/**
* @brief Resets the SDADC1 peripheral.
*
* @api
*/
#define rccResetSDADC1() rccResetAPB2(RCC_APB2RSTR_SDADC1RST)
/**
* @brief Enables the SDADC2 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableSDADC2(lp) rccEnableAPB2(RCC_APB2ENR_SDADC2EN, lp)
/**
* @brief Disables the SDADC2 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableSDADC2(lp) rccDisableAPB2(RCC_APB2ENR_SDADC2EN, lp)
/**
* @brief Resets the SDADC2 peripheral.
*
* @api
*/
#define rccResetSDADC2() rccResetAPB2(RCC_APB2RSTR_SDADC2RST)
/**
* @brief Enables the SDADC3 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableSDADC3(lp) rccEnableAPB2(RCC_APB2ENR_SDADC3EN, lp)
/**
* @brief Disables the SDADC3 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableSDADC3(lp) rccDisableAPB2(RCC_APB2ENR_SDADC3EN, lp)
/**
* @brief Resets the SDADC3 peripheral.
*
* @api
*/
#define rccResetSDADC3() rccResetAPB2(RCC_APB2RSTR_SDADC3RST)
/** @} */
/**
* @name 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.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableSPI3(lp) rccEnableAPB1(RCC_APB1ENR_SPI3EN, lp)
/**
* @brief Disables the SPI3 peripheral clock.
* @note The @p lp parameter is ignored in this family.
*
* @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)
/** @} */
/**
* @name TIM peripherals specific RCC operations
* @{
*/
/**
* @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.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableTIM5(lp) rccEnableAPB1(RCC_APB1ENR_TIM5EN, lp)
/**
* @brief Disables the TIM5 peripheral clock.
*
* @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 TIM6 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableTIM6(lp) rccEnableAPB1(RCC_APB1ENR_TIM6EN, lp)
/**
* @brief Disables the TIM6 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableTIM6(lp) rccDisableAPB1(RCC_APB1ENR_TIM6EN, lp)
/**
* @brief Resets the TIM6 peripheral.
*
* @api
*/
#define rccResetTIM6() rccResetAPB1(RCC_APB1RSTR_TIM6RST)
/** @} */
/**
* @brief Enables the TIM7 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableTIM7(lp) rccEnableAPB1(RCC_APB1ENR_TIM7EN, lp)
/**
* @brief Disables the TIM7 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableTIM7(lp) rccDisableAPB1(RCC_APB1ENR_TIM7EN, lp)
/**
* @brief Resets the TIM7 peripheral.
*
* @api
*/
#define rccResetTIM7() rccResetAPB1(RCC_APB1RSTR_TIM7RST)
/** @} */
/**
* @brief Enables the TIM12 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableTIM12(lp) rccEnableAPB1(RCC_APB1ENR_TIM12EN, lp)
/**
* @brief Disables the TIM12 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableTIM12(lp) rccDisableAPB1(RCC_APB1ENR_TIM12EN, lp)
/**
* @brief Resets the TIM12 peripheral.
*
* @api
*/
#define rccResetTIM12() rccResetAPB1(RCC_APB1RSTR_TIM12RST)
/** @} */
/**
* @brief Enables the TIM14 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableTIM14(lp) rccEnableAPB1(RCC_APB1ENR_TIM14EN, lp)
/**
* @brief Disables the TIM14 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableTIM14(lp) rccDisableAPB1(RCC_APB1ENR_TIM14EN, lp)
/**
* @brief Resets the TIM14 peripheral.
*
* @api
*/
#define rccResetTIM14() rccResetAPB1(RCC_APB1RSTR_TIM14RST)
/** @} */
/**
* @name 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)
/** @} */
/**
* @name USB peripheral specific RCC operations
* @{
*/
/**
* @brief Enables the USB peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
/**
* @brief Disables the USB peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableUSB(lp) rccDisableAPB1(RCC_APB1ENR_USBEN, lp)
/**
* @brief Resets the USB peripheral.
*
* @api
*/
#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
/** @} */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* _STM32_RCC_ */
/** @} */

View File

@ -0,0 +1,207 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32F37x/stm32_registry.h
* @brief STM32F37x capabilities registry.
*
* @addtogroup HAL
* @{
*/
#ifndef _STM32_REGISTRY_H_
#define _STM32_REGISTRY_H_
/*===========================================================================*/
/* Platform capabilities. */
/*===========================================================================*/
/**
* @name STM32F37x capabilities
* @{
*/
/* ADC attributes.*/
#define STM32_HAS_ADC1 TRUE
#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
#define STM32_ADC1_DMA_CHN 0x00000000
#define STM32_HAS_ADC2 FALSE
#define STM32_ADC2_DMA_MSK 0
#define STM32_ADC2_DMA_CHN 0x00000000
#define STM32_HAS_ADC3 FALSE
#define STM32_ADC3_DMA_MSK 0
#define STM32_ADC3_DMA_CHN 0x00000000
#define STM32_HAS_ADC4 FALSE
#define STM32_ADC4_DMA_MSK 0
#define STM32_ADC4_DMA_CHN 0x00000000
#define STM32_HAS_SDADC1 TRUE
#define STM32_SDADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3))
#define STM32_SDADC1_DMA_CHN 0x00000000
#define STM32_HAS_SDADC2 TRUE
#define STM32_SDADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4))
#define STM32_SDADC2_DMA_CHN 0x00000000
#define STM32_HAS_SDADC3 TRUE
#define STM32_SDADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
#define STM32_SDADC3_DMA_CHN 0x00000000
/* CAN attributes.*/
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
#define STM32_CAN_MAX_FILTERS 14
/* DAC attributes.*/
#define STM32_HAS_DAC TRUE
/* DMA attributes.*/
#define STM32_ADVANCED_DMA FALSE
#define STM32_HAS_DMA1 TRUE
#define STM32_HAS_DMA2 TRUE
/* ETH attributes.*/
#define STM32_HAS_ETH FALSE
/* EXTI attributes.*/
#define STM32_EXTI_NUM_CHANNELS 29
/* GPIO attributes.*/
#define STM32_HAS_GPIOA TRUE
#define STM32_HAS_GPIOB TRUE
#define STM32_HAS_GPIOC TRUE
#define STM32_HAS_GPIOD TRUE
#define STM32_HAS_GPIOE TRUE
#define STM32_HAS_GPIOF TRUE
#define STM32_HAS_GPIOG FALSE
#define STM32_HAS_GPIOH FALSE
#define STM32_HAS_GPIOI FALSE
/* I2C attributes.*/
#define STM32_HAS_I2C1 TRUE
#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
#define STM32_I2C1_RX_DMA_CHN 0x00000000
#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
#define STM32_I2C1_TX_DMA_CHN 0x00000000
#define STM32_HAS_I2C2 TRUE
#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
#define STM32_I2C2_RX_DMA_CHN 0x00000000
#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
#define STM32_I2C2_TX_DMA_CHN 0x00000000
#define STM32_HAS_I2C3 FALSE
#define STM32_I2C3_RX_DMA_MSK 0
#define STM32_I2C3_RX_DMA_CHN 0x00000000
#define STM32_I2C3_TX_DMA_MSK 0
#define STM32_I2C3_TX_DMA_CHN 0x00000000
/* RTC attributes.*/
#define STM32_HAS_RTC TRUE
#define STM32_RTC_HAS_SUBSECONDS TRUE
#define STM32_RTC_IS_CALENDAR TRUE
/* SDIO attributes.*/
#define STM32_HAS_SDIO FALSE
/* SPI attributes.*/
#define STM32_HAS_SPI1 TRUE
#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
#define STM32_SPI1_RX_DMA_CHN 0x00000000
#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
#define STM32_SPI1_TX_DMA_CHN 0x00000000
#define STM32_HAS_SPI2 TRUE
#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
#define STM32_SPI2_RX_DMA_CHN 0x00000000
#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
#define STM32_SPI2_TX_DMA_CHN 0x00000000
#define STM32_HAS_SPI3 TRUE
#define STM32_SPI3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 1)
#define STM32_SPI3_RX_DMA_CHN 0x00000000
#define STM32_SPI3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 2)
#define STM32_SPI3_TX_DMA_CHN 0x00000000
/* TIM attributes.*/
#define STM32_HAS_TIM1 FALSE
#define STM32_HAS_TIM2 TRUE
#define STM32_HAS_TIM3 TRUE
#define STM32_HAS_TIM4 TRUE
#define STM32_HAS_TIM5 TRUE
#define STM32_HAS_TIM6 TRUE
#define STM32_HAS_TIM7 TRUE
#define STM32_HAS_TIM8 FALSE
#define STM32_HAS_TIM9 FALSE
#define STM32_HAS_TIM10 FALSE
#define STM32_HAS_TIM11 FALSE
#define STM32_HAS_TIM12 TRUE
#define STM32_HAS_TIM13 TRUE
#define STM32_HAS_TIM14 TRUE
#define STM32_HAS_TIM15 TRUE
#define STM32_HAS_TIM16 TRUE
#define STM32_HAS_TIM17 TRUE
#define STM32_HAS_TIM18 TRUE
#define STM32_HAS_TIM19 TRUE
/* USART attributes.*/
#define STM32_HAS_USART1 TRUE
#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
#define STM32_USART1_RX_DMA_CHN 0x00000000
#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
#define STM32_USART1_TX_DMA_CHN 0x00000000
#define STM32_HAS_USART2 TRUE
#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
#define STM32_USART2_RX_DMA_CHN 0x00000000
#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
#define STM32_USART2_TX_DMA_CHN 0x00000000
#define STM32_HAS_USART3 TRUE
#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
#define STM32_USART3_RX_DMA_CHN 0x00000000
#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
#define STM32_USART3_TX_DMA_CHN 0x00000000
#define STM32_HAS_UART4 FALSE
#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3))
#define STM32_UART4_RX_DMA_CHN 0x00000000
#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
#define STM32_UART4_TX_DMA_CHN 0x00000000
#define STM32_HAS_UART5 FALSE
#define STM32_UART5_RX_DMA_MSK 0
#define STM32_UART5_RX_DMA_CHN 0x00000000
#define STM32_UART5_TX_DMA_MSK 0
#define STM32_UART5_TX_DMA_CHN 0x00000000
#define STM32_HAS_USART6 FALSE
#define STM32_USART6_RX_DMA_MSK 0
#define STM32_USART6_RX_DMA_CHN 0x00000000
#define STM32_USART6_TX_DMA_MSK 0
#define STM32_USART6_TX_DMA_CHN 0x00000000
/* USB attributes.*/
#define STM32_HAS_USB TRUE
#define STM32_HAS_OTG1 FALSE
#define STM32_HAS_OTG2 FALSE
/** @} */
#endif /* _STM32_REGISTRY_H_ */
/** @} */

View File

@ -0,0 +1,282 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32L1xx/adc_lld.c
* @brief STM32L1xx ADC subsystem low level driver source.
*
* @addtogroup ADC
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_ADC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/** @brief ADC1 driver identifier.*/
#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
ADCDriver ADCD1;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* 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 || defined(__DOXYGEN__)
/**
* @brief ADC interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(ADC1_IRQHandler) {
uint32_t sr;
CH_IRQ_PROLOGUE();
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.*/
CH_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level ADC driver initialization.
*
* @notapi
*/
void adc_lld_init(void) {
#if STM32_ADC_USE_ADC1
/* Driver initialization.*/
adcObjectInit(&ADCD1);
ADCD1.adc = ADC1;
ADCD1.dmastp = STM32_DMA1_STREAM1;
ADCD1.dmamode = 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;
#endif
/* The shared vector is initialized on driver initialization and never
disabled.*/
nvicEnableVector(ADC1_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 */
/* 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 and analog part.*/
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
}
}
/**
* @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);
dmaStreamEnable(adcp->dmastp);
/* ADC setup.*/
adcp->adc->SR = 0;
adcp->adc->SMPR1 = grpp->smpr1;
adcp->adc->SMPR2 = grpp->smpr2;
adcp->adc->SMPR3 = grpp->smpr3;
adcp->adc->SQR1 = grpp->sqr1;
adcp->adc->SQR2 = grpp->sqr2;
adcp->adc->SQR3 = grpp->sqr3;
adcp->adc->SQR4 = grpp->sqr4;
adcp->adc->SQR5 = grpp->sqr5;
/* 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;
if ((grpp->cr2 & ADC_CR2_SWSTART) != 0)
adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA |
ADC_CR2_DDS | ADC_CR2_ADON;
else
adcp->adc->CR2 = grpp->cr2 | 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;
}
#endif /* HAL_USE_ADC */
/** @} */

View File

@ -0,0 +1,484 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32L1xx/adc_lld.h
* @brief STM32L1xx 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 Triggers selection
* @{
*/
#define ADC_CR2_EXTSEL_SRC(n) ((n) << 24) /**< @brief Trigger source. */
/** @} */
/**
* @name ADC clock divider settings
* @{
*/
#define ADC_CCR_ADCPRE_DIV1 0
#define ADC_CCR_ADCPRE_DIV2 1
#define ADC_CCR_ADCPRE_DIV4 2
/** @} */
/**
* @name Available analog channels
* @{
*/
#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
#define ADC_CHANNEL_IN18 18 /**< @brief External analog input 18. */
#define ADC_CHANNEL_IN19 19 /**< @brief External analog input 19. */
#define ADC_CHANNEL_IN20 20 /**< @brief External analog input 20. */
#define ADC_CHANNEL_IN21 21 /**< @brief External analog input 21. */
#define ADC_CHANNEL_IN22 22 /**< @brief External analog input 22. */
#define ADC_CHANNEL_IN23 23 /**< @brief External analog input 23. */
#define ADC_CHANNEL_IN24 24 /**< @brief External analog input 24. */
#define ADC_CHANNEL_IN25 25 /**< @brief External analog input 25. */
/** @} */
/**
* @name Sampling rates
* @{
*/
#define ADC_SAMPLE_4 0 /**< @brief 4 cycles sampling time. */
#define ADC_SAMPLE_9 1 /**< @brief 9 cycles sampling time. */
#define ADC_SAMPLE_16 2 /**< @brief 16 cycles sampling time. */
#define ADC_SAMPLE_24 3 /**< @brief 24 cycles sampling time. */
#define ADC_SAMPLE_48 4 /**< @brief 48 cycles sampling time. */
#define ADC_SAMPLE_96 5 /**< @brief 96 cycles sampling time. */
#define ADC_SAMPLE_192 6 /**< @brief 192 cycles sampling time. */
#define ADC_SAMPLE_384 7 /**< @brief 384 cycles sampling time. */
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @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 FALSE
#endif
/**
* @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_DIV1
#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 ADC interrupt priority level setting.
*/
#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
/** @} */
/*===========================================================================*/
/* 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_ADC1
#error "ADC driver activated but no ADC peripheral assigned"
#endif
#if STM32_ADC_USE_ADC1 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ADC_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to ADC1"
#endif
#if STM32_ADC_USE_ADC1 && \
!CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
#error "Invalid IRQ priority assigned to ADC1 DMA"
#endif
#if STM32_ADC_USE_ADC1 && \
!STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
#error "Invalid DMA priority assigned to ADC1"
#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
* @param[in] err ADC error code
*/
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
* 20...25.
*/
uint32_t smpr1;
/**
* @brief ADC SMPR2 register initialization data.
* @details In this field must be specified the sample times for channels
* 10...19.
*/
uint32_t smpr2;
/**
* @brief ADC SMPR3 register initialization data.
* @details In this field must be specified the sample times for channels
* 0...9.
*/
uint32_t smpr3;
/**
* @brief ADC SQR1 register initialization data.
* @details Conversion group sequence 25...27 + sequence length.
*/
uint32_t sqr1;
/**
* @brief ADC SQR2 register initialization data.
* @details Conversion group sequence 19...24.
*/
uint32_t sqr2;
/**
* @brief ADC SQR3 register initialization data.
* @details Conversion group sequence 13...18.
*/
uint32_t sqr3;
/**
* @brief ADC SQR3 register initialization data.
* @details Conversion group sequence 7...12.
*/
uint32_t sqr4;
/**
* @brief ADC SQR3 register initialization data.
* @details Conversion group sequence 1...6.
*/
uint32_t sqr5;
} 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 DMA 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_SQR5_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
#define ADC_SQR5_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
#define ADC_SQR5_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
#define ADC_SQR5_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
#define ADC_SQR5_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
#define ADC_SQR5_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
#define ADC_SQR4_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
#define ADC_SQR4_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
#define ADC_SQR4_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
#define ADC_SQR4_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
#define ADC_SQR4_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
#define ADC_SQR4_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
#define ADC_SQR3_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
#define ADC_SQR3_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
#define ADC_SQR3_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
#define ADC_SQR3_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
#define ADC_SQR3_SQ17_N(n) ((n) << 20) /**< @brief 17th channel in seq.*/
#define ADC_SQR3_SQ18_N(n) ((n) << 25) /**< @brief 18th channel in seq.*/
#define ADC_SQR2_SQ19_N(n) ((n) << 0) /**< @brief 19th channel in seq.*/
#define ADC_SQR2_SQ20_N(n) ((n) << 5) /**< @brief 20th channel in seq.*/
#define ADC_SQR2_SQ21_N(n) ((n) << 10) /**< @brief 21th channel in seq.*/
#define ADC_SQR2_SQ22_N(n) ((n) << 15) /**< @brief 22th channel in seq.*/
#define ADC_SQR2_SQ23_N(n) ((n) << 20) /**< @brief 23th channel in seq.*/
#define ADC_SQR2_SQ24_N(n) ((n) << 25) /**< @brief 24th channel in seq.*/
#define ADC_SQR1_SQ25_N(n) ((n) << 0) /**< @brief 25th channel in seq.*/
#define ADC_SQR1_SQ26_N(n) ((n) << 5) /**< @brief 26th channel in seq.*/
#define ADC_SQR1_SQ27_N(n) ((n) << 10) /**< @brief 27th channel in seq.*/
/** @} */
/**
* @name Sampling rate settings helper macros
* @{
*/
#define ADC_SMPR3_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
#define ADC_SMPR3_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
#define ADC_SMPR3_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
#define ADC_SMPR3_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
#define ADC_SMPR3_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
#define ADC_SMPR3_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
#define ADC_SMPR3_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
#define ADC_SMPR3_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
#define ADC_SMPR3_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
#define ADC_SMPR3_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
#define ADC_SMPR2_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
#define ADC_SMPR2_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
#define ADC_SMPR2_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
#define ADC_SMPR2_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
#define ADC_SMPR2_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
#define ADC_SMPR2_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
#define ADC_SMPR2_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
sampling time. */
#define ADC_SMPR2_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
sampling time. */
#define ADC_SMPR2_SMP_AN18(n) ((n) << 24) /**< @brief AN18 sampling time. */
#define ADC_SMPR2_SMP_AN19(n) ((n) << 27) /**< @brief AN19 sampling time. */
#define ADC_SMPR1_SMP_AN20(n) ((n) << 0) /**< @brief AN20 sampling time. */
#define ADC_SMPR1_SMP_AN21(n) ((n) << 3) /**< @brief AN21 sampling time. */
#define ADC_SMPR1_SMP_AN22(n) ((n) << 6) /**< @brief AN22 sampling time. */
#define ADC_SMPR1_SMP_AN23(n) ((n) << 9) /**< @brief AN23 sampling time. */
#define ADC_SMPR1_SMP_AN24(n) ((n) << 12) /**< @brief AN24 sampling time. */
#define ADC_SMPR1_SMP_AN25(n) ((n) << 15) /**< @brief AN25 sampling time. */
/** @} */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
extern ADCDriver ADCD1;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void adc_lld_init(void);
void adc_lld_start(ADCDriver *adcp);
void adc_lld_stop(ADCDriver *adcp);
void adc_lld_start_conversion(ADCDriver *adcp);
void adc_lld_stop_conversion(ADCDriver *adcp);
void adcSTM32EnableTSVREFE(void);
void adcSTM32DisableTSVREFE(void);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_ADC */
#endif /* _ADC_LLD_H_ */
/** @} */

View File

@ -0,0 +1,339 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32L1xx/ext_lld_isr.c
* @brief STM32L1xx EXT subsystem low level driver ISR code.
*
* @addtogroup EXT
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_EXT || defined(__DOXYGEN__)
#include "ext_lld_isr.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief EXTI[0] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(EXTI0_IRQHandler) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 0);
EXTD1.config->channels[0].cb(&EXTD1, 0);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[1] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(EXTI1_IRQHandler) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 1);
EXTD1.config->channels[1].cb(&EXTD1, 1);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[2] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(EXTI2_IRQHandler) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 2);
EXTD1.config->channels[2].cb(&EXTD1, 2);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[3] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(EXTI3_IRQHandler) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 3);
EXTD1.config->channels[3].cb(&EXTD1, 3);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[4] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(EXTI4_IRQHandler) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 4);
EXTD1.config->channels[4].cb(&EXTD1, 4);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[5]...EXTI[9] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(EXTI9_5_IRQHandler) {
uint32_t pr;
CH_IRQ_PROLOGUE();
pr = EXTI->PR & ((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9));
EXTI->PR = pr;
if (pr & (1 << 5))
EXTD1.config->channels[5].cb(&EXTD1, 5);
if (pr & (1 << 6))
EXTD1.config->channels[6].cb(&EXTD1, 6);
if (pr & (1 << 7))
EXTD1.config->channels[7].cb(&EXTD1, 7);
if (pr & (1 << 8))
EXTD1.config->channels[8].cb(&EXTD1, 8);
if (pr & (1 << 9))
EXTD1.config->channels[9].cb(&EXTD1, 9);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[10]...EXTI[15] interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(EXTI15_10_IRQHandler) {
uint32_t pr;
CH_IRQ_PROLOGUE();
pr = EXTI->PR & ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | (1 << 14) |
(1 << 15));
EXTI->PR = pr;
if (pr & (1 << 10))
EXTD1.config->channels[10].cb(&EXTD1, 10);
if (pr & (1 << 11))
EXTD1.config->channels[11].cb(&EXTD1, 11);
if (pr & (1 << 12))
EXTD1.config->channels[12].cb(&EXTD1, 12);
if (pr & (1 << 13))
EXTD1.config->channels[13].cb(&EXTD1, 13);
if (pr & (1 << 14))
EXTD1.config->channels[14].cb(&EXTD1, 14);
if (pr & (1 << 15))
EXTD1.config->channels[15].cb(&EXTD1, 15);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[16] interrupt handler (PVD).
*
* @isr
*/
CH_IRQ_HANDLER(PVD_IRQHandler) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 16);
EXTD1.config->channels[16].cb(&EXTD1, 16);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[17] interrupt handler (RTC).
*
* @isr
*/
CH_IRQ_HANDLER(RTC_Alarm_IRQHandler) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 17);
EXTD1.config->channels[17].cb(&EXTD1, 17);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[18] interrupt handler (USB_FS_WKUP).
*
* @isr
*/
CH_IRQ_HANDLER(USB_FS_WKUP_IRQHandler) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 18);
EXTD1.config->channels[18].cb(&EXTD1, 18);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[19] interrupt handler (TAMPER_STAMP).
*
* @isr
*/
CH_IRQ_HANDLER(TAMPER_STAMP_IRQHandler) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 19);
EXTD1.config->channels[19].cb(&EXTD1, 19);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[20] interrupt handler (RTC_WKUP).
*
* @isr
*/
CH_IRQ_HANDLER(RTC_WKUP_IRQHandler) {
CH_IRQ_PROLOGUE();
EXTI->PR = (1 << 20);
EXTD1.config->channels[20].cb(&EXTD1, 20);
CH_IRQ_EPILOGUE();
}
/**
* @brief EXTI[21]...EXTI[22] interrupt handler (COMP).
*
* @isr
*/
CH_IRQ_HANDLER(COMP_IRQHandler) {
uint32_t pr;
CH_IRQ_PROLOGUE();
pr = EXTI->PR & ((1 << 21) | (1 << 22));
EXTI->PR = pr;
if (pr & (1 << 21))
EXTD1.config->channels[21].cb(&EXTD1, 21);
if (pr & (1 << 22))
EXTD1.config->channels[22].cb(&EXTD1, 22);
CH_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Enables EXTI IRQ sources.
*
* @notapi
*/
void ext_lld_exti_irq_enable(void) {
nvicEnableVector(EXTI0_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI0_IRQ_PRIORITY));
nvicEnableVector(EXTI1_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI1_IRQ_PRIORITY));
nvicEnableVector(EXTI2_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI2_IRQ_PRIORITY));
nvicEnableVector(EXTI3_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI3_IRQ_PRIORITY));
nvicEnableVector(EXTI4_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI4_IRQ_PRIORITY));
nvicEnableVector(EXTI9_5_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI5_9_IRQ_PRIORITY));
nvicEnableVector(EXTI15_10_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI10_15_IRQ_PRIORITY));
nvicEnableVector(PVD_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI16_IRQ_PRIORITY));
nvicEnableVector(RTC_Alarm_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI17_IRQ_PRIORITY));
nvicEnableVector(USB_FS_WKUP_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY));
nvicEnableVector(TAMPER_STAMP_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI19_IRQ_PRIORITY));
nvicEnableVector(RTC_WKUP_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI20_IRQ_PRIORITY));
nvicEnableVector(COMP_IRQn,
CORTEX_PRIORITY_MASK(STM32_EXT_EXTI21_22_IRQ_PRIORITY));
}
/**
* @brief Disables EXTI IRQ sources.
*
* @notapi
*/
void ext_lld_exti_irq_disable(void) {
nvicDisableVector(EXTI0_IRQn);
nvicDisableVector(EXTI1_IRQn);
nvicDisableVector(EXTI2_IRQn);
nvicDisableVector(EXTI3_IRQn);
nvicDisableVector(EXTI4_IRQn);
nvicDisableVector(EXTI9_5_IRQn);
nvicDisableVector(EXTI15_10_IRQn);
nvicDisableVector(PVD_IRQn);
nvicDisableVector(RTC_Alarm_IRQn);
nvicDisableVector(USB_FS_WKUP_IRQn);
nvicDisableVector(TAMPER_STAMP_IRQn);
nvicDisableVector(RTC_WKUP_IRQn);
nvicDisableVector(COMP_IRQn);
}
#endif /* HAL_USE_EXT */
/** @} */

View File

@ -0,0 +1,163 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32L1xx/ext_lld_isr.h
* @brief STM32L1xx EXT subsystem low level driver ISR header.
*
* @addtogroup EXT
* @{
*/
#ifndef _EXT_LLD_ISR_H_
#define _EXT_LLD_ISR_H_
#if HAL_USE_EXT || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief EXTI0 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI0_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI1 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI1_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI2 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI2_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI3 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI3_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI4 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI4_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI9..5 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI5_9_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI15..10 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI10_15_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI16 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI16_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI16_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI17 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI17_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI17_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI18 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI18_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI18_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI19 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI19_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI19_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI20 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI20_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI20_IRQ_PRIORITY 6
#endif
/**
* @brief EXTI21..22 interrupt priority level setting.
*/
#if !defined(STM32_EXT_EXTI21_22_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_EXT_EXTI21_22_IRQ_PRIORITY 6
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void ext_lld_exti_irq_enable(void);
void ext_lld_exti_irq_disable(void);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_EXT */
#endif /* _EXT_LLD_ISR_H_ */
/** @} */

View File

@ -0,0 +1,236 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32L1xx/hal_lld.c
* @brief STM32L1xx HAL subsystem low level driver source.
*
* @addtogroup HAL
* @{
*/
/* TODO: LSEBYP like in F3.*/
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Initializes the backup domain.
*/
static void hal_lld_backup_domain_init(void) {
/* Backup domain access enabled and left open.*/
PWR->CR |= PWR_CR_DBP;
/* Reset BKP domain if different clock source selected.*/
if ((RCC->CSR & STM32_RTCSEL_MASK) != STM32_RTCSEL){
/* Backup domain reset.*/
RCC->CSR |= RCC_CSR_RTCRST;
RCC->CSR &= ~RCC_CSR_RTCRST;
}
/* If enabled then the LSE is started.*/
#if STM32_LSE_ENABLED
RCC->CSR |= RCC_CSR_LSEON;
while ((RCC->CSR & RCC_CSR_LSERDY) == 0)
; /* Waits until LSE is stable. */
#endif
#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK
/* If the backup domain hasn't been initialized yet then proceed with
initialization.*/
if ((RCC->CSR & RCC_CSR_RTCEN) == 0) {
/* Selects clock source.*/
RCC->CSR |= STM32_RTCSEL;
/* RTC clock enabled.*/
RCC->CSR |= RCC_CSR_RTCEN;
}
#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*
* @notapi
*/
void hal_lld_init(void) {
/* Reset of all peripherals.*/
rccResetAHB(~RCC_AHBRSTR_FLITFRST);
rccResetAPB1(~RCC_APB1RSTR_PWRRST);
rccResetAPB2(~0);
/* SysTick initialization using the system clock.*/
SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
/* DWT cycle counter enable.*/
SCS_DEMCR |= SCS_DEMCR_TRCENA;
DWT_CTRL |= DWT_CTRL_CYCCNTENA;
/* PWR clock enabled.*/
rccEnablePWRInterface(FALSE);
/* Initializes the backup domain.*/
hal_lld_backup_domain_init();
#if defined(STM32_DMA_REQUIRED)
dmaInit();
#endif
/* Programmable voltage detector enable.*/
#if STM32_PVD_ENABLE
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
#endif /* STM32_PVD_ENABLE */
}
/**
* @brief STM32L1xx voltage, clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h.
* @note This function should be invoked just after the system reset.
*
* @special
*/
#if defined(STM32L1XX_MD) || 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;
/* Core voltage setup.*/
while ((PWR->CSR & PWR_CSR_VOSF) != 0)
; /* Waits until regulator is stable. */
PWR->CR = STM32_VOS;
while ((PWR->CSR & PWR_CSR_VOSF) != 0)
; /* Waits until regulator is stable. */
/* Initial clocks setup and wait for MSI stabilization, the MSI clock is
always enabled because it is the fallback clock when PLL the fails.
Trim fields are not altered from reset values.*/
RCC->CFGR = 0;
RCC->ICSCR = (RCC->ICSCR & ~STM32_MSIRANGE_MASK) | STM32_MSIRANGE;
RCC->CSR = RCC_CSR_RMVF;
RCC->CR = RCC_CR_MSION;
while ((RCC->CR & RCC_CR_MSIRDY) == 0)
; /* Waits until MSI is stable. */
#if STM32_HSI_ENABLED
/* HSI activation.*/
RCC->CR |= RCC_CR_HSION;
while ((RCC->CR & RCC_CR_HSIRDY) == 0)
; /* Waits until HSI is stable. */
#endif
#if STM32_HSE_ENABLED
#if defined(STM32_HSE_BYPASS)
/* HSE Bypass.*/
RCC->CR |= RCC_CR_HSEBYP;
#endif
/* HSE activation.*/
RCC->CR |= RCC_CR_HSEON;
while ((RCC->CR & RCC_CR_HSERDY) == 0)
; /* Waits until HSE is stable. */
#endif
#if STM32_LSI_ENABLED
/* LSI activation.*/
RCC->CSR |= RCC_CSR_LSION;
while ((RCC->CSR & RCC_CSR_LSIRDY) == 0)
; /* Waits until LSI is stable. */
#endif
#if STM32_LSE_ENABLED
/* LSE activation, have to unlock the register.*/
if ((RCC->CSR & RCC_CSR_LSEON) == 0) {
PWR->CR |= PWR_CR_DBP;
RCC->CSR |= RCC_CSR_LSEON;
PWR->CR &= ~PWR_CR_DBP;
}
while ((RCC->CSR & RCC_CSR_LSERDY) == 0)
; /* Waits until LSE is stable. */
#endif
#if STM32_ACTIVATE_PLL
/* PLL activation.*/
RCC->CFGR |= STM32_PLLDIV | STM32_PLLMUL | STM32_PLLSRC;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
; /* Waits until PLL is stable. */
#endif
/* Other clock-related settings (dividers, MCO etc).*/
RCC->CR |= STM32_RTCPRE;
RCC->CFGR |= STM32_MCOPRE | STM32_MCOSEL |
STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
RCC->CSR |= STM32_RTCSEL;
/* Flash setup and final clock selection.*/
#if defined(STM32_FLASHBITS1)
FLASH->ACR = STM32_FLASHBITS1;
#endif
#if defined(STM32_FLASHBITS2)
FLASH->ACR = STM32_FLASHBITS2;
#endif
/* Switching to the configured clock source if it is different from MSI.*/
#if (STM32_SW != STM32_SW_MSI)
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

View File

@ -0,0 +1,315 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @defgroup STM32L1xx_DRIVERS STM32L1xx Drivers
* @details This section describes all the supported drivers on the STM32L1xx
* platform and the implementation details of the single drivers.
*
* @ingroup platforms
*/
/**
* @defgroup STM32L1xx_HAL STM32L1xx Initialization Support
* @details The STM32L1xx HAL support is responsible for system initialization.
*
* @section stm32l1xx_hal_1 Supported HW resources
* - PLL1.
* - RCC.
* - Flash.
* .
* @section stm32l1xx_hal_2 STM32L1xx 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 STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_ADC STM32L1xx ADC Support
* @details The STM32L1xx ADC driver supports the ADC peripherals using DMA
* channels for maximum performance.
*
* @section stm32l1xx_adc_1 Supported HW resources
* - ADC1.
* - DMA1.
* .
* @section stm32l1xx_adc_2 STM32L1xx 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 STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_EXT STM32L1xx EXT Support
* @details The STM32L1xx EXT driver uses the EXTI peripheral.
*
* @section stm32l1xx_ext_1 Supported HW resources
* - EXTI.
* .
* @section stm32l1xx_ext_2 STM32L1xx 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 STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_GPT STM32L1xx GPT Support
* @details The STM32L1xx GPT driver uses the TIMx peripherals.
*
* @section stm32l1xx_gpt_1 Supported HW resources
* - TIM2.
* - TIM3.
* - TIM4.
* .
* @section stm32l1xx_gpt_2 STM32L1xx 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 STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_ICU STM32L1xx ICU Support
* @details The STM32L1xx ICU driver uses the TIMx peripherals.
*
* @section stm32l1xx_icu_1 Supported HW resources
* - TIM2.
* - TIM3.
* - TIM4.
* .
* @section stm32l1xx_icu_2 STM32L1xx 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 STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_PAL STM32L1xx PAL Support
* @details The STM32L1xx PAL driver uses the GPIO peripherals.
*
* @section stm32l1xx_pal_1 Supported HW resources
* - GPIOA.
* - GPIOB.
* - GPIOC.
* - GPIOD.
* - GPIOE.
* - GPIOH.
* .
* @section stm32l1xx_pal_2 STM32L1xx 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 stm32l1xx_pal_3 Supported PAL setup modes
* The STM32L1xx 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 stm32l1xx_pal_4 Suboptimal behavior
* The STM32L1xx 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 STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_PWM STM32L1xx PWM Support
* @details The STM32L1xx PWM driver uses the TIMx peripherals.
*
* @section stm32l1xx_pwm_1 Supported HW resources
* - TIM1.
* - TIM2.
* - TIM3.
* - TIM4.
* .
* @section stm32l1xx_pwm_2 STM32L1xx 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 STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_SERIAL STM32L1xx Serial Support
* @details The STM32L1xx Serial driver uses the USART/UART peripherals in a
* buffered, interrupt driven, implementation.
*
* @section stm32l1xx_serial_1 Supported HW resources
* The serial driver can support any of the following hardware resources:
* - USART1.
* - USART2.
* - USART3 (where present).
* - UART4 (where present).
* - UART5 (where present).
* .
* @section stm32l1xx_serial_2 STM32L1xx 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 STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_SPI STM32L1xx SPI Support
* @details The SPI driver supports the STM32L1xx SPI peripherals using DMA
* channels for maximum performance.
*
* @section stm32l1xx_spi_1 Supported HW resources
* - SPI1.
* - SPI2.
* - SPI3 (where present).
* - DMA1.
* - DMA2 (where present).
* .
* @section stm32l1xx_spi_2 STM32L1xx 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 STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_UART STM32L1xx UART Support
* @details The UART driver supports the STM32L1xx USART peripherals using DMA
* channels for maximum performance.
*
* @section stm32l1xx_uart_1 Supported HW resources
* The UART driver can support any of the following hardware resources:
* - USART1.
* - USART2.
* - USART3 (where present).
* - DMA1.
* .
* @section stm32l1xx_uart_2 STM32L1xx 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 STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_USB STM32L1xx USB Support
* @details The USB driver supports the STM32L1xx USB peripheral.
*
* @section stm32l1xx_usb_1 Supported HW resources
* The USB driver can support any of the following hardware resources:
* - USB.
* .
* @section stm32l1xx_usb_2 STM32L1xx USB driver implementation features
* - Clock stop for reduced power usage when the driver is in stop state.
* - Programmable interrupt priority levels.
* - Each endpoint programmable in Control, Bulk and Interrupt modes.
* .
* @ingroup STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_PLATFORM_DRIVERS STM32L1xx Platform Drivers
* @details Platform support drivers. Platform drivers do not implement HAL
* standard driver templates, their role is to support platform
* specific functionalities.
*
* @ingroup STM32L1xx_DRIVERS
*/
/**
* @defgroup STM32L1xx_DMA STM32L1xx 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 stm32l1xx_dma_1 Supported HW resources
* The DMA driver can support any of the following hardware resources:
* - DMA1.
* .
* @section stm32l1xx_dma_2 STM32L1xx 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 STM32L1xx_PLATFORM_DRIVERS
*/
/**
* @defgroup STM32L1xx_ISR STM32L1xx ISR Support
* @details This ISR helper driver is used by the other drivers in order to
* map ISR names to physical vector names.
*
* @ingroup STM32L1xx_PLATFORM_DRIVERS
*/
/**
* @defgroup STM32L1xx_RCC STM32L1xx 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 stm32l1xx_rcc_2 STM32L1xx RCC driver implementation features
* - Peripherals reset.
* - Peripherals clock enable.
* - Peripherals clock disable.
* .
* @ingroup STM32L1xx_PLATFORM_DRIVERS
*/

View File

@ -0,0 +1,25 @@
# List of all the STM32L1xx platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32L1xx/stm32_dma.c \
${CHIBIOS}/os/hal/platforms/STM32L1xx/hal_lld.c \
${CHIBIOS}/os/hal/platforms/STM32L1xx/adc_lld.c \
${CHIBIOS}/os/hal/platforms/STM32L1xx/ext_lld_isr.c \
${CHIBIOS}/os/hal/platforms/STM32/ext_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/I2Cv1/i2c_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/SPIv1/spi_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/TIMv1/gpt_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/TIMv1/icu_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/TIMv1/pwm_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/USARTv1/serial_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/USARTv1/uart_lld.c \
${CHIBIOS}/os/hal/platforms/STM32/USBv1/usb_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32L1xx \
${CHIBIOS}/os/hal/platforms/STM32 \
${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 \
${CHIBIOS}/os/hal/platforms/STM32/I2Cv1 \
${CHIBIOS}/os/hal/platforms/STM32/SPIv1 \
${CHIBIOS}/os/hal/platforms/STM32/TIMv1 \
${CHIBIOS}/os/hal/platforms/STM32/USARTv1 \
${CHIBIOS}/os/hal/platforms/STM32/USBv1

View File

@ -0,0 +1,344 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32L1xx/stm32_dma.c
* @brief DMA helper driver code.
*
* @addtogroup STM32L1xx_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
* drivers to coordinate the access to the resource.
* @note The DMA ISR handlers are all declared into this module because
* sharing, the various device drivers can associate a callback to
* ISRs when allocating streams.
* @{
*/
#include "ch.h"
#include "hal.h"
/* The following macro is only defined if some driver requiring DMA services
has been enabled.*/
#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/**
* @brief Mask of the DMA1 streams in @p dma_streams_mask.
*/
#define STM32_DMA1_STREAMS_MASK 0x0000007F
/**
* @brief Mask of the DMA2 streams in @p dma_streams_mask.
*/
#define STM32_DMA2_STREAMS_MASK 0x00000F80
/**
* @brief Post-reset value of the stream CCR register.
*/
#define STM32_DMA_CCR_RESET_VALUE 0x00000000
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief DMA streams descriptors.
* @details This table keeps the association between an unique stream
* identifier and the involved physical registers.
* @note Don't use this array directly, use the appropriate wrapper macros
* instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc.
*/
const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
{DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn},
{DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_IRQn},
{DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel3_IRQn},
{DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_IRQn},
{DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel5_IRQn},
{DMA1_Channel6, &DMA1->IFCR, 20, 5, DMA1_Channel6_IRQn},
{DMA1_Channel7, &DMA1->IFCR, 24, 6, DMA1_Channel7_IRQn}
};
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/**
* @brief DMA ISR redirector type.
*/
typedef struct {
stm32_dmaisr_t dma_func; /**< @brief DMA callback function. */
void *dma_param; /**< @brief DMA callback parameter. */
} dma_isr_redir_t;
/**
* @brief Mask of the allocated streams.
*/
static uint32_t dma_streams_mask;
/**
* @brief DMA IRQ redirectors.
*/
static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS];
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief DMA1 stream 1 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 0;
if (dma_isr_redir[0].dma_func)
dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 2 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch2_IRQHandler) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 4;
if (dma_isr_redir[1].dma_func)
dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 3 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch3_IRQHandler) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 8;
if (dma_isr_redir[2].dma_func)
dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 4 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch4_IRQHandler) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 12;
if (dma_isr_redir[3].dma_func)
dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 5 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 16;
if (dma_isr_redir[4].dma_func)
dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 6 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 20;
if (dma_isr_redir[5].dma_func)
dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/**
* @brief DMA1 stream 7 shared interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
uint32_t flags;
CH_IRQ_PROLOGUE();
flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK;
DMA1->IFCR = STM32_DMA_ISR_MASK << 24;
if (dma_isr_redir[6].dma_func)
dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags);
CH_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief STM32 DMA helper initialization.
*
* @init
*/
void dmaInit(void) {
int i;
dma_streams_mask = 0;
for (i = 0; i < STM32_DMA_STREAMS; i++) {
_stm32_dma_streams[i].channel->CCR = 0;
dma_isr_redir[i].dma_func = NULL;
}
DMA1->IFCR = 0xFFFFFFFF;
}
/**
* @brief Allocates a DMA stream.
* @details The stream is allocated and, if required, the DMA clock enabled.
* The function also enables the IRQ vector associated to the stream
* and initializes its priority.
* @pre The stream must not be already in use or an error is returned.
* @post The stream is allocated and the default ISR handler redirected
* to the specified function.
* @post The stream ISR vector is enabled and its priority configured.
* @post The stream must be freed using @p dmaStreamRelease() before it can
* be reused with another peripheral.
* @post The stream is in its post-reset state.
* @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
* @param[in] priority IRQ priority mask for the DMA stream
* @param[in] func handling function pointer, can be @p NULL
* @param[in] param a parameter to be passed to the handling function
* @return The operation status.
* @retval FALSE no error, stream taken.
* @retval TRUE error, stream already taken.
*
* @special
*/
bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
uint32_t priority,
stm32_dmaisr_t func,
void *param) {
chDbgCheck(dmastp != NULL, "dmaStreamAllocate");
/* Checks if the stream is already taken.*/
if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0)
return TRUE;
/* Marks the stream as allocated.*/
dma_isr_redir[dmastp->selfindex].dma_func = func;
dma_isr_redir[dmastp->selfindex].dma_param = param;
dma_streams_mask |= (1 << dmastp->selfindex);
/* Enabling DMA clocks required by the current streams set.*/
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0)
rccEnableDMA1(FALSE);
/* Putting the stream in a safe state.*/
dmaStreamDisable(dmastp);
dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE;
/* Enables the associated IRQ vector if a callback is defined.*/
if (func != NULL)
nvicEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority));
return FALSE;
}
/**
* @brief Releases a DMA stream.
* @details The stream is freed and, if required, the DMA clock disabled.
* Trying to release a unallocated stream is an illegal operation
* and is trapped if assertions are enabled.
* @pre The stream must have been allocated using @p dmaStreamAllocate().
* @post The stream is again available.
* @note This function can be invoked in both ISR or thread context.
*
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
*
* @special
*/
void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
chDbgCheck(dmastp != NULL, "dmaStreamRelease");
/* Check if the streams is not taken.*/
chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
"dmaStreamRelease(), #1", "not allocated");
/* Disables the associated IRQ vector.*/
nvicDisableVector(dmastp->vector);
/* Marks the stream as not allocated.*/
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)
rccDisableDMA1(FALSE);
}
#endif /* STM32_DMA_REQUIRED */
/** @} */

View File

@ -0,0 +1,396 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32L1xx/stm32_dma.h
* @brief DMA helper driver header.
* @note This file requires definitions from the ST header file stm32l1xx.h.
* @note This driver uses the new naming convention used for the STM32F2xx
* so the "DMA channels" are referred as "DMA streams".
*
* @addtogroup STM32L1xx_DMA
* @{
*/
#ifndef _STM32_DMA_H_
#define _STM32_DMA_H_
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Total number of DMA streams.
* @note This is the total number of streams among all the DMA units.
*/
#define STM32_DMA_STREAMS 7
/**
* @brief Mask of the ISR bits passed to the DMA callback functions.
*/
#define STM32_DMA_ISR_MASK 0x0F
/**
* @brief Returns the channel associated to the specified stream.
*
* @param[in] n the stream number (0...STM32_DMA_STREAMS-1)
* @param[in] c a stream/channel association word, one channel per
* nibble, not associated channels must be set to 0xF
* @return Always zero, in this platform there is no dynamic
* association between streams and channels.
*/
#define STM32_DMA_GETCHANNEL(n, c) 0
/**
* @brief Checks if a DMA priority is within the valid range.
* @param[in] prio DMA priority
*
* @retval The check result.
* @retval FALSE invalid DMA priority.
* @retval TRUE correct DMA priority.
*/
#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0) && ((prio) <= 3))
/**
* @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) ((stream) - 1)
/**
* @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
* @{
*/
/**
* @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_STREAM1 STM32_DMA_STREAM(0)
#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1)
#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(2)
#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(3)
#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4)
#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(5)
#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(6)
/** @} */
/**
* @name CR register constants common to all DMA types
* @{
*/
#define STM32_DMA_CR_EN DMA_CCR1_EN
#define STM32_DMA_CR_TEIE DMA_CCR1_TEIE
#define STM32_DMA_CR_HTIE DMA_CCR1_HTIE
#define STM32_DMA_CR_TCIE DMA_CCR1_TCIE
#define STM32_DMA_CR_DIR_MASK (DMA_CCR1_DIR | DMA_CCR1_MEM2MEM)
#define STM32_DMA_CR_DIR_P2M 0
#define STM32_DMA_CR_DIR_M2P DMA_CCR1_DIR
#define STM32_DMA_CR_DIR_M2M DMA_CCR1_MEM2MEM
#define STM32_DMA_CR_CIRC DMA_CCR1_CIRC
#define STM32_DMA_CR_PINC DMA_CCR1_PINC
#define STM32_DMA_CR_MINC DMA_CCR1_MINC
#define STM32_DMA_CR_PSIZE_MASK DMA_CCR1_PSIZE
#define STM32_DMA_CR_PSIZE_BYTE 0
#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR1_PSIZE_0
#define STM32_DMA_CR_PSIZE_WORD DMA_CCR1_PSIZE_1
#define STM32_DMA_CR_MSIZE_MASK DMA_CCR1_MSIZE
#define STM32_DMA_CR_MSIZE_BYTE 0
#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR1_MSIZE_0
#define STM32_DMA_CR_MSIZE_WORD DMA_CCR1_MSIZE_1
#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_PSIZE_MASK | \
STM32_DMA_CR_MSIZE_MASK)
#define STM32_DMA_CR_PL_MASK DMA_CCR1_PL
#define STM32_DMA_CR_PL(n) ((n) << 12)
/** @} */
/**
* @name CR register constants only found in enhanced DMA
* @{
*/
#define STM32_DMA_CR_DMEIE 0 /**< @brief Ignored by normal DMA. */
#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */
#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal DMA. */
/** @} */
/**
* @name Status flags passed to the ISR callbacks
* @{
*/
#define STM32_DMA_ISR_FEIF 0
#define STM32_DMA_ISR_DMEIF 0
#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1
#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1
#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief STM32 DMA stream descriptor structure.
*/
typedef struct {
DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
uint8_t ishift; /**< @brief Bits offset in xIFCR
register. */
uint8_t selfindex; /**< @brief Index to self in array. */
uint8_t vector; /**< @brief Associated IRQ vector. */
} stm32_dma_stream_t;
/**
* @brief STM32 DMA ISR function type.
*
* @param[in] p parameter for the registered function
* @param[in] flags pre-shifted content of the ISR register, the bits
* are aligned to bit zero
*/
typedef void (*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 CPAR register
*
* @special
*/
#define dmaStreamSetPeripheral(dmastp, addr) { \
(dmastp)->channel->CPAR = (uint32_t)(addr); \
}
/**
* @brief Associates a memory destination to a DMA stream.
* @note This function can be invoked in both ISR or thread context.
* @pre The stream must have been allocated using @p 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 CMAR register
*
* @special
*/
#define dmaStreamSetMemory0(dmastp, addr) { \
(dmastp)->channel->CMAR = (uint32_t)(addr); \
}
/**
* @brief Sets the number of transfers to be performed.
* @note This function can be invoked in both ISR or thread context.
* @pre The stream must have been allocated using @p 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
*
* @special
*/
#define dmaStreamSetTransactionSize(dmastp, size) { \
(dmastp)->channel->CNDTR = (uint32_t)(size); \
}
/**
* @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.
*
* @special
*/
#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR))
/**
* @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 CCR register
*
* @special
*/
#define dmaStreamSetMode(dmastp, mode) { \
(dmastp)->channel->CCR = (uint32_t)(mode); \
}
/**
* @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] dmastp pointer to a stm32_dma_stream_t structure
*
* @special
*/
#define dmaStreamEnable(dmastp) { \
(dmastp)->channel->CCR |= STM32_DMA_CR_EN; \
}
/**
* @brief DMA stream disable.
* @details The function disables the specified stream and then clears any
* pending interrupt.
* @note This function can be invoked in both ISR or thread context.
* @note Interrupts enabling flags are set to zero after this call, see
* bug 3607518.
* @pre The stream must have been allocated using @p dmaStreamAllocate().
* @post After use the stream can be released using @p dmaStreamRelease().
*
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
*
* @special
*/
#define dmaStreamDisable(dmastp) { \
(dmastp)->channel->CCR &= ~(STM32_DMA_CR_TCIE | STM32_DMA_CR_HTIE | \
STM32_DMA_CR_TEIE | STM32_DMA_CR_EN); \
dmaStreamClearInterrupt(dmastp); \
}
/**
* @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
*
* @special
*/
#define dmaStreamClearInterrupt(dmastp) { \
*(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)->channel->CNDTR > 0) \
; \
dmaStreamDisable(dmastp); \
}
/** @} */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if !defined(__DOXYGEN__)
extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
#endif
#ifdef __cplusplus
extern "C" {
#endif
void dmaInit(void);
bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
uint32_t priority,
stm32_dmaisr_t func,
void *param);
void dmaStreamRelease(const stm32_dma_stream_t *dmastp);
#ifdef __cplusplus
}
#endif
#endif /* _STM32_DMA_H_ */
/** @} */

View File

@ -0,0 +1,92 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32L1xx/stm32_isr.h
* @brief ISR remapper driver header.
*
* @addtogroup STM32L1xx_ISR
* @{
*/
#ifndef _STM32_ISR_H_
#define _STM32_ISR_H_
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name ISR names and numbers remapping
* @{
*/
/*
* TIM units.
*/
#define STM32_TIM2_HANDLER TIM2_IRQHandler
#define STM32_TIM3_HANDLER TIM3_IRQHandler
#define STM32_TIM4_HANDLER TIM4_IRQHandler
#define STM32_TIM9_HANDLER TIM9_IRQHandler
#define STM32_TIM2_NUMBER TIM2_IRQn
#define STM32_TIM3_NUMBER TIM3_IRQn
#define STM32_TIM4_NUMBER TIM4_IRQn
#define STM32_TIM9_NUMBER TIM9_IRQn
/*
* USART units.
*/
#define STM32_USART1_HANDLER USART1_IRQHandler
#define STM32_USART2_HANDLER USART2_IRQHandler
#define STM32_USART3_HANDLER USART3_IRQHandler
#define STM32_USART1_NUMBER USART1_IRQn
#define STM32_USART2_NUMBER USART2_IRQn
#define STM32_USART3_NUMBER USART3_IRQn
/*
* USB units.
*/
#define STM32_USB1_HP_HANDLER Vector8C
#define STM32_USB1_LP_HANDLER Vector90
#define STM32_USB1_HP_NUMBER USB_HP_IRQn
#define STM32_USB1_LP_NUMBER USB_LP_IRQn
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#endif /* _STM32_ISR_H_ */
/** @} */

View File

@ -0,0 +1,662 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file STM32L1xx/stm32_rcc.h
* @brief RCC helper driver header.
* @note This file requires definitions from the ST header file
* @p stm32l1xx.h.
*
* @addtogroup STM32L1xx_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 AHB bus.
*
* @param[in] mask AHB peripherals mask
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableAHB(mask, lp) { \
RCC->AHBENR |= (mask); \
if (lp) \
RCC->AHBLPENR |= (mask); \
}
/**
* @brief Disables the clock of one or more peripheral on the AHB bus.
*
* @param[in] mask AHB peripherals mask
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableAHB(mask, lp) { \
RCC->AHBENR &= ~(mask); \
if (lp) \
RCC->AHBLPENR &= ~(mask); \
}
/**
* @brief Resets one or more peripheral on the AHB bus.
*
* @param[in] mask AHB peripherals mask
*
* @api
*/
#define rccResetAHB(mask) { \
RCC->AHBRSTR |= (mask); \
RCC->AHBRSTR = 0; \
}
/** @} */
/**
* @name 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)
/** @} */
/**
* @name DMA peripheral specific RCC operations
* @{
*/
/**
* @brief Enables the DMA1 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
/**
* @brief Disables the DMA1 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableDMA1(lp) rccDisableAHB(RCC_AHBENR_DMA1EN, lp)
/**
* @brief Resets the DMA1 peripheral.
*
* @api
*/
#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
/** @} */
/**
* @name PWR interface specific RCC operations
* @{
*/
/**
* @brief Enables the PWR interface clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnablePWRInterface(lp) rccEnableAPB1(RCC_APB1ENR_PWREN, lp)
/**
* @brief Disables PWR interface clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisablePWRInterface(lp) rccDisableAPB1(RCC_APB1ENR_PWREN, lp)
/**
* @brief Resets the PWR interface.
*
* @api
*/
#define rccResetPWRInterface() rccResetAPB1(RCC_APB1RSTR_PWRRST)
/** @} */
/**
* @name 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)
/** @} */
/**
* @name 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)
/** @} */
/**
* @name TIM peripherals specific RCC operations
* @{
*/
/**
* @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 TIM9 peripheral clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableTIM9(lp) rccEnableAPB2(RCC_APB2ENR_TIM9EN, lp)
/**
* @brief Disables the TIM9 peripheral clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableTIM9(lp) rccDisableAPB2(RCC_APB2ENR_TIM9EN, lp)
/**
* @brief Resets the TIM9 peripheral.
*
* @api
*/
#define rccResetTIM9() rccResetAPB2(RCC_APB2RSTR_TIM9RST)
/**
* @brief Enables the TIM10 peripheral clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableTIM10(lp) rccEnableAPB2(RCC_APB2ENR_TIM10EN, lp)
/**
* @brief Disables the TIM10 peripheral clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableTIM10(lp) rccDisableAPB2(RCC_APB2ENR_TIM10EN, lp)
/**
* @brief Resets the TIM10 peripheral.
*
* @api
*/
#define rccResetTIM10() rccResetAPB2(RCC_APB2RSTR_TIM10RST)
/**
* @brief Enables the TIM10 peripheral clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableTIM11(lp) rccEnableAPB2(RCC_APB2ENR_TIM11EN, lp)
/**
* @brief Disables the TIM11 peripheral clock.
* @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableTIM11(lp) rccDisableAPB2(RCC_APB2ENR_TIM11EN, lp)
/**
* @brief Resets the TIM11 peripheral.
*
* @api
*/
#define rccResetTIM11() rccResetAPB2(RCC_APB2RSTR_TIM11RST)
/** @} */
/**
* @name 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)
/** @} */
/**
* @name USB peripheral specific RCC operations
* @{
*/
/**
* @brief Enables the USB peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
/**
* @brief Disables the USB peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
#define rccDisableUSB(lp) rccDisableAPB1(RCC_APB1ENR_USBEN, lp)
/**
* @brief Resets the USB peripheral.
*
* @api
*/
#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
/** @} */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* _STM32_RCC_ */
/** @} */

View File

@ -0,0 +1,15 @@
# List of the ChibiOS/NIL Cortex-M4 STM32F37x port files.
PORTSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0.c \
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c \
${CHIBIOS}/os/nil/ports/ARMCMx/nilcore.c \
${CHIBIOS}/os/nil/ports/ARMCMx/nilcore_v7m.c
PORTASM = $(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v7m.s
PORTINC = ${CHIBIOS}/os/ext/CMSIS/include \
${CHIBIOS}/os/ext/CMSIS/ST \
${CHIBIOS}/os/common/ports/ARMCMx/devices/STM32F37x \
${CHIBIOS}/os/nil/ports/ARMCMx \
${CHIBIOS}/os/nil/ports/ARMCMx/compilers/GCC
PORTLD = ${CHIBIOS}/os/common/ports/ARMCMx/compilers/GCC/ld

View File

@ -0,0 +1,15 @@
# List of the ChibiOS/NIL Cortex-M0 STM32F4xx port files.
PORTSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0.c \
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c \
${CHIBIOS}/os/nil/ports/ARMCMx/nilcore.c \
${CHIBIOS}/os/nil/ports/ARMCMx/nilcore_v6m.c
PORTASM = $(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v6m.s
PORTINC = ${CHIBIOS}/os/ext/CMSIS/include \
${CHIBIOS}/os/ext/CMSIS/ST \
${CHIBIOS}/os/common/ports/ARMCMx/devices/STM32F4xx \
${CHIBIOS}/os/nil/ports/ARMCMx \
${CHIBIOS}/os/nil/ports/ARMCMx/compilers/GCC
PORTLD = ${CHIBIOS}/os/common/ports/ARMCMx/compilers/GCC/ld

View File

@ -0,0 +1,15 @@
# List of the ChibiOS/RT Cortex-M4 STM32F37x port files.
PORTSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0.c \
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c \
${CHIBIOS}/os/rt/ports/ARMCMx/chcore.c \
${CHIBIOS}/os/rt/ports/ARMCMx/chcore_v7m.c
PORTASM = $(CHIBIOS)/os/rt/ports/ARMCMx/compilers/GCC/chcoreasm_v7m.s
PORTINC = ${CHIBIOS}/os/ext/CMSIS/include \
${CHIBIOS}/os/ext/CMSIS/ST \
${CHIBIOS}/os/common/ports/ARMCMx/devices/STM32F37x \
${CHIBIOS}/os/rt/ports/ARMCMx \
${CHIBIOS}/os/rt/ports/ARMCMx/compilers/GCC
PORTLD = ${CHIBIOS}/os/common/ports/ARMCMx/compilers/GCC/ld