/*---------------------------------------------------------------------------* Project: HIO2 demos - simple File: simple.c (C)2005 HUDSON SOFT $Header: /home/cvsroot/SDK/build/demos/hio2demo/src/simple.c,v 1.4 2007/11/26 13:54:44 iwai_yuma Exp $ $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include #include "multi.h" // Divert to generate send 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 device that was detected exiDev = type; return FALSE; } // receive : // // Use as a callback function when detecting a mailbox write from the PC with an interrupt // // // Use as a subroutine when detecting a mailbox write from the PC with status // // 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 + 1); 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 or received if ( !sendPossible ) continue; // Perform a PC connection notification when mail can be sent/received 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, "NDEV 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); // When the device could not 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