Index: avrdude-5.11.1/Makefile.am =================================================================== --- avrdude-5.11.1.orig/Makefile.am 2012-07-22 10:38:55.281926086 -0300 +++ avrdude-5.11.1/Makefile.am 2012-07-22 10:39:01.946145199 -0300 @@ -118,6 +118,8 @@ lists.c \ lists.h \ my_ddk_hidsdi.h \ + nanonote.c \ + nanonote.h \ par.c \ par.h \ pgm.c \ Index: avrdude-5.11.1/config_gram.y =================================================================== --- avrdude-5.11.1.orig/config_gram.y 2012-07-22 10:38:55.261925424 -0300 +++ avrdude-5.11.1/config_gram.y 2012-07-22 10:39:01.946145199 -0300 @@ -50,6 +50,7 @@ #include "jtagmkI.h" #include "jtagmkII.h" #include "avrftdi.h" +#include "nanonote.h" #if defined(WIN32NATIVE) #define strtok_r( _s, _sep, _lasts ) \ @@ -103,6 +104,7 @@ %token K_DRAGON_JTAG %token K_DRAGON_PDI %token K_DRAGON_PP +%token K_NANONOTE %token K_STK500_DEVCODE %token K_AVR910_DEVCODE %token K_EEPROM @@ -587,6 +589,12 @@ } } | + K_TYPE TKN_EQUAL K_NANONOTE { + { + nanonote_initpgm(current_prog); + } + } | + K_DESC TKN_EQUAL TKN_STRING { strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN); current_prog->desc[PGM_DESCLEN-1] = 0; Index: avrdude-5.11.1/lexer.l =================================================================== --- avrdude-5.11.1.orig/lexer.l 2012-07-22 10:38:55.269925685 -0300 +++ avrdude-5.11.1/lexer.l 2012-07-22 10:39:01.946145199 -0300 @@ -168,6 +168,7 @@ min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; } miso { yylval=NULL; return K_MISO; } mosi { yylval=NULL; return K_MOSI; } +nanonote { yylval=NULL; return K_NANONOTE; } num_banks { yylval=NULL; return K_NUM_PAGES; } num_pages { yylval=NULL; return K_NUM_PAGES; } nvm_base { yylval=NULL; return K_NVM_BASE; } Index: avrdude-5.11.1/nanonote.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ avrdude-5.11.1/nanonote.c 2012-07-22 10:44:40.605282695 -0300 @@ -0,0 +1,378 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean + * Copyright (C) 2005 Michael Holzt + * Copyright (C) 2006 Joerg Wunsch + * + * 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 + */ + +/* + * Posix serial bitbanging interface for avrdude. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "avr.h" +#include "pgm.h" +#include "bitbang.h" + + +struct pdata { + unsigned clk; /* clock output on CLK; 0 if none */ +}; + +#define PDATA(pgm) ((struct pdata *) (pgm)->cookie) + + +static volatile void *mem; + + +#define PLL_CLK 336 /* PLL runs at 336 MHz */ + +#define POWER_OFF 3, 2 /* PD02, drive low to enable power */ +#define CMD 3, 8 /* PD08, CMD */ +#define CLK 3, 9 /* PD09, CLK */ +#define DAT0 3, 10 /* PD10, DAT0 */ +#define DAT1 3, 11 /* PD11, DAT1 */ +#define DAT2 3, 12 /* PD12, DAT2 */ +#define DAT3 3, 13 /* PD13, DAT3 */ + + +static struct { + unsigned port; + unsigned bit; +} pin_map[] = { + { 0, 0}, /* 0: not assigned */ + { 3, 11 }, /* 1: PD11, DAT1 */ + { 3, 10 }, /* 2: PD12, DAT0 */ + { 0, 0 }, /* 3: VSS */ + { 3, 9 }, /* 4: PD09, CLK (also used for clock output) */ + { 0, 0 }, /* 5: VDD */ + { 3, 8 }, /* 6: PD08, CMD */ + { 3, 13 }, /* 7: PD13, DAT3 */ + { 3, 12 } /* 8: PD13, DAT2 */ +}; + +#define PIN_IDX_CLK 4 + + +#define BASE 0x10000000 +#define REG_WINDOW 0x30000 + +#define REG(off) (*(volatile uint32_t *) (mem+(off))) + +#define CGU(n) REG(0x00000+(n)) +#define GPIO(n) REG(0x10000+(n)) +#define MSC(n) REG(0x21000+(n)) + +#define port_pin(port) GPIO(port*0x100) +#define port_dats(port) GPIO(port*0x100+0x14) +#define port_datc(port) GPIO(port*0x100+0x18) +#define port_funs(port) GPIO(port*0x100+0x44) +#define port_func(port) GPIO(port*0x100+0x48) +#define port_dirs(port) GPIO(port*0x100+0x64) +#define port_dirc(port) GPIO(port*0x100+0x68) + +#define MSC_STRPCL MSC(0x00) /* Start/stop MMC/SD clock */ +#define MSC_CLKRT MSC(0x08) /* MSC Clock Rate */ + +#define CLKGR CGU(0x0020) /* Clock Gate */ +#define MSCCDR CGU(0x0068) /* MSC device clock divider */ + + +static inline void gpio_high(unsigned port, unsigned bit) +{ + port_dats(port) = 1 << bit; +} + + +static void gpio_low(unsigned port, unsigned bit) +{ + port_datc(port) = 1 << bit; +} + + +static void gpio_set(unsigned port, unsigned bit, int value) +{ + if (value) + gpio_high(port, bit); + else + gpio_low(port, bit); +} + + +static int gpio_get(unsigned port, unsigned bit) +{ + return (port_pin(port) >> bit) & 1; +} + + +static void gpio_output(unsigned port, unsigned bit) +{ + port_dirs(port) = 1 << bit; +} + + +static void gpio_input(unsigned port, unsigned bit) +{ + port_dirc(port) = 1 << bit; +} + + +static void gpio_function(unsigned port, unsigned bit, int on) +{ + if (on) + port_funs(port) = 1 << bit; + else + port_func(port) = 1 << bit; +} + + +static int nanonote_setpin(PROGRAMMER *pgm, int pin, int value) +{ + if (pin & PIN_INVERSE) { + value = !value; + pin &= PIN_MASK; + } + + if (pin < 1 || pin >= sizeof(pin_map)/sizeof(*pin_map)) + return -1; + if (!pin_map[pin].port) + return -1; + +#if 0 +fprintf(stderr, "pin %d (%u, %u) = %d\n", +pin, pin_map[pin].port, pin_map[pin].bit, value); +#endif + gpio_set(pin_map[pin].port, pin_map[pin].bit, value); + + /* + * We get unstable results with values <= 16 but stable results + * with 17 and above. + */ + bitbang_delay(pgm->ispdelay+20); + + return 0; +} + + +static int nanonote_getpin(PROGRAMMER *pgm, int pin) +{ + int invert = 0; + int v; + + if (pin & PIN_INVERSE) { + invert = 1; + pin &= PIN_MASK; + } + + if (pin < 1 || pin >= sizeof(pin_map)/sizeof(*pin_map)) + return -1; + if (!pin_map[pin].port) + return -1; + if (pin == PIN_IDX_CLK && PDATA(pgm)->clk) + return -1; + + gpio_input(pin_map[pin].port, pin_map[pin].bit); /* @@@ hack */ + v = gpio_get(pin_map[pin].port, pin_map[pin].bit); +#if 0 +fprintf(stderr, "pin %d (%u, %u): %d\n", +pin, pin_map[pin].port, pin_map[pin].bit, v); +#endif + return invert ? !v : v; +} + + +static int nanonote_highpulsepin(PROGRAMMER *pgm, int pin) +{ + return -1; +} + + +static void nanonote_display(PROGRAMMER *pgm, const char *p) +{ + /* nothing */ +} + + +static void misc_high(PROGRAMMER *pgm) +{ + gpio_high(POWER_OFF); + gpio_high(DAT1); + gpio_high(DAT0); + gpio_high(CMD); + gpio_high(DAT3); + gpio_high(DAT2); + gpio_function(CLK, 0); /* set CLK to GPIO */ + gpio_high(CLK); +} + + +static void nanonote_enable(PROGRAMMER *pgm) +{ + int div, log2 = 0; + + misc_high(pgm); + if (!PDATA(pgm)->clk) + return; + + /* give the bus clock output to the MMC controller */ + gpio_function(CLK, 1); + + /* + * set the MSC clock divider, dividing the 316 MHz system clock + */ + div = PLL_CLK/PDATA(pgm)->clk; + if (PLL_CLK % PDATA(pgm)->clk) + div++; + while (div > 32) { + log2++; + div = (div+1)/2; + } + MSCCDR = div-1; + + /* + * Enable the MSC clock. We need to do this before accessing any + * registers of the MSC block ! + */ + CLKGR &= ~(1 << 7); + + /* bus clock = MSC clock / 2^log2 */ + MSC_CLKRT = log2; + + /* start MMC clock output */ + MSC_STRPCL = 2; +} + + +static void nanonote_disable(PROGRAMMER *pgm) +{ + misc_high(pgm); +} + + +static void nanonote_powerup(PROGRAMMER *pgm) +{ + gpio_low(POWER_OFF); +} + + +static void nanonote_powerdown(PROGRAMMER *pgm) +{ + gpio_input(DAT0); + gpio_input(CLK); + gpio_input(CMD); + gpio_input(DAT3); + gpio_input(DAT2); + gpio_input(DAT1); + gpio_high(POWER_OFF); +} + + +static int nanonote_open(PROGRAMMER *pgm, char *port) +{ + bitbang_check_prerequisites(pgm); + + pgm->fd.ifd = open("/dev/mem", O_RDWR | O_SYNC); + if (pgm->fd.ifd < 0) { + perror("/dev/mem"); + return -1; + } + mem = mmap(NULL, REG_WINDOW, PROT_READ | PROT_WRITE, MAP_SHARED, + pgm->fd.ifd, BASE); + if (mem == MAP_FAILED) { + perror("mmap"); + return -1; + } + + gpio_output(POWER_OFF); + gpio_output(DAT0); + gpio_output(CLK); + gpio_output(CMD); + gpio_output(DAT3); + gpio_output(DAT2); + gpio_output(DAT1); + + nanonote_disable(pgm); + + return 0; +} + + +static void nanonote_close(PROGRAMMER *pgm) +{ + if (pgm->fd.ifd != -1) + close(pgm->fd.ifd); +} + + +static int nanonote_parseextparams(PROGRAMMER *pgm, LISTID extparms) +{ + LNODEID n; + const char *param; + + for (n = lfirst(extparms); n; n = lnext(n)) { + param = ldata(n); + if (sscanf(param, "clk=%u", &PDATA(pgm)->clk) == 1) + continue; + fprintf(stderr, "unrecognized parameter \"%s\"\n", param); + return -1; + } + + return 0; +} + + +void nanonote_initpgm(PROGRAMMER *pgm) +{ + strcpy(pgm->type, "NANONOTE"); + + 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 = nanonote_display; + pgm->enable = nanonote_enable; + pgm->disable = nanonote_disable; + pgm->powerup = nanonote_powerup; + pgm->powerdown = nanonote_powerdown; + pgm->program_enable = bitbang_program_enable; + pgm->chip_erase = bitbang_chip_erase; + pgm->cmd = bitbang_cmd; + pgm->open = nanonote_open; + pgm->close = nanonote_close; + pgm->setpin = nanonote_setpin; + pgm->getpin = nanonote_getpin; + pgm->highpulsepin = nanonote_highpulsepin; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; + pgm->parseextparams = nanonote_parseextparams; + + pgm->cookie = malloc(sizeof(struct pdata)); + if (!pgm->cookie) { + perror("malloc"); + exit(1); + } + PDATA(pgm)->clk = 0; +} Index: avrdude-5.11.1/nanonote.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ avrdude-5.11.1/nanonote.h 2012-07-22 10:39:01.946145199 -0300 @@ -0,0 +1,6 @@ +#ifndef nanonote_h +#define nanonote_h + +void nanonote_initpgm(PROGRAMMER *pgm); + +#endif