avrdude-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avrdude-dev] Serial <-> SPI interface support?


From: Ivan Shmakov
Subject: [avrdude-dev] Serial <-> SPI interface support?
Date: Mon, 03 Dec 2012 00:42:53 +0700
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux)

        It appears that there's a way to communicate to AVR MCU's, which
        is not yet covered by avrdude: a “serial port to SPI” interface.

        I wonder if it's possible to add support for such a “programmer”
        to avrdude?  A preliminary patch is MIME'd.  At the very least,
        it seems to work with the interface I have at hand.

-- 
FSF associate member #7257
Index: Makefile.am
===================================================================
--- Makefile.am (revision 1118)
+++ Makefile.am (working copy)
@@ -145,6 +145,8 @@
        serbb.h \
        serbb_posix.c \
        serbb_win32.c \
+       serspi.h \
+       serspi.c \
        ser_avrdoper.c \
        ser_posix.c \
        ser_win32.c \
Index: pgm_type.c
===================================================================
--- pgm_type.c  (revision 1118)
+++ pgm_type.c  (working copy)
@@ -42,6 +42,7 @@
 #include "pickit2.h"
 #include "ppi.h"
 #include "serbb.h"
+#include "serspi.h"
 #include "stk500.h"
 #include "stk500generic.h"
 #include "stk500v2.h"
@@ -76,6 +77,7 @@
         {"par", par_initpgm, par_desc},
         {"pickit2", pickit2_initpgm, pickit2_desc},
         {"serbb", serbb_initpgm, serbb_desc},
+        {"serspi", serspi_initpgm, serspi_desc},
         {"stk500", stk500_initpgm, stk500_desc},
         {"stk500generic", stk500generic_initpgm, stk500generic_desc},
         {"stk500v2", stk500v2_initpgm, stk500v2_desc},
/*** serspi.c --- UART to SPI converter support for avrdude  -*- C -*- */

/*** Ivan Shmakov, 2012 */

/** To the extent possible under law, the author(s) have dedicated all
 ** copyright and related and neighboring rights to this software to the
 ** public domain worldwide.  This software is distributed without any
 ** warranty.
 **
 ** You should have received a copy of the CC0 Public Domain Dedication
 ** along with this software.  If not, see
 ** <http://creativecommons.org/publicdomain/zero/1.0/>.
 */

/*** Code: */

#include "ac_cfg.h"

#include <assert.h>             /* for assert () */
#include <stdio.h>              /* for fprintf () */
#include <string.h>             /* for memcpy () */

#include "avrdude.h"
#include "avr.h"
#include "config.h"
#include "pgm.h"
#include "serspi.h"
#include "serial.h"

static void
do_nothing ()
{
  /* do nothing */
}

static int
serspi_open (PROGRAMMER *pgm, char *port)
{
  int brate
    = pgm->baudrate;
  if (brate == 0) {
    fprintf (stderr, "%s: baud rate not set; set with -b\n",
             progname);
    /* . */
    return -1;
  }

  /* FIXME: check for possible overflow */
  strcpy (pgm->port, port);
  if (serial_open (port, brate, &(pgm->fd)) == -1) {
    /* . */
    return -1;
  }

  /* flush input */
  serial_drain (&(pgm->fd), 0);

  /* . */
  return 0;
}

static void
serspi_close (PROGRAMMER *pgm)
{
  serial_close (&(pgm->fd));
  pgm->fd.ifd
    = -1;

  /* . */
}

static int
serspi_cmd (PROGRAMMER *pgm,
            unsigned char cmd[4],
            unsigned char res[4])
{
  int i;

  for (i = 0; i < 4; i++) {
    int wr
      = serial_send (&pgm->fd, cmd + i, 1);
    if (wr != 0) {
      /* . */
      return -1;
    }

    int rd
      = serial_recv (&pgm->fd, res + i, 1);
    if (rd != 0) {
      /* . */
      return -1;
    }
  }

  if (verbose >= 2) {
    fprintf (stderr,
             ("serspi_cmd ():"
              " [ %02X %02X %02X %02X ]"
              " [ %02X %02X %02X %02X ]\n"),
             cmd[0], cmd[1], cmd[2], cmd[3],
             res[0], res[1], res[2], res[3]);
  }

  /* . */
  return 0;
}

