1 /*---------------------------------------------------------------------------*
2 Project: HIO2 demos - simple
3 File: simple.c
4
5 (C)2005 HUDSON SOFT
6
7 $Header: /home/cvsroot/SDK/build/demos/hio2demo/src/simple.c,v 1.4 2007/11/26 13:54:44 iwai_yuma Exp $
8
9 $NoKeywords: $
10 *---------------------------------------------------------------------------*/
11
12 #include <string.h>
13 #include <demo.h>
14 #include <revolution/hio2.h>
15 #include "multi.h" // Divert to generate send data
16 #include "simple.h"
17
18 //-----------------------------------------------------------------------------
19 // Define
20
21 // Coordinates for DEMORFPrintf()
22 #define POS_COMM_X 32
23 #define POS_TITLE_Y 64
24 #define POS_SEND_Y 96
25 #define POS_SENDDATA_Y 128
26 #define POS_RECVDATA_Y 192
27 #define POS_MES_Y 416
28 #define POS_CONNECT_X 480
29
30 //-----------------------------------------------------------------------------
31 // Local symbol definition
32
33 // HIO2 API handle
34 static HIO2Handle hHIO2;
35
36 // HIO2 API buffer
37 static MULTI_PACKET sendBuffer ATTRIBUTE_ALIGN(32);
38 static MULTI_PACKET recvBuffer ATTRIBUTE_ALIGN(32);
39
40 // Color data
41 static const GXColor gxFont = { 0xFF, 0xFF, 0xFF, 0 }, gxBg = { 0, 0, 0, 0 };
42
43 // Error messages
44 static char strError[128] = { '\0' };
45
46 // EXI device
47 static HIO2DeviceType exiDev = HIO2_DEVICE_INVALID;
48
49 // PC connection state
50 static BOOL bConnect = FALSE;
51
52 // Termination flag
53 static BOOL bExit = FALSE;
54
55 // Send flag
56 static BOOL bSend = TRUE;
57
58 //-----------------------------------------------------------------------------
59 // Local function declared
60
61 static void myAppInit( void );
62 static void myUpdateDisp( void );
63 static void myHIO2Init( void );
64 static void myHIO2Exit( void );
65
66 static inline
myHalt(SIMPLE_ERROR errno)67 void myHalt( SIMPLE_ERROR errno )
68 {
69 (void)sprintf(strError, simpleErrorMessage[errno], HIO2GetLastError());
70
71 OSFatal(gxFont, gxBg, strError);
72 }
73
74 ///////////////////////////////////////////////////////////////////////////////
75 //
76 // Callback
77 //
78
79 // enum devices
80 static
myEnumCallback(HIO2DeviceType type)81 BOOL myEnumCallback( HIO2DeviceType type )
82 {
83 // Use the first device that was detected
84 exiDev = type;
85 return FALSE;
86 }
87
88 // receive :
89 //
90 // Use as a callback function when detecting a mailbox write from the PC with an interrupt
91 //
92 //
93 // Use as a subroutine when detecting a mailbox write from the PC with status
94 //
95 //
96 static
myReceiveCallback(HIO2Handle h)97 void myReceiveCallback( HIO2Handle h )
98 {
99 u32 mail;
100
101 if ( !HIO2ReadMailbox(h, &mail) ) myHalt(SIMPLE_ERR_HIO2_READ_MAILBOX);
102
103 switch ( mail )
104 {
105 case SIMPLE_MAIL_OPEN_RESULT: // Open completion notification from connection target
106 bConnect = TRUE;
107 break;
108 case SIMPLE_MAIL_RECV: // Receive data from connection target
109 if ( !HIO2Read(h, SIMPLE_PC2NNGC_ADDR, &recvBuffer,
110 sizeof(recvBuffer)) )
111 myHalt(SIMPLE_ERR_HIO2_READ);
112 DCInvalidateRange(&recvBuffer, sizeof(recvBuffer));
113 break;
114 case SIMPLE_MAIL_EXIT: // Termination notification from connection target
115 bExit = TRUE; break;
116 }
117 }
118
119 // Disconnect
120 static
myDisconnectCallback(HIO2Handle h)121 void myDisconnectCallback( HIO2Handle h )
122 {
123 #pragma unused(h)
124 myHalt(SIMPLE_ERR_EXI2USB_DISCONNECT);
125 }
126
127 ///////////////////////////////////////////////////////////////////////////////
128 //
129 // Simple function
130 //
131
132 //-----------------------------------------------------------------------------
main(void)133 void main( void )
134 {
135 int v = 0;
136
137 // Initialization
138 myAppInit();
139
140 // HIO2 API initialization
141 myHIO2Init();
142
143 while ( !bExit )
144 {
145 OSCalendarTime calender;
146 BOOL sendPossible = FALSE;
147
148 // Display update
149 DEMOBeforeRender();
150 myUpdateDisp();
151 DEMODoneRender();
152
153 // Controller input
154 DEMOPadRead();
155
156 // Set calendar input results to PC send buffer
157 OSTicksToCalendarTime(OSGetTime(), &calender);
158 sendBuffer.mon = (u8)(calender.mon + 1);
159 sendBuffer.mday = (u8)calender.mday;
160 sendBuffer.hour = (u8)calender.hour;
161 sendBuffer.min = (u8)calender.min;
162 sendBuffer.sec = (u8)calender.sec;
163 sendBuffer.msec = (u16)calender.msec;
164 {
165 u32 status;
166 // Get HIO2 status
167 if ( !HIO2ReadStatus(hHIO2, &status) )
168 myHalt(SIMPLE_ERR_HIO2_READ_STATUS);
169 sendPossible = !(status & HIO2_STATUS_RX);
170 #ifdef POLLING
171 if ( status & HIO2_STATUS_TX )
172 myReceiveCallback(hHIO2);
173 #endif // POLLING
174 }
175
176 // Do nothing when mail cannot be sent or received
177 if ( !sendPossible ) continue;
178
179 // Perform a PC connection notification when mail can be sent/received but there is no PC connection yet
180 if ( !bConnect )
181 {
182 if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_OPEN) )
183 myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX);
184 continue;
185 }
186
187 // Switch between send and receive when A Button is pressed
188 if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_A )
189 {
190 bSend = !bSend;
191 if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_CHANGE) )
192 myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX);
193 }
194 // Perform PC termination notification and terminate when START Button is pressed
195 else if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_START )
196 {
197 if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_EXIT) )
198 myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX);
199 bExit = TRUE;
200 }
201 // Send data to PC during send state (in 60V units)
202 else if ( bSend && (++v == 60) )
203 {
204 DCFlushRange(&sendBuffer, sizeof(sendBuffer));
205 if ( !HIO2Write(hHIO2, SIMPLE_NNGC2PC_ADDR, &sendBuffer,
206 sizeof(sendBuffer)) )
207 myHalt(SIMPLE_ERR_HIO2_WRITE);
208 if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_RECV) )
209 myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX);
210 v = 0;
211 }
212 }
213
214 // HIO2 termination
215 myHIO2Exit();
216 }
217
218 //----------------------------------------------------------------------------
219 static
myAppInit(void)220 void myAppInit( void )
221 {
222 GXRenderModeObj* rmp;
223
224 DEMOInit(NULL);
225
226 // DEMORFPrintf() initialization
227 (void)DEMOInitROMFont();
228
229 rmp = DEMOGetRenderModeObj();
230 DEMOInitCaption(DM_FT_OPQ, (s16) rmp->fbWidth, (s16) rmp->efbHeight);
231 DEMOSetFontType(DM_FT_OPQ);
232
233 // Screen initialization
234 GXSetCopyClear(gxBg, 0x00ffffff);
235 GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
236
237 // Controller initialization
238 DEMOPadInit();
239
240 (void)strcpy(sendBuffer.string, "NDEV TIME");
241 (void)strcpy(recvBuffer.string, "PC TIME");
242 }
243
244 //----------------------------------------------------------------------------
245 static
myUpdateDisp(void)246 void myUpdateDisp( void )
247 {
248 char dispBuf[128];
249
250 // Title
251 #ifndef POLLING
252 (void)DEMORFPrintf(POS_COMM_X, POS_TITLE_Y, 0,
253 "HIO2 DEMO - simple (EXI INT)");
254 #else // POLLING
255 (void)DEMORFPrintf(POS_COMM_X, POS_TITLE_Y, 0,
256 "HIO2 DEMO - simple (polling)");
257 #endif // POLLING
258
259 // Connection state
260 (void)DEMORFPrintf(POS_CONNECT_X, POS_TITLE_Y, 0,
261 bConnect ? "CONNECT" : "DISCONNECT");
262
263 // Send/receive state
264 (void)DEMORFPrintf(POS_CONNECT_X, POS_SEND_Y, 0, bSend ? "SEND" : "RECV");
265
266 // Send information
267 MultiPacketToString(dispBuf, &sendBuffer);
268 (void)DEMORFPrintf(POS_COMM_X, POS_SENDDATA_Y, 0, dispBuf);
269
270 // Receive information
271 MultiPacketToString(dispBuf, &recvBuffer);
272 (void)DEMORFPrintf(POS_COMM_X, POS_RECVDATA_Y, 0, "%s", dispBuf);
273
274 // Message
275 (void)DEMORFPrintf(POS_COMM_X, POS_MES_Y, 0,
276 "push START button to exit");
277 }
278
279 //----------------------------------------------------------------------------
280 static
myHIO2Init(void)281 void myHIO2Init( void )
282 {
283 // Initialization
284 if ( !HIO2Init() ) myHalt(SIMPLE_ERR_HIO2_INIT);
285
286 // Device list
287 if ( !HIO2EnumDevices(myEnumCallback) ) myHalt(SIMPLE_ERR_HIO2_ENUMDEVICES);
288
289 // When the device could not be found
290 if ( exiDev == HIO2_DEVICE_INVALID ) myHalt(SIMPLE_ERR_EXI2USB_NOT_FIND);
291
292 #ifndef POLLING
293 // Device open
294 if ( (hHIO2=HIO2Open(exiDev, myReceiveCallback, myDisconnectCallback))
295 == HIO2_INVALID_HANDLE_VALUE )
296 myHalt(SIMPLE_ERR_HIO2_OPEN);
297 #else // POLLING
298 // Device open
299 if ( (hHIO2=HIO2Open(exiDev, NULL, myDisconnectCallback))
300 == HIO2_INVALID_HANDLE_VALUE )
301 myHalt(SIMPLE_ERR_HIO2_OPEN);
302 #endif // POLLING
303 }
304
305 //----------------------------------------------------------------------------
306 static
myHIO2Exit(void)307 void myHIO2Exit( void )
308 {
309 (void)HIO2Close(hHIO2);
310 HIO2Exit();
311
312 DEMOBeforeRender();
313
314 (void)DEMORFPrintf(POS_COMM_X, POS_TITLE_Y, 0, "HIO2 DEMO - simple done.");
315
316 DEMODoneRender();
317 }
318
319 // End of simple.c
320