1
0
mirror of git://projects.qi-hardware.com/ben-blinkenlights.git synced 2024-11-30 17:56:15 +02:00
ben-blinkenlights/avrdude/patches/nanonote.patch

453 lines
10 KiB
Diff

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:47:07.398111708 -0300
@@ -0,0 +1,378 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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 <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#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 */
+ { DAT1 }, /* 1: PD11, DAT1 */
+ { DAT0 }, /* 2: PD10, DAT0 */
+ { 0, 0 }, /* 3: VSS */
+ { CLK }, /* 4: PD09, CLK (also used for clock output) */
+ { 0, 0 }, /* 5: VDD */
+ { CMD }, /* 6: PD08, CMD */
+ { DAT3 }, /* 7: PD13, DAT3 */
+ { DAT2 } /* 8: PD12, 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