This is post #3 in a series covering the hardware and software design for my work-in-progress GPS-guided rocket recovery project. The main index to the series of posts is here, and an introduction to the project (a PowerPoint presentation) is here.

This post is an introduction to the source code. (Which can be downloaded from my last post.)

OVERVIEW OF SOURCE FILES

The software consists of the following C source files:

  • main.c – hardware init and main program loop
  • stateMachine.c – finite state machine (most functionality is here)
  • globals.c – global variables
  • isr.c – interrupt service routine
  • hardware.c – hardware abstraction wrappers
  • peripherals.c – higher-level (than hardware.c) peripheral control
  • nmeaGps.c – reads and parses NMEA-0183 standard format GPS data
  • logging.c – logging of flight status data to Flash memory
  • compass.c – drives Honeywell HM55B magnetic compass (no longer used)

and the following header files:

  • tweaks.h – main “tweakable” parameter file and compilation switches
  • stateMachine.h – defines state values and prototypes for stateMachine.c
  • globals.h – prototypes for globals.c, generally useful macros
  • hardware.h – symbol definitions for hardware abstractions, prototypes for hardware.c
  • peripherals.h – peripheral-related macros and constants, prototypes for peripherals.c
  • nmeaGps.h – data structure for GPS fixes, prototypes for nmeaGps.c and related constants
  • logging.h – data structures for flight data logging, prototypes for logging.c
  • compass.h – hardware abstractions for compass, prototypes for compass.c
  • debug.h – macros to support “Z-80 Speedometer”
  • djllib.h – variable type definitions, standard constants, misc. macros

In addition there is the Microchip header file pic18f26k20.h and the linker file 18f2620i.lkr. Neither of these are my work – they are unmodified from Microchip.

Servo arrangement after successful radio-controlled landing. To fit in the rocket, the servo arm stays at an extreme setting until after parachute deployment.

SYMBOL NAMING CONVENTIONS

These are the naming conventions I use for function and variable names:

Function scope Variable scope Convention 1st character
n/a Block (local) lower_case_ABBR_excepted_underscore_delimited Lowercase
File (normal) File mixedCaseDelimitedABBRexcepted Lowercase
Global (exported) Global MixedCaseDelimitedABBRexcepted Uppercase
Macro Macro ALL_CAPS_UNDERSCORE_DELIMITED Uppercase
n/a Typedef ALL_CAPS_UNDERSCORE_DELIMITED Uppercase

Also, a name with a leading underscore, for example _name(), indicates a “hidden” function or variable which is not meant for general use. Usually it’s a component of some other function that is meant to be used on a normal basis. (See __waitloop_internal() in hardware.c and #define wait() in hardware.h for an example.)

WHERE TO START

If you want to have a look at the software with an eye to modifying it, I suggest you start with a quick skim of the following files (in this order):

  • tweaks.h
  • main.c
  • stateMachine.c
  • isr.c

One you have a sense of what those are doing, the rest will start to make sense. That’s the order in which I’ll cover them here.

TWEAKS.H

As mentioned earlier, this file contains most (perhaps all) of the conditional compilation switches and “tweakable” parameters for compilation.

Note that FLASH_BASE is the address where flight log data will be stored in Flash memory. This needs to be above the last address used by the program to avoid overwriting the program. Look in the “Program Memory Usage” section of the .MAP file produced by the compiler to find the last address used. In the posted version it’s 0x730a, and FLASH_BASE is above that at 0x7800.

FLASH_SIZE is the size of the storage area for logging data. As mentioned in the comments, it needs to be a power of 2.

FOSC is the CPU clock frequency (in Hz). It must be one of the rates supported by the PIC hardware.

The RTC interrupt interval is 1 millisecond (1000 Hz). I’ll discuss this more under the ISR.

There are a bunch of time periods (or intervals) defined, always in terms of RTC ticks (currently 1 ms), but calculated from seconds and milliseconds at compile time using macros. This way if you change the RTC interrupt rate you don’t have to modify all these values by hand.

My next post will walk you thru main.c.