Week 5 Progress:

     I plan to do some more palm development and test sending and receive from the serial port.  I also want to take a more active role in connecting some of the hardware pieces together on the bread board.  Stay tuned to see some source code.

    We haven't received our development board or UART yet even though we ordered it almost two weeks ago.  I received an email the other day saying that our order has been delayed and will hopefully be shipped this coming week.  Because of this unfortunate mishap, we had to work around this.  Ilya was making schematics and designing the hardware further but you can only do so much without the parts.  He decided to help Ilya with the VHDL since he is more familiar with it.  Programming the Palm proved more challenging then I thought.  The user interfaces were easy because we have the constructor to help us generate the resource file.  The back end is harder because we have to get the palm to synchronize with the hardware.  I've implemented the serial manager by calling the SysLibFind, SerOpen, SerClose, and SerSend API function calls.  I couldn't get it to work yet.  But I did figure out how to download everything into the Palm itself.  The tutorial tells you that you need to change the palm mode using shortcut 2.  This is really confusing because this shortcut is not visible to the user.  After playing with the graffiti for awhile I got it to download.  Here are the present GUI's that I've downloaded to the palm.

    The second screen is where the user enters the triggering conditions.  We will initially just support 1,0, and don't care. These fields will eventually be replace by drop downs instead of manual entries.  The only thing I need to do now is to test the sending of the bits.  I've implement the serial manager and set it to a baud rate of 57600.  Here is my source code so far:

#include <Pilot.h> // all the system toolbox headers
#include <SerialMgr.h>
#include <PalmStdio.h>
#include <FeatureMgr.h>
#include "LogicRsc.h" // application resource defines

#define k2KBytes 2048
static Word CurrentView;
/***********************************************************************
* Prototypes for internal functions
**********************************************************************/
static void StartApplication(void);
static Boolean MainFormHandleEvent(EventPtr event);
static void EventLoop(void);
static FieldPtr GetFocusObjectPtr(void);
static Boolean ApplicationHandleEvent(EventPtr event);
static Boolean Result1FormHandleEvent(EventPtr event);
static Boolean Resul2FormHandleEvent(EventPtr event);
static Boolean WelcomeFormHandleEvent(EventPtr event);
/***********************************************************************
*
* FUNCTION: StartApplication
*
* DESCRIPTION: This routine sets up the initial state of the application.
*
* PARAMETERS: None.
*
* RETURNED: Nothing.
*
***********************************************************************/
static void StartApplication(void)
{
CurrentView = WelcomeForm;
/* FormPtr frm;

// Initialize and draw the main memo pad form.
frm = FrmInitForm(LogicMainForm); //MemoPadMainForm
FrmSetActiveForm(frm);
FrmDrawForm(frm);*/

}

static FieldPtr GetFocusObjectPtr (void)
{
FormPtr frm;
Word focus;

// get a pointer to tha active form and the index of the form object with focus
frm = FrmGetActiveForm ();
focus = FrmGetFocus (frm);

// if no object has the focus return NULL pointer
if (focus == noFocus)
return (NULL);

// return a pointer to the object with focus
return (FrmGetObjectPtr (frm, focus));
}

