From 048acf5bdfa3bde321f12104e4bd24a50a95738f Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 18 Jun 2015 09:43:47 +0000 Subject: Added CAN support for STM32F0xx. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8046 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/can_lld.c | 82 +++++++++++++++++++++++++++ os/hal/ports/STM32/STM32F0xx/platform.mk | 4 ++ os/hal/ports/STM32/STM32F0xx/stm32_isr.h | 5 ++ os/hal/ports/STM32/STM32F0xx/stm32_rcc.h | 32 +++++++++++ os/hal/ports/STM32/STM32F0xx/stm32_registry.h | 6 ++ 5 files changed, 129 insertions(+) (limited to 'os/hal') diff --git a/os/hal/ports/STM32/LLD/can_lld.c b/os/hal/ports/STM32/LLD/can_lld.c index 44cb95281..7bca76d8e 100644 --- a/os/hal/ports/STM32/LLD/can_lld.c +++ b/os/hal/ports/STM32/LLD/can_lld.c @@ -252,6 +252,38 @@ static void can_lld_sce_handler(CANDriver *canp) { /*===========================================================================*/ #if STM32_CAN_USE_CAN1 || defined(__DOXYGEN__) +#if defined(STM32_CAN1_UNIFIED_HANDLER) +/** + * @brief CAN1 unified interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_CAN1_UNIFIED_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + can_lld_tx_handler(&CAND1); + can_lld_rx0_handler(&CAND1); + can_lld_rx1_handler(&CAND1); + can_lld_sce_handler(&CAND1); + + OSAL_IRQ_EPILOGUE(); +} +#else /* !defined(STM32_CAN1_UNIFIED_HANDLER) */ + +#if !defined(STM32_CAN1_TX_HANDLER) +#error "STM32_CAN1_TX_HANDLER not defined" +#endif +#if !defined(STM32_CAN1_RX0_HANDLER) +#error "STM32_CAN1_RX0_HANDLER not defined" +#endif +#if !defined(STM32_CAN1_RX1_HANDLER) +#error "STM32_CAN1_RX1_HANDLER not defined" +#endif +#if !defined(STM32_CAN1_SCE_HANDLER) +#error "STM32_CAN1_SCE_HANDLER not defined" +#endif + /** * @brief CAN1 TX interrupt handler. * @@ -307,9 +339,42 @@ OSAL_IRQ_HANDLER(STM32_CAN1_SCE_HANDLER) { OSAL_IRQ_EPILOGUE(); } +#endif /* !defined(STM32_CAN1_UNIFIED_HANDLER) */ #endif /* STM32_CAN_USE_CAN1 */ #if STM32_CAN_USE_CAN2 || defined(__DOXYGEN__) +#if defined(STM32_CAN2_UNIFIED_HANDLER) +/** + * @brief CAN1 unified interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_CAN2_UNIFIED_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + can_lld_tx_handler(&CAND2); + can_lld_rx0_handler(&CAND2); + can_lld_rx1_handler(&CAND2); + can_lld_sce_handler(&CAND2); + + OSAL_IRQ_EPILOGUE(); +} +#else /* !defined(STM32_CAN2_UNIFIED_HANDLER) */ + +#if !defined(STM32_CAN1_TX_HANDLER) +#error "STM32_CAN1_TX_HANDLER not defined" +#endif +#if !defined(STM32_CAN1_RX0_HANDLER) +#error "STM32_CAN1_RX0_HANDLER not defined" +#endif +#if !defined(STM32_CAN1_RX1_HANDLER) +#error "STM32_CAN1_RX1_HANDLER not defined" +#endif +#if !defined(STM32_CAN1_SCE_HANDLER) +#error "STM32_CAN1_SCE_HANDLER not defined" +#endif + /** * @brief CAN2 TX interrupt handler. * @@ -365,6 +430,7 @@ OSAL_IRQ_HANDLER(STM32_CAN2_SCE_HANDLER) { OSAL_IRQ_EPILOGUE(); } +#endif /* !defined(STM32_CAN2_UNIFIED_HANDLER) */ #endif /* STM32_CAN_USE_CAN2 */ /*===========================================================================*/ @@ -409,10 +475,14 @@ void can_lld_start(CANDriver *canp) { /* Clock activation.*/ #if STM32_CAN_USE_CAN1 if (&CAND1 == canp) { +#if defined(STM32_CAN1_UNIFIED_NUMBER) + nvicEnableVector(STM32_CAN1_UNIFIED_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY); +#else nvicEnableVector(STM32_CAN1_TX_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY); nvicEnableVector(STM32_CAN1_RX0_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY); nvicEnableVector(STM32_CAN1_RX1_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY); nvicEnableVector(STM32_CAN1_SCE_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY); +#endif rccEnableCAN1(FALSE); } #endif @@ -421,10 +491,14 @@ void can_lld_start(CANDriver *canp) { osalDbgAssert(CAND1.state != CAN_STOP, "CAN1 must be started"); +#if defined(STM32_CAN2_UNIFIED_NUMBER) + nvicEnableVector(STM32_CAN2_UNIFIED_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY); +#else nvicEnableVector(STM32_CAN2_TX_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY); nvicEnableVector(STM32_CAN2_RX0_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY); nvicEnableVector(STM32_CAN2_RX1_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY); nvicEnableVector(STM32_CAN2_SCE_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY); +#endif rccEnableCAN2(FALSE); } #endif @@ -463,10 +537,14 @@ void can_lld_stop(CANDriver *canp) { CAN1->MCR = 0x00010002; /* Register reset value. */ CAN1->IER = 0x00000000; /* All sources disabled. */ +#if defined(STM32_CAN1_UNIFIED_NUMBER) + nvicDisableVector(STM32_CAN1_UNIFIED_NUMBER); +#else nvicDisableVector(STM32_CAN1_TX_NUMBER); nvicDisableVector(STM32_CAN1_RX0_NUMBER); nvicDisableVector(STM32_CAN1_RX1_NUMBER); nvicDisableVector(STM32_CAN1_SCE_NUMBER); +#endif rccDisableCAN1(FALSE); } #endif @@ -474,10 +552,14 @@ void can_lld_stop(CANDriver *canp) { if (&CAND2 == canp) { CAN2->MCR = 0x00010002; /* Register reset value. */ CAN2->IER = 0x00000000; /* All sources disabled. */ +#if defined(STM32_CAN2_UNIFIED_NUMBER) + nvicDisableVector(STM32_CAN2_UNIFIED_NUMBER); +#else nvicDisableVector(STM32_CAN2_TX_NUMBER); nvicDisableVector(STM32_CAN2_RX0_NUMBER); nvicDisableVector(STM32_CAN2_RX1_NUMBER); nvicDisableVector(STM32_CAN2_SCE_NUMBER); +#endif rccDisableCAN2(FALSE); } #endif diff --git a/os/hal/ports/STM32/STM32F0xx/platform.mk b/os/hal/ports/STM32/STM32F0xx/platform.mk index 0da61dc5a..02fd58fb4 100644 --- a/os/hal/ports/STM32/STM32F0xx/platform.mk +++ b/os/hal/ports/STM32/STM32F0xx/platform.mk @@ -13,6 +13,9 @@ ifneq ($(findstring HAL_USE_EXT TRUE,$(HALCONF)),) PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/ext_lld_isr.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/ext_lld.c endif +ifneq ($(findstring HAL_USE_CAN TRUE,$(HALCONF)),) +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/can_lld.c +endif ifneq ($(findstring HAL_USE_DAC TRUE,$(HALCONF)),) PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/dac_lld.c endif @@ -52,6 +55,7 @@ PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \ $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/hal_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/adc_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/ext_lld_isr.c \ + $(CHIBIOS)/os/hal/ports/STM32/LLD/can_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/ext_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/dac_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c \ diff --git a/os/hal/ports/STM32/STM32F0xx/stm32_isr.h b/os/hal/ports/STM32/STM32F0xx/stm32_isr.h index 4b636afa4..f3db0c5f5 100644 --- a/os/hal/ports/STM32/STM32F0xx/stm32_isr.h +++ b/os/hal/ports/STM32/STM32F0xx/stm32_isr.h @@ -33,6 +33,11 @@ * @name ISR names and numbers remapping * @{ */ +/* + * CAN units. + */ +#define STM32_CAN1_UNIFIED_HANDLER VectorB8 +#define STM32_CAN1_UNIFIED_NUMBER 30 /* * I2C units. diff --git a/os/hal/ports/STM32/STM32F0xx/stm32_rcc.h b/os/hal/ports/STM32/STM32F0xx/stm32_rcc.h index 9d6be2b3d..f51687787 100644 --- a/os/hal/ports/STM32/STM32F0xx/stm32_rcc.h +++ b/os/hal/ports/STM32/STM32F0xx/stm32_rcc.h @@ -198,6 +198,38 @@ #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_CANEN, 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_CANEN, lp) + +/** + * @brief Resets the CAN1 peripheral. + * + * @api + */ +#define rccResetCAN1() rccResetAPB1(RCC_APB1RSTR_CANRST) +/** @} */ + /** * @name DAC peripheral specific RCC operations * @{ diff --git a/os/hal/ports/STM32/STM32F0xx/stm32_registry.h b/os/hal/ports/STM32/STM32F0xx/stm32_registry.h index c3d346c19..a36ec839b 100644 --- a/os/hal/ports/STM32/STM32F0xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32F0xx/stm32_registry.h @@ -203,7 +203,12 @@ #define STM32_HAS_ADC4 FALSE /* CAN attributes.*/ +#if defined(STM32F072xB) +#define STM32_HAS_CAN1 TRUE +#define STM32_CAN_MAX_FILTERS 14 +#else #define STM32_HAS_CAN1 FALSE +#endif #define STM32_HAS_CAN2 FALSE /* DAC attributes.*/ @@ -655,6 +660,7 @@ /* CAN attributes.*/ #define STM32_HAS_CAN1 TRUE #define STM32_HAS_CAN2 FALSE +#define STM32_CAN_MAX_FILTERS 14 /* DAC attributes.*/ #define STM32_HAS_DAC1_CH1 FALSE -- cgit v1.2.3