From 84796cd7a01e949167a155ec21f55fd71e788015 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 26 Jun 2014 20:41:16 +0200 Subject: [PATCH] make it compile --- .config | 294 +++++++++++++++++++++ cmdline.c | 236 +++++++++++++++++ cmdline.h | 63 +++++ commands.c | 276 +++++++++++++++++++ commands_gen.c | 382 +++++++++++++++++++++++++++ time_config.h => diagnostic_config.h | 27 +- eeprom_config.c | 157 +++++++++++ eeprom_config.h | 48 ++++ imu.c | 220 ++++++++++++--- main.c | 181 +++++++++++++ main.h | 85 ++++++ mpu6050.c | 5 +- rdline_config.h | 0 timer_config.h | 13 +- 14 files changed, 1940 insertions(+), 47 deletions(-) create mode 100644 .config create mode 100644 cmdline.c create mode 100644 cmdline.h create mode 100644 commands.c create mode 100644 commands_gen.c rename time_config.h => diagnostic_config.h (53%) create mode 100644 eeprom_config.c create mode 100644 eeprom_config.h create mode 100644 main.c create mode 100644 main.h create mode 100644 rdline_config.h diff --git a/.config b/.config new file mode 100644 index 0000000..ac313e5 --- /dev/null +++ b/.config @@ -0,0 +1,294 @@ +# +# Automatically generated make config: 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_ATTINY45 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_ATMEGA328P 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 is not set +# 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_MCU_ATXMEGA128A1 is not set +# CONFIG_MCU_ATMEGA168P is not set +CONFIG_MCU_ATMEGA1284P=y +CONFIG_QUARTZ=12000000 + +# +# 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=y +# CONFIG_FDEVOPEN_COMPAT is not set +# CONFIG_NO_PRINTF is not set +# CONFIG_MINIMAL_PRINTF is not set +# CONFIG_STANDARD_PRINTF is not set +CONFIG_ADVANCED_PRINTF=y +CONFIG_FORMAT_IHEX=y +# CONFIG_FORMAT_SREC is not set +# CONFIG_FORMAT_BINARY is not set + +# +# Base modules +# + +# +# Enable math library in generation options to see all 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_HOSTSIM 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 is not set +CONFIG_MODULE_SCHEDULER_MANUAL=y +CONFIG_MODULE_CALLOUT=y +# 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 +# + +# +# uart needs circular buffer, mf2 client may need scheduler +# +CONFIG_MODULE_UART=y +# CONFIG_MODULE_UART_9BITS is not set +# CONFIG_MODULE_UART_CREATE_CONFIG is not set +# CONFIG_MODULE_SPI is not set +# CONFIG_MODULE_SPI_CREATE_CONFIG is not set +CONFIG_MODULE_I2C=y +# 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=y +# 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 is not set +# 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 is not set +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 (fixed point lib may be needed) +# +# CONFIG_MODULE_ROBOT_SYSTEM is not set +# CONFIG_MODULE_ROBOT_SYSTEM_USE_F64 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 + +# +# Filters +# +# CONFIG_MODULE_PID is not set +# CONFIG_MODULE_PID_CREATE_CONFIG is not set +# 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 +# + +# +# Some radio devices require SPI to be activated +# +# CONFIG_MODULE_CC2420 is not set +# CONFIG_MODULE_CC2420_CREATE_CONFIG is not set +CONFIG_MODULE_XBEE=y +CONFIG_MODULE_XBEE_STATS=y +CONFIG_MODULE_XBEE_ATCMD_HELP=y + +# +# Crypto modules +# + +# +# Crypto modules depend on utils module +# +# 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 +# + +# +# Encoding modules depend on utils module +# +# CONFIG_MODULE_BASE64 is not set +# CONFIG_MODULE_HAMMING is not set + +# +# Debug modules +# + +# +# Debug modules depend on utils module +# +CONFIG_MODULE_DIAGNOSTIC=y +# CONFIG_MODULE_DIAGNOSTIC_CREATE_CONFIG is not set +CONFIG_MODULE_ERROR=y +CONFIG_MODULE_ERROR_CREATE_CONFIG=y + +# +# Programmer options +# +CONFIG_AVRDUDE=y +# CONFIG_AVARICE is not set + +# +# 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 is not set +# CONFIG_AVRDUDE_PROG_PAVR is not set +# CONFIG_AVRDUDE_PROG_BUTTERFLY is not set +# CONFIG_AVRDUDE_PROG_AVR910 is not set +# CONFIG_AVRDUDE_PROG_AVR911 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_PROG_AVRISPMKII=y +# CONFIG_AVRDUDE_PROG_ARDUINO is not set +CONFIG_AVRDUDE_PORT="usb" +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 diff --git a/cmdline.c b/cmdline.c new file mode 100644 index 0000000..91360a9 --- /dev/null +++ b/cmdline.c @@ -0,0 +1,236 @@ +/* + * Copyright Droids Corporation + * Olivier Matz + * + * 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.7 2009-11-08 17:24:33 zer0 Exp $ + * + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "callout.h" +#include "main.h" +#include "cmdline.h" + +#define FLUSH_LOGS_MS 1000 /* every second */ +#define LOG_PER_SEC_MAX 10 + +extern const parse_ctx_t PROGMEM main_ctx[]; + +static struct callout flush_log_timer; +static uint8_t log_count; + +int cmdline_dev_send(char c, FILE* f) +{ + (void)f; + uart_send(CMDLINE_UART, c); + return 0; +} + +int cmdline_dev_recv(FILE* f) +{ + int16_t c; + + (void)f; + c = uart_recv_nowait(CMDLINE_UART); + if (c < 0) + return _FDEV_EOF; + + return c; +} + + +int xbee_dev_send(char c, FILE* f) +{ + (void)f; + uart_send(XBEE_UART, c); + return 0; +} + +int xbee_dev_recv(FILE* f) +{ + int16_t c; + + (void)f; + c = uart_recv_nowait(XBEE_UART); + if (c < 0) + return _FDEV_EOF; + + return c; +} + +void cmdline_valid_buffer(const char *buf, uint8_t size) +{ + int8_t ret; + PGM_P ctx = (PGM_P)main_ctx; + + (void)size; + ret = parse(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")); +} + +static int8_t +complete_buffer(const char *buf, char *dstbuf, uint8_t dstsize, + int16_t *state) +{ + PGM_P ctx = (PGM_P)main_ctx; + return complete(ctx, buf, state, dstbuf, dstsize); +} + + +void cmdline_write_char(char c) +{ + cmdline_dev_send(c, NULL); +} + + +/* sending "pop" on cmdline uart resets the robot */ +void emergency(char c) +{ + static uint8_t i = 0; + + if ((i == 0 && c == 'p') || + (i == 1 && c == 'o') || + (i == 2 && c == 'p')) + i++; + else if ( !(i == 1 && c == 'p') ) + i = 0; + if (i == 3) { + //bootloader(); + reset(); + } +} + +/* log function, configured dynamically */ +void mylog(struct error * e, ...) +{ +#ifndef HOST_VERSION + u16 stream_flags = stdout->flags; +#endif + va_list ap; + uint8_t i, flags; + uint32_t ms; + uint8_t prio; + + /* too many logs */ + if (log_count >= LOG_PER_SEC_MAX) + return; + + /* higher log value means lower criticity */ + if (e->severity > ERROR_SEVERITY_ERROR) { + if (imuboard.log_level < e->severity) + return; + + for (i=0; ierr_num) + break; + if (i == NB_LOGS+1) + return; + } + + /* get time */ + IRQ_LOCK(flags); + ms = global_ms; + IRQ_UNLOCK(flags); + + /* prevent flush log to occur */ + prio = callout_mgr_set_prio(&imuboard.intr_cm, + LOW_PRIO); + + /* display the log */ + va_start(ap, e); + printf_P(PSTR("%d.%.3d: "), (int)(ms/1000UL), (int)(ms%1000UL)); + vfprintf_P(stdout, e->text, ap); + printf_P(PSTR("\r\n")); + va_end(ap); + +#ifndef HOST_VERSION + stdout->flags = stream_flags; +#endif + callout_mgr_restore_prio(&imuboard.intr_cm, prio); +} + +static void flush_logs_cb(struct callout_mgr *cm, struct callout *tim, + void *arg) +{ + (void)cm; + (void)tim; + (void)arg; + + if (log_count == LOG_PER_SEC_MAX) + printf_P("some logs were dropped\n"); + callout_reschedule(&imuboard.intr_cm, &flush_log_timer, + FLUSH_LOGS_MS); +} + + +int cmdline_poll(void) +{ + const char *history, *buffer; + int8_t ret, same = 0; + int16_t c; + + c = cmdline_dev_recv(NULL); + if (c < 0) + return -1; + + ret = rdline_char_in(&imuboard.rdl, c); + if (ret == 1) { + buffer = rdline_get_buffer(&imuboard.rdl); + history = rdline_get_history_item(&imuboard.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(&imuboard.rdl, buffer); + + if (imuboard.rdl.status != RDLINE_STOPPED) + rdline_newline(&imuboard.rdl, imuboard.prompt); + } + + return 0; +} + +void cmdline_init(void) +{ + /* init command line */ + rdline_init(&imuboard.rdl, cmdline_write_char, cmdline_valid_buffer, + complete_buffer); + snprintf_P(imuboard.prompt, sizeof(imuboard.prompt), + PSTR("imu > ")); + + /* load a timer for flushing logs */ + callout_init(&flush_log_timer, flush_logs_cb, NULL, LOW_PRIO); + callout_schedule(&imuboard.intr_cm, &flush_log_timer, FLUSH_LOGS_MS); +} diff --git a/cmdline.h b/cmdline.h new file mode 100644 index 0000000..034244a --- /dev/null +++ b/cmdline.h @@ -0,0 +1,63 @@ +/* + * Copyright Droids Corporation + * Olivier Matz + * + * 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.4 2009-11-08 17:24:33 zer0 Exp $ + * + */ + +#ifndef _CMDLINE_H_ +#define _CMDLINE_H_ + +#define CMDLINE_UART 1 +#define XBEE_UART 0 + +void cmdline_init(void); + +/* uart rx callback for reset() */ +void emergency(char c); + +/* log function */ +void mylog(struct error * e, ...); + +/* poll cmdline */ +int cmdline_poll(void); + +int cmdline_dev_send(char c, FILE* f); +int cmdline_dev_recv(FILE* f); +void cmdline_write_char(char c); +void cmdline_valid_buffer(const char *buf, uint8_t size); + +int xbee_dev_send(char c, FILE* f); +int xbee_dev_recv(FILE* f); + +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); +} + +#endif /* _CMDLINE_H_ */ diff --git a/commands.c b/commands.c new file mode 100644 index 0000000..42d243f --- /dev/null +++ b/commands.c @@ -0,0 +1,276 @@ +/* + * Copyright Droids Corporation (2011) + * + * 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.9 2009-11-08 17:24:33 zer0 Exp $ + * + * Olivier MATZ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.h" +#include "cmdline.h" +#include "eeprom_config.h" + +/* commands_gen.c */ +extern const parse_inst_t PROGMEM cmd_reset; +extern const parse_inst_t PROGMEM cmd_bootloader; +extern const parse_inst_t PROGMEM cmd_log; +extern const parse_inst_t PROGMEM cmd_log_show; +extern const parse_inst_t PROGMEM cmd_log_type; +extern const parse_inst_t PROGMEM cmd_stack_space; +extern const parse_inst_t PROGMEM cmd_callout; + +/**********************************************************/ + +/* this structure is filled when cmd_test_eeprom_config is parsed successfully */ +struct cmd_test_eeprom_config_result { + fixed_string_t arg0; +}; + +static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data) +{ + (void)parsed_result; + (void)data; + + eeprom_dump_cmds(); + eeprom_append_cmd("salut1\n"); + eeprom_dump_cmds(); + eeprom_append_cmd("salut2\n"); + eeprom_append_cmd("salut3\n"); + eeprom_append_cmd("salut4\n"); + eeprom_dump_cmds(); + eeprom_insert_cmd_before("coin\n", 0); + eeprom_insert_cmd_before("coin2\n", 2); + eeprom_dump_cmds(); + eeprom_delete_cmd(2); + eeprom_delete_cmd(0); + eeprom_dump_cmds(); +} + +const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config"; +const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 = + TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0, + str_test_eeprom_config_arg0); + +const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration"; +const parse_inst_t PROGMEM cmd_test_eeprom_config = { + .f = cmd_test_eeprom_config_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_test_eeprom_config, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_test_eeprom_config_arg0, + NULL, + }, +}; + +/* ************* */ + +struct cmd_eeprom_del_result { + fixed_string_t cmd; + fixed_string_t action; + uint8_t n; +}; + +static void cmd_eeprom_del_parsed(void *parsed_result, + void *data) +{ + struct cmd_eeprom_del_result *res = parsed_result; + + (void)data; + if (eeprom_delete_cmd(res->n) < 0) + printf_P(PSTR("cannot delete command\n")); + eeprom_dump_cmds(); +} + +const char PROGMEM str_eeprom_del_eeprom[] = "eeprom"; +const parse_token_string_t PROGMEM cmd_eeprom_del_cmd = + TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd, + str_eeprom_del_eeprom); +const char PROGMEM str_eeprom_del_del[] = "del"; +const parse_token_string_t PROGMEM cmd_eeprom_del_action = + TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action, + str_eeprom_del_del); +const parse_token_num_t PROGMEM cmd_eeprom_del_num = + TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n, + UINT8); + +const char PROGMEM help_eeprom_del[] = "delete an eeprom init command"; +const parse_inst_t PROGMEM cmd_eeprom_del = { + .f = cmd_eeprom_del_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_eeprom_del, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_eeprom_del_cmd, + (PGM_P)&cmd_eeprom_del_action, + (PGM_P)&cmd_eeprom_del_num, + NULL, + }, +}; + +/* ************* */ + +struct cmd_eeprom_add_result { + fixed_string_t cmd; + fixed_string_t action; + uint8_t n; +}; + +static void cmd_eeprom_add_parsed(void *parsed_result, + void *data) +{ + struct cmd_eeprom_add_result *res = parsed_result; + struct rdline rdl; + const char *buffer; + int8_t ret; + int16_t c; + + rdline_init(&rdl, cmdline_write_char, NULL, NULL); + rdline_newline(&rdl, "> "); + + while (1) { + c = cmdline_dev_recv(NULL); + if (c < 0) + continue; + + ret = rdline_char_in(&rdl, c); + if (ret == -2) { + printf_P(PSTR("abort\n")); + return; + } + if (ret == 1) + break; + } + + buffer = rdline_get_buffer(&rdl); + if (data == NULL) + eeprom_insert_cmd_before(buffer, res->n); + else + eeprom_append_cmd(buffer); + eeprom_dump_cmds(); +} + +const char PROGMEM str_eeprom_add_eeprom[] = "eeprom"; +const parse_token_string_t PROGMEM cmd_eeprom_add_cmd = + TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd, + str_eeprom_add_eeprom); +const char PROGMEM str_eeprom_add_add[] = "add"; +const parse_token_string_t PROGMEM cmd_eeprom_add_action = + TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action, + str_eeprom_add_add); +const parse_token_num_t PROGMEM cmd_eeprom_add_num = + TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n, + UINT8); + +const char PROGMEM help_eeprom_add[] = "insert an eeprom init command"; +const parse_inst_t PROGMEM cmd_eeprom_add = { + .f = cmd_eeprom_add_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_eeprom_add, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_eeprom_add_cmd, + (PGM_P)&cmd_eeprom_add_action, + (PGM_P)&cmd_eeprom_add_num, + NULL, + }, +}; + +const char PROGMEM help_eeprom_add2[] = "append an eeprom init command"; +const parse_inst_t PROGMEM cmd_eeprom_add2 = { + .f = cmd_eeprom_add_parsed, /* function to call */ + .data = (void *)1, /* 2nd arg of func */ + .help_str = help_eeprom_add2, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_eeprom_add_cmd, + (PGM_P)&cmd_eeprom_add_action, + NULL, + }, +}; + +/* ************* */ + +struct cmd_eeprom_list_result { + fixed_string_t cmd; + fixed_string_t action; +}; + +static void cmd_eeprom_list_parsed(void *parsed_result, + void *data) +{ + (void)parsed_result; + (void)data; + eeprom_dump_cmds(); +} + +const char PROGMEM str_eeprom_list_eeprom[] = "eeprom"; +const parse_token_string_t PROGMEM cmd_eeprom_list_cmd = + TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd, + str_eeprom_list_eeprom); +const char PROGMEM str_eeprom_list_list[] = "list"; +const parse_token_string_t PROGMEM cmd_eeprom_list_action = + TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action, + str_eeprom_list_list); + +const char PROGMEM help_eeprom_list[] = "list all eeprom init commands"; +const parse_inst_t PROGMEM cmd_eeprom_list = { + .f = cmd_eeprom_list_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_eeprom_list, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_eeprom_list_cmd, + (PGM_P)&cmd_eeprom_list_action, + NULL, + }, +}; + + +/* ************* */ + +/* in progmem */ +const parse_ctx_t PROGMEM main_ctx[] = { + + /* commands_gen.c */ + &cmd_reset, + &cmd_bootloader, + &cmd_log, + &cmd_log_show, + &cmd_log_type, + &cmd_stack_space, + &cmd_callout, + &cmd_test_eeprom_config, + &cmd_eeprom_del, + &cmd_eeprom_add, + &cmd_eeprom_add2, + &cmd_eeprom_list, + NULL, +}; diff --git a/commands_gen.c b/commands_gen.c new file mode 100644 index 0000000..f49ef9a --- /dev/null +++ b/commands_gen.c @@ -0,0 +1,382 @@ +/* + * Copyright Droids Corporation (2011) + * + * 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_gen.c,v 1.8 2009-11-08 17:24:33 zer0 Exp $ + * + * Olivier MATZ + */ + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include "callout.h" +#include "main.h" +#include "cmdline.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(void * parsed_result, void * data) +{ + (void)parsed_result; + (void)data; +#ifdef HOST_VERSION + hostsim_exit(); +#endif + reset(); +} + +const char PROGMEM str_reset_arg0[] = "reset"; +const parse_token_string_t PROGMEM cmd_reset_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_reset_result, arg0, str_reset_arg0); + +const char PROGMEM help_reset[] = "Reset the board"; +const parse_inst_t PROGMEM cmd_reset = { + .f = cmd_reset_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_reset, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_reset_arg0, + NULL, + }, +}; + +/**********************************************************/ +/* Bootloader */ + +/* this structure is filled when cmd_bootloader is parsed successfully */ +struct cmd_bootloader_result { + fixed_string_t arg0; +}; + +/* function called when cmd_bootloader is parsed successfully */ +static void cmd_bootloader_parsed(void *parsed_result, void *data) +{ + (void)parsed_result; + (void)data; +#ifndef HOST_VERSION + bootloader(); +#else + printf("not implemented\n"); +#endif +} + +const char PROGMEM str_bootloader_arg0[] = "bootloader"; +const parse_token_string_t PROGMEM cmd_bootloader_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_bootloader_result, arg0, str_bootloader_arg0); + +const char PROGMEM help_bootloader[] = "Launch the bootloader"; +const parse_inst_t PROGMEM cmd_bootloader = { + .f = cmd_bootloader_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_bootloader, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_bootloader_arg0, + NULL, + }, +}; + +/**********************************************************/ +/* Callout show */ + +/* this structure is filled when cmd_callout is parsed successfully */ +struct cmd_callout_result { + fixed_string_t arg0; + fixed_string_t arg1; +}; + +/* function called when cmd_callout is parsed successfully */ +static void cmd_callout_parsed(void *parsed_result, void *data) +{ + (void)parsed_result; + (void)data; + callout_dump_stats(&imuboard.intr_cm); +} + +const char PROGMEM str_callout_arg0[] = "callout"; +const parse_token_string_t PROGMEM cmd_callout_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_callout_result, arg0, str_callout_arg0); +const char PROGMEM str_callout_arg1[] = "show"; +const parse_token_string_t PROGMEM cmd_callout_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_callout_result, arg1, str_callout_arg1); + +const char PROGMEM help_callout[] = "Show callout events"; +const parse_inst_t PROGMEM cmd_callout = { + .f = cmd_callout_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_callout, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_callout_arg0, + (PGM_P)&cmd_callout_arg1, + NULL, + }, +}; + +/**********************************************************/ +/* Log */ + +/* this structure is filled when cmd_log is parsed successfully */ +struct cmd_log_result { + fixed_string_t arg0; + fixed_string_t arg1; + uint8_t arg2; + fixed_string_t arg3; +}; + +/* keep it sync with string choice */ +static const char PROGMEM uart_log[] = "uart"; +static const char PROGMEM i2c_log[] = "i2c"; +static const char PROGMEM default_log[] = "default"; +static const char PROGMEM xbee_log[] = "xbee"; +static const char PROGMEM rc_proto_log[] = "rc_proto"; + +struct log_name_and_num { + const char *name; + uint8_t num; +}; + +static const struct log_name_and_num log_name_and_num[] = { + { uart_log, E_UART }, + { i2c_log, E_I2C }, + { default_log, E_USER_DEFAULT }, + { xbee_log, E_USER_XBEE }, + { rc_proto_log, E_USER_RC_PROTO }, +}; + +static uint8_t +log_name2num(const char * s) +{ + uint8_t i; + + for (i=0; iarg1, PSTR("level"))) { + imuboard.log_level = res->arg2; + } + + /* else it is a show */ + cmd_log_do_show(); +} + +const char PROGMEM str_log_arg0[] = "log"; +const parse_token_string_t PROGMEM cmd_log_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_log_result, arg0, str_log_arg0); +const char PROGMEM str_log_arg1[] = "level"; +const parse_token_string_t PROGMEM cmd_log_arg1 = TOKEN_STRING_INITIALIZER(struct cmd_log_result, arg1, str_log_arg1); +const parse_token_num_t PROGMEM cmd_log_arg2 = TOKEN_NUM_INITIALIZER(struct cmd_log_result, arg2, INT8); + +const char PROGMEM help_log[] = "Set log options: level (0 -> 5)"; +const parse_inst_t PROGMEM cmd_log = { + .f = cmd_log_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_log, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_log_arg0, + (PGM_P)&cmd_log_arg1, + (PGM_P)&cmd_log_arg2, + NULL, + }, +}; + +const char PROGMEM str_log_arg1_show[] = "show"; +const parse_token_string_t PROGMEM cmd_log_arg1_show = TOKEN_STRING_INITIALIZER(struct cmd_log_result, arg1, str_log_arg1_show); + +const char PROGMEM help_log_show[] = "Show configured logs"; +const parse_inst_t PROGMEM cmd_log_show = { + .f = cmd_log_parsed, /* function to call */ + .data = NULL, /* 2nd arg of func */ + .help_str = help_log_show, + .tokens = { /* token list, NULL terminated */ + (PGM_P)&cmd_log_arg0, + (PGM_P)&cmd_log_arg1_show, + NULL, + }, +}; + +/* this structure is filled when cmd_log is parsed successfully */ +struct cmd_log_type_result { + fixed_string_t arg0; + fixed_string_t arg1; + fixed_string_t arg2; + fixed_string_t arg3; +}; + +/* function called when cmd_log is parsed successfully */ +static void cmd_log_type_parsed(void * parsed_result, void *data) +{ + struct cmd_log_type_result *res = (struct cmd_log_type_result *) parsed_result; + uint8_t lognum; + uint8_t i; + + (void)data; + + lognum = log_name2num(res->arg2); + if (lognum == 0) { + printf_P(PSTR("Cannot find log num\r\n")); + return; + } + + if (!strcmp_P(res->arg3, PSTR("on"))) { + for (i=0; iarg3, PSTR("off"))) { + for (i=0; i + * + * 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 +#include +#include + +#include +#include +#include + +#include + + +#include "cmdline.h" +#include "eeprom_config.h" + +/* load configuration from eeprom */ +int8_t eeprom_load_config(void) +{ + struct eeprom_config *e = NULL; + struct eeprom_cmd cmd; + uint32_t magic; + uint8_t i, max; + + eeprom_read_block(&magic, &e->magic, sizeof(magic)); + if (magic != EEPROM_CONFIG_MAGIC) { + printf_P(PSTR("no EEPROM config\n")); + eeprom_set_ncmds(0); + return 0; + } + + max = eeprom_get_ncmds(); + for (i = 0; i < max; i++) { + eeprom_get_cmd(&cmd, i); + printf_P(PSTR("%s"), cmd.buf); + cmdline_valid_buffer(cmd.buf, strlen(cmd.buf)); + } + + return -1; +} + +uint8_t eeprom_get_ncmds(void) +{ + struct eeprom_config *e = NULL; + uint8_t ncmds; + + eeprom_read_block(&ncmds, &e->ncmds, sizeof(ncmds)); + return ncmds; +} + +void eeprom_set_ncmds(uint8_t ncmds) +{ + struct eeprom_config *e = NULL; + uint32_t magic = EEPROM_CONFIG_MAGIC; + eeprom_update_block(&ncmds, &e->ncmds, sizeof(ncmds)); + eeprom_update_block(&magic, &e->magic, sizeof(magic)); +} + +/* fill cmd struct with the n-th command from eeprom, no check is done + * on index or size. The \0 is added at the end of the string. */ +void eeprom_get_cmd(struct eeprom_cmd *cmd, uint8_t n) +{ + struct eeprom_config *e = NULL; + + eeprom_read_block(cmd, &e->cmds[n], sizeof(*cmd)); + cmd->buf[EEPROM_CMD_SIZE-1] = '\0'; +} + +/* fill n-th command of eeprom from struct, no check is done on index + * or size */ +void eeprom_set_cmd(struct eeprom_cmd *cmd, uint8_t n) +{ + struct eeprom_config *e = NULL; + + eeprom_update_block(cmd, &e->cmds[n], sizeof(*cmd)); +} + +void eeprom_dump_cmds(void) +{ + uint8_t i, max; + struct eeprom_cmd cmd; + + printf_P(PSTR("init commands:\n")); + max = eeprom_get_ncmds(); + for (i = 0; i < max; i++) { + eeprom_get_cmd(&cmd, i); + printf_P(PSTR("%.2d: %s"), i, cmd.buf); + } +} + +int8_t eeprom_insert_cmd_before(const char *str, uint8_t n) +{ + uint8_t i, max; + struct eeprom_cmd cmd; + + if (strlen(str) >= EEPROM_CMD_SIZE) + return -1; + + max = eeprom_get_ncmds(); + if (n > max) + return -1; + if (max >= EEPROM_N_CMD_MAX) + return -1; + + for (i = max; i > n; i--) { + eeprom_get_cmd(&cmd, i-1); + eeprom_set_cmd(&cmd, i); + } + + snprintf(cmd.buf, sizeof(cmd.buf), "%s", str); + eeprom_set_cmd(&cmd, n); + eeprom_set_ncmds(max + 1); + return 0; +} + +int8_t eeprom_append_cmd(const char *str) +{ + uint8_t max; + + max = eeprom_get_ncmds(); + return eeprom_insert_cmd_before(str, max); +} + +int8_t eeprom_delete_cmd(uint8_t n) +{ + uint8_t i, max; + struct eeprom_cmd cmd; + + max = eeprom_get_ncmds(); + if (n >= max) + return -1; + + for (i = n; i < max-1; i++) { + eeprom_get_cmd(&cmd, i+1); + eeprom_set_cmd(&cmd, i); + } + + eeprom_set_ncmds(max - 1); + return 0; +} diff --git a/eeprom_config.h b/eeprom_config.h new file mode 100644 index 0000000..7aff867 --- /dev/null +++ b/eeprom_config.h @@ -0,0 +1,48 @@ +/* + * Copyright 2013 Olivier Matz + * + * 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 _EEPROM_CONFIG_H_ +#define _EEPROM_CONFIG_H_ + +#define EEPROM_CONFIG_MAGIC 0x666bea57 +#define EEPROM_CMD_SIZE 64 +#define EEPROM_N_CMD_MAX 16 + +struct eeprom_cmd { + char buf[EEPROM_CMD_SIZE]; +}; + +struct eeprom_config +{ + uint32_t magic; + uint8_t ncmds; + struct eeprom_cmd cmds[EEPROM_N_CMD_MAX]; +}; + +int8_t eeprom_load_config(void); +uint8_t eeprom_get_ncmds(void); +void eeprom_set_ncmds(uint8_t ncmds); +void eeprom_get_cmd(struct eeprom_cmd *cmd, uint8_t n); +void eeprom_set_cmd(struct eeprom_cmd *cmd, uint8_t n); +void eeprom_dump_cmds(void); +int8_t eeprom_insert_cmd_before(const char *str, uint8_t n); +int8_t eeprom_append_cmd(const char *str); +int8_t eeprom_delete_cmd(uint8_t n); + +#endif diff --git a/imu.c b/imu.c index efaba62..72bdd74 100644 --- a/imu.c +++ b/imu.c @@ -1,10 +1,9 @@ #include #include -#include -#include - +#include #include +#include #include @@ -19,6 +18,7 @@ //#include "itg3200.h" //#include "ak8500.h" +#include "main.h" #include "mpu6050.h" #include "vector.h" @@ -27,7 +27,23 @@ #include "MadgwickAHRS.h" -#define LED_PRIO 170 + +#include +#include +#include +#include "fat.h" +#include "fat_config.h" +#include "partition.h" +#include "sd_raw.h" +#include "sd_raw_config.h" + +#include +#include +#include +#include "cmdline.h" + + +//#define LED_PRIO 170 #define GYRO_PRIO 100 int internal_mag_x; @@ -39,7 +55,6 @@ int mag_y; int mag_z; -void i2c_recvevent(uint8_t * buf, int8_t size) void i2c_recvevent(uint8_t *buf, int8_t size) { (void)buf; @@ -51,7 +66,7 @@ void i2c_sendevent(int8_t size) (void)size; } - +#if 0 static void main_timer_interrupt(void) { static uint8_t cpt = 0; @@ -60,7 +75,7 @@ static void main_timer_interrupt(void) if ((cpt & 0x3) == 0) scheduler_interrupt(); } - +#endif #define LED1_TOGGLE() PORTB ^= 0x20; @@ -81,6 +96,31 @@ void do_led_blink(void *dummy) } +static uint8_t find_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name, struct fat_dir_entry_struct* dir_entry) +{ + (void)fs; + + while(fat_read_dir(dd, dir_entry)) + { + if(strcmp(dir_entry->long_name, name) == 0) + { + fat_reset_dir(dd); + return 1; + } + } + + return 0; +} + +static struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name) +{ + struct fat_dir_entry_struct file_entry; + if(!find_file_in_dir(fs, dd, name, &file_entry)) + return 0; + + return fat_open_file(fs, &file_entry); +} + /* for i2c */ @@ -288,58 +328,122 @@ void quaternion2euler(void) yaw = atan2f(2.0f * (q1 * q2 + q0 * q3), q0*q0 + q1*q1 - q2*q2 - q3*q3); } -#define swap_u16(a) (((a>>8)&0xff) | (((a&0xFF)<<8))) -int main(void) +static struct fat_file_struct *open_log_file(void) { - int16_t temp; - //uint8_t err; - uint16_t * ptr; - uint8_t a; - int i; - - - int16_t mpu6050_axes[10]; - - /* UART */ - uart_init(); - - fdevopen(uart0_dev_send, uart0_dev_recv); + struct fat_file_struct *fd; + struct fat_fs_struct *fs; + struct partition_struct *partition ; + struct fat_dir_struct *dd; + struct fat_dir_entry_struct directory; + struct fat_dir_entry_struct file_entry; + int16_t i = 0; + char name[16]; + + /* setup sd card slot */ + if (!sd_raw_init()) { +#if SD_DEBUG + printf_P(PSTR("MMC/SD initialization failed\n")); +#endif + return NULL; + } -#if 0 - i2c_init(I2C_MODE_MASTER, 1/* I2C_MAIN_ADDR */); - i2c_register_recv_event(i2c_recvevent); - i2c_register_send_event(i2c_sendevent); + /* open first partition */ + partition = partition_open(sd_raw_read, + sd_raw_read_interval, +#if SD_RAW_WRITE_SUPPORT + sd_raw_write, sd_raw_write_interval, #else - - i2cm_NUM_init(); + 0, 0, +#endif + 0); + + if (!partition) { + /* If the partition did not open, assume the storage device + * is a "superfloppy", i.e. has no MBR. + */ + partition = partition_open(sd_raw_read, + sd_raw_read_interval, +#if SD_RAW_WRITE_SUPPORT + sd_raw_write, + sd_raw_write_interval, +#else + 0, + 0, +#endif + -1); + if (!partition) { +#if SD_DEBUG + printf_P(PSTR("opening partition failed\n")); #endif + return NULL; + } + } + /* open file system */ + fs = fat_open(partition); + if (!fs) { +#if SD_DEBUG + printf_P(PSTR("opening filesystem failed\n")); +#endif + return NULL; + } + /* open root directory */ + fat_get_dir_entry_of_path(fs, "/", &directory); + dd = fat_open_dir(fs, &directory); + if (!dd) { +#if SD_DEBUG + printf_P(PSTR("opening root directory failed\n")); +#endif + return NULL; + } - // LED output - DDRB |= 0x20; + /* print some card information as a boot message */ + //print_disk_info(fs); + printf("choose log file name\n"); + while (1) { + snprintf(name, sizeof(name), "log%.4d", i++); + if (!find_file_in_dir(fs, dd, name, &file_entry)) + break; + } - /* TIMER */ - timer_init(); - timer0_register_OV_intr(main_timer_interrupt); + printf("create log file %s\n", name); + if (!fat_create_file(dd, name, &file_entry)) { + printf_P(PSTR("error creating file: ")); + } + fd = open_file_in_dir(fs, dd, name); + if (!fd) { + printf_P(PSTR("error opening ")); + return NULL; + } - /* SCHEDULER */ - scheduler_init(); + return fd; +} +#define swap_u16(a) (((a>>8)&0xff) | (((a&0xFF)<<8))) +int imu_loop(void) +{ + //int16_t temp; + //uint8_t err; + //uint16_t * ptr; + //uint8_t a; + //int i; - sei(); + struct fat_file_struct *fd = NULL; + int16_t mpu6050_axes[10]; + char buf[128]; + int16_t len; + uint32_t ms; + uint8_t flags; /* bma150_init(); itg3200_init(); ak8975_read_sensitivity(); */ - scheduler_add_periodical_event_priority(do_led_blink, NULL, - 1000000L / SCHEDULER_UNIT, - LED_PRIO); /* scheduler_add_periodical_event_priority(update_gyro, NULL, 1000000L / SCHEDULER_UNIT, @@ -347,9 +451,14 @@ int main(void) */ mpu6050_init(); - Mad_f32_init(); + if (1) { + fd = open_log_file(); + if (fd == NULL) + printf("open log failed\r\n"); + } while (1) { + counter ++; mpu6050_read_all_axes(mpu6050_axes); /* @@ -393,7 +502,36 @@ int main(void) mpu6050_axes[8] = swap_u16(mpu6050_axes[8]); mpu6050_axes[9] = swap_u16(mpu6050_axes[9]); */ - printf("%+3.3f\t%+3.3f\t%+3.3f\r\n", roll, pitch, yaw); + //printf("%+3.3f\t%+3.3f\t%+3.3f\r\n", roll, pitch, yaw); + + IRQ_LOCK(flags); + ms = global_ms; + IRQ_UNLOCK(flags); + + if (fd != NULL) { + len = snprintf(buf, sizeof(buf), + "%"PRIu32"\t" + "gyro %+3.3f\t%+3.3f\t%+3.3f\t\t" + "accel %+3.3f\t%+3.3f\t%+3.3f\t\t" + "magnet %+3.3f\t%+3.3f\t%+3.3f\r\n", + ms, + mpu6050_gx, mpu6050_gy, mpu6050_gz, + mpu6050_ax, mpu6050_ay, mpu6050_az, + mpu6050_mx, mpu6050_my, mpu6050_mz); + if (fat_write_file(fd, (unsigned char *)buf, len) != len) { + printf_P(PSTR("error writing to file\n")); + return -1; + } + } + + printf("%"PRIu32"\t", ms); + printf("gyro %+3.3f\t%+3.3f\t%+3.3f\t\t", + mpu6050_gx, mpu6050_gy, mpu6050_gz); + printf("accel %+3.3f\t%+3.3f\t%+3.3f\t\t", + mpu6050_ax, mpu6050_ay, mpu6050_az); + printf("magnet %+3.3f\t%+3.3f\t%+3.3f\r\n", + mpu6050_mx, mpu6050_my, mpu6050_mz); + //printf("%+.4d %+.4d %+.4d\r\n", mpu6050_axes[7], mpu6050_axes[8], mpu6050_axes[9]); //printf("%+3.3f\r\n", mpu6050_temp);//, mpu6050_axes[9]); //printf("%+3.3f\t%+3.3f\t%+3.3f\r\n", mpu6050_mx, mpu6050_my, mpu6050_mz ); diff --git a/main.c b/main.c new file mode 100644 index 0000000..91ee7b7 --- /dev/null +++ b/main.c @@ -0,0 +1,181 @@ +/* + * 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. + */ + +/* fuses: + * avrdude -p atmega1284p -P usb -c avrispmkii -U lfuse:w:0xff:m -U hfuse:w:0x91:m -U efuse:w:0xff:m + * -> it failed but I answered y, then make reset and it was ok + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "eeprom_config.h" +#include "main.h" + +struct imuboard imuboard; +volatile uint32_t global_ms; + +/* global xbee device */ +struct xbee_dev *xbee_dev; + +void bootloader(void) +{ +#define BOOTLOADER_ADDR 0x3f000 + if (pgm_read_byte_far(BOOTLOADER_ADDR) == 0xff) { + printf_P(PSTR("Bootloader is not present\r\n")); + return; + } + cli(); + /* ... very specific :( */ + TIMSK0 = 0; + TIMSK1 = 0; + TIMSK2 = 0; + TIMSK3 = 0; + EIMSK = 0; + UCSR0B = 0; + UCSR1B = 0; + SPCR = 0; + TWCR = 0; + ACSR = 0; + ADCSRA = 0; + + /* XXX */ + /* __asm__ __volatile__ ("ldi r31,0xf8\n"); */ + /* __asm__ __volatile__ ("ldi r30,0x00\n"); */ + /* __asm__ __volatile__ ("eijmp\n"); */ +} + +/* return time in milliseconds on unsigned 16 bits */ +uint16_t get_time_ms(void) +{ + uint16_t ms; + uint8_t flags; + IRQ_LOCK(flags); + ms = global_ms; + IRQ_UNLOCK(flags); + return ms; +} + +static void main_timer_interrupt(void) +{ + static uint16_t cycles; + static uint8_t stack = 0; + static uint8_t cpt = 0; + cpt++; + + /* LED blink */ + if (global_ms & 0x80) + LED1_ON(); + else + LED1_OFF(); + + if ((cpt & 0x03) != 0) + return; + + /* the following code is only called one interrupt among 4: every 682us + * (at 12 Mhz) = 8192 cycles */ + cycles += 8192; + if (cycles >= 12000) { + cycles -= 12000; + global_ms ++; + } + + /* called */ + if (stack++ == 0) + LED2_ON(); + sei(); + if ((cpt & 0x3) == 0) + callout_manage(&imuboard.intr_cm); + cli(); + if (--stack == 0) + LED2_OFF(); +} + +/* XXX */ +int imu_loop(void); +int sd_main(void); + +int main(void) +{ + DDRB = 0x18 /* LEDs */; + + uart_init(); + uart_register_rx_event(CMDLINE_UART, emergency); + + fdevopen(cmdline_dev_send, cmdline_dev_recv); + timer_init(); + timer0_register_OV_intr(main_timer_interrupt); + + callout_mgr_init(&imuboard.intr_cm, get_time_ms); + + cmdline_init(); + /* LOGS */ + error_register_emerg(mylog); + error_register_error(mylog); + error_register_warning(mylog); + error_register_notice(mylog); + error_register_debug(mylog); + + /* communication with mpu6050 */ + i2cm_init(); + + sei(); + + eeprom_load_config(); + + printf_P(PSTR("\r\n")); + rdline_newline(&imuboard.rdl, imuboard.prompt); + + //sd_main(); + + imu_loop(); + + while (1) { + cmdline_poll(); + } + + return 0; +} diff --git a/main.h b/main.h new file mode 100644 index 0000000..ed8f435 --- /dev/null +++ b/main.h @@ -0,0 +1,85 @@ +/* + * 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. + */ + +#ifndef _MAIN_H_ +#define _MAIN_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "cmdline.h" + +#define NB_LOGS 4 + +/** ERROR NUMS */ +#define E_USER_DEFAULT 194 +#define E_USER_XBEE 195 +#define E_USER_RC_PROTO 196 + +#define LED1_ON() sbi(PORTB, 3) +#define LED1_OFF() cbi(PORTB, 3) + +#define LED2_ON() sbi(PORTB, 4) +#define LED2_OFF() cbi(PORTB, 4) + +/* highest priority */ +#define LED_PRIO 160 +#define TIME_PRIO 140 +#define LOW_PRIO 60 +/* lowest priority */ + +#define MAX_POWER_LEVEL 5 +/* generic to all boards */ +struct imuboard { + /* command line interface */ + struct rdline rdl; + char prompt[RDLINE_PROMPT_SIZE]; + + struct callout_mgr intr_cm; + + /* log */ + uint8_t logs[NB_LOGS+1]; + uint8_t log_level; + uint8_t debug; +}; +extern struct imuboard imuboard; + +extern volatile uint32_t global_ms; + +void bootloader(void); +uint16_t get_time_ms(void); + +#endif /* _MAIN_H_ */ diff --git a/mpu6050.c b/mpu6050.c index fe53992..4dda84b 100644 --- a/mpu6050.c +++ b/mpu6050.c @@ -1,10 +1,11 @@ #include #include -#include #include #include +#include + #include #include @@ -157,7 +158,7 @@ void mpu6050_compute_drift(void) s_gx = s_gy = s_gz = 0; for (i = 0; i < 0x100; i ++) { - mpu6050_read_gyro_raw(&g_values); + mpu6050_read_gyro_raw(g_values); s_gx += g_values[0]; s_gy += g_values[1]; s_gz += g_values[2]; diff --git a/rdline_config.h b/rdline_config.h new file mode 100644 index 0000000..e69de29 diff --git a/timer_config.h b/timer_config.h index 986a7f5..47d9f18 100644 --- a/timer_config.h +++ b/timer_config.h @@ -15,11 +15,22 @@ * 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: timer_config.h,v 1.1.2.1 2007-12-06 08:58:00 zer0 Exp $ + * Revision : $Id: timer_config.h,v 1.1 2009-02-20 21:10:01 zer0 Exp $ * */ #define TIMER0_ENABLED +/* #define TIMER1_ENABLED */ +/* #define TIMER1A_ENABLED */ +/* #define TIMER1B_ENABLED */ +/* #define TIMER1C_ENABLED */ + +/* #define TIMER2_ENABLED */ + +/* #define TIMER3_ENABLED */ +/* #define TIMER3A_ENABLED */ +/* #define TIMER3B_ENABLED */ +/* #define TIMER3C_ENABLED */ #define TIMER0_PRESCALER_DIV 8 -- 2.20.1