In message <[EMAIL PROTECTED]>, Roberto Fichera w
rites:
>Hi all on the list,
>
>Since I just got my first net5501-60 (I've installed smootly, a quite minimal 
>Fedora8 on a 
>8GB CF) I would like to be pointed out to an userspace example of GPIO usage. 
>Does anyone
>can give me an URL or an example to start from?

The NET5501 is the same as the NET4801 in this respect so any example
from there can be used as well.

Included is some code I bang'ed together to program PIC18 chips with,
you can glean various bits from there, but grab a copy of the
datasheet as well, you'll need it.


/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <[EMAIL PROTECTED]> wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
 * ----------------------------------------------------------------------------
 * $Id: icsp.c,v 1.26 2008/01/27 15:04:52 phk Exp $
 *
 */

#include <sys/types.h>
#include <machine/cpufunc.h>
#include <stdio.h>
#include <assert.h>
#include <wchar.h>
#include <printf.h>
#include <assert.h>
#include <string.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>

#include <phk_ihex.h>

#define HD_COLUMN_MASK  0x000000ff
#define HD_DELIM_MASK   0x0000ff00
#define HD_OMIT_COUNT   (1 << 16)
#define HD_OMIT_HEX     (1 << 17)
#define HD_OMIT_CHARS   (1 << 18)

static int verbose = 0;

static u_int net4801 = 0;
static u_int atms = 0;
static u_int porto = 0;
static u_int porti = 0x379;
static int d_opt = 0x08;

struct fixup {
        u_int           address;
        u_int           set_bits;
        u_int           clr_bits;
        const char      *reason;
};

static struct fixup fix8722[] = {
        { 0x300006, 0x04, 0x00, "Enable Single-Supply ICSP" },
        { 0x300008, 0xff, 0x00, "Don't code protect code blocks 0-7" },
        { 0x300009, 0x40, 0x00, "Don't code protect boot block" },
        { 0x300009, 0x80, 0x00, "Don't code protect data EEPROM" },
        { 0x30000a, 0xff, 0x00, "Don't write protect code blocks 0-7" },
        { 0x30000b, 0x20, 0x00, "Don't write protect config registers" },
        { 0x30000b, 0x40, 0x00, "Don't write protect boot block" },
        { 0x30000b, 0x80, 0x00, "Don't write protect data EEPROM" },
        { 0x30000c, 0xff, 0x00, "Don't tblrd protect code blocks 0-7" },
        { 0x30000d, 0x40, 0x00, "Don't tblrd protect boot block" },
        { .reason = NULL }
};

static struct fixup fix1220[] = {
        { 0x300006, 0x04, 0x00, "Enable Single-Supply ICSP" },
        { .reason = NULL }
};

static struct fixup fix2523[] = {
        { 0x300006, 0x04, 0x00, "Enable Single-Supply ICSP" },
        { .reason = NULL }
};

enum write_alg {
        W1,     /* PIC18FX220/X320 DS39592B */
        W2,     /* PIC18F8722 DS39643B */
};

struct chipid {
        const char      *name;
        u_int           devid1;
        u_int           devid1_mask;
        u_int           devid2;
        u_int           code_size;
        u_int           code_block;     /* ??? */
        u_int           eeprom_size;
        u_int           config_size;
        u_int           ident_size;
        u_int           write_size;
        u_int           erase_size;
        struct fixup    *fixup;
        enum write_alg  write_alg;
};

#define K       1024

#define CFG     0x300000
#define IDENT   0x200000

