diff options
author | Michael Walker <walkerstop@gmail.com> | 2018-05-02 03:37:31 -0700 |
---|---|---|
committer | Michael Walker <walkerstop@gmail.com> | 2018-05-02 03:37:31 -0700 |
commit | cd7559268dcc2da5f2b1f3872e6baa1cff1d5476 (patch) | |
tree | 0cf31de069f9df06a13743eab4e1879f05ce9c12 /os/hal/ports/TIVA/LLD/uDMA | |
parent | 4d7ccdd1fce0c95c57129b80c81fab829daf9f99 (diff) | |
parent | 457afa6202fe9f8e6accb65411629172bb32c41b (diff) | |
download | ChibiOS-Contrib-cd7559268dcc2da5f2b1f3872e6baa1cff1d5476.tar.gz ChibiOS-Contrib-cd7559268dcc2da5f2b1f3872e6baa1cff1d5476.tar.bz2 ChibiOS-Contrib-cd7559268dcc2da5f2b1f3872e6baa1cff1d5476.zip |
Merge branch 'master' into mike
Diffstat (limited to 'os/hal/ports/TIVA/LLD/uDMA')
-rw-r--r-- | os/hal/ports/TIVA/LLD/uDMA/driver.mk | 2 | ||||
-rw-r--r-- | os/hal/ports/TIVA/LLD/uDMA/tiva_udma.c | 151 | ||||
-rw-r--r-- | os/hal/ports/TIVA/LLD/uDMA/tiva_udma.h | 162 |
3 files changed, 315 insertions, 0 deletions
diff --git a/os/hal/ports/TIVA/LLD/uDMA/driver.mk b/os/hal/ports/TIVA/LLD/uDMA/driver.mk new file mode 100644 index 0000000..3a2d929 --- /dev/null +++ b/os/hal/ports/TIVA/LLD/uDMA/driver.mk @@ -0,0 +1,2 @@ +PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.c +PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/uDMA diff --git a/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.c b/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.c new file mode 100644 index 0000000..2d18ff5 --- /dev/null +++ b/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.c @@ -0,0 +1,151 @@ +/* + Copyright (C) 2014..2017 Marco Veeneman + + 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 uDMA/tiva_udma.c + * @brief DMA helper driver code. + * + * @addtogroup TIVA_DMA + * @{ + */ + +#include "hal.h" + +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ +#if defined(TIVA_UDMA_REQUIRED) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +udmaControlTable_t udmaControlTable; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +static uint32_t udma_channel_mask; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if !defined(TIVA_UDMA_SW_HANDLER) +#error "TIVA_UDMA_SW_HANDLER not defined" +#endif +/** + * @brief UDMA software interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(TIVA_UDMA_SW_HANDLER) +{ + OSAL_IRQ_PROLOGUE(); + + /* TODO Process software transfer interrupts.*/ + + OSAL_IRQ_EPILOGUE(); +} + +#if !defined(TIVA_UDMA_ERR_HANDLER) +#error "TIVA_UDMA_ERR_HANDLER not defined" +#endif +/** + * @brief UDMA error interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(TIVA_UDMA_ERR_HANDLER) +{ + OSAL_IRQ_PROLOGUE(); + + /* TODO Do we need to halt the system on a DMA error?*/ + + if (HWREG(UDMA_ERRCLR)) { + HWREG(UDMA_ERRCLR) = 1; + } + + OSAL_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Initialize UDMA. + * + * @init + */ +void udmaInit(void) +{ + udma_channel_mask = 0; + + /* Enable UDMA module.*/ + HWREG(SYSCTL_RCGCDMA) = 1; + while (!(HWREG(SYSCTL_PRDMA) & (1 << 0))) + ; + + nvicEnableVector(TIVA_UDMA_ERR_NUMBER, TIVA_UDMA_ERR_IRQ_PRIORITY); + nvicEnableVector(TIVA_UDMA_SW_NUMBER, TIVA_UDMA_SW_IRQ_PRIORITY); + + /* Enable UDMA controller.*/ + HWREG(UDMA_CFG) = UDMA_CFG_MASTEN; + + /* Set address of control table.*/ + HWREG(UDMA_CTLBASE) = (uint32_t)udmaControlTable.primary; +} + +/** + * @brief Allocates a DMA channel. + * + * @special + */ +bool udmaChannelAllocate(uint8_t dmach) +{ + /* Checks if the channel is already taken.*/ + if ((udma_channel_mask & (1 << dmach)) != 0) + return TRUE; + + /* Mark channel as used */ + udma_channel_mask |= (1 << dmach); + + return FALSE; +} + +/** + * @brief Releases a DMA channel. + * + * @special + */ +void udmaChannelRelease(uint8_t dmach) +{ + /* Marks the channel as not used.*/ + udma_channel_mask &= ~(1 << dmach); +} + +#endif + +/** @} */ diff --git a/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.h b/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.h new file mode 100644 index 0000000..a473f6c --- /dev/null +++ b/os/hal/ports/TIVA/LLD/uDMA/tiva_udma.h @@ -0,0 +1,162 @@ +/* + Copyright (C) 2014..2017 Marco Veeneman + + 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 uDMA/tiva_udma.h + * @brief DMA helper driver header. + * + * @addtogroup TIVA_DMA + * @{ + */ + +#ifndef TIVA_UDMA_H_ +#define TIVA_UDMA_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief CHCTL XFERSIZE helper. + */ +#define UDMA_CHCTL_XFERSIZE(n) (((n)-1) << 4) + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief UDMA software interrupt priority level setting. + */ +#if !defined(TIVA_UDMA_SW_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define TIVA_UDMA_SW_IRQ_PRIORITY 5 +#endif + +/** + * @brief UDMA error interrupt priority level setting. + */ +#if !defined(TIVA_UDMA_ERR_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define TIVA_UDMA_ERR_IRQ_PRIORITY 5 +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief A structure that defines an entry in the channel control table. + * @note These fields are used by the uDMA controller and normally it is not + * necessary for software to directly read or write fields in the + * table. + */ +typedef struct __attribute__((packed)) +{ + /** + * @brief The ending source address of the data transfer. + */ + volatile void *srcendp; + /** + * @brief The ending destination address of the data transfer. + */ + volatile void *dstendp; + /** + * @brief The channel control mode. + */ + volatile uint32_t chctl; + /** + * @brief An unused location. + */ + volatile uint32_t unused; +} tiva_udma_table_entry_t; + +typedef struct __attribute__((packed, aligned(1024))) +{ + union { + struct { + tiva_udma_table_entry_t primary[32]; + tiva_udma_table_entry_t alternate[32]; + }; + uint8_t raw[1024]; + }; +} udmaControlTable_t ; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +#define dmaChannelEnable(dmach) {\ + HWREG(UDMA_ENASET) = (1 << dmach);\ +} + +#define dmaChannelDisable(dmach) { \ + HWREG(UDMA_ENACLR) = (1 << dmach); \ +} + +#define dmaChannelPrimary(dmach) {\ + HWREG(UDMA_ALTCLR) = (1 << dmach); \ +} + +#define dmaChannelAlternate(dmach) { \ + HWREG(UDMA_ALTSET) = (1 << dmach); \ +} + +#define dmaChannelSingleBurst(dmach) { \ + HWREG(UDMA_USEBURSTCLR) = (1 << dmach); \ +} + +#define dmaChannelBurstOnly(dmach) { \ + HWREG(UDMA_USEBURSTSET) = (1 << dmach); \ +} + +#define dmaChannelPriorityHigh(dmach) { \ + HWREG(UDMA_PRIOSET) = (1 << dmach); \ +} + +#define dmaChannelPriorityDefault(dmach) { \ + HWREG(UDMA_PRIOCLR) = (1 << dmach); \ +} + +#define dmaChannelEnableRequest(dmach) {\ + HWREG(UDMA_REQMASKCLR) = (1 << dmach); \ +} + +#define dmaChannelDisableRequest(dmach) {\ + HWREG(UDMA_REQMASKSET) = (1 << dmach); \ +} + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +extern udmaControlTable_t udmaControlTable; + +#ifdef __cplusplus +extern "C" { +#endif + void udmaInit(void); + bool udmaChannelAllocate(uint8_t dmach); + void udmaChannelRelease(uint8_t dmach); +#ifdef __cplusplus +} +#endif + +#endif /* TIVA_UDMA_H_ */ + +/** @} */ |