From: Olivier Matz Date: Thu, 31 Oct 2013 18:47:39 +0000 (+0100) Subject: add code to control the audio buzzer X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=9a43add2f0ed382ce1f180bba65fdc077d03b6fb;p=protos%2Fxbee-avr.git add code to control the audio buzzer --- diff --git a/Makefile b/Makefile index c7ea9a7..4883bb4 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ SRC += parse_neighbor.c SRC += parse_atcmd.c SRC += parse_monitor.c SRC += cmdline.c +SRC += beep.c CFLAGS += -W -Wall -Werror diff --git a/beep.c b/beep.c new file mode 100644 index 0000000..f34219c --- /dev/null +++ b/beep.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include + +#include +#include + +#include "main.h" + +/* 100 ms */ +#define BEEP_PERIOD (100000UL/SCHEDULER_UNIT) + +static struct cirbuf beep_fifo; +static char beep_fifo_buf[16]; +volatile uint8_t beep_mask = 1; /* init beep */ + +union beep_t { + uint8_t u08; + struct { + uint8_t tone:2; + uint8_t len:3; + uint8_t pause:3; + }; +}; +static volatile union beep_t current_beep; + +/* called by the scheduler */ +static void beep_cb(void *arg) +{ + (void)arg; + + beep_mask = 0; + if (current_beep.len == 0 && current_beep.pause == 0) { + if (CIRBUF_GET_LEN(&beep_fifo) == 0) + return; + current_beep.u08 = cirbuf_get_head(&beep_fifo); + cirbuf_del_head(&beep_fifo); + } + + if (current_beep.len > 0) { + current_beep.len --; + switch (current_beep.tone) { + case 0: beep_mask = 1; break; + case 1: beep_mask = 2; break; + case 2: beep_mask = 4; break; + case 3: beep_mask = 8; break; + default: break; + } + return; + } + + if (current_beep.pause > 0) { + current_beep.pause --; + } +} + +void beep(uint8_t tone, uint8_t len, uint8_t pause) +{ + uint8_t flags; + union beep_t b; + + b.tone = tone; + b.len = len; + b.pause = pause; + IRQ_LOCK(flags); + cirbuf_add_tail(&beep_fifo, b.u08); + IRQ_UNLOCK(flags); +} + +void beep_init(void) +{ + cirbuf_init(&beep_fifo, beep_fifo_buf, 0, sizeof(beep_fifo_buf)); + scheduler_add_periodical_event_priority(&beep_cb, NULL, + BEEP_PERIOD, BEEP_PRIO); +} diff --git a/beep.h b/beep.h new file mode 100644 index 0000000..50e5750 --- /dev/null +++ b/beep.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2013, Olivier MATZ + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +extern volatile uint8_t beep_mask; + +/* tone between 0 and 3, len between 0 and 7, pause between 0 and 7 */ +void beep(uint8_t tone, uint8_t len, uint8_t pause); +void beep_init(void); diff --git a/commands.c b/commands.c index c9d415f..b58594a 100644 --- a/commands.c +++ b/commands.c @@ -51,6 +51,7 @@ #include "rc_proto.h" #include "main.h" #include "cmdline.h" +#include "beep.h" /* commands_gen.c */ extern const parse_inst_t PROGMEM cmd_reset; @@ -1299,6 +1300,45 @@ const parse_inst_t PROGMEM cmd_baudrate = { }, }; + +/**********************************************************/ + +/* this structure is filled when cmd_beep is parsed successfully */ +struct cmd_beep_result { + fixed_string_t beep; +}; + +/* function called when cmd_beep is parsed successfully */ +static void cmd_beep_parsed(void *parsed_result, void *data) +{ + (void)parsed_result; + (void)data; + + beep(0, 3, 3); + beep(1, 3, 3); + beep(2, 3, 3); + beep(0, 1, 1); + beep(1, 1, 1); + beep(2, 1, 1); +} + +const char PROGMEM str_beep[] = "beep"; +const parse_token_string_t PROGMEM cmd_beep_beep = + TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep, + str_beep); + +const char PROGMEM help_beep[] = "Send a beep"; + +const parse_inst_t PROGMEM cmd_beep = { + .f = cmd_beep_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_beep, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_beep_beep, + NULL, + }, +}; + /**********************************************************/ /* this structure is filled when cmd_servo is parsed successfully */ @@ -1546,6 +1586,7 @@ const parse_ctx_t PROGMEM main_ctx[] = { &cmd_dump, &cmd_debug, &cmd_baudrate, + &cmd_beep, &cmd_servo_set, &cmd_servo_bypassppm, &cmd_servo_show, diff --git a/main.c b/main.c index 0e52717..8e2aa0e 100644 --- a/main.c +++ b/main.c @@ -52,6 +52,7 @@ #include #include +#include "beep.h" #include "main.h" struct xbeeboard xbeeboard; @@ -588,6 +589,8 @@ static void main_timer_interrupt(void) static uint16_t cycles; static uint8_t cpt; + cpt++; + /* interrupt every 2048 cycles */ cycles += 2048; if (cycles >= 12000) { @@ -601,6 +604,11 @@ static void main_timer_interrupt(void) else LED1_OFF(); + if (cpt & beep_mask) + BUZZER_ON(); + else + BUZZER_OFF(); + /* call scheduler every 682us with interrupt unlocked */ sei(); if ((cpt & 0x3) == 0) @@ -614,7 +622,7 @@ int main(void) int8_t err; struct xbee_dev dev; - DDRA = 0x07; /* LEDs */ + DDRA = 0x07 /* LEDs */ | 0x10 /* buzzer */; uart_init(); uart_register_rx_event(CMDLINE_UART, emergency); @@ -627,6 +635,7 @@ int main(void) cmdline_init(); spi_servo_init(); + beep_init(); printf_P(PSTR("\r\n")); rdline_newline(&xbeeboard.rdl, xbeeboard.prompt); diff --git a/main.h b/main.h index 87070a3..9ba70de 100644 --- a/main.h +++ b/main.h @@ -64,9 +64,13 @@ extern volatile uint16_t global_ms; #define LED3_ON() sbi(PORTA, 0) #define LED3_OFF() cbi(PORTA, 0) +#define BUZZER_ON() sbi(PORTA, 4) +#define BUZZER_OFF() cbi(PORTA, 4) + /* highest priority */ #define LED_PRIO 170 #define TIME_PRIO 160 +#define BEEP_PRIO 130 #define SPI_PRIO 100 /* users of spi_servo must have lower prio */ /* lowest priority */