static struct chipid chips[] = {
    { "PIC18F1220", 0xe0, 0xe0, 0x07,   4*K,  2*K,  256, 14, 8,  8, 64, 
fix1220, W1 },
    { "PIC18F2220", 0x80, 0xe0, 0x05,   4*K,  2*K,  256, 14, 8,  8, 64, 
fix1220, W1 },
    { "PIC18F4220", 0xa0, 0xe0, 0x05,   4*K,  2*K,  256, 14, 8,  8, 64, 
fix1220, W1 },
    { "PIC18F1320", 0xc0, 0xe0, 0x07,   8*K,  4*K,  256, 14, 8,  8, 64, 
fix1220, W1 },
    { "PIC18F2320", 0x00, 0xe0, 0x05,   8*K,  2*K,  256, 14, 8,  8, 64, 
fix1220, W1 },
    { "PIC18F4320", 0x20, 0xe0, 0x05,   8*K,  2*K,  256, 14, 8,  8, 64, 
fix1220, W1 },

    { "PIC18F2423", 0x50, 0xf0, 0x11,  16*K,  8*K,  256, 14, 8, 32, 64, 
fix2523, W2 },
    { "PIC18F2523", 0x10, 0xf0, 0x11,  32*K,  8*K,  256, 14, 8, 32, 64, 
fix2523, W2 },
    { "PIC18F4423", 0xd0, 0xf0, 0x10,  16*K,  8*K,  256, 14, 8, 32, 64, 
fix2523, W2 },
    { "PIC18F4523", 0x90, 0xf0, 0x10,  32*K,  8*K,  256, 14, 8, 32, 64, 
fix2523, W2 },

    { "PIC18F6527", 0x40, 0xe0, 0x13,  48*K, 16*K,  1*K, 14, 8, 64, 64, 
fix8722, W2 },
    { "PIC18F6622", 0x80, 0xe0, 0x13,  64*K, 16*K,  1*K, 14, 8, 64, 64, 
fix8722, W2 },
    { "PIC18F6627", 0xc0, 0xe0, 0x13,  96*K, 16*K,  1*K, 14, 8, 64, 64, 
fix8722, W2 },
    { "PIC18F6722", 0x00, 0xe0, 0x14, 128*K, 16*K,  1*K, 14, 8, 64, 64, 
fix8722, W2 },
    { "PIC18F8527", 0x60, 0xe0, 0x13,  48*K, 16*K,  1*K, 14, 8, 64, 64, 
fix8722, W2 },
    { "PIC18F8622", 0x50, 0xf0, 0x13,  64*K, 16*K,  1*K, 14, 8, 64, 64, 
fix8722, W2 },
    { "PIC18F8627", 0xe0, 0xe0, 0x13,  96*K, 16*K,  1*K, 14, 8, 64, 64, 
fix8722, W2 },
    { "PIC18F8722", 0x20, 0xe0, 0x14, 128*K, 16*K,  1*K, 14, 8, 64, 64, 
fix8722, W2 },

    { .name = NULL }
};

#undef K

struct chip {
        struct chipid   *id;
        u_char          *code;
        u_char          *eeprom;
        u_char          *config;
        u_char          *ident;
        struct phkihex  *ihf;
};

/*

  1  -------------- VPP  bl
  14 -------------- PGM br
  17 -------------- PGC ora
  10 ----/\/\/\---- PGD gr
       |
       |
       v
       -
       |
  16 ---

*/
/*
J401            Soekris JP5     Signal
1       -----      3/gpio20     MCLR/VPP
2       -----      4/gpio21     PGM
3       -----      5/gpio22     PGC
4       -----      6/gpio23     PGD
*/

static int loopcount = 3;

static __inline void
S(int pgd, int pgc, int pgm, int vpp)
{
        int i, j;

        i = 0;
        if (!net4801) {
                if (pgd)  i |= 4;
                if (!pgc) i |= 8;
                if (!pgm) i |= 2;
                if (!vpp) i |= 1;
                outb(0x37a, i);
        } else {
                if (pgd)  i |= 0x08;
                if (pgc)  i |= 0x04;
                if (pgm)  i |= 0x02;
                if (vpp)  i |= 0x01;
                for (j = 0; j < loopcount; j++)
                        outb(porto, i);
        }
}

