From 0aa2dd05114a68ac0e0a23fe8227215a13e2c77b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 25 Aug 2011 15:14:09 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3253 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/DMAv1/sdc_lld.h | 2 +- os/hal/platforms/STM32/DMAv1/stm32_dma.c | 5 - os/hal/platforms/STM32/DMAv1/stm32_dma.h | 11 +- os/hal/platforms/STM32/DMAv2/stm32_dma.c | 487 +++++++++++++++++++++++++++++++ os/hal/platforms/STM32/DMAv2/stm32_dma.h | 235 +++++++++++++++ os/hal/platforms/STM32/GPIOv1/pal_lld.c | 4 +- os/hal/platforms/STM32/GPIOv1/pal_lld.h | 4 +- 7 files changed, 732 insertions(+), 16 deletions(-) create mode 100644 os/hal/platforms/STM32/DMAv2/stm32_dma.c create mode 100644 os/hal/platforms/STM32/DMAv2/stm32_dma.h (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/DMAv1/sdc_lld.h b/os/hal/platforms/STM32/DMAv1/sdc_lld.h index 5466eacad..eea76dadd 100644 --- a/os/hal/platforms/STM32/DMAv1/sdc_lld.h +++ b/os/hal/platforms/STM32/DMAv1/sdc_lld.h @@ -152,7 +152,7 @@ struct SDCDriver { uint32_t rca; /* End of the mandatory fields.*/ /** - * @brief Tthread waiting for I/O completion IRQ. + * @brief Thread waiting for I/O completion IRQ. */ Thread *thread; }; diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.c b/os/hal/platforms/STM32/DMAv1/stm32_dma.c index 2232df448..4ea8e99ee 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.c +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.c @@ -366,17 +366,12 @@ void dmaInit(void) { * @param[in] channel requested channel id * @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 operation successfully allocated. - * @retval TRUE the channel was already in use. * * @special */ void dmaAllocate(uint32_t dma, uint32_t channel, stm32_dmaisr_t func, void *param) { - chDbgCheck(func != NULL, "dmaAllocate"); - #if STM32_HAS_DMA2 switch (dma) { case STM32_DMA1_ID: diff --git a/os/hal/platforms/STM32/DMAv1/stm32_dma.h b/os/hal/platforms/STM32/DMAv1/stm32_dma.h index 66a2f8c69..7ef5ad8b9 100644 --- a/os/hal/platforms/STM32/DMAv1/stm32_dma.h +++ b/os/hal/platforms/STM32/DMAv1/stm32_dma.h @@ -22,7 +22,7 @@ * @file stm32_dma.h * @brief STM32 DMA helper driver header. * @note This file requires definitions from the ST STM32 header file - * stm3232f10x.h. + * stm32f10x.h. * * @addtogroup STM32_DMA * @{ @@ -154,7 +154,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * data register. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp dmachp to a stm32_dma_channel_t structure + * @param[in] dmachp pointer to a stm32_dma_channel_t structure * @param[in] cndtr value to be written in the CNDTR register * @param[in] cmar value to be written in the CMAR register * @param[in] ccr value to be written in the CCR register @@ -171,7 +171,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @brief DMA channel enable by channel pointer. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp dmachp to a stm32_dma_channel_t structure + * @param[in] dmachp pointer to a stm32_dma_channel_t structure * * @special */ @@ -179,12 +179,11 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); (dmachp)->CCR |= DMA_CCR1_EN; \ } - /** * @brief DMA channel disable by channel pointer. * @note This function can be invoked in both ISR or thread context. * - * @param[in] dmachp dmachp to a stm32_dma_channel_t structure + * @param[in] dmachp pointer to a stm32_dma_channel_t structure * * @special */ @@ -256,7 +255,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * * @special */ -#define dmaClearChannel(dmap, ch){ \ +#define dmaClearChannel(dmap, ch) { \ (dmap)->IFCR = 1 << ((ch) * 4); \ } diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.c b/os/hal/platforms/STM32/DMAv2/stm32_dma.c new file mode 100644 index 000000000..d64cfc5f9 --- /dev/null +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.c @@ -0,0 +1,487 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file DMAv2/stm32_dma.c + * @brief STM32F2xx Enhanced DMA helper driver code. + * + * @addtogroup STM32_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 + * IRSs 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 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_STREAM0, @p STM32_DMA1_STREAM1 etc. + */ +const stm32_dma_stream_t _stm32_dma_streams[16] = { + {0, DMA1, DMA1_Stream0, &DMA1->LISR, &DMA1->LIFCR, 0}, + {1, DMA1, DMA1_Stream1, &DMA1->LISR, &DMA1->LIFCR, 6}, + {2, DMA1, DMA1_Stream2, &DMA1->LISR, &DMA1->LIFCR, 16}, + {3, DMA1, DMA1_Stream3, &DMA1->LISR, &DMA1->LIFCR, 22}, + {4, DMA1, DMA1_Stream4, &DMA1->HISR, &DMA1->HIFCR, 0}, + {5, DMA1, DMA1_Stream5, &DMA1->HISR, &DMA1->HIFCR, 6}, + {6, DMA1, DMA1_Stream6, &DMA1->HISR, &DMA1->HIFCR, 16}, + {7, DMA1, DMA1_Stream7, &DMA1->HISR, &DMA1->HIFCR, 22}, + {8, DMA2, DMA2_Stream0, &DMA2->LISR, &DMA2->LIFCR, 0}, + {9, DMA2, DMA2_Stream1, &DMA2->LISR, &DMA2->LIFCR, 6}, + {10, DMA2, DMA2_Stream2, &DMA2->LISR, &DMA2->LIFCR, 16}, + {11, DMA2, DMA2_Stream3, &DMA2->LISR, &DMA2->LIFCR, 22}, + {12, DMA2, DMA2_Stream4, &DMA2->HISR, &DMA2->HIFCR, 0}, + {13, DMA2, DMA2_Stream5, &DMA2->HISR, &DMA2->HIFCR, 6}, + {14, DMA2, DMA2_Stream6, &DMA2->HISR, &DMA2->HIFCR, 16}, + {15, DMA2, DMA2_Stream7, &DMA2->HISR, &DMA2->HIFCR, 22}, +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief DMA ISR redirector type. + */ +typedef struct { + stm32_dmaisr_t dma_func; + void *dma_param; +} 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 0 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream0_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = 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 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 6) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 16; + 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 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->LISR >> 22) & STM32_DMA_ISR_MASK; + DMA1->LIFCR = STM32_DMA_ISR_MASK << 22; + 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 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 0; + 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 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 6) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 6; + 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 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 16) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Stream7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->HISR >> 22) & STM32_DMA_ISR_MASK; + DMA1->HIFCR = STM32_DMA_ISR_MASK << 22; + 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 0 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream0_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 0; + 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 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 6) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 6; + 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 2 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream2_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 16; + 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 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->LISR >> 22) & STM32_DMA_ISR_MASK; + DMA2->LIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[11].dma_func) + dma_isr_redir[11].dma_func(dma_isr_redir[11].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 4 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream4_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 0) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[12].dma_func) + dma_isr_redir[12].dma_func(dma_isr_redir[12].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 6) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 6; + if (dma_isr_redir[13].dma_func) + dma_isr_redir[13].dma_func(dma_isr_redir[13].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 6 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream6_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 16) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[14].dma_func) + dma_isr_redir[14].dma_func(dma_isr_redir[14].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA2 stream 7 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA2_Stream7_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA2->HISR >> 22) & STM32_DMA_ISR_MASK; + DMA2->HIFCR = STM32_DMA_ISR_MASK << 22; + if (dma_isr_redir[15].dma_func) + dma_isr_redir[15].dma_func(dma_isr_redir[15].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA helper initialization. + * + * @init + */ +void dmaInit(void) { + stm32_dma_stream_t *stp; + + dma_streams_mask = 0; + for (i = 0 - 1; i < STM32_DMA_STREAMS; i--) { + _stm32_dma_streams[i]->stream->CR = 0; + dma_isr_redir[i].dma_func = NULL; + } + DMA1->LIFCR = 0xFFFFFFFF; + DMA1->HIFCR = 0xFFFFFFFF; + DMA2->LIFCR = 0xFFFFFFFF; + DMA2->HIFCR = 0xFFFFFFFF; +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * Trying to allocate a stream already allocated is an illegal + * operation and is trapped if assertions are enabled. + * @pre The stream must not be already in use. + * @post The stream is allocated and the default ISR handler redirected + * to the specified function. + * @post The stream must be freed using @p dmaRelease() before it can + * be reused with another peripheral. + * @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] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * + * @special + */ +void dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param) { + + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + chDbgAssert((dma_streams_mask & dmastp->mask) == 0, + "dmaAllocate(), #1", "already allocated"); + + /* 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 & 0x000000FF) != 0) + RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; + if ((dma_streams_mask & 0x0000FF00) != 0) + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + + /* Making sure there are no spurious interrupts flags pending.*/ + dmaStreamClearInterrupt(); +} + +/** + * @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 dmaRequest(). + * @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 dmaRelease(stm32_dma_stream_t *dmastp) { + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & dmastp->mask) != 0, + "dmaRelease(), #1", "not allocated"); + + /* 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 & 0x000000FF) == 0) + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN; + if ((dma_streams_mask & 0x0000FF00) == 0) + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN; +} + +#endif /* STM32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/platforms/STM32/DMAv2/stm32_dma.h b/os/hal/platforms/STM32/DMAv2/stm32_dma.h new file mode 100644 index 000000000..805fd7c4b --- /dev/null +++ b/os/hal/platforms/STM32/DMAv2/stm32_dma.h @@ -0,0 +1,235 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file DMAv2/stm32_dma.h + * @brief STM32F2xx Enhanced DMA helper driver header. + * @note This file requires definitions from the ST STM32F2xx header file + * stm32f2xx.h. + * + * @addtogroup STM32_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 16 + +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define STM32_DMA_ISR_MASK 0x3D + +/** + * @name DMA streams identifiers + * @{ + */ +#define STM32_DMA1_STREAM0 (&_stm32_dma_streams[0]) +#define STM32_DMA1_STREAM1 (&_stm32_dma_streams[1]) +#define STM32_DMA1_STREAM2 (&_stm32_dma_streams[2]) +#define STM32_DMA1_STREAM3 (&_stm32_dma_streams[3]) +#define STM32_DMA1_STREAM4 (&_stm32_dma_streams[4]) +#define STM32_DMA1_STREAM5 (&_stm32_dma_streams[5]) +#define STM32_DMA1_STREAM6 (&_stm32_dma_streams[6]) +#define STM32_DMA1_STREAM7 (&_stm32_dma_streams[7]) +#define STM32_DMA2_STREAM0 (&_stm32_dma_streams[8]) +#define STM32_DMA2_STREAM1 (&_stm32_dma_streams[9]) +#define STM32_DMA2_STREAM2 (&_stm32_dma_streams[10]) +#define STM32_DMA2_STREAM3 (&_stm32_dma_streams[11]) +#define STM32_DMA2_STREAM4 (&_stm32_dma_streams[12]) +#define STM32_DMA2_STREAM5 (&_stm32_dma_streams[13]) +#define STM32_DMA2_STREAM6 (&_stm32_dma_streams[14]) +#define STM32_DMA2_STREAM7 (&_stm32_dma_streams[15]) +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA stream descriptor structure. + */ +typedef struct { + uint32_t selfindex; /**< @brief Index to self in array. */ + DMA_TypeDef *dma; /**< @brief Associated DMA unit. */ + DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */ + volatile uint32_t *isr; /**< @brief Associated xISR reg. */ + volatile uint32_t *ifcr; /**< @brief Associated xIFCR reg. */ + uint32_t ishift; /**< @brief Bits offset in xISR and + xIFCR registers. */ +} 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 xISR register, the bits + * are aligned to bit zero + */ +typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Associates a peripheral data register to a DMA stream. + * @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] addr value to be written in the PAR register + * + * @special + */ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->stream->PAR = (uint32_t)(addr); \ +} + +/** + * @brief Associates a memory destination to a DMA stream. + * @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] addr value to be written in the M0AR register + * + * @special + */ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->stream->M0AR = (uint32_t)(addr); \ +} + +/** + * @brief Associates an alternate memory destination to a DMA stream. + * @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] addr value to be written in the M1AR register + * + * @special + */ +#define dmaStreamSetMemory1(dmastp, addr) { \ + (dmastp)->stream->M1AR = (uint32_t)(addr); \ +} + +/** + * @brief Associates an alternate memory destination to a DMA stream. + * @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] size value to be written in the NDTR register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->stream->NDTR = (uint32_t)(size); \ +} + +/** + * @brief Programs the stream mode settings. + * @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] mode1 value to be written in the FCR register + * @param[in] mode2 value to be written in the CR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode1, mode2) { \ + (dmastp)->stream->FCR = (uint32_t)(mode1); \ + (dmastp)->stream->CR = (uint32_t)(mode2); \ +} + +/** + * @brief DMA stream enable. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmachp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamEnable(dmachp) { \ + (dmastp)->stream->CR |= DMA_SxCR_EN; \ +} + +/** + * @brief DMA stream disable. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->stream->CR &= ~DMA_SxCR_EN; \ +} + +/** + * @brief DMA stream interrupt sources clear. + * @details Sets the appropriate CGIF bit into the IFCR register in order to + * withdraw all the pending interrupt bits from the ISR register. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamClearInterrupt(dmastp) { \ + *(dmastp)->stream->ifcr = STM32_DMA_ISR_MASK << (dmastp)->stream->ishift; \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined() +extern _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + void dmaAllocate(stm32_dma_stream_t *dmastp, + stm32_dmaisr_t func, void *param); + void dmaRelease(stm32_dma_stream_t *dmastp); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.c b/os/hal/platforms/STM32/GPIOv1/pal_lld.c index a0a1fb6e5..81846fa58 100644 --- a/os/hal/platforms/STM32/GPIOv1/pal_lld.c +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.c @@ -19,8 +19,8 @@ */ /** - * @file STM32/pal_lld.c - * @brief STM32 GPIO low level driver code. + * @file STM32/GPIOv1/pal_lld.c + * @brief STM32F1xx GPIO low level driver code. * * @addtogroup PAL * @{ diff --git a/os/hal/platforms/STM32/GPIOv1/pal_lld.h b/os/hal/platforms/STM32/GPIOv1/pal_lld.h index fe2102637..65e660944 100644 --- a/os/hal/platforms/STM32/GPIOv1/pal_lld.h +++ b/os/hal/platforms/STM32/GPIOv1/pal_lld.h @@ -19,8 +19,8 @@ */ /** - * @file STM32/pal_lld.h - * @brief STM32 GPIO low level driver header. + * @file STM32/GPIOv1/pal_lld.h + * @brief STM32F1xx GPIO low level driver header. * * @addtogroup PAL * @{ -- cgit v1.2.3