--- /dev/null
+#
+# Automatically generated by make menuconfig: don't edit
+#
+
+#
+# Hardware
+#
+# CONFIG_MCU_AT90S2313 is not set
+# CONFIG_MCU_AT90S2323 is not set
+# CONFIG_MCU_AT90S3333 is not set
+# CONFIG_MCU_AT90S2343 is not set
+# CONFIG_MCU_ATTINY22 is not set
+# CONFIG_MCU_ATTINY26 is not set
+# CONFIG_MCU_AT90S4414 is not set
+# CONFIG_MCU_AT90S4433 is not set
+# CONFIG_MCU_AT90S4434 is not set
+# CONFIG_MCU_AT90S8515 is not set
+# CONFIG_MCU_AT90S8534 is not set
+# CONFIG_MCU_AT90S8535 is not set
+# CONFIG_MCU_AT86RF401 is not set
+# CONFIG_MCU_ATMEGA103 is not set
+# CONFIG_MCU_ATMEGA603 is not set
+# CONFIG_MCU_AT43USB320 is not set
+# CONFIG_MCU_AT43USB355 is not set
+# CONFIG_MCU_AT76C711 is not set
+# CONFIG_MCU_ATMEGA8 is not set
+# CONFIG_MCU_ATMEGA48 is not set
+# CONFIG_MCU_ATMEGA88 is not set
+# CONFIG_MCU_ATMEGA8515 is not set
+# CONFIG_MCU_ATMEGA8535 is not set
+# CONFIG_MCU_ATTINY13 is not set
+# CONFIG_MCU_ATTINY2313 is not set
+# CONFIG_MCU_ATMEGA16 is not set
+# CONFIG_MCU_ATMEGA161 is not set
+# CONFIG_MCU_ATMEGA162 is not set
+# CONFIG_MCU_ATMEGA163 is not set
+# CONFIG_MCU_ATMEGA165 is not set
+# CONFIG_MCU_ATMEGA168 is not set
+# CONFIG_MCU_ATMEGA169 is not set
+# CONFIG_MCU_ATMEGA32 is not set
+# CONFIG_MCU_ATMEGA323 is not set
+# CONFIG_MCU_ATMEGA325 is not set
+# CONFIG_MCU_ATMEGA3250 is not set
+# CONFIG_MCU_ATMEGA64 is not set
+# CONFIG_MCU_ATMEGA645 is not set
+# CONFIG_MCU_ATMEGA6450 is not set
+CONFIG_MCU_ATMEGA128=y
+# CONFIG_MCU_ATMEGA1281 is not set
+# CONFIG_MCU_AT90CAN128 is not set
+# CONFIG_MCU_AT94K is not set
+# CONFIG_MCU_AT90S1200 is not set
+# CONFIG_MCU_ATMEGA2560 is not set
+# CONFIG_MCU_ATMEGA256 is not set
+CONFIG_QUARTZ=16000000
+
+#
+# Generation options
+#
+# CONFIG_OPTM_0 is not set
+# CONFIG_OPTM_1 is not set
+# CONFIG_OPTM_2 is not set
+# CONFIG_OPTM_3 is not set
+CONFIG_OPTM_S=y
+# CONFIG_MATH_LIB is not set
+# CONFIG_FDEVOPEN_COMPAT is not set
+# CONFIG_NO_PRINTF is not set
+# CONFIG_MINIMAL_PRINTF is not set
+CONFIG_STANDARD_PRINTF=y
+# CONFIG_FORMAT_IHEX is not set
+# CONFIG_FORMAT_SREC is not set
+CONFIG_FORMAT_BINARY=y
+
+#
+# Base modules
+#
+CONFIG_MODULE_CIRBUF=y
+# CONFIG_MODULE_CIRBUF_LARGE is not set
+# CONFIG_MODULE_FIXED_POINT is not set
+# CONFIG_MODULE_VECT2 is not set
+# CONFIG_MODULE_GEOMETRY is not set
+# CONFIG_MODULE_SCHEDULER is not set
+# CONFIG_MODULE_SCHEDULER_STATS is not set
+# CONFIG_MODULE_SCHEDULER_CREATE_CONFIG is not set
+# CONFIG_MODULE_SCHEDULER_USE_TIMERS is not set
+CONFIG_MODULE_SCHEDULER_TIMER0=y
+# CONFIG_MODULE_SCHEDULER_MANUAL is not set
+# CONFIG_MODULE_TIME is not set
+# CONFIG_MODULE_TIME_CREATE_CONFIG is not set
+# CONFIG_MODULE_TIME_EXT is not set
+# CONFIG_MODULE_TIME_EXT_CREATE_CONFIG is not set
+
+#
+# Communication modules
+#
+CONFIG_MODULE_UART=y
+# CONFIG_MODULE_UART_9BITS is not set
+CONFIG_MODULE_UART_CREATE_CONFIG=y
+# CONFIG_MODULE_SPI is not set
+# CONFIG_MODULE_SPI_CREATE_CONFIG is not set
+# CONFIG_MODULE_I2C is not set
+# CONFIG_MODULE_I2C_MASTER is not set
+# CONFIG_MODULE_I2C_MULTIMASTER is not set
+# CONFIG_MODULE_I2C_CREATE_CONFIG is not set
+# CONFIG_MODULE_MF2_CLIENT is not set
+# CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER is not set
+# CONFIG_MODULE_MF2_CLIENT_CREATE_CONFIG is not set
+# CONFIG_MODULE_MF2_SERVER is not set
+# CONFIG_MODULE_MF2_SERVER_CREATE_CONFIG is not set
+
+#
+# Hardware modules
+#
+# CONFIG_MODULE_TIMER is not set
+# CONFIG_MODULE_TIMER_CREATE_CONFIG is not set
+# CONFIG_MODULE_TIMER_DYNAMIC is not set
+# CONFIG_MODULE_PWM is not set
+# CONFIG_MODULE_PWM_CREATE_CONFIG is not set
+CONFIG_MODULE_PWM_NG=y
+# CONFIG_MODULE_ADC is not set
+# CONFIG_MODULE_ADC_CREATE_CONFIG is not set
+
+#
+# IHM modules
+#
+# CONFIG_MODULE_MENU is not set
+CONFIG_MODULE_VT100=y
+CONFIG_MODULE_RDLINE=y
+CONFIG_MODULE_RDLINE_CREATE_CONFIG=y
+CONFIG_MODULE_RDLINE_KILL_BUF=y
+CONFIG_MODULE_RDLINE_HISTORY=y
+CONFIG_MODULE_PARSE=y
+# CONFIG_MODULE_PARSE_NO_FLOAT is not set
+
+#
+# External devices modules
+#
+# CONFIG_MODULE_LCD is not set
+# CONFIG_MODULE_LCD_CREATE_CONFIG is not set
+# CONFIG_MODULE_MULTISERVO is not set
+# CONFIG_MODULE_MULTISERVO_CREATE_CONFIG is not set
+# CONFIG_MODULE_AX12 is not set
+# CONFIG_MODULE_AX12_CREATE_CONFIG is not set
+
+#
+# Brushless motor drivers (you should enable pwm modules to see all)
+#
+# CONFIG_MODULE_BRUSHLESS_3PHASE_DIGITAL_HALL is not set
+# CONFIG_MODULE_BRUSHLESS_3PHASE_DIGITAL_HALL_CREATE_CONFIG is not set
+# CONFIG_MODULE_BRUSHLESS_3PHASE_DIGITAL_HALL_DOUBLE is not set
+# CONFIG_MODULE_BRUSHLESS_3PHASE_DIGITAL_HALL_DOUBLE_CREATE_CONFIG is not set
+
+#
+# Encoders (you need comm/spi for encoders_spi)
+#
+# CONFIG_MODULE_ENCODERS_MICROB is not set
+# CONFIG_MODULE_ENCODERS_MICROB_CREATE_CONFIG is not set
+# CONFIG_MODULE_ENCODERS_EIRBOT is not set
+# CONFIG_MODULE_ENCODERS_EIRBOT_CREATE_CONFIG is not set
+# CONFIG_MODULE_ENCODERS_SPI is not set
+# CONFIG_MODULE_ENCODERS_SPI_CREATE_CONFIG is not set
+
+#
+# Robot specific modules
+#
+# CONFIG_MODULE_ROBOT_SYSTEM is not set
+# CONFIG_MODULE_ROBOT_SYSTEM_MOT_AND_EXT is not set
+# CONFIG_MODULE_POSITION_MANAGER is not set
+# CONFIG_MODULE_COMPENSATE_CENTRIFUGAL_FORCE is not set
+# CONFIG_MODULE_TRAJECTORY_MANAGER is not set
+# CONFIG_MODULE_BLOCKING_DETECTION_MANAGER is not set
+# CONFIG_MODULE_OBSTACLE_AVOIDANCE is not set
+# CONFIG_MODULE_OBSTACLE_AVOIDANCE_CREATE_CONFIG is not set
+
+#
+# Control system modules
+#
+# CONFIG_MODULE_CONTROL_SYSTEM_MANAGER is not set
+CONFIG_MODULE_PID=y
+CONFIG_MODULE_PID_CREATE_CONFIG=y
+# CONFIG_MODULE_RAMP is not set
+# CONFIG_MODULE_QUADRAMP is not set
+# CONFIG_MODULE_QUADRAMP_DERIVATE is not set
+# CONFIG_MODULE_BIQUAD is not set
+
+#
+# Radio devices
+#
+# CONFIG_MODULE_CC2420 is not set
+# CONFIG_MODULE_CC2420_CREATE_CONFIG is not set
+
+#
+# Crypto modules
+#
+# CONFIG_MODULE_AES is not set
+# CONFIG_MODULE_AES_CTR is not set
+# CONFIG_MODULE_MD5 is not set
+# CONFIG_MODULE_MD5_HMAC is not set
+# CONFIG_MODULE_RC4 is not set
+
+#
+# Encodings modules
+#
+# CONFIG_MODULE_BASE64 is not set
+# CONFIG_MODULE_HAMMING is not set
+
+#
+# Debug modules
+#
+# CONFIG_MODULE_DIAGNOSTIC is not set
+# CONFIG_MODULE_DIAGNOSTIC_CREATE_CONFIG is not set
+# CONFIG_MODULE_ERROR is not set
+# CONFIG_MODULE_ERROR_CREATE_CONFIG is not set
+
+#
+# Programmer options
+#
+# CONFIG_AVRDUDE is not set
+CONFIG_AVARICE=y
+
+#
+# Avrdude
+#
+# CONFIG_AVRDUDE_PROG_FUTURELEC is not set
+# CONFIG_AVRDUDE_PROG_ABCMINI is not set
+# CONFIG_AVRDUDE_PROG_PICOWEB is not set
+# CONFIG_AVRDUDE_PROG_SP12 is not set
+# CONFIG_AVRDUDE_PROG_ALF is not set
+# CONFIG_AVRDUDE_PROG_BASCOM is not set
+# CONFIG_AVRDUDE_PROG_DT006 is not set
+# CONFIG_AVRDUDE_PROG_PONY_STK200 is not set
+CONFIG_AVRDUDE_PROG_STK200=y
+# CONFIG_AVRDUDE_PROG_PAVR is not set
+# CONFIG_AVRDUDE_PROG_BUTTERFLY is not set
+# CONFIG_AVRDUDE_PROG_AVR910 is not set
+# CONFIG_AVRDUDE_PROG_STK500 is not set
+# CONFIG_AVRDUDE_PROG_AVRISP is not set
+# CONFIG_AVRDUDE_PROG_BSD is not set
+# CONFIG_AVRDUDE_PROG_DAPA is not set
+# CONFIG_AVRDUDE_PROG_JTAG1 is not set
+# CONFIG_AVRDUDE_PROG_AVR109 is not set
+CONFIG_AVRDUDE_PORT="/dev/parport0"
+CONFIG_AVRDUDE_BAUDRATE=19200
+
+#
+# Avarice
+#
+CONFIG_AVARICE_PORT="/dev/ttyS0"
+CONFIG_AVARICE_DEBUG_PORT=1234
+CONFIG_AVARICE_PROG_MKI=y
+# CONFIG_AVARICE_PROG_MKII is not set
+# CONFIG_AVRDUDE_CHECK_SIGNATURE is not set
--- /dev/null
+TARGET = beacon_tsop
+
+AVERSIVE_DIR = ../../../..
+
+# List C source files here. (C dependencies are automatically generated.)
+SRC = main.c commands.c cmdline.c
+
+# List Assembler source files here.
+# Make them always end in a capital .S. Files ending in a lowercase .s
+# will not be considered source files but generated files (assembler
+# output from the compiler), and will be deleted upon "make clean"!
+# Even though the DOS/Win* filesystem matches both .s and .S the same,
+# it will preserve the spelling of the filenames, and gcc itself does
+# care about how the name is spelled on its command-line.
+ASRC =
+
+AVRDUDE_DELAY=30
+
+CFLAGS += -W
+
+########################################
+
+-include .aversive_conf
+include $(AVERSIVE_DIR)/mk/aversive_project.mk
--- /dev/null
+/*
+ * Copyright Droids Corporation
+ * Olivier Matz <zer0@droids-corp.org>
+ *
+ * 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
+ *
+ * Revision : $Id: cmdline.c,v 1.5 2009-05-02 10:08:09 zer0 Exp $
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <aversive.h>
+#include <aversive/error.h>
+
+#include <parse.h>
+#include <rdline.h>
+#include <uart.h>
+#include <pwm_ng.h>
+
+#include <pid.h>
+
+#include "main.h"
+#include "cmdline.h"
+
+
+/******** See in commands.c for the list of commands. */
+extern parse_pgm_ctx_t main_ctx[];
+
+void write_char(char c)
+{
+ uart_send(CMDLINE_UART, c);
+}
+
+void valid_buffer(const char *buf, __attribute__((unused)) uint8_t size)
+{
+ int8_t ret;
+
+ ret = parse(main_ctx, buf);
+ if (ret == PARSE_AMBIGUOUS)
+ printf_P(PSTR("Ambiguous command\r\n"));
+ else if (ret == PARSE_NOMATCH)
+ printf_P(PSTR("Command not found\r\n"));
+ else if (ret == PARSE_BAD_ARGS)
+ printf_P(PSTR("Bad arguments\r\n"));
+}
+
+int8_t complete_buffer(const char *buf, char *dstbuf, uint8_t dstsize,
+ int16_t *state)
+{
+ return complete(main_ctx, buf, state, dstbuf, dstsize);
+}
+
+int cmdline_process(void)
+{
+ const char *history, *buffer;
+ int8_t ret, same = 0;
+ int16_t c;
+
+ while ( (c = uart_recv_nowait(CMDLINE_UART)) != -1) {
+
+ ret = rdline_char_in(&beacon_tsop.rdl, c);
+ if (ret != 2 && ret != 0) {
+ buffer = rdline_get_buffer(&beacon_tsop.rdl);
+ history = rdline_get_history_item(&beacon_tsop.rdl, 0);
+ if (history) {
+ same = !memcmp(buffer, history, strlen(history)) &&
+ buffer[strlen(history)] == '\n';
+ }
+ else
+ same = 0;
+ if (strlen(buffer) > 1 && !same)
+ rdline_add_history(&beacon_tsop.rdl, buffer);
+ rdline_newline(&beacon_tsop.rdl, beacon_tsop.prompt);
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright Droids Corporation
+ * Olivier Matz <zer0@droids-corp.org>
+ *
+ * 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
+ *
+ * Revision : $Id: cmdline.h,v 1.2 2009-02-27 22:23:37 zer0 Exp $
+ *
+ */
+
+#define CMDLINE_UART 0
+
+int cmdline_process(void);
+
+static inline uint8_t cmdline_keypressed(void) {
+ return (uart_recv_nowait(CMDLINE_UART) != -1);
+}
+
+static inline int16_t cmdline_getchar(void) {
+ return uart_recv_nowait(CMDLINE_UART);
+}
+
+static inline uint8_t cmdline_getchar_wait(void) {
+ return uart_recv(CMDLINE_UART);
+}
+
+void write_char(char c);
+void valid_buffer(const char *buf, uint8_t size);
+int8_t complete_buffer(const char *buf, char *dstbuf, uint8_t dstsize,
+ int16_t *state);
+
--- /dev/null
+/*
+ * Copyright Droids Corporation (2009)
+ *
+ * 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
+ *
+ * Revision : $Id: commands.c,v 1.7 2009-04-24 19:30:41 zer0 Exp $
+ *
+ * Olivier MATZ <zer0@droids-corp.org>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <aversive/pgmspace.h>
+#include <aversive/wait.h>
+#include <aversive/error.h>
+
+#include <pid.h>
+#include <pwm_ng.h>
+#include <parse.h>
+#include <rdline.h>
+#include <parse_string.h>
+
+#include "main.h"
+
+/**********************************************************/
+/* Reset */
+
+/* this structure is filled when cmd_reset is parsed successfully */
+struct cmd_reset_result {
+ fixed_string_t arg0;
+};
+
+/* function called when cmd_reset is parsed successfully */
+static void cmd_reset_parsed(__attribute__((unused)) void *parsed_result,
+ __attribute__((unused)) void *data)
+{
+ reset();
+}
+
+prog_char str_reset_arg0[] = "reset";
+parse_pgm_token_string_t cmd_reset_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_reset_result, arg0, str_reset_arg0);
+
+prog_char help_reset[] = "Reset the board";
+parse_pgm_inst_t cmd_reset = {
+ .f = cmd_reset_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = help_reset,
+ .tokens = { /* token list, NULL terminated */
+ (prog_void *)&cmd_reset_arg0,
+ NULL,
+ },
+};
+
+/**********************************************************/
+/* Debug_Frame */
+
+/* this structure is filled when cmd_debug_frame is parsed successfully */
+struct cmd_debug_frame_result {
+ fixed_string_t arg0;
+ fixed_string_t arg1;
+};
+
+/* function called when cmd_debug_frame is parsed successfully */
+static void cmd_debug_frame_parsed(void *parsed_result,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_debug_frame_result *res = parsed_result;
+ if (!strcmp_P(res->arg1, PSTR("on")))
+ beacon_tsop.debug_frame = 1;
+ else
+ beacon_tsop.debug_frame = 0;
+}
+
+prog_char str_debug_frame_arg0[] = "debug_frame";
+parse_pgm_token_string_t cmd_debug_frame_arg0 =
+ TOKEN_STRING_INITIALIZER(struct cmd_debug_frame_result,
+ arg0, str_debug_frame_arg0);
+prog_char str_debug_frame_arg1[] = "on#off";
+parse_pgm_token_string_t cmd_debug_frame_arg1 =
+ TOKEN_STRING_INITIALIZER(struct cmd_debug_frame_result,
+ arg1, str_debug_frame_arg1);
+
+prog_char help_debug_frame[] = "Enable frame debug [debug_frame on|off]";
+parse_pgm_inst_t cmd_debug_frame = {
+ .f = cmd_debug_frame_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = help_debug_frame,
+ .tokens = { /* token list, NULL terminated */
+ (prog_void *)&cmd_debug_frame_arg0,
+ (prog_void *)&cmd_debug_frame_arg1,
+ NULL,
+ },
+};
+
+/**********************************************************/
+/* Debug_Speed */
+
+/* this structure is filled when cmd_debug_speed is parsed successfully */
+struct cmd_debug_speed_result {
+ fixed_string_t arg0;
+ fixed_string_t arg1;
+};
+
+/* function called when cmd_debug_speed is parsed successfully */
+static void cmd_debug_speed_parsed(void *parsed_result,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_debug_speed_result *res = parsed_result;
+ if (!strcmp_P(res->arg1, PSTR("on")))
+ beacon_tsop.debug_speed = 1;
+ else
+ beacon_tsop.debug_speed = 0;
+}
+
+prog_char str_debug_speed_arg0[] = "debug_speed";
+parse_pgm_token_string_t cmd_debug_speed_arg0 =
+ TOKEN_STRING_INITIALIZER(struct cmd_debug_speed_result,
+ arg0, str_debug_speed_arg0);
+prog_char str_debug_speed_arg1[] = "on#off";
+parse_pgm_token_string_t cmd_debug_speed_arg1 =
+ TOKEN_STRING_INITIALIZER(struct cmd_debug_speed_result,
+ arg1, str_debug_speed_arg1);
+
+prog_char help_debug_speed[] = "Enable speed debug [debug_speed on|off]";
+parse_pgm_inst_t cmd_debug_speed = {
+ .f = cmd_debug_speed_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = help_debug_speed,
+ .tokens = { /* token list, NULL terminated */
+ (prog_void *)&cmd_debug_speed_arg0,
+ (prog_void *)&cmd_debug_speed_arg1,
+ NULL,
+ },
+};
+
+/**********************************************************/
+
+/* in progmem */
+parse_pgm_ctx_t main_ctx[] = {
+
+ /* commands_gen.c */
+ (parse_pgm_inst_t *)&cmd_reset,
+ (parse_pgm_inst_t *)&cmd_debug_frame,
+ (parse_pgm_inst_t *)&cmd_debug_speed,
+ NULL,
+};
--- /dev/null
+/*
+ * Copyright Droids Corporation (2009)
+ * Olivier Matz <zer0@droids-corp.org>
+ *
+ * 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
+ *
+ * Revision : $Id: main.c,v 1.8 2009-05-02 10:08:09 zer0 Exp $
+ *
+ */
+
+#include <aversive.h>
+#include <aversive/wait.h>
+
+#include <uart.h>
+#include <pid.h>
+#include <pwm_ng.h>
+#include <parse.h>
+#include <rdline.h>
+
+#include "cmdline.h"
+#include "main.h"
+
+/******************* TSOP */
+
+#define EICRx_TSOP EICRB /* EICRA is not ok, cannot do intr on any edge */
+#ifdef BOARD2006
+#define INTx_TSOP INT6
+#define ISCx0_TSOP ISC60
+#define ISCx1_TSOP ISC61
+#define SIG_TSOP SIG_INTERRUPT6
+#define TSOP_READ() (PINE & 0x40)
+#else
+#define INTx_TSOP INT4
+#define ISCx0_TSOP ISC40
+#define ISCx1_TSOP ISC41
+#define SIG_TSOP SIG_INTERRUPT4
+#define TSOP_READ() (PINE & 0x10)
+#endif
+
+#define TSOP_FREQ_MHZ 0.455
+#define TSOP_PERIOD_US (1./TSOP_FREQ_MHZ)
+#define N_PERIODS 10.
+
+#define TSOP_TIME_SHORT_US (1.5 * N_PERIODS * TSOP_PERIOD_US)
+#define TSOP_TIME_LONG_US (2.5 * N_PERIODS * TSOP_PERIOD_US)
+
+#define TSOP_TIME_SHORT ((uint16_t)(TSOP_TIME_SHORT_US*2))
+#define TSOP_TIME_LONG ((uint16_t)(TSOP_TIME_LONG_US*2))
+
+#define FRAME_LEN 16
+
+/* frame */
+static uint16_t start_angle_time;
+static uint16_t frame;
+static uint16_t mask;
+static uint8_t len;
+static uint8_t val;
+
+struct detected_frame {
+ uint16_t frame;
+ uint16_t time;
+};
+
+#define FRAME_RING_ORDER 4
+#define FRAME_RING_SIZE (1<<FRAME_RING_ORDER)
+#define FRAME_RING_MASK (FRAME_RING_SIZE-1)
+static uint8_t frame_ring_head = 0;
+static uint8_t frame_ring_tail = 0;
+static struct detected_frame frame_ring[FRAME_RING_SIZE];
+
+/********************** CS */
+
+/* 8ms, easier if it's a pow of 2 */
+#define CS_PERIOD_US (8192)
+#define CS_PERIOD ((uint16_t)(CS_PERIOD_US*2))
+#define CPT_ICR_MAX (uint8_t)((1000000UL/(uint32_t)CS_PERIOD_US)) /* too slow = 1 tr/s */
+#define CPT_ICR_MIN (uint8_t)((10000UL/(uint32_t)CS_PERIOD_US)) /* too fast = 100 tr/s */
+
+/* in tr / 1000s */
+#define CS_CONSIGN (25 * 1000L)
+
+/* pwm for laser:
+ * - clear on timer compare (CTC)
+ * - Toggle OC0 on compare match
+ * - prescaler = 1 */
+#define LASER_ON() do { TCCR0 = _BV(WGM01) | _BV(COM00) | _BV(CS00); } while (0)
+#define LASER_OFF() do { TCCR0 = 0; } while (0)
+
+struct beacon_tsop beacon_tsop;
+
+void debug_serial(void)
+{
+#if 0
+ while (1) {
+ int16_t c;
+ c = uart_recv_nowait(0);
+ if (c != -1)
+ printf("%c", (char)(c+1));
+ LED1_ON();
+ wait_ms(500);
+ LED1_OFF();
+ wait_ms(500);
+ }
+#endif
+}
+
+void debug_tsop(void)
+{
+#if 0
+ while (1) {
+ if (TSOP_READ())
+ LED1_OFF();
+ else {
+ LED1_ON();
+ wait_ms(500);
+ }
+ }
+#endif
+}
+
+/* decode frame */
+SIGNAL(SIG_TSOP) {
+ static uint8_t led_cpt = 0;
+
+ /* tsop status */
+ static uint8_t prev_tsop = 0;
+ uint8_t cur_tsop;
+
+ /* time */
+ static uint16_t prev_time;
+ uint16_t ref_time;
+ uint16_t cur_time;
+ uint16_t diff_time;
+
+ ref_time = ICR3;
+ cur_time = TCNT3;
+ cur_tsop = TSOP_READ();
+ diff_time = cur_time - prev_time;
+
+ /* first rising edge */
+ if (cur_tsop && diff_time > TSOP_TIME_LONG) {
+ len = 1;
+ val = 1;
+ frame = 0;
+ start_angle_time = cur_time - ref_time;
+ mask = 1;
+ }
+ /* any short edge */
+ else if (diff_time < TSOP_TIME_SHORT) {
+ if (len & 1) {
+ if (val)
+ frame |= mask;
+ mask <<= 1;
+ }
+ len ++;
+ }
+ /* any long edge */
+ else if (diff_time < TSOP_TIME_LONG) {
+ val = !val;
+ if (val)
+ frame |= mask;
+ mask <<= 1;
+ len += 2;
+ }
+
+ /* end of frame */
+ if (len == FRAME_LEN*2) {
+ uint8_t tail_next = (frame_ring_tail+1) & FRAME_RING_MASK;
+ if (tail_next != frame_ring_head) {
+ frame_ring[frame_ring_tail].frame = frame;
+ frame_ring[frame_ring_tail].time = start_angle_time;
+ frame_ring_tail = tail_next;
+ }
+ if (led_cpt & 0x8)
+ LED3_TOGGLE();
+ led_cpt ++;
+ }
+
+ prev_time = cur_time;
+ prev_tsop = cur_tsop;
+}
+
+/* absolute value */
+static inline int32_t AbS(int32_t x)
+{
+ if (x > 0)
+ return x;
+ else
+ return -x;
+}
+
+/* Get the speed of motor (tr / 1000s)
+ * - icr_cpt is the number of CS period between 2 ICR updates
+ * - icr_diff is the difference of ICR values between the ICR updates
+ * (modulo 65536 obviously) */
+static inline int32_t get_speed(uint8_t icr_cpt, uint16_t icr_diff)
+{
+ int32_t best_diff = 65536L;
+ int8_t best_cpt = -2;
+ int32_t diff;
+ int8_t i;
+
+ /* too slow (less than 1 tr/s) */
+ if (icr_cpt > CPT_ICR_MAX)
+ return 1000L;
+
+ /* too fast (more than 100 tr/s) */
+ if (icr_cpt < CPT_ICR_MIN)
+ return 100000L;
+
+ /* try to get the real time knowning icr_cpt and icr_diff */
+ for (i=-1; i<2; i++) {
+ diff = ((icr_cpt+i)&3) * 16384L;
+ diff += (icr_diff & 0x3fff);
+ diff -= icr_diff;
+ if (diff > 32768L)
+ diff -= 65536L;
+ if (diff < -32768)
+ diff += 65536L;
+
+ if (AbS(diff) < AbS(best_diff)) {
+ best_diff = diff;
+ best_cpt = icr_cpt + i;
+ }
+ }
+
+ /* real time difference in 1/2 us */
+ diff = (best_cpt * 16384L) + (icr_diff & 0x3fff);
+ return 2000000000L/diff;
+}
+
+int main(void)
+{
+ uint16_t prev_cs = 0;
+ uint16_t prev_icr = 0;
+ uint16_t icr = 0;
+ uint16_t diff_icr = 0;
+ uint8_t cpt_icr = 0;
+ uint8_t cpt = 0;
+ int32_t speed, out, err;
+ uint16_t tcnt3;
+ uint8_t x = 0;
+
+ /* LEDS */
+ LED1_DDR |= _BV(LED1_BIT);
+ LED2_DDR |= _BV(LED2_BIT);
+ LED3_DDR |= _BV(LED3_BIT);
+ DDRB |= 0x10; /* OC0 (laser pwm) */
+
+ /* PID init */
+ pid_init(&beacon_tsop.pid);
+ pid_set_gains(&beacon_tsop.pid, 500, 0, 0);
+ pid_set_maximums(&beacon_tsop.pid, 0, 20000, 4095);
+ pid_set_out_shift(&beacon_tsop.pid, 10);
+ pid_set_derivate_filter(&beacon_tsop.pid, 4);
+
+ uart_init();
+ fdevopen(uart0_dev_send, uart0_dev_recv);
+
+ rdline_init(&beacon_tsop.rdl, write_char, valid_buffer, complete_buffer);
+ snprintf(beacon_tsop.prompt, sizeof(beacon_tsop.prompt), "beacon > ");
+ rdline_newline(&beacon_tsop.rdl, beacon_tsop.prompt);
+
+ debug_tsop();
+ debug_serial();
+
+ /* configure external interrupt for TSOP */
+ EICRx_TSOP |= _BV(ISCx0_TSOP);
+ EIMSK |= _BV(INTx_TSOP);
+
+ /* pwm for motor */
+ PWM_NG_TIMER_16BITS_INIT(1, TIMER_16_MODE_PWM_10,
+ TIMER1_PRESCALER_DIV_1);
+ PWM_NG_INIT16(&beacon_tsop.pwm_motor, 1, A, 10, 0, NULL, 0);
+
+ /* pwm for laser:
+ * - clear on timer compare (CTC)
+ * - Toggle OC0 on compare match
+ * - prescaler = 1 */
+ TCCR0 = _BV(WGM01) | _BV(COM00) | _BV(CS00);
+ OCR0 = 80; /* f = 100 khz at 16 Mhz */
+
+ /* configure timer 3: CLK/8
+ * it is used as a reference time
+ * enable noise canceller for ICP3 */
+ TCCR3B = _BV(ICNC3) | _BV(CS11);
+
+ sei();
+
+ /* Control system will be done in main loop */
+ while (1) {
+
+ /* process pending bytes on uart */
+ cmdline_process();
+
+ /* monitor the value of ICR (which is modified
+ * automatically on TT rising edge). If the value
+ * changed, process the time difference. */
+ if (ETIFR & _BV(ICF3)) {
+ cli();
+ icr = ICR3;
+ sei();
+ ETIFR = _BV(ICF3);
+
+ LED2_TOGGLE();
+ diff_icr = (icr - prev_icr);
+ cpt_icr = cpt;
+ prev_icr = icr;
+ cpt = 0;
+ speed = get_speed(cpt_icr, diff_icr);
+ }
+
+ /* read time reference */
+ cli();
+ tcnt3 = TCNT3;
+ sei();
+
+ /* wait cs period */
+ if (tcnt3 - prev_cs < CS_PERIOD)
+ continue;
+
+ /* CS LED */
+ if (x & 0x80)
+ LED1_ON();
+ else
+ LED1_OFF();
+ x++;
+
+ /* process CS... maybe we don't need to use
+ * control_system_manager, just PID is enough */
+ if (cpt == CPT_ICR_MAX)
+ speed = 0;
+ else
+ speed = get_speed(cpt_icr, diff_icr);
+
+ /* enabled laser when rotation speed if at least 5tr/s */
+ if (speed > 5000)
+ LASER_ON();
+ else
+ LASER_OFF();
+
+ err = CS_CONSIGN - speed;
+ out = pid_do_filter(&beacon_tsop.pid, err);
+ if (x == 0 && beacon_tsop.debug_speed)
+ printf("%ld %ld\n", speed, out);
+ if (out < 0)
+ out = 0;
+ /* XXX */
+ if (out > 2000)
+ out = 2000;
+
+ pwm_ng_set(&beacon_tsop.pwm_motor, out);
+
+ prev_cs = tcnt3;
+
+ /* count the number of CS period between 2 ICR
+ * captures */
+ if (cpt < CPT_ICR_MAX)
+ cpt ++;
+
+ /* after CS, check if we have a new frame in ring */
+ if (frame_ring_head != frame_ring_tail) {
+ uint8_t head_next;
+ head_next = (frame_ring_head+1) & FRAME_RING_MASK;
+ if (beacon_tsop.debug_frame)
+ printf("%x %d\n", frame_ring[frame_ring_head].frame,
+ frame_ring[frame_ring_head].time);
+ frame_ring_head = head_next;
+ }
+
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright Droids Corporation (2009)
+ * Olivier Matz <zer0@droids-corp.org>
+ *
+ * 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
+ *
+ * Revision : $Id: main.c,v 1.8 2009-05-02 10:08:09 zer0 Exp $
+ *
+ */
+
+#define BOARD2006
+
+/********************** LEDs */
+#define LED_TOGGLE(port, bit) do { \
+ if (port & _BV(bit)) \
+ port &= ~_BV(bit); \
+ else \
+ port |= _BV(bit); \
+ } while(0)
+
+#ifdef BOARD2006
+#define LED1_PORT PORTE
+#define LED1_DDR DDRE
+#define LED1_BIT 2
+#define LED2_PORT PORTE
+#define LED2_DDR DDRE
+#define LED2_BIT 3
+#define LED3_PORT PORTB
+#define LED3_DDR DDRB
+#define LED3_BIT 3
+#define LED1_ON() sbi(LED1_PORT, LED1_BIT)
+#define LED1_OFF() cbi(LED1_PORT, LED1_BIT)
+#define LED1_TOGGLE() LED1_TOGGLE(LED_PORT, LED1_BIT)
+#define LED2_ON() sbi(LED2_PORT, LED2_BIT)
+#define LED2_OFF() cbi(LED2_PORT, LED2_BIT)
+#define LED2_TOGGLE() LED_TOGGLE(LED2_PORT, LED2_BIT)
+#define LED3_ON() sbi(LED3_PORT, LED3_BIT)
+#define LED3_OFF() cbi(LED3_PORT, LED3_BIT)
+#define LED3_TOGGLE() LED_TOGGLE(LED3_PORT, LED3_BIT)
+#else
+#define LED_PORT PORTD
+#define LED_DDR DDRD
+#define LED1_BIT 5
+#define LED2_BIT 6
+#define LED3_BIT 7
+#define LED1_ON() sbi(LED_PORT, LED1_BIT)
+#define LED1_OFF() cbi(LED_PORT, LED1_BIT)
+#define LED1_TOGGLE() LED_TOGGLE(LED_PORT, LED1_BIT)
+#define LED2_ON() sbi(LED_PORT, LED2_BIT)
+#define LED2_OFF() cbi(LED_PORT, LED2_BIT)
+#define LED2_TOGGLE() LED_TOGGLE(LED_PORT, LED2_BIT)
+#define LED3_ON() sbi(LED_PORT, LED3_BIT)
+#define LED3_OFF() cbi(LED_PORT, LED3_BIT)
+#define LED3_TOGGLE() LED_TOGGLE(LED_PORT, LED3_BIT)
+#endif
+
+struct beacon_tsop {
+ struct rdline rdl;
+ char prompt[RDLINE_PROMPT_SIZE];
+ struct pwm_ng pwm_motor;
+ struct pid_filter pid;
+ uint8_t debug_frame;
+ uint8_t debug_speed;
+};
+
+extern struct beacon_tsop beacon_tsop;
--- /dev/null
+/*
+ * Copyright Droids Corporation, Microb Technology, Eirbot (2005)
+ *
+ * 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
+ *
+ *
+ *
+ */
+
+#ifndef PID_CONFIG_H
+#define PID_CONFIG_H
+
+/** the derivate term can be filtered to remove the noise. This value
+ * is the maxium sample count to keep in memory to do this
+ * filtering. For an instance of pid, this count is defined o*/
+#define PID_DERIVATE_FILTER_MAX_SIZE 4
+
+#endif
--- /dev/null
+/*
+ * Copyright Droids Corporation, Microb Technology, Eirbot (2005)
+ *
+ * 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
+ *
+ * Revision : $Id: pwm_config.h,v 1.2.6.3 2007-09-06 08:18:22 zer0 Exp $
+ *
+ */
+
+/* Droids-corp, Eirbot, Microb Technology 2005 - Zer0
+ * Config for PWM
+ */
+/** \file pwm_config.h
+ \brief Module to operate all PWM outputs
+
+ \test not tested
+
+*/
+
+
+#ifndef _PWM_CONFIG_
+#define _PWM_CONFIG_
+
+#define _PWM_CONFIG_VERSION_ 2
+
+/* Which PWM are enabled ? */
+//#define PWM0_ENABLED
+#define PWM1A_ENABLED
+//#define PWM1B_ENABLED
+//#define PWM1C_ENABLED
+//#define PWM2_ENABLED
+//#define PWM3A_ENABLED
+//#define PWM3B_ENABLED
+//#define PWM3C_ENABLED
+
+
+/** max value for PWM entry, default 12 bits > 4095 */
+#define PWM_SIGNIFICANT_BITS 12
+
+// timer configs (not all possibilities can be used at this time)
+#define TIMER0_MODE TIMER_8_MODE_PWM
+#define TIMER0_PRESCALE TIMER0_PRESCALER_DIV_64
+
+#define TIMER1_MODE TIMER_16_MODE_PWM_10
+#define TIMER1_PRESCALE TIMER1_PRESCALER_DIV_8
+
+#define TIMER2_MODE TIMER_8_MODE_PWM
+#define TIMER2_PRESCALE TIMER1_PRESCALER_DIV_64
+
+#define TIMER3_MODE TIMER_16_MODE_PWM_10
+#define TIMER3_PRESCALE TIMER3_PRESCALER_DIV_8
+
+
+
+
+/** config for pwm and signs
+
+The pwm mode is defined as follows :
+you can add flags like the ones who follow :
+
+PWM_NORMAL : normal pwm, just to put a value if nothing else is needed
+PWM_REVERSE : invert pwm output, not sign
+
+PWM_SIGNED : activate the sign output on a port (see config)
+PWM_SIGN_INVERTED : invert sign output
+PWM_SPECIAL_SIGN_MODE : if defined, the pwm is always near 0 for low values,
+ else negative low values are near 100%
+
+
+the values of PWMxx_SIGN_PORT and PWMxx_SIGN_BIT are simply ignored if the PWM is not signed
+
+
+if you need for example a PWM1A with special sign mode you configure like this :
+
+#define PWM1A_MODE (PWM_SIGNED | PWM_SPECIAL_SIGN_MODE)
+#define PWM1A_SIGN_PORT PORTB
+#define PWM1A_SIGN_BIT 2
+
+*/
+
+
+
+// example for signed pwm1A
+#define PWM1A_MODE (PWM_SIGNED)
+#define PWM1A_SIGN_PORT PORTB
+#define PWM1A_SIGN_BIT 2
+
+
+
+
+
+/**
+PWM synchronization.
+
+this makes the PWMs synchronized.
+just activate the timers you want to synchronize
+
+to synch PWMs you need to enshure that the timers have same prescales. This is verified.
+you need also to enshure that the PWM mode is the same, this is NOT verified !!
+especially, for syncing 8 and 16 bit timers, the PWM mode should be 8 bit.
+
+
+side effect : on some controllers prescalers are shared, so unwanted prescalers can be reset.
+
+This feature is not 100% shure for the moment, but has been tested on M32 and M128
+*/
+
+//#define TIMER0_SYNCH
+//#define TIMER1_SYNCH
+//#define TIMER2_SYNCH
+//#define TIMER3_SYNCH
+
+
+
+#endif
+
--- /dev/null
+/* \r
+ * Copyright Droids Corporation, Microb Technology, Eirbot (2005)\r
+ * \r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ *\r
+ * Revision : $Id: uart_config.h,v 1.3.10.1 2006-11-26 21:06:02 zer0 Exp $\r
+ *\r
+ */\r
+\r
+/* Droids-corp 2004 - Zer0\r
+ * config for uart module\r
+ */\r
+\r
+#ifndef UART_CONFIG_H\r
+#define UART_CONFIG_H\r
+\r
+/*\r
+ * UART0 definitions \r
+ */\r
+\r
+/* compile uart0 fonctions, undefine it to pass compilation */\r
+#define UART0_COMPILE \r
+\r
+/* enable uart0 if == 1, disable if == 0 */\r
+#define UART0_ENABLED 1\r
+\r
+/* enable uart0 interrupts if == 1, disable if == 0 */\r
+#define UART0_INTERRUPT_ENABLED 0\r
+\r
+#define UART0_BAUDRATE 57600\r
+\r
+/* \r
+ * if you enable this, the maximum baudrate you can reach is \r
+ * higher, but the precision is lower. \r
+ */\r
+#define UART0_USE_DOUBLE_SPEED 1\r
+//#define UART0_USE_DOUBLE_SPEED 1\r
+\r
+#define UART0_RX_FIFO_SIZE 4\r
+#define UART0_TX_FIFO_SIZE 1\r
+//#define UART0_NBITS 5\r
+//#define UART0_NBITS 6\r
+//#define UART0_NBITS 7\r
+#define UART0_NBITS 8\r
+//#define UART0_NBITS 9\r
+\r
+#define UART0_PARITY UART_PARTITY_NONE\r
+//#define UART0_PARITY UART_PARTITY_ODD\r
+//#define UART0_PARITY UART_PARTITY_EVEN\r
+\r
+#define UART0_STOP_BIT UART_STOP_BITS_1\r
+//#define UART0_STOP_BIT UART_STOP_BITS_2\r
+\r
+\r
+\r
+\r
+/* .... same for uart 1, 2, 3 ... */\r
+\r
+#endif\r
+\r
#include <aversive.h>
#include <aversive/wait.h>
+#include <uart.h>
+
/*
* Leds: PD5 -> PD7
* Photodiodes: PC0 PC1
#define IR_BIT 1
/* FRAME must be odd */
-#define FRAME 0x0B /* in little endian 1-1-0-1 */
-#define FRAME_LEN 4
+/* #define FRAME 0x0B /\* in little endian 1-1-0-1 *\/ */
+/* #define FRAME_LEN 4 */
+#define FRAME 0xAA5B /* in little endian */
+#define FRAME_LEN 16
/* pin returns 1 when nothing, and 0 when laser is on photodiode */
#define PHOTO_PIN PINC
/* in ms */
#define INTER_LASER_TIME 10
-#define WAIT_LASER
+#define NO_MODULATION
+//#define WAIT_LASER
/* basic functions to transmit on IR */
static inline void xmit_0(void)
{
uint8_t t = ((N_CYCLES_PERIOD * N_PERIODS) / 3);
+#ifdef NO_MODULATION
+ cbi(IR_PORT, IR_BIT);
+#else
TCCR1B = 0;
TCCR1A = 0;
+#endif
_delay_loop_1(t); /* 3 cycles per loop */
}
static inline void xmit_1(void)
{
uint8_t t = ((N_CYCLES_PERIOD * N_PERIODS) / 3);
+#ifdef NO_MODULATION
+ sbi(IR_PORT, IR_BIT);
+#else
TCCR1B = _BV(WGM13) | _BV(WGM12);
TCNT1 = N_CYCLES_PERIOD-1;
TCCR1A = _BV(COM1A1) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);
+#endif
_delay_loop_1(t); /* 3 cycles per loop */
}
/* transmit a full frame. Each byte is lsb first. */
-static void xmit_bits(uint8_t *buf, uint8_t nbit)
+static void xmit_bits(uint32_t frame, uint8_t nbit)
{
uint8_t i;
- uint8_t byte = *buf;
for (i=0; i<nbit; i++) {
- if (byte & 1)
+ if (frame & 1)
xmit_manchester_1();
else
xmit_manchester_0();
/* next bit */
- byte >>= 1;
-
- /* next byte */
- if (((i & 0x07) == 0) && (i != 0))
- byte = *(++buf);
+ frame >>= 1UL;
}
xmit_0();
}
int main(void)
{
/* must be odd */
- uint8_t frame = FRAME;
+ uint32_t frame = FRAME;
int8_t ret;
+ int16_t c;
/* LEDS */
LED_DDR = _BV(LED1_BIT) | _BV(LED2_BIT) | _BV(LED3_BIT);
IR_DDR |= _BV(IR_BIT);
+ uart_init();
+ fdevopen(uart0_dev_send, uart0_dev_recv);
+ sei();
+
#if 0
while (1) {
+ c = uart_recv_nowait(0);
+ if (c != -1)
+ printf("%c", (char)(c+1));
LED1_ON();
wait_ms(500);
LED1_OFF();
}
#endif
+#ifndef NO_MODULATION
/* configure PWM */
ICR1 = N_CYCLES_PERIOD;
OCR1A = N_CYCLES_1;
TCCR1A = _BV(COM1A1) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(WGM12);
+#endif
/* configure timer 0, prescaler = 64 */
TCCR0 = _BV(CS01) | _BV(CS00);
#if 1
LED3_ON();
/* ok, transmit frame */
- xmit_bits(&frame, FRAME_LEN);
+ xmit_bits(frame, FRAME_LEN);
/* don't watch a laser during this time */
wait_ms(INTER_LASER_TIME);