static u_int
SW(u_int word, u_int bits)
{
        u_int u = 0, v;

        S(0, 0, 1, 1);
        while (bits--) {
                v = word & 1;
                S(v, 1, 1, 1);
                if (net4801)
                        u |= (inb(porti) & d_opt ? 0x100 : 0);
                else
                        u |= (inb(porti) & 0x40 ? 0x100 : 0);
                S(v, 0, 1, 1);
                u >>= 1;
                word >>= 1;
        }
        return (u);
}

static u_int
RW(u_int word)
{
        u_int u = 0, v;
        int bits = 20;

        while (bits--) {
                v = word & 1;
                S(v, 1, 1, 1);
                if (net4801)
                        u |= (inb(porti) & d_opt ? 0x100 : 0);
                else
                        u |= (inb(porti) & 0x40 ? 0x100 : 0);
                S(v, 0, 1, 1);
                u >>= 1;
                word >>= 1;
        }
        return (u);
}

static void
NOP_P9P10(void)
{

        S(0, 0, 1, 1);
        S(0, 1, 1, 1);

        S(0, 0, 1, 1);
        S(0, 1, 1, 1);

        S(0, 0, 1, 1);
        S(0, 1, 1, 1);

        S(0, 0, 1, 1);
        S(0, 1, 1, 1);
        usleep(1000);

        S(0, 0, 1, 1);
        usleep(100);

        SW(0, 16);
}

static void
NOP_P10P11(void)
{
        S(0, 0, 1, 1);
        S(0, 1, 1, 1);

        S(0, 0, 1, 1);
        S(0, 1, 1, 1);

        S(0, 0, 1, 1);
        S(0, 1, 1, 1);

        S(0, 0, 1, 1);
        S(0, 1, 1, 1);
        S(0, 0, 1, 1);
        usleep(5100);   /* P11 = 5msec + P10 = 100usec */

        SW(0, 16);
}

static u_int
Instr(u_int instr)
{

        SW(0x0, 4);
        return (SW(instr, 16));
}

static void
SetAddr(u_int addr)
{
        if (addr & ~0xffffff)
                errx(1, "Wrong address in SetAddr %x", addr);

        Instr(0x0e00 | ((addr >> 16) & 0xff));  /* movlw <ADDR21:16>    */
        Instr(0x6ef8);                          /* movwf TBLPTRU        */
        Instr(0x0e00 | ((addr >> 8) & 0xff));   /* movlw <ADDR15:8>     */
        Instr(0x6ef7);                          /* movwf TBLPTRH        */
        Instr(0x0e00 | ((addr >> 0) & 0xff));   /* movlw <ADDR7:0>      */
        Instr(0x6ef6);                          /* movwf TBLPTRL        */
}

static u_int
ReadEepromByte(struct chip *cp, u_int addr)
{

        if (addr >= cp->id->eeprom_size)
                errx(1, "Wrong address in ReadEeprom 0x%x", addr);

        Instr(0x9ea6);                  /* bcf EECON1, EEPGD    */
        Instr(0x9ca6);                  /* bcf EECON1, CFGS     */

        Instr(0x0e00 | addr);           /* movlw <ADDR>         */
        Instr(0x6ea9);                  /* movwf EEADR          */

        Instr(0x80a6);                  /* bsf EECON1, RD       */

        Instr(0x50a8);                  /* movf EEDATA, W, 0    */
        Instr(0x6ef5);                  /* movwf TABLAT         */

        SW(0x2, 4);
        return (SW(0x0000, 16));
}

