It is perfectly reasonable to rewrite main(). I did it. I don't understand why IFI put in such a baroque superstructure in the FRC default code. The EDU code was cleaner.
You can replace *everything* that IFI gave you, except for their library. All I saved was the printf (modified slightly) and the main library with the rxget and txput routines since those are "hidden" in a library. The important thing to keep the same is how the IFI stuff is initialized and how you go about getting and putting the packet from the master CPU. Every thing else is fair game.
In short, my main looks like this:
Code:
void main (void)
{
#ifdef UNCHANGEABLE_DEFINITION_AREA
IFI_Initialization (); /* DO NOT CHANGE! */
#endif
User_Initialization(); /* You edit this in user_routines.c */
statusflag.NEW_SPI_DATA = 0; /* DO NOT CHANGE! */
while (1)
{
#ifdef _SIMULATOR
statusflag.NEW_SPI_DATA = 1;
#endif
if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */
{
Getdata(&rxdata);
ProcessPacket(); // User_routines.c
Putdata(&txdata); /* DO NOT DELETE, or you will get no PWM outputs! */
}
Process_Tasks(); // user_routines.c
} /* while (1) */
} /* END of Main */
and my user_code looks like this:
Code:
void ProcessPacket(void)
{
int c;
// Put common stuff here
CheckSwitches(); // Mass examine digital input for change
if (autonomous_mode)
{
User_Autonomous_Code();
}
else
{
User_Normal_Code();
}
pwm01 = DoPid(&Left, &LeftEncoder);
pwm02 = DoPid(&Right, &RightEncoder);
//---------- Inputs to Relays--------------------------------------------
relay8_fwd = !rc_dig_in18; /* Power pump only if pressure switch is off. */
relay8_rev = 0;
...
and finally, my "tasking code" which was more complicated, but now is pretty simple
Code:
void Process_Tasks(void)
{
static char GyroTimer = 0, PrintTimer = 0;
Poll_Rx1(); // The fast loop runs > 100khz
Poll_Tx1(); // Poll rather than interrupts
Poll_Rx2();
Poll_Tx2();
while (MsTimer) // Incremented by TimerInterrupt.
{
MsTimer--; // Section.
if (++GyroTimer == 10) // 100hz
{
GyroTimer = 0;
Gyro_Task();
} // END GyroTimer
if (++PrintTimer == 100) // 10hz
{
PrintTimer = 0;
TetherTask(STDIO);
} // END Print task
}// END Tasking
}
In short my "packet driver" code does common stuff up front (read sensors) the calls appropriate normal or autonomous code, then at the back end formats up stuff to send out.
Just pay attention to those lines with /* DO NOT CHANGE */ appended to them. Not all, but most are important.
Also, if you are interested in my tasking code, I put a zip called "sensors.zip" out on one of the programming forums (PID or Gyro, one of the two...)