Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rit.c Source File

rit.c

00001 /****************************************************************************
00002  *    Copyright 2010 Andy Kirkham, Stellar Technologies Ltd
00003  *    
00004  *    This file is part of the Satellite Observers Workbench (SOWB).
00005  *
00006  *    SOWB is free software: you can redistribute it and/or modify
00007  *    it under the terms of the GNU General Public License as published by
00008  *    the Free Software Foundation, either version 3 of the License, or
00009  *    (at your option) any later version.
00010  *
00011  *    SOWB is distributed in the hope that it will be useful,
00012  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *    GNU General Public License for more details.
00015  *
00016  *    You should have received a copy of the GNU General Public License
00017  *    along with SOWB.  If not, see <http://www.gnu.org/licenses/>.
00018  *
00019  *    $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $
00020  *    
00021  ***************************************************************************/
00022  
00023 #include "sowb.h"
00024 #include "debug.h"
00025 #include "rit.h"
00026 #include "gps.h"
00027 #include "gpio.h"
00028 
00029 volatile uint32_t uptimeL;
00030 volatile uint32_t uptimeH;
00031 
00032 /* Declare "timer at zero" callback function prototypes. */
00033 void _gps_timer_tick_cb(int);
00034 void _user_wait_ms_cb(int);
00035 void _nexstar_timeout_callback(int);
00036 void _nexstar_one_second_timer(int index);
00037 void _nexstar_100th_timer(int index);
00038 void _flash_write_timer_callback(int index);
00039 void _main_test_callback(int index);
00040 void _sdcard_timer_callback(int index);
00041 
00042 /* Define an array of timers that the ISR should handle. */
00043 volatile RIT_TIMER timers[] = {
00044     { 10, 10, _gps_timer_tick_cb            },      /* Index 0 */
00045     {  0,  0, _user_wait_ms_cb              },      /* Index 1 */
00046     {  0,  0, _nexstar_timeout_callback     },      /* Index 2 */
00047     {  0,  0, _nexstar_one_second_timer     },      /* Index 3 */
00048     {  0,  0, _nexstar_100th_timer          },      /* Index 4 */
00049     {  0,  0, _flash_write_timer_callback   },      /* Index 5 */
00050     {  0,  0, _sdcard_timer_callback        },      /* Index 6 */
00051     {  0,  0, _main_test_callback           },      /* Index 7 */
00052     {  0,  0, NULL                          }       /* Always the last entry. */
00053 };
00054 
00055 /** RIT_IRQHandler
00056  *
00057  * The ISR for the RIT.
00058  */
00059 extern "C" static void RIT_IRQHandler(void) __irq {
00060     if (++uptimeL == 0) uptimeH++;
00061     for (int index = 0; timers[index].callback != NULL; index++) {
00062         if (timers[index].counter > 0) {
00063             timers[index].counter--;
00064             if (timers[index].counter == 0) {
00065                 (timers[index].callback)(index);
00066                 if (timers[index].reload > 0) {
00067                     timers[index].counter = timers[index].reload;
00068                 }
00069             }
00070         }
00071     }
00072     LPC_RIT->RICTRL |= 0x1; /* Dismiss the IRQ. */
00073 }
00074 
00075 /** rit_index_check
00076  *
00077  * Check that an index exists. Ensures that index into array is valid.
00078  *
00079  * @param int inex The index to check.
00080  * @return int zero on non-existent index, non-zero otherwise.
00081  */
00082 inline static bool rit_index_check(int index) {
00083     for (int i = 0; timers[i].callback != NULL; i++) if (i == index) return true;
00084     return false;
00085 }
00086 
00087 /** rit_timer_set_counter
00088  */
00089 void rit_timer_set_counter(int index, uint32_t value) {
00090     if (rit_index_check(index)) timers[index].counter = value;
00091 }
00092 
00093 /** rit_timer_set_reload
00094  */
00095 void rit_timer_set_reload(int index, uint32_t value) {
00096     if (rit_index_check(index)) timers[index].reload = value;
00097 }
00098 
00099 /** rit_timer_get_values
00100  *
00101  * Get the current counter/reload values of the specified timer.
00102  *
00103  * If the supplied "index" value is out of range the index value pointed to by
00104  * the caller is set to -1 to signify an error has occured (subscript/index out
00105  * of range).
00106  *
00107  * @param int * index A pointer to an int for the index value of the array to return.
00108  * @param uint32_t * counter A pointer to variable to place the counter value into.
00109  * @param uint32_t * counter A pointer to variable to place the reload value into.
00110  */
00111 void rit_timer_get_values(int *index, uint32_t *counter, uint32_t *reload) {
00112     if (rit_index_check(*(index))) {
00113         *(counter) = timers[*(index)].counter;
00114         *(reload)  = timers[*(index)].reload;
00115     }
00116     else *(index) = -1;
00117 }
00118 
00119 /** rit_get_uptime
00120  */
00121 void rit_read_uptime(uint32_t *h, uint32_t *l) {
00122     *(l) = uptimeL;
00123     *(h) = uptimeH;
00124 }
00125 
00126 /** rit_init
00127  */
00128 void rit_init(void) {
00129     
00130     DEBUG_INIT_START;
00131     
00132     uptimeL = uptimeH = 0;
00133     
00134     /* Start by switching power on to the peripheral */
00135     LPC_SC->PCONP |= (1UL << 16); 
00136     
00137     /* The compare value depends on the PCLK frequency.
00138        The following are based on a CCLK of 96Mhz to
00139        achieve a 1ms timeout value. */
00140     switch ((LPC_SC->PCLKSEL1 >> 26) & 0x3) {
00141         case 0: LPC_RIT->RICOMPVAL = (96000000L / 4 / 1000); break; /* CCLK / 4 */
00142         case 1: LPC_RIT->RICOMPVAL = (96000000L / 1 / 1000); break; /* CCLK / 1 */
00143         case 2: LPC_RIT->RICOMPVAL = (96000000L / 2 / 1000); break; /* CCLK / 2 */
00144         case 3: LPC_RIT->RICOMPVAL = (96000000L / 8 / 1000); break; /* CCLK / 8 */
00145     }
00146     
00147     /* Set the ISR vector and enable interrupts for the RIT. */
00148     NVIC_SetVector(RIT_IRQn, (uint32_t)RIT_IRQHandler);
00149     NVIC_EnableIRQ(RIT_IRQn);
00150     
00151     /* Enable the RIT. */
00152     LPC_RIT->RICTRL     = 0x0000000A;
00153     
00154     DEBUG_INIT_END;
00155 }