diff --git a/demos/ARMCM3-STM32F103-GCC/Makefile b/demos/ARMCM3-STM32F103-GCC/Makefile index 8f3e902ed..2e65c9c16 100644 --- a/demos/ARMCM3-STM32F103-GCC/Makefile +++ b/demos/ARMCM3-STM32F103-GCC/Makefile @@ -72,6 +72,7 @@ CSRC = ${PORTSRC} \ ${CHIBIOS}/os/io/platforms/STM32/pal_lld.c \ ${CHIBIOS}/os/io/platforms/STM32/serial_lld.c \ ${CHIBIOS}/os/io/platforms/STM32/spi_lld.c \ + ${CHIBIOS}/os/io/platforms/STM32/stm32_dma.c \ ${CHIBIOS}/os/various/evtimer.c \ board.c main.c diff --git a/demos/ARMCM3-STM32F103-GCC/board.c b/demos/ARMCM3-STM32F103-GCC/board.c index 6c8bf8c0a..050c2be62 100644 --- a/demos/ARMCM3-STM32F103-GCC/board.c +++ b/demos/ARMCM3-STM32F103-GCC/board.c @@ -19,10 +19,12 @@ #include #include +#include +#include +#include #include #include "board.h" -#include "serial.h" #define AIRCR_VECTKEY 0x05FA0000 @@ -112,7 +114,9 @@ void hwinit1(void) { /* * Other subsystems initialization. */ + dmaInit(); sdInit(); + spiInit(); /* * ChibiOS/RT initialization. diff --git a/os/io/platforms/STM32/spi_lld.c b/os/io/platforms/STM32/spi_lld.c index fb3021d80..73e55bd43 100644 --- a/os/io/platforms/STM32/spi_lld.c +++ b/os/io/platforms/STM32/spi_lld.c @@ -26,9 +26,8 @@ #include #include - -#include "nvic.h" -#include "board.h" +#include +#include #if USE_STM32_SPI1 || defined(__DOXYGEN__) /** @brief SPI1 driver identifier.*/ @@ -200,15 +199,17 @@ void spi_lld_init(void) { */ void spi_lld_start(SPIDriver *spip) { - /* If in stopped state then enables the SPI clock.*/ + /* If in stopped state then enables the SPI and DMA clocks.*/ if (spip->spd_state == SPI_STOP) { #if USE_STM32_SPI1 if (&SPID1 == spip) { + dmaEnable(DMA1_ID); RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; } #endif #if USE_STM32_SPI2 if (&SPID2 == spip) { + dmaEnable(DMA1_ID); RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; } #endif @@ -248,11 +249,13 @@ void spi_lld_stop(SPIDriver *spip) { if (spip->spd_state == SPI_READY) { #if USE_STM32_SPI1 if (&SPID1 == spip) { + dmaDisable(DMA1_ID); RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN; } #endif #if USE_STM32_SPI2 if (&SPID2 == spip) { + dmaDisable(DMA1_ID); RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN; } #endif diff --git a/os/io/platforms/STM32/stm32_dma.c b/os/io/platforms/STM32/stm32_dma.c new file mode 100644 index 000000000..d78a058d9 --- /dev/null +++ b/os/io/platforms/STM32/stm32_dma.c @@ -0,0 +1,89 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 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 . +*/ + +/** + * @file stm32_dma.c + * @brief STM32 DMA helper driver code + * @addtogroup STM32_DMA + * @{ + */ + +#include + +#include "stm32_dma.h" + +static cnt_t dmacnt1; +#if defined(STM32F10X_HD) || defined (STM32F10X_CL) +static cnt_t dmacnt2; +#endif + +/** + * @brief STM32 DMA helper initialization. + */ +void dmaInit(void) { + + dmacnt1 = 0; +#if defined(STM32F10X_HD) || defined (STM32F10X_CL) + dmacnt2 = 0; +#endif +} + +/** + * @brief Enables the specified DMA controller clock. + * + * @param[in] dma the DMA controller id + */ +void dmaEnable(uint32_t dma) { + + switch (dma) { + case DMA1_ID: + if (dmacnt1++ == 0) + RCC->AHBENR |= RCC_AHBENR_DMA1EN; + break; +#if defined(STM32F10X_HD) || defined (STM32F10X_CL) + case DMA2_ID: + if (dmacnt2++ == 0) + RCC->AHBENR |= RCC_AHBENR_DMA2EN; + break; +#endif + } +} + +/** + * @brief Disables the specified DMA controller clock. + * + * @param[in] dma the DMA controller id + */ +void dmaDisable(uint32_t dma) { + + switch (dma) { + case DMA1_ID: + if (--dmacnt1 == 0) + RCC->AHBENR &= ~RCC_AHBENR_DMA1EN; + break; +#if defined(STM32F10X_HD) || defined (STM32F10X_CL) + case DMA2_ID: + if (--dmacnt2 == 0) + RCC->AHBENR &= ~RCC_AHBENR_DMA2EN; + break; +#endif + } +} + +/** @} */ diff --git a/os/io/platforms/STM32/stm32_dma.h b/os/io/platforms/STM32/stm32_dma.h new file mode 100644 index 000000000..c22ff0100 --- /dev/null +++ b/os/io/platforms/STM32/stm32_dma.h @@ -0,0 +1,56 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 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 . +*/ + +/** + * @file stm32_dma.h + * @brief STM32 DMA helper driver header + * @addtogroup STM32_DMA + * @{ + */ + +#ifndef _STM32_DMA_H_ +#define _STM32_DMA_H_ + +#undef FALSE +#undef TRUE +#include +#define FALSE 0 +#define TRUE (!FALSE) + +/** @brief DMA1 identifier.*/ +#define DMA1_ID 0 + +/** @brief DMA2 identifier.*/ +#if defined(STM32F10X_HD) || defined (STM32F10X_CL) || defined(__DOXYGEN__) +#define DMA2_ID 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + void dmaEnable(uint32_t dma); + void dmaDisable(uint32_t dma); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */