1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - CARD - libraries
3 File: card_pullOut.c
4
5 Copyright 2007-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-17#$
14 $Rev: 8556 $
15 $Author: okubata_ryoma $
16
17 *---------------------------------------------------------------------------*/
18
19
20 #include <nitro/card/rom.h>
21 #include <nitro/card/pullOut.h>
22
23 #include "card_rom.h"
24
25 //---- User callback for card pulled out
26 static CARDPulledOutCallback CARD_UserCallback;
27
28 //---- Flag to be pulled out
29 static u32 CARDiSlotResetCount;
30 static BOOL CARDi_IsPulledOutFlag = FALSE;
31
32 static void CARDi_PulledOutCallback(PXIFifoTag tag, u32 data, BOOL err);
33 static void CARDi_SendtoPxi(u32 data, u32 wait);
34
35 /*---------------------------------------------------------------------------*
36 Name: CARD_InitPulledOutCallback
37
38 Description: Initialize callback setting.
39
40 Arguments: None.
41
42 Returns: None.
43 *---------------------------------------------------------------------------*/
CARD_InitPulledOutCallback(void)44 void CARD_InitPulledOutCallback(void)
45 {
46 PXI_Init();
47
48 CARDiSlotResetCount = 0;
49 CARDi_IsPulledOutFlag = FALSE;
50
51 //---- Set PXI callback
52 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CARD, CARDi_PulledOutCallback);
53
54 //---- Init user callback
55 CARD_UserCallback = NULL;
56 }
57
58 /*---------------------------------------------------------------------------*
59 Name: CARDi_PulledOutCallback
60
61 Description: Callback to receive data from PXI.
62
63 Arguments: tag: Tag from PXI (unused)
64 data: Data from PXI
65 err: Error bit (unused)
66
67 Returns: None.
68 *---------------------------------------------------------------------------*/
CARDi_PulledOutCallback(PXIFifoTag tag,u32 data,BOOL err)69 static void CARDi_PulledOutCallback(PXIFifoTag tag, u32 data, BOOL err)
70 {
71 #pragma unused( tag, err )
72
73 u32 command = data & CARD_PXI_COMMAND_MASK;
74
75 //---- Receive message 'pulled out'
76 if (command == CARD_PXI_COMMAND_PULLED_OUT)
77 {
78 if (CARDi_IsPulledOutFlag == FALSE)
79 {
80 BOOL isTerminateImm = TRUE;
81
82 CARDi_IsPulledOutFlag = TRUE;
83 CARDi_NotifyEvent(CARD_EVENT_PULLEDOUT, NULL);
84
85 //---- Call user callback
86 if (CARD_UserCallback)
87 {
88 isTerminateImm = CARD_UserCallback();
89 }
90
91 //---- Terminate
92 if (isTerminateImm)
93 {
94 CARD_TerminateForPulledOut();
95 }
96 }
97 }
98 else if (command == CARD_PXI_COMMAND_RESET_SLOT)
99 {
100 CARDiSlotResetCount += 1;
101 CARDi_IsPulledOutFlag = FALSE;
102 CARDi_NotifyEvent(CARD_EVENT_SLOTRESET, NULL);
103 }
104 else
105 {
106 #ifndef SDK_FINALROM
107 OS_Panic("illegal card pxi command.");
108 #else
109 OS_Panic("");
110 #endif
111 }
112 }
113
114 /*---------------------------------------------------------------------------*
115 Name: CARD_SetPulledOutCallback
116
117 Description: Set user callback for card being pulled out.
118
119 Arguments: callback: Callback
120
121 Returns: None.
122 *---------------------------------------------------------------------------*/
CARD_SetPulledOutCallback(CARDPulledOutCallback callback)123 void CARD_SetPulledOutCallback(CARDPulledOutCallback callback)
124 {
125 CARD_UserCallback = callback;
126 }
127
128 /*---------------------------------------------------------------------------*
129 Name: CARD_IsPulledOut
130
131 Description: Return if have detected card pulled out.
132
133 Arguments: None.
134
135 Returns: TRUE if detected.
136 *---------------------------------------------------------------------------*/
CARD_IsPulledOut(void)137 BOOL CARD_IsPulledOut(void)
138 {
139 return CARDi_IsPulledOutFlag;
140 }
141
142 //================================================================================
143 // TERMINATION
144 //================================================================================
145 /*---------------------------------------------------------------------------*
146 Name: CARD_TerminateForPulledOut
147
148 Description: Terminate for pulling out card.
149 Send message to do termination to ARM7.
150
151 Arguments: None.
152
153 Returns: None.
154 *---------------------------------------------------------------------------*/
CARD_TerminateForPulledOut(void)155 void CARD_TerminateForPulledOut(void)
156 {
157 //---- If folding, power off
158 if (PAD_DetectFold())
159 {
160 (void)PM_ForceToPowerOff();
161 //---- Power off is always successful so this point is never reached
162 }
163
164 // When the cover is not closed, send Terminate command because the ARM7 processor must be stopped
165 #ifdef SDK_TWL
166 if ( OS_IsRunOnTwl() )
167 {
168 // End processing
169 // If making an ARM7 processor request, wait for the callback function to complete
170 PMi_ExecutePostExitCallbackList();
171 }
172 #endif // SDK_TWL
173 //---- Send 'TERMINATE' command to ARM7, and terminate itself immediately
174 CARDi_SendtoPxi(CARD_PXI_COMMAND_TERMINATE, 1);
175
176 //---- Stop all dma
177 MI_StopAllDma();
178 #ifdef SDK_TWL
179 if ( OS_IsRunOnTwl() )
180 {
181 MI_StopAllNDma();
182 }
183 #endif
184
185 OS_Terminate();
186 }
187
188 /*---------------------------------------------------------------------------*
189 Name: CARDi_CheckPulledOutCore
190
191 Description: Main processing for the card removal detection function.
192 The card bus must be locked.
193
194 Arguments: id: ROM-ID read from the card
195
196 Returns: None.
197 *---------------------------------------------------------------------------*/
CARDi_CheckPulledOutCore(u32 id)198 void CARDi_CheckPulledOutCore(u32 id)
199 {
200 //---- Card ID IPL had read
201 vu32 iplCardID = *(vu32 *)(HW_BOOT_CHECK_INFO_BUF);
202 //---- If card removal has been detected, simulate PXI-notification from ARM7
203 if (id != (u32)iplCardID)
204 {
205 OSIntrMode bak_cpsr = OS_DisableInterrupts();
206 CARDi_PulledOutCallback(PXI_FIFO_TAG_CARD, CARD_PXI_COMMAND_PULLED_OUT, FALSE);
207 (void)OS_RestoreInterrupts(bak_cpsr);
208 }
209 }
210
211 /*---------------------------------------------------------------------------*
212 Name: CARD_CheckPulledOut
213
214 Description: Get whether system has detected pulled out card
215 by comparing IPL cardID with current cardID
216 (notice that once a card is pulled out, IDs are absolutely different)
217
218 Arguments: None.
219
220 Returns: TRUE if current cardID is equal to IPL cardID.
221 *---------------------------------------------------------------------------*/
CARD_CheckPulledOut(void)222 void CARD_CheckPulledOut(void)
223 {
224 CARDi_CheckPulledOutCore(CARDi_ReadRomID());
225 }
226
227 //================================================================================
228 // SEND PXI COMMAND
229 //================================================================================
230 /*---------------------------------------------------------------------------*
231 Name: CARDi_SendtoPxi
232
233 Description: Send data via PXI.
234
235 Arguments: data: Data to send
236
237 Returns: None.
238 *---------------------------------------------------------------------------*/
CARDi_SendtoPxi(u32 data,u32 wait)239 static void CARDi_SendtoPxi(u32 data, u32 wait)
240 {
241 while (PXI_SendWordByFifo(PXI_FIFO_TAG_CARD, data, FALSE) != PXI_FIFO_SUCCESS)
242 {
243 SVC_WaitByLoop((s32)wait);
244 }
245 }
246
247
248 /*---------------------------------------------------------------------------*
249 * Internal functions
250 *---------------------------------------------------------------------------*/
251
252 /*---------------------------------------------------------------------------*
253 Name: CARDi_GetSlotResetCount
254
255 Description: Get the number of times the slot detects reinsertion.
256 Simply return the number of times the CARDi_ResetSlotStatus function was called.
257
258 Arguments: None.
259
260 Returns: Number of times slot detects reinsertion. Initial value was 0.
261 *---------------------------------------------------------------------------*/
CARDi_GetSlotResetCount(void)262 u32 CARDi_GetSlotResetCount(void)
263 {
264 return CARDiSlotResetCount;
265 }
266
267 /*---------------------------------------------------------------------------*
268 Name: CARDi_IsPulledOutEx
269
270 Description: Determines whether the card was pulled from the slot.
271
272 Arguments: count: The number of times the slot was reinserted as confirmed last time.
273 Get using the CARDi_GetSlotResetCount function.
274
275 Returns: If the specified number of times the slot detected reinsertion is the same as the current and the card is currently pulled out, TRUE.
276
277 *---------------------------------------------------------------------------*/
CARDi_IsPulledOutEx(u32 count)278 BOOL CARDi_IsPulledOutEx(u32 count)
279 {
280 BOOL result = FALSE;
281 OSIntrMode bak = OS_DisableInterrupts();
282 {
283 result = ((count == CARDi_GetSlotResetCount()) && !CARD_IsPulledOut());
284 }
285 (void)OS_RestoreInterrupts(bak);
286 return result;
287 }
288