diff -Nur avrdude-5.10/ac_cfg.h.in avrdude-5.10-gpio/ac_cfg.h.in --- avrdude-5.10/ac_cfg.h.in 2010-01-19 12:42:16.000000000 +0200 +++ avrdude-5.10-gpio/ac_cfg.h.in 2010-04-12 16:53:37.000000000 +0300 @@ -39,6 +39,9 @@ /* parallel port access enabled */ #undef HAVE_PARPORT +/* linux sysfs gpio support enabled */ +#undef HAVE_GPIO + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT diff -Nur avrdude-5.10/avrdude.conf.in avrdude-5.10-gpio/avrdude.conf.in --- avrdude-5.10/avrdude.conf.in 2010-01-19 12:39:11.000000000 +0200 +++ avrdude-5.10-gpio/avrdude.conf.in 2010-04-12 16:42:54.000000000 +0300 @@ -801,6 +801,27 @@ @HAVE_PARPORT_END@ address@hidden@ + +# +#This programmer bitbangs GPIO lines using the Linux sysfs GPIO interface +# +#Set the configuration below to match the GPIO lines connected to the +#relevant ISP header pin. max GPIO number is 255, defined in gpio.c +# + +programmer + id = "gpio"; + desc = "Use sysfs interface to bitbang GPIO lines"; + type = gpio; + reset = 11; + sck = 13; + mosi = 12; + miso = 9; +; + address@hidden@ + # # some ultra cheap programmers use bitbanging on the # serialport. diff -Nur avrdude-5.10/config_gram.y avrdude-5.10-gpio/config_gram.y --- avrdude-5.10/config_gram.y 2010-01-19 12:39:11.000000000 +0200 +++ avrdude-5.10-gpio/config_gram.y 2010-04-11 01:18:16.000000000 +0300 @@ -39,6 +39,7 @@ #include "stk500.h" #include "arduino.h" #include "buspirate.h" +#include "gpio.h" #include "stk500v2.h" #include "stk500generic.h" #include "avr910.h" @@ -99,6 +100,7 @@ %token K_DRAGON_JTAG %token K_DRAGON_PDI %token K_DRAGON_PP +%token K_GPIO %token K_STK500_DEVCODE %token K_AVR910_DEVCODE %token K_EEPROM @@ -437,6 +439,12 @@ buspirate_initpgm(current_prog); } } | + + K_TYPE TKN_EQUAL K_GPIO { + { + gpio_initpgm(current_prog); + } + } | K_TYPE TKN_EQUAL K_STK600 { { diff -Nur avrdude-5.10/configure.ac avrdude-5.10-gpio/configure.ac --- avrdude-5.10/configure.ac 2010-01-19 12:39:11.000000000 +0200 +++ avrdude-5.10-gpio/configure.ac 2010-04-12 16:47:41.000000000 +0300 @@ -171,6 +171,18 @@ *) AC_MSG_ERROR(bad value ${enableval} for enable-parport option) ;; esac], [enabled_parport=yes]) + +AC_ARG_ENABLE( + [gpio], + AC_HELP_STRING( + [--enable-gpio], + [Enable using the Linux sysfs GPIO interface(default)]), + [case "${enableval}" in + yes) enabled_gpio=yes ;; + no) enabled_gpio=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for enable-gpio option) ;; + esac], + [enabled_gpio=no]) DIST_SUBDIRS_AC='doc windows' @@ -239,6 +251,14 @@ else confsubst="-e /address@hidden@/,/address@hidden@/d" fi + +if test "$enabled_gpio" = "yes"; then + AC_DEFINE(HAVE_GPIO, 1, [Linux sysfs GPIO support enabled]) + confsubst="$confsubst -e /address@hidden/d" +else + confsubst="$confsubst -e /address@hidden@/,/address@hidden@/d" +fi + export confsubst # If we are compiling with gcc, enable all warning and make warnings errors. diff -Nur avrdude-5.10/gpio.c avrdude-5.10-gpio/gpio.c --- avrdude-5.10/gpio.c 1970-01-01 02:00:00.000000000 +0200 +++ avrdude-5.10-gpio/gpio.c 2010-04-12 17:20:07.000000000 +0300 @@ -0,0 +1,311 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Support for bitbanging GPIO pins using the /sys/class/gpio interface + * + * Copyright (C) 2010 Radoslav Kolev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ac_cfg.h" + +#include +#include +#include +#include +#include +#include + +#include "avrdude.h" +#include "avr.h" +#include "pindefs.h" +#include "pgm.h" +#include "bitbang.h" + +#if HAVE_GPIO + +/* + * GPIO user space helpers + * + * Copyright 2009 Analog Devices Inc. + * Michael Hennerich (address@hidden) + * + * Licensed under the GPL-2 or later + */ + +#define GPIO_DIR_IN 0 +#define GPIO_DIR_OUT 1 + +static int gpio_export(unsigned gpio) +{ + int fd, len; + char buf[11]; + + fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd < 0) { + perror("gpio/export"); + return fd; + } + + len = snprintf(buf, sizeof(buf), "%d", gpio); + write(fd, buf, len); + close(fd); + + return 0; +} + +static int gpio_unexport(unsigned gpio) +{ + int fd, len; + char buf[11]; + + fd = open("/sys/class/gpio/unexport", O_WRONLY); + if (fd < 0) { + perror("gpio/export"); + return fd; + } + + len = snprintf(buf, sizeof(buf), "%d", gpio); + write(fd, buf, len); + close(fd); + return 0; +} + +static int gpio_dir(unsigned gpio, unsigned dir) +{ + int fd, len; + char buf[60]; + + len = snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); + + fd = open(buf, O_WRONLY); + if (fd < 0) { + perror("gpio/direction"); + return fd; + } + + if (dir == GPIO_DIR_OUT) + write(fd, "out", 4); + else + write(fd, "in", 3); + + close(fd); + return 0; +} + +static int gpio_dir_out(unsigned gpio) +{ + return gpio_dir(gpio, GPIO_DIR_OUT); +} + +static int gpio_dir_in(unsigned gpio) +{ + return gpio_dir(gpio, GPIO_DIR_IN); +} + +/* + * End of GPIO user space helpers + */ + +#define N_GPIO 256 + +/* +* an array which holds open FDs to /sys/class/gpio/gpioXX/value for all needed pins +*/ +static int gpio_fds[N_GPIO] ; + + +static int gpio_setpin(PROGRAMMER * pgm, int pin, int value) +{ + int r; + + if (pin & PIN_INVERSE) + { + value = !value; + pin &= PIN_MASK; + } + + if ( gpio_fds[pin] < 0 ) + return -1; + + if (value) + r=write(gpio_fds[pin], "1", 1); + else + r=write(gpio_fds[pin], "0", 1); + + if (r!=1) return -1; + + if (pgm->ispdelay > 1) + bitbang_delay(pgm->ispdelay); + + return 0; +} + +static int gpio_getpin(PROGRAMMER * pgm, int pin) +{ + unsigned char invert=0; + char c; + + if (pin & PIN_INVERSE) + { + invert = 1; + pin &= PIN_MASK; + } + + if ( gpio_fds[pin] < 0 ) + return -1; + + if (lseek(gpio_fds[pin], 0, SEEK_SET)<0) + return -1; + + if (read(gpio_fds[pin], &c, 1)!=1) + return -1; + + if (c=='0') + return 0+invert; + else if (c=='1') + return 1-invert; + else + return -1; + +} + +static int gpio_highpulsepin(PROGRAMMER * pgm, int pin) +{ + + if ( gpio_fds[pin & PIN_MASK] < 0 ) + return -1; + + gpio_setpin(pgm, pin, 1); + gpio_setpin(pgm, pin, 0); + + return 0; +} + + + +static void gpio_display(PROGRAMMER *pgm, const char *p) +{ + /* MAYBE */ +} + +static void gpio_enable(PROGRAMMER *pgm) +{ + /* nothing */ +} + +static void gpio_disable(PROGRAMMER *pgm) +{ + /* nothing */ +} + +static void gpio_powerup(PROGRAMMER *pgm) +{ + /* nothing */ +} + +static void gpio_powerdown(PROGRAMMER *pgm) +{ + /* nothing */ +} + +static int gpio_open(PROGRAMMER *pgm, char *port) +{ + int r,i; + char filepath[60]; + + + bitbang_check_prerequisites(pgm); + + + for (i=0; ipinno[i] != 0) { + if ((r=gpio_export(pgm->pinno[i])) < 0) + return r; + + + if (i == PIN_AVR_MISO) + r=gpio_dir_in(pgm->pinno[i]); + else + r=gpio_dir_out(pgm->pinno[i]); + + if (r < 0) + return r; + + if ((r=snprintf(filepath, sizeof(filepath), "/sys/class/gpio/gpio%d/value", pgm->pinno[i]))<0) + return r; + + if ((gpio_fds[pgm->pinno[i]]=open(filepath, O_RDWR))<0) + return gpio_fds[pgm->pinno[i]]; + + } + } + + return(0); +} + +static void gpio_close(PROGRAMMER *pgm) +{ + int i; + + pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1); + + for (i=0; i=0) { + close(gpio_fds[i]); + gpio_unexport(i); + } + return; +} + +void gpio_initpgm(PROGRAMMER *pgm) +{ + strcpy(pgm->type, "GPIO"); + + pgm->rdy_led = bitbang_rdy_led; + pgm->err_led = bitbang_err_led; + pgm->pgm_led = bitbang_pgm_led; + pgm->vfy_led = bitbang_vfy_led; + pgm->initialize = bitbang_initialize; + pgm->display = gpio_display; + pgm->enable = gpio_enable; + pgm->disable = gpio_disable; + pgm->powerup = gpio_powerup; + pgm->powerdown = gpio_powerdown; + pgm->program_enable = bitbang_program_enable; + pgm->chip_erase = bitbang_chip_erase; + pgm->cmd = bitbang_cmd; + pgm->open = gpio_open; + pgm->close = gpio_close; + pgm->setpin = gpio_setpin; + pgm->getpin = gpio_getpin; + pgm->highpulsepin = gpio_highpulsepin; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; +} + +#else /* !HAVE_GPIO */ + +void gpio_initpgm(PROGRAMMER * pgm) +{ + fprintf(stderr, + "%s: Linux sysfs GPIO support not available in this configuration\n", + progname); +} + +#endif /* HAVE_GPIO */ diff -Nur avrdude-5.10/gpio.h avrdude-5.10-gpio/gpio.h --- avrdude-5.10/gpio.h 1970-01-01 02:00:00.000000000 +0200 +++ avrdude-5.10-gpio/gpio.h 2010-04-11 01:05:25.000000000 +0300 @@ -0,0 +1,35 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2000-2004 Brian S. Dean + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* $Id: par.h 722 2007-01-24 22:43:46Z joerg_wunsch $ */ + +#ifndef gpio_h +#define gpio_h + +#ifdef __cplusplus +extern "C" { +#endif + +void gpio_initpgm (PROGRAMMER * pgm); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nur avrdude-5.10/lexer.l avrdude-5.10-gpio/lexer.l --- avrdude-5.10/lexer.l 2010-01-19 12:39:11.000000000 +0200 +++ avrdude-5.10-gpio/lexer.l 2010-04-11 01:21:26.000000000 +0300 @@ -146,6 +146,7 @@ enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; } errled { yylval=NULL; return K_ERRLED; } flash { yylval=NULL; return K_FLASH; } +gpio { yylval=NULL; return K_GPIO; } has_jtag { yylval=NULL; return K_HAS_JTAG; } has_debugwire { yylval=NULL; return K_HAS_DW; } has_pdi { yylval=NULL; return K_HAS_PDI; } diff -Nur avrdude-5.10/Makefile.am avrdude-5.10-gpio/Makefile.am --- avrdude-5.10/Makefile.am 2010-01-19 12:39:11.000000000 +0200 +++ avrdude-5.10-gpio/Makefile.am 2010-04-12 16:50:54.000000000 +0300 @@ -101,6 +101,8 @@ fileio.c \ fileio.h \ freebsd_ppi.h \ + gpio.c \ + gpio.h \ jtagmkI.c \ jtagmkI.h \ jtagmkI_private.h \