/*---------------------------------------------------------------------------* Project: HIO2 demos - simple File: simple.c (C)2005 HUDSON SOFT $Header: /home/cvsroot/SDK/build/demos/hio2demo/src/simple.c,v 1.2 2006/03/09 12:28:38 yasuh-to Exp $ $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include #include "multi.h" // divert to generation of sent data #include "simple.h" //----------------------------------------------------------------------------- // define // coordinates for DEMORFPrintf() #define POS_COMM_X 32 #define POS_TITLE_Y 64 #define POS_SEND_Y 96 #define POS_SENDDATA_Y 128 #define POS_RECVDATA_Y 192 #define POS_MES_Y 416 #define POS_CONNECT_X 480 //----------------------------------------------------------------------------- // local symbol definition // HIO2 API handle static HIO2Handle hHIO2; // HIO2 API buffer static MULTI_PACKET sendBuffer ATTRIBUTE_ALIGN(32); static MULTI_PACKET recvBuffer ATTRIBUTE_ALIGN(32); // color data static const GXColor gxFont = { 0xFF, 0xFF, 0xFF, 0 }, gxBg = { 0, 0, 0, 0 }; // Error messages static char strError[128] = { '\0' }; // EXI device static HIO2DeviceType exiDev = HIO2_DEVICE_INVALID; // PC connection state static BOOL bConnect = FALSE; // termination flag static BOOL bExit = FALSE; // send flag static BOOL bSend = TRUE; //----------------------------------------------------------------------------- // local function declared static void myAppInit( void ); static void myUpdateDisp( void ); static void myHIO2Init( void ); static void myHIO2Exit( void ); static inline void myHalt( SIMPLE_ERROR errno ) { (void)sprintf(strError, simpleErrorMessage[errno], HIO2GetLastError()); OSFatal(gxFont, gxBg, strError); } /////////////////////////////////////////////////////////////////////////////// // // callback // // enum devices static BOOL myEnumCallback( HIO2DeviceType type ) { // use the first detected device exiDev = type; return FALSE; } // receive : // // use as a callback function when detected during an interrupt of a mailbox write // from the PC // // use as a subroutine when detected during status of a mailbox write // from the PC // static void myReceiveCallback( HIO2Handle h ) { u32 mail; if ( !HIO2ReadMailbox(h, &mail) ) myHalt(SIMPLE_ERR_HIO2_READ_MAILBOX); switch ( mail ) { case SIMPLE_MAIL_OPEN_RESULT: // open completion notification from connection target bConnect = TRUE; break; case SIMPLE_MAIL_RECV: // receive data from connection target if ( !HIO2Read(h, SIMPLE_PC2NNGC_ADDR, &recvBuffer, sizeof(recvBuffer)) ) myHalt(SIMPLE_ERR_HIO2_READ); DCInvalidateRange(&recvBuffer, sizeof(recvBuffer)); break; case SIMPLE_MAIL_EXIT: // termination notification from connection target bExit = TRUE; break; } } // disconnect static void myDisconnectCallback( HIO2Handle h ) { #pragma unused(h) myHalt(SIMPLE_ERR_EXI2USB_DISCONNECT); } /////////////////////////////////////////////////////////////////////////////// // // simple function // //----------------------------------------------------------------------------- void main( void ) { int v = 0; // initialization myAppInit(); // HIO2 API initialization myHIO2Init(); while ( !bExit ) { OSCalendarTime calender; BOOL sendPossible = FALSE; // display update DEMOBeforeRender(); myUpdateDisp(); DEMODoneRender(); // controller input DEMOPadRead(); // set calendar input results to PC send buffer OSTicksToCalendarTime(OSGetTime(), &calender); sendBuffer.mon = (u8)calender.mon; sendBuffer.mday = (u8)calender.mday; sendBuffer.hour = (u8)calender.hour; sendBuffer.min = (u8)calender.min; sendBuffer.sec = (u8)calender.sec; sendBuffer.msec = (u16)calender.msec; { u32 status; // get HIO2 status if ( !HIO2ReadStatus(hHIO2, &status) ) myHalt(SIMPLE_ERR_HIO2_READ_STATUS); sendPossible = !(status & HIO2_STATUS_RX); #ifdef POLLING if ( status & HIO2_STATUS_TX ) myReceiveCallback(hHIO2); #endif // POLLING } // do nothing when mail cannot be sent if ( !sendPossible ) continue; // perform a PC connection notification when mail can be sent but there is no PC connection yet if ( !bConnect ) { if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_OPEN) ) myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX); continue; } // switch between send and receive when A button is pressed if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_A ) { bSend = !bSend; if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_CHANGE) ) myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX); } // perform PC termination notification and terminate when START button is pressed else if ( DEMOPadGetButtonDown(0) & PAD_BUTTON_START ) { if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_EXIT) ) myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX); bExit = TRUE; } // send data to PC during send state (in 60V units) else if ( bSend && (++v == 60) ) { DCFlushRange(&sendBuffer, sizeof(sendBuffer)); if ( !HIO2Write(hHIO2, SIMPLE_NNGC2PC_ADDR, &sendBuffer, sizeof(sendBuffer)) ) myHalt(SIMPLE_ERR_HIO2_WRITE); if ( !HIO2WriteMailbox(hHIO2, SIMPLE_MAIL_RECV) ) myHalt(SIMPLE_ERR_HIO2_WRITE_MAILBOX); v = 0; } } // HIO2 termination myHIO2Exit(); } //---------------------------------------------------------------------------- static void myAppInit( void ) { GXRenderModeObj* rmp; DEMOInit(NULL); // DEMORFPrintf() initialization (void)DEMOInitROMFont(); rmp = DEMOGetRenderModeObj(); DEMOInitCaption(DM_FT_OPQ, (s16) rmp->fbWidth, (s16) rmp->efbHeight); DEMOSetFontType(DM_FT_OPQ); // screen initialization GXSetCopyClear(gxBg, 0x00ffffff); GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE); // controller initialization DEMOPadInit(); (void)strcpy(sendBuffer.string, "NNGC TIME"); (void)strcpy(recvBuffer.string, "PC TIME"); } //---------------------------------------------------------------------------- static void myUpdateDisp( void ) { char dispBuf[128]; // Title #ifndef POLLING (void)DEMORFPrintf(POS_COMM_X, POS_TITLE_Y, 0, "HIO2 DEMO - simple (EXI INT)"); #else // POLLING (void)DEMORFPrintf(POS_COMM_X, POS_TITLE_Y, 0, "HIO2 DEMO - simple (polling)"); #endif // POLLING // Connection state (void)DEMORFPrintf(POS_CONNECT_X, POS_TITLE_Y, 0, bConnect ? "CONNECT" : "DISCONNECT"); // send/receive state (void)DEMORFPrintf(POS_CONNECT_X, POS_SEND_Y, 0, bSend ? "SEND" : "RECV"); // send information MultiPacketToString(dispBuf, &sendBuffer); (void)DEMORFPrintf(POS_COMM_X, POS_SENDDATA_Y, 0, dispBuf); // receive information MultiPacketToString(dispBuf, &recvBuffer); (void)DEMORFPrintf(POS_COMM_X, POS_RECVDATA_Y, 0, "%s", dispBuf); // message (void)DEMORFPrintf(POS_COMM_X, POS_MES_Y, 0, "push START button to exit"); } //---------------------------------------------------------------------------- static void myHIO2Init( void ) { // initialization if ( !HIO2Init() ) myHalt(SIMPLE_ERR_HIO2_INIT); // device list if ( !HIO2EnumDevices(myEnumCallback) ) myHalt(SIMPLE_ERR_HIO2_ENUMDEVICES); // if device cannot be found if ( exiDev == HIO2_DEVICE_INVALID ) myHalt(SIMPLE_ERR_EXI2USB_NOT_FIND); #ifndef POLLING // device open if ( (hHIO2=HIO2Open(exiDev, myReceiveCallback, myDisconnectCallback)) == HIO2_INVALID_HANDLE_VALUE ) myHalt(SIMPLE_ERR_HIO2_OPEN); #else // POLLING // device open if ( (hHIO2=HIO2Open(exiDev, NULL, myDisconnectCallback)) == HIO2_INVALID_HANDLE_VALUE ) myHalt(SIMPLE_ERR_HIO2_OPEN); #endif // POLLING } //---------------------------------------------------------------------------- static void myHIO2Exit( void ) { (void)HIO2Close(hHIO2); HIO2Exit(); DEMOBeforeRender(); (void)DEMORFPrintf(POS_COMM_X, POS_TITLE_Y, 0, "HIO2 DEMO - simple done."); DEMODoneRender(); } // end of simple.c