#if 0
static void
WriteEepromByte(u_int addr, u_int data)
{
        if (addr & ~0xff)
                errx(1, "Wrong address in WriteEeprom %x", addr);
        if (data & ~0xff)
                errx(1, "Wrong data in WriteEeprom %x", data);

        printf("WriteEeprom(%02x, %02x)\n", addr, data);

        Instr(0x9ea6);                  /* bcf EECON1, EEPGD    */
        Instr(0x9ca6);                  /* bcf EECON1, CFGS     */

        Instr(0x0e00 | addr);           /* movlw <ADDR>         */
        Instr(0x6ea9);                  /* movwf EEADR          */

        Instr(0x0e00 | data);           /* movlw <DATA>         */
        Instr(0x6ea8);                  /* movwf EEDATA         */

        Instr(0x84a6);                  /* bsf EECON1, WREN     */

        Instr(0x0e55);                  /* movlw 0x55           */
        Instr(0x6ea7);                  /* movwf EECON2         */
        Instr(0x0eaa);                  /* movlw 0xaa           */
        Instr(0x6ea7);                  /* movwf EECON2         */

        Instr(0x82a6);                  /* bsf EECON1, WR       */
        Instr(0x0000);                  /* nop                  */
        Instr(0x0000);                  /* nop                  */

        usleep(5000);

        Instr(0x94a6);                  /* bcf EECON1, WREN     */
}
#endif

static void
ReadEeprom(struct chip *cp)
{
        u_int u;

        for (u = 0; u < cp->id->eeprom_size; u++)
                cp->eeprom[u] = ReadEepromByte(cp, u);
}

static __inline u_int
TblRdIncr(void)
{
        u_int u;

        u = RW(0xff009);
        return (u);
}

static void
ReadCode(struct chip *cp)
{
        u_int u;

        SetAddr(0x0);
        for (u = 0x0; u < cp->id->code_size; u++) 
                cp->code[u] = TblRdIncr();
}

static void
ReadConfig(struct chip *cp)
{
        u_int u;

        SetAddr(CFG);
        for (u = 0x0; u < cp->id->config_size; u++)
                cp->config[u] = TblRdIncr();
}

static void
ReadIdent(struct chip *cp)
{
        u_int u;

        SetAddr(IDENT);
        for (u = 0x0; u < cp->id->ident_size; u++)
                cp->ident[u] = TblRdIncr();
}


static struct chipid *
FindChip(void)
{
        u_int devid1, devid2, devid, revid;
        struct chipid *cp;

        SetAddr(0x3ffffe);
        devid1 = TblRdIncr();
        devid2 = TblRdIncr();
        if (devid1 == 0xff && devid2 == 0xff)
                return (NULL);
        printf("DEVID1: 0x%02x ", devid1);
        printf("DEVID2: 0x%02x ", devid2);

        devid = (devid2 << 8) | devid1;
        revid = devid & 0x1f;
        devid >>= 5;
        printf("DEVID:  0x%02x ", devid);
        printf("REVID:  0x%02x\n", revid);
        for(cp = chips; cp->name != NULL; cp++) {
                if (cp->devid1 & ~cp->devid1_mask) {
                        printf("Bogus: %s\n", cp->name);
                }
                if (cp->devid1 == (devid1 & cp->devid1_mask)
                     && cp->devid2 == devid2) {
                        printf("CHIP:   %s\n", cp->name);
                        return (cp);
                }
        }
        return (NULL);
}

static struct chip *
AllocChip(struct chipid *cp)
{
        struct chip *c;

        c = calloc(sizeof *c, 1);
        c->id = cp;
        c->code = calloc(1, cp->code_size);
        memset(c->code, 0xff, cp->code_size);
        c->eeprom = calloc(1, cp->eeprom_size);
        memset(c->eeprom, 0xff, cp->eeprom_size);
        c->ident = calloc(1, cp->ident_size);
        memset(c->ident, 0xff, cp->ident_size);
        c->config = calloc(1, cp->config_size);
        memset(c->config, 0xff, cp->config_size);
        return (c);
}

