source: rtems/bsps/arm/lpc176x/start/dma-copy.c @ ba619b7f

Last change on this file since ba619b7f was ba619b7f, checked in by Joel Sherrill <joel@…>, on 03/01/22 at 21:38:20

bsps/arm/: Scripted embedded brains header file clean up

Updates #4625.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSBSPsARMLPC176X_dma
5 *
6 * @brief Direct memory access (DMA) support.
7 */
8
9/*
10 * Copyright (c) 2008, 2009 embedded brains GmbH.  All rights reserved.
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 */
16
17#include <bsp/lpc176x.h>
18#include <bsp/dma.h>
19#include <bsp/irq.h>
20
21static rtems_id lpc176x_dma_sema_table[ GPDMA_CH_NUMBER ];
22static bool     lpc176x_dma_status_table[ GPDMA_CH_NUMBER ];
23
24static void lpc176x_dma_copy_handler( void *arg )
25{
26  /* Get interrupt status */
27  uint32_t tc = GPDMA_INT_TCSTAT;
28  uint32_t err = GPDMA_INT_ERR_STAT;
29
30  /* Clear interrupt status */
31  GPDMA_INT_TCCLR = tc;
32  GPDMA_INT_ERR_CLR = err;
33
34  if ( ( tc & GPDMA_STATUS_CH_0 ) != 0 ) {
35    rtems_semaphore_release( lpc176x_dma_sema_table[ 0 ] );
36  }
37
38  /* else implies that the channel is not the 0. Also,
39     there is nothing to do. */
40
41  lpc176x_dma_status_table[ 0 ] = ( err & GPDMA_STATUS_CH_0 ) == 0;
42
43  if ( ( tc & GPDMA_STATUS_CH_1 ) != 0 ) {
44    rtems_semaphore_release( lpc176x_dma_sema_table[ 1 ] );
45  }
46
47  /* else implies that the channel is not the 1. Also,
48     there is nothing to do. */
49
50  lpc176x_dma_status_table[ 1 ] = ( err & GPDMA_STATUS_CH_1 ) == 0;
51}
52
53rtems_status_code lpc176x_dma_copy_initialize( void )
54{
55  rtems_status_code status_code = RTEMS_SUCCESSFUL;
56  rtems_id          id0 = RTEMS_ID_NONE;
57  rtems_id          id1 = RTEMS_ID_NONE;
58
59  /* Create semaphore for channel 0 */
60  status_code = rtems_semaphore_create( rtems_build_name( 'D', 'M', 'A', '0' ),
61    0,
62    RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE,
63    0,
64    &id0 );
65
66  if ( status_code != RTEMS_SUCCESSFUL ) {
67    return status_code;
68  }
69
70  /* else implies that the semaphore to the channel 0 was created succefully.
71     Also, there is nothing to do. */
72
73  /* Create semaphore for channel 1 */
74  status_code = rtems_semaphore_create( rtems_build_name( 'D', 'M', 'A', '1' ),
75    0,
76    RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE,
77    0,
78    &id1 );
79
80  if ( status_code != RTEMS_SUCCESSFUL ) {
81    rtems_semaphore_delete( id0 );
82
83    return status_code;
84  }
85
86  /* else implies that the semaphore to the channel 1 was created succefully.
87     Also, there is nothing to do. */
88
89  /* Install DMA interrupt handler */
90  status_code = rtems_interrupt_handler_install( LPC176X_IRQ_DMA,
91    "DMA copy",
92    RTEMS_INTERRUPT_UNIQUE,
93    lpc176x_dma_copy_handler,
94    NULL );
95
96  if ( status_code != RTEMS_SUCCESSFUL ) {
97    rtems_semaphore_delete( id0 );
98    rtems_semaphore_delete( id1 );
99
100    return status_code;
101  }
102
103  /* else implies that the interrupt handler was installed succefully. Also,
104     there is nothing to do. */
105
106  /* Initialize global data */
107  lpc176x_dma_sema_table[ 0 ] = id0;
108  lpc176x_dma_sema_table[ 1 ] = id1;
109
110  return RTEMS_SUCCESSFUL;
111}
112
113rtems_status_code lpc176x_dma_copy_release( void )
114{
115  rtems_status_code status_code = RTEMS_SUCCESSFUL;
116  rtems_status_code status_code_aux = RTEMS_SUCCESSFUL;
117
118  status_code = rtems_interrupt_handler_remove( LPC176X_IRQ_DMA,
119    lpc176x_dma_copy_handler,
120    NULL );
121
122  if ( status_code != RTEMS_SUCCESSFUL ) {
123    status_code_aux = status_code;
124  }
125
126  /* else implies that the interrupt handler was removed succefully. Also,
127     there is nothing to do. */
128
129  status_code = rtems_semaphore_delete( lpc176x_dma_sema_table[ 0 ] );
130
131  if ( status_code != RTEMS_SUCCESSFUL ) {
132    status_code_aux = status_code;
133  }
134
135  /* else implies that the semaphore to the channel 0 was deleted succefully.
136     Also, there is nothing to do. */
137
138  status_code = rtems_semaphore_delete( lpc176x_dma_sema_table[ 1 ] );
139
140  if ( status_code != RTEMS_SUCCESSFUL ) {
141    status_code_aux = status_code;
142  }
143
144  /* else implies that the semaphore to the channel 1 was deleted succefully.
145     Also, there is nothing to do. */
146
147  return status_code_aux;
148}
149
150rtems_status_code lpc176x_dma_copy(
151  unsigned          channel,
152  const void *const dest,
153  const void *const src,
154  size_t            n,
155  const size_t      width
156)
157{
158  rtems_status_code             status_code = RTEMS_SUCCESSFUL;
159  volatile lpc176x_dma_channel *e = GPDMA_CH_BASE_ADDR( channel );
160  uint32_t                      w = GPDMA_CH_CTRL_W_8;
161
162  switch ( width ) {
163    case 4:
164      w = GPDMA_CH_CTRL_W_32;
165      break;
166    case 2:
167      w = GPDMA_CH_CTRL_W_16;
168      break;
169  }
170
171  n = n >> w;
172
173  if ( n > 0 && n < 4096 ) {
174    e->desc.src = (uint32_t) src;
175    e->desc.dest = (uint32_t) dest;
176    e->desc.lli = 0;
177    e->desc.ctrl = SET_GPDMA_CH_CTRL_TSZ( 0, n ) |
178                   SET_GPDMA_CH_CTRL_SBSZ( 0, GPDMA_CH_CTRL_BSZ_1 ) |
179                   SET_GPDMA_CH_CTRL_DBSZ( 0, GPDMA_CH_CTRL_BSZ_1 ) |
180                   SET_GPDMA_CH_CTRL_SW( 0, w ) |
181                   SET_GPDMA_CH_CTRL_DW( 0, w ) |
182                   GPDMA_CH_CTRL_ITC |
183                   GPDMA_CH_CTRL_SI |
184                   GPDMA_CH_CTRL_DI;
185    e->cfg = SET_GPDMA_CH_CFG_FLOW( 0, GPDMA_CH_CFG_FLOW_MEM_TO_MEM_DMA ) |
186             GPDMA_CH_CFG_IE |
187             GPDMA_CH_CFG_ITC |
188             GPDMA_CH_CFG_EN;
189  } else {
190    status_code = RTEMS_INVALID_SIZE;
191  }
192
193  return status_code;
194}
195
196rtems_status_code lpc176x_dma_copy_wait( const unsigned channel )
197{
198  rtems_status_code status_code = RTEMS_SUCCESSFUL;
199
200  status_code = rtems_semaphore_obtain( lpc176x_dma_sema_table[ channel ],
201    RTEMS_WAIT,
202    RTEMS_NO_TIMEOUT );
203
204  if ( status_code != RTEMS_SUCCESSFUL ) {
205    return status_code;
206  }
207
208  /* else implies that the semaphore was obtained succefully. Also,
209     there is nothing to do. */
210
211  status_code = lpc176x_dma_status_table[ channel ]
212                ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR;
213
214  return status_code;
215}
Note: See TracBrowser for help on using the repository browser.