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