static void
WriteCode(struct chip *cp)
{
        u_int i, j;
        u_int addr, a2, ws, es;
        u_char *dp;
        enum write_alg wa;
        u_char *fh;
        u_char *dv;

        if (verbose)
                printf("Write Code begin.\n");
        es = cp->id->erase_size;
        ws = cp->id->write_size;
        wa = cp->id->write_alg;
        fh = calloc(sizeof *fh, es);
        assert(fh != NULL);
        dv = calloc(sizeof *fh, es);
        assert(dv != NULL);
        /* Loop through all erase blocks */
        for (addr = 0; addr < cp->id->code_size; addr += es) {
                /* See if the hexfile has anything for us */
                if (!PhkIhexGet(&cp->ihf, addr, es, fh)) {
                        if (verbose > 1)
                                printf("HexFileEmpty(%x)\n", addr);
                        else if (verbose)
                                printf(".");
                        continue;
                }
                /* Read what the device has */
                SetAddr(addr);
                for (j = 0x0; j < es; j++) 
                        fh[j] = dv[j] = TblRdIncr();

                /* Overwrite with hexfile contents */
                PhkIhexGet(&cp->ihf, addr, es, fh);

                /* If identical skip block */
                if (!memcmp(fh, dv, es)) {
                        if (verbose > 1)
                                printf("Unchanged(%x)\n", addr);
                        else if (verbose)
                                printf("=");
                        continue;
                }

                Instr(0x8ea6);          /* bsf EECON1, EEPGD    */
                Instr(0x9ca6);          /* bcf EECON1, CFGS     */

                /* Erase block if necessary */
                for (i = 0; i < es; i++) {
                        if (dv[i] == 0xff)
                                continue;
                        if (verbose > 1)
                                printf("EraseBlock(%x)\n", addr);
                        else if (verbose)
                                printf("E");
                        SetAddr(addr);
                        Instr(0x84a6);          /* bsf EECON1, WREN     */
                        Instr(0x88a6);          /* bsf EECON1, FREE     */

                        if (wa == W1) {
                                Instr(0x0e55);  /* movlw 0x55           */
                                Instr(0x6ea7);  /* movwf eecon2         */
                                Instr(0x0eaa);  /* movlw 0xaa           */
                                Instr(0x6ea7);  /* movwf eecon2         */
                        }

                        Instr(0x82a6);          /* bsf EECON1, WR       */

                        NOP_P10P11();
                        Instr(0x94a6);          /* bcf EECON1, WREN */
                        usleep(10000);          /* XXX: hack */
                        break;
                }

                if (wa == W2) {
                        Instr(0x8ca6);          /* bcf EECON1, CFGS     */
                        Instr(0x9ca6);          /* bcf EECON1, CFGS     */
                }

                for (j = 0; j < es; j += ws) {
                        a2 = addr + j;
                        dp = &fh[j];
                        if (verbose > 1)
                                printf("WriteBlock(%x)\n%H\n%H\n",
                                    a2, &dv[j], ws, dp, ws);
                        else if (verbose)
                                printf("W");

                        SetAddr(a2);

                        for (i = 0; i < ws - 2; i += 2) {
                                SW(0xd, 4); SW((dp[1] << 8) | dp[0], 16);
                                dp += 2;
                        }
                        SW(0xf, 4); SW((dp[1] << 8) | dp[0], 16);
                        NOP_P9P10();
                }
        }
        if (verbose)
                printf("%sWrite Code done.\n", verbose == 1 ? "\n" : "");
}

