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