From 0e9b1c289851f6fe48d025f5edde3c0ac7485296 Mon Sep 17 00:00:00 2001 From: rliebscher Date: Wed, 4 Dec 2013 19:02:55 +0000 Subject: [PATCH] Rework of bitbanging functions setpin, getpin, highpulsepin to make simplier use of new pindefs data in pgm structure * linuxgpio.c, bitbang.c, buspirate.c, par.c, pgm.h, term.c, serbb_*.c: changed interface of setpin, getpin, highpulsepin to take pin function as parameter (not the real number, which can be found by pgm->pinno[function]) git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1252 81a1dc3b-b13d-400b-aceb-764788c761c2 --- ChangeLog | 8 +++++++ bitbang.c | 58 +++++++++++++++++++++++++-------------------------- buspirate.c | 21 ++++++++++++------- linuxgpio.c | 15 +++++++------ par.c | 38 ++++++++++++++++++++------------- pgm.h | 6 +++--- serbb_posix.c | 16 ++++++++------ serbb_win32.c | 15 +++++++------ term.c | 4 ++-- 9 files changed, 107 insertions(+), 74 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6bec728e..e59101a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-12-04 Rene Liebscher + + Rework of bitbanging functions setpin, getpin, highpulsepin to make simplier use + of new pindefs data in pgm structure + * linuxgpio.c, bitbang.c, buspirate.c, par.c, pgm.h, term.c, serbb_*.c: changed + interface of setpin, getpin, highpulsepin to take pin function as parameter + (not the real number, which can be found by pgm->pinno[function]) + 2013-11-30 Rene Liebscher bug #40748 linuxgpio doesn't work on Raspberry PI rev. 2. diff --git a/bitbang.c b/bitbang.c index 5d12ddca..a8855ca2 100644 --- a/bitbang.c +++ b/bitbang.c @@ -195,17 +195,17 @@ static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte) b = (byte >> i) & 0x01; /* set the data input line as desired */ - pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], b); + pgm->setpin(pgm, PIN_AVR_MOSI, b); - pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 1); + pgm->setpin(pgm, PIN_AVR_SCK, 1); /* * read the result bit (it is either valid from a previous falling * edge or it is ignored in the current context) */ - r = pgm->getpin(pgm, pgm->pinno[PIN_AVR_MISO]); + r = pgm->getpin(pgm, PIN_AVR_MISO); - pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0); + pgm->setpin(pgm, PIN_AVR_SCK, 0); rbyte |= r << i; } @@ -216,11 +216,11 @@ static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte) static int bitbang_tpi_clk(PROGRAMMER * pgm) { unsigned char r = 0; - pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 1); + pgm->setpin(pgm, PIN_AVR_SCK, 1); - r = pgm->getpin(pgm, pgm->pinno[PIN_AVR_MISO]); + r = pgm->getpin(pgm, PIN_AVR_MISO); - pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0); + pgm->setpin(pgm, PIN_AVR_SCK, 0); return r; } @@ -231,7 +231,7 @@ void bitbang_tpi_tx(PROGRAMMER * pgm, unsigned char byte) unsigned char b, parity; /* start bit */ - pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 0); + pgm->setpin(pgm, PIN_AVR_MOSI, 0); bitbang_tpi_clk(pgm); parity = 0; @@ -240,16 +240,16 @@ void bitbang_tpi_tx(PROGRAMMER * pgm, unsigned char byte) parity ^= b; /* set the data input line as desired */ - pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], b); + pgm->setpin(pgm, PIN_AVR_MOSI, b); bitbang_tpi_clk(pgm); } /* parity bit */ - pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], parity); + pgm->setpin(pgm, PIN_AVR_MOSI, parity); bitbang_tpi_clk(pgm); /* 2 stop bits */ - pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 1); + pgm->setpin(pgm, PIN_AVR_MOSI, 1); bitbang_tpi_clk(pgm); bitbang_tpi_clk(pgm); } @@ -260,7 +260,7 @@ int bitbang_tpi_rx(PROGRAMMER * pgm) unsigned char b, rbyte, parity; /* make sure pin is on for "pullup" */ - pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 1); + pgm->setpin(pgm, PIN_AVR_MOSI, 1); /* wait for start bit (up to 10 bits) */ b = 1; @@ -303,25 +303,25 @@ int bitbang_tpi_rx(PROGRAMMER * pgm) int bitbang_rdy_led(PROGRAMMER * pgm, int value) { - pgm->setpin(pgm, pgm->pinno[PIN_LED_RDY], !value); + pgm->setpin(pgm, PIN_LED_RDY, !value); return 0; } int bitbang_err_led(PROGRAMMER * pgm, int value) { - pgm->setpin(pgm, pgm->pinno[PIN_LED_ERR], !value); + pgm->setpin(pgm, PIN_LED_ERR, !value); return 0; } int bitbang_pgm_led(PROGRAMMER * pgm, int value) { - pgm->setpin(pgm, pgm->pinno[PIN_LED_PGM], !value); + pgm->setpin(pgm, PIN_LED_PGM, !value); return 0; } int bitbang_vfy_led(PROGRAMMER * pgm, int value) { - pgm->setpin(pgm, pgm->pinno[PIN_LED_VFY], !value); + pgm->setpin(pgm, PIN_LED_VFY, !value); return 0; } @@ -402,13 +402,13 @@ int bitbang_spi(PROGRAMMER * pgm, const unsigned char *cmd, { int i; - pgm->setpin(pgm, pgm->pinno[PIN_LED_PGM], 0); + pgm->setpin(pgm, PIN_LED_PGM, 0); for (i=0; isetpin(pgm, pgm->pinno[PIN_LED_PGM], 1); + pgm->setpin(pgm, PIN_LED_PGM, 1); if(verbose >= 2) { @@ -549,19 +549,19 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p) } /* bring RESET high first */ - pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1); + pgm->setpin(pgm, PIN_AVR_RESET, 1); usleep(1000); if (verbose >= 2) fprintf(stderr, "doing MOSI-MISO link check\n"); - pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 0); - if (pgm->getpin(pgm, pgm->pinno[PIN_AVR_MISO]) != 0) { + pgm->setpin(pgm, PIN_AVR_MOSI, 0); + if (pgm->getpin(pgm, PIN_AVR_MISO) != 0) { fprintf(stderr, "MOSI->MISO 0 failed\n"); return -1; } - pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 1); - if (pgm->getpin(pgm, pgm->pinno[PIN_AVR_MISO]) != 1) { + pgm->setpin(pgm, PIN_AVR_MOSI, 1); + if (pgm->getpin(pgm, PIN_AVR_MISO) != 1) { fprintf(stderr, "MOSI->MISO 1 failed\n"); return -1; } @@ -570,15 +570,15 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p) fprintf(stderr, "MOSI-MISO link present\n"); } - pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0); - pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0); + pgm->setpin(pgm, PIN_AVR_SCK, 0); + pgm->setpin(pgm, PIN_AVR_RESET, 0); usleep(20000); if (p->flags & AVRPART_HAS_TPI) { /* keep TPIDATA high for 16 clock cycles */ - pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 1); + pgm->setpin(pgm, PIN_AVR_MOSI, 1); for (i = 0; i < 16; i++) - pgm->highpulsepin(pgm, pgm->pinno[PIN_AVR_SCK]); + pgm->highpulsepin(pgm, PIN_AVR_SCK); /* remove extra guard timing bits */ bitbang_tpi_tx(pgm, TPI_CMD_SSTCS | TPI_REG_TPIPCR); @@ -592,7 +592,7 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p) return -1; } } else { - pgm->highpulsepin(pgm, pgm->pinno[PIN_AVR_RESET]); + pgm->highpulsepin(pgm, PIN_AVR_RESET); } usleep(20000); /* 20 ms XXX should be a per-chip parameter */ @@ -614,7 +614,7 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p) rc = pgm->program_enable(pgm, p); if ((rc == 0)||(rc == -1)) break; - pgm->highpulsepin(pgm, pgm->pinno[p->retry_pulse/*PIN_AVR_SCK*/]); + pgm->highpulsepin(pgm, p->retry_pulse/*PIN_AVR_SCK*/); tries++; } while (tries < 65); diff --git a/buspirate.c b/buspirate.c index 13407540..a7193641 100644 --- a/buspirate.c +++ b/buspirate.c @@ -1191,10 +1191,11 @@ static void buspirate_bb_enable(struct programmer_t *pgm) Both respond with a byte with current status: 0|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS */ -static int buspirate_bb_getpin(struct programmer_t *pgm, int pin) +static int buspirate_bb_getpin(struct programmer_t *pgm, int pinfunc) { unsigned char buf[10]; int value = 0; + int pin = pgm->pinno[pinfunc]; if (pin & PIN_INVERSE) { pin &= PIN_MASK; @@ -1227,7 +1228,7 @@ static int buspirate_bb_getpin(struct programmer_t *pgm, int pin) return value; } -static int buspirate_bb_setpin(struct programmer_t *pgm, int pin, int value) +static int buspirate_bb_setpin_internal(struct programmer_t *pgm, int pin, int value) { unsigned char buf[10]; @@ -1258,23 +1259,29 @@ static int buspirate_bb_setpin(struct programmer_t *pgm, int pin, int value) return 0; } -static int buspirate_bb_highpulsepin(struct programmer_t *pgm, int pin) +static int buspirate_bb_setpin(struct programmer_t *pgm, int pinfunc, int value) +{ + return buspirate_bb_setpin_internal(pgm, pgm->pinno[pinfunc], value); +} + + +static int buspirate_bb_highpulsepin(struct programmer_t *pgm, int pinfunc) { int ret; - ret = buspirate_bb_setpin(pgm, pin, 1); + ret = buspirate_bb_setpin(pgm, pinfunc, 1); if (ret < 0) return ret; - return buspirate_bb_setpin(pgm, pin, 0); + return buspirate_bb_setpin(pgm, pinfunc, 0); } static void buspirate_bb_powerup(struct programmer_t *pgm) { - buspirate_bb_setpin(pgm, 7, 1); + buspirate_bb_setpin_internal(pgm, 7, 1); } static void buspirate_bb_powerdown(struct programmer_t *pgm) { - buspirate_bb_setpin(pgm, 7, 0); + buspirate_bb_setpin_internal(pgm, 7, 0); } const char buspirate_bb_desc[] = "Using the Bus Pirate's bitbang interface for programming"; diff --git a/linuxgpio.c b/linuxgpio.c index 9fb6af91..a02bc34c 100644 --- a/linuxgpio.c +++ b/linuxgpio.c @@ -145,9 +145,10 @@ static int linuxgpio_dir_in(unsigned int gpio) static int linuxgpio_fds[N_GPIO] ; -static int linuxgpio_setpin(PROGRAMMER * pgm, int pin, int value) +static int linuxgpio_setpin(PROGRAMMER * pgm, int pinfunc, int value) { int r; + int pin = pgm->pinno[pinfunc]; // TODO if (pin & PIN_INVERSE) { @@ -171,10 +172,11 @@ static int linuxgpio_setpin(PROGRAMMER * pgm, int pin, int value) return 0; } -static int linuxgpio_getpin(PROGRAMMER * pgm, int pin) +static int linuxgpio_getpin(PROGRAMMER * pgm, int pinfunc) { unsigned char invert=0; char c; + int pin = pgm->pinno[pinfunc]; // TODO if (pin & PIN_INVERSE) { @@ -200,14 +202,15 @@ static int linuxgpio_getpin(PROGRAMMER * pgm, int pin) } -static int linuxgpio_highpulsepin(PROGRAMMER * pgm, int pin) +static int linuxgpio_highpulsepin(PROGRAMMER * pgm, int pinfunc) { - + int pin = pgm->pinno[pinfunc]; // TODO + if ( linuxgpio_fds[pin & PIN_MASK] < 0 ) return -1; - linuxgpio_setpin(pgm, pin, 1); - linuxgpio_setpin(pgm, pin, 0); + linuxgpio_setpin(pgm, pinfunc, 1); + linuxgpio_setpin(pgm, pinfunc, 0); return 0; } diff --git a/par.c b/par.c index dab3293c..933349dd 100644 --- a/par.c +++ b/par.c @@ -74,7 +74,7 @@ static struct ppipins_t ppipins[] = { #define NPINS (sizeof(ppipins)/sizeof(struct ppipins_t)) -static int par_setpin(PROGRAMMER * pgm, int pin, int value) +static int par_setpin_internal(PROGRAMMER * pgm, int pin, int value) { int inverted; @@ -103,23 +103,30 @@ static int par_setpin(PROGRAMMER * pgm, int pin, int value) return 0; } -static void par_setmany(PROGRAMMER * pgm, unsigned int pinset, int value) +static int par_setpin(PROGRAMMER * pgm, int pinfunc, int value) +{ + return par_setpin_internal(pgm, pgm->pinno[pinfunc], value); +} + +static void par_setmany(PROGRAMMER * pgm, int pinfunc, int value) { int pin, mask; + int pinset = pgm->pinno[pinfunc]; /* mask is anything non-pin - needs to be applied to each par_setpin to preserve inversion */ mask = pinset & (~PIN_MASK); for (pin = 1; pin <= 17; pin++) { if (pinset & (1 << pin)) - par_setpin(pgm, pin | mask, value); + par_setpin_internal(pgm, pin | mask, value); } } -static int par_getpin(PROGRAMMER * pgm, int pin) +static int par_getpin(PROGRAMMER * pgm, int pinfunc) { int value; int inverted; + int pin = pgm->pinno[pinfunc]; inverted = pin & PIN_INVERSE; pin &= PIN_MASK; @@ -144,9 +151,10 @@ static int par_getpin(PROGRAMMER * pgm, int pin) } -static int par_highpulsepin(PROGRAMMER * pgm, int pin) +static int par_highpulsepin(PROGRAMMER * pgm, int pinfunc) { int inverted; + int pin = pgm->pinno[pinfunc]; inverted = pin & PIN_INVERSE; pin &= PIN_MASK; @@ -185,7 +193,7 @@ static int par_highpulsepin(PROGRAMMER * pgm, int pin) */ static void par_powerup(PROGRAMMER * pgm) { - par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 1); /* power up */ + par_setmany(pgm, PPI_AVR_VCC, 1); /* power up */ usleep(100000); } @@ -195,12 +203,12 @@ static void par_powerup(PROGRAMMER * pgm) */ static void par_powerdown(PROGRAMMER * pgm) { - par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 0); /* power down */ + par_setmany(pgm, PPI_AVR_VCC, 0); /* power down */ } static void par_disable(PROGRAMMER * pgm) { - par_setmany(pgm, pgm->pinno[PPI_AVR_BUFF], 1); /* turn off */ + par_setmany(pgm, PPI_AVR_BUFF, 1); /* turn off */ } static void par_enable(PROGRAMMER * pgm) @@ -216,13 +224,13 @@ static void par_enable(PROGRAMMER * pgm) * and not via the buffer chip. */ - par_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0); + par_setpin(pgm, PIN_AVR_RESET, 0); usleep(1); /* * enable the 74367 buffer, if connected; this signal is active low */ - par_setmany(pgm, pgm->pinno[PPI_AVR_BUFF], 0); + par_setmany(pgm, PPI_AVR_BUFF, 0); } static int par_open(PROGRAMMER * pgm, char * port) @@ -269,18 +277,18 @@ static void par_close(PROGRAMMER * pgm) ppi_setall(&pgm->fd, PPIDATA, pgm->ppidata); ppi_setall(&pgm->fd, PPICTRL, pgm->ppictrl); - par_setmany(pgm, pgm->pinno[PPI_AVR_BUFF], 1); + par_setmany(pgm, PPI_AVR_BUFF, 1); /* * Handle exit specs. */ switch (pgm->exit_reset) { case EXIT_RESET_ENABLED: - par_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0); + par_setpin(pgm, PIN_AVR_RESET, 0); break; case EXIT_RESET_DISABLED: - par_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1); + par_setpin(pgm, PIN_AVR_RESET, 1); break; case EXIT_RESET_UNSPEC: @@ -304,11 +312,11 @@ static void par_close(PROGRAMMER * pgm) switch (pgm->exit_vcc) { case EXIT_VCC_ENABLED: - par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 1); + par_setmany(pgm, PPI_AVR_VCC, 1); break; case EXIT_VCC_DISABLED: - par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 0); + par_setmany(pgm, PPI_AVR_VCC, 0); break; case EXIT_VCC_UNSPEC: diff --git a/pgm.h b/pgm.h index 00405005..88cba103 100644 --- a/pgm.h +++ b/pgm.h @@ -122,9 +122,9 @@ typedef struct programmer_t { int (*set_varef) (struct programmer_t * pgm, unsigned int chan, double v); int (*set_fosc) (struct programmer_t * pgm, double v); int (*set_sck_period) (struct programmer_t * pgm, double v); - int (*setpin) (struct programmer_t * pgm, int pin, int value); - int (*getpin) (struct programmer_t * pgm, int pin); - int (*highpulsepin) (struct programmer_t * pgm, int pin); + int (*setpin) (struct programmer_t * pgm, int pinfunc, int value); + int (*getpin) (struct programmer_t * pgm, int pinfunc); + int (*highpulsepin) (struct programmer_t * pgm, int pinfunc); int (*parseexitspecs) (struct programmer_t * pgm, char *s); int (*perform_osccal) (struct programmer_t * pgm); int (*parseextparams) (struct programmer_t * pgm, LISTID xparams); diff --git a/serbb_posix.c b/serbb_posix.c index da9e5830..6d5b0c84 100644 --- a/serbb_posix.c +++ b/serbb_posix.c @@ -71,10 +71,11 @@ static char *serpins[DB9PINS + 1] = { "NONE", "CD", "RXD", "TXD", "DTR", "GND", "DSR", "RTS", "CTS", "RI" }; #endif -static int serbb_setpin(PROGRAMMER * pgm, int pin, int value) +static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value) { unsigned int ctl; int r; + int pin = pgm->pinno[pinfunc]; // get its value if (pin & PIN_INVERSE) { @@ -127,11 +128,12 @@ static int serbb_setpin(PROGRAMMER * pgm, int pin, int value) return 0; } -static int serbb_getpin(PROGRAMMER * pgm, int pin) +static int serbb_getpin(PROGRAMMER * pgm, int pinfunc) { unsigned int ctl; unsigned char invert; int r; + int pin = pgm->pinno[pinfunc]; // get its value if (pin & PIN_INVERSE) { @@ -177,13 +179,15 @@ static int serbb_getpin(PROGRAMMER * pgm, int pin) } } -static int serbb_highpulsepin(PROGRAMMER * pgm, int pin) +static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc) { + int pin = pgm->pinno[pinfunc]; // replace pin name by its value + if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS ) return -1; - serbb_setpin(pgm, pin, 1); - serbb_setpin(pgm, pin, 0); + serbb_setpin(pgm, pinfunc, 1); + serbb_setpin(pgm, pinfunc, 0); return 0; } @@ -277,7 +281,7 @@ static void serbb_close(PROGRAMMER *pgm) if (pgm->fd.ifd != -1) { (void)tcsetattr(pgm->fd.ifd, TCSANOW, &oldmode); - pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1); + pgm->setpin(pgm, PIN_AVR_RESET, 1); close(pgm->fd.ifd); } return; diff --git a/serbb_win32.c b/serbb_win32.c index 58a5147e..2289c66b 100644 --- a/serbb_win32.c +++ b/serbb_win32.c @@ -60,8 +60,9 @@ static int dtr, rts, txd; #define DB9PINS 9 -static int serbb_setpin(PROGRAMMER * pgm, int pin, int value) +static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value) { + int pin = pgm->pinno[pinfunc]; HANDLE hComPort = (HANDLE)pgm->fd.pfd; LPVOID lpMsgBuf; DWORD dwFunc; @@ -132,8 +133,9 @@ static int serbb_setpin(PROGRAMMER * pgm, int pin, int value) return 0; } -static int serbb_getpin(PROGRAMMER * pgm, int pin) +static int serbb_getpin(PROGRAMMER * pgm, int pinfunc) { + int pin = pgm->pinno[pinfunc]; HANDLE hComPort = (HANDLE)pgm->fd.pfd; LPVOID lpMsgBuf; int invert, rv; @@ -225,13 +227,14 @@ static int serbb_getpin(PROGRAMMER * pgm, int pin) return rv; } -static int serbb_highpulsepin(PROGRAMMER * pgm, int pin) +static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc) { + int pin = pgm->pinno[pinfunc]; if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS ) return -1; - serbb_setpin(pgm, pin, 1); - serbb_setpin(pgm, pin, 0); + serbb_setpin(pgm, pinfunc, 1); + serbb_setpin(pgm, pinfunc, 0); return 0; } @@ -333,7 +336,7 @@ static void serbb_close(PROGRAMMER *pgm) HANDLE hComPort=(HANDLE)pgm->fd.pfd; if (hComPort != INVALID_HANDLE_VALUE) { - pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1); + pgm->setpin(pgm, PIN_AVR_RESET, 1); CloseHandle (hComPort); } if (verbose > 2) diff --git a/term.c b/term.c index 2f4c8da2..e209a111 100644 --- a/term.c +++ b/term.c @@ -749,7 +749,7 @@ static int cmd_help(PROGRAMMER * pgm, struct avrpart * p, static int cmd_spi(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) { - pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1); + pgm->setpin(pgm, PIN_AVR_RESET, 1); spi_mode = 1; return 0; } @@ -757,7 +757,7 @@ static int cmd_spi(PROGRAMMER * pgm, struct avrpart * p, static int cmd_pgm(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[]) { - pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0); + pgm->setpin(pgm, PIN_AVR_RESET, 0); spi_mode = 0; pgm->initialize(pgm, p); return 0;