1 /*---------------------------------------------------------------------------*
2 Project: HIO2 demos - dual
3 File: dual-main.c
4
5 (C)2005 HUDSON SOFT
6
7 $Header: /home/cvsroot/SDK/build/demos/hio2demo/src/dual-main.c,v 1.3 2006/08/16 08:13:07 mitu Exp $
8
9 $NoKeywords: $
10 *---------------------------------------------------------------------------*/
11
12 #include <demo.h>
13 #include "Hio2If.h"
14 #include "dual.h"
15
16 //-----------------------------------------------------------------------------
17 // define
18
19 // Coordinates for DEMORFPrintf()
20 #define POS_COMM_X 32
21 #define POS_COL_X 48
22 #define POS_TITLE_Y 64
23 #define POS_R_Y 96
24 #define POS_G_Y 128
25 #define POS_B_Y 160
26 #define POS_RECV_Y 352
27 #define POS_SEND_Y 384
28 #define POS_V_Y 416
29 #define POS_CONNECT_X 200
30 #define POS_CONNECT_Y 416
31 #define POS_STAT_X 512
32 #define POS_RECV_STAT_Y POS_R_Y
33 #define POS_SEND_STAT_Y POS_G_Y
34
35 #define POS_SYNC_X POS_STAT_X
36 #define POS_SYNC_Y POS_CONNECT_Y
37
38 //-----------------------------------------------------------------------------
39 // Type definition
40
41 // Type for calling the HIO2IF API, based on the presence of a PROTOCOL_USED specification
42 typedef HIO2IF_RESULT (* MYREAD)(HIO2IF_ID id, u32 addr, void* buffer, s32 size, BOOL async);
43 typedef HIO2IF_RESULT (* MYWRITE)(HIO2IF_ID id, u32 addr, void* buffer, s32 size, BOOL async);
44
45 //-----------------------------------------------------------------------------
46 // Local symbol definition
47
48 // Information to reference/set for Paint Box display
49 static u32 dwFbWidth, dwFbSize;
50 static GXColor gxColor = { 0, 0, 0, 0 };
51
52 // Host I/O API buffer
53 static u8 rgbBuffer[DUAL_BUFFER_SIZE] ATTRIBUTE_ALIGN(32);
54
55 // Color data
56 static const GXColor gxFont = { 0xFF, 0xFF, 0xFF, 0 }, gxBg = { 0, 0, 0, 0 };
57
58 // HIO2IF ID
59 static HIO2IF_ID hioRecvID = HIO2IF_INVALID_ID,
60 hioSendID = HIO2IF_INVALID_ID;
61
62 // Synchronous, asynchronous controls
63 static BOOL hioAsync = FALSE;
64
65 // Connection-related information
66 volatile const char* pRecvStatus = "NOT FIND";
67 volatile const char* pSendStatus = "NOT FIND";
68 #ifdef PROTOCOL_USED
69 volatile BOOL bReceived = FALSE;
70 volatile BOOL bSendPossible = TRUE;
71 #else // PROTOCOL_USED
72 #define bReceived TRUE
73 #define bSendPossible TRUE
74 #endif // PROTOCOL_USED
75
76 // V counter
77 static u32 dwVCounter = 0;
78
79 #ifdef PROTOCOL_USED
80 static const char* strProtocol = "protocol used";
81 #else // PROTOCOL_USED
82 static const char* strProtocol = "non protocol";
83 #endif // PROTOCOL_USED
84
85
86 //-----------------------------------------------------------------------------
87 // Local function definition
88
89 static void myAppInit(void);
90 static void myHioInit(void);
91 static void myHioExit(void);
92 static u32 myMakeColor(void);
93 static void myPaintBox(void);
94 static void myDispInfo(void);
95
96 static inline
myHalt(void)97 void myHalt(void)
98 {
99 OSFatal(gxFont, gxBg, HIO2IFGetErrorMessage());
100 }
101
102 static inline
myIsConnect(void)103 BOOL myIsConnect(void)
104 {
105 return (HIO2IFIsConnected(hioRecvID) | HIO2IFIsConnected(hioSendID));
106 }
107
108 ///////////////////////////////////////////////////////////////////////////////
109 //
110 // Event callback
111 //
112 static
myEventCallback(HIO2IF_ID id,HIO2IF_EVENT event)113 void myEventCallback(HIO2IF_ID id, HIO2IF_EVENT event)
114 {
115 switch ( event )
116 {
117 case HIO2IF_EVENT_CONNECT: // Establish connection
118 #ifdef HIO2IF_DEBUG
119 OSReport("EVENT CONNECT : id(%d) hioRecvID(%d) hioSendID(%d)\n",
120 id, hioRecvID, hioSendID);
121 #endif
122 if ( id == hioRecvID ) pRecvStatus = "CONNECT";
123 else pSendStatus = "CONNECT";
124 break;
125 case HIO2IF_EVENT_DISCONNECT: // connection released
126 #ifdef HIO2IF_DEBUG
127 OSReport("EVENT DISCONNECT : id(%d) hioRecvID(%d) hioSendID(%d)\n",
128 id, hioRecvID, hioSendID);
129 #endif
130 if ( id == hioRecvID ) pRecvStatus = "DISCONNECT";
131 else pSendStatus = "DISCONNECT";
132 (void)HIO2IFClose(id);
133 gxColor.r = gxColor.g = gxColor.b = 0;
134 break;
135 #ifdef PROTOCOL_USED
136 case HIO2IF_EVENT_RECEIVED: // Receive data
137 bReceived = TRUE;
138 break;
139 case HIO2IF_EVENT_SEND_POSSIBLE: // send possible
140 bSendPossible = TRUE;
141 break;
142 #endif // PROTOCOL_USED
143 case HIO2IF_EVENT_READ_ASYNC_DONE:
144 gxColor.r = rgbBuffer[DUAL_DATA_IDX_RED];
145 gxColor.g = rgbBuffer[DUAL_DATA_IDX_GREEN];
146 gxColor.b = rgbBuffer[DUAL_DATA_IDX_BLUE];
147 break;
148 case HIO2IF_EVENT_WRITE_ASYNC_DONE:
149 break;
150 case HIO2IF_EVENT_INTERRUPT:
151 myHalt();
152 break;
153 }
154 }
155
156 ///////////////////////////////////////////////////////////////////////////////
157 //
158 // dual-main function
159 //
160
161 //-----------------------------------------------------------------------------
main(void)162 void main(void)
163 {
164 MYREAD hioIfRead;
165 MYWRITE hioIfWrite;
166
167 // Initialization
168 myAppInit();
169
170 // Change communication method depending on the build method
171 #ifdef PROTOCOL_USED
172 hioIfRead = HIO2IFRead;
173 hioIfWrite = HIO2IFWrite;
174 #else // PROTOCOL_USED
175 hioIfRead = HIO2IFReadFree;
176 hioIfWrite = HIO2IFWriteFree;
177 #endif // PROTOCOL_USED
178
179 // Host I/O initialization
180 myHioInit();
181
182 while ( 1 )
183 {
184 HIO2IF_RESULT result;
185 u32 recvStat = 0, sendStat = 0;
186
187 // Display communication state
188 (void)HIO2IFReadStatus(hioRecvID, &recvStat);
189 (void)HIO2IFReadStatus(hioSendID, &sendStat);
190 (void)DEMORFPrintf(POS_STAT_X, POS_RECV_STAT_Y, 0, "R:%04X", recvStat);
191 (void)DEMORFPrintf(POS_STAT_X, POS_SEND_STAT_Y, 0, "S:%04X", sendStat);
192
193 // Controller input
194 DEMOPadRead();
195
196 // Connect when A Button is pressed
197 // End connection when B Button is pressed
198 // Switch between SYNC and ASYNC modes when the X Button is pressed
199 if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_A ) myHioInit();
200 else if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_B ) myHioExit();
201 else if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_X ) hioAsync=!hioAsync;
202 // Perform receive process when connected to PC
203 if ( bReceived && HIO2IFIsConnected(hioRecvID) )
204 {
205 // Receive from PC
206 result = hioIfRead(hioRecvID, DUAL_PC2NNGC_ADDR,
207 rgbBuffer, DUAL_BUFFER_SIZE, hioAsync);
208 if ( HIO2IF_FAILED(result) ) myHalt();
209 #ifdef PROTOCOL_USED
210 bReceived = FALSE;
211 #endif // PROTOCOL_USED
212
213 // If data has been received, reflect in color data for Paint Box
214 if ( HIO2IF_SUCCESS(result) && !hioAsync )
215 {
216 gxColor.r = rgbBuffer[DUAL_DATA_IDX_RED];
217 gxColor.g = rgbBuffer[DUAL_DATA_IDX_GREEN];
218 gxColor.b = rgbBuffer[DUAL_DATA_IDX_BLUE];
219 }
220 }
221
222 // Send current color data to the PC when connected
223 if ( bSendPossible && HIO2IFIsConnected(hioSendID) )
224 {
225 rgbBuffer[DUAL_DATA_IDX_RED] = gxColor.r;
226 rgbBuffer[DUAL_DATA_IDX_GREEN] = gxColor.g;
227 rgbBuffer[DUAL_DATA_IDX_BLUE] = gxColor.b;
228 result = hioIfWrite(hioSendID, DUAL_NNGC2PC_ADDR,
229 rgbBuffer, DUAL_BUFFER_SIZE, hioAsync);
230 if ( HIO2IF_FAILED(result) ) myHalt();
231 #ifdef PROTOCOL_USED
232 bSendPossible = FALSE;
233 #endif // PROTOCOL_USED
234 }
235
236 DEMOBeforeRender();
237
238 // Paint Box update
239 myPaintBox();
240
241 // Display information update
242 myDispInfo();
243
244 DEMODoneRender();
245
246 dwVCounter++;
247
248 // Sync
249 HIO2IFSync();
250 }
251
252 }
253
254 //----------------------------------------------------------------------------
255 static
myAppInit(void)256 void myAppInit(void)
257 {
258 GXRenderModeObj* rmp;
259
260 DEMOInit(NULL);
261
262 // DEMORFPrintf() initialization
263 (void)DEMOInitROMFont();
264
265 rmp = DEMOGetRenderModeObj();
266 DEMOInitCaption(DM_FT_OPQ, (s16) rmp->fbWidth, (s16) rmp->efbHeight);
267 DEMOSetFontType(DM_FT_OPQ);
268
269 // Screen initialization
270 GXSetCopyClear(gxBg, 0x00ffffff);
271 GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
272
273 // Paint Box display initialization
274 dwFbWidth =
275 (u32)(VIPadFrameBufferWidth(rmp->fbWidth) * VI_DISPLAY_PIX_SZ );
276 dwFbSize = (u32)(dwFbWidth * rmp->xfbHeight);
277
278 // Controller initialization
279 DEMOPadInit();
280 }
281
282 //----------------------------------------------------------------------------
283 static
myHioInit(void)284 void myHioInit(void)
285 {
286 int count;
287
288 if ( myIsConnect() ) return;
289
290 // Host I/O initialization
291 if ( HIO2IF_FAILED(HIO2IFInit()) ) myHalt();
292
293 // Gets the number of enumerated devices
294 count = HIO2IFGetDeviceCount();
295
296 // Receive channel open
297 if ( count > 0 )
298 {
299 if ( HIO2IF_FAILED(HIO2IFOpen(
300 HIO2IFGetDevice(0),
301 HIO2IF_MODE_RDONLY,
302 myEventCallback,
303 &hioRecvID)) )
304 myHalt();
305 pRecvStatus = "DISCONNECT";
306 #ifdef PROTOCOL_USED
307 bReceived = FALSE;
308 #endif
309 }
310
311 // Send channel open
312 if ( count > 1 )
313 {
314 if ( HIO2IF_FAILED(HIO2IFOpen(
315 HIO2IFGetDevice(1),
316 HIO2IF_MODE_WRONLY,
317 myEventCallback,
318 &hioSendID)) )
319 myHalt();
320 pSendStatus = "DISCONNECT";
321 #ifdef PROTOCOL_USED
322 bSendPossible = TRUE;
323 #endif
324 }
325 }
326
327 //----------------------------------------------------------------------------
328 static
myHioExit(void)329 void myHioExit(void)
330 {
331 if ( HIO2IFIsConnected(hioRecvID) )
332 {
333 (void)HIO2IFClose(hioRecvID);
334 pRecvStatus = "DISCONNECT";
335 #ifdef PROTOCOL_USED
336 bReceived = FALSE;
337 #endif
338 }
339
340 if ( HIO2IFIsConnected(hioSendID) )
341 {
342 (void)HIO2IFClose(hioSendID);
343 pSendStatus = "DISCONNECT";
344 #ifdef PROTOCOL_USED
345 bSendPossible = FALSE;
346 #endif
347 }
348
349 gxColor.r = gxColor.g = gxColor.b = 0;
350 }
351
352 //----------------------------------------------------------------------------
myMakeColor(void)353 u32 myMakeColor(void)
354 {
355 #define CLAMP(x,l,h) ((x > h) ? h : ((x < l) ? l : x))
356
357 u32 colY , colCr , colCb , colVal;
358 double Y,Cr,Cb;
359
360 Y = 0.257 * gxColor.r + 0.504 * gxColor.g + 0.098
361 * gxColor.b + 16.0 + 0.5;
362 Cb = -0.148 * gxColor.r - 0.291 * gxColor.g + 0.439
363 * gxColor.b + 128.0 + 0.5;
364 Cr = 0.439 * gxColor.r - 0.368 * gxColor.g - 0.071
365 * gxColor.b + 128.0 + 0.5;
366
367 Y = CLAMP(Y , 16, 235);
368 Cb = CLAMP(Cb, 16, 240);
369 Cr = CLAMP(Cr, 16, 240);
370
371 colY = (u32)Y;
372 colCr = (u32)Cr;
373 colCb = (u32)Cb;
374
375 colVal = (colY << 24) | (colCb << 16) | (colY << 8) | colCr;
376
377 return colVal;
378 }
379
380 //----------------------------------------------------------------------------
381 static
myPaintBox(void)382 void myPaintBox(void)
383 {
384 u32 x=96, y=128, w=128, h=192, col = myMakeColor();
385 u32 pixSize = (VI_DISPLAY_PIX_SZ << 1), lineSize = pixSize * w, i;
386 u8* xfb = VIGetNextFrameBuffer();
387
388 for (i=0; i<h; i++)
389 {
390 u8 *ptr, *sPtr;
391 sPtr = xfb + (pixSize * x) + (dwFbWidth * (y + i));
392 for (ptr=sPtr; ptr<(sPtr + lineSize); ptr+=pixSize)
393 *(u32*)ptr = col;
394 }
395
396 DCStoreRange((void*)xfb, dwFbSize);
397 }
398
399 //----------------------------------------------------------------------------
400 static
myDispInfo(void)401 void myDispInfo(void)
402 {
403 static const char* devName[HIO2_CHAN_MAX + 2] =
404 { "UNKOWN", "EXI2USB0", "EXI2USB1", "MrEXI" };
405
406 // Title
407 (void)DEMORFPrintf(POS_COMM_X, POS_TITLE_Y, 0, "HIO2 DEMO - dual(%s)",
408 strProtocol);
409 // Color
410 (void)DEMORFPrintf(POS_COL_X, POS_R_Y, 0, " R:%02X(%03d)",
411 gxColor.r, gxColor.r);
412 (void)DEMORFPrintf(POS_COL_X, POS_G_Y, 0, " G:%02X(%03d)",
413 gxColor.g, gxColor.g);
414 (void)DEMORFPrintf(POS_COL_X, POS_B_Y, 0, " B:%02X(%03d)",
415 gxColor.b, gxColor.b);
416
417 (void)DEMORFPrintf(POS_COMM_X, POS_RECV_Y, 0,
418 " RECV CHAN : %s, NDEV %s, PC%d",
419 pRecvStatus, devName[HIO2IFGetDeviceType(hioRecvID)+1],
420 HIO2IFGetPcChan(hioRecvID));
421
422 (void)DEMORFPrintf(POS_COMM_X, POS_SEND_Y, 0,
423 " SEND CHAN : %s, NDEV %s, PC%d",
424 pSendStatus, devName[HIO2IFGetDeviceType(hioSendID)+1],
425 HIO2IFGetPcChan(hioSendID));
426
427 // V counter
428 (void)DEMORFPrintf(POS_COMM_X, POS_V_Y, 0, " V=%ld", dwVCounter);
429
430 // Connection state
431 (void)DEMORFPrintf(POS_CONNECT_X, POS_CONNECT_Y, 0,
432 myIsConnect() ?
433 "PUSH B DISCONNECT" : "PUSH A CONNECT");
434
435 // SYNC/ASYNC status
436 (void)DEMORFPrintf(POS_SYNC_X, POS_SYNC_Y, 0, hioAsync ? "ASYNC" : "SYNC");
437 }
438
439 // end of dual-main.c
440