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.2 2006/03/09 12:28:38 yasuh-to 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 generation of sent 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 detected device
83 exiDev = type;
84 return FALSE;
85 }
86
87 // receive :
88 //
89 // use as a callback function when detected during an interrupt of a mailbox write
90 // from the PC
91 //
92 // use as a subroutine when detected during status of a mailbox write
93 // from the PC
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
176 if ( !sendPossible ) continue;
177
178 // perform a PC connection notification when mail can be sent 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, "NNGC 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 // if device cannot 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