/***********************************************************************
*
* FUNCTION: MainFormHandleEvent
*
* DESCRIPTION: Handles processing of events for the “main” form.
*
* PARAMETERS: event - the most recent event.
*
* RETURNED: True if the event is handled, false otherwise.
*
***********************************************************************/
static Boolean MainFormHandleEvent(EventPtr event)
{
Boolean handled = false;
EventType newEvent;
char sendbits[16], *pointer;
unsigned short num, *ref;
short error, *perr;
pointer = &sendbits[0];
perr = &error;
ref = &num;
switch (event->eType)
{
case ctlSelectEvent:
if (event->data.ctlEnter.controlID == LogicMainExitButton)
{
MemSet(&newEvent, sizeof(EventType), 0);
newEvent.eType = appStopEvent;
EvtAddEventToQueue(&newEvent);
handled = true;
}
else if (event->data.ctlEnter.controlID == LogicMainBsendButton)
{
switch (LogicMainR0Field)
{
case '1':
sendbits[0] = '0';
sendbits[1] = '1';
break;
case '0':
sendbits[0] = '1';
sendbits[1] = '0';
break;
default:
sendbits[0] = '0';
sendbits[1] = '0';
break;
}
switch (LogicMainR1Field)
{
case '1':
sendbits[2] = '0';
sendbits[3] = '1';
break;
case '0':
sendbits[2] = '1';
sendbits[3] = '0';
break;
default:
sendbits[2] = '0';
sendbits[3] = '0';
break;
}
switch (LogicMainR2Field)
{
case '1':
sendbits[4] = '0';
sendbits[5] = '1';
break;
case '0':
sendbits[4] = '1';
sendbits[5] = '0';
break;
default:
sendbits[4] = '0';
sendbits[5] = '0';
break;
}
switch (LogicMainR3Field)
{
case '1':
sendbits[6] = '0';
sendbits[7] = '1';
break;
case '0':
sendbits[6] = '1';
sendbits[7] = '0';
break;
default:
sendbits[6] = '0';
sendbits[7] = '0';
break;
}
switch (LogicMainR4Field)
{
case '1':
sendbits[8] = '0';
sendbits[9] = '1';
break;
case '0':
sendbits[8] = '1';
sendbits[9] = '0';
break;
default:
sendbits[8] = '0';
sendbits[9] = '0';
break;
}
switch (LogicMainR5Field)
{
case '1':
sendbits[10] = '0';
sendbits[11] = '1';
break;
case '0':
sendbits[10] = '1';
sendbits[11] = '0';
break;
default:
sendbits[10] = '0';
sendbits[11] = '0';
break;
}
switch (LogicMainR6Field)
{
case '1':
sendbits[12] = '0';
sendbits[13] = '1';
break;
case '0':
sendbits[12] = '1';
sendbits[13] = '0';
break;
default:
sendbits[12] = '0';
sendbits[13] = '0';
break;
}
switch (LogicMainR7Field)
{
case '1':
sendbits[14] = '0';
sendbits[15] = '1';
break;
case '0':
sendbits[14] = '1';
sendbits[15] = '0';
break;
default:
sendbits[14] = '0';
sendbits[15] = '0';
break;
}
SysLibFind("Serial Library",ref);
SerOpen(num,0,57600);
SerSend(num,pointer,2,perr);
SerClose(num);
FrmGotoForm(Result1Form);
handled = true;
}
case frmOpenEvent: // P3. The form was told to open.
// It has already been loaded and activated so just draw it.
FrmDrawForm (FrmGetActiveForm());
handled = true;
break;
}
/* if (event->eType == ctlSelectEvent)
{
// A control button is pressed and released.
// The exit button being the only button, stop the application.

MemSet(&newEvent, sizeof(EventType), 0);
newEvent.eType = appStopEvent;
EvtAddEventToQueue(&newEvent);

handled = true;
}*/


return(handled);
}

/***********************************************************************
*
* FUNCTION: MainFormHandleEvent
*
* DESCRIPTION: Handles processing of events for the “main” form.
*
* PARAMETERS: event - the most recent event.
*
* RETURNED: True if the event is handled, false otherwise.
*
***********************************************************************/
static Boolean WelcomeFormHandleEvent(EventPtr event)
{
Boolean handled = false;
//EventType newEvent;


switch (event->eType)
{
case ctlSelectEvent:
if (event->data.ctlEnter.controlID == WelcomeWelcomeButton)
{
FrmGotoForm(LogicMainForm);
handled = true;
}
case frmOpenEvent: // P3. The form was told to open.
// It has already been loaded and activated so just draw it.
FrmDrawForm (FrmGetActiveForm());
handled = true;
break;
}
/* if (event->eType == ctlSelectEvent)
{
// A control button is pressed and released.
// The exit button being the only button, stop the application.

MemSet(&newEvent, sizeof(EventType), 0);
newEvent.eType = appStopEvent;
EvtAddEventToQueue(&newEvent);

handled = true;
}*/


return(handled);
}