static void
WriteConfig(struct chip *cp)
{
        u_int i;
        u_char *dp;
        u_char *p, n;
        u_char *fh;
        struct fixup *fp;

        ReadConfig(cp);
        fh = calloc(sizeof *fh, cp->id->config_size);
        assert(fh != NULL);
        memcpy(fh, cp->config, cp->id->config_size);
        if (!PhkIhexGet(&cp->ihf, CFG, cp->id->config_size, fh)) {
                printf("No config in hex file");
                return;
        }

        for (fp = cp->id->fixup; fp->address != 0; fp++) {
                assert(fp->address >= CFG &&
                    fp->address < CFG + cp->id->config_size);
                p = fh + fp->address - CFG;
                n = *p;
                n |= fp->set_bits;
                n &= ~fp->clr_bits;
                if (*p == n)
                        continue;
                printf("FIXUP: 0x%x: %02x -> %02x -- %s\n",
                    fp->address, *p, n, fp->reason);
                *p = n;
        }

        for (i = 0; i < cp->id->config_size; i += 2) {
                if (!memcmp(cp->config + i, fh + i, 2))
                        continue;

                printf("Config %x (%02x %02x) -> (%02x %02x)\n",
                    CFG + i, cp->config[i], cp->config[i + 1],
                    fh[i], fh[i + 1]);

                dp = &fh[i];

                Instr(0x8ea6);          /* bsf EECON1, EEPGD    */
                Instr(0x8ca6);          /* bsf EECON1, CFGS     */

                Instr(0xef00);          /* goto 0x100000        */
                Instr(0xf800);

                SetAddr(CFG + i);
                SW(0xf, 4); SW((dp[1] << 8) | dp[0], 16);
                NOP_P9P10();
                SetAddr(CFG + i + 1);
                SW(0xf, 4); SW((dp[1] << 8) | dp[0], 16);
                NOP_P9P10();
        }
}

static void
Fixup(struct chip *cp)
{
        struct fixup *fp;
        u_char *p, n;

        for (fp = cp->id->fixup; fp->address != 0; fp++) {
                if (fp->address < cp->id->code_size)
                        p = cp->code + fp->address;
                else if (fp->address >= CFG &&
                    fp->address < CFG + cp->id->config_size)
                        p = cp->config + fp->address - CFG;
                else
                        errx(1, "Unknown fixup address %x\n", fp->address);
                n = *p;
                n |= fp->set_bits;
                n &= ~fp->clr_bits;
                if (*p == n)
                        continue;
                printf("FIXUP: 0x%x: %02x -> %02x -- %s\n",
                    fp->address, *p, n, fp->reason);
                *p = n;
        }
}

static void
DumpAll(struct chip *cp)
{

        printf("IDN\n%+#H\n", cp->ident, cp->id->ident_size);
        printf("EEP\n%+#H\n", cp->eeprom, cp->id->eeprom_size);
        printf("COD\n%+#H\n", cp->code,   cp->id->code_size);
        printf("CFG\n%+#H\n", cp->config, cp->id->config_size);
}

static void
BulkErase(void)
{

        printf("Bulk Erase\n");
        SetAddr(0x3c0005);
        SW(0xc, 4); SW(0xffff, 16);
        SetAddr(0x3c0004);
        SW(0xc, 4); SW(0x8787, 16);

        NOP_P10P11();
}

