From f4fc3bbd571ce99b707d326a206159a6eab49547 Mon Sep 17 00:00:00 2001 From: Lorenz Meier <lm@inf.ethz.ch> 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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 delta 13325 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 TCBX5Lc;Gi#bXfa;t^0ofBQfxA 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 <lm@inf.ethz.ch> + * + * 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 <nuttx/config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mount.h> +#include <sys/ioctl.h> +#include <sys/stat.h> + +#include <nuttx/spi.h> +#include <nuttx/mtd.h> +#include <nuttx/fs/nxffs.h> +#include <nuttx/fs/ioctl.h> + +#include <arch/board/board.h> + +#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 -- GitLab