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

4.104.115
Last change on this file since 9832a22c was 29cc1477, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 09/30/08 at 10:01:38

added SSP support files, fixed some typos

  • Property mode set to 100644
File size: 2.7 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup lpc24xx
5 *
6 * @brief DMA support.
7 */
8
9/*
10 * Copyright (c) 2008
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
26/**
27 * @brief Table that indicates if a channel is currently occupied.
28 */
29static bool lpc24xx_dma_channel_occupation [GPDMA_CH_NUMBER];
30
31/**
32 * @brief Initializes the general purpose DMA.
33 */
34void lpc24xx_dma_initialize( void)
35{
36  rtems_interrupt_level level;
37
38  /* Enable power */
39  rtems_interrupt_disable( level);
40  PCONP = SET_FLAG( PCONP, PCONP_PCGPDMA);
41  rtems_interrupt_enable( level);
42
43  /* Disable module */
44  GPDMA_CONFIG = 0;
45
46  /* Enable module */
47  #if BYTE_ORDER == LITTLE_ENDIAN
48    GPDMA_CONFIG = GPDMA_CONFIG_EN;
49  #else
50    GPDMA_CONFIG = GPDMA_CONFIG_EN | GPDMA_CONFIG_MODE;
51  #endif
52
53  /* Reset registers */
54  GPDMA_SOFT_SREQ = 0;
55  GPDMA_SOFT_BREQ = 0;
56  GPDMA_SOFT_LSREQ = 0;
57  GPDMA_SOFT_LBREQ = 0;
58  GPDMA_SYNC = 0;
59}
60
61/**
62 * @brief Returns true if the channel @a channel was obtained.
63 *
64 * If the channel number @a channel is out of range the last valid channel will
65 * be used.
66 */
67bool lpc24xx_dma_channel_obtain( unsigned channel)
68{
69  rtems_interrupt_level level;
70  bool occupation = true;
71
72  if (channel > GPDMA_CH_NUMBER) {
73    channel = GPDMA_CH_NUMBER - 1;
74  }
75
76  rtems_interrupt_disable( level);
77  occupation = lpc24xx_dma_channel_occupation [channel];
78  lpc24xx_dma_channel_occupation [channel] = true;
79  rtems_interrupt_enable( level);
80
81  return !occupation;
82}
83
84/**
85 * @brief Releases the channel @a channel.  You must have obtained this channel
86 * with lpc24xx_dma_channel_obtain() previously.
87 *
88 * If the channel number @a channel is out of range the last valid channel will
89 * be used.
90 */
91void lpc24xx_dma_channel_release( unsigned channel)
92{
93  if (channel > GPDMA_CH_NUMBER) {
94    channel = GPDMA_CH_NUMBER - 1;
95  }
96
97  lpc24xx_dma_channel_occupation [channel] = false;
98}
99
100/**
101 * @brief Disables the channel @a channel.
102 *
103 * If @a force is false the channel will be halted and disabled when the
104 * channel is inactive.  If the channel number @a channel is out of range the
105 * last valid channel will be used.
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.