static int
serspi_cmd_x (PROGRAMMER *pgm, AVRPART *part,
              int cm, unsigned char *cmc, unsigned char *res)
{
  OPCODE *op
    = part->op[cm];

  if (op == 0) {
    /* FIXME: isn't there a avr_strop () function? */
    fprintf (stderr,
             ("%s: the %s (%d) instruction not defined"
              " for part \"%s\"\n"),
             progname,
             (cm    == AVR_OP_CHIP_ERASE    ? "chip erase"
              : cm  == AVR_OP_PGM_ENABLE    ? "programming enable"
              : "(unknown)"),
             cm,
             part->desc);
    /* . */
    return -1;
  }

  {
    unsigned char cmd[4] = { 0, 0, 0, 0 }, re1[4];
    avr_set_bits (op, cmd);
    int r
      = pgm->cmd (pgm, cmd, re1);
    if (r != 0) {
      /* . */
      return -1;
    }
    if (cmc != 0) {
      memcpy (cmc, cmd, sizeof (cmd));
    }
    if (res != 0) {
      memcpy (res, re1, sizeof (re1));
    }
  }

  /* . */
  return 0;
}

static int
serspi_program_enable (PROGRAMMER *pgm, AVRPART *part)
{
  /* only SPI parts are supported */
  assert ((part->flags & AVRPART_HAS_TPI) == 0);

  {
    unsigned char cmd[4], res[4];
    int r
      = serspi_cmd_x (pgm, part, AVR_OP_PGM_ENABLE, cmd, res);
    if (r != 0) {
      /* . */
      return -1;
    }
    if (res[2] != cmd[1]) {
      /* . */
      return -2;
    }
  }

  /* . */
  return 0;
}

static int
serspi_initialize (PROGRAMMER *pgm, AVRPART *part)
{
  /* only SPI parts are supported */
  assert ((part->flags & AVRPART_HAS_TPI) == 0);

  /* try serspi_program_enable () some 55 times */
  int i;
  for (i = 0; i < 55; i++) {
    int r
      = pgm->program_enable (pgm, part);
    if (r == 0 || r == -1) {
      /* . */
      return r;
    }
  }

  fprintf (stderr, "%s: AVR device not responding\n", progname);

  /* . */
  return -1;
}

static int
serspi_chip_erase (PROGRAMMER *pgm, AVRPART *part)
{
  /* only SPI parts are supported */
  assert ((part->flags & AVRPART_HAS_TPI) == 0);

  {
    int r
      = serspi_cmd_x (pgm, part, AVR_OP_CHIP_ERASE, 0, 0);
    if (r != 0) {
      /* . */
      return -1;
    }
  }

  /* . */
  return
    pgm->initialize (pgm, part);
}

const char serspi_desc[]
  = "Serial port to SPI converters";

void
serspi_initpgm (PROGRAMMER *p)
{
  strcpy (p->type, "serspi");

  /* mandatory functions */
  p->open           = serspi_open;
  p->close          = serspi_close;
  p->cmd            = serspi_cmd;
  p->program_enable = serspi_program_enable;
  p->initialize     = serspi_initialize;
  p->chip_erase     = serspi_chip_erase;
  p->disable        = do_nothing;
  p->display        = do_nothing;
  p->enable         = do_nothing;

  /* optional functions */
  p->read_byte      = avr_read_byte_default;
  p->write_byte     = avr_write_byte_default;

  /* . */
}

/*** serspi.c ends here */
/*** serspi.h --- UART to SPI converter support for avrdude  -*- C -*- */

/*** Ivan Shmakov, 2012 */

/** To the extent possible under law, the author(s) have dedicated all
 ** copyright and related and neighboring rights to this software to the
 ** public domain worldwide.  This software is distributed without any
 ** warranty.
 **
 ** You should have received a copy of the CC0 Public Domain Dedication
 ** along with this software.  If not, see
 ** <http://creativecommons.org/publicdomain/zero/1.0/>.
 */

/*** Code: */
#ifndef serspi_h
#define serspi_h

#include "pgm.h"                /* for PROGRAMMER */

#ifdef __cplusplus
extern "C" {
#endif

extern const char serspi_desc[];
void serspi_initpgm (PROGRAMMER *pgm);

#ifdef __cplusplus
}
#endif

#endif  /* serspi_h */
/*** serspi.h ends here */

reply via email to

[Prev in Thread] Current Thread [Next in Thread]