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 = #
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.
The data protocol between the Palm controller and the hardware should be the following:
All the commands have the following format:
LH<data><cr> The bits have the following values:
Bits b2 - b0 specify the trigging condition Note: currently the value of this bit is ignored. Note: 'b' designates the 7-bit binary number.
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.
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.
the character designating the end of the
command.
Read the FPGA code
version number
Read the Analyzer
configuration
b0 - Analyzer Support
The rest of bits are defaulted to 0.
b1 - Pattern generator support
b2-b3 - number of channels (00 - 8, 01 - 16)
Read system error
Read status byte.
Reset the Analyzer
Start data acquisition
Set number of
channels.
Set acquisition
frequency.
<data> specifies the acquisition frequency in coded form (TBD).
Write the
Analyzer configuration string.
Read data stored in the
internal buffer