static Boolean Result1FormHandleEvent(EventPtr event)
{
//FormPtr frm;
Boolean handled = false;

switch (event->eType)
{
case ctlSelectEvent: // A control button was pressed and released.

// If the done button is pressed, go back to the main form.
if (event->data.ctlEnter.controlID == Result1OkButton)
{
FrmGotoForm(LogicMainForm);
handled = true;
}

else if (event->data.ctlEnter.controlID == Result1BnextButton)
{
FrmGotoForm(Result2Form);
handled = true;
}
case frmOpenEvent: // P3. The form was told to open.
// It has already been loaded and activated so just draw it.
FrmDrawForm (FrmGetActiveForm());
handled = true;
break;
}
/* case frmOpenEvent: // The form was told to open.
// It has already been loaded and activated so just draw it.
frm = FrmGetActiveForm();
FrmDrawForm (frm);

// P4. set the focus, and the insertion point, to the text edit field
FrmSetFocus(frm, FrmGetObjectIndex(frm, MemoPadEditEditFieldField));
handled = true;
break;

case menuEvent: // P4. A menu item was selected.
// First clear the menu status from the display.
MenuEraseStatus(0);

// process menu commands for the edit form
EditDoMenuCommand(event->data.menu.itemID);
handled = true;
break;
}*/

return(handled);
}


static Boolean Resul2FormHandleEvent(EventPtr event)
{
//FormPtr frm;
Boolean handled = false;

switch (event->eType)
{
case ctlSelectEvent: // A control button was pressed and released.

// If the done button is pressed, go back to the main form.
if (event->data.ctlEnter.controlID == Result2OkButton)
{
FrmGotoForm(LogicMainForm);
handled = true;
}

else if (event->data.ctlEnter.controlID == Result2BprevButton)
{
FrmGotoForm(Result1Form);
handled = true;
}
case frmOpenEvent: // P3. The form was told to open.
// It has already been loaded and activated so just draw it.
FrmDrawForm (FrmGetActiveForm());
handled = true;
break;
}
/* case frmOpenEvent: // The form was told to open.
// It has already been loaded and activated so just draw it.
frm = FrmGetActiveForm();
FrmDrawForm (frm);

// P4. set the focus, and the insertion point, to the text edit field
FrmSetFocus(frm, FrmGetObjectIndex(frm, MemoPadEditEditFieldField));
handled = true;
break;

case menuEvent: // P4. A menu item was selected.
// First clear the menu status from the display.
MenuEraseStatus(0);

// process menu commands for the edit form
EditDoMenuCommand(event->data.menu.itemID);
handled = true;
break;
}*/
return(handled);
}


static Boolean ApplicationHandleEvent (EventPtr event)
{
FormPtr frm;
Word formId;
Boolean handled = false;

if (event->eType == frmLoadEvent)
{
// load the form resource specified in the event then activate the form.
formId = event->data.frmLoad.formID;
frm = FrmInitForm(formId);
FrmSetActiveForm(frm);

// set the event handler for the form. The handler of the currently 
// active form is called by FrmDispatchEvent each time it receives an event.
switch (formId)
{
case WelcomeForm:
FrmSetEventHandler(frm, WelcomeFormHandleEvent);
break;
case LogicMainForm:
FrmSetEventHandler(frm, MainFormHandleEvent);
break;

case Result1Form:
FrmSetEventHandler(frm, Result1FormHandleEvent);
break;
case Result2Form:
FrmSetEventHandler(frm, Resul2FormHandleEvent);
break;
}
handled = true;
}

return handled;
}


/***********************************************************************
*
* FUNCTION: EventLoop
*
* DESCRIPTION: A simple loop that obtains events from the Event
* Manager and passes them on to various applications and
* system event handlers before passing them on to
* FrmHandleEvent for default processing.
*
* PARAMETERS: None.
*
* RETURNED: Nothing.
*
***********************************************************************/
static void EventLoop(void)
{
EventType event;

do
{
// Get the next available event.
EvtGetEvent(&event, evtWaitForever);

// Give the system a chance to handle the event.
if (! SysHandleEvent (&event))

// Give the application a chance to handle the event.
if (! ApplicationHandleEvent(&event))

// Let the form object provide default handling of the event.
FrmDispatchEvent(&event);
//FrmHandleEvent(FrmGetActiveForm(), &event);

while (event.eType != appStopEvent);
// ** SPECIAL NOTE **
// In order for the Emulator to exit
// cleanly when the File|Quit menu option is
// selected, the running application
// must exit. The emulator will generate an 
// “appStopEvent” when Quit is selected.
}


/***********************************************************************
*
* FUNCTION: PilotMain
*
* DESCRIPTION: This function is the equivalent of a main() function
* in standard “C”. It is called by the Emulator to begin
* execution of this application.
*
* PARAMETERS: cmd - command specifying how to launch the application.
* cmdPBP - parameter block for the command.
* launchFlags - flags used to configure the launch. 
*
* RETURNED: Any applicable error code.
*
***********************************************************************/
DWord PilotMain(Word cmd, Ptr cmdPBP, Word launchFlags)
{
// Check for a normal launch.
if (cmd == sysAppLaunchCmdNormalLaunch)
{
// Set up initial form.
StartApplication();
FrmGotoForm(CurrentView);
//println("\n This is cool");
// Start up the event loop.
EventLoop();
}

return(0);
}

I will test sending the bits first and then receiving later.  Here is the protocol we are going to follow.  Note that this may change later.

Protocol Description

    The data protocol between the Palm controller and the hardware should be the following:

    All the commands have the following format:

LH<data><cr>

 
where:
L  
represents the hex-ASCII Command Class letter. One of the letters specified inthe table below. Every command has to start from this latter. 
represents the 8-bit hex Command Suffix identifying the meter data or features to which the command is directed. 
 
<data> 
is the string of characters containing the variable information the Palm is sending to the Analyzer. These data (whether BCD or binary) are encoded into hex-ASCII characters, two characters to the byte. Square brackets (indicating optional status) enclose this string, since some commands contain no data.
 
<cr> 
the character designating the end of the command.

 
 
 
Command
Description
Response
S01
 Read the FPGA code version number
b.b<cr>
S02
 Read the Analyzer configuration
b<cr>

The bits have the following values: 

b0 - Analyzer Support 
b1 - Pattern generator support 
b2-b3 - number of channels (00 - 8, 01 - 16)
The rest of bits are defaulted to 0.
S03
 Read system error
B<cr>
S04
 Read status byte.
B<cr>
C01
 Reset the Analyzer 
-
C02
 Start data acquisition
-
C03
Set number of channels. <data> specifies the number of channels in 7-bit format:
-
B3 - b0
# of Channels
0000
1
0001
2
0010
4
0100
8
1000
16
C04
 Set acquisition frequency.
<data> specifies the acquisition frequency in coded form (TBD).
-
W01
Write the Analyzer configuration string. <data> specifies the configuration for each acquisition channel starting from channel 0 up to the maximum channel number (depends on the C03 command). Channel specification is done in the following form:

Bits b2 - b0 specify the trigging condition

-
Bits b2 - b0
Condition
000
Don't care
001
High Level
010
Low Level
011
Rising Edge
100
Falling Edge
101
Any Edge
Bit b3 is a flag that indicate whether some timing information will be added to specify the trigging condition. If b3=1, the word that follows this one specifies time.

Note: currently the value of this bit is ignored.

R01
Read data stored in the internal buffer
b…b<cr>
The data is send back as a sequence of bits specifying the values on each channel starting from 0 up to the last channel.

Note: 'b' designates the 7-bit binary number.