From: Keith Packard Date: Mon, 13 Apr 2009 05:52:47 +0000 (-0700) Subject: Add 100Hz timer X-Git-Tag: sn1-flight1~23 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=823f4f92de0c1f8dd7a644a8e56ffe9822bee6e2 Add 100Hz timer Use Timer 1 to generate a 100Hz timer interrupt --- diff --git a/Makefile b/Makefile index 2fb24898..b6da6b8f 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ INC = \ SRC = \ ao_task.c \ + ao_timer.c \ ao_panic.c \ ao_test.c \ _bp.c diff --git a/ao.h b/ao.h index 4fd368c0..2d434134 100644 --- a/ao.h +++ b/ao.h @@ -22,7 +22,9 @@ #include #include "cc1111.h" -#define AO_STACK_START 0x11 +#define DATA_TO_XDATA(a) ((void __xdata *) ((uint8_t) (a) | 0xff00)) + +#define AO_STACK_START 0x21 #define AO_STACK_END 0xfe #define AO_STACK_SIZE (AO_STACK_END - AO_STACK_START + 1) @@ -36,6 +38,10 @@ struct ao_task { #define AO_ERROR_NO_TASK 1 +#define ao_interrupt_disable() (EA = 0) +#define ao_interrupt_enable() (EA = 1) + +/* ao_task.c */ int ao_sleep(__xdata void *wchan); int ao_wakeup(__xdata void *wchan); void ao_add_task(__xdata struct ao_task * task, void (*start)(void)); @@ -43,4 +49,13 @@ void ao_start_scheduler(void); void ao_yield(void) _naked; void ao_panic(uint8_t reason); +/* ao_timer.c */ + +volatile __data uint16_t ao_time; + +void ao_timer_isr(void) interrupt 9; +void ao_timer_init(void); +uint16_t ao_time_atomic(void); +void ao_delay(uint16_t ticks); + #endif /* _AO_H_ */ diff --git a/ao_task.c b/ao_task.c index 0af5043c..0e976d7c 100644 --- a/ao_task.c +++ b/ao_task.c @@ -181,5 +181,6 @@ ao_start_scheduler(void) { ao_cur_task_id = AO_NO_TASK; ao_cur_task = NULL; + ao_timer_init(); ao_yield(); } diff --git a/ao_test.c b/ao_test.c index 85d523af..35a019fa 100644 --- a/ao_test.c +++ b/ao_test.c @@ -45,7 +45,7 @@ blink_1(void) { for (;;) { P1 ^= 2; - delay(20); + ao_delay(20); } } @@ -53,7 +53,7 @@ void wakeup(void) { for (;;) { - delay(10); + ao_delay(10); ao_wakeup(&blink_chan); } } @@ -62,6 +62,9 @@ void main(void) { CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; + /* Set p1_1 and p1_0 to output */ P1DIR = 0x03; diff --git a/ao_timer.c b/ao_timer.c new file mode 100644 index 00000000..7a81f32e --- /dev/null +++ b/ao_timer.c @@ -0,0 +1,80 @@ +/* + * Copyright © 2009 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" + +volatile __data uint16_t ao_time; + +void ao_timer_isr(void) interrupt 9 +{ + ++ao_time; + ao_wakeup(DATA_TO_XDATA(&ao_time)); +} + +uint16_t ao_time_atomic(void) +{ + uint8_t ret1; + uint16_t ret2; + + for (;;) { + ret1 = ao_time >> 8; + ret2 = ao_time; + if (ret1 == ((__xdata uint8_t *)(&ret2))[1]) + break; + } + return ret2; +} + +#define T1_CLOCK_DIVISOR 8 /* 24e6/8 = 3e6 */ +#define T1_SAMPLE_TIME 30000 /* 3e6/30000 = 100 */ + +void +ao_timer_init(void) +{ + /* NOTE: This uses a timer only present on cc1111 architecture. */ + + /* disable timer 1 */ + T1CTL = 0; + + /* set the sample rate */ + T1CC0H = T1_SAMPLE_TIME >> 8; + T1CC0L = T1_SAMPLE_TIME; + + T1CCTL0 = T1CCTL_MODE_COMPARE; + T1CCTL1 = 0; + T1CCTL2 = 0; + + /* clear timer value */ + T1CNTL = 0; + + /* enable overflow interrupt */ + OVFIM = 1; + /* enable timer 1 interrupt */ + T1IE = 1; + + /* enable timer 1 in module mode, dividing by 8 */ + T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8; +} + +void +ao_delay(uint16_t ticks) +{ + uint16_t until = ao_time_atomic() + ticks; + + while ((int16_t) (until - ao_time_atomic()) > 0) + ao_sleep(DATA_TO_XDATA(&ao_time)); +}