int
main(int argc, char **argv)
{
        struct chipid *id;
        struct chip *cp;
        FILE *fio;
        u_int u, i;
        int ch;
        int i_opt, r_opt, E_opt;

        setbuf(stdout, NULL);
        register_printf_render_std("VH");

        i_opt = r_opt = E_opt = 0;
        while ((ch = getopt(argc, argv, "dEirv")) != -1) {
                switch (ch) {
                case 'd':
                        d_opt = 0x10;
                        break;
                case 'E':
                        E_opt = 1;
                        break;
                case 'i':
                        i_opt = 1;
                        break;
                case 'r':
                        r_opt = 1;
                        break;
                case 'v':
                        verbose++;
                        break;
                default:
                        errx(1, "Usage: %s [-v] [-i] [-E] [-r] [file.hex]");
                }
        }
        argc -= optind;
        argv += optind;

        fio = fopen("/dev/io", "w");
        if (fio == NULL)
                errx(1, "Could not open /dev/io");

        /* Probe for NET4801 super-I/O */
        outb(0x2e, 0x20);
        u = inb(0x2f);
        if (u == 0xe9) {
/*
J401            Soekris JP5     Signal
1       -----      3/gpio20     MCLR/VPP
2       -----      4/gpio21     PGM
3       -----      5/gpio22     PGC
4       -----      6/gpio23     PGD
*/

                printf("Found PC87366 Super-I/O, assuming NET4801\n");
                net4801 = 1;
                outb(0x2e, 0x07); outb(0x2f, 0x07);
                outb(0x2e, 0x60); atms = inb(0x2f) << 8;
                outb(0x2e, 0x61); atms |= inb(0x2f);
                outb(0x2e, 0x30); i = inb(0x2f);
                if (!(i & 1))
                        errx(1, "GPIO not enabled\n");
                printf("ATMS = %x\n", atms);

                outb(0x2e, 0xf0); outb(0x2f, 0x20);
                outb(0x2e, 0xf1); outb(0x2f, 0x01); /* O-Drain, has pull-up */

                outb(0x2e, 0xf0); outb(0x2f, 0x21);
                outb(0x2e, 0xf1); outb(0x2f, 0x03); /* Push-Pull */

                outb(0x2e, 0xf0); outb(0x2f, 0x22);
                outb(0x2e, 0xf1); outb(0x2f, 0x03); /* Push-Pull */

                outb(0x2e, 0xf0); outb(0x2f, 0x23);
                outb(0x2e, 0xf1); outb(0x2f, 0x05); /* O-Drain w/ pull-up */

                if (d_opt != 0x08) {
                        outb(0x2e, 0xf0); outb(0x2f, 0x24);
                        outb(0x2e, 0xf1); outb(0x2f, 0x04); /* Input w/pu */
                }
                porto = atms + 4 * 2 + 0;
                porti = atms + 4 * 2 + 1;
        }

        if (r_opt) {
                S(0, 0, 0, 0);
                S(0, 0, 1, 0);
                goto bailout;
        }

        for (loopcount = 10; loopcount < 75; loopcount++) {
                S(0, 0, 0, 0);
                S(0, 0, 1, 0);
                usleep(2);
                S(0, 0, 1, 1);
                usleep(2);

                id = FindChip();
                if (id != NULL)
                        break;
        }
        loopcount *= 12;
        loopcount /= 10;
        if (id == NULL) {
                printf("Stop\n");
                S(0, 0, 0, 0);
                errx(1, "Unknown chip or cable problem");
        }
        printf("Using loopcount %d\n", loopcount);

        cp = AllocChip(id);

        if (r_opt)
                goto bailout;

        if (i_opt) {
                ReadIdent(cp);
                goto bailout;
        }

        if (E_opt)
                BulkErase();
        else if (argc == 0) {
                ReadIdent(cp);
                ReadConfig(cp);
                ReadEeprom(cp);
                ReadCode(cp);
                DumpAll(cp);
        }

        if (argc > 0) {
                i = PhkIhexRead(argv[0], &cp->ihf);
                assert(i == 0);
                Fixup(cp);
                WriteCode(cp);
                WriteConfig(cp);
        }

bailout:
        S(0, 0, 1, 1);
        printf("Stop\n");
        S(0, 0, 0, 0);
        printf("Start program\n");
        S(0, 0, 0, 1);
        if (net4801) {

                outb(0x2e, 0xf0); outb(0x2f, 0x20);
                outb(0x2e, 0xf1); outb(0x2f, 0x00);

                outb(0x2e, 0xf0); outb(0x2f, 0x21);
                outb(0x2e, 0xf1); outb(0x2f, 0x00);

                outb(0x2e, 0xf0); outb(0x2f, 0x22);
                outb(0x2e, 0xf1); outb(0x2f, 0x00);

                outb(0x2e, 0xf0); outb(0x2f, 0x23);
                outb(0x2e, 0xf1); outb(0x2f, 0x00);
        }
        exit(0);
}


-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
[EMAIL PROTECTED]         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe    
Never attribute to malice what can adequately be explained by incompetence.
_______________________________________________
Soekris-tech mailing list
[email protected]
http://lists.soekris.com/mailman/listinfo/soekris-tech

Reply via email to