Search   
Home  Print View  

 

GP-LOGIC

Branch Content

Firmware Program Structure

Althogh the Firmware is different for every model, the program structure is basically the same. It comprises the following blocks:

* Initialization
* Main Loop
* Virtual Timers
* UART Interrupt Service Routines
* Command Interpreter
* Command Semantics

Initialization

After disabling interrupts, the initialization routine writes the alarm code ALM_INIT in memory and illuminates the ALARM LED signaling that Firmware initialization is taking place.

The initialization routine continues to configure on-chip resources and memory variables, including UART, on-chip timers and Virtual Timers.

As mentioned earlier in this manual, GPIO configuration is stored in FLASH as results of a SETUP GPIO serial command. Also in FLASH is a "setup bit" telling whether or not that command have been ever received. If that bit is set, the initialization routine configures GPIO ports as indicated in FLASH, putting all GPOs in no-activated status; otherwise, all GPIO ports are configured as inputs.

Before ending, the initialization routines writes the alarm code ALM_NONE. If the "setup bit" is clear, it also turns the ALARM LED off; otherwise, it let it on signaling that the unit has not been setup yet.

Initialization ends by enabling interrupts before falling into the Main Loop.

Main Loop

The main task of the Main Loop is to monitor and debounce GPI inputs. When a valid (stable) change is detected, the status of all GPIs is saved into memory variable GPI_STATUS as a bit-map. This variable will later be used by the Command Semantics routines to generate responses to GET STATUS query commands.

The Main Loop is structured as a Finite State Machine (FSM).

Being in state 1, it reads the GPIO ports masking the GPOs to obtain a bit-map of GPIs which is compared with a temporary variable GPI_TMP. This variable had previously been initialized as zero (no active GPIs). While no change is detected, the FSM remains in state 1.

As soon as GPIs reading mismatches GPI_TMP, the FSM starts a Debounce Timer and changes to state 2 in which it will remain indefinetly.

The timeout routine of the Debounce Timer will simply set the FSM state to 3. Being in this state, the FSM will read the GPIs port again and repeat the comparison. A match means that the now debounced input is statable, so GPI_TMP is copied to GPI_STATUS, and returns to initial state 1. A mismatch means that the reading is not stable; in this case, the Debounce Timer is started again and status is changed to 2 to give it another try.

The number of tries is limited, but that is not part of the FSM; instead, a counter is checked against a literal DEBOUNCE_TRIES_MAX.

Virtual Timers

A Virtual Timer consists of these parts:

* Memory variable T[i] representing a count down.
* Literal COUNT[i] to initialize T[i].
* Time-out routine.
* Enable flag.

There are two types of Virtual Timers:

* Free-Running:
  When T reaches zero, it is loaded again with COUNT so the count down restarts automatically.

* One-Time:
  When T reaches zero, the Enable flag is cleared automatically.

All Virtual Timers are initialized during the Initialization routine by copying COUNT[i] into T[i] and setting the enable flag to zero (disabled).

The interrupt service routine TMR_ISR of the on-chip real-timer decrements at once all Virtual Timers T's of those that happen to be enabled.

TMR_ISR also checks if T[i] equals zero, in which case it reloads the timer (T[i]=COUNT[i]), then call the TimeOut[i] routine. If it is of type One-Time, it clears the Enable bit of that Virtual Timer before calling TimeOut[i] so the Virtual Timer runs only once.

The TimeOut[i] routine implements the useful work. From the client code viewpoint, that routine takes the place that otherwise would occupy the Interrupt Service Routine of a real timer.

Client code activate or deactivate Virtual Timers at will by setting or clearing their Enable flags, respectively.

Online Manuals -- this software is based on Help Books running at melissa