Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
rit/rit.c@0:0a841b89d614, 2010-10-11 (annotated)
- Committer:
- AjK
- Date:
- Mon Oct 11 10:34:55 2010 +0000
- Revision:
- 0:0a841b89d614
Totally Alpha quality as this project isn\t completed. Just publishing it as it answers many questions asked in the forums
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AjK | 0:0a841b89d614 | 1 | /**************************************************************************** |
AjK | 0:0a841b89d614 | 2 | * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd |
AjK | 0:0a841b89d614 | 3 | * |
AjK | 0:0a841b89d614 | 4 | * This file is part of the Satellite Observers Workbench (SOWB). |
AjK | 0:0a841b89d614 | 5 | * |
AjK | 0:0a841b89d614 | 6 | * SOWB is free software: you can redistribute it and/or modify |
AjK | 0:0a841b89d614 | 7 | * it under the terms of the GNU General Public License as published by |
AjK | 0:0a841b89d614 | 8 | * the Free Software Foundation, either version 3 of the License, or |
AjK | 0:0a841b89d614 | 9 | * (at your option) any later version. |
AjK | 0:0a841b89d614 | 10 | * |
AjK | 0:0a841b89d614 | 11 | * SOWB is distributed in the hope that it will be useful, |
AjK | 0:0a841b89d614 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
AjK | 0:0a841b89d614 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
AjK | 0:0a841b89d614 | 14 | * GNU General Public License for more details. |
AjK | 0:0a841b89d614 | 15 | * |
AjK | 0:0a841b89d614 | 16 | * You should have received a copy of the GNU General Public License |
AjK | 0:0a841b89d614 | 17 | * along with SOWB. If not, see <http://www.gnu.org/licenses/>. |
AjK | 0:0a841b89d614 | 18 | * |
AjK | 0:0a841b89d614 | 19 | * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $ |
AjK | 0:0a841b89d614 | 20 | * |
AjK | 0:0a841b89d614 | 21 | ***************************************************************************/ |
AjK | 0:0a841b89d614 | 22 | |
AjK | 0:0a841b89d614 | 23 | #include "sowb.h" |
AjK | 0:0a841b89d614 | 24 | #include "debug.h" |
AjK | 0:0a841b89d614 | 25 | #include "rit.h" |
AjK | 0:0a841b89d614 | 26 | #include "gps.h" |
AjK | 0:0a841b89d614 | 27 | #include "gpio.h" |
AjK | 0:0a841b89d614 | 28 | |
AjK | 0:0a841b89d614 | 29 | volatile uint32_t uptimeL; |
AjK | 0:0a841b89d614 | 30 | volatile uint32_t uptimeH; |
AjK | 0:0a841b89d614 | 31 | |
AjK | 0:0a841b89d614 | 32 | /* Declare "timer at zero" callback function prototypes. */ |
AjK | 0:0a841b89d614 | 33 | void _gps_timer_tick_cb(int); |
AjK | 0:0a841b89d614 | 34 | void _user_wait_ms_cb(int); |
AjK | 0:0a841b89d614 | 35 | void _nexstar_timeout_callback(int); |
AjK | 0:0a841b89d614 | 36 | void _nexstar_one_second_timer(int index); |
AjK | 0:0a841b89d614 | 37 | void _nexstar_100th_timer(int index); |
AjK | 0:0a841b89d614 | 38 | void _flash_write_timer_callback(int index); |
AjK | 0:0a841b89d614 | 39 | void _main_test_callback(int index); |
AjK | 0:0a841b89d614 | 40 | void _sdcard_timer_callback(int index); |
AjK | 0:0a841b89d614 | 41 | |
AjK | 0:0a841b89d614 | 42 | /* Define an array of timers that the ISR should handle. */ |
AjK | 0:0a841b89d614 | 43 | volatile RIT_TIMER timers[] = { |
AjK | 0:0a841b89d614 | 44 | { 10, 10, _gps_timer_tick_cb }, /* Index 0 */ |
AjK | 0:0a841b89d614 | 45 | { 0, 0, _user_wait_ms_cb }, /* Index 1 */ |
AjK | 0:0a841b89d614 | 46 | { 0, 0, _nexstar_timeout_callback }, /* Index 2 */ |
AjK | 0:0a841b89d614 | 47 | { 0, 0, _nexstar_one_second_timer }, /* Index 3 */ |
AjK | 0:0a841b89d614 | 48 | { 0, 0, _nexstar_100th_timer }, /* Index 4 */ |
AjK | 0:0a841b89d614 | 49 | { 0, 0, _flash_write_timer_callback }, /* Index 5 */ |
AjK | 0:0a841b89d614 | 50 | { 0, 0, _sdcard_timer_callback }, /* Index 6 */ |
AjK | 0:0a841b89d614 | 51 | { 0, 0, _main_test_callback }, /* Index 7 */ |
AjK | 0:0a841b89d614 | 52 | { 0, 0, NULL } /* Always the last entry. */ |
AjK | 0:0a841b89d614 | 53 | }; |
AjK | 0:0a841b89d614 | 54 | |
AjK | 0:0a841b89d614 | 55 | /** RIT_IRQHandler |
AjK | 0:0a841b89d614 | 56 | * |
AjK | 0:0a841b89d614 | 57 | * The ISR for the RIT. |
AjK | 0:0a841b89d614 | 58 | */ |
AjK | 0:0a841b89d614 | 59 | extern "C" static void RIT_IRQHandler(void) __irq { |
AjK | 0:0a841b89d614 | 60 | if (++uptimeL == 0) uptimeH++; |
AjK | 0:0a841b89d614 | 61 | for (int index = 0; timers[index].callback != NULL; index++) { |
AjK | 0:0a841b89d614 | 62 | if (timers[index].counter > 0) { |
AjK | 0:0a841b89d614 | 63 | timers[index].counter--; |
AjK | 0:0a841b89d614 | 64 | if (timers[index].counter == 0) { |
AjK | 0:0a841b89d614 | 65 | (timers[index].callback)(index); |
AjK | 0:0a841b89d614 | 66 | if (timers[index].reload > 0) { |
AjK | 0:0a841b89d614 | 67 | timers[index].counter = timers[index].reload; |
AjK | 0:0a841b89d614 | 68 | } |
AjK | 0:0a841b89d614 | 69 | } |
AjK | 0:0a841b89d614 | 70 | } |
AjK | 0:0a841b89d614 | 71 | } |
AjK | 0:0a841b89d614 | 72 | LPC_RIT->RICTRL |= 0x1; /* Dismiss the IRQ. */ |
AjK | 0:0a841b89d614 | 73 | } |
AjK | 0:0a841b89d614 | 74 | |
AjK | 0:0a841b89d614 | 75 | /** rit_index_check |
AjK | 0:0a841b89d614 | 76 | * |
AjK | 0:0a841b89d614 | 77 | * Check that an index exists. Ensures that index into array is valid. |
AjK | 0:0a841b89d614 | 78 | * |
AjK | 0:0a841b89d614 | 79 | * @param int inex The index to check. |
AjK | 0:0a841b89d614 | 80 | * @return int zero on non-existent index, non-zero otherwise. |
AjK | 0:0a841b89d614 | 81 | */ |
AjK | 0:0a841b89d614 | 82 | inline static bool rit_index_check(int index) { |
AjK | 0:0a841b89d614 | 83 | for (int i = 0; timers[i].callback != NULL; i++) if (i == index) return true; |
AjK | 0:0a841b89d614 | 84 | return false; |
AjK | 0:0a841b89d614 | 85 | } |
AjK | 0:0a841b89d614 | 86 | |
AjK | 0:0a841b89d614 | 87 | /** rit_timer_set_counter |
AjK | 0:0a841b89d614 | 88 | */ |
AjK | 0:0a841b89d614 | 89 | void rit_timer_set_counter(int index, uint32_t value) { |
AjK | 0:0a841b89d614 | 90 | if (rit_index_check(index)) timers[index].counter = value; |
AjK | 0:0a841b89d614 | 91 | } |
AjK | 0:0a841b89d614 | 92 | |
AjK | 0:0a841b89d614 | 93 | /** rit_timer_set_reload |
AjK | 0:0a841b89d614 | 94 | */ |
AjK | 0:0a841b89d614 | 95 | void rit_timer_set_reload(int index, uint32_t value) { |
AjK | 0:0a841b89d614 | 96 | if (rit_index_check(index)) timers[index].reload = value; |
AjK | 0:0a841b89d614 | 97 | } |
AjK | 0:0a841b89d614 | 98 | |
AjK | 0:0a841b89d614 | 99 | /** rit_timer_get_values |
AjK | 0:0a841b89d614 | 100 | * |
AjK | 0:0a841b89d614 | 101 | * Get the current counter/reload values of the specified timer. |
AjK | 0:0a841b89d614 | 102 | * |
AjK | 0:0a841b89d614 | 103 | * If the supplied "index" value is out of range the index value pointed to by |
AjK | 0:0a841b89d614 | 104 | * the caller is set to -1 to signify an error has occured (subscript/index out |
AjK | 0:0a841b89d614 | 105 | * of range). |
AjK | 0:0a841b89d614 | 106 | * |
AjK | 0:0a841b89d614 | 107 | * @param int * index A pointer to an int for the index value of the array to return. |
AjK | 0:0a841b89d614 | 108 | * @param uint32_t * counter A pointer to variable to place the counter value into. |
AjK | 0:0a841b89d614 | 109 | * @param uint32_t * counter A pointer to variable to place the reload value into. |
AjK | 0:0a841b89d614 | 110 | */ |
AjK | 0:0a841b89d614 | 111 | void rit_timer_get_values(int *index, uint32_t *counter, uint32_t *reload) { |
AjK | 0:0a841b89d614 | 112 | if (rit_index_check(*(index))) { |
AjK | 0:0a841b89d614 | 113 | *(counter) = timers[*(index)].counter; |
AjK | 0:0a841b89d614 | 114 | *(reload) = timers[*(index)].reload; |
AjK | 0:0a841b89d614 | 115 | } |
AjK | 0:0a841b89d614 | 116 | else *(index) = -1; |
AjK | 0:0a841b89d614 | 117 | } |
AjK | 0:0a841b89d614 | 118 | |
AjK | 0:0a841b89d614 | 119 | /** rit_get_uptime |
AjK | 0:0a841b89d614 | 120 | */ |
AjK | 0:0a841b89d614 | 121 | void rit_read_uptime(uint32_t *h, uint32_t *l) { |
AjK | 0:0a841b89d614 | 122 | *(l) = uptimeL; |
AjK | 0:0a841b89d614 | 123 | *(h) = uptimeH; |
AjK | 0:0a841b89d614 | 124 | } |
AjK | 0:0a841b89d614 | 125 | |
AjK | 0:0a841b89d614 | 126 | /** rit_init |
AjK | 0:0a841b89d614 | 127 | */ |
AjK | 0:0a841b89d614 | 128 | void rit_init(void) { |
AjK | 0:0a841b89d614 | 129 | |
AjK | 0:0a841b89d614 | 130 | DEBUG_INIT_START; |
AjK | 0:0a841b89d614 | 131 | |
AjK | 0:0a841b89d614 | 132 | uptimeL = uptimeH = 0; |
AjK | 0:0a841b89d614 | 133 | |
AjK | 0:0a841b89d614 | 134 | /* Start by switching power on to the peripheral */ |
AjK | 0:0a841b89d614 | 135 | LPC_SC->PCONP |= (1UL << 16); |
AjK | 0:0a841b89d614 | 136 | |
AjK | 0:0a841b89d614 | 137 | /* The compare value depends on the PCLK frequency. |
AjK | 0:0a841b89d614 | 138 | The following are based on a CCLK of 96Mhz to |
AjK | 0:0a841b89d614 | 139 | achieve a 1ms timeout value. */ |
AjK | 0:0a841b89d614 | 140 | switch ((LPC_SC->PCLKSEL1 >> 26) & 0x3) { |
AjK | 0:0a841b89d614 | 141 | case 0: LPC_RIT->RICOMPVAL = (96000000L / 4 / 1000); break; /* CCLK / 4 */ |
AjK | 0:0a841b89d614 | 142 | case 1: LPC_RIT->RICOMPVAL = (96000000L / 1 / 1000); break; /* CCLK / 1 */ |
AjK | 0:0a841b89d614 | 143 | case 2: LPC_RIT->RICOMPVAL = (96000000L / 2 / 1000); break; /* CCLK / 2 */ |
AjK | 0:0a841b89d614 | 144 | case 3: LPC_RIT->RICOMPVAL = (96000000L / 8 / 1000); break; /* CCLK / 8 */ |
AjK | 0:0a841b89d614 | 145 | } |
AjK | 0:0a841b89d614 | 146 | |
AjK | 0:0a841b89d614 | 147 | /* Set the ISR vector and enable interrupts for the RIT. */ |
AjK | 0:0a841b89d614 | 148 | NVIC_SetVector(RIT_IRQn, (uint32_t)RIT_IRQHandler); |
AjK | 0:0a841b89d614 | 149 | NVIC_EnableIRQ(RIT_IRQn); |
AjK | 0:0a841b89d614 | 150 | |
AjK | 0:0a841b89d614 | 151 | /* Enable the RIT. */ |
AjK | 0:0a841b89d614 | 152 | LPC_RIT->RICTRL = 0x0000000A; |
AjK | 0:0a841b89d614 | 153 | |
AjK | 0:0a841b89d614 | 154 | DEBUG_INIT_END; |
AjK | 0:0a841b89d614 | 155 | } |