#include #include #include #include #include #include // P4. Needed to get the ROM version #include "SitzmarkRsc.h" #pragma bool on /*********************************************************************** * * Internal Structures * ***********************************************************************/ struct StarterPreferenceType { Byte replaceme; } ; struct StarterAppInfoType { Byte replaceme; } ; /*********************************************************************** * * Internal Constants * ***********************************************************************/ const unsigned long appFileCreator = 'STRT'; const unsigned short appVersionNum = 0x01; const unsigned short appPrefID = 0x00; const unsigned short appPrefVersionNum = 0x01; const unsigned long version20 = 0x02000000; #define BAUDRATE 4800 #define FRAMINGBYTE 0x1C #define SerRcvQueueSize 100 #define POLLING SysTicksPerSecond() #define MASK(x) 0x0001&x #define FileName "SitzmarkFile" const unsigned long FileCreator = 'SITC'; const unsigned long FileType = 'SITT'; #define SitzmarkAppType 'Sitz' // P5. type for application. must be 4 chars, mixed case. #define SitzmarkDBType 'Data' // P5. type for application database. must be 4 chars, mixed case. #define SitzmarkDBName "SitzmarkDB" // P5. name for application database. up to 31 characters. #define noRecordSelected -1 // P5. index for no current record. /*********************************************************************** * * Global variables * ***********************************************************************/ static UInt serRefNum; static bool EVBDetected; static Char serRcvQueue[SerRcvQueueSize]; //serial receive queue static Word waitBetweenSends; static FileHand FileHandle; static DmOpenRef SDataBase; /*********************************************************************** * * Internal Functions * ************************************************************************/ static void SitzmarkMain(); static bool RequestData(); static void RFConnect(); static void RFDisconnect(); static void PalmSleep (UInt sec); static void PrintInt (Long i, SWord x, SWord y); static void FileToDB (); static void WriteToFile (Char* dataP, Long objSize, Long numObj); static void ReadFrFile(Long objSize); /*********************************************************************** * * FUNCTION: RomVersionCompatible * * DESCRIPTION: This routine checks that a ROM version is meet your * minimum requirement. * * PARAMETERS: requiredVersion - minimum rom version required * (see sysFtrNumROMVersion in SystemMgr.h * for format) * launchFlags - flags that indicate if the application * UI is initialized. * * RETURNED: error code or zero if rom is compatible * * REVISION HISTORY: * ***********************************************************************/ static Err RomVersionCompatible(DWord requiredVersion, Word launchFlags) { DWord romVersion; // See if we're on in minimum required version of the ROM or later. FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); if (romVersion < requiredVersion) { if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) { FrmAlert (RomIncompatibleAlert); // Pilot 1.0 will continuously relaunch this app unless we switch to // another safe one. if (romVersion < version20) { //Err err; AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); } } return (sysErrRomIncompatible); } return (0); } /*********************************************************************** * * FUNCTION: GetObjectPtr * * DESCRIPTION: This routine returns a pointer to an object in the current * form. * * PARAMETERS: formId - id of the form to display * * RETURNED: VoidPtr * * REVISION HISTORY: * * ***********************************************************************/ static VoidPtr GetObjectPtr(Word objectID) { FormPtr frmP; frmP = FrmGetActiveForm(); return (FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); } /*********************************************************************** * * FUNCTION: MainFormInit * * DESCRIPTION: This routine initializes the MainForm form. * * PARAMETERS: frm - pointer to the MainForm form. * * RETURNED: nothing * * REVISION HISTORY: * * ***********************************************************************/ static void MainFormInit(FormPtr frmP) { } /*********************************************************************** * * FUNCTION: MainFormDoCommand * * DESCRIPTION: This routine performs the menu command specified. * * PARAMETERS: command - menu item id * * RETURNED: nothing * * REVISION HISTORY: * * ***********************************************************************/ static Boolean MainFormDoCommand(Word command) { FormPtr frmP; Boolean handled = false; switch (command) { case MainOptionsAboutSitzmark: MenuEraseStatus(0); frmP = FrmInitForm(INFOForm); FrmDoDialog(frmP); FrmDeleteForm(frmP); handled = true; break; } return handled; } /*********************************************************************** * * FUNCTION: MainFormHandleEvent * * DESCRIPTION: This routine is the event handler for the * "MainForm" of this application. * * PARAMETERS: eventP - a pointer to an EventType structure * * RETURNED: true if the event has handle and should not be passed * to a higher level handler. * * REVISION HISTORY: * * ***********************************************************************/ static Boolean MainFormHandleEvent(EventPtr eventP) { Boolean handled = false; FormPtr frmP; switch (eventP->eType) { case menuEvent: return MainFormDoCommand(eventP->data.menu.itemID); case frmOpenEvent: frmP = FrmGetActiveForm(); MainFormInit( frmP); FrmDrawForm ( frmP); handled = true; break; default: break; } return handled; } /*********************************************************************** * * FUNCTION: AppHandleEvent * * DESCRIPTION: This routine loads form resources and set the event * handler for the form loaded. * * PARAMETERS: event - a pointer to an EventType structure * * RETURNED: true if the event has handle and should not be passed * to a higher level handler. * * REVISION HISTORY: * * ***********************************************************************/ static Boolean AppHandleEvent( EventPtr eventP) { Word formId; FormPtr frmP; if (eventP->eType == frmLoadEvent) { // Load the form resource. formId = eventP->data.frmLoad.formID; frmP = FrmInitForm(formId); FrmSetActiveForm(frmP); // Set the event handler for the form. The handler of the currently // active form is called by FrmHandleEvent each time is receives an // event. switch (formId) { case SITZMARKForm: { FrmSetEventHandler(frmP, MainFormHandleEvent); RFConnect(); // Open serial connection } break; default: // ErrFatalDisplay("Invalid Form Load Event"); break; } return true; } return false; } /*********************************************************************** * * FUNCTION: AppEventLoop * * DESCRIPTION: This routine is the event loop for the application. * * PARAMETERS: nothing * * RETURNED: nothing * * REVISION HISTORY: * * ***********************************************************************/ static void AppEventLoop(void) { Word error; EventType event; do { //EvtGetEvent(&event, evtWaitForever); EvtGetEvent(&event, 100); if (! SysHandleEvent(&event)) if (! MenuHandleEvent(0, &event, &error)) if (! AppHandleEvent(&event)) FrmDispatchEvent(&event); SitzmarkMain(); } while (event.eType != appStopEvent); } /*********************************************************************** * * FUNCTION: AppStart * * DESCRIPTION: Get the current application's preferences. * * PARAMETERS: nothing * * RETURNED: Err value 0 if nothing went wrong * * REVISION HISTORY: * * ***********************************************************************/ static AppStart (void) { /*StarterPreferenceType prefs; Word prefsSize; // Read the saved preferences / saved-state information. prefsSize = sizeof(StarterPreferenceType); if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != noPreferenceFound) { } */ Err err = 0; Long filesize = 0; UInt cardNo; LocalID dbID; UInt dbAttrs; UInt DBmode = dmModeReadWrite; serRefNum = 0; EVBDetected = false; waitBetweenSends = 0; FileHandle = 0; // Open/Create Database SDataBase = DmOpenDatabaseByTypeCreator(SitzmarkDBType, SitzmarkAppType, DBmode); if (!SDataBase) { err = DmCreateDatabase(0, SitzmarkDBName, SitzmarkAppType,SitzmarkDBType, false); ErrFatalDisplayIf(err, "Could not create new database."); SDataBase = DmOpenDatabaseByTypeCreator(SitzmarkDBType, SitzmarkAppType, DBmode); err = DmOpenDatabaseInfo(SDataBase, &dbID, NULL, NULL, &cardNo, NULL); ErrFatalDisplayIf(err, "Could not get database info."); err = DmDatabaseInfo(0, dbID, NULL, &dbAttrs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ErrFatalDisplayIf(err, "Could not get database info."); err = DmSetDatabaseInfo(0, dbID, NULL, &dbAttrs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); ErrFatalDisplayIf(err, "Could not set database info."); } // Open file for read and write DWord mode = fileModeReadWrite | fileModeTemporary; FileHandle = FileOpen (0, FileName, 0, 0, mode,&err); ErrFatalDisplayIf(err, "Problem openning file Sitzmark!"); FileRewind(FileHandle); FileWrite (FileHandle, "Time,Speed,Heart Rate,Latitude,Longitude\n",sizeof(char),41,&err); // Long index = FileTell(FileHandle, &filesize, &err); // ErrFatalDisplayIf(err, "Problem with file Sitzmark!"); // PrintInt(filesize, 5, 130); // PrintInt(index, 5, 140); // ReadFrFile (sizeof(Char)); return 0; } /*********************************************************************** * * FUNCTION: AppStop * * DESCRIPTION: Save the current state of the application. * * PARAMETERS: nothing * * RETURNED: nothing * * REVISION HISTORY: * * ***********************************************************************/ static void AppStop(void) { /* StarterPreferenceType prefs; // Write the saved preferences / saved-state information. This data // will be backed up during a HotSync. PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, &prefs, sizeof (prefs), true); */ Err err=0; // Close the application's database. FileToDB(); // Close file err = FileClose (FileHandle); DmCloseDatabase(SDataBase); // PrintInt(err, 5, 110); // for(int i=0; i<10000; i++); // ErrFatalDisplayIf(err != 0, "Problem closing file Sitzmark!"); // Close connection RFDisconnect(); } /*********************************************************************** * * FUNCTION: StarterPilotMain * * DESCRIPTION: This is the main entry point for the application. * PARAMETERS: cmd - word value specifying the launch code. * cmdPB - pointer to a structure that is associated with the launch code. * launchFlags - word value providing extra information about the launch. * * RETURNED: Result of launch * * REVISION HISTORY: * * ***********************************************************************/ static DWord StarterPilotMain(Word cmd, Ptr cmdPBP, Word launchFlags) { Err error; error = RomVersionCompatible (version20, launchFlags); if (error) return (error); switch (cmd) { case sysAppLaunchCmdNormalLaunch: error = AppStart(); if (error) return error; FrmGotoForm(SITZMARKForm); AppEventLoop(); AppStop(); break; default: break; } return 0; } /*********************************************************************** * * FUNCTION: PilotMain * * DESCRIPTION: This is the main entry point for the application. * * PARAMETERS: cmd - word value specifying the launch code. * cmdPB - pointer to a structure that is associated with the launch code. * launchFlags - word value providing extra information about the launch. * RETURNED: Result of launch * * REVISION HISTORY: * * ***********************************************************************/ DWord PilotMain( Word cmd, Ptr cmdPBP, Word launchFlags) { return StarterPilotMain(cmd, cmdPBP, launchFlags); } /*********************************************************************** * * Function: * * Description: * * Parameters: * * Returned: * * Revision History: * * ***********************************************************************/ static void SitzmarkMain() { ULong numBytes = 0; Err err = 0; if(RequestData()) { SerReceiveCheck(serRefNum, &numBytes); SerReceive(serRefNum, serRcvQueue, numBytes, 0, &err); if (err) return; // Receive data from Handy Board WinDrawChars("Reveiving Data...", 17, 5, 100); // WinDrawChars(serRcvQueue, numBytes, 5, 110); WriteToFile(serRcvQueue, sizeof(Char), numBytes); waitBetweenSends = 0; } return; } static void FileToDB () { Long filesize; VoidPtr textPtr; VoidHand textHandle; UInt index = 0; Err err = 0; CharPtr text = "Hello World"; FileTell(FileHandle, &filesize, NULL); if (filesize) { //textHandle = DmNewRecord(SDataBase, &index, StrLen(text)+1); textHandle = DmNewRecord(SDataBase, &index, filesize); textPtr = MemHandleLock(textHandle); //DmWrite(textPtr, 0, text, StrLen(text)+1); FileRewind(FileHandle); FileDmRead (FileHandle, textPtr, 0, sizeof(Char), filesize, &err); ErrFatalDisplayIf(err, "Problem writing Sitzmark Database"); MemHandleUnlock(textHandle); DmReleaseRecord(SDataBase, index, true); } } static void WriteToFile (Char* dataP, Long objSize, Long numObj) { Err err; int i, j; char buffer [32]; //FileWrite (FileHandle, "hello world\n", sizeof(char), 12, &err); /*** //***************Parse packet here ******************** // Write Time unsigned long time = TimGetSeconds(); StrIToA (buffer, time); FileWrite (FileHandle, buffer, sizeof(char), StrLen(buffer), &err); FileWrite (FileHandle, ",", sizeof(char), 1, &err); // Write Speed if (dataP[1] == 255) FileWrite (FileHandle, "0,", sizeof(char), 2, &err); else { StrIToA (buffer, dataP[1]); FileWrite (FileHandle, buffer, sizeof(char), StrLen(buffer), &err); FileWrite (FileHandle, ",", sizeof(char), 1, &err); } // Write Heart Rate StrIToA (buffer, dataP[3]); FileWrite (FileHandle, buffer, sizeof(char), StrLen(buffer), &err); FileWrite (FileHandle, ",", sizeof(char), 1, &err); // Write Latitude, Longitude // check validity of GPS data if (dataP[0] == 255) FileWrite (FileHandle, ",,", sizeof(char), 2, &err); else { i=5; j=0; while (dataP[i] != ',') { buffer[j] = dataP[i]; i++;j++; } // Write latitude FileWrite (FileHandle, buffer, sizeof(char), StrLen(buffer), &err); FileWrite (FileHandle, ",", sizeof(char), 1, &err); i++; j=0; while (dataP[i] != ',') { buffer[j] = dataP[i]; i++;j++; } // Write longitude FileWrite (FileHandle, buffer, sizeof(char), StrLen(buffer), &err); FileWrite (FileHandle, "\n", sizeof(char), 1, &err); } */ FileWrite(FileHandle, dataP, objSize, numObj, &err); ErrFatalDisplayIf(err, "Problem writing file Sitzmark"); ReadFrFile(objSize); } static void ReadFrFile(Long objSize) { Err err; Long size; Char buffer[100]; FileRewind(FileHandle); // Return to the begining of the file size = FileRead(FileHandle, buffer, objSize, 100, &err); ErrFatalDisplayIf(MASK(err), "Problem reading file Sitzmark"); WinDrawChars(buffer, size, 5, 110); } // packet number. Initially set to 2 so that it doesn't conflict with // the usual initial packet #, 0 int packetNum = 2; static bool RequestData() { Err err = 0; ULong numBytes = 0; char s[10] = "\0"; Byte buffer[] = {0x23,packetNum,0x01,0x1C}; if (waitBetweenSends == 0) { //waitBetweenSends = POLLING; waitBetweenSends = 20; SerSend (serRefNum, buffer, 4, &err); // Adjust packet number for next packet packetNum++; if (packetNum==8) packetNum = 1; if (err) goto ERROR; SerSendWait (serRefNum, -1); // Wait until xmit buffer empty } waitBetweenSends--; PrintInt(waitBetweenSends, 5, 145); // Wait for ACK from EVB SerReceiveCheck(serRefNum, &numBytes); // PrintInt(numBytes, 5, 120); if (numBytes > 0) { SerReceive(serRefNum, serRcvQueue, 1, 0, &err); if (err) goto ERROR; // WinDrawChars(serRcvQueue, numBytes, 5, 130); // PrintInt (serRcvQueue[0], 5, 130); if (serRcvQueue[0] == FRAMINGBYTE) { // EVBDetected = true; return true; } } ERROR: if (err) { if (err == serErrLineErr) SerClearErr(serRefNum); // Reset the serial port } return false; } static void PrintInt (Long i, SWord x, SWord y) { Word j; Char s[20] = "\0"; StrIToA (s, i); for (j=0; s[j]!=0 && j<20; j++) ; WinDrawChars(s, j, x, y); } static void PalmSleep (UInt sec) { WinDrawChars( "SLEEP", 5, 5, 145 ); SysTaskDelay(sec*SysTicksPerSecond()); WinEraseChars("SLEEP", 5, 5, 145); WinDrawChars( "UP", 2, 5, 145 ); return; } static void RFConnect() { SerSettingsType settings; Err err; err = SysLibFind ("Serial Library", &serRefNum); ErrFatalDisplayIf(err, "Can't find Serial Library!"); if (err) SerClose(serRefNum); /* ** open the serial connection at the specified baud rate */ err = SerOpen(serRefNum, 0, BAUDRATE); ErrFatalDisplayIf(err, "Problem opening the serial port!"); if (err) { SerClose(serRefNum); serRefNum = 0; } settings.baudRate = BAUDRATE; settings.ctsTimeout = serDefaultCTSTimeout; settings.flags = serSettingsFlagStopBits1 | serSettingsFlagBitsPerChar8 | serSettingsFlagRTSAutoM; SerSetSettings(serRefNum, &settings); } static void RFDisconnect() { // Close connection if (serRefNum != 0) { SerClose(serRefNum); serRefNum = 0; } }