RC bootup sequence

I have another question to the wizards and programmers here,

When the EDU-RC’s user programmable pic is powered up, i can see that it jumps to a reset vector (defined in ifi_startup.c). Then, IFI_Startup.c is processed. After that, I seem to understand that main.c begins processing, and the master loop begins. (Am i correct so far?)

If i remove IFI_utilities.c, will anything happen to this procedure?

What purpose is printf_lib.c serving? Can it be removed?

What if I make just one file (rc.c) and have the initialization code and main loop and user code all in that file? And then combine all the header files into one file. Will the code work at all, or will chaos reign supreme?

(sorry for the long post)
:]

IFI_Utilities.c has a collection of procdures to use in custom programming. I’m pretty sure they aren’t used in the startup (I haven’t went through those files thoroughly yet).

printf_lib.c is a port of the printf function for the PIC controller. You can use it to output feedback such as loop counters/errors/flags. It is used in the main loop I think as an output for errors.

I’m not sure why you’d want to combine them into one file, but I don’t THINK there would be a problem as long as you copy the files EXACTLY and fix the include statements. Again, I haven’t went through these files thoroughly…

My recommendation is to leave them seperated since they’re in a project file for the IDE we have to use anyhow (atleast the IDE we have to use right now…there may be more available later…).

I think it is very important for us to understand how powerful the ability to program the RC in C is. The C language provides us with a way to break the code down into small bite sized chunks that can be easily distributed among many developers as well as make understanding the code much easier.

Header files (.h) should be considered like contracts or interface agreements with other programmers. I can break my code down into small segments and have Bob go off and develop the main loop while Jill creates a library of functions for accessing sensors. Jill and Bob will get together and decide on the outline of functions that will be made available and Jill will create a header file containing the agreed upon declarations of these functions. Bob can take this header file and go off and us the function prototypes to work out the logic of his main loop. Bob can even test compile his code all without ever having the actual implementation of the sensor library. Meanwhile Jill can create the implementation of the sensor library functions in her C file (.c). To make things even better Jill might provide Bob with an implementation of the sensor library with all of the functions stubbed out to only print a debug message or just return without doing anything so that Bob can compile and run this main loop to test logic etc. Then as Jill finishes the implementation details of the sensor library she can provide Bob with beta versions of the sensor library to test.

Splitting the code up can also make it much easier to debug a problem. If you logically break the code down into functional areas then you know exactly where to look in the code to find the problem as opposed to looking through one big file full of code.

I hope you can begin to see how much better this splitting up of the code into small chunks can make design/development/debug go.

I can also see a situation where someone might develop a library much like the ifi provided ifi_library.lib to provide (stick with me here) communications between 2 robots during autonomous mode via a sensor. That someone might not want to give away the source code but could provide the library and a header file to alliance partners to include in their code. Someone might also write a complete generic autonomous mode library and provide it to anyone who might want it. Makes for all kinds of interesting possibilities!

Hope this helps:D

I’d like to have a way to mark real time, especially useful in autonomous mode. I guess the timing enforced by the data exchange with the master processor is a pretty good timer, but pretty low resolution. I started wondering about using the timers on the PIC and started playing with timer1. My test worked fine in the IDE simulator so I downloaded it to the EDU-RC. BAD IDEA! This program broke the RC bad enough that I could no longer get it into download mode to fix it - a bit of a stuck spot. After a while I found a way out.

===> Here’s the tip: if pressing the program button doesn’t get the orange led to turn on (in my case it flashed red instead), turn off the RC, hold down the program button, and turn it back on. This appears to get it into download mode before the bad code wrecks everything.

So, having passed that jewel along, has anyone figured out a safe way to use any of the timers as a RTC?

Bill

*Originally posted by WizardOfAz *

So, having passed that jewel along, has anyone figured out a safe way to use any of the timers as a RTC?

Bill

I’m pretty sure that IFI has snagged all the timers in the high priority interrupt and isn’t going to give us access to them.

There is a routine in user_routines_fast.c which supposedly executes every program cycle. I think this is a timed loop and will give you cycle times faster than the 17ms data update. I was going to run a test to determine that last night but I ran outta steam.

The other way to consider doing this is to use the low priority interrupt to which you have access. You can wire up an oscillator/timer circuit and feed a timer signal to one of the six external interrupt pins.

The third option is to do an old DOS trick and to snag the high priority interrupt vector. You can insert your interrupt vector in place of the existing one. At the end of your ISR, you can call the IFI interrupt vector.

I personally do not plan to use this trick, as the other two methods should provide more reliable results. I suspect that the IFI supplied “every program cycle” function will be sufficient for most purposes.

I don’t think you can get any timing information by using user_routines_fast. If you look at the bottom of main.c, you see how this is used, and it doesn’t help with knowing how much time has passed.

Here’s what you see in main.c (slightly edited for clarity):

while (1)
{
if (statusflag.NEW_SPI_DATA) /* 17ms loop area /
{ /
I’m slow! I only execute every 17ms because /
/
that’s how fast the Master uP gives me data. /
Process_Data_From_Master_uP(); /
in user_routines.c */
}

/* I'm fast!  I execute during every loop.*/
Process_Data_From_Local_IO();     

}

The Process_Data_From_Master_uP function is called whenever there is new data available from the Master uP, every 17ms in the EDU-RC and every 26 ms in the big RC. The other one (Process_Data_From_Local_IO) is called every time around the loop. How often this will happen depends on how much is being done in that function, and will also (every 17 or 26 ms) be delayed a different amount while Process_Data_From_Master_uP runs. The main reason they’ve provided this is in case you want to handle local I/O (pwm and digital I/O that’s on the robot, not on the OI) faster than you do the OI I/O.

In other words, yes you will get cycle times much faster than 17 or 26 ms in Process_Data_From_Local_IO, but how much faster is not controlled by anything you can depend on.

Driving an oscillator into the interrupt is a workable idea, I was just hoping that with 6 on-chip timers there would be one that we could use.

Does IFI want to weigh in on this?

It is my understanding (99% confident) that the SPI code that tranmits/receives data between the master CPU and the user CPU does NOT use up any of the timers.

FYI.

Joe J.

*Originally posted by Joe Johnson *
It is my understanding (99% confident) that the SPI code that tranmits/receives data between the master CPU and the user CPU does NOT use up any of the timers.

ifi_picdefs.h seems to support this. None of the timer registers are listed as “do not use”.

*Originally posted by WizardOfAz *
**I don’t think you can get any timing information by using user_routines_fast. If you look at the bottom of main.c, you see how this is used, and it doesn’t help with knowing how much time has passed.

The other one (Process_Data_From_Local_IO) is called every time around the loop. How often this will happen depends on how much is being done in that function, and will also (every 17 or 26 ms) be delayed a different amount while **

You’re right. I didn’t have the code in front of me. I was hoping when they said “every program cycle” that they were using strict terminology. However, that was too good to be true.

Another thought, if IFI has not snagged all timers, you could use one in a low-priority interrupt routine.

Based on page 10-5 of the “PICmicro 18C Reference Manual” timers 0,1, 2, and 3, tie into the low priority interrupt logic.

It should be straightforward to poll the timer registers and see if they’re in use. Or look at INTCON and IPR registers to see if a high priority interrupt is located on one. If a timer is not in use, you should be able to use it to fire the low priority interrupt and run your timed cycle.

The good side of doing it this way is that low priority interrupt over-runs should not cause a crash in communications between your chip and the master uP.

Another way to do what you want would be to read a timer at the end of the main loop (assuming a timer is set in free-running mode). You can run your loop. Then, at the end of the loop you can poll the timer until it reaches your sample time. This is a clumsy way of doing things. However, if all four timers are in use (and I think at least three will be), this may be your only on chip option.

*Originally posted by Dave Flowerday *
**ifi_picdefs.h seems to support this. None of the timer registers are listed as “do not use”. **

In INTCON2bits, the TMR0IP is listed as “reserved.”

All of the IPRlbits are “reserved” which potentially takes out TMR1 and TMR2.

IPR2bits contain TMR3IP and the whole byte is listed as “reserved.” This would knock out TMR3.

However, I would actually read the bits on the actual values. I think IFI just didn’t want us mucking with any of these registers since they affect the priority of other, critical interrupts.

I suppose it’s possible that the way I set the timer up caused the problem even though the timer may not have been in use. Perhaps it started generating interrupts for which there was no code to handle. Or something.

Here’s what I tried. It was just an experiment to try to learn how to use the timers.

unsigned int t1, t2;
OpenTimer1(TIMER_INT_OFF&T1_16BIT_RW&T1_SOURCE_INT&T1_PS_1_8);

while (1) /* this is the main loop in main.c */
{
t1 = ReadTimer1();
if(t1&0xf000 != t2) {
t2 = t1&0xf000;
printf("timer1: %u
", t1);
}

}

This ran OK in the simulator, and ran OK in the EDU-RC when I first loaded it, but after that, I could no longer put the EDU-RC in program download mode. See earlier post.

Anybody tried and succeeded in using the timers and want to give advice?

That’s a good suggestion, don’t set up the timers, just try reading them to see if one is already running in a usable mode. My thought was to mask off most of the lower order bits to get ticks at a managable speed, then use a change in the remaining bits to increment a static counter that wouldn’t overflow (or at least not too often). Ultimately, knowing how much time has passed since some particular event (like start of autonomous mode) is the goal, and that should accomplish it.

Thanks, Bill

*Originally posted by Andrew *
**
Based on page 10-5 of the “PICmicro 18C Reference Manual” timers 0,1, 2, and 3, tie into the low priority interrupt logic.
**

“18C reference manual” I really hope you mean the C18 reference manual. The interrupt timer priorities are configurable to be either high or low by changing bits of the IPR1, IPR2, and IPR4 registers. O, and don’t forget TMR4.

*Originally posted by Rickertsen2 *
**“18C reference manual” I really hope you mean the C18 reference manual. The interrupt timer priorities are configurable to be either high or low by changing bits of the IPR1, IPR2, and IPR4 registers. O, and don’t forget TMR4. **

I’m talking about the hardware manual, not the compiler manual. It’s available from Microchip.

*Originally posted by Andrew *
**I’m talking about the hardware manual, not the compiler manual. It’s available from Microchip. **

U need the “PIC18FXX20 Data Sheet” The 18C series is an entirely different series of chips from the 18F series.

Innovation First would like to clear a few things up:

  1. All five timers are available to the user.
  2. You may use any of the timer interrupts, but only at low priority.
  3. The user may use NO high priority interrupts anywhere in their code.

The problem that WizardOfAz ran into is addressed by this FAQ:
http://www.innovationfirst.com/firstrobotics/faq/?Action=Q&ID=73

We will be releasing a white paper shortly on how to use the timers, both by polling and by using interrupts. This will be available at http://www.innovationfirst.com/firstrobotics/white_papers.htm

Best regards,
The Firmware Team
Innovation First, Inc.

SWEET! all five are available! I can go work on my code now.

*Originally posted by Venkatesh *
When the EDU-RC’s user programmable pic is powered up, i can see that it jumps to a reset vector (defined in ifi_startup.c). Then, IFI_Startup.c is processed. After that, I seem to understand that main.c begins processing, and the master loop begins. (Am i correct so far?)
Yes.
If i remove IFI_utilities.c, will anything happen to this procedure?
Yes.

What purpose is printf_lib.c serving? Can it be removed?
printf_lib.c provides support for the printf() function, which many C programmers are familiar with (and love!). This is used for sending debugging information over the RS232 port to a computer. Yes it can be removed, as long as you also remove all the calls to printf() and have no desire to print.
What if I make just one file (rc.c) and have the initialization code and main loop and user code all in that file? And then combine all the header files into one file. Will the code work at all, or will chaos reign supreme?
Yes is should work fine, assuming you do not modify or move any of the preprocessor directives (such as the #pragma’s)