From f4fc3bbd571ce99b707d326a206159a6eab49547 Mon Sep 17 00:00:00 2001 From: Lorenz Meier Date: Sun, 28 Jul 2013 14:10:37 +0200 Subject: [PATCH] Added RAMTRON device, updated diagrams --- Documentation/flight_mode_state_machine.odg | Bin 18105 -> 18452 bytes makefiles/config_px4fmu-v1_default.mk | 1 + src/systemcmds/ramtron/module.mk | 6 + src/systemcmds/ramtron/ramtron.c | 279 ++++++++++++++++++++ 4 files changed, 286 insertions(+) create mode 100644 src/systemcmds/ramtron/module.mk create mode 100644 src/systemcmds/ramtron/ramtron.c diff --git a/Documentation/flight_mode_state_machine.odg b/Documentation/flight_mode_state_machine.odg index b630ecb40242a9a52a796c30ff0dbc283a4de7e7..f9fa7a032343b3b74e3b795504a34539e442e065 100644 GIT binary patch delta 13736 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%0ApMdZ63sIagPH# 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 aD|<|q2ohfcoFIt@ewRgub@-QF=l=jBG4O8y diff --git a/makefiles/config_px4fmu-v1_default.mk b/makefiles/config_px4fmu-v1_default.mk index 74be1cd23f..3f88b8c8c9 100644 --- a/makefiles/config_px4fmu-v1_default.mk +++ b/makefiles/config_px4fmu-v1_default.mk @@ -39,6 +39,7 @@ MODULES += modules/sensors # System commands # MODULES += systemcmds/eeprom +MODULES += systemcmds/ramtron MODULES += systemcmds/bl_update MODULES += systemcmds/boardinfo MODULES += systemcmds/i2c diff --git a/src/systemcmds/ramtron/module.mk b/src/systemcmds/ramtron/module.mk new file mode 100644 index 0000000000..e4eb1d143c --- /dev/null +++ b/src/systemcmds/ramtron/module.mk @@ -0,0 +1,6 @@ +# +# RAMTRON file system driver +# + +MODULE_COMMAND = ramtron +SRCS = ramtron.c diff --git a/src/systemcmds/ramtron/ramtron.c b/src/systemcmds/ramtron/ramtron.c new file mode 100644 index 0000000000..03c713987a --- /dev/null +++ b/src/systemcmds/ramtron/ramtron.c @@ -0,0 +1,279 @@ +/**************************************************************************** + * + * Copyright (C) 2013 PX4 Development Team. All rights reserved. + * Author: Lorenz Meier + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name PX4 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER OR 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. + * + ****************************************************************************/ + +/** + * @file ramtron.c + * + * ramtron service and utility app. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "systemlib/systemlib.h" +#include "systemlib/param/param.h" +#include "systemlib/err.h" + +__EXPORT int ramtron_main(int argc, char *argv[]); + +#ifndef CONFIG_MTD_RAMTRON + +/* create a fake command with decent message to not confuse users */ +int ramtron_main(int argc, char *argv[]) +{ + errx(1, "RAMTRON not enabled, skipping."); +} +#else + +static void ramtron_attach(void); +static void ramtron_start(void); +static void ramtron_erase(void); +static void ramtron_ioctl(unsigned operation); +static void ramtron_save(const char *name); +static void ramtron_load(const char *name); +static void ramtron_test(void); + +static bool attached = false; +static bool started = false; +static struct mtd_dev_s *ramtron_mtd; + +int ramtron_main(int argc, char *argv[]) +{ + if (argc >= 2) { + if (!strcmp(argv[1], "start")) + ramtron_start(); + + if (!strcmp(argv[1], "save_param")) + ramtron_save(argv[2]); + + if (!strcmp(argv[1], "load_param")) + ramtron_load(argv[2]); + + if (!strcmp(argv[1], "erase")) + ramtron_erase(); + + if (!strcmp(argv[1], "test")) + ramtron_test(); + + if (0) { /* these actually require a file on the filesystem... */ + + if (!strcmp(argv[1], "reformat")) + ramtron_ioctl(FIOC_REFORMAT); + + if (!strcmp(argv[1], "repack")) + ramtron_ioctl(FIOC_OPTIMIZE); + } + } + + errx(1, "expected a command, try 'start'\n\t'save_param /ramtron/parameters'\n\t'load_param /ramtron/parameters'\n\t'erase'\n"); +} + +struct mtd_dev_s *ramtron_initialize(FAR struct spi_dev_s *dev); + + +static void +ramtron_attach(void) +{ + /* find the right spi */ + struct spi_dev_s *spi = up_spiinitialize(2); + /* this resets the spi bus, set correct bus speed again */ + // xxx set in ramtron driver, leave this out +// SPI_SETFREQUENCY(spi, 4000000); + SPI_SETFREQUENCY(spi, 375000000); + SPI_SETBITS(spi, 8); + SPI_SETMODE(spi, SPIDEV_MODE3); + SPI_SELECT(spi, SPIDEV_FLASH, false); + + if (spi == NULL) + errx(1, "failed to locate spi bus"); + + /* start the MTD driver, attempt 5 times */ + for (int i = 0; i < 5; i++) { + ramtron_mtd = ramtron_initialize(spi); + if (ramtron_mtd) { + /* abort on first valid result */ + if (i > 0) { + warnx("warning: ramtron needed %d attempts to attach", i+1); + } + break; + } + } + + /* if last attempt is still unsuccessful, abort */ + if (ramtron_mtd == NULL) + errx(1, "failed to initialize ramtron driver"); + + attached = true; +} + +static void +ramtron_start(void) +{ + int ret; + + if (started) + errx(1, "ramtron already mounted"); + + if (!attached) + ramtron_attach(); + + /* start NXFFS */ + ret = nxffs_initialize(ramtron_mtd); + + if (ret < 0) + errx(1, "failed to initialize NXFFS - erase ramtron to reformat"); + + /* mount the ramtron */ + ret = mount(NULL, "/ramtron", "nxffs", 0, NULL); + + if (ret < 0) + errx(1, "failed to mount /ramtron - erase ramtron to reformat"); + + started = true; + warnx("mounted ramtron at /ramtron"); + exit(0); +} + +//extern int at24c_nuke(void); + +static void +ramtron_erase(void) +{ + if (!attached) + ramtron_attach(); + +// if (at24c_nuke()) + errx(1, "erase failed"); + + errx(0, "erase done, reboot now"); +} + +static void +ramtron_ioctl(unsigned operation) +{ + int fd; + + fd = open("/ramtron/.", 0); + + if (fd < 0) + err(1, "open /ramtron"); + + if (ioctl(fd, operation, 0) < 0) + err(1, "ioctl"); + + exit(0); +} + +static void +ramtron_save(const char *name) +{ + if (!started) + errx(1, "must be started first"); + + if (!name) + err(1, "missing argument for device name, try '/ramtron/parameters'"); + + warnx("WARNING: 'ramtron save_param' deprecated - use 'param save' instead"); + + /* delete the file in case it exists */ + unlink(name); + + /* create the file */ + int fd = open(name, O_WRONLY | O_CREAT | O_EXCL); + + if (fd < 0) + err(1, "opening '%s' failed", name); + + int result = param_export(fd, false); + close(fd); + + if (result < 0) { + unlink(name); + errx(1, "error exporting to '%s'", name); + } + + exit(0); +} + +static void +ramtron_load(const char *name) +{ + if (!started) + errx(1, "must be started first"); + + if (!name) + err(1, "missing argument for device name, try '/ramtron/parameters'"); + + warnx("WARNING: 'ramtron load_param' deprecated - use 'param load' instead"); + + int fd = open(name, O_RDONLY); + + if (fd < 0) + err(1, "open '%s'", name); + + int result = param_load(fd); + close(fd); + + if (result < 0) + errx(1, "error importing from '%s'", name); + + exit(0); +} + +//extern void at24c_test(void); + +static void +ramtron_test(void) +{ +// at24c_test(); + exit(0); +} + +#endif