source: rtems/bsps/m68k/genmcf548x/mcdma/mcdma_glue.c @ 945095d

5
Last change on this file since 945095d was 945095d, checked in by Sebastian Huber <sebastian.huber@…>, on 03/26/18 at 11:08:07

bsps/genmcf548x: Move libcpu content to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 10.0 KB
Line 
1/*===============================================================*\
2| Project: RTEMS generic MCF548x BSP                              |
3+-----------------------------------------------------------------+
4|                    Copyright (c) 2004-2009                      |
5|                    Embedded Brains GmbH                         |
6|                    Obere Lagerstr. 30                           |
7|                    D-82178 Puchheim                             |
8|                    Germany                                      |
9|                    rtems@embedded-brains.de                     |
10+-----------------------------------------------------------------+
11| The license and distribution terms for this file may be         |
12| found in the file LICENSE in this distribution or at            |
13|                                                                 |
14| http://www.rtems.org/license/LICENSE.                           |
15|                                                                 |
16+-----------------------------------------------------------------+
17| this file contains glue functions to the Freescale MC_DMA API   |
18\*===============================================================*/
19#include <rtems.h>
20#include <rtems/error.h>
21#include <bsp.h>
22#include <mcf548x/mcf548x.h>
23#include <mcf548x/MCD_dma.h>
24#include <mcf548x/mcdma_glue.h>
25
26#define MCDMA_INT_ENABLE(reg,chan)   (reg &= ~(1 << (chan)))
27#define MCDMA_INT_DISABLE(reg,chan)  (reg |=  (1 << (chan)))
28#define MCDMA_CLEAR_IEVENT(reg,chan) (reg  =  (1 << (chan)))
29
30#define MCDMA_INT_BIT_IMPL           0x0000FFFF /* implemented IRQ sources (bitmask for IPEND... */
31#define MCDMA_IRQ_VECTOR    (48+64)
32#define MCDMA_IRQ_LEVEL     (2)
33#define MCDMA_IRQ_PRIORITY  (2)
34/*=========================================================================*\
35| Function:                                                                 |
36\*-------------------------------------------------------------------------*/
37void mcdma_glue_irq_enable
38(
39/*-------------------------------------------------------------------------*\
40| Purpose:                                                                  |
41|   enable interrupt for given task number                                  |
42+---------------------------------------------------------------------------+
43| Input Parameters:                                                         |
44\*-------------------------------------------------------------------------*/
45 int mcdma_channo                              /* task number to enable    */
46)
47/*-------------------------------------------------------------------------*\
48| Return Value:                                                             |
49|    none                                                                   |
50\*=========================================================================*/
51{
52  rtems_interrupt_level level;
53  if (0 != ((1UL<<mcdma_channo) & MCDMA_INT_BIT_IMPL)) {
54    rtems_interrupt_disable(level);
55    /*
56     * valid task number
57     * enable interrupt in mcdma mask
58     */
59    MCDMA_INT_ENABLE(MCF548X_DMA_DIMR,mcdma_channo);
60    rtems_interrupt_enable(level);
61  }
62}
63
64/*=========================================================================*\
65| Function:                                                                 |
66\*-------------------------------------------------------------------------*/
67void mcdma_glue_irq_disable
68(
69/*-------------------------------------------------------------------------*\
70| Purpose:                                                                  |
71|   disable interrupt for given task number                                 |
72+---------------------------------------------------------------------------+
73| Input Parameters:                                                         |
74\*-------------------------------------------------------------------------*/
75 int mcdma_channo                              /* task number to disable   */
76)
77/*-------------------------------------------------------------------------*\
78| Return Value:                                                             |
79|    none                                                                   |
80\*=========================================================================*/
81{
82  rtems_interrupt_level level;
83  if (0 != ((1UL<<mcdma_channo) & MCDMA_INT_BIT_IMPL)) {
84    rtems_interrupt_disable(level);
85    /*
86     * valid task number
87     * disable interrupt in mcdma mask
88     */
89    MCDMA_INT_DISABLE(MCF548X_DMA_DIMR,mcdma_channo);
90    rtems_interrupt_enable(level);
91  }
92}
93
94typedef struct {
95  void (*the_handler)(void *param);
96  void *the_param;
97} mcdma_glue_irq_handlers_t;
98
99mcdma_glue_irq_handlers_t mcdma_glue_irq_handlers[32];
100
101/*=========================================================================*\
102| Function:                                                                 |
103\*-------------------------------------------------------------------------*/
104void mcdma_glue_irq_install
105(
106/*-------------------------------------------------------------------------*\
107| Purpose:                                                                  |
108|   install given function as mcdma interrupt handler                    |
109+---------------------------------------------------------------------------+
110| Input Parameters:                                                         |
111\*-------------------------------------------------------------------------*/
112 int mcdma_channo,                          /* task number for handler  */
113 void (*the_handler)(void *),               /* function to call         */
114 void *the_param
115)
116/*-------------------------------------------------------------------------*\
117| Return Value:                                                             |
118|    none                                                                   |
119\*=========================================================================*/
120{
121  if (0 != ((1UL<<mcdma_channo) & MCDMA_INT_BIT_IMPL)) {
122    /*
123     * valid task number
124     * install handler
125     */
126    mcdma_glue_irq_handlers[mcdma_channo].the_handler = the_handler;
127    mcdma_glue_irq_handlers[mcdma_channo].the_param   = the_param;
128  }
129}
130
131/*=========================================================================*\
132| Function:                                                                 |
133\*-------------------------------------------------------------------------*/
134static rtems_isr mcdma_glue_irq_dispatcher
135(
136/*-------------------------------------------------------------------------*\
137| Purpose:                                                                  |
138|   general mcdma interrupt handler/dispatcher                              |
139+---------------------------------------------------------------------------+
140| Input Parameters:                                                         |
141\*-------------------------------------------------------------------------*/
142 rtems_vector_number v                   /* irq specific handle (not used) */
143
144)
145/*-------------------------------------------------------------------------*\
146| Return Value:                                                             |
147|    none                                                                   |
148\*=========================================================================*/
149{
150  uint32_t pending;
151  int curr_channo;
152
153  pending = MCF548X_DMA_DIPR & ~MCF548X_DMA_DIMR;
154  curr_channo = 0;
155  while (pending != 0) {
156    if ((pending & (1UL<<curr_channo)) != 0) {
157      if (mcdma_glue_irq_handlers[curr_channo].the_handler == NULL) {
158        /*
159         * This should never happen. we have a pending IRQ but no handler
160         * let's clear this pending bit
161         */
162        MCDMA_CLEAR_IEVENT(MCF548X_DMA_DIPR,curr_channo);
163      }
164      else {
165        /*
166         * call proper handler
167         */
168        mcdma_glue_irq_handlers[curr_channo].the_handler
169          (mcdma_glue_irq_handlers[curr_channo].the_param);
170      }
171      /*
172       * clear this bit in our pending copy
173       * and go to next bit
174       */
175      pending &= ~(1<<curr_channo);
176    }
177    curr_channo++;
178  }
179}
180
181static bool mcdma_glue_is_initialized = false;
182/*=========================================================================*\
183| Function:                                                                 |
184\*-------------------------------------------------------------------------*/
185void mcdma_glue_init
186(
187/*-------------------------------------------------------------------------*\
188| Purpose:                                                                  |
189|   initialize the mcdma module (if not yet done):                          |
190|   - load code                                                             |
191|   - initialize registers                                                  |
192|   - initialize bus arbiter                                                |
193|   - initialize interrupt control                                          |
194+---------------------------------------------------------------------------+
195| Input Parameters:                                                         |
196\*-------------------------------------------------------------------------*/
197 void *sram_base         /* base address for SRAM, to be used for DMA task */
198)
199/*-------------------------------------------------------------------------*\
200| Return Value:                                                             |
201|    none                                                                   |
202\*=========================================================================*/
203{
204  rtems_isr_entry old_handler;
205  if (!mcdma_glue_is_initialized) {
206    mcdma_glue_is_initialized = true;
207
208    MCD_initDma((dmaRegs *)&MCF548X_DMA_TASKBAR,
209                sram_base,
210                MCD_TT_FLAGS_DEF);
211
212    /*
213     * initialize interrupt dispatcher
214     */
215    if(rtems_interrupt_catch(mcdma_glue_irq_dispatcher,
216                             MCDMA_IRQ_VECTOR,
217                             &old_handler)) {
218      rtems_panic ("Can't attach MFC548x MCDma interrupt handler\n");
219    }
220    MCF548X_INTC_ICRn(MCDMA_IRQ_VECTOR - 64) =
221      MCF548X_INTC_ICRn_IL(MCDMA_IRQ_LEVEL) |
222      MCF548X_INTC_ICRn_IP(MCDMA_IRQ_PRIORITY);
223
224    MCF548X_INTC_IMRH &= ~(1 << (MCDMA_IRQ_VECTOR % 32));
225  }
226}
Note: See TracBrowser for help on using the repository browser.