1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - PXI - libraries
3 File: pxi_fifo.c
4
5 Copyright 2003-2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2008-09-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17 #ifdef SDK_TWL
18 #include <twl.h>
19 #else
20 #include <nitro.h>
21 #endif
22
23 static u16 FifoCtrlInit = 0;
24 static PXIFifoCallback FifoRecvCallbackTable[PXI_MAX_FIFO_TAG];
25
26 /*********** function prototypes ******************/
27 static inline PXIFifoStatus PXIi_GetFromFifo(u32 *data_buf);
28 static inline PXIFifoStatus PXIi_SetToFifo(u32 data);
29
30
31 /*---------------------------------------------------------------------------*
32 Name: PXI_InitFifo
33
34 Description: initialize FIFO system
35
36 Arguments: None.
37
38 Returns: None.
39 *---------------------------------------------------------------------------*/
PXI_InitFifo(void)40 void PXI_InitFifo(void)
41 {
42 int i;
43 OSIntrMode enabled;
44 OSSystemWork *p = OS_GetSystemWork();
45
46 enabled = OS_DisableInterrupts();
47
48 if (!FifoCtrlInit)
49 {
50 FifoCtrlInit = TRUE;
51
52 p->pxiHandleChecker[PXI_PROC_ARM] = 0UL;
53
54 for (i = 0; i < PXI_MAX_FIFO_TAG; i++)
55 {
56 FifoRecvCallbackTable[i] = NULL;
57 }
58
59 reg_PXI_FIFO_CNT =
60 (REG_PXI_FIFO_CNT_SEND_CL_MASK |
61 REG_PXI_FIFO_CNT_RECV_RI_MASK | REG_PXI_FIFO_CNT_E_MASK | REG_PXI_FIFO_CNT_ERR_MASK);
62
63 (void)OS_ResetRequestIrqMask(OS_IE_FIFO_RECV);
64 (void)OS_SetIrqFunction(OS_IE_FIFO_RECV, PXIi_HandlerRecvFifoNotEmpty);
65 (void)OS_EnableIrqMask(OS_IE_FIFO_RECV);
66
67 #ifndef SDK_FINALROM
68 //
69 // Send signal to let ensata know the time of PXI initialized
70 // Requested by ensata dev team 04/03/10
71 //
72 if (OSi_DetectEmulator())
73 {
74 reg_PXI_INTF = 0x100;
75 }
76 else
77 #endif
78 #ifdef SDK_ARM7
79 {
80 //-------------------------------
81 // PXI_INTF
82 // d14 RW IE
83 // d13 W IREQ
84 // d11-d08 RW OUT Status
85 // d03-d00 R IN Status
86 //-------------------------------
87 for (i = 8; i >= 0; i--)
88 {
89 reg_PXI_INTF = (u16)(i << 8);
90 OS_SpinWait(1000); // Yield main bus to ARM9
91
92 if ((reg_PXI_INTF & 15) != i)
93 {
94 i = 8;
95 }
96 }
97 }
98 #else
99 {
100 int timeout;
101 s32 c;
102
103 for (i = 0;; i++)
104 {
105 c = reg_PXI_INTF & 15;
106 reg_PXI_INTF = (u16)(c << 8);
107
108 if (c == 0 && i > 4)
109 {
110 break;
111 }
112
113 for (timeout = 1000; (reg_PXI_INTF & 15) == c; timeout--)
114 {
115 if (timeout == 0)
116 {
117 i = 0;
118 break;
119 }
120 }
121 }
122 }
123 #endif
124 }
125 (void)OS_RestoreInterrupts(enabled);
126 }
127
128
129 /*---------------------------------------------------------------------------*
130 Name: PXI_SetFifoRecvCallback
131
132 Description: set callback function when data arrive via FIFO
133
134 Arguments: fifotag fifo tag NO (0-31)
135 callback callback function to be called
136
137 Returns: None.
138 *---------------------------------------------------------------------------*/
PXI_SetFifoRecvCallback(int fifotag,PXIFifoCallback callback)139 void PXI_SetFifoRecvCallback(int fifotag, PXIFifoCallback callback)
140 {
141 OSIntrMode enabled;
142 OSSystemWork *p = OS_GetSystemWork();
143
144 SDK_WARNING(callback == NULL ||
145 FifoRecvCallbackTable[fifotag] == NULL ||
146 FifoRecvCallbackTable[fifotag] == callback,
147 "Fifo Callback overridden [fifotag=%d]\n", fifotag);
148
149 enabled = OS_DisableInterrupts();
150
151 FifoRecvCallbackTable[fifotag] = callback;
152 if (callback)
153 {
154 p->pxiHandleChecker[PXI_PROC_ARM] |= (1UL << fifotag);
155 }
156 else
157 {
158 p->pxiHandleChecker[PXI_PROC_ARM] &= ~(1UL << fifotag);
159 }
160 (void)OS_RestoreInterrupts(enabled);
161 }
162
163 /*---------------------------------------------------------------------------*
164 Name: PXI_IsCallbackReady
165
166 Description: check if callback is ready
167
168 Arguments: fifotag fifo tag NO (0-31)
169 proc processor name PXI_PROC_ARM9 or PXI_PROC_ARM7
170
171 Returns: True if callback is ready
172 *---------------------------------------------------------------------------*/
PXI_IsCallbackReady(int fifotag,PXIProc proc)173 BOOL PXI_IsCallbackReady(int fifotag, PXIProc proc)
174 {
175 OSSystemWork *p = OS_GetSystemWork();
176
177 return (p->pxiHandleChecker[proc] & (1UL << fifotag)) ? TRUE : FALSE;
178 }
179
180 /*---------------------------------------------------------------------------*
181 Name: PXI_SetFifoSendCallback
182
183 Description: set callback function when FIFO empty
184
185 Arguments: callback callback function to be called
186
187 Returns: None.
188 *---------------------------------------------------------------------------*/
PXI_SetFifoSendCallback(PXIFifoEmtpyCallback callback)189 void PXI_SetFifoSendCallback(PXIFifoEmtpyCallback callback)
190 {
191 OSIntrMode enabled;
192
193 enabled = OS_DisableInterrupts();
194
195 (void)OS_SetIrqFunction(OS_IE_FIFO_SEND, callback);
196 (void)OS_EnableIrqMask(OS_IE_FIFO_SEND);
197
198 reg_PXI_FIFO_CNT |= REG_PXI_FIFO_CNT_SEND_TI_MASK;
199
200 (void)OS_RestoreInterrupts(enabled);
201 }
202
203
204 /*---------------------------------------------------------------------------*
205 Name: PXI_SendWordByFifo
206
207 Description: Send 32bit-word to anothre CPU via FIFO
208
209 Arguments: fifotag fifo tag NO (0-31)
210 data data(26-bit) whichi is sent
211 err 1 on error
212
213 Returns: if error occured, returns minus value
214 *---------------------------------------------------------------------------*/
PXI_SendWordByFifo(int fifotag,u32 data,BOOL err)215 int PXI_SendWordByFifo(int fifotag, u32 data, BOOL err)
216 {
217 PXIFifoMessage fifomsg;
218
219 SDK_ASSERTMSG(0 <= fifotag && fifotag < PXI_MAX_FIFO_TAG, "[FifoTag] out of range");
220 SDK_ASSERTMSG(data < (1UL << PXI_FIFOMESSAGE_BITSZ_DATA), "[data] out of range");
221
222 fifomsg.e.tag = (PXIFifoTag)fifotag;
223 fifomsg.e.err = (u32)err;
224 fifomsg.e.data = data;
225
226 return PXIi_SetToFifo(fifomsg.raw);
227 }
228
229
230 //======================================================================
231 // Write Send-FIFO reg.
232 //======================================================================
PXIi_SetToFifo(u32 data)233 static inline PXIFifoStatus PXIi_SetToFifo(u32 data)
234 {
235 OSIntrMode enabled;
236
237 if (reg_PXI_FIFO_CNT & REG_PXI_FIFO_CNT_ERR_MASK)
238 {
239 reg_PXI_FIFO_CNT |= (REG_PXI_FIFO_CNT_E_MASK | REG_PXI_FIFO_CNT_ERR_MASK);
240 return PXI_FIFO_FAIL_SEND_ERR;
241 }
242
243 enabled = OS_DisableInterrupts();
244 if (reg_PXI_FIFO_CNT & REG_PXI_FIFO_CNT_SEND_FULL_MASK)
245 {
246 (void)OS_RestoreInterrupts(enabled);
247 return PXI_FIFO_FAIL_SEND_FULL;
248 }
249
250 reg_PXI_SEND_FIFO = data;
251 (void)OS_RestoreInterrupts(enabled);
252 return PXI_FIFO_SUCCESS;
253 }
254
255
256 //======================================================================
257 // Read Send-FIFO reg.
258 //======================================================================
PXIi_GetFromFifo(u32 * data_buf)259 static inline PXIFifoStatus PXIi_GetFromFifo(u32 *data_buf)
260 {
261
262 OSIntrMode enabled;
263
264 if (reg_PXI_FIFO_CNT & REG_PXI_FIFO_CNT_ERR_MASK)
265 {
266 reg_PXI_FIFO_CNT |= (REG_PXI_FIFO_CNT_E_MASK | REG_PXI_FIFO_CNT_ERR_MASK);
267 return PXI_FIFO_FAIL_RECV_ERR;
268 }
269
270 enabled = OS_DisableInterrupts();
271 if (reg_PXI_FIFO_CNT & REG_PXI_FIFO_CNT_RECV_EMP_MASK)
272 {
273 (void)OS_RestoreInterrupts(enabled);
274 return PXI_FIFO_FAIL_RECV_EMPTY;
275 }
276
277 *data_buf = reg_PXI_RECV_FIFO;
278 (void)OS_RestoreInterrupts(enabled);
279
280 return PXI_FIFO_SUCCESS;
281 }
282
283
284 //======================================================================
285 // Interrupt handler called when SEND FIFO empty
286 //======================================================================
PXIi_HandlerSendFifoEmpty(void)287 static void PXIi_HandlerSendFifoEmpty(void)
288 {
289 }
290
291 //======================================================================
292 // Interrupt handler called when RECV FIFO not empty
293 //======================================================================
294 #ifdef SDK_CW_WA_OPT_BLX
295 #pragma optimization_level 1 // for BLX problem
296 #endif
297
PXIi_HandlerRecvFifoNotEmpty(void)298 void PXIi_HandlerRecvFifoNotEmpty(void)
299 {
300 PXIFifoMessage fifomsg;
301 PXIFifoStatus ret_code;
302 PXIFifoTag tag;
303
304 while (1)
305 {
306 ret_code = PXIi_GetFromFifo(&fifomsg.raw);
307
308 if (ret_code == PXI_FIFO_FAIL_RECV_EMPTY)
309 break;
310 if (ret_code == PXI_FIFO_FAIL_RECV_ERR)
311 continue;
312
313 tag = (PXIFifoTag)fifomsg.e.tag;
314
315 if (tag)
316 {
317 if (FifoRecvCallbackTable[tag])
318 {
319 (FifoRecvCallbackTable[tag]) (tag, fifomsg.e.data, (BOOL)fifomsg.e.err);
320 }
321 else
322 {
323 if (fifomsg.e.err) /* reject if ping-pong message */
324 {
325 }
326 else
327 {
328 fifomsg.e.err = TRUE; /* Set error & block send */
329 (void)PXIi_SetToFifo(fifomsg.raw);
330 }
331 }
332 }
333 else
334 {
335 /* Extended FIFO command */
336 }
337 }
338 }
339
340 #ifdef SDK_CW_WA_OPT_BLX
341 #pragma optimization_level 4
342 #endif
343