Support our P2_0 connected buzzer, and formalize LED output support.
Signed-off-by: Keith Packard <keithp@keithp.com>
*.lnk
*.map
*.mem
-altos-flash
-altos-ram
+altos
SRC = \
ao_adc.c \
+ ao_beep.c \
+ ao_led.c \
ao_task.c \
ao_timer.c \
ao_panic.c \
RST=$(SRC:.c=.rst)
SYM=$(SRC:.c=.sym)
-PROGS=$(PROG)-flash.ihx $(PROG)-ram.ihx
+PROGS=$(PROG).ihx
PCDB=$(PROGS:.ihx=.cdb)
PLNK=$(PROGS:.ihx=.lnk)
PMAP=$(PROGS:.ihx=.map)
all: $(PROGS)
-$(PROG)-ram.ihx: $(REL) Makefile
- $(CC) $(LDFLAGS_RAM) $(CFLAGS) -o $(PROG)-ram.ihx $(REL)
- $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG)-flash.ihx $(REL)
- sh check-stack ao.h $(PROG)-flash.mem
-
-$(PROG)-flash.ihx: $(PROG)-ram.ihx
+$(PROG).ihx: $(REL) Makefile
+ $(CC) $(LDFLAGS_FLASH) $(CFLAGS) -o $(PROG).ihx $(REL)
+ sh check-stack ao.h $(PROG).mem
clean:
rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
volatile __data uint16_t ao_time;
+#define AO_MS_TO_TICKS(ms) ((ms) / 10)
+#define AO_SEC_TO_TICKS(s) ((s) * 100)
+
void ao_timer_isr(void) interrupt 9;
void ao_timer_init(void);
uint16_t ao_time_atomic(void);
int16_t sense_m;
};
-extern __xdata struct ao_adc ao_adc_ring[ADC_RING];
-extern __data uint8_t ao_adc_head;
+extern volatile __xdata struct ao_adc ao_adc_ring[ADC_RING];
+extern volatile __data uint8_t ao_adc_head;
void ao_adc_isr(void) interrupt 1;
void ao_adc_init(void);
void ao_adc_poll(void);
void ao_adc_get(__xdata struct ao_adc *packet);
+/* ao_beep.c */
+
+#define AO_BEEP_LOW 150
+#define AO_BEEP_MID 94
+#define AO_BEEP_HIGH 75
+#define AO_BEEP_OFF 0
+
+void
+ao_beep_init(void);
+
+void
+ao_beep(uint8_t beep);
+
+void
+ao_beep_for(uint8_t beep, uint16_t ticks);
+
+/* ao_led.c */
+
+#define AO_LED_NONE 0
+#define AO_LED_GREEN 1
+#define AO_LED_RED 2
+
+void
+ao_led_init(void);
+
+void
+ao_led_on(uint8_t colors);
+
+void
+ao_led_off(uint8_t colors);
+
+void
+ao_led_set(uint8_t colors);
+
+void
+ao_led_for(uint8_t colors, uint16_t ticks);
+
#endif /* _AO_H_ */
#include "ao.h"
-__xdata struct ao_adc ao_adc_ring[ADC_RING];
-__data uint8_t ao_adc_head;
+volatile __xdata struct ao_adc ao_adc_ring[ADC_RING];
+volatile __data uint8_t ao_adc_head;
void ao_adc_isr(void) interrupt 1
{
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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"
+
+void
+ao_beep_init(void)
+{
+ /* Our beeper is on P2_0, which is hooked to timer 4 using
+ * configuration alternative 2
+ */
+ P2_0 = 0;
+ P2SEL = (P2SEL & ~P2SEL_SELP2_0_MASK) | P2SEL_SELP2_0_GPIO;
+ PERCFG = (PERCFG & ~PERCFG_T4CFG_ALT_MASK) | PERCFG_T4CFG_ALT_2;
+ T4CCTL0 = TxCCTLy_CMP_TOGGLE|TxCCTLy_CMP_MODE_ENABLE;
+}
+
+void
+ao_beep(uint8_t beep)
+{
+ if (beep == 0) {
+ P2_0 = 0;
+ P2SEL = (P2SEL & ~P2SEL_SELP2_0_MASK) | P2SEL_SELP2_0_GPIO;
+ T4CTL = 0;
+ } else {
+ P2SEL = (P2SEL & ~P2SEL_SELP2_0_MASK) | P2SEL_SELP2_0_PERIPHERAL;
+ T4CC0 = beep;
+ T4CTL = TxCTL_DIV_32 | TxCTL_MODE_MODULO | TxCTL_START;
+ }
+}
+
+void
+ao_beep_for(uint8_t beep, uint16_t ticks)
+{
+ ao_beep(beep);
+ ao_delay(ticks);
+ ao_beep(0);
+}
--- /dev/null
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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"
+
+void
+ao_led_init(void)
+{
+ P1SEL &= ~3;
+ P1 &= ~3;
+ P1DIR |= 3;
+}
+
+void
+ao_led_on(uint8_t colors)
+{
+ P1 |= colors;
+}
+
+void
+ao_led_off(uint8_t colors)
+{
+ P1 &= ~colors;
+}
+
+void
+ao_led_set(uint8_t colors)
+{
+ P1 = (P1 & ~3) | colors;
+}
+
+void
+ao_led_for(uint8_t colors, uint16_t ticks)
+{
+ ao_led_on(colors);
+ ao_delay(ticks);
+ ao_led_off(colors);
+}
+
void
ao_start_scheduler(void)
{
+ ao_timer_init();
+ ao_adc_init();
+ ao_beep_init();
+ ao_led_init();
+
ao_cur_task_id = AO_NO_TASK;
ao_cur_task = NULL;
ao_yield();
struct ao_task __xdata blink_0_task;
struct ao_task __xdata blink_1_task;
struct ao_task __xdata wakeup_task;
+struct ao_task __xdata beep_task;
void delay(int n) __reentrant
{
void
blink_0(void)
{
+ uint8_t b = 0;
for (;;) {
- P1 ^= 1;
+ b = 1 - b;
+ if (b)
+ ao_led_on(AO_LED_GREEN);
+ else
+ ao_led_off(AO_LED_GREEN);
ao_sleep(&blink_chan);
}
}
ao_sleep(&ao_adc_ring);
ao_adc_get(&adc);
if (adc.accel < 15900)
- P1_1 = 1;
+ ao_led_on(AO_LED_RED);
else
- P1_1 = 0;
+ ao_led_off(AO_LED_RED);
}
}
wakeup(void)
{
for (;;) {
- ao_delay(10);
+ ao_delay(AO_MS_TO_TICKS(100));
ao_wakeup(&blink_chan);
}
}
+void
+beep(void)
+{
+ static struct ao_adc adc;
+
+ for (;;) {
+ ao_delay(AO_SEC_TO_TICKS(1));
+ ao_adc_get(&adc);
+ if (adc.temp > 7400)
+ ao_beep_for(AO_BEEP_LOW, AO_MS_TO_TICKS(50));
+ }
+}
+
void
main(void)
{
while (!(SLEEP & SLEEP_XOSC_STB))
;
- /* Set p1_1 and p1_0 to output */
- P1DIR = 0x03;
-
- ao_adc_init();
- ao_timer_init();
-
ao_add_task(&blink_0_task, blink_0);
ao_add_task(&blink_1_task, blink_1);
ao_add_task(&wakeup_task, wakeup);
+ ao_add_task(&beep_task, beep);
ao_start_scheduler();
}