From 53b33e912f64b05eba3481cfba092c13dbb22f19 Mon Sep 17 00:00:00 2001 From: Robert Hartung Date: Fri, 15 Sep 2017 13:34:21 +0200 Subject: [PATCH 1/9] dist/tools: adds inga_tool --- dist/tools/inga_tool/.gitignore | 1 + dist/tools/inga_tool/Makefile | 61 +++ dist/tools/inga_tool/README.md | 66 +++ dist/tools/inga_tool/inga_tool.c | 535 +++++++++++++++++++ dist/tools/inga_tool/inga_usb.c | 848 +++++++++++++++++++++++++++++++ dist/tools/inga_tool/inga_usb.h | 111 ++++ makefiles/tools/inga_tool.inc.mk | 4 + makefiles/tools/targets.inc.mk | 5 + 8 files changed, 1631 insertions(+) create mode 100644 dist/tools/inga_tool/.gitignore create mode 100644 dist/tools/inga_tool/Makefile create mode 100644 dist/tools/inga_tool/README.md create mode 100644 dist/tools/inga_tool/inga_tool.c create mode 100644 dist/tools/inga_tool/inga_usb.c create mode 100644 dist/tools/inga_tool/inga_usb.h create mode 100644 makefiles/tools/inga_tool.inc.mk diff --git a/dist/tools/inga_tool/.gitignore b/dist/tools/inga_tool/.gitignore new file mode 100644 index 000000000000..8178831b4774 --- /dev/null +++ b/dist/tools/inga_tool/.gitignore @@ -0,0 +1 @@ +inga_tool diff --git a/dist/tools/inga_tool/Makefile b/dist/tools/inga_tool/Makefile new file mode 100644 index 000000000000..5fe6d4c52e55 --- /dev/null +++ b/dist/tools/inga_tool/Makefile @@ -0,0 +1,61 @@ +UNAME := $(shell uname) +FTDI_VERSION := -1 + +# this is ugly! +CC = gcc +ifeq ($(UNAME), Linux) +# Use pkg-config to determine the compiler and linker flag forlibudev +LIBUDEV_CFLAGS := `pkg-config --cflags libudev` +LIBUDEV_LDLIBS := `pkg-config --libs libudev` +endif + +# Use pkg-config to determine which libftdi version we have +HASFTDI := $(shell pkg-config --exists libftdi ; echo "$$?" ) +HASFTDI0 := $(shell pkg-config --exists libftdi0; echo "$$?" ) +HASFTDI1 := $(shell pkg-config --exists libftdi1; echo "$$?" ) + +# libftdi1 uses libusb-1.0, libftdi0 uses libusb (0.1) +ifeq (0, ${HASFTDI1}) + FTDI_VERSION := 1 + FTDI_CFLAGS := `pkg-config --cflags libftdi1 libusb-1.0` + FTDI_LDLIBS := `pkg-config --libs libftdi1 libusb-1.0` +else ifeq (0, ${HASFTDI0}) + FTDI_VERSION := 0 + FTDI_CFLAGS := `pkg-config --cflags libftdi0 libusb` + FTDI_LDLIBS := `pkg-config --libs libftdi0 libusb` +else ifeq (0, ${HASFTDI}) + FTDI_VERSION := 0 + FTDI_CFLAGS := `pkg-config --cflags libftdi libusb` + FTDI_LDLIBS := `pkg-config --libs libftdi libusb` +endif + + +# Use pkg-config to determine the compiler and linker flag for popt +POPT_CFLAGS := `pkg-config --cflags popt` +POPT_LDLIBS := `pkg-config --libs popt` + + +CFLAGS=${FTDI_CFLAGS} ${POPT_CFLAGS} ${LIBUDEV_CFLAGS} -DFTDI_VERSION="${FTDI_VERSION}" -ggdb +LDLIBS=${FTDI_LDLIBS} ${POPT_LDLIBS} ${LIBUDEV_LDLIBS} + +# Standard recipes to make inga_tool + +NAME := inga_tool +SOURCES := inga_usb.c inga_tool.c +HEADERS := inga_usb.h +OBJECTS := $(SOURCES:%.c=%.o) + +all: ${NAME} + +${NAME}: ${OBJECTS} + $(info Making $@) + ${CC} ${OBJECTS} ${LDLIBS} -o $@ + +${OBJECTS}: %.o:%.c ${HEADERS} + $(info Making $@) + ${CC} ${CFLAGS} $< -c -o $@ + +clean: + rm -f ${OBJECTS} ${NAME} + +.PHONY: clean diff --git a/dist/tools/inga_tool/README.md b/dist/tools/inga_tool/README.md new file mode 100644 index 000000000000..fc06ce877907 --- /dev/null +++ b/dist/tools/inga_tool/README.md @@ -0,0 +1,66 @@ +inga_tool is a utility to reset the INGA and update the FTDI EEPROM +=================================================================== + +## Building +To build it, you need libudev and lipopt; and either libftdi 0.19 (or later) with libusb 0.1, or libftdi 1.0 (or later) with libusb 1.0. +Just typing + + $ make + +should build the binary. I might add autotools support eventually. + + +Use it like this to reset an INGA node: + + ./inga_tool -d /path/to/usb/serial/device -r + +The following will flash the EEPROM (WARNING, not extensively tested): + + ./inga_tool -d /path/to/usb/serial/device -f -v + +You can also read out the EEPROM: + + ./inga_tool -d /path/to/usb/serial/device -s + +It is also possible to choose a device based on the USB serial ID: + + ./inga_tool -u -r + +### Reset +This is used to go into the bootloader without the need to reset the device manually. +You'll need an up-to-date bootloader for this to work. +In addition, flashing the EEPROM of INGA is required before using the reset functionality. + +### Flashing +Right now no options are supported for flashing, that will be something for the future. +The following changes will be made: + * manufacturer -> "IBR" + * product -> "INGA" + * cbus functions are set to + + ``` + CBUS0 TXLED + CBUS1 RXLED + CBUS2 TXDEN + CBUS3 IOMODE + CBUS4 SLEEP + ``` + +Unchanged are VID/PID and the serial. + +## OS X +inga_tool works partly also with OS X. +Selecting a device ist only possible with option `-u` (serial number). +It is not possible to unload the FTDI driver for a specific USB-device. +Also you need to be a superuser to unload the FTDI driver (***Warning: this disconnects all FTDI devices***). + +But if you need so you can use + + sudo kextunload -bundle com.apple.driver.AppleUSBFTDI + +to unload the driver and + + sudo kextload -bundle com.apple.driver.AppleUSBFTDI + +to reactivate the driver after using inga_tool. +These changes are only permanent until next reboot. diff --git a/dist/tools/inga_tool/inga_tool.c b/dist/tools/inga_tool/inga_tool.c new file mode 100644 index 000000000000..e7a2ede79546 --- /dev/null +++ b/dist/tools/inga_tool/inga_tool.c @@ -0,0 +1,535 @@ +/* Reset INGA nodes and configure their FTDI + * + * (C) 2011 Daniel Willmann + * (C) 2014 Sven Hesse + * All Rights Reserved + * + * 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 of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "inga_usb.h" + +enum { + MODE_RESET, + MODE_UPDATE_EEPROM, + MODE_READ_SERIAL, + MODE_EUI64, +}; + +struct ftdi_eemem_info { + const char *manufacturer; + const char *product; + const char *serial; + int chip_type; + int vendor_id; + int product_id; + int max_power; + int cbus[5]; +}; + +struct config_t { + struct inga_usb_config_t usb; + + int mode; + int verbose; + int eep_cbusio; + struct ftdi_eemem_info eep; +}; + +#define VERBOSE(args ...) \ + if (cfg->verbose) \ + fprintf(stderr, ## args) + + +void inga_reset(struct config_t *cfg) +{ + int rc; + struct inga_usb_ftdi_t *ftdi; + struct inga_usb_device_t *usbdev = NULL; + + if (inga_usb_ftdi_init(&ftdi) < 0) { + fprintf(stderr, "ftdi_init failed\n"); + exit(EXIT_FAILURE); + } + + /* Find the USB device for the path */ + usbdev = inga_usb_find_device(&cfg->usb, cfg->verbose); + if (!usbdev) { + fprintf(stderr, "Could not find device\n"); + exit(EXIT_FAILURE); + } + + rc = inga_usb_ftdi_open(ftdi, usbdev); + if (rc < 0) { + fprintf(stderr, "unable to open ftdi device: %d (%s)\n", rc, inga_usb_ftdi_get_error_string(ftdi)); + exit(EXIT_FAILURE); + } + + printf("Resetting INGA node..."); + fflush(stdout); + + /* Set CBUS3 to output and high */ + inga_usb_ftdi_set_bitmode(ftdi, 0x88, BITMODE_CBUS); + + /* sleep(1); */ + + /* Set CBUS3 to output and low */ + inga_usb_ftdi_set_bitmode(ftdi, 0x80, BITMODE_CBUS); + + VERBOSE("done\n"); + + inga_usb_ftdi_set_bitmode(ftdi, 0, BITMODE_RESET); + +out: + + VERBOSE("Resetting USB device\n"); + + inga_usb_ftdi_reset(ftdi); + inga_usb_ftdi_close(ftdi); + inga_usb_ftdi_deinit(ftdi); + + inga_usb_free_device(usbdev); +} + +void inga_read_eeprom(struct config_t *cfg, struct inga_usb_ftdi_t *ftdi, struct ftdi_eemem_info *info) +{ + int rc; + struct inga_usb_device_t *usbdev = NULL; + + if (inga_usb_ftdi_init(&ftdi) < 0) { + fprintf(stderr, "ftdi_init failed\n"); + exit(EXIT_FAILURE); + } + + /* Find the USB device for the path */ + usbdev = inga_usb_find_device(&cfg->usb, cfg->verbose); + if (!usbdev) { + fprintf(stderr, "Could not find device\n"); + exit(EXIT_FAILURE); + } + + rc = inga_usb_ftdi_open(ftdi, usbdev); + if (rc < 0) { + fprintf(stderr, "unable to open ftdi device: %d (%s)\n", rc, inga_usb_ftdi_get_error_string(ftdi)); + exit(EXIT_FAILURE); + } + + VERBOSE("Reading out EEPROM image..."); + fflush(stdout); + rc = inga_usb_ftdi_eeprom_read(ftdi); + if (rc < 0) { + fprintf(stderr, "\nCould not read and decode EEPROM: %i\n", rc); + exit(EXIT_FAILURE); + } + VERBOSE("done\n\n"); + + if ((inga_usb_ftdi_eeprom_get_value(ftdi, CHIP_TYPE, &info->chip_type) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, VENDOR_ID, &info->vendor_id) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, PRODUCT_ID, &info->product_id) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, MAX_POWER, &info->max_power) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, CBUS_FUNCTION_0, &info->cbus[0]) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, CBUS_FUNCTION_1, &info->cbus[1]) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, CBUS_FUNCTION_2, &info->cbus[2]) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, CBUS_FUNCTION_3, &info->cbus[3]) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, CBUS_FUNCTION_4, &info->cbus[4]) < 0)) { + + fprintf(stderr, "Could not read the EEPROM values\n"); + exit(EXIT_FAILURE); + } + + if ((inga_usb_ftdi_eeprom_get_string(ftdi, MANUFACTURER_STRING, &info->manufacturer) < 0) || + (inga_usb_ftdi_eeprom_get_string(ftdi, PRODUCT_STRING, &info->product) < 0) || + (inga_usb_ftdi_eeprom_get_string(ftdi, SERIAL_STRING, &info->serial) < 0)) { + + fprintf(stderr, "Could not read the EEPROM manufacturer, product and serial strings\n"); + exit(EXIT_FAILURE); + } + + VERBOSE("Resetting USB device\n"); + + inga_usb_ftdi_reset(ftdi); + inga_usb_ftdi_close(ftdi); + inga_usb_ftdi_deinit(ftdi); + + inga_usb_free_device(usbdev); +} + +void inga_print_eeinfo(struct config_t *cfg) +{ + struct inga_usb_ftdi_t *ftdi; + struct ftdi_eemem_info info; + + inga_read_eeprom(cfg, ftdi, &info); + + + printf("EEPROM config:\n" + "Chip type: %i\n" + "VID: 0x%04x\n" + "PID: 0x%04x\n" + "Manufacturer: %s\n" + "Product: %s\n" + "Serial: %s\n" + "Max power: %i\n" + "CBUS: %1x%1x %1x%1x 0%1x\n\n", + info.chip_type, info.vendor_id, info.product_id, info.manufacturer, info.product, info.serial, info.max_power * 2, + info.cbus[1], info.cbus[0], info.cbus[3], info.cbus[2], info.cbus[4]); +} + +uint64_t inga_serial_to_id(const char *serial) +{ + int i = 0; + int character = 0; + uint64_t return_value = 0; + + for (i = 0; i < 8; i++) { + character = serial[i] - 48; // "0" == 48, Z == 42 + + if (character > 42) { + character = 42; + } + + return_value = (return_value << 6) | (character & 0x3F); + } + + /* Insert FFFE as required by http://msdn.microsoft.com/en-us/library/aa915616.aspx */ + return_value = ((return_value & 0xFFFFFF000000) << 16) | (((uint64_t) 0xFEFF) << 24) | (return_value & 0x00000000FFFFF); + + /* Insert 00 */ + return_value &= 0xFFFFFFFFFFFFFF7F; + + return return_value; +} + +void inga_eui64(struct config_t *cfg) +{ + struct inga_usb_ftdi_t *ftdi; + struct ftdi_eemem_info info; + + const char *serial = NULL; + uint8_t *pointer = NULL; + + inga_read_eeprom(cfg, ftdi, &info); + + /* Obtain EUI64 */ + uint64_t id = inga_serial_to_id(info.serial); + pointer = (uint8_t *) &id; + + printf("EUI64: "); + int i; + for (i = 0; i < 8; i++) { + printf("%02X", pointer[i]); + + if (i < 7) { + printf(":"); + } + } + printf("\n"); +} + +void inga_eeprom(struct config_t *cfg) +{ + int rc; + struct inga_usb_ftdi_t *ftdi; + struct inga_usb_device_t *usbdev = NULL; + const char *manufacturer = NULL, *product = NULL, *serial = NULL; + int chip_type, vid, pid, max_power, cbus[5]; + + if (inga_usb_ftdi_init(&ftdi) < 0) { + fprintf(stderr, "ftdi_init failed\n"); + exit(EXIT_FAILURE); + } + + /* Find the USB device for the path */ + usbdev = inga_usb_find_device(&cfg->usb, cfg->verbose); + if (!usbdev) { + fprintf(stderr, "Could not find device\n"); + exit(EXIT_FAILURE); + } + + rc = inga_usb_ftdi_open(ftdi, usbdev); + if (rc < 0) { + fprintf(stderr, "unable to open ftdi device: %d (%s)\n", rc, inga_usb_ftdi_get_error_string(ftdi)); + exit(EXIT_FAILURE); + } + + printf("Reading out EEPROM image..."); + fflush(stdout); + rc = inga_usb_ftdi_eeprom_read(ftdi); + if (rc < 0) { + fprintf(stderr, "\nCould not read and decode EEPROM: %i\n", rc); + exit(EXIT_FAILURE); + } + VERBOSE("done\n\n"); + + if ((inga_usb_ftdi_eeprom_get_value(ftdi, CHIP_TYPE, &chip_type) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, VENDOR_ID, &vid) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, PRODUCT_ID, &pid) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, MAX_POWER, &max_power) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, CBUS_FUNCTION_0, &cbus[0]) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, CBUS_FUNCTION_1, &cbus[1]) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, CBUS_FUNCTION_2, &cbus[2]) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, CBUS_FUNCTION_3, &cbus[3]) < 0) || + (inga_usb_ftdi_eeprom_get_value(ftdi, CBUS_FUNCTION_4, &cbus[4]) < 0)) { + + fprintf(stderr, "Could not read the EEPROM values\n"); + exit(EXIT_FAILURE); + } + + if ((inga_usb_ftdi_eeprom_get_string(ftdi, MANUFACTURER_STRING, &manufacturer) < 0) || + (inga_usb_ftdi_eeprom_get_string(ftdi, PRODUCT_STRING, &product) < 0) || + (inga_usb_ftdi_eeprom_get_string(ftdi, SERIAL_STRING, &serial) < 0)) { + + fprintf(stderr, "Could not read the EEPROM manufacturer, product and serial strings\n"); + exit(EXIT_FAILURE); + } + + VERBOSE("\nEEPROM config:\n" + "Chip type: %i\n" + "VID: 0x%04x\n" + "PID: 0x%04x\n" + "Manufacturer: %s\n" + "Product: %s\n" + "Serial: %s\n" + "Max power: %i\n" + "CBUS: %1x%1x %1x%1x 0%1x\n\n", + chip_type, vid, pid, manufacturer, product, serial, max_power * 2, + cbus[1], cbus[0], cbus[3], cbus[2], cbus[4]); + + vid = cfg->eep.vendor_id ? cfg->eep.vendor_id : vid; + pid = cfg->eep.product_id ? cfg->eep.product_id : pid; + + manufacturer = cfg->eep.manufacturer ? cfg->eep.manufacturer : manufacturer; + product = cfg->eep.product ? cfg->eep.product : product; + serial = cfg->eep.serial ? cfg->eep.serial : serial; + + max_power = (cfg->eep.max_power > 0) ? (cfg->eep.max_power / 2) : max_power; + + cbus[0] = cfg->eep.cbus[0]; + cbus[1] = cfg->eep.cbus[1]; + cbus[2] = cfg->eep.cbus[2]; + cbus[3] = cfg->eep.cbus[3]; + cbus[4] = cfg->eep.cbus[4]; + + VERBOSE("\nUpdating with EEPROM config:\n" + "Chip type: %i\n" + "VID: 0x%04x\n" + "PID: 0x%04x\n" + "Manufacturer: %s\n" + "Product: %s\n" + "Serial: %s\n" + "Max power: %i\n" + "CBUS: %1x%1x %1x%1x 0%1x\n\n", + chip_type, vid, pid, manufacturer, product, serial, max_power * 2, + cbus[1], cbus[0], cbus[3], cbus[2], cbus[4]); + + if ((inga_usb_ftdi_eeprom_set_value(ftdi, CHIP_TYPE, chip_type) < 0) || + (inga_usb_ftdi_eeprom_set_value(ftdi, VENDOR_ID, vid) < 0) || + (inga_usb_ftdi_eeprom_set_value(ftdi, PRODUCT_ID, pid) < 0) || + (inga_usb_ftdi_eeprom_set_value(ftdi, MAX_POWER, max_power) < 0) || + (inga_usb_ftdi_eeprom_set_value(ftdi, CBUS_FUNCTION_0, cbus[0]) < 0) || + (inga_usb_ftdi_eeprom_set_value(ftdi, CBUS_FUNCTION_1, cbus[1]) < 0) || + (inga_usb_ftdi_eeprom_set_value(ftdi, CBUS_FUNCTION_2, cbus[2]) < 0) || + (inga_usb_ftdi_eeprom_set_value(ftdi, CBUS_FUNCTION_3, cbus[3]) < 0) || + (inga_usb_ftdi_eeprom_set_value(ftdi, CBUS_FUNCTION_4, cbus[4]) < 0)) { + + fprintf(stderr, "Could not write the EEPROM values\n"); + exit(EXIT_FAILURE); + } + + if ((inga_usb_ftdi_eeprom_set_string(ftdi, MANUFACTURER_STRING, manufacturer) < 0) || + (inga_usb_ftdi_eeprom_set_string(ftdi, PRODUCT_STRING, product) < 0) || + (inga_usb_ftdi_eeprom_set_string(ftdi, SERIAL_STRING, serial) < 0)) { + + fprintf(stderr, "Could not write the EEPROM manufacturer, product and serial strings\n"); + exit(EXIT_FAILURE); + } + + printf("Writing updated EEPROM image..."); + fflush(stdout); + + rc = inga_usb_ftdi_eeprom_write(ftdi); + if (rc < 0) { + fprintf(stderr, "Could not build and write EEPROM: %i\n", rc); + exit(EXIT_FAILURE); + } + sleep(10); + VERBOSE("done\n"); + +out: + + VERBOSE("Resetting USB device\n"); + + inga_usb_ftdi_reset(ftdi); + inga_usb_ftdi_close(ftdi); + inga_usb_ftdi_deinit(ftdi); + + inga_usb_free_device(usbdev); +} + +void usage(poptContext poptc, int exitcode, char *error, char *addl) +{ + poptPrintUsage(poptc, stderr, 0); + if (error) { + fprintf(stderr, "%s: %s\n", error, addl); + } + exit(exitcode); +} + +void parse_options(int argc, const char **argv, struct config_t *cfg) +{ + char rc, *tmp; + poptContext poptc; + + struct poptOption options[] = { + { "reset", 'r', POPT_ARG_VAL, &cfg->mode, MODE_RESET, "Reset INGA node (default)", + NULL }, + { "flash", 'f', POPT_ARG_VAL, &cfg->mode, MODE_UPDATE_EEPROM, "Update FTDI EEPROM of INGA", + NULL }, + { "serial", 's', POPT_ARG_VAL, &cfg->mode, MODE_READ_SERIAL, "Read the FTDI serial from its EEPROM", + NULL }, + { "device", 'd', POPT_ARG_STRING, &cfg->usb.device_path, 0, "Path to the serial device", + "pathname" }, + { "usbserial", 'u', POPT_ARG_STRING, &cfg->usb.device_serial, 0, "Serial of the FTDI to use", + "usbserial" }, + { "id", 'i', POPT_ARG_STRING, &cfg->usb.device_id, 0, "Limit choice to USB device id", + "device_id" }, + { "verbose", 'v', POPT_ARG_NONE, &cfg->verbose, 0, "Be verbose", + NULL }, + { "max-power", 'p', POPT_ARG_INT, &cfg->eep.max_power, 0, "Maximum current to draw from USB (mA)", + "current" }, + { "eui64", 'e', POPT_ARG_VAL, &cfg->mode, MODE_EUI64, "Print out INGAs EUI64", + NULL }, + POPT_AUTOHELP + { NULL, 0, 0, NULL, 0 } + }; + + cfg->mode = MODE_RESET; + + poptc = poptGetContext(NULL, argc, argv, options, 0); + + while ((rc = poptGetNextOpt(poptc)) >= 0) ; + + if (poptPeekArg(poptc) != NULL) { + poptPrintUsage(poptc, stderr, 0); + exit(EXIT_FAILURE); + } + + if (rc < -1) { + /* Option parsing error */ + fprintf(stderr, "%s: %s\n", poptBadOption(poptc, POPT_BADOPTION_NOALIAS), poptStrerror(rc)); + exit(EXIT_FAILURE); + } + + if (!cfg->usb.device_path && !cfg->usb.device_serial) { + usage(poptc, 1, "At least one of --device or --serial has to be set", ""); + } + + poptFreeContext(poptc); + + if (!cfg->usb.device_path) { + return; + } + + /* Resolve symlinks/relative paths */ + tmp = realpath(cfg->usb.device_path, NULL); + if (!tmp) { + perror("Could not open device"); + exit(EXIT_FAILURE); + } + + VERBOSE("Resolving path %s to %s\n", cfg->usb.device_path, tmp); + + free(cfg->usb.device_path); + cfg->usb.device_path = tmp; +} + +struct config_t *init_config(void) +{ + struct config_t *cfg = malloc(sizeof(struct config_t)); + + if (!cfg) { + return NULL; + } + + memset(cfg, 0, sizeof(struct config_t)); + + /* Set some sensible defaults + * Enable CBUS3 IO, keep vendor/product ID as is, + * set manufacturer to IBR and product string to INGA, + * keep serial, don't change the max power setting */ + cfg->eep.cbus[0] = CBUS_TXLED; + cfg->eep.cbus[1] = CBUS_RXLED; + cfg->eep.cbus[2] = CBUS_TXDEN; + cfg->eep.cbus[3] = CBUS_IOMODE; + cfg->eep.cbus[4] = CBUS_SLEEP; + cfg->eep.manufacturer = "IBR"; + cfg->eep.product = "INGA"; + cfg->eep.max_power = -1; + + return cfg; +} + +int main(int argc, const char **argv) +{ + struct config_t *cfg; + + cfg = init_config(); + if (!cfg) { + fprintf(stderr, "Could not initialize config\n"); + exit(EXIT_FAILURE); + } + + parse_options(argc, argv, cfg); + + VERBOSE("Config: path: %s, serial: %s, id: %s\n", cfg->usb.device_path, cfg->usb.device_serial, cfg->usb.device_id); + + if (cfg->mode == MODE_RESET) { + inga_reset(cfg); + } + else if (cfg->mode == MODE_UPDATE_EEPROM) { + inga_eeprom(cfg); + } + else if (cfg->mode == MODE_READ_SERIAL) { + inga_print_eeinfo(cfg); + } + else if (cfg->mode == MODE_EUI64) { + inga_eui64(cfg); + } + + exit(EXIT_SUCCESS); +} diff --git a/dist/tools/inga_tool/inga_usb.c b/dist/tools/inga_tool/inga_usb.c new file mode 100644 index 000000000000..d54ade53a074 --- /dev/null +++ b/dist/tools/inga_tool/inga_usb.c @@ -0,0 +1,848 @@ +/* Reset INGA nodes and configure their FTDI + * + * (C) 2011 Daniel Willmann + * (C) 2014 Sven Hesse + * All Rights Reserved + * + * 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 of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#if __linux__ +#include +#endif +#include + +#include "inga_usb.h" + +#define VERBOSE(args ...) \ + if (verbose) \ + fprintf(stderr, ## args) + +static void inga_usb_resolve(struct inga_usb_config_t *cfg, int verbose); + +#if FTDI_VERSION == 0 +/* Code specific to libftdi 0.x / libusb-0.1 */ + +#include + +struct inga_usb_device_t { + struct usb_device *usbdev; +}; + +struct inga_usb_ftdi_t { + struct ftdi_context ctx; + + struct ftdi_eeprom eeprom; + unsigned char eeprom_data[FTDI_DEFAULT_EEPROM_SIZE]; +}; + +struct inga_usb_device_t *inga_usb_find_device(struct inga_usb_config_t *cfg, int verbose) +{ + int rc; + struct usb_bus *bus; + struct inga_usb_device_t *usb; + struct usb_dev_handle *ufd; + long int busnum; + char *bus_end, buf[256]; + + inga_usb_resolve(cfg, verbose); + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + bus = usb_get_busses(); + + usb = (struct inga_usb_device_t *) malloc(sizeof(struct inga_usb_device_t)); + memset(usb, 0, sizeof(struct inga_usb_device_t)); + + /* Iterate over all devices in all busses and see if one matches */ + for (; bus != NULL; bus = bus->next) { + for (usb->usbdev = bus->devices; usb->usbdev != NULL; usb->usbdev = usb->usbdev->next) { + + /* Check if busnumber and devicenumber match */ + if ((cfg->busnum != 0) && (cfg->devnum != 0)) { + if (usb->usbdev->devnum != cfg->devnum) { + continue; + } + + /* Convert the bus number */ + busnum = strtol(usb->usbdev->bus->dirname, &bus_end, 10); + if (bus_end[0] == 0 && usb->usbdev->bus->dirname[0] != 0) { + if (busnum != cfg->busnum) { + continue; + } + } + VERBOSE("Found USB device matching %i:%i\n", cfg->busnum, cfg->devnum); + } + + /* Check if USB serial matches */ + if (cfg->device_serial) { + ufd = usb_open(usb->usbdev); + if (!ufd) { + continue; + } + if (!usb->usbdev->descriptor.iSerialNumber) { + usb_close(ufd); + continue; + } + rc = usb_get_string_simple(ufd, usb->usbdev->descriptor.iSerialNumber, buf, sizeof(buf)); + usb_close(ufd); + + if (rc <= 0 || strcmp(buf, cfg->device_serial)) { + continue; + } + + VERBOSE("Found USB serial %s on USB device %s:%i\n", cfg->device_serial, usb->usbdev->bus->dirname, usb->usbdev->devnum); + } + + VERBOSE("All requirements match, using %i:%i as target device\n", atoi(usb->usbdev->bus->dirname), usb->usbdev->devnum); + return usb; + } + } + + inga_usb_free_device(usb); + return NULL; +} + +int inga_usb_ftdi_reset(struct inga_usb_ftdi_t *ftdi) +{ + if (ftdi_usb_reset(&ftdi->ctx) < 0) { + return -1; + } + + if (usb_reset(ftdi->ctx.usb_dev) < 0) { + return -1; + } + + return 0; +} + +int inga_usb_ftdi_close(struct inga_usb_ftdi_t *ftdi) +{ + return ftdi_usb_close(&ftdi->ctx); +} + +void inga_usb_free_device(struct inga_usb_device_t *usb) +{ + free(usb); +} + + +int inga_usb_ftdi_eeprom_read(struct inga_usb_ftdi_t *ftdi) +{ + int rc; + + if ((rc = ftdi_read_eeprom(&ftdi->ctx, ftdi->eeprom_data)) < 0) { + return rc; + } + + if ((rc = ftdi_eeprom_decode(&ftdi->eeprom, ftdi->eeprom_data, sizeof(ftdi->eeprom_data))) < 0) { + return rc; + } + + /* Decode fails to set the size which is needed to build an image again */ + ftdi->eeprom.size = FTDI_DEFAULT_EEPROM_SIZE; + + if (ftdi->eeprom.chip_type != ftdi->ctx.type) { + fprintf(stderr, "WARNING: eeprom.chip_type (%d) != ctx.type (%d)\n", ftdi->eeprom.chip_type, ftdi->ctx.type); + } + + return 0; +} + +int inga_usb_ftdi_eeprom_write(struct inga_usb_ftdi_t *ftdi) +{ + int rc; + + if ((rc = ftdi_eeprom_build(&ftdi->eeprom, ftdi->eeprom_data)) < 0) { + return rc; + } + + if ((rc = ftdi_write_eeprom(&ftdi->ctx, ftdi->eeprom_data)) < 0) { + return rc; + } + + return 0; +} + +int inga_usb_ftdi_eeprom_get_value(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_value value_name, int *value) +{ + switch (value_name) { + case VENDOR_ID: + *value = ftdi->eeprom.vendor_id; + break; + case PRODUCT_ID: + *value = ftdi->eeprom.product_id; + break; + case SELF_POWERED: + *value = ftdi->eeprom.self_powered; + break; + case REMOTE_WAKEUP: + *value = ftdi->eeprom.remote_wakeup; + break; + case IN_IS_ISOCHRONOUS: + *value = ftdi->eeprom.in_is_isochronous; + break; + case OUT_IS_ISOCHRONOUS: + *value = ftdi->eeprom.out_is_isochronous; + break; + case SUSPEND_PULL_DOWNS: + *value = ftdi->eeprom.suspend_pull_downs; + break; + case USE_SERIAL: + *value = ftdi->eeprom.use_serial; + break; + case USB_VERSION: + *value = ftdi->eeprom.usb_version; + break; + case MAX_POWER: + *value = ftdi->eeprom.max_power; + break; + case CBUS_FUNCTION_0: + *value = ftdi->eeprom.cbus_function[0]; + break; + case CBUS_FUNCTION_1: + *value = ftdi->eeprom.cbus_function[1]; + break; + case CBUS_FUNCTION_2: + *value = ftdi->eeprom.cbus_function[2]; + break; + case CBUS_FUNCTION_3: + *value = ftdi->eeprom.cbus_function[3]; + break; + case CBUS_FUNCTION_4: + *value = ftdi->eeprom.cbus_function[4]; + break; + case CBUS_FUNCTION_5: + *value = 0; + break; + case CBUS_FUNCTION_6: + *value = 0; + break; + case CBUS_FUNCTION_7: + *value = 0; + break; + case CBUS_FUNCTION_8: + *value = 0; + break; + case CBUS_FUNCTION_9: + *value = 0; + break; + case INVERT: + *value = ftdi->eeprom.invert; + break; + case CHIP_TYPE: + *value = ftdi->eeprom.chip_type; + break; + case CHIP_SIZE: + *value = ftdi->eeprom.size; + break; + default: + return -1; + } + return 0; +} + +int inga_usb_ftdi_eeprom_set_value(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_value value_name, int value) +{ + switch (value_name) { + case VENDOR_ID: + ftdi->eeprom.vendor_id = value; + break; + case PRODUCT_ID: + ftdi->eeprom.product_id = value; + break; + case SELF_POWERED: + ftdi->eeprom.self_powered = value; + break; + case REMOTE_WAKEUP: + ftdi->eeprom.remote_wakeup = value; + break; + case IN_IS_ISOCHRONOUS: + ftdi->eeprom.in_is_isochronous = value; + break; + case OUT_IS_ISOCHRONOUS: + ftdi->eeprom.out_is_isochronous = value; + break; + case SUSPEND_PULL_DOWNS: + ftdi->eeprom.suspend_pull_downs = value; + break; + case USE_SERIAL: + ftdi->eeprom.use_serial = value; + break; + case USB_VERSION: + ftdi->eeprom.usb_version = value; + break; + case MAX_POWER: + ftdi->eeprom.max_power = value; + break; + case CBUS_FUNCTION_0: + ftdi->eeprom.cbus_function[0] = value; + break; + case CBUS_FUNCTION_1: + ftdi->eeprom.cbus_function[1] = value; + break; + case CBUS_FUNCTION_2: + ftdi->eeprom.cbus_function[2] = value; + break; + case CBUS_FUNCTION_3: + ftdi->eeprom.cbus_function[3] = value; + break; + case CBUS_FUNCTION_4: + ftdi->eeprom.cbus_function[4] = value; + break; + case CBUS_FUNCTION_5: + ftdi->eeprom.cbus_function[5] = value; + break; + case CBUS_FUNCTION_6: + ftdi->eeprom.cbus_function[6] = value; + break; + case CBUS_FUNCTION_7: + ftdi->eeprom.cbus_function[7] = value; + break; + case CBUS_FUNCTION_8: + ftdi->eeprom.cbus_function[8] = value; + break; + case CBUS_FUNCTION_9: + ftdi->eeprom.cbus_function[9] = value; + break; + case INVERT: + ftdi->eeprom.invert = value; + break; + case CHIP_TYPE: + ftdi->eeprom.chip_type = value; + break; + case CHIP_SIZE: + return -1; + default: + return -1; + } + return 0; +} + +int inga_usb_ftdi_eeprom_get_string(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_string string_name, const char **str) +{ + *str = NULL; + + switch (string_name) { + case MANUFACTURER_STRING: + *str = ftdi->eeprom.manufacturer; + break; + + case PRODUCT_STRING: + *str = ftdi->eeprom.product; + break; + + case SERIAL_STRING: + *str = ftdi->eeprom.serial; + break; + + default: + return -1; + } + + return 0; +} + +int inga_usb_ftdi_eeprom_set_string(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_string string_name, const char *str) +{ + char **dst = NULL; + + switch (string_name) { + case MANUFACTURER_STRING: + dst = &ftdi->eeprom.manufacturer; + break; + + case PRODUCT_STRING: + dst = &ftdi->eeprom.product; + break; + + case SERIAL_STRING: + dst = &ftdi->eeprom.serial; + break; + + default: + return -1; + } + + if (*dst == str) { + return 0; + } + + free(*dst); + *dst = NULL; + + if (str) { + *dst = strdup(str); + } + + return 0; +} + + +#elif FTDI_VERSION == 1 +/* Code specific to libftdi 1.x / libusb-1.x */ + +#include + +#define FTDI_DEFAULT_EEPROM_SIZE 256 +#define FTDI_EEPROM_VALUES CHANNEL_D_RS485 + +struct inga_usb_device_t { + libusb_context *usbctx; + + struct libusb_device *usbdev; +}; + +struct inga_usb_ftdi_t { + struct ftdi_context ctx; + + char *eeprom_manufacturer; + char *eeprom_product; + char *eeprom_serial; + + int eeprom_values[FTDI_EEPROM_VALUES]; +}; + +struct inga_usb_device_t *inga_usb_find_device(struct inga_usb_config_t *cfg, int verbose) +{ + struct inga_usb_device_t *usb; + libusb_device **dev_list = NULL; + ssize_t dev_count, i, j; + + inga_usb_resolve(cfg, verbose); + + usb = (struct inga_usb_device_t *) malloc(sizeof(struct inga_usb_device_t)); + memset(usb, 0, sizeof(struct inga_usb_device_t)); + + libusb_init(&usb->usbctx); + + dev_count = libusb_get_device_list(usb->usbctx, &dev_list); + if (dev_count < 0) { + fprintf(stderr, "Failed get USB device list\n"); + exit(EXIT_FAILURE); + } + + /* Iterate over all devices and see if one matches */ + for (i = 0; i < dev_count; i++) { + usb->usbdev = dev_list[i]; + + if ((cfg->busnum != 0) && (cfg->devnum != 0)) { + if ((libusb_get_bus_number(usb->usbdev) != cfg->busnum) || (libusb_get_device_address(usb->usbdev) != cfg->devnum)) { + continue; + } + + VERBOSE("Found USB device matching %i:%i\n", cfg->busnum, cfg->devnum); + } + + /* Check if USB serial matches */ + if (cfg->device_serial) { + struct libusb_device_descriptor desc; + libusb_device_handle *handle; + char buf[256]; + int rc; + + if (libusb_get_device_descriptor(usb->usbdev, &desc) != 0) { + continue; + } + + if (!desc.iSerialNumber) { + continue; + } + + if (libusb_open(usb->usbdev, &handle) < 0) { + continue; + } + + rc = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)buf, sizeof(buf)); + libusb_close(handle); + + if (rc <= 0 || strcmp(buf, cfg->device_serial)) { + continue; + } + + VERBOSE("Found USB serial %s on USB device %i:%i\n", cfg->device_serial, + libusb_get_bus_number(usb->usbdev), libusb_get_device_address(usb->usbdev)); + } + + VERBOSE("All requirements match, using %i:%i as target device\n", + libusb_get_bus_number(usb->usbdev), libusb_get_device_address(usb->usbdev)); + + /* Unreference the devices we are not going to use */ + for (j = 0; j < dev_count; j++) + if (dev_list[j] != usb->usbdev) { + libusb_unref_device(dev_list[j]); + } + + libusb_free_device_list(dev_list, 0); + return usb; + } + + libusb_free_device_list(dev_list, 1); + inga_usb_free_device(usb); + return NULL; +} + +int inga_usb_ftdi_reset(struct inga_usb_ftdi_t *ftdi) +{ + if (ftdi_usb_reset(&ftdi->ctx) < 0) { + return -1; + } + + if (libusb_reset_device(ftdi->ctx.usb_dev) < 1) { + return -1; + } + + return 0; +} + +int inga_usb_ftdi_close(struct inga_usb_ftdi_t *ftdi) +{ + libusb_device *dev = NULL; + int interface; + + /* Remember the USB device and ftdi_sio interface */ + if (ftdi->ctx.usb_dev) { + dev = libusb_get_device(ftdi->ctx.usb_dev); + interface = ftdi->ctx.interface; + } + + /* Close the FTDI */ + if (ftdi_usb_close(&ftdi->ctx) < 0) { + return -1; + } + + /* Reattach the ftdi_sio kernel module to the USB device */ + if (dev) { + libusb_device_handle *handle = NULL; + + if (libusb_open(dev, &handle) >= 0) { + libusb_attach_kernel_driver(handle, interface); + libusb_close(handle); + } + } + + return 0; +} + +void inga_usb_free_device(struct inga_usb_device_t *usb) +{ + if (!usb) { + return; + } + + if (usb->usbdev) { + libusb_unref_device(usb->usbdev); + } + + if (usb->usbctx) { + libusb_exit(usb->usbctx); + } + + free(usb); +} + +static void inga_usb_read_eeprom_string(char **str, const char *buf, int offset, int length) +{ + int i; + + free(*str); + *str = NULL; + + if (length > 0) { + *str = malloc(length); + + for (i = 0; i < length - 1; i++) + (*str)[i] = buf[2 + offset + 2 * i]; + (*str)[i] = '\0'; + } +} + +int inga_usb_ftdi_eeprom_read(struct inga_usb_ftdi_t *ftdi) +{ + int rc; + char buf[FTDI_DEFAULT_EEPROM_SIZE]; + int string_size, eeprom_size, i; + + if ((rc = ftdi_read_eeprom(&ftdi->ctx)) < 0) { + return rc; + } + + if ((rc = ftdi_eeprom_decode(&ftdi->ctx, 0)) < 0) { + return rc; + } + + if ((rc = ftdi_get_eeprom_buf(&ftdi->ctx, (unsigned char *)buf, sizeof(buf))) < 0) { + return rc; + } + + if ((rc = ftdi_get_eeprom_value(&ftdi->ctx, CHIP_SIZE, &eeprom_size)) < 0) { + return rc; + } + + inga_usb_read_eeprom_string(&ftdi->eeprom_manufacturer, buf, buf[0x0E] & (eeprom_size - 1), buf[0x0F] / 2); + inga_usb_read_eeprom_string(&ftdi->eeprom_product, buf, buf[0x10] & (eeprom_size - 1), buf[0x11] / 2); + inga_usb_read_eeprom_string(&ftdi->eeprom_serial, buf, buf[0x12] & (eeprom_size - 1), buf[0x13] / 2); + + return 0; +} + +static void inga_usb_ftdi_read_eeprom_values(struct inga_usb_ftdi_t *ftdi) +{ + int i; + + for (i = 0; i < FTDI_EEPROM_VALUES; i++) + ftdi_get_eeprom_value(&ftdi->ctx, i, &ftdi->eeprom_values[i]); +} + +static void inga_usb_ftdi_write_eeprom_values(struct inga_usb_ftdi_t *ftdi) +{ + int i; + + for (i = 0; i < FTDI_EEPROM_VALUES; i++) + ftdi_set_eeprom_value(&ftdi->ctx, i, ftdi->eeprom_values[i]); +} + +int inga_usb_ftdi_eeprom_write(struct inga_usb_ftdi_t *ftdi) +{ + int rc; + + /* ftdi_eeprom_initdefaults() is the only way to change the manufacturer, product and serial strings, + but that function also clobbers everything else. Therefore, we save all EEPROM values beforehand + and restore them afterwards. + */ + + inga_usb_ftdi_read_eeprom_values(ftdi); + + if ((rc = ftdi_eeprom_initdefaults(&ftdi->ctx, + ftdi->eeprom_manufacturer, ftdi->eeprom_product, ftdi->eeprom_serial)) < 0) { + return rc; + } + + inga_usb_ftdi_write_eeprom_values(ftdi); + + + if ((rc = ftdi_eeprom_build(&ftdi->ctx)) < 0) { + return rc; + } + + if ((rc = ftdi_write_eeprom(&ftdi->ctx)) < 0) { + return rc; + } + + return 0; +} + +int inga_usb_ftdi_eeprom_get_value(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_value value_name, int *value) +{ + int rc; + + if ((rc = ftdi_get_eeprom_value(&ftdi->ctx, value_name, value) < 0)) { + return rc; + } + + if (value_name == MAX_POWER) { + *value /= 2; + } + + return rc; +} + +int inga_usb_ftdi_eeprom_set_value(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_value value_name, int value) +{ + if (value_name == MAX_POWER) { + value *= 2; + } + + return ftdi_set_eeprom_value(&ftdi->ctx, value_name, value); +} + +int inga_usb_ftdi_eeprom_get_string(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_string string_name, const char **str) +{ + *str = NULL; + + switch (string_name) { + case MANUFACTURER_STRING: + *str = ftdi->eeprom_manufacturer; + break; + + case PRODUCT_STRING: + *str = ftdi->eeprom_product; + break; + + case SERIAL_STRING: + *str = ftdi->eeprom_serial; + break; + + default: + return -1; + } + + return 0; +} + +int inga_usb_ftdi_eeprom_set_string(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_string string_name, const char *str) +{ + char **dst = NULL; + + switch (string_name) { + case MANUFACTURER_STRING: + dst = &ftdi->eeprom_manufacturer; + break; + + case PRODUCT_STRING: + dst = &ftdi->eeprom_product; + break; + + case SERIAL_STRING: + dst = &ftdi->eeprom_serial; + break; + + default: + return -1; + } + + if (*dst == str) { + return 0; + } + + free(*dst); + *dst = NULL; + + if (str) { + *dst = strdup(str); + } + + return 0; +} + +#else + #error Unrecognized libftdi version +#endif + + +/* Code common to libftdi 0.x / libusb-0.1 and libftdi 1.x / libusb-1.x */ + +/* Use udev to find the USB bus and device numbers a ttyUSB device is connected to */ +static void inga_usb_resolve(struct inga_usb_config_t *cfg, int verbose) +{ +#if __linux__ + int rc; + struct udev *udev; + struct udev_device *dev; + char *devpath; + const char *devnum, *busnum; + + if (cfg->device_path) { + udev = udev_new(); + if (!udev) { + fprintf(stderr, "Failed to initialize udev\n"); + exit(EXIT_FAILURE); + } + + rc = asprintf(&devpath, "/sys/class/tty/%s", basename(cfg->device_path)); + if (rc < 0) { + fprintf(stderr, "Failed to generate sysfs path\n"); + exit(EXIT_FAILURE); + } + + dev = udev_device_new_from_syspath(udev, devpath); + free(devpath); + if (!dev) { + fprintf(stderr, "Failed get udev device\n"); + exit(EXIT_FAILURE); + } + + while (dev) { + busnum = udev_device_get_sysattr_value(dev, "busnum"); + devnum = udev_device_get_sysattr_value(dev, "devnum"); + + if (busnum && devnum) { + /* TODO: Check conversion errors */ + cfg->busnum = atoi(busnum); + cfg->devnum = atoi(devnum); + VERBOSE("Device %s resolved to USB device %i:%i\n", cfg->device_path, cfg->busnum, cfg->devnum); + break; + } + + dev = udev_device_get_parent(dev); + } + udev_unref(udev); + + if (cfg->busnum == 0 || cfg->devnum == 0) { + fprintf(stderr, "Failed to resolve %s to USB device\n", cfg->device_path); + exit(EXIT_FAILURE); + } + } +#endif +} + +int inga_usb_ftdi_init(struct inga_usb_ftdi_t **ftdi) +{ + *ftdi = (struct inga_usb_ftdi_t *) malloc(sizeof(struct inga_usb_ftdi_t)); + memset(*ftdi, 0, sizeof(struct inga_usb_ftdi_t)); + + return ftdi_init(&(*ftdi)->ctx); +} + +void inga_usb_ftdi_deinit(struct inga_usb_ftdi_t *ftdi) +{ + if (!ftdi) { + return; + } + + ftdi_deinit(&ftdi->ctx); + + free(ftdi); +} + +int inga_usb_ftdi_open(struct inga_usb_ftdi_t *ftdi, struct inga_usb_device_t *usb) +{ + return ftdi_usb_open_dev(&ftdi->ctx, usb->usbdev); +} + +int inga_usb_ftdi_set_bitmode(struct inga_usb_ftdi_t *ftdi, unsigned char bitmask, unsigned char mode) +{ + return ftdi_set_bitmode(&ftdi->ctx, bitmask, mode); +} + +int inga_usb_ftdi_get_chip_type(struct inga_usb_ftdi_t *ftdi) +{ + return ftdi->ctx.type; +} + + +char *inga_usb_ftdi_get_error_string(struct inga_usb_ftdi_t *ftdi) +{ + return ftdi_get_error_string(&ftdi->ctx); +} diff --git a/dist/tools/inga_tool/inga_usb.h b/dist/tools/inga_tool/inga_usb.h new file mode 100644 index 000000000000..bc0c8ad9efe3 --- /dev/null +++ b/dist/tools/inga_tool/inga_usb.h @@ -0,0 +1,111 @@ +/* Reset INGA nodes and configure their FTDI + * + * (C) 2011 Daniel Willmann + * (C) 2014 Sven Hesse + * All Rights Reserved + * + * 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 of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +#ifndef INGA_USB_H +#define INGA_USB_H + +#include + +#if FTDI_VERSION == 0 +enum ftdi_eeprom_value { + VENDOR_ID = 0, + PRODUCT_ID = 1, + SELF_POWERED = 2, + REMOTE_WAKEUP = 3, + IN_IS_ISOCHRONOUS = 6, + OUT_IS_ISOCHRONOUS = 7, + SUSPEND_PULL_DOWNS = 8, + USE_SERIAL = 9, + USB_VERSION = 10, + MAX_POWER = 12, + CBUS_FUNCTION_0 = 17, + CBUS_FUNCTION_1 = 18, + CBUS_FUNCTION_2 = 19, + CBUS_FUNCTION_3 = 20, + CBUS_FUNCTION_4 = 21, + CBUS_FUNCTION_5 = 22, + CBUS_FUNCTION_6 = 23, + CBUS_FUNCTION_7 = 24, + CBUS_FUNCTION_8 = 25, + CBUS_FUNCTION_9 = 26, + INVERT = 30, + CHIP_SIZE = 43, + CHIP_TYPE = 44, +}; +#endif /* FTDI_VERSION == 0 */ + +enum ftdi_eeprom_string { + MANUFACTURER_STRING = 0, + PRODUCT_STRING = 1, + SERIAL_STRING = 2 +}; + +struct inga_usb_config_t { + char *device_path; + char *device_serial; + char *device_id; + + int busnum; + int devnum; +}; + +struct inga_usb_device_t; +struct inga_usb_ftdi_t; + +struct inga_usb_device_t *inga_usb_find_device(struct inga_usb_config_t *cfg, int verbose); + +void inga_usb_free_device(struct inga_usb_device_t *usb); + +int inga_usb_ftdi_init(struct inga_usb_ftdi_t **ftdi); +void inga_usb_ftdi_deinit(struct inga_usb_ftdi_t *ftdi); + +int inga_usb_ftdi_open(struct inga_usb_ftdi_t *ftdi, struct inga_usb_device_t *usb); +int inga_usb_ftdi_close(struct inga_usb_ftdi_t *ftdi); + +int inga_usb_ftdi_reset(struct inga_usb_ftdi_t *ftdi); + +int inga_usb_ftdi_eeprom_read(struct inga_usb_ftdi_t *ftdi); +int inga_usb_ftdi_eeprom_write(struct inga_usb_ftdi_t *ftdi); + +int inga_usb_ftdi_eeprom_get_value(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_value value_name, int *value); +int inga_usb_ftdi_eeprom_set_value(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_value value_name, int value); + +int inga_usb_ftdi_eeprom_get_string(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_string string_name, const char **str); +int inga_usb_ftdi_eeprom_set_string(struct inga_usb_ftdi_t *ftdi, enum ftdi_eeprom_string string_name, const char *str); + +int inga_usb_ftdi_set_bitmode(struct inga_usb_ftdi_t *ftdi, unsigned char bitmask, unsigned char mode); + +int inga_usb_ftdi_get_chip_type(struct inga_usb_ftdi_t *ftdi); + +char *inga_usb_ftdi_get_error_string(struct inga_usb_ftdi_t *ftdi); + +#endif /* INGA_USB_H */ diff --git a/makefiles/tools/inga_tool.inc.mk b/makefiles/tools/inga_tool.inc.mk new file mode 100644 index 000000000000..d5525a5902ad --- /dev/null +++ b/makefiles/tools/inga_tool.inc.mk @@ -0,0 +1,4 @@ +export FLASHER = $(RIOTBASE)/dist/tools/inga_tool/inga_tool +# Using the FFLAGS here to append the port for the inga_tool and avrdude +export FFLAGS = -d $(PORT) -r && avrdude -c avr109 -p m1284p -P $(PORT) -b 230400 -u -U flash:w:$(HEXFILE) +FLASHDEPS += $(RIOTBASE)/dist/tools/inga_tool/inga_tool diff --git a/makefiles/tools/targets.inc.mk b/makefiles/tools/targets.inc.mk index 4be923a92a05..f7e7d26911a9 100644 --- a/makefiles/tools/targets.inc.mk +++ b/makefiles/tools/targets.inc.mk @@ -14,3 +14,8 @@ $(RIOTBASE)/dist/tools/edbg/edbg: @echo "[INFO] edbg binary not found - building it from source now" CC= CFLAGS= make -C $(RIOTBASE)/dist/tools/edbg @echo "[INFO] edbg binary successfully build!" + +$(RIOTBASE)/dist/tools/inga_tool/inga_tool: + @echo "[INFO] inga_tool binary not found - building it from source" + @make -C $(RIOTBASE)/dist/tools/inga_tool + @echo "[INFO] inga_tool binary successfully build!" From 6a927cf88fdd8157cf91c5d4735a5c85267d740d Mon Sep 17 00:00:00 2001 From: Robert Hartung Date: Mon, 25 Sep 2017 10:17:42 +0200 Subject: [PATCH 2/9] cpu: adds atmega1284p boards: adds INGA --- cpu/atmega1284p/Makefile | 7 +++ cpu/atmega1284p/Makefile.include | 9 ++++ cpu/atmega1284p/cpu.c | 50 +++++++++++++++++++ cpu/atmega1284p/include/cpu_conf.h | 48 ++++++++++++++++++ cpu/atmega1284p/include/periph_cpu.h | 55 +++++++++++++++++++++ cpu/atmega1284p/periph/Makefile | 2 + cpu/atmega1284p/startup.c | 73 ++++++++++++++++++++++++++++ cpu/atmega_common/periph/spi.c | 7 ++- 8 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 cpu/atmega1284p/Makefile create mode 100644 cpu/atmega1284p/Makefile.include create mode 100644 cpu/atmega1284p/cpu.c create mode 100644 cpu/atmega1284p/include/cpu_conf.h create mode 100644 cpu/atmega1284p/include/periph_cpu.h create mode 100644 cpu/atmega1284p/periph/Makefile create mode 100644 cpu/atmega1284p/startup.c diff --git a/cpu/atmega1284p/Makefile b/cpu/atmega1284p/Makefile new file mode 100644 index 000000000000..6fdcb1bb0669 --- /dev/null +++ b/cpu/atmega1284p/Makefile @@ -0,0 +1,7 @@ +# define the module that is build +MODULE = cpu + +# add a list of subdirectories, that should also be build +DIRS = periph $(RIOTCPU)/atmega_common + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/atmega1284p/Makefile.include b/cpu/atmega1284p/Makefile.include new file mode 100644 index 000000000000..398e48eb3f8d --- /dev/null +++ b/cpu/atmega1284p/Makefile.include @@ -0,0 +1,9 @@ +# tell the build system that the CPU depends on the atmega common files +USEMODULE += atmega_common + +# explicitly tell the linker to link the syscalls and startup code. +# Without this the interrupt vectors will not be linked correctly! +export UNDEF += $(BINDIR)/cpu/startup.o + +# CPU depends on the atmega common module, so include it +include $(RIOTCPU)/atmega_common/Makefile.include diff --git a/cpu/atmega1284p/cpu.c b/cpu/atmega1284p/cpu.c new file mode 100644 index 000000000000..cb38a6405ea3 --- /dev/null +++ b/cpu/atmega1284p/cpu.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016 Robert Hartung + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_atmega1284p + * @{ + * + * @file + * @brief Implementation of the CPU initialization + * + * @author Robert Hartung + * @} + */ + +#include "cpu.h" +#include "periph/init.h" +#include + +#if (__AVR_LIBC_VERSION__ >= 10700UL) +/* The proper way to set the signature is */ +#include +#else + +/* signature API not available before avr-lib-1.7.0. Do it manually.*/ +typedef struct { + const unsigned char B2; + const unsigned char B1; + const unsigned char B0; +} __signature_t; +#define SIGNATURE __signature_t __signature __attribute__((section(".signature"))) +SIGNATURE = { + .B2 = 0x05, //SIGNATURE_2, //ATMEGA1284p + .B1 = 0x97, //SIGNATURE_1, //128KB flash + .B0 = 0x1E, //SIGNATURE_0, //Atmel +}; +#endif /* (__AVR_LIBC_VERSION__ >= 10700UL) */ + +/** + * @brief Initialize the CPU, set IRQ priorities + */ +void cpu_init(void) +{ + wdt_disable(); + periph_init(); +} diff --git a/cpu/atmega1284p/include/cpu_conf.h b/cpu/atmega1284p/include/cpu_conf.h new file mode 100644 index 000000000000..1e8ca656dfbb --- /dev/null +++ b/cpu/atmega1284p/include/cpu_conf.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2016 Robert Hartung + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file + * @brief Implementation specific CPU configuration options + * + * @author Robert Hartung + */ + +#ifndef CPU_CONF_H +#define CPU_CONF_H + +#include "atmega_regs_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Kernel configuration + * + * Since printf seems to get memory allocated by the linker/avr-libc the stack + * size tested sucessfully even with pretty small stacks.k + * @{ + */ +#define THREAD_EXTRA_STACKSIZE_PRINTF (256) + +#ifndef THREAD_STACKSIZE_DEFAULT +#define THREAD_STACKSIZE_DEFAULT (256) +#endif + +#define THREAD_STACKSIZE_IDLE (128) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* CPU_CONF_H */ +/** @} */ diff --git a/cpu/atmega1284p/include/periph_cpu.h b/cpu/atmega1284p/include/periph_cpu.h new file mode 100644 index 000000000000..2e292a554138 --- /dev/null +++ b/cpu/atmega1284p/include/periph_cpu.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 Technische Universität Braunschweig, IBR + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_atmega1284p + * @{ + * + * @file + * @brief CPU specific definitions for internal peripheral handling + * + * @author Robert Hartung + */ + +#ifndef PERIPH_CPU_H_ +#define PERIPH_CPU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "periph_cpu_common.h" + +/** + * @brief Available ports on the ATmega1281 family + */ +enum { + PORT_A = 0, /**< port A */ + PORT_B = 1, /**< port B */ + PORT_C = 2, /**< port C */ + PORT_D = 3, /**< port D */ + PORT_E = 4, /**< port E */ + PORT_F = 5, /**< port F */ + PORT_G = 6, /**< port G */ +}; + +/** + * @name Defines for the I2C interface + * @{ + */ +#define I2C_PORT_REG PORTD +#define I2C_PIN_MASK (1 << PORTD1) | (1 << PORTD0) +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CPU_H_ */ +/** @} */ diff --git a/cpu/atmega1284p/periph/Makefile b/cpu/atmega1284p/periph/Makefile new file mode 100644 index 000000000000..87a55ed6845f --- /dev/null +++ b/cpu/atmega1284p/periph/Makefile @@ -0,0 +1,2 @@ +MODULE = periph +include $(RIOTBASE)/Makefile.base diff --git a/cpu/atmega1284p/startup.c b/cpu/atmega1284p/startup.c new file mode 100644 index 000000000000..027fdbeeca9b --- /dev/null +++ b/cpu/atmega1284p/startup.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 TU Braunschweig, IBR, Robert Hartung + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_atmega1284p + * @{ + * + * @file + * @brief Startup code and interrupt vector definition + * + * @author Hinnerk van Bruinehsen + * @author Robert Hartung + * + * @} + */ + +#include +#include +#include + +/* For Catchall-Loop */ +#include "board.h" + +/** + * @brief functions for initializing the board, std-lib and kernel + */ +extern void board_init(void); +extern void kernel_init(void); +extern void __libc_init_array(void); + +/** + * @brief This pair of functions hook circumvent the call to main + * + * avr-libc normally uses the .init9 section for a call to main. This call + * seems to be not replaceable without hacking inside the library. We + * circumvent the call to main by using section .init7 to call the function + * reset_handler which therefore is the real entry point and section .init8 + * which should never be reached but just in case jumps to exit. + * This way there should be no way to call main directly. + */ +void init7_ovr(void) __attribute__((naked)) __attribute__((section(".init7"))); +void init8_ovr(void) __attribute__((naked)) __attribute__((section(".init8"))); + + +__attribute__((used, naked)) void init7_ovr(void) +{ + __asm__ ("call reset_handler"); +} + +__attribute__((used, naked)) void init8_ovr(void) +{ + __asm__ ("jmp exit"); +} + +/** + * @brief This function is the entry point after a system reset + * + * After a system reset, the following steps are necessary and carried out: + * 1. initialize the board (sync clock, setup std-IO) + * 2. initialize and start RIOTs kernel + */ +__attribute__((used)) void reset_handler(void) +{ + /* initialize the board and startup the kernel */ + board_init(); + /* startup the kernel */ + kernel_init(); +} diff --git a/cpu/atmega_common/periph/spi.c b/cpu/atmega_common/periph/spi.c index 6b89e73e7bc0..fb004fa7fd1f 100644 --- a/cpu/atmega_common/periph/spi.c +++ b/cpu/atmega_common/periph/spi.c @@ -53,9 +53,12 @@ void spi_init_pins(spi_t bus) /* set SPI pins as output */ #if defined (CPU_ATMEGA2560) || defined (CPU_ATMEGA1281) DDRB |= ((1 << DDB2) | (1 << DDB1) | (1 << DDB0)); -#endif -#ifdef CPU_ATMEGA328P +#elif defined(CPU_ATMEGA328P) DDRB |= ((1 << DDB2) | (1 << DDB3) | (1 << DDB5)); +#elif defined(CPU_ATMEGA1284P) + DDRB |= ((1 << DDB5) | (1 << DDB7) | (1 << DDB4)); +#else +#warning please add the correct SPI pin configuration for your MCU to periph/spi.c #endif } From 8c81727adf9016c59570aa61a50cc6ed1a175758 Mon Sep 17 00:00:00 2001 From: Robert Hartung Date: Mon, 25 Sep 2017 10:19:44 +0200 Subject: [PATCH 3/9] boards/inga: adds all four versions --- boards/inga_blue/Makefile | 3 + boards/inga_blue/Makefile.dep | 3 + boards/inga_blue/Makefile.features | 1 + boards/inga_blue/Makefile.include | 12 ++ boards/inga_blue/include/board.h | 28 +++++ boards/inga_blue/include/periph_conf.h | 32 ++++++ boards/inga_common/Makefile | 3 + boards/inga_common/Makefile.features | 11 ++ boards/inga_common/Makefile.include | 11 ++ boards/inga_common/board.c | 77 +++++++++++++ boards/inga_common/include/board_common.h | 73 ++++++++++++ .../inga_common/include/periph_conf_common.h | 105 ++++++++++++++++++ boards/inga_green/Makefile | 3 + boards/inga_green/Makefile.dep | 3 + boards/inga_green/Makefile.features | 1 + boards/inga_green/Makefile.include | 11 ++ boards/inga_green/include/board.h | 49 ++++++++ boards/inga_green/include/periph_conf.h | 32 ++++++ boards/inga_red/Makefile | 3 + boards/inga_red/Makefile.dep | 3 + boards/inga_red/Makefile.features | 1 + boards/inga_red/Makefile.include | 11 ++ boards/inga_red/include/board.h | 49 ++++++++ boards/inga_red/include/periph_conf.h | 32 ++++++ boards/inga_white/Makefile | 3 + boards/inga_white/Makefile.dep | 3 + boards/inga_white/Makefile.features | 1 + boards/inga_white/Makefile.include | 11 ++ boards/inga_white/include/board.h | 49 ++++++++ boards/inga_white/include/periph_conf.h | 32 ++++++ examples/default/Makefile | 3 +- 31 files changed, 658 insertions(+), 1 deletion(-) create mode 100644 boards/inga_blue/Makefile create mode 100644 boards/inga_blue/Makefile.dep create mode 100644 boards/inga_blue/Makefile.features create mode 100644 boards/inga_blue/Makefile.include create mode 100644 boards/inga_blue/include/board.h create mode 100644 boards/inga_blue/include/periph_conf.h create mode 100644 boards/inga_common/Makefile create mode 100644 boards/inga_common/Makefile.features create mode 100644 boards/inga_common/Makefile.include create mode 100644 boards/inga_common/board.c create mode 100644 boards/inga_common/include/board_common.h create mode 100644 boards/inga_common/include/periph_conf_common.h create mode 100644 boards/inga_green/Makefile create mode 100644 boards/inga_green/Makefile.dep create mode 100644 boards/inga_green/Makefile.features create mode 100644 boards/inga_green/Makefile.include create mode 100644 boards/inga_green/include/board.h create mode 100644 boards/inga_green/include/periph_conf.h create mode 100644 boards/inga_red/Makefile create mode 100644 boards/inga_red/Makefile.dep create mode 100644 boards/inga_red/Makefile.features create mode 100644 boards/inga_red/Makefile.include create mode 100644 boards/inga_red/include/board.h create mode 100644 boards/inga_red/include/periph_conf.h create mode 100644 boards/inga_white/Makefile create mode 100644 boards/inga_white/Makefile.dep create mode 100644 boards/inga_white/Makefile.features create mode 100644 boards/inga_white/Makefile.include create mode 100644 boards/inga_white/include/board.h create mode 100644 boards/inga_white/include/periph_conf.h diff --git a/boards/inga_blue/Makefile b/boards/inga_blue/Makefile new file mode 100644 index 000000000000..323e91da13d4 --- /dev/null +++ b/boards/inga_blue/Makefile @@ -0,0 +1,3 @@ +MODULE = board +DIRS = $(RIOTBOARD)/inga_common +include $(RIOTBASE)/Makefile.base diff --git a/boards/inga_blue/Makefile.dep b/boards/inga_blue/Makefile.dep new file mode 100644 index 000000000000..f6936323ba9f --- /dev/null +++ b/boards/inga_blue/Makefile.dep @@ -0,0 +1,3 @@ +ifneq (,$(filter netdev_default gnrc_netdev_default,$(USEMODULE))) + USEMODULE += at86rf233 +endif diff --git a/boards/inga_blue/Makefile.features b/boards/inga_blue/Makefile.features new file mode 100644 index 000000000000..474c3960294a --- /dev/null +++ b/boards/inga_blue/Makefile.features @@ -0,0 +1 @@ +include $(RIOTBOARD)/inga_common/Makefile.features diff --git a/boards/inga_blue/Makefile.include b/boards/inga_blue/Makefile.include new file mode 100644 index 000000000000..c5d45405c2fc --- /dev/null +++ b/boards/inga_blue/Makefile.include @@ -0,0 +1,12 @@ +USEMODULE += inga_common + +export FLASHER = avrdude +# JTAG ICE mkII +export FFLAGS = -c jtag2isp -p m1284p -P usb -u -U flash:w:$(HEXFILE) + +export INCLUDES += -I$(RIOTBOARD)/inga_common/include/ + +# setup the boards dependencies +include $(RIOTBOARD)/$(BOARD)/Makefile.dep + +include $(RIOTBOARD)/inga_common/Makefile.include diff --git a/boards/inga_blue/include/board.h b/boards/inga_blue/include/board.h new file mode 100644 index 000000000000..3a9e97a2499b --- /dev/null +++ b/boards/inga_blue/include/board.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 Robert Hartung + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef INGA_COMMON_BOARD_H_ +#define INGA_COMMON_BOARD_H_ + +#include "cpu.h" +#include "periph_conf.h" +#include "periph/gpio.h" +#include "board_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* the blue inga does not have any LEDs or buttons */ + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* INGA_COMMON_BOARD_H_ */ diff --git a/boards/inga_blue/include/periph_conf.h b/boards/inga_blue/include/periph_conf.h new file mode 100644 index 000000000000..4348e21716cd --- /dev/null +++ b/boards/inga_blue/include/periph_conf.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 TU Braunschweig, IBR + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_inga_red + * @{ + * + * @file + * @brief Peripheral MCU configuration for the INGA red board + * + * @author Robert Hartung + */ + +#ifndef PERIPH_CONF_H_ +#define PERIPH_CONF_H_ + +#include "periph_conf_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H_ */ diff --git a/boards/inga_common/Makefile b/boards/inga_common/Makefile new file mode 100644 index 000000000000..8b72586e210d --- /dev/null +++ b/boards/inga_common/Makefile @@ -0,0 +1,3 @@ +MODULE = inga_common + +include $(RIOTBASE)/Makefile.base diff --git a/boards/inga_common/Makefile.features b/boards/inga_common/Makefile.features new file mode 100644 index 000000000000..b2090575bdb4 --- /dev/null +++ b/boards/inga_common/Makefile.features @@ -0,0 +1,11 @@ +# Put defined MCU peripherals here (in alphabetical order) +FEATURES_PROVIDED += periph_gpio +FEATURES_PROVIDED += periph_spi +FEATURES_PROVIDED += periph_timer +FEATURES_PROVIDED += periph_uart +FEATURES_PROVIDED += periph_i2c + +#FEATURES_PROVIDED += adxl345 + +# The board MPU family (used for grouping by the CI system) +FEATURES_MCU_GROUP = avr8 diff --git a/boards/inga_common/Makefile.include b/boards/inga_common/Makefile.include new file mode 100644 index 000000000000..f534ddae420b --- /dev/null +++ b/boards/inga_common/Makefile.include @@ -0,0 +1,11 @@ +## the cpu to build for +export CPU = atmega1284p + +# flash tool configuration +export OFLAGS = -j .text -j .data -O ihex + +# set default port depending on operating system +PORT_LINUX ?= $(firstword $(sort $(wildcard /dev/ttyUSB*))) +# setup serial terminal +export BAUD ?= 19200 +include $(RIOTMAKE)/tools/serial.inc.mk diff --git a/boards/inga_common/board.c b/boards/inga_common/board.c new file mode 100644 index 000000000000..44a4401ff215 --- /dev/null +++ b/boards/inga_common/board.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2017 Robert Hartung + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_inga_common + * @{ + * + * @file + * @brief Common implementations for the INGA boards + * + * @author Robert Hartung + * + * @} + */ + +#include "cpu.h" +#include "board.h" +#include "uart_stdio.h" +#include "avr/io.h" + +static int uart_putchar(char c, FILE *stream); +static int uart_getchar(FILE *stream); + +static FILE uart_stdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); +static FILE uart_stdin = FDEV_SETUP_STREAM(NULL, uart_getchar, _FDEV_SETUP_READ); + +/** + * @brief Initialize the system, initialize the button + */ +void board_init(void) +{ + /* initialize the CPU */ + cpu_init(); + + /* initialize STDIO over UART */ + uart_stdio_init(); + stdout = &uart_stdout; + stdin = &uart_stdin; + puts("\f"); + + /* Disable JTAG to be able to use PCINTs on PD5, PD6, PD7 */ + MCUCR=(1< + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_inga_common + * @{ + * + * @file + * @brief Common board definitions for the INGA boards + * + * @author Robert Hartung + * + * @} + */ + +#ifndef INGA_COMMON_BOARD_COMMON_H_ +#define INGA_COMMON_BOARD_COMMON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef UART_STDIO_BAUDRATE +#define UART_STDIO_BAUDRATE (19200) +#endif + +/** + * Context swap defines + * Setup to use PA0 which is pin change interrupt 0 (PCINT0) + * This emulates a software triggered interrupt + */ +#define AVR_CONTEXT_SWAP_INIT do { \ + DDRA |= (1 << DDA0); \ + PCICR |= (1 << PCIE0); \ + PCMSK0 |= (1 << PCINT0); \ +} while (0) +#define AVR_CONTEXT_SWAP_INTERRUPT_VECT PCINT0_vect +#define AVR_CONTEXT_SWAP_INTERRUPT_VECT_NUM PCINT0_vect_num +#define AVR_CONTEXT_SWAP_TRIGGER PORTA ^= (1 << PA0) + +/** + * @name at86rf233 configuration + * @{ + */ +#define AT86RF2XX_PARAMS_BOARD {.spi = SPI_DEV(0), \ + .spi_clk = SPI_CLK_5MHZ, \ + .cs_pin = GPIO_PIN(PORT_B, 4),\ + .int_pin = GPIO_PIN(PORT_D, 6),\ + .sleep_pin = GPIO_PIN(PORT_B, 3),\ + .reset_pin = GPIO_PIN(PORT_B, 1)} +/** @} */ + +/** + * @name xtimer configuration values + * @{ + */ +#define XTIMER_WIDTH (16) +#define XTIMER_BACKOFF (40) +#define XTIMER_DEV (0) +#define XTIMER_CHAN (0) +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* INGA_COMMON_BOARD_COMMON_H_ */ diff --git a/boards/inga_common/include/periph_conf_common.h b/boards/inga_common/include/periph_conf_common.h new file mode 100644 index 000000000000..ff7e9f299893 --- /dev/null +++ b/boards/inga_common/include/periph_conf_common.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2016 Robert Hartung + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef INGA_COMMON_PERIPH_CONF_COMMON_H_ +#define INGA_COMMON_PERIPH_CONF_COMMON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Clock configuration + * @{ + */ +#define CLOCK_CORECLOCK (8000000UL) +/** @} */ + +/** + * @brief Timer configuration + * + * The timer driver only supports the four 16-bit timers (Timer1, Timer3, + * Timer4, Timer5), so those are the only onces we can use here. + * + * @{ + */ +#define TIMER_NUMOF (1U) + +#define TIMER_0 MEGA_TIMER1 +#define TIMER_0_MASK &TIMSK1 +#define TIMER_0_FLAG &TIFR1 +#define TIMER_0_ISRA TIMER1_COMPA_vect +#define TIMER_0_ISRB TIMER1_COMPB_vect +/** @} */ + +/** + * @brief UART configuration + * + * The UART devices have fixed pin mappings, so all we need to do, is to specify + * which devices we would like to use and their corresponding RX interrupts. See + * the reference manual for the fixed pin mapping. + * + * @{ + */ +#define UART_NUMOF (1U) + +#define UART_0 MEGA_UART0 +#define UART_0_ISR USART0_RX_vect +/** @} */ + +/** + * The INGA has exactly 1 I2C interface + * @{ + */ +#define I2C_NUMOF (1U) + +#define I2C_0_EN (1) +#define I2C_0_SCL GPIO_PIN(PORT_C, 0) +#define I2C_0_SDA GPIO_PIN(PORT_C, 1) +/** @} */ + +/** + * INGA ADXL345 configuration + * @{ + */ +#define ADXL345_PARAM_ADDR ADXL345_ADDR_53 /* (0xA6>>1) */ +#define ADXL345_PARAM_I2C (0) +#define ADXL345_PARAMS { .offset = ADXL345_PARAM_OFFSET, \ + .range = ADXL345_RANGE_2G, \ + .rate = ADXL345_RATE_100HZ, \ + .full_res = ADXL345_PARAM_FULL_RES } +/** @} */ + +/** + * Pin Change Interrupt configuration + * @{ + */ +#define AVR_USE_PCINT (1) +/** @} */ + +/** + * INGA L3G4200D adress + * @{ + */ +#define L3G4200D_PARAM_ADDR (0x69) /* 0xD2>>1 */ +/** @} */ + +/** + * The INGA has exactly 1 SPI interface + * @{ + */ +#define SPI_NUMOF (1U) +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* INGA_COMMON_PERIPH_CONF_COMMON_H_ */ diff --git a/boards/inga_green/Makefile b/boards/inga_green/Makefile new file mode 100644 index 000000000000..323e91da13d4 --- /dev/null +++ b/boards/inga_green/Makefile @@ -0,0 +1,3 @@ +MODULE = board +DIRS = $(RIOTBOARD)/inga_common +include $(RIOTBASE)/Makefile.base diff --git a/boards/inga_green/Makefile.dep b/boards/inga_green/Makefile.dep new file mode 100644 index 000000000000..69863c9818f5 --- /dev/null +++ b/boards/inga_green/Makefile.dep @@ -0,0 +1,3 @@ +ifneq (,$(filter netdev_default gnrc_netdev_default,$(USEMODULE))) + USEMODULE += at86rf231 +endif diff --git a/boards/inga_green/Makefile.features b/boards/inga_green/Makefile.features new file mode 100644 index 000000000000..474c3960294a --- /dev/null +++ b/boards/inga_green/Makefile.features @@ -0,0 +1 @@ +include $(RIOTBOARD)/inga_common/Makefile.features diff --git a/boards/inga_green/Makefile.include b/boards/inga_green/Makefile.include new file mode 100644 index 000000000000..255204d077d5 --- /dev/null +++ b/boards/inga_green/Makefile.include @@ -0,0 +1,11 @@ +USEMODULE += inga_common + +# inga_tool for flashing +include $(RIOTMAKE)/tools/inga_tool.inc.mk + +export INCLUDES += -I$(RIOTBOARD)/inga_common/include/ + +# setup the boards dependencies +include $(RIOTBOARD)/$(BOARD)/Makefile.dep + +include $(RIOTBOARD)/inga_common/Makefile.include diff --git a/boards/inga_green/include/board.h b/boards/inga_green/include/board.h new file mode 100644 index 000000000000..ac44cb2ed4b7 --- /dev/null +++ b/boards/inga_green/include/board.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 Robert Hartung + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef INGA_COMMON_BOARD_H_ +#define INGA_COMMON_BOARD_H_ + +#include "cpu.h" +#include "periph_conf.h" +#include "periph/gpio.h" +#include "board_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name User LED pin definitions and handlers + */ +#define LED1_PIN GPIO_PIN(PORT_D, 5) +#define LED1_MASK (1 << 5) +#define LED1_OFF (PORTD |= LED1_MASK) +#define LED1_ON (PORTD &= ~LED1_MASK) +#define LED1_TOGGLE (PORTD ^= LED1_MASK) + +#define LED2_PIN GPIO_PIN(PORT_D, 7) +#define LED2_MASK (1 << 7) +#define LED2_OFF (PORTD |= LED2_MASK) +#define LED2_ON (PORTD &= ~LED2_MASK) +#define LED2_TOGGLE (PORTD ^= LED2_MASK) +/** @} */ + +/** + * @name User button pin definitions + */ +#define BTN0_PIN GPIO_PIN(PORT_B,2) /* PB2 */ +#define BTN0_MODE GPIO_IN +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* INGA_COMMON_BOARD_H_ */ diff --git a/boards/inga_green/include/periph_conf.h b/boards/inga_green/include/periph_conf.h new file mode 100644 index 000000000000..e2495a5c92a3 --- /dev/null +++ b/boards/inga_green/include/periph_conf.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 TU Braunschweig, IBR + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_inga_white + * @{ + * + * @file + * @brief Peripheral MCU configuration for the INGA white board + * + * @author Robert Hartung + */ + +#ifndef PERIPH_CONF_H_ +#define PERIPH_CONF_H_ + +#include "periph_conf_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H_ */ diff --git a/boards/inga_red/Makefile b/boards/inga_red/Makefile new file mode 100644 index 000000000000..323e91da13d4 --- /dev/null +++ b/boards/inga_red/Makefile @@ -0,0 +1,3 @@ +MODULE = board +DIRS = $(RIOTBOARD)/inga_common +include $(RIOTBASE)/Makefile.base diff --git a/boards/inga_red/Makefile.dep b/boards/inga_red/Makefile.dep new file mode 100644 index 000000000000..f6936323ba9f --- /dev/null +++ b/boards/inga_red/Makefile.dep @@ -0,0 +1,3 @@ +ifneq (,$(filter netdev_default gnrc_netdev_default,$(USEMODULE))) + USEMODULE += at86rf233 +endif diff --git a/boards/inga_red/Makefile.features b/boards/inga_red/Makefile.features new file mode 100644 index 000000000000..474c3960294a --- /dev/null +++ b/boards/inga_red/Makefile.features @@ -0,0 +1 @@ +include $(RIOTBOARD)/inga_common/Makefile.features diff --git a/boards/inga_red/Makefile.include b/boards/inga_red/Makefile.include new file mode 100644 index 000000000000..da42b537e4a5 --- /dev/null +++ b/boards/inga_red/Makefile.include @@ -0,0 +1,11 @@ +USEMODULE += inga_common + +# New flash tool +include $(RIOTMAKE)/tools/inga_tool.inc.mk + +export INCLUDES += -I$(RIOTBOARD)/inga_common/include/ + +# setup the boards dependencies +include $(RIOTBOARD)/$(BOARD)/Makefile.dep + +include $(RIOTBOARD)/inga_common/Makefile.include diff --git a/boards/inga_red/include/board.h b/boards/inga_red/include/board.h new file mode 100644 index 000000000000..d815e9ec9281 --- /dev/null +++ b/boards/inga_red/include/board.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 Robert Hartung + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef INGA_COMMON_BOARD_H_ +#define INGA_COMMON_BOARD_H_ + +#include "cpu.h" +#include "periph_conf.h" +#include "periph/gpio.h" +#include "board_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name User LED pin definitions and handlers + */ +#define LED1_PIN GPIO_PIN(PORT_D, 5) +#define LED1_MASK (1 << 5) +#define LED1_OFF (PORTD |= LED1_MASK) +#define LED1_ON (PORTD &= ~LED1_MASK) +#define LED1_TOGGLE (PORTD ^= LED1_MASK) + +#define LED2_PIN GPIO_PIN(PORT_D, 7) +#define LED2_MASK (1 << 7) +#define LED2_OFF (PORTD |= LED2_MASK) +#define LED2_ON (PORTD &= ~LED2_MASK) +#define LED2_TOGGLE (PORTD ^= LED2_MASK) +/** @} */ + +/** + * @name User button pin definitions + */ +#define BTN0_PIN GPIO_PIN(1,2) /* PB2 */ +#define BTN0_MODE GPIO_IN +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* INGA_COMMON_BOARD_H_ */ diff --git a/boards/inga_red/include/periph_conf.h b/boards/inga_red/include/periph_conf.h new file mode 100644 index 000000000000..4348e21716cd --- /dev/null +++ b/boards/inga_red/include/periph_conf.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 TU Braunschweig, IBR + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_inga_red + * @{ + * + * @file + * @brief Peripheral MCU configuration for the INGA red board + * + * @author Robert Hartung + */ + +#ifndef PERIPH_CONF_H_ +#define PERIPH_CONF_H_ + +#include "periph_conf_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H_ */ diff --git a/boards/inga_white/Makefile b/boards/inga_white/Makefile new file mode 100644 index 000000000000..323e91da13d4 --- /dev/null +++ b/boards/inga_white/Makefile @@ -0,0 +1,3 @@ +MODULE = board +DIRS = $(RIOTBOARD)/inga_common +include $(RIOTBASE)/Makefile.base diff --git a/boards/inga_white/Makefile.dep b/boards/inga_white/Makefile.dep new file mode 100644 index 000000000000..69863c9818f5 --- /dev/null +++ b/boards/inga_white/Makefile.dep @@ -0,0 +1,3 @@ +ifneq (,$(filter netdev_default gnrc_netdev_default,$(USEMODULE))) + USEMODULE += at86rf231 +endif diff --git a/boards/inga_white/Makefile.features b/boards/inga_white/Makefile.features new file mode 100644 index 000000000000..474c3960294a --- /dev/null +++ b/boards/inga_white/Makefile.features @@ -0,0 +1 @@ +include $(RIOTBOARD)/inga_common/Makefile.features diff --git a/boards/inga_white/Makefile.include b/boards/inga_white/Makefile.include new file mode 100644 index 000000000000..255204d077d5 --- /dev/null +++ b/boards/inga_white/Makefile.include @@ -0,0 +1,11 @@ +USEMODULE += inga_common + +# inga_tool for flashing +include $(RIOTMAKE)/tools/inga_tool.inc.mk + +export INCLUDES += -I$(RIOTBOARD)/inga_common/include/ + +# setup the boards dependencies +include $(RIOTBOARD)/$(BOARD)/Makefile.dep + +include $(RIOTBOARD)/inga_common/Makefile.include diff --git a/boards/inga_white/include/board.h b/boards/inga_white/include/board.h new file mode 100644 index 000000000000..ac44cb2ed4b7 --- /dev/null +++ b/boards/inga_white/include/board.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 Robert Hartung + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef INGA_COMMON_BOARD_H_ +#define INGA_COMMON_BOARD_H_ + +#include "cpu.h" +#include "periph_conf.h" +#include "periph/gpio.h" +#include "board_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name User LED pin definitions and handlers + */ +#define LED1_PIN GPIO_PIN(PORT_D, 5) +#define LED1_MASK (1 << 5) +#define LED1_OFF (PORTD |= LED1_MASK) +#define LED1_ON (PORTD &= ~LED1_MASK) +#define LED1_TOGGLE (PORTD ^= LED1_MASK) + +#define LED2_PIN GPIO_PIN(PORT_D, 7) +#define LED2_MASK (1 << 7) +#define LED2_OFF (PORTD |= LED2_MASK) +#define LED2_ON (PORTD &= ~LED2_MASK) +#define LED2_TOGGLE (PORTD ^= LED2_MASK) +/** @} */ + +/** + * @name User button pin definitions + */ +#define BTN0_PIN GPIO_PIN(PORT_B,2) /* PB2 */ +#define BTN0_MODE GPIO_IN +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* INGA_COMMON_BOARD_H_ */ diff --git a/boards/inga_white/include/periph_conf.h b/boards/inga_white/include/periph_conf.h new file mode 100644 index 000000000000..e2495a5c92a3 --- /dev/null +++ b/boards/inga_white/include/periph_conf.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 TU Braunschweig, IBR + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_inga_white + * @{ + * + * @file + * @brief Peripheral MCU configuration for the INGA white board + * + * @author Robert Hartung + */ + +#ifndef PERIPH_CONF_H_ +#define PERIPH_CONF_H_ + +#include "periph_conf_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H_ */ diff --git a/examples/default/Makefile b/examples/default/Makefile index 664945b5df73..8fc6b5d1e60c 100644 --- a/examples/default/Makefile +++ b/examples/default/Makefile @@ -37,7 +37,8 @@ USEMODULE += saul_default BOARD_PROVIDES_NETIF := acd52832 airfy-beacon b-l072z-lrwan1 cc2538dk fox iotlab-m3 iotlab-a8-m3 mulle \ microbit native nrf51dongle nrf52dk nrf6310 openmote-cc2538 pba-d-01-kw2x \ remote-pa remote-reva samr21-xpro \ - spark-core telosb yunjia-nrf51822 z1 + spark-core telosb yunjia-nrf51822 z1 \ + inga_red inga_white inga_blue inga_green ifneq (,$(filter $(BOARD),$(BOARD_PROVIDES_NETIF))) # Use modules for networking From ba108f399fbc7718c030de7532eee911f3222f64 Mon Sep 17 00:00:00 2001 From: Robert Hartung Date: Thu, 30 Nov 2017 13:57:34 +0100 Subject: [PATCH 4/9] fixup! adds missing features --- boards/inga_common/Makefile.features | 2 ++ cpu/atmega1284p/Makefile.features | 1 + 2 files changed, 3 insertions(+) create mode 100644 cpu/atmega1284p/Makefile.features diff --git a/boards/inga_common/Makefile.features b/boards/inga_common/Makefile.features index b2090575bdb4..dccfc3c4a1f6 100644 --- a/boards/inga_common/Makefile.features +++ b/boards/inga_common/Makefile.features @@ -9,3 +9,5 @@ FEATURES_PROVIDED += periph_i2c # The board MPU family (used for grouping by the CI system) FEATURES_MCU_GROUP = avr8 + +include $(RIOTCPU)/atmega1284p/Makefile.features diff --git a/cpu/atmega1284p/Makefile.features b/cpu/atmega1284p/Makefile.features new file mode 100644 index 000000000000..008260685b10 --- /dev/null +++ b/cpu/atmega1284p/Makefile.features @@ -0,0 +1 @@ +-include $(RIOTCPU)/atmega_common/Makefile.features From 9e9a16d4985db3cfc1948f95dd7721be0488abfd Mon Sep 17 00:00:00 2001 From: Robert Hartung Date: Mon, 4 Dec 2017 09:37:47 +0100 Subject: [PATCH 5/9] boards/inga_common: moved to boards/common/inga --- boards/{inga_common => common/inga}/Makefile | 0 boards/{inga_common => common/inga}/Makefile.features | 0 boards/{inga_common => common/inga}/Makefile.include | 0 boards/{inga_common => common/inga}/board.c | 0 boards/{inga_common => common/inga}/include/board_common.h | 0 boards/{inga_common => common/inga}/include/periph_conf_common.h | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename boards/{inga_common => common/inga}/Makefile (100%) rename boards/{inga_common => common/inga}/Makefile.features (100%) rename boards/{inga_common => common/inga}/Makefile.include (100%) rename boards/{inga_common => common/inga}/board.c (100%) rename boards/{inga_common => common/inga}/include/board_common.h (100%) rename boards/{inga_common => common/inga}/include/periph_conf_common.h (100%) diff --git a/boards/inga_common/Makefile b/boards/common/inga/Makefile similarity index 100% rename from boards/inga_common/Makefile rename to boards/common/inga/Makefile diff --git a/boards/inga_common/Makefile.features b/boards/common/inga/Makefile.features similarity index 100% rename from boards/inga_common/Makefile.features rename to boards/common/inga/Makefile.features diff --git a/boards/inga_common/Makefile.include b/boards/common/inga/Makefile.include similarity index 100% rename from boards/inga_common/Makefile.include rename to boards/common/inga/Makefile.include diff --git a/boards/inga_common/board.c b/boards/common/inga/board.c similarity index 100% rename from boards/inga_common/board.c rename to boards/common/inga/board.c diff --git a/boards/inga_common/include/board_common.h b/boards/common/inga/include/board_common.h similarity index 100% rename from boards/inga_common/include/board_common.h rename to boards/common/inga/include/board_common.h diff --git a/boards/inga_common/include/periph_conf_common.h b/boards/common/inga/include/periph_conf_common.h similarity index 100% rename from boards/inga_common/include/periph_conf_common.h rename to boards/common/inga/include/periph_conf_common.h From bd187a8329fb5287c17d3d8b934ad2836432d385 Mon Sep 17 00:00:00 2001 From: Robert Hartung Date: Mon, 4 Dec 2017 09:55:32 +0100 Subject: [PATCH 6/9] fixup! adapts Makefiles --- boards/common/inga/Makefile | 2 +- boards/inga_blue/Makefile | 2 +- boards/inga_blue/Makefile.features | 2 +- boards/inga_blue/Makefile.include | 6 +++--- boards/inga_green/Makefile | 2 +- boards/inga_green/Makefile.features | 2 +- boards/inga_green/Makefile.include | 6 +++--- boards/inga_red/Makefile | 2 +- boards/inga_red/Makefile.features | 2 +- boards/inga_red/Makefile.include | 6 +++--- boards/inga_white/Makefile | 2 +- boards/inga_white/Makefile.features | 2 +- boards/inga_white/Makefile.include | 6 +++--- 13 files changed, 21 insertions(+), 21 deletions(-) diff --git a/boards/common/inga/Makefile b/boards/common/inga/Makefile index 8b72586e210d..1f0d767c33e2 100644 --- a/boards/common/inga/Makefile +++ b/boards/common/inga/Makefile @@ -1,3 +1,3 @@ -MODULE = inga_common +MODULE = boards_common_inga include $(RIOTBASE)/Makefile.base diff --git a/boards/inga_blue/Makefile b/boards/inga_blue/Makefile index 323e91da13d4..39f725c62c96 100644 --- a/boards/inga_blue/Makefile +++ b/boards/inga_blue/Makefile @@ -1,3 +1,3 @@ MODULE = board -DIRS = $(RIOTBOARD)/inga_common +DIRS = $(RIOTBOARD)/common/inga include $(RIOTBASE)/Makefile.base diff --git a/boards/inga_blue/Makefile.features b/boards/inga_blue/Makefile.features index 474c3960294a..84a3d18c04c2 100644 --- a/boards/inga_blue/Makefile.features +++ b/boards/inga_blue/Makefile.features @@ -1 +1 @@ -include $(RIOTBOARD)/inga_common/Makefile.features +include $(RIOTBOARD)/common/inga/Makefile.features diff --git a/boards/inga_blue/Makefile.include b/boards/inga_blue/Makefile.include index c5d45405c2fc..5104f9b32c10 100644 --- a/boards/inga_blue/Makefile.include +++ b/boards/inga_blue/Makefile.include @@ -1,12 +1,12 @@ -USEMODULE += inga_common +USEMODULE += boards_common_inga export FLASHER = avrdude # JTAG ICE mkII export FFLAGS = -c jtag2isp -p m1284p -P usb -u -U flash:w:$(HEXFILE) -export INCLUDES += -I$(RIOTBOARD)/inga_common/include/ +export INCLUDES += -I$(RIOTBOARD)/common/inga/include/ # setup the boards dependencies include $(RIOTBOARD)/$(BOARD)/Makefile.dep -include $(RIOTBOARD)/inga_common/Makefile.include +include $(RIOTBOARD)/common/inga/Makefile.include diff --git a/boards/inga_green/Makefile b/boards/inga_green/Makefile index 323e91da13d4..39f725c62c96 100644 --- a/boards/inga_green/Makefile +++ b/boards/inga_green/Makefile @@ -1,3 +1,3 @@ MODULE = board -DIRS = $(RIOTBOARD)/inga_common +DIRS = $(RIOTBOARD)/common/inga include $(RIOTBASE)/Makefile.base diff --git a/boards/inga_green/Makefile.features b/boards/inga_green/Makefile.features index 474c3960294a..84a3d18c04c2 100644 --- a/boards/inga_green/Makefile.features +++ b/boards/inga_green/Makefile.features @@ -1 +1 @@ -include $(RIOTBOARD)/inga_common/Makefile.features +include $(RIOTBOARD)/common/inga/Makefile.features diff --git a/boards/inga_green/Makefile.include b/boards/inga_green/Makefile.include index 255204d077d5..96769e4d44b1 100644 --- a/boards/inga_green/Makefile.include +++ b/boards/inga_green/Makefile.include @@ -1,11 +1,11 @@ -USEMODULE += inga_common +USEMODULE += boards_common_inga # inga_tool for flashing include $(RIOTMAKE)/tools/inga_tool.inc.mk -export INCLUDES += -I$(RIOTBOARD)/inga_common/include/ +export INCLUDES += -I$(RIOTBOARD)/common/inga/include/ # setup the boards dependencies include $(RIOTBOARD)/$(BOARD)/Makefile.dep -include $(RIOTBOARD)/inga_common/Makefile.include +include $(RIOTBOARD)/common/inga/Makefile.include diff --git a/boards/inga_red/Makefile b/boards/inga_red/Makefile index 323e91da13d4..39f725c62c96 100644 --- a/boards/inga_red/Makefile +++ b/boards/inga_red/Makefile @@ -1,3 +1,3 @@ MODULE = board -DIRS = $(RIOTBOARD)/inga_common +DIRS = $(RIOTBOARD)/common/inga include $(RIOTBASE)/Makefile.base diff --git a/boards/inga_red/Makefile.features b/boards/inga_red/Makefile.features index 474c3960294a..84a3d18c04c2 100644 --- a/boards/inga_red/Makefile.features +++ b/boards/inga_red/Makefile.features @@ -1 +1 @@ -include $(RIOTBOARD)/inga_common/Makefile.features +include $(RIOTBOARD)/common/inga/Makefile.features diff --git a/boards/inga_red/Makefile.include b/boards/inga_red/Makefile.include index da42b537e4a5..82c3f8d9c226 100644 --- a/boards/inga_red/Makefile.include +++ b/boards/inga_red/Makefile.include @@ -1,11 +1,11 @@ -USEMODULE += inga_common +USEMODULE += boards_common_inga # New flash tool include $(RIOTMAKE)/tools/inga_tool.inc.mk -export INCLUDES += -I$(RIOTBOARD)/inga_common/include/ +export INCLUDES += -I$(RIOTBOARD)/common/inga/include/ # setup the boards dependencies include $(RIOTBOARD)/$(BOARD)/Makefile.dep -include $(RIOTBOARD)/inga_common/Makefile.include +include $(RIOTBOARD)/common/inga/Makefile.include diff --git a/boards/inga_white/Makefile b/boards/inga_white/Makefile index 323e91da13d4..39f725c62c96 100644 --- a/boards/inga_white/Makefile +++ b/boards/inga_white/Makefile @@ -1,3 +1,3 @@ MODULE = board -DIRS = $(RIOTBOARD)/inga_common +DIRS = $(RIOTBOARD)/common/inga include $(RIOTBASE)/Makefile.base diff --git a/boards/inga_white/Makefile.features b/boards/inga_white/Makefile.features index 474c3960294a..84a3d18c04c2 100644 --- a/boards/inga_white/Makefile.features +++ b/boards/inga_white/Makefile.features @@ -1 +1 @@ -include $(RIOTBOARD)/inga_common/Makefile.features +include $(RIOTBOARD)/common/inga/Makefile.features diff --git a/boards/inga_white/Makefile.include b/boards/inga_white/Makefile.include index 255204d077d5..96769e4d44b1 100644 --- a/boards/inga_white/Makefile.include +++ b/boards/inga_white/Makefile.include @@ -1,11 +1,11 @@ -USEMODULE += inga_common +USEMODULE += boards_common_inga # inga_tool for flashing include $(RIOTMAKE)/tools/inga_tool.inc.mk -export INCLUDES += -I$(RIOTBOARD)/inga_common/include/ +export INCLUDES += -I$(RIOTBOARD)/common/inga/include/ # setup the boards dependencies include $(RIOTBOARD)/$(BOARD)/Makefile.dep -include $(RIOTBOARD)/inga_common/Makefile.include +include $(RIOTBOARD)/common/inga/Makefile.include From 493797e3574bf92c751c3cfcd75435a7da7475ab Mon Sep 17 00:00:00 2001 From: Robert Hartung Date: Tue, 19 Dec 2017 08:58:59 +0100 Subject: [PATCH 7/9] fixup! stack sizes --- cpu/atmega1284p/include/cpu_conf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/atmega1284p/include/cpu_conf.h b/cpu/atmega1284p/include/cpu_conf.h index 1e8ca656dfbb..51fc43a6c0d8 100644 --- a/cpu/atmega1284p/include/cpu_conf.h +++ b/cpu/atmega1284p/include/cpu_conf.h @@ -34,10 +34,10 @@ extern "C" { #define THREAD_EXTRA_STACKSIZE_PRINTF (256) #ifndef THREAD_STACKSIZE_DEFAULT -#define THREAD_STACKSIZE_DEFAULT (256) +#define THREAD_STACKSIZE_DEFAULT (512) #endif -#define THREAD_STACKSIZE_IDLE (128) +#define THREAD_STACKSIZE_IDLE (512 + THREAD_EXTRA_STACKSIZE_PRINTF) /** @} */ #ifdef __cplusplus From 609650610c77587020967e8828454732fb2a1358 Mon Sep 17 00:00:00 2001 From: Robert Hartung Date: Fri, 5 Jan 2018 13:25:29 +0100 Subject: [PATCH 8/9] adjust stack sizes --- cpu/atmega1284p/include/cpu_conf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/atmega1284p/include/cpu_conf.h b/cpu/atmega1284p/include/cpu_conf.h index 51fc43a6c0d8..4f0dc5846e15 100644 --- a/cpu/atmega1284p/include/cpu_conf.h +++ b/cpu/atmega1284p/include/cpu_conf.h @@ -34,10 +34,10 @@ extern "C" { #define THREAD_EXTRA_STACKSIZE_PRINTF (256) #ifndef THREAD_STACKSIZE_DEFAULT -#define THREAD_STACKSIZE_DEFAULT (512) +#define THREAD_STACKSIZE_DEFAULT (1024) // 512 #endif -#define THREAD_STACKSIZE_IDLE (512 + THREAD_EXTRA_STACKSIZE_PRINTF) +#define THREAD_STACKSIZE_IDLE (256) // 512 + THREAD_EXTRA_STACKSIZE_PRINTF /** @} */ #ifdef __cplusplus From ad50e082a934ff400f1c5fe4a088d7bf6195b821 Mon Sep 17 00:00:00 2001 From: Robert Hartung Date: Fri, 5 Jan 2018 14:21:56 +0100 Subject: [PATCH 9/9] adds simplistic RTT implementation --- boards/inga_blue/Makefile.features | 1 + boards/inga_blue/include/periph_conf.h | 4 + cpu/atmega1284p/Makefile.include | 2 + cpu/atmega1284p/periph/rtt.c | 131 +++++++++++++++++++++++++ 4 files changed, 138 insertions(+) create mode 100644 cpu/atmega1284p/periph/rtt.c diff --git a/boards/inga_blue/Makefile.features b/boards/inga_blue/Makefile.features index 84a3d18c04c2..7c18aea6f2e1 100644 --- a/boards/inga_blue/Makefile.features +++ b/boards/inga_blue/Makefile.features @@ -1 +1,2 @@ include $(RIOTBOARD)/common/inga/Makefile.features +FEATURES_PROVIDED += periph_rtt diff --git a/boards/inga_blue/include/periph_conf.h b/boards/inga_blue/include/periph_conf.h index 4348e21716cd..c1c235e5a4e0 100644 --- a/boards/inga_blue/include/periph_conf.h +++ b/boards/inga_blue/include/periph_conf.h @@ -25,6 +25,10 @@ extern "C" { #endif +#define RTT_NUMOF 1 +#define RTT_FREQUENCY (32) +#define RTT_MAX_VALUE (0xFF) + #ifdef __cplusplus } #endif diff --git a/cpu/atmega1284p/Makefile.include b/cpu/atmega1284p/Makefile.include index 398e48eb3f8d..4ec011b5f1bd 100644 --- a/cpu/atmega1284p/Makefile.include +++ b/cpu/atmega1284p/Makefile.include @@ -1,5 +1,7 @@ # tell the build system that the CPU depends on the atmega common files USEMODULE += atmega_common +# ??? This should not be needed +USEMODULE += periph # explicitly tell the linker to link the syscalls and startup code. # Without this the interrupt vectors will not be linked correctly! diff --git a/cpu/atmega1284p/periph/rtt.c b/cpu/atmega1284p/periph/rtt.c new file mode 100644 index 000000000000..6f22cfb08c22 --- /dev/null +++ b/cpu/atmega1284p/periph/rtt.c @@ -0,0 +1,131 @@ +#include "board.h" +#include "periph/rtt.h" +#ifdef MODULE_PM_LAYERED +#include "pm_layered.h" +#endif + +#include "irq.h" +#include "thread.h" + +rtt_cb_t rtt_next_cb; +volatile int cnt = 0; + +void rtt_init(void) { + printf("init rtt\n"); + rtt_poweron(); + + /* Disable all interrupts */ + TIMSK2 = 0; + + /* Select asynchronous clock source */ + ASSR = (1 << AS2); + + /* Reset output compare */ + TCCR2A = 0; + /* 32768Hz / 1024 -> 32 ticks per second! */ + TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20); + /* Match register -> 1 interrupt every second */ + OCR2A = 32; + /* Set count register to 0 */ + TCNT2 = 0; + /* Enable interrupts () */ + TIMSK2 |= ( 1 << OCIE2A) /*| (1 << TOIE2)*/; + + /* Wait until not busy anymore */ + while( ASSR & (1 << TCN2UB) ); + while( ASSR & (1 << OCR2AUB) ); + while( ASSR & (1 << TCR2AUB) ); + + /* Clear interrupt flags */ + TIFR2 &= ~( (1 << OCF2B) | (1 << OCF2A) | (1 << TOV2) ); + /* +a. Disable the Timer/Counter2 interrupts by clearing OCIE2x and TOIE2. +b. Select clock source by setting AS2 as appropriate. +c. Write new values to TCNT2, OCR2x, and TCCR2x. +d. To switch to asynchronous operation: Wait for TCN2UB, OCR2xUB, and TCR2xUB. +e. Clear the Timer/Counter2 Interrupt Flags. +f. Enable interrupts, if needed + */ + + irq_enable(); +} + +void rtt_set_overflow_cb(rtt_cb_t cb, void *arg) { + rtt_next_cb = cb; + (void) arg; +} + +void rtt_clear_overflow_cb(void) { + rtt_next_cb = NULL; +} + +uint32_t rtt_get_counter(void) { + return TCNT2; +} + +void rtt_set_counter(uint32_t counter) { + TCNT2 = (uint8_t)counter; +} + +void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg) { + (void)arg; + (void)alarm; + rtt_next_cb = cb; + OCR2A = (uint8_t)alarm; +} + +uint32_t rtt_get_alarm(void) { + return OCR2A; +} + +void rtt_clear_alarm(void) { + TIMSK2 &= ~(1 << OCIE2A); + OCR2A = 0; +} + +void rtt_poweron(void) { +#ifdef MODULE_PM_LAYERED + pm_block(PM_SLEEPMODE_INVALID_TIMER2); +#endif + power_timer2_enable(); +} + +void rtt_poweroff(void) { + power_timer2_disable(); +#ifdef MODULE_PM_LAYERED + pm_unblock(PM_SLEEPMODE_INVALID_TIMER2); +#endif +} + +/* +ISR(TIMER2_OVF_vect) { + __enter_isr(); + /// What to do here? + //puts("TIMER2_OVF"); + //rtt_next_cb(NULL); + __exit_isr(); +} +*/ + +ISR(TIMER2_COMPA_vect) { + __enter_isr(); + //puts("TIMER2_COMPA"); + //TCNT2 = 0; + rtt_next_cb(NULL); + if (sched_context_switch_request) { + thread_yield(); + } + __exit_isr(); +} + +/* +ISR(TIMER2_COMPB_vect) { + __enter_isr(); + //puts("TIMER2_COMPB"); + //TCNT2 = 0; + if (sched_context_switch_request) { + thread_yield(); + } + __exit_isr(); +} +*/