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