source: rtems/c/src/lib/libbsp/arm/lpc24xx/misc/dma.c @ f90c5fb

4.104.115
Last change on this file since f90c5fb was 7ae2775, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 07/17/09 at 13:53:04

ARM bsp maintenance

  • Property mode set to 100644
File size: 2.8 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup lpc24xx
5 *
6 * @brief DMA support.
7 */
8
9/*
10 * Copyright (c) 2008, 2009
11 * embedded brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * rtems@embedded-brains.de
16 *
17 * The license and distribution terms for this file may be found in the file
18 * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
19 */
20
21#include <rtems/endian.h>
22
23#include <bsp/lpc24xx.h>
24#include <bsp/dma.h>
25#include <bsp/io.h>
26
27/**
28 * @brief Table that indicates if a channel is currently occupied.
29 */
30static bool lpc24xx_dma_channel_occupation [GPDMA_CH_NUMBER];
31
32/**
33 * @brief Initializes the general purpose DMA.
34 */
35void lpc24xx_dma_initialize(void)
36{
37  rtems_interrupt_level level;
38
39  /* Enable module power */
40  lpc24xx_module_enable(LPC24XX_MODULE_GPDMA, 0, LPC24XX_MODULE_PCLK_DEFAULT);
41
42  /* Disable module */
43  GPDMA_CONFIG = 0;
44
45  /* Enable module */
46  #if BYTE_ORDER == LITTLE_ENDIAN
47    GPDMA_CONFIG = GPDMA_CONFIG_EN;
48  #else
49    GPDMA_CONFIG = GPDMA_CONFIG_EN | GPDMA_CONFIG_MODE;
50  #endif
51
52  /* Reset registers */
53  GPDMA_SOFT_SREQ = 0;
54  GPDMA_SOFT_BREQ = 0;
55  GPDMA_SOFT_LSREQ = 0;
56  GPDMA_SOFT_LBREQ = 0;
57  GPDMA_SYNC = 0;
58}
59
60/**
61 * @brief Tries to obtain the channel @a channel.
62 *
63 * @retval RTEMS_SUCCESSFUL Successful operation.
64 * @retval RTEMS_INVALID_ID Invalid channel number.
65 * @retval RTEMS_RESOURCE_IN_USE Channel already occupied.
66 */
67rtems_status_code lpc24xx_dma_channel_obtain(unsigned channel)
68{
69  if (channel < GPDMA_CH_NUMBER) {
70    rtems_interrupt_level level;
71    bool occupation = true;
72
73    rtems_interrupt_disable(level);
74    occupation = lpc24xx_dma_channel_occupation [channel];
75    lpc24xx_dma_channel_occupation [channel] = true;
76    rtems_interrupt_enable(level);
77
78    return occupation ? RTEMS_RESOURCE_IN_USE : RTEMS_SUCCESSFUL;
79  } else {
80    return RTEMS_INVALID_ID;
81  }
82}
83
84/**
85 * @brief Releases the channel @a channel.
86 *
87 * You must have obtained this channel with lpc24xx_dma_channel_obtain()
88 * previously.
89 *
90 * If the channel number @a channel is out of range nothing will happen.
91 */
92void lpc24xx_dma_channel_release(unsigned channel)
93{
94  if (channel < GPDMA_CH_NUMBER) {
95    lpc24xx_dma_channel_occupation [channel] = false;
96  }
97}
98
99/**
100 * @brief Disables the channel @a channel.
101 *
102 * If @a force is false the channel will be halted and disabled when the
103 * channel is inactive.
104 *
105 * If the channel number @a channel is out of range the behaviour is undefined.
106 */
107void lpc24xx_dma_channel_disable(unsigned channel, bool force)
108{
109  volatile lpc24xx_dma_channel *ch = GPDMA_CH_BASE_ADDR(channel);
110  uint32_t cfg = ch->cfg;
111
112  if (!force) {
113    /* Halt */
114    ch->cfg = SET_FLAG(cfg, GPDMA_CH_CFG_HALT);
115
116    /* Wait for inactive */
117    do {
118      cfg = ch->cfg;
119    } while (IS_FLAG_SET(cfg, GPDMA_CH_CFG_ACTIVE));
120  }
121
122  /* Disable */
123  ch->cfg = CLEAR_FLAG(cfg, GPDMA_CH_CFG_EN);
124}
Note: See TracBrowser for help on using the repository browser.