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.3 2006/08/16 08:13:07 mitu 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 	OSFatal(gxFont, gxBg, strError);
71 }
72 
73 ///////////////////////////////////////////////////////////////////////////////
74 //
75 // callback
76 //
77 
78 // enum devices
79 static
myEnumCallback(HIO2DeviceType type)80 BOOL	myEnumCallback( HIO2DeviceType type )
81 {
82 	// Use the first device that was detected
83 	exiDev = type;
84 	return FALSE;
85 }
86 
87 // receive :
88 //
89 // Use as a callback function when detecting a mailbox write from the PC with an interrupt
90 //
91 //
92 // Use as a subroutine when detecting a mailbox write from the PC with status
93 //
94 //
95 static
myReceiveCallback(HIO2Handle h)96 void	myReceiveCallback( HIO2Handle h )
97 {
98 	u32 mail;
99 
100 	if ( !HIO2ReadMailbox(h, &mail) ) myHalt(SIMPLE_ERR_HIO2_READ_MAILBOX);
101 
102 	switch ( mail )
103 	{
104 	case SIMPLE_MAIL_OPEN_RESULT:	// Open completion notification from connection target
105 		bConnect = TRUE;
106 		break;
107 	case SIMPLE_MAIL_RECV:	// Receive data from connection target
108 		if ( !HIO2Read(h, SIMPLE_PC2NNGC_ADDR, &recvBuffer,
109 					   sizeof(recvBuffer)) )
110 			myHalt(SIMPLE_ERR_HIO2_READ);
111 		DCInvalidateRange(&recvBuffer, sizeof(recvBuffer));
112 		break;
113 	case SIMPLE_MAIL_EXIT:	// Termination notification from connection target
114 		bExit = TRUE; break;
115 	}
116 }
117 
118 // disconnect
119 static
myDisconnectCallback(HIO2Handle h)120 void	myDisconnectCallback( HIO2Handle h )
121 {
122 #pragma unused(h)
123 	myHalt(SIMPLE_ERR_EXI2USB_DISCONNECT);
124 }
125 
126 ///////////////////////////////////////////////////////////////////////////////
127 //
128 // simple function
129 //
130 
131 //-----------------------------------------------------------------------------
main(void)132 void	main( void )
133 {
134 	int v = 0;
135 
136 	// Initialization
137 	myAppInit();
138 
139 	// HIO2 API initialization
140 	myHIO2Init();
141 
142 	while ( !bExit )
143 	{
144 		OSCalendarTime calender;
145 		BOOL sendPossible = FALSE;
146 
147 		// Display update
148 		DEMOBeforeRender();
149 		myUpdateDisp();
150 		DEMODoneRender();
151 
152 		// Controller input
153 		DEMOPadRead();
154 
155 		// Set calendar input results to PC send buffer
156 		OSTicksToCalendarTime(OSGetTime(), &calender);
157 		sendBuffer.mon	= (u8)calender.mon;
158 		sendBuffer.mday	= (u8)calender.mday;
159 		sendBuffer.hour	= (u8)calender.hour;
160 		sendBuffer.min	= (u8)calender.min;
161 		sendBuffer.sec	= (u8)calender.sec;
162 		sendBuffer.msec	= (u16)calender.msec;
163 		{
164 			u32 status;
165 			// Get HIO2 status
166 			if ( !HIO2ReadStatus(hHIO2, &status) )
167 				myHalt(SIMPLE_ERR_HIO2_READ_STATUS);
168 			sendPossible = !(status & HIO2_STATUS_RX);
169 #ifdef	POLLING
170 			if ( status & HIO2_STATUS_TX )
171 				myReceiveCallback(hHIO2);
172 #endif	// POLLING
173 		}
174 
175 		// Do nothing when mail cannot be sent or received
176 		if ( !sendPossible ) continue;
177 
178 		// Perform a PC connection notification when mail can be sent/received but there is no PC connection yet
179 		if ( !bConnect )
180 		{
181 			if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_OPEN) )
182 				myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX);
183 			continue;
184 		}
185 
186 		// Switch between send and receive when A Button is pressed
187 		if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_A )
188 		{
189 			bSend = !bSend;
190 			if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_CHANGE) )
191 				myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX);
192 		}
193 		// Perform PC termination notification and terminate when START Button is pressed
194 		else if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_START )
195 		{
196 			if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_EXIT) )
197 				myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX);
198 				bExit = TRUE;
199 		}
200 		// Send data to PC during send state (in 60V units)
201 		else if ( bSend && (++v == 60) )
202 		{
203 			DCFlushRange(&sendBuffer, sizeof(sendBuffer));
204 			if ( !HIO2Write(hHIO2, SIMPLE_NNGC2PC_ADDR,	&sendBuffer,
205 							sizeof(sendBuffer)) )
206 				myHalt(SIMPLE_ERR_HIO2_WRITE);
207 			if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_RECV) )
208 				myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX);
209 			v = 0;
210 		}
211 	}
212 
213 	// HIO2 termination
214 	myHIO2Exit();
215 }
216 
217 //----------------------------------------------------------------------------
218 static
myAppInit(void)219 void	myAppInit( void )
220 {
221     GXRenderModeObj* rmp;
222 
223 	DEMOInit(NULL);
224 
225 	// DEMORFPrintf() initialization
226 	(void)DEMOInitROMFont();
227 
228     rmp = DEMOGetRenderModeObj();
229     DEMOInitCaption(DM_FT_OPQ, (s16) rmp->fbWidth, (s16) rmp->efbHeight);
230     DEMOSetFontType(DM_FT_OPQ);
231 
232 	// Screen initialization
233     GXSetCopyClear(gxBg, 0x00ffffff);
234     GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
235 
236 	// Controller initialization
237 	DEMOPadInit();
238 
239 	(void)strcpy(sendBuffer.string, "NDEV TIME");
240 	(void)strcpy(recvBuffer.string, "PC TIME");
241 }
242 
243 //----------------------------------------------------------------------------
244 static
myUpdateDisp(void)245 void	myUpdateDisp( void )
246 {
247 	char dispBuf[128];
248 
249 	// Title
250 #ifndef	POLLING
251 	(void)DEMORFPrintf(POS_COMM_X, POS_TITLE_Y, 0,
252 					   "HIO2 DEMO - simple (EXI INT)");
253 #else	// POLLING
254 	(void)DEMORFPrintf(POS_COMM_X, POS_TITLE_Y, 0,
255 					   "HIO2 DEMO - simple (polling)");
256 #endif	// POLLING
257 
258 	// Connection state
259 	(void)DEMORFPrintf(POS_CONNECT_X, POS_TITLE_Y, 0,
260 					   bConnect ? "CONNECT" : "DISCONNECT");
261 
262 	// Send/receive state
263 	(void)DEMORFPrintf(POS_CONNECT_X, POS_SEND_Y, 0, bSend ? "SEND" : "RECV");
264 
265 	// Send information
266 	MultiPacketToString(dispBuf, &sendBuffer);
267 	(void)DEMORFPrintf(POS_COMM_X, POS_SENDDATA_Y, 0, dispBuf);
268 
269 	// Receive information
270 	MultiPacketToString(dispBuf, &recvBuffer);
271 	(void)DEMORFPrintf(POS_COMM_X, POS_RECVDATA_Y, 0, "%s", dispBuf);
272 
273 	// Message
274 	(void)DEMORFPrintf(POS_COMM_X, POS_MES_Y, 0,
275 					   "push START button to exit");
276 }
277 
278 //----------------------------------------------------------------------------
279 static
myHIO2Init(void)280 void	myHIO2Init( void )
281 {
282 	// Initialization
283 	if ( !HIO2Init() ) myHalt(SIMPLE_ERR_HIO2_INIT);
284 
285 	// Device list
286 	if ( !HIO2EnumDevices(myEnumCallback) ) myHalt(SIMPLE_ERR_HIO2_ENUMDEVICES);
287 
288 	// When the device could not be found
289 	if ( exiDev == HIO2_DEVICE_INVALID ) myHalt(SIMPLE_ERR_EXI2USB_NOT_FIND);
290 
291 #ifndef	POLLING
292 	// Device open
293 	if ( (hHIO2=HIO2Open(exiDev, myReceiveCallback, myDisconnectCallback))
294 		== HIO2_INVALID_HANDLE_VALUE )
295 		myHalt(SIMPLE_ERR_HIO2_OPEN);
296 #else	// POLLING
297 	// Device open
298 	if ( (hHIO2=HIO2Open(exiDev, NULL, myDisconnectCallback))
299 		== HIO2_INVALID_HANDLE_VALUE )
300 		myHalt(SIMPLE_ERR_HIO2_OPEN);
301 #endif	// POLLING
302 }
303 
304 //----------------------------------------------------------------------------
305 static
myHIO2Exit(void)306 void	myHIO2Exit( void )
307 {
308 	(void)HIO2Close(hHIO2);
309 	HIO2Exit();
310 
311 	DEMOBeforeRender();
312 
313 	(void)DEMORFPrintf(POS_COMM_X, POS_TITLE_Y, 0, "HIO2 DEMO - simple done.");
314 
315 	DEMODoneRender();
316 }
317 
318 // end of simple.c
319