X-Git-Url: http://git.droids-corp.org/?p=protos%2Fimu.git;a=blobdiff_plain;f=main.c;h=91ee7b709392ed9a66a08302c2274a1253b15373;hp=47298d41e8588202a4545e459f84d71d047fcdc1;hb=fca0b2912944620636daaf2bd4f9fbf66c992ef1;hpb=b1352af6f340a1b878d46ed15b51d30eb3d3c36a diff --git a/main.c b/main.c index 47298d4..91ee7b7 100644 --- a/main.c +++ b/main.c @@ -1,666 +1,181 @@ - /* - * Copyright (c) 2006-2012 by Roland Riegel - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. + * 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 "fat.h" -#include "fat_config.h" -#include "partition.h" -#include "sd_raw.h" -#include "sd_raw_config.h" -#include "uart.h" - -#define DEBUG 1 - -/** - * \mainpage MMC/SD/SDHC card library - * - * This project provides a general purpose library which implements read and write - * support for MMC, SD and SDHC memory cards. - * - * It includes - * - low-level \link sd_raw MMC, SD and SDHC read/write routines \endlink - * - \link partition partition table support \endlink - * - a simple \link fat FAT16/FAT32 read/write implementation \endlink - * - * \section circuit The circuit - * The circuit which was mainly used during development consists of an Atmel AVR - * microcontroller with some passive components. It is quite simple and provides - * an easy test environment. The circuit which can be downloaded on the - * project homepage has been - * improved with regard to operation stability. - * - * I used different microcontrollers during development, the ATmega8 with 8kBytes - * of flash, and its pin-compatible alternative, the ATmega168 with 16kBytes flash. - * The first one is the one I started with, but when I implemented FAT16 write - * support, I ran out of flash space and switched to the ATmega168. For FAT32, an - * ATmega328 is required. - * - * The circuit board is a self-made and self-soldered board consisting of a single - * copper layer and standard DIL components, except of the MMC/SD card connector. - * - * The connector is soldered to the bottom side of the board. It has a simple - * eject button which, when a card is inserted, needs some space beyond the connector - * itself. As an additional feature the connector has two electrical switches - * to detect wether a card is inserted and wether this card is write-protected. - * - * \section pictures Pictures - * \image html pic01.jpg "The circuit board used to implement and test this application." - * \image html pic02.jpg "The MMC/SD card connector on the soldering side of the circuit board." - * - * \section software The software - * The software is written in C (ISO C99). It might not be the smallest or - * the fastest one, but I think it is quite flexible. See the project's - * benchmark page to get an - * idea of the possible data rates. - * - * I implemented an example application providing a simple command prompt which is accessible - * via the UART at 9600 Baud. With commands similiar to the Unix shell you can browse different - * directories, read and write files, create new ones and delete them again. Not all commands are - * available in all software configurations. - * - cat \\n - * Writes a hexdump of \ to the terminal. - * - cd \\n - * Changes current working directory to \. - * - disk\n - * Shows card manufacturer, status, filesystem capacity and free storage space. - * - init\n - * Reinitializes and reopens the memory card. - * - ls\n - * Shows the content of the current directory. - * - mkdir \\n - * Creates a directory called \. - * - mv \ \\n - * Renames \ to \. - * - rm \\n - * Deletes \. - * - sync\n - * Ensures all buffered data is written to the card. - * - touch \\n - * Creates \. - * - write \ \\n - * Writes text to \, starting from \. The text is read - * from the UART, line by line. Finish with an empty line. - * - * \htmlonly - *

- * The following table shows some typical code sizes in bytes, using the 20090330 release with a - * buffered read-write MMC/SD configuration, FAT16 and static memory allocation: - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
layercode sizestatic RAM usage
MMC/SD2410518
Partition45617
FAT167928188
- * - *

- * The static RAM is mostly used for buffering memory card access, which - * improves performance and reduces implementation complexity. - *

- * - *

- * Please note that the numbers above do not include the C library functions - * used, e.g. some string functions. These will raise the numbers somewhat - * if they are not already used in other program parts. - *

- * - *

- * When opening a partition, filesystem, file or directory, a little amount - * of RAM is used, as listed in the following table. Depending on the library - * configuration, the memory is either allocated statically or dynamically. - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
descriptordynamic/static RAM
partition17
filesystem26
file53
directory49
- * - * \endhtmlonly - * - * \section adaptation Adapting the software to your needs - * The only hardware dependent part is the communication layer talking to the - * memory card. The other parts like partition table and FAT support are - * completely independent, you could use them even for managing Compact Flash - * cards or standard ATAPI hard disks. - * - * By changing the MCU* variables in the Makefile, you can use other Atmel - * microcontrollers or different clock speeds. You might also want to change - * the configuration defines in the files fat_config.h, partition_config.h, - * sd_raw_config.h and sd-reader_config.h. For example, you could disable - * write support completely if you only need read support. - * - * For further information, visit the project's - * FAQ page. - * - * \section bugs Bugs or comments? - * If you have comments or found a bug in the software - there might be some - * of them - you may contact me per mail at feedback@roland-riegel.de. - * - * \section acknowledgements Acknowledgements - * Thanks go to Ulrich Radig, who explained on his homepage how to interface - * MMC cards to the Atmel microcontroller (http://www.ulrichradig.de/). - * I adapted his work for my circuit. - * - * \section copyright Copyright 2006-2012 by Roland Riegel - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation (http://www.gnu.org/copyleft/gpl.html). - * At your option, you can alternatively redistribute and/or modify the following - * files under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation (http://www.gnu.org/copyleft/lgpl.html): - * - byteordering.c - * - byteordering.h - * - fat.c - * - fat.h - * - fat_config.h - * - partition.c - * - partition.h - * - partition_config.h - * - sd_raw.c - * - sd_raw.h - * - sd_raw_config.h - * - sd-reader_config.h +/* 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 */ -static uint8_t read_line(char* buffer, uint8_t buffer_length); -static uint32_t strtolong(const char* str); -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); -static struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name); -static uint8_t print_disk_info(const struct fat_fs_struct* fs); - -int main() -{ - /* we will just use ordinary idle mode */ - set_sleep_mode(SLEEP_MODE_IDLE); - - /* setup uart */ - uart_init(); - - while(1) - { - /* setup sd card slot */ - if(!sd_raw_init()) - { -#if DEBUG - uart_puts_p(PSTR("MMC/SD initialization failed\n")); -#endif - continue; - } - - /* open first partition */ - struct partition_struct* 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 - 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 DEBUG - uart_puts_p(PSTR("opening partition failed\n")); -#endif - continue; - } - } - - /* open file system */ - struct fat_fs_struct* fs = fat_open(partition); - if(!fs) - { -#if DEBUG - uart_puts_p(PSTR("opening filesystem failed\n")); -#endif - continue; - } - - /* open root directory */ - struct fat_dir_entry_struct directory; - fat_get_dir_entry_of_path(fs, "/", &directory); - - struct fat_dir_struct* dd = fat_open_dir(fs, &directory); - if(!dd) - { -#if DEBUG - uart_puts_p(PSTR("opening root directory failed\n")); -#endif - continue; - } - - /* print some card information as a boot message */ - print_disk_info(fs); - - /* provide a simple shell */ - char buffer[24]; - while(1) - { - /* print prompt */ - uart_putc('>'); - uart_putc(' '); - - /* read command */ - char* command = buffer; - if(read_line(command, sizeof(buffer)) < 1) - continue; - - /* execute command */ - if(strcmp_P(command, PSTR("init")) == 0) - { - break; - } - else if(strncmp_P(command, PSTR("cd "), 3) == 0) - { - command += 3; - if(command[0] == '\0') - continue; - - /* change directory */ - struct fat_dir_entry_struct subdir_entry; - if(find_file_in_dir(fs, dd, command, &subdir_entry)) - { - struct fat_dir_struct* dd_new = fat_open_dir(fs, &subdir_entry); - if(dd_new) - { - fat_close_dir(dd); - dd = dd_new; - continue; - } - } - - uart_puts_p(PSTR("directory not found: ")); - uart_puts(command); - uart_putc('\n'); - } - else if(strcmp_P(command, PSTR("ls")) == 0) - { - /* print directory listing */ - struct fat_dir_entry_struct dir_entry; - while(fat_read_dir(dd, &dir_entry)) - { - uint8_t spaces = sizeof(dir_entry.long_name) - strlen(dir_entry.long_name) + 4; - - uart_puts(dir_entry.long_name); - uart_putc(dir_entry.attributes & FAT_ATTRIB_DIR ? '/' : ' '); - while(spaces--) - uart_putc(' '); - uart_putdw_dec(dir_entry.file_size); - uart_putc('\n'); - } - } - else if(strncmp_P(command, PSTR("cat "), 4) == 0) - { - command += 4; - if(command[0] == '\0') - continue; - - /* search file in current directory and open it */ - struct fat_file_struct* fd = open_file_in_dir(fs, dd, command); - if(!fd) - { - uart_puts_p(PSTR("error opening ")); - uart_puts(command); - uart_putc('\n'); - continue; - } - - /* print file contents */ - uint8_t buffer[8]; - uint32_t offset = 0; - intptr_t count; - while((count = fat_read_file(fd, buffer, sizeof(buffer))) > 0) - { - uart_putdw_hex(offset); - uart_putc(':'); - for(intptr_t i = 0; i < count; ++i) - { - uart_putc(' '); - uart_putc_hex(buffer[i]); - } - uart_putc('\n'); - offset += 8; - } +#include +#include +#include +#include +#include - fat_close_file(fd); - } - else if(strcmp_P(command, PSTR("disk")) == 0) - { - if(!print_disk_info(fs)) - uart_puts_p(PSTR("error reading disk info\n")); - } -#if FAT_WRITE_SUPPORT - else if(strncmp_P(command, PSTR("rm "), 3) == 0) - { - command += 3; - if(command[0] == '\0') - continue; - - struct fat_dir_entry_struct file_entry; - if(find_file_in_dir(fs, dd, command, &file_entry)) - { - if(fat_delete_file(fs, &file_entry)) - continue; - } +#include - uart_puts_p(PSTR("error deleting file: ")); - uart_puts(command); - uart_putc('\n'); - } - else if(strncmp_P(command, PSTR("touch "), 6) == 0) - { - command += 6; - if(command[0] == '\0') - continue; - - struct fat_dir_entry_struct file_entry; - if(!fat_create_file(dd, command, &file_entry)) - { - uart_puts_p(PSTR("error creating file: ")); - uart_puts(command); - uart_putc('\n'); - } - } - else if(strncmp_P(command, PSTR("mv "), 3) == 0) - { - command += 3; - if(command[0] == '\0') - continue; - - char* target = command; - while(*target != ' ' && *target != '\0') - ++target; - - if(*target == ' ') - *target++ = '\0'; - else - continue; - - struct fat_dir_entry_struct file_entry; - if(find_file_in_dir(fs, dd, command, &file_entry)) - { - if(fat_move_file(fs, &file_entry, dd, target)) - continue; - } - - uart_puts_p(PSTR("error moving file: ")); - uart_puts(command); - uart_putc('\n'); - } - else if(strncmp_P(command, PSTR("write "), 6) == 0) - { - command += 6; - if(command[0] == '\0') - continue; - - char* offset_value = command; - while(*offset_value != ' ' && *offset_value != '\0') - ++offset_value; - - if(*offset_value == ' ') - *offset_value++ = '\0'; - else - continue; - - /* search file in current directory and open it */ - struct fat_file_struct* fd = open_file_in_dir(fs, dd, command); - if(!fd) - { - uart_puts_p(PSTR("error opening ")); - uart_puts(command); - uart_putc('\n'); - continue; - } - - int32_t offset = strtolong(offset_value); - if(!fat_seek_file(fd, &offset, FAT_SEEK_SET)) - { - uart_puts_p(PSTR("error seeking on ")); - uart_puts(command); - uart_putc('\n'); - - fat_close_file(fd); - continue; - } - - /* read text from the shell and write it to the file */ - uint8_t data_len; - while(1) - { - /* give a different prompt */ - uart_putc('<'); - uart_putc(' '); - - /* read one line of text */ - data_len = read_line(buffer, sizeof(buffer)); - if(!data_len) - break; - - /* write text to file */ - if(fat_write_file(fd, (uint8_t*) buffer, data_len) != data_len) - { - uart_puts_p(PSTR("error writing to file\n")); - break; - } - } +#include +#include +#include +#include +#include +#include +#include +#include - fat_close_file(fd); - } - else if(strncmp_P(command, PSTR("mkdir "), 6) == 0) - { - command += 6; - if(command[0] == '\0') - continue; +#include +#include +#include +#include - struct fat_dir_entry_struct dir_entry; - if(!fat_create_dir(dd, command, &dir_entry)) - { - uart_puts_p(PSTR("error creating directory: ")); - uart_puts(command); - uart_putc('\n'); - } - } -#endif -#if SD_RAW_WRITE_BUFFERING - else if(strcmp_P(command, PSTR("sync")) == 0) - { - if(!sd_raw_sync()) - uart_puts_p(PSTR("error syncing disk\n")); - } -#endif - else - { - uart_puts_p(PSTR("unknown command: ")); - uart_puts(command); - uart_putc('\n'); - } - } +#include "eeprom_config.h" +#include "main.h" - /* close directory */ - fat_close_dir(dd); +struct imuboard imuboard; +volatile uint32_t global_ms; - /* close file system */ - fat_close(fs); +/* global xbee device */ +struct xbee_dev *xbee_dev; - /* close partition */ - partition_close(partition); - } - - return 0; +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"); */ } -uint8_t read_line(char* buffer, uint8_t buffer_length) +/* return time in milliseconds on unsigned 16 bits */ +uint16_t get_time_ms(void) { - memset(buffer, 0, buffer_length); - - uint8_t read_length = 0; - while(read_length < buffer_length - 1) - { - uint8_t c = uart_getc(); - - if(c == 0x08 || c == 0x7f) - { - if(read_length < 1) - continue; - - --read_length; - buffer[read_length] = '\0'; - - uart_putc(0x08); - uart_putc(' '); - uart_putc(0x08); - - continue; - } - - uart_putc(c); - - if(c == '\n') - { - buffer[read_length] = '\0'; - break; - } - else - { - buffer[read_length] = c; - ++read_length; - } - } - - return read_length; + uint16_t ms; + uint8_t flags; + IRQ_LOCK(flags); + ms = global_ms; + IRQ_UNLOCK(flags); + return ms; } -uint32_t strtolong(const char* str) +static void main_timer_interrupt(void) { - uint32_t l = 0; - while(*str >= '0' && *str <= '9') - l = l * 10 + (*str++ - '0'); - - return l; + 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(); } -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) +/* XXX */ +int imu_loop(void); +int sd_main(void); + +int main(void) { - while(fat_read_dir(dd, dir_entry)) - { - if(strcmp(dir_entry->long_name, name) == 0) - { - fat_reset_dir(dd); - return 1; - } - } + DDRB = 0x18 /* LEDs */; - return 0; -} + uart_init(); + uart_register_rx_event(CMDLINE_UART, emergency); -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; + fdevopen(cmdline_dev_send, cmdline_dev_recv); + timer_init(); + timer0_register_OV_intr(main_timer_interrupt); - return fat_open_file(fs, &file_entry); -} + callout_mgr_init(&imuboard.intr_cm, get_time_ms); -uint8_t print_disk_info(const struct fat_fs_struct* fs) -{ - if(!fs) - return 0; + cmdline_init(); + /* LOGS */ + error_register_emerg(mylog); + error_register_error(mylog); + error_register_warning(mylog); + error_register_notice(mylog); + error_register_debug(mylog); - struct sd_raw_info disk_info; - if(!sd_raw_get_info(&disk_info)) - return 0; + /* communication with mpu6050 */ + i2cm_init(); - uart_puts_p(PSTR("manuf: 0x")); uart_putc_hex(disk_info.manufacturer); uart_putc('\n'); - uart_puts_p(PSTR("oem: ")); uart_puts((char*) disk_info.oem); uart_putc('\n'); - uart_puts_p(PSTR("prod: ")); uart_puts((char*) disk_info.product); uart_putc('\n'); - uart_puts_p(PSTR("rev: ")); uart_putc_hex(disk_info.revision); uart_putc('\n'); - uart_puts_p(PSTR("serial: 0x")); uart_putdw_hex(disk_info.serial); uart_putc('\n'); - uart_puts_p(PSTR("date: ")); uart_putw_dec(disk_info.manufacturing_month); uart_putc('/'); - uart_putw_dec(disk_info.manufacturing_year); uart_putc('\n'); - uart_puts_p(PSTR("size: ")); uart_putdw_dec(disk_info.capacity / 1024 / 1024); uart_puts_p(PSTR("MB\n")); - uart_puts_p(PSTR("copy: ")); uart_putw_dec(disk_info.flag_copy); uart_putc('\n'); - uart_puts_p(PSTR("wr.pr.: ")); uart_putw_dec(disk_info.flag_write_protect_temp); uart_putc('/'); - uart_putw_dec(disk_info.flag_write_protect); uart_putc('\n'); - uart_puts_p(PSTR("format: ")); uart_putw_dec(disk_info.format); uart_putc('\n'); - uart_puts_p(PSTR("free: ")); uart_putdw_dec(fat_get_fs_free(fs)); uart_putc('/'); - uart_putdw_dec(fat_get_fs_size(fs)); uart_putc('\n'); + sei(); - return 1; -} + eeprom_load_config(); -#if FAT_DATETIME_SUPPORT -void get_datetime(uint16_t* year, uint8_t* month, uint8_t* day, uint8_t* hour, uint8_t* min, uint8_t* sec) -{ - *year = 2007; - *month = 1; - *day = 1; - *hour = 0; - *min = 0; - *sec = 0; -} -#endif + printf_P(PSTR("\r\n")); + rdline_newline(&imuboard.rdl, imuboard.prompt); + + //sd_main(); + imu_loop(); + while (1) { + cmdline_poll(); + } + + return 0; +}