2001-10-15 02:46:59 +00:00
|
|
|
/*
|
2003-02-08 04:17:25 +00:00
|
|
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
2004-12-22 01:52:45 +00:00
|
|
|
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
|
2006-07-16 21:30:14 +00:00
|
|
|
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
2001-10-15 02:46:59 +00:00
|
|
|
*
|
2003-02-06 19:54:46 +00:00
|
|
|
* 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.
|
2001-10-15 02:46:59 +00:00
|
|
|
*
|
2003-02-06 19:54:46 +00:00
|
|
|
* 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.
|
2001-10-15 02:46:59 +00:00
|
|
|
*
|
2003-02-06 19:54:46 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
2012-11-20 14:03:50 +00:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2001-10-15 02:46:59 +00:00
|
|
|
*/
|
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
/* $Id$ */
|
2003-02-11 21:27:06 +00:00
|
|
|
%{
|
|
|
|
|
2003-02-14 20:34:03 +00:00
|
|
|
#include "ac_cfg.h"
|
|
|
|
|
2003-02-11 21:27:06 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
2007-01-24 21:07:54 +00:00
|
|
|
#include "avrdude.h"
|
2014-05-19 10:01:59 +00:00
|
|
|
#include "libavrdude.h"
|
2014-06-17 20:08:28 +00:00
|
|
|
#include "config.h"
|
2003-02-11 21:27:06 +00:00
|
|
|
|
2022-01-07 12:15:55 +00:00
|
|
|
#if defined(WIN32)
|
2004-06-24 11:05:07 +00:00
|
|
|
#define strtok_r( _s, _sep, _lasts ) \
|
|
|
|
( *(_lasts) = strtok( (_s), (_sep) ) )
|
|
|
|
#endif
|
|
|
|
|
2014-06-17 20:08:28 +00:00
|
|
|
#define STRINGIFY(x) #x
|
|
|
|
#define TOSTRING(x) STRINGIFY(x)
|
|
|
|
|
2003-02-11 21:27:06 +00:00
|
|
|
int yylex(void);
|
2014-06-17 20:08:28 +00:00
|
|
|
int yyerror(char * errmsg, ...);
|
|
|
|
int yywarning(char * errmsg, ...);
|
2003-02-11 21:27:06 +00:00
|
|
|
|
2005-09-18 20:12:23 +00:00
|
|
|
static int assign_pin(int pinno, TOKEN * v, int invert);
|
2012-11-13 21:34:02 +00:00
|
|
|
static int assign_pin_list(int invert);
|
2003-02-12 09:08:10 +00:00
|
|
|
static int which_opcode(TOKEN * opcode);
|
|
|
|
static int parse_cmdbits(OPCODE * op);
|
2011-12-17 15:34:47 +00:00
|
|
|
|
|
|
|
static int pin_name;
|
2003-02-11 21:27:06 +00:00
|
|
|
%}
|
2001-10-14 23:17:26 +00:00
|
|
|
|
2001-11-21 02:46:55 +00:00
|
|
|
%token K_READ
|
|
|
|
%token K_WRITE
|
|
|
|
%token K_READ_LO
|
|
|
|
%token K_READ_HI
|
|
|
|
%token K_WRITE_LO
|
|
|
|
%token K_WRITE_HI
|
|
|
|
%token K_LOADPAGE_LO
|
|
|
|
%token K_LOADPAGE_HI
|
2006-05-23 22:27:43 +00:00
|
|
|
%token K_LOAD_EXT_ADDR
|
2001-11-21 02:46:55 +00:00
|
|
|
%token K_WRITEPAGE
|
|
|
|
%token K_CHIP_ERASE
|
|
|
|
%token K_PGM_ENABLE
|
|
|
|
|
|
|
|
%token K_MEMORY
|
|
|
|
|
2001-10-16 23:32:30 +00:00
|
|
|
%token K_PAGE_SIZE
|
2001-11-21 02:46:55 +00:00
|
|
|
%token K_PAGED
|
2003-02-20 14:11:34 +00:00
|
|
|
|
Alias keyword (#868)
Implementation for an "alias" keyword.
By now, only applied inside memory descriptions.
* Make "mem_alias" a separate nonterminal.
The previous implementation attempt caused a syntax error in
yacc code, and separating mem_alias on the same level as
mem_spec appears to be the cleaner solution anyway.
* Maintain real memory aliases.
Instead of duplicating the aliased memory with a new name, maintain a
second list of memory aliases (per device) that contains a pointer to
the memory area it is aliased to. That way, a memory name can be
clearly distinguished between the canonical one and any aliases.
* Check p->mem_alias != NULL before touching it
* Add avr_find_memalias()
This takes a memory region as input, and searches whether an
alias can be found for it.
* We need to add a list structure for the mem_alias list, always.
By that means, mem_alias won't ever be NULL, so no need to check
later.
Also, in avr_dup_part(), duplicate the alias list.
* In a memory alias, actually remember the current name.
* In avr_dup_part(), adjust pointers of aliased memories
While walking the list of memories, for each entry, see if there is an
alias pointing to it. If so, allocate a duplicated one, and fix its
aliased_mem pointer to point to the duplicated memory region instead
of the original one.
* Add avr_locate_mem_noalias()
When looking whether any memory region has already been defined for
the current part while parsing the config file, only non-aliased names
must be considered. Otherwise, a newly defined alias would kick out
the memory definition it is being aliased to.
* When defining a mem_alias, drop any existing one of that name.
* Actually use avr_find_memalias() to find aliases
* Add declaration for avr_find_memalias()
* When defining a memory, also search for an existing alias
If the newly defined name has the same as an existing alias, the alias
can be removed.
Note that we do explicitly *not* remove any memory by the same name of
a later defined alias, as this might invalidate another alias'es
pointer. If someone defines that, the alias name just won't ever be
found by avr_locate_mem().
2022-02-10 19:39:19 +00:00
|
|
|
%token K_ALIAS
|
2004-01-03 18:36:44 +00:00
|
|
|
%token K_BAUDRATE
|
2003-02-20 14:11:34 +00:00
|
|
|
%token K_BS2
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_BUFF
|
|
|
|
%token K_CHIP_ERASE_DELAY
|
2012-01-30 17:08:48 +00:00
|
|
|
%token K_CONNTYPE
|
2003-02-20 14:11:34 +00:00
|
|
|
%token K_DEDICATED
|
2013-09-13 17:22:38 +00:00
|
|
|
%token K_DEFAULT_BITCLOCK
|
2003-02-21 18:46:51 +00:00
|
|
|
%token K_DEFAULT_PARALLEL
|
2003-02-21 21:07:43 +00:00
|
|
|
%token K_DEFAULT_PROGRAMMER
|
2003-02-21 18:46:51 +00:00
|
|
|
%token K_DEFAULT_SERIAL
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_DESC
|
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9507: Fix UPDI chip erase
* lexer.l (family_id): New keyword.
* config_gram.y: (Ditto)
* doc/avrdude.texi: Document new keyword
* avrdude.conf.in: Add family_id for avr8x devices
* avr.c: Pass error code up.
* jtag3.c: Pass error code from memory read up; implement
jtag3_read_sib()
* libavrdude.h: Add new items.
* main.c: Implement different chip erase handling required
for UPDI devices.
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9506: Script to create device configuration stub from Atmel ATDF files
* avrdude.conf.in (ATtiny202, ATtiny204, ATtiny402, ATtiny404)
(ATtiny406, ATtiny804, ATtiny806, ATtiny807, ATtiny1604)
(ATtiny1606, ATtiny1607, ATtiny212, ATtiny214, ATtiny412)
(ATTiny414, ATtiny416, ATtiny417, ATtiny814, ATtiny816)
(ATtiny1614, ATtiny1616, ATtiny3214, ATtiny3216, ATtiny3217)
(ATmega3208, ATmega3209, ATmega4808, ATmega4809): New devices
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1405 81a1dc3b-b13d-400b-aceb-764788c761c2
2018-01-09 23:29:31 +00:00
|
|
|
%token K_FAMILY_ID
|
2002-12-01 04:30:01 +00:00
|
|
|
%token K_DEVICECODE
|
2003-03-17 06:20:02 +00:00
|
|
|
%token K_STK500_DEVCODE
|
|
|
|
%token K_AVR910_DEVCODE
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_EEPROM
|
|
|
|
%token K_ERRLED
|
|
|
|
%token K_FLASH
|
|
|
|
%token K_ID
|
2003-02-20 14:11:34 +00:00
|
|
|
%token K_IO
|
2001-10-16 23:32:30 +00:00
|
|
|
%token K_LOADPAGE
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_MAX_WRITE_DELAY
|
2012-04-13 15:25:41 +00:00
|
|
|
%token K_MCU_BASE
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_MIN_WRITE_DELAY
|
|
|
|
%token K_MISO
|
|
|
|
%token K_MOSI
|
2001-10-16 23:32:30 +00:00
|
|
|
%token K_NUM_PAGES
|
2008-07-26 22:53:40 +00:00
|
|
|
%token K_NVM_BASE
|
2017-11-29 23:09:51 +00:00
|
|
|
%token K_OCD_BASE
|
2012-12-04 13:59:37 +00:00
|
|
|
%token K_OCDREV
|
2008-07-26 22:53:40 +00:00
|
|
|
%token K_OFFSET
|
2003-02-20 14:11:34 +00:00
|
|
|
%token K_PAGEL
|
2003-02-20 19:46:23 +00:00
|
|
|
%token K_PARALLEL
|
2011-12-29 16:51:44 +00:00
|
|
|
%token K_PARENT
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_PART
|
|
|
|
%token K_PGMLED
|
|
|
|
%token K_PROGRAMMER
|
2003-02-20 19:46:23 +00:00
|
|
|
%token K_PSEUDO
|
2002-11-30 14:09:12 +00:00
|
|
|
%token K_PWROFF_AFTER_WRITE
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_RDYLED
|
|
|
|
%token K_READBACK_P1
|
|
|
|
%token K_READBACK_P2
|
2001-10-16 23:32:30 +00:00
|
|
|
%token K_READMEM
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_RESET
|
2003-02-21 17:24:47 +00:00
|
|
|
%token K_RETRY_PULSE
|
2003-02-20 19:46:23 +00:00
|
|
|
%token K_SERIAL
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_SCK
|
2006-02-27 17:18:42 +00:00
|
|
|
%token K_SIGNATURE
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_SIZE
|
2012-01-30 17:08:48 +00:00
|
|
|
%token K_USB
|
2011-08-25 16:12:30 +00:00
|
|
|
%token K_USBDEV
|
|
|
|
%token K_USBSN
|
|
|
|
%token K_USBPID
|
|
|
|
%token K_USBPRODUCT
|
|
|
|
%token K_USBVENDOR
|
|
|
|
%token K_USBVID
|
2002-11-30 14:09:12 +00:00
|
|
|
%token K_TYPE
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_VCC
|
|
|
|
%token K_VFYLED
|
2001-10-16 23:32:30 +00:00
|
|
|
|
|
|
|
%token K_NO
|
2001-10-14 23:17:26 +00:00
|
|
|
%token K_YES
|
|
|
|
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
/* stk500 v2 xml file parameters */
|
2006-07-16 21:30:14 +00:00
|
|
|
/* ISP */
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
%token K_TIMEOUT
|
|
|
|
%token K_STABDELAY
|
|
|
|
%token K_CMDEXEDELAY
|
2006-07-21 21:53:49 +00:00
|
|
|
%token K_HVSPCMDEXEDELAY
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
%token K_SYNCHLOOPS
|
|
|
|
%token K_BYTEDELAY
|
|
|
|
%token K_POLLVALUE
|
|
|
|
%token K_POLLINDEX
|
|
|
|
%token K_PREDELAY
|
|
|
|
%token K_POSTDELAY
|
|
|
|
%token K_POLLMETHOD
|
|
|
|
%token K_MODE
|
|
|
|
%token K_DELAY
|
|
|
|
%token K_BLOCKSIZE
|
|
|
|
%token K_READSIZE
|
2006-07-21 21:53:49 +00:00
|
|
|
/* HV mode */
|
|
|
|
%token K_HVENTERSTABDELAY
|
2006-07-16 21:30:14 +00:00
|
|
|
%token K_PROGMODEDELAY
|
|
|
|
%token K_LATCHCYCLES
|
|
|
|
%token K_TOGGLEVTG
|
|
|
|
%token K_POWEROFFDELAY
|
|
|
|
%token K_RESETDELAYMS
|
|
|
|
%token K_RESETDELAYUS
|
2006-07-21 21:53:49 +00:00
|
|
|
%token K_HVLEAVESTABDELAY
|
2006-07-16 21:30:14 +00:00
|
|
|
%token K_RESETDELAY
|
2006-07-21 21:53:49 +00:00
|
|
|
%token K_SYNCHCYCLES
|
|
|
|
%token K_HVCMDEXEDELAY
|
2006-07-16 21:30:14 +00:00
|
|
|
|
2006-07-19 21:25:08 +00:00
|
|
|
%token K_CHIPERASEPULSEWIDTH
|
|
|
|
%token K_CHIPERASEPOLLTIMEOUT
|
2006-07-21 21:53:49 +00:00
|
|
|
%token K_CHIPERASETIME
|
2006-07-19 21:25:08 +00:00
|
|
|
%token K_PROGRAMFUSEPULSEWIDTH
|
|
|
|
%token K_PROGRAMFUSEPOLLTIMEOUT
|
|
|
|
%token K_PROGRAMLOCKPULSEWIDTH
|
|
|
|
%token K_PROGRAMLOCKPOLLTIMEOUT
|
|
|
|
|
2006-07-16 21:30:14 +00:00
|
|
|
%token K_PP_CONTROLSTACK
|
2006-07-21 21:53:49 +00:00
|
|
|
%token K_HVSP_CONTROLSTACK
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
|
|
|
|
/* JTAG ICE mkII specific parameters */
|
|
|
|
%token K_ALLOWFULLPAGEBITSTREAM /*
|
|
|
|
* Internal parameter for the JTAG
|
|
|
|
* ICE; describes the internal JTAG
|
|
|
|
* streaming behaviour inside the MCU.
|
|
|
|
* 1 for all older chips, 0 for newer
|
|
|
|
* MCUs.
|
|
|
|
*/
|
|
|
|
%token K_ENABLEPAGEPROGRAMMING /* ? yes for mega256*, mega406 */
|
|
|
|
%token K_HAS_JTAG /* MCU has JTAG i/f. */
|
2006-11-20 23:23:37 +00:00
|
|
|
%token K_HAS_DW /* MCU has debugWire i/f. */
|
2008-07-26 22:53:40 +00:00
|
|
|
%token K_HAS_PDI /* MCU has PDI i/f rather than ISP (ATxmega). */
|
2017-11-29 23:09:51 +00:00
|
|
|
%token K_HAS_UPDI /* MCU has UPDI i/f (AVR8X). */
|
2010-01-15 16:36:13 +00:00
|
|
|
%token K_HAS_TPI /* MCU has TPI i/f rather than ISP (ATtiny4/5/9/10). */
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
%token K_IDR /* address of OCD register in IO space */
|
2011-08-29 09:25:04 +00:00
|
|
|
%token K_IS_AT90S1200 /* chip is an AT90S1200 (needs special treatment) */
|
2009-10-10 20:09:52 +00:00
|
|
|
%token K_IS_AVR32 /* chip is in the avr32 family */
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
%token K_RAMPZ /* address of RAMPZ reg. in IO space */
|
|
|
|
%token K_SPMCR /* address of SPMC[S]R in memory space */
|
Quite some cleanup of the JTAG ICE mkII stuff.
. Implement the new EECRAddress field in the device descriptor that is
required by the 4.x firmware; make an uneducated guess about what
firmware requires what length of device descriptor -- perhaps Atmel
can be convinced to publish an official matrix for that.
. Specify EECR in the config file where required. Obviously, only
locations that differ from the 0x3c default are mentioned in the
XML files, so by now, this only affects the AT90CAN128 for us.
. After clarification with Atmel, EnablePageProgramming should really
default to 1, and only cleared if specified by an XML parameter. So
far, only the XML files for the ATmega256x and ATmega406 do specify
it at all, and they specify a 1, too.
. Drop the entire OCDEN fuse heuristic. If OCDEN is unprogrammed at
startup, issue a warning that single-byte EEPROM updates won't be
possible. Leave it to the user to program the fuse if desired.
That way, we won't run into any issue of prematurely wearing out the
hfuse EEPROM cell. Interestingly enough, this also solved the
problem of the target not restarting from scratch upon sign-off.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@461 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-11 20:06:23 +00:00
|
|
|
%token K_EECR /* address of EECR in memory space */
|
2006-11-20 23:23:37 +00:00
|
|
|
%token K_FLASH_INSTR /* flash instructions */
|
2006-11-23 07:07:06 +00:00
|
|
|
%token K_EEPROM_INSTR /* EEPROM instructions */
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
%token TKN_COMMA
|
|
|
|
%token TKN_EQUAL
|
|
|
|
%token TKN_SEMI
|
2005-09-18 20:12:23 +00:00
|
|
|
%token TKN_TILDE
|
2012-11-13 21:34:02 +00:00
|
|
|
%token TKN_LEFT_PAREN
|
|
|
|
%token TKN_RIGHT_PAREN
|
2001-10-14 23:17:26 +00:00
|
|
|
%token TKN_NUMBER
|
2012-11-04 17:18:59 +00:00
|
|
|
%token TKN_NUMBER_REAL
|
2001-10-14 23:17:26 +00:00
|
|
|
%token TKN_STRING
|
|
|
|
|
2003-03-05 01:19:17 +00:00
|
|
|
%start configuration
|
2001-10-14 23:17:26 +00:00
|
|
|
|
|
|
|
%%
|
|
|
|
|
2012-11-04 17:18:59 +00:00
|
|
|
number_real :
|
|
|
|
TKN_NUMBER {
|
|
|
|
$$ = $1;
|
|
|
|
/* convert value to real */
|
|
|
|
$$->value.number_real = $$->value.number;
|
|
|
|
$$->value.type = V_NUM_REAL;
|
|
|
|
} |
|
|
|
|
TKN_NUMBER_REAL {
|
|
|
|
$$ = $1;
|
|
|
|
}
|
|
|
|
|
2003-03-05 01:19:17 +00:00
|
|
|
configuration :
|
|
|
|
/* empty */ | config
|
|
|
|
;
|
2001-10-14 23:17:26 +00:00
|
|
|
|
|
|
|
config :
|
|
|
|
def |
|
|
|
|
config def
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
def :
|
|
|
|
prog_def TKN_SEMI |
|
2003-02-21 18:46:51 +00:00
|
|
|
|
|
|
|
part_def TKN_SEMI |
|
|
|
|
|
2003-02-21 21:07:43 +00:00
|
|
|
K_DEFAULT_PROGRAMMER TKN_EQUAL TKN_STRING TKN_SEMI {
|
|
|
|
strncpy(default_programmer, $3->value.string, MAX_STR_CONST);
|
|
|
|
default_programmer[MAX_STR_CONST-1] = 0;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2003-02-21 18:46:51 +00:00
|
|
|
K_DEFAULT_PARALLEL TKN_EQUAL TKN_STRING TKN_SEMI {
|
|
|
|
strncpy(default_parallel, $3->value.string, PATH_MAX);
|
|
|
|
default_parallel[PATH_MAX-1] = 0;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_DEFAULT_SERIAL TKN_EQUAL TKN_STRING TKN_SEMI {
|
|
|
|
strncpy(default_serial, $3->value.string, PATH_MAX);
|
|
|
|
default_serial[PATH_MAX-1] = 0;
|
|
|
|
free_token($3);
|
2011-08-26 20:30:26 +00:00
|
|
|
} |
|
|
|
|
|
2012-11-04 17:18:59 +00:00
|
|
|
K_DEFAULT_BITCLOCK TKN_EQUAL number_real TKN_SEMI {
|
|
|
|
default_bitclock = $3->value.number_real;
|
2011-08-26 20:30:26 +00:00
|
|
|
free_token($3);
|
2003-03-05 01:19:17 +00:00
|
|
|
}
|
2001-10-14 23:17:26 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
prog_def :
|
2011-12-17 15:34:47 +00:00
|
|
|
prog_decl prog_parms
|
|
|
|
{
|
2012-01-17 20:56:37 +00:00
|
|
|
PROGRAMMER * existing_prog;
|
|
|
|
char * id;
|
2001-10-14 23:17:26 +00:00
|
|
|
if (lsize(current_prog->id) == 0) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("required parameter id not specified");
|
|
|
|
YYABORT;
|
2001-10-14 23:17:26 +00:00
|
|
|
}
|
2012-01-22 12:31:54 +00:00
|
|
|
if (current_prog->initpgm == NULL) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("programmer type not specified");
|
|
|
|
YYABORT;
|
2002-11-30 14:09:12 +00:00
|
|
|
}
|
2012-01-17 20:56:37 +00:00
|
|
|
id = ldata(lfirst(current_prog->id));
|
|
|
|
existing_prog = locate_programmer(programmers, id);
|
|
|
|
if (existing_prog) {
|
2022-01-07 10:31:16 +00:00
|
|
|
{ /* temporarily set lineno to lineno of programmer start */
|
2014-06-17 20:08:28 +00:00
|
|
|
int temp = lineno; lineno = current_prog->lineno;
|
|
|
|
yywarning("programmer %s overwrites previous definition %s:%d.",
|
2012-01-17 20:56:37 +00:00
|
|
|
id, existing_prog->config_file, existing_prog->lineno);
|
2014-06-17 20:08:28 +00:00
|
|
|
lineno = temp;
|
|
|
|
}
|
2012-01-17 20:56:37 +00:00
|
|
|
lrmv_d(programmers, existing_prog);
|
|
|
|
pgm_free(existing_prog);
|
|
|
|
}
|
2022-01-09 10:51:36 +00:00
|
|
|
LISTADD(programmers, current_prog);
|
2013-05-03 22:35:00 +00:00
|
|
|
// pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed
|
|
|
|
// pgm_display_generic(current_prog, id);
|
2011-12-17 15:34:47 +00:00
|
|
|
current_prog = NULL;
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
prog_decl :
|
|
|
|
K_PROGRAMMER
|
|
|
|
{ current_prog = pgm_new();
|
2014-06-17 20:08:28 +00:00
|
|
|
if (current_prog == NULL) {
|
|
|
|
yyerror("could not create pgm instance");
|
|
|
|
YYABORT;
|
|
|
|
}
|
2011-12-17 15:34:47 +00:00
|
|
|
strcpy(current_prog->config_file, infile);
|
|
|
|
current_prog->lineno = lineno;
|
2001-10-14 23:17:26 +00:00
|
|
|
}
|
2012-01-22 12:31:54 +00:00
|
|
|
|
|
|
|
|
K_PROGRAMMER K_PARENT TKN_STRING
|
|
|
|
{
|
|
|
|
struct programmer_t * pgm = locate_programmer(programmers, $3->value.string);
|
|
|
|
if (pgm == NULL) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("parent programmer %s not found", $3->value.string);
|
|
|
|
free_token($3);
|
|
|
|
YYABORT;
|
2012-01-22 12:31:54 +00:00
|
|
|
}
|
|
|
|
current_prog = pgm_dup(pgm);
|
2014-06-17 20:08:28 +00:00
|
|
|
if (current_prog == NULL) {
|
|
|
|
yyerror("could not duplicate pgm instance");
|
|
|
|
free_token($3);
|
|
|
|
YYABORT;
|
|
|
|
}
|
2012-01-22 12:31:54 +00:00
|
|
|
strcpy(current_prog->config_file, infile);
|
|
|
|
current_prog->lineno = lineno;
|
|
|
|
free_token($3);
|
|
|
|
}
|
2001-10-14 23:17:26 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
part_def :
|
2011-12-29 16:51:44 +00:00
|
|
|
part_decl part_parms
|
2001-10-14 23:17:26 +00:00
|
|
|
{
|
2001-11-21 02:46:55 +00:00
|
|
|
LNODEID ln;
|
|
|
|
AVRMEM * m;
|
2012-01-17 20:56:37 +00:00
|
|
|
AVRPART * existing_part;
|
2001-10-16 23:32:30 +00:00
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
if (current_part->id[0] == 0) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("required parameter id not specified");
|
|
|
|
YYABORT;
|
2001-10-14 23:17:26 +00:00
|
|
|
}
|
2001-10-16 02:47:55 +00:00
|
|
|
|
|
|
|
/*
|
2001-10-16 23:34:07 +00:00
|
|
|
* perform some sanity checking, and compute the number of bits
|
|
|
|
* to shift a page for constructing the page address for
|
|
|
|
* page-addressed memories.
|
2001-10-16 02:47:55 +00:00
|
|
|
*/
|
2001-11-21 02:46:55 +00:00
|
|
|
for (ln=lfirst(current_part->mem); ln; ln=lnext(ln)) {
|
|
|
|
m = ldata(ln);
|
|
|
|
if (m->paged) {
|
|
|
|
if (m->page_size == 0) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("must specify page_size for paged memory");
|
|
|
|
YYABORT;
|
2001-10-16 02:47:55 +00:00
|
|
|
}
|
2001-11-21 02:46:55 +00:00
|
|
|
if (m->num_pages == 0) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("must specify num_pages for paged memory");
|
|
|
|
YYABORT;
|
2001-10-16 02:47:55 +00:00
|
|
|
}
|
2001-11-21 02:46:55 +00:00
|
|
|
if (m->size != m->page_size * m->num_pages) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("page size (%u) * num_pages (%u) = "
|
|
|
|
"%u does not match memory size (%u)",
|
|
|
|
m->page_size,
|
|
|
|
m->num_pages,
|
2001-11-21 02:46:55 +00:00
|
|
|
m->page_size * m->num_pages,
|
|
|
|
m->size);
|
2014-06-17 20:08:28 +00:00
|
|
|
YYABORT;
|
2001-10-16 02:47:55 +00:00
|
|
|
}
|
2001-11-21 02:46:55 +00:00
|
|
|
|
2001-10-16 02:47:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-17 20:56:37 +00:00
|
|
|
existing_part = locate_part(part_list, current_part->id);
|
|
|
|
if (existing_part) {
|
2022-01-07 10:31:16 +00:00
|
|
|
{ /* temporarily set lineno to lineno of part start */
|
2014-06-17 20:08:28 +00:00
|
|
|
int temp = lineno; lineno = current_part->lineno;
|
|
|
|
yywarning("part %s overwrites previous definition %s:%d.",
|
|
|
|
current_part->id,
|
2012-01-17 20:56:37 +00:00
|
|
|
existing_part->config_file, existing_part->lineno);
|
2014-06-17 20:08:28 +00:00
|
|
|
lineno = temp;
|
|
|
|
}
|
2012-01-17 20:56:37 +00:00
|
|
|
lrmv_d(part_list, existing_part);
|
|
|
|
avr_free_part(existing_part);
|
|
|
|
}
|
2022-01-09 10:51:36 +00:00
|
|
|
LISTADD(part_list, current_part);
|
2001-10-14 23:17:26 +00:00
|
|
|
current_part = NULL;
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
2011-12-29 16:51:44 +00:00
|
|
|
part_decl :
|
|
|
|
K_PART
|
|
|
|
{
|
|
|
|
current_part = avr_new_part();
|
2014-06-17 20:08:28 +00:00
|
|
|
if (current_part == NULL) {
|
|
|
|
yyerror("could not create part instance");
|
|
|
|
YYABORT;
|
|
|
|
}
|
2011-12-29 16:51:44 +00:00
|
|
|
strcpy(current_part->config_file, infile);
|
|
|
|
current_part->lineno = lineno;
|
|
|
|
} |
|
|
|
|
K_PART K_PARENT TKN_STRING
|
|
|
|
{
|
|
|
|
AVRPART * parent_part = locate_part(part_list, $3->value.string);
|
|
|
|
if (parent_part == NULL) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("can't find parent part");
|
|
|
|
free_token($3);
|
|
|
|
YYABORT;
|
2011-12-29 16:51:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
current_part = avr_dup_part(parent_part);
|
2014-06-17 20:08:28 +00:00
|
|
|
if (current_part == NULL) {
|
|
|
|
yyerror("could not duplicate part instance");
|
|
|
|
free_token($3);
|
|
|
|
YYABORT;
|
|
|
|
}
|
2011-12-29 16:51:44 +00:00
|
|
|
strcpy(current_part->config_file, infile);
|
|
|
|
current_part->lineno = lineno;
|
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
}
|
|
|
|
;
|
2001-10-14 23:17:26 +00:00
|
|
|
|
|
|
|
string_list :
|
|
|
|
TKN_STRING { ladd(string_list, $1); } |
|
|
|
|
string_list TKN_COMMA TKN_STRING { ladd(string_list, $3); }
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
num_list :
|
|
|
|
TKN_NUMBER { ladd(number_list, $1); } |
|
|
|
|
num_list TKN_COMMA TKN_NUMBER { ladd(number_list, $3); }
|
|
|
|
;
|
|
|
|
|
|
|
|
prog_parms :
|
|
|
|
prog_parm TKN_SEMI |
|
|
|
|
prog_parms prog_parm TKN_SEMI
|
|
|
|
;
|
|
|
|
|
|
|
|
prog_parm :
|
|
|
|
K_ID TKN_EQUAL string_list {
|
2011-12-17 15:34:47 +00:00
|
|
|
{
|
2001-10-14 23:17:26 +00:00
|
|
|
TOKEN * t;
|
2014-06-17 20:08:28 +00:00
|
|
|
char *s;
|
|
|
|
int do_yyabort = 0;
|
2001-10-14 23:17:26 +00:00
|
|
|
while (lsize(string_list)) {
|
|
|
|
t = lrmv_n(string_list, 1);
|
2014-06-17 20:08:28 +00:00
|
|
|
if (!do_yyabort) {
|
|
|
|
s = dup_string(t->value.string);
|
|
|
|
if (s == NULL) {
|
|
|
|
do_yyabort = 1;
|
|
|
|
} else {
|
|
|
|
ladd(current_prog->id, s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* if do_yyabort == 1 just make the list empty */
|
2001-10-14 23:17:26 +00:00
|
|
|
free_token(t);
|
|
|
|
}
|
2014-06-17 20:08:28 +00:00
|
|
|
if (do_yyabort) {
|
|
|
|
YYABORT;
|
|
|
|
}
|
2001-10-14 23:17:26 +00:00
|
|
|
}
|
|
|
|
} |
|
2011-12-17 15:34:47 +00:00
|
|
|
prog_parm_type
|
|
|
|
|
|
|
|
|
prog_parm_pins
|
|
|
|
|
|
|
|
|
prog_parm_usb
|
|
|
|
|
|
2012-01-30 17:08:48 +00:00
|
|
|
prog_parm_conntype
|
|
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
K_DESC TKN_EQUAL TKN_STRING {
|
|
|
|
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
|
|
|
|
current_prog->desc[PGM_DESCLEN-1] = 0;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
2011-12-17 15:34:47 +00:00
|
|
|
K_BAUDRATE TKN_EQUAL TKN_NUMBER {
|
|
|
|
{
|
|
|
|
current_prog->baudrate = $3->value.number;
|
|
|
|
free_token($3);
|
2001-10-14 23:17:26 +00:00
|
|
|
}
|
2011-12-17 15:34:47 +00:00
|
|
|
}
|
|
|
|
;
|
2001-12-29 21:37:20 +00:00
|
|
|
|
2011-12-17 15:34:47 +00:00
|
|
|
prog_parm_type:
|
|
|
|
K_TYPE TKN_EQUAL prog_parm_type_id
|
|
|
|
;
|
2001-12-29 21:37:20 +00:00
|
|
|
|
2011-12-17 15:34:47 +00:00
|
|
|
prog_parm_type_id:
|
2012-01-31 17:03:43 +00:00
|
|
|
TKN_STRING {
|
|
|
|
const struct programmer_type_t * pgm_type = locate_programmer_type($1->value.string);
|
|
|
|
if (pgm_type == NULL) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("programmer type %s not found", $1->value.string);
|
|
|
|
free_token($1);
|
|
|
|
YYABORT;
|
2012-01-31 17:03:43 +00:00
|
|
|
}
|
|
|
|
current_prog->initpgm = pgm_type->initpgm;
|
|
|
|
free_token($1);
|
|
|
|
}
|
|
|
|
| error
|
|
|
|
{
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("programmer type must be written as \"id_type\"");
|
|
|
|
YYABORT;
|
2012-01-31 17:03:43 +00:00
|
|
|
}
|
2011-12-17 15:34:47 +00:00
|
|
|
;
|
2001-12-29 21:37:20 +00:00
|
|
|
|
2012-01-30 17:08:48 +00:00
|
|
|
prog_parm_conntype:
|
|
|
|
K_CONNTYPE TKN_EQUAL prog_parm_conntype_id
|
|
|
|
;
|
|
|
|
|
|
|
|
prog_parm_conntype_id:
|
|
|
|
K_PARALLEL { current_prog->conntype = CONNTYPE_PARALLEL; } |
|
|
|
|
K_SERIAL { current_prog->conntype = CONNTYPE_SERIAL; } |
|
|
|
|
K_USB { current_prog->conntype = CONNTYPE_USB; }
|
|
|
|
;
|
|
|
|
|
2011-12-17 15:34:47 +00:00
|
|
|
prog_parm_usb:
|
2011-08-25 16:12:30 +00:00
|
|
|
K_USBDEV TKN_EQUAL TKN_STRING {
|
|
|
|
{
|
|
|
|
strncpy(current_prog->usbdev, $3->value.string, PGM_USBSTRINGLEN);
|
|
|
|
current_prog->usbdev[PGM_USBSTRINGLEN-1] = 0;
|
|
|
|
free_token($3);
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
K_USBVID TKN_EQUAL TKN_NUMBER {
|
|
|
|
{
|
|
|
|
current_prog->usbvid = $3->value.number;
|
2011-12-17 13:45:54 +00:00
|
|
|
free_token($3);
|
2011-08-25 16:12:30 +00:00
|
|
|
}
|
|
|
|
} |
|
2014-02-27 13:06:03 +00:00
|
|
|
K_USBPID TKN_EQUAL usb_pid_list |
|
2011-08-25 16:12:30 +00:00
|
|
|
K_USBSN TKN_EQUAL TKN_STRING {
|
|
|
|
{
|
|
|
|
strncpy(current_prog->usbsn, $3->value.string, PGM_USBSTRINGLEN);
|
|
|
|
current_prog->usbsn[PGM_USBSTRINGLEN-1] = 0;
|
|
|
|
free_token($3);
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
K_USBVENDOR TKN_EQUAL TKN_STRING {
|
|
|
|
{
|
|
|
|
strncpy(current_prog->usbvendor, $3->value.string, PGM_USBSTRINGLEN);
|
|
|
|
current_prog->usbvendor[PGM_USBSTRINGLEN-1] = 0;
|
|
|
|
free_token($3);
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
K_USBPRODUCT TKN_EQUAL TKN_STRING {
|
|
|
|
{
|
|
|
|
strncpy(current_prog->usbproduct, $3->value.string, PGM_USBSTRINGLEN);
|
|
|
|
current_prog->usbproduct[PGM_USBSTRINGLEN-1] = 0;
|
|
|
|
free_token($3);
|
|
|
|
}
|
2011-12-17 15:34:47 +00:00
|
|
|
}
|
|
|
|
;
|
|
|
|
|
2014-02-27 13:06:03 +00:00
|
|
|
usb_pid_list:
|
|
|
|
TKN_NUMBER {
|
2014-07-16 20:02:01 +00:00
|
|
|
{
|
|
|
|
/* overwrite pids, so clear the existing entries */
|
|
|
|
ldestroy_cb(current_prog->usbpid, free);
|
|
|
|
current_prog->usbpid = lcreat(NULL, 0);
|
|
|
|
}
|
2014-02-27 13:06:03 +00:00
|
|
|
{
|
|
|
|
int *ip = malloc(sizeof(int));
|
|
|
|
if (ip) {
|
|
|
|
*ip = $1->value.number;
|
|
|
|
ladd(current_prog->usbpid, ip);
|
|
|
|
}
|
|
|
|
free_token($1);
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
usb_pid_list TKN_COMMA TKN_NUMBER {
|
|
|
|
{
|
|
|
|
int *ip = malloc(sizeof(int));
|
|
|
|
if (ip) {
|
|
|
|
*ip = $3->value.number;
|
|
|
|
ladd(current_prog->usbpid, ip);
|
|
|
|
}
|
|
|
|
free_token($3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
2013-05-03 22:35:00 +00:00
|
|
|
pin_number_non_empty:
|
2014-06-17 20:08:28 +00:00
|
|
|
TKN_NUMBER { if(0 != assign_pin(pin_name, $1, 0)) YYABORT; }
|
2011-12-17 15:34:47 +00:00
|
|
|
|
|
2014-06-17 20:08:28 +00:00
|
|
|
TKN_TILDE TKN_NUMBER { if(0 != assign_pin(pin_name, $2, 1)) YYABORT; }
|
2011-12-17 15:34:47 +00:00
|
|
|
;
|
|
|
|
|
2013-05-03 22:35:00 +00:00
|
|
|
pin_number:
|
|
|
|
pin_number_non_empty
|
2012-11-13 21:34:02 +00:00
|
|
|
|
|
2013-05-03 22:35:00 +00:00
|
|
|
/* empty */ { pin_clear_all(&(current_prog->pin[pin_name])); }
|
|
|
|
;
|
|
|
|
|
|
|
|
pin_list_element:
|
|
|
|
pin_number_non_empty
|
2012-11-13 21:34:02 +00:00
|
|
|
|
|
2014-06-17 20:08:28 +00:00
|
|
|
TKN_TILDE TKN_LEFT_PAREN num_list TKN_RIGHT_PAREN { if(0 != assign_pin_list(1)) YYABORT; }
|
2013-05-03 22:35:00 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
pin_list_non_empty:
|
|
|
|
pin_list_element
|
2012-01-22 12:31:54 +00:00
|
|
|
|
|
2013-05-03 22:35:00 +00:00
|
|
|
pin_list_non_empty TKN_COMMA pin_list_element
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
pin_list:
|
|
|
|
pin_list_non_empty
|
|
|
|
|
|
|
|
|
/* empty */ { pin_clear_all(&(current_prog->pin[pin_name])); }
|
2001-10-14 23:17:26 +00:00
|
|
|
;
|
|
|
|
|
2011-12-17 15:34:47 +00:00
|
|
|
prog_parm_pins:
|
|
|
|
K_VCC TKN_EQUAL {pin_name = PPI_AVR_VCC; } pin_list |
|
|
|
|
K_BUFF TKN_EQUAL {pin_name = PPI_AVR_BUFF; } pin_list |
|
|
|
|
K_RESET TKN_EQUAL {pin_name = PIN_AVR_RESET;} pin_number { free_token($1); } |
|
|
|
|
K_SCK TKN_EQUAL {pin_name = PIN_AVR_SCK; } pin_number { free_token($1); } |
|
|
|
|
K_MOSI TKN_EQUAL {pin_name = PIN_AVR_MOSI; } pin_number |
|
|
|
|
K_MISO TKN_EQUAL {pin_name = PIN_AVR_MISO; } pin_number |
|
|
|
|
K_ERRLED TKN_EQUAL {pin_name = PIN_LED_ERR; } pin_number |
|
|
|
|
K_RDYLED TKN_EQUAL {pin_name = PIN_LED_RDY; } pin_number |
|
|
|
|
K_PGMLED TKN_EQUAL {pin_name = PIN_LED_PGM; } pin_number |
|
|
|
|
K_VFYLED TKN_EQUAL {pin_name = PIN_LED_VFY; } pin_number
|
|
|
|
;
|
2001-10-14 23:17:26 +00:00
|
|
|
|
2001-11-21 02:46:55 +00:00
|
|
|
opcode :
|
|
|
|
K_READ |
|
|
|
|
K_WRITE |
|
|
|
|
K_READ_LO |
|
|
|
|
K_READ_HI |
|
|
|
|
K_WRITE_LO |
|
|
|
|
K_WRITE_HI |
|
|
|
|
K_LOADPAGE_LO |
|
|
|
|
K_LOADPAGE_HI |
|
2006-05-23 22:27:43 +00:00
|
|
|
K_LOAD_EXT_ADDR |
|
2001-11-21 02:46:55 +00:00
|
|
|
K_WRITEPAGE |
|
|
|
|
K_CHIP_ERASE |
|
|
|
|
K_PGM_ENABLE
|
|
|
|
;
|
|
|
|
|
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
part_parms :
|
|
|
|
part_parm TKN_SEMI |
|
|
|
|
part_parms part_parm TKN_SEMI
|
|
|
|
;
|
|
|
|
|
|
|
|
|
2003-02-20 14:11:34 +00:00
|
|
|
reset_disposition :
|
|
|
|
K_DEDICATED | K_IO
|
|
|
|
;
|
|
|
|
|
2003-02-20 19:46:23 +00:00
|
|
|
parallel_modes :
|
|
|
|
yesno | K_PSEUDO
|
|
|
|
;
|
|
|
|
|
2003-02-21 17:24:47 +00:00
|
|
|
retry_lines :
|
|
|
|
K_RESET | K_SCK
|
|
|
|
;
|
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
part_parm :
|
|
|
|
K_ID TKN_EQUAL TKN_STRING
|
|
|
|
{
|
|
|
|
strncpy(current_part->id, $3->value.string, AVR_IDLEN);
|
|
|
|
current_part->id[AVR_IDLEN-1] = 0;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_DESC TKN_EQUAL TKN_STRING
|
|
|
|
{
|
2020-09-10 21:43:23 +00:00
|
|
|
strncpy(current_part->desc, $3->value.string, AVR_DESCLEN - 1);
|
2001-10-14 23:17:26 +00:00
|
|
|
current_part->desc[AVR_DESCLEN-1] = 0;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9507: Fix UPDI chip erase
* lexer.l (family_id): New keyword.
* config_gram.y: (Ditto)
* doc/avrdude.texi: Document new keyword
* avrdude.conf.in: Add family_id for avr8x devices
* avr.c: Pass error code up.
* jtag3.c: Pass error code from memory read up; implement
jtag3_read_sib()
* libavrdude.h: Add new items.
* main.c: Implement different chip erase handling required
for UPDI devices.
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
patch #9506: Script to create device configuration stub from Atmel ATDF files
* avrdude.conf.in (ATtiny202, ATtiny204, ATtiny402, ATtiny404)
(ATtiny406, ATtiny804, ATtiny806, ATtiny807, ATtiny1604)
(ATtiny1606, ATtiny1607, ATtiny212, ATtiny214, ATtiny412)
(ATTiny414, ATtiny416, ATtiny417, ATtiny814, ATtiny816)
(ATtiny1614, ATtiny1616, ATtiny3214, ATtiny3216, ATtiny3217)
(ATmega3208, ATmega3209, ATmega4808, ATmega4809): New devices
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1405 81a1dc3b-b13d-400b-aceb-764788c761c2
2018-01-09 23:29:31 +00:00
|
|
|
K_FAMILY_ID TKN_EQUAL TKN_STRING
|
|
|
|
{
|
|
|
|
strncpy(current_part->family_id, $3->value.string, AVR_FAMILYIDLEN);
|
|
|
|
current_part->family_id[AVR_FAMILYIDLEN] = 0;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2002-12-01 04:30:01 +00:00
|
|
|
K_DEVICECODE TKN_EQUAL TKN_NUMBER {
|
|
|
|
{
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("devicecode is deprecated, use "
|
|
|
|
"stk500_devcode instead");
|
|
|
|
YYABORT;
|
2003-03-17 06:20:02 +00:00
|
|
|
}
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_STK500_DEVCODE TKN_EQUAL TKN_NUMBER {
|
|
|
|
{
|
|
|
|
current_part->stk500_devcode = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_AVR910_DEVCODE TKN_EQUAL TKN_NUMBER {
|
|
|
|
{
|
|
|
|
current_part->avr910_devcode = $3->value.number;
|
2002-12-01 04:30:01 +00:00
|
|
|
free_token($3);
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
|
2006-02-27 17:18:42 +00:00
|
|
|
K_SIGNATURE TKN_EQUAL TKN_NUMBER TKN_NUMBER TKN_NUMBER {
|
|
|
|
{
|
|
|
|
current_part->signature[0] = $3->value.number;
|
|
|
|
current_part->signature[1] = $4->value.number;
|
|
|
|
current_part->signature[2] = $5->value.number;
|
|
|
|
free_token($3);
|
|
|
|
free_token($4);
|
|
|
|
free_token($5);
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
|
2014-01-15 13:34:49 +00:00
|
|
|
K_USBPID TKN_EQUAL TKN_NUMBER {
|
|
|
|
{
|
|
|
|
current_part->usbpid = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
|
2006-07-16 21:30:14 +00:00
|
|
|
K_PP_CONTROLSTACK TKN_EQUAL num_list {
|
|
|
|
{
|
|
|
|
TOKEN * t;
|
|
|
|
unsigned nbytes;
|
|
|
|
int ok;
|
|
|
|
|
|
|
|
current_part->ctl_stack_type = CTL_STACK_PP;
|
|
|
|
nbytes = 0;
|
|
|
|
ok = 1;
|
|
|
|
|
2011-12-29 16:51:44 +00:00
|
|
|
memset(current_part->controlstack, 0, CTL_STACK_SIZE);
|
2006-07-16 21:30:14 +00:00
|
|
|
while (lsize(number_list)) {
|
|
|
|
t = lrmv_n(number_list, 1);
|
|
|
|
if (nbytes < CTL_STACK_SIZE)
|
|
|
|
{
|
|
|
|
current_part->controlstack[nbytes] = t->value.number;
|
|
|
|
nbytes++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ok = 0;
|
|
|
|
}
|
|
|
|
free_token(t);
|
|
|
|
}
|
|
|
|
if (!ok)
|
|
|
|
{
|
2014-06-17 20:08:28 +00:00
|
|
|
yywarning("too many bytes in control stack");
|
2006-07-16 21:30:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
|
2006-07-21 21:53:49 +00:00
|
|
|
K_HVSP_CONTROLSTACK TKN_EQUAL num_list {
|
|
|
|
{
|
|
|
|
TOKEN * t;
|
|
|
|
unsigned nbytes;
|
|
|
|
int ok;
|
|
|
|
|
|
|
|
current_part->ctl_stack_type = CTL_STACK_HVSP;
|
|
|
|
nbytes = 0;
|
|
|
|
ok = 1;
|
|
|
|
|
2011-12-29 16:51:44 +00:00
|
|
|
memset(current_part->controlstack, 0, CTL_STACK_SIZE);
|
2006-07-21 21:53:49 +00:00
|
|
|
while (lsize(number_list)) {
|
|
|
|
t = lrmv_n(number_list, 1);
|
|
|
|
if (nbytes < CTL_STACK_SIZE)
|
|
|
|
{
|
|
|
|
current_part->controlstack[nbytes] = t->value.number;
|
|
|
|
nbytes++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ok = 0;
|
|
|
|
}
|
|
|
|
free_token(t);
|
|
|
|
}
|
|
|
|
if (!ok)
|
|
|
|
{
|
2014-06-17 20:08:28 +00:00
|
|
|
yywarning("too many bytes in control stack");
|
2006-07-21 21:53:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
K_FLASH_INSTR TKN_EQUAL num_list {
|
|
|
|
{
|
|
|
|
TOKEN * t;
|
|
|
|
unsigned nbytes;
|
|
|
|
int ok;
|
|
|
|
|
|
|
|
nbytes = 0;
|
|
|
|
ok = 1;
|
|
|
|
|
2011-12-29 16:51:44 +00:00
|
|
|
memset(current_part->flash_instr, 0, FLASH_INSTR_SIZE);
|
2006-11-20 23:23:37 +00:00
|
|
|
while (lsize(number_list)) {
|
|
|
|
t = lrmv_n(number_list, 1);
|
|
|
|
if (nbytes < FLASH_INSTR_SIZE)
|
|
|
|
{
|
|
|
|
current_part->flash_instr[nbytes] = t->value.number;
|
|
|
|
nbytes++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ok = 0;
|
|
|
|
}
|
|
|
|
free_token(t);
|
|
|
|
}
|
|
|
|
if (!ok)
|
|
|
|
{
|
2014-06-17 20:08:28 +00:00
|
|
|
yywarning("too many bytes in flash instructions");
|
2006-11-20 23:23:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
|
2006-11-23 07:07:06 +00:00
|
|
|
K_EEPROM_INSTR TKN_EQUAL num_list {
|
|
|
|
{
|
|
|
|
TOKEN * t;
|
|
|
|
unsigned nbytes;
|
|
|
|
int ok;
|
|
|
|
|
|
|
|
nbytes = 0;
|
|
|
|
ok = 1;
|
|
|
|
|
2011-12-29 16:51:44 +00:00
|
|
|
memset(current_part->eeprom_instr, 0, EEPROM_INSTR_SIZE);
|
2006-11-23 07:07:06 +00:00
|
|
|
while (lsize(number_list)) {
|
|
|
|
t = lrmv_n(number_list, 1);
|
|
|
|
if (nbytes < EEPROM_INSTR_SIZE)
|
|
|
|
{
|
|
|
|
current_part->eeprom_instr[nbytes] = t->value.number;
|
|
|
|
nbytes++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ok = 0;
|
|
|
|
}
|
|
|
|
free_token(t);
|
|
|
|
}
|
|
|
|
if (!ok)
|
|
|
|
{
|
2014-06-17 20:08:28 +00:00
|
|
|
yywarning("too many bytes in EEPROM instructions");
|
2006-11-23 07:07:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} |
|
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
K_CHIP_ERASE_DELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->chip_erase_delay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2003-02-20 14:11:34 +00:00
|
|
|
K_PAGEL TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->pagel = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_BS2 TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->bs2 = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_RESET TKN_EQUAL reset_disposition
|
|
|
|
{
|
|
|
|
if ($3->primary == K_DEDICATED)
|
|
|
|
current_part->reset_disposition = RESET_DEDICATED;
|
|
|
|
else if ($3->primary == K_IO)
|
|
|
|
current_part->reset_disposition = RESET_IO;
|
|
|
|
|
2003-02-21 17:24:47 +00:00
|
|
|
free_tokens(2, $1, $3);
|
2003-02-20 14:11:34 +00:00
|
|
|
} |
|
|
|
|
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
K_TIMEOUT TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->timeout = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_STABDELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->stabdelay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_CMDEXEDELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->cmdexedelay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2006-07-21 21:53:49 +00:00
|
|
|
K_HVSPCMDEXEDELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->hvspcmdexedelay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
K_SYNCHLOOPS TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->synchloops = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_BYTEDELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->bytedelay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_POLLVALUE TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->pollvalue = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_POLLINDEX TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->pollindex = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_PREDELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->predelay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_POSTDELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->postdelay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_POLLMETHOD TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->pollmethod = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2006-07-21 21:53:49 +00:00
|
|
|
K_HVENTERSTABDELAY TKN_EQUAL TKN_NUMBER
|
2006-07-16 21:30:14 +00:00
|
|
|
{
|
2006-07-21 21:53:49 +00:00
|
|
|
current_part->hventerstabdelay = $3->value.number;
|
2006-07-16 21:30:14 +00:00
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_PROGMODEDELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->progmodedelay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_LATCHCYCLES TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->latchcycles = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_TOGGLEVTG TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->togglevtg = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_POWEROFFDELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->poweroffdelay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_RESETDELAYMS TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->resetdelayms = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_RESETDELAYUS TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->resetdelayus = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2006-07-21 21:53:49 +00:00
|
|
|
K_HVLEAVESTABDELAY TKN_EQUAL TKN_NUMBER
|
2006-07-16 21:30:14 +00:00
|
|
|
{
|
2006-07-21 21:53:49 +00:00
|
|
|
current_part->hvleavestabdelay = $3->value.number;
|
2006-07-16 21:30:14 +00:00
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_RESETDELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->resetdelay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2006-07-19 21:25:08 +00:00
|
|
|
K_CHIPERASEPULSEWIDTH TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->chiperasepulsewidth = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_CHIPERASEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->chiperasepolltimeout = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2006-07-21 21:53:49 +00:00
|
|
|
K_CHIPERASETIME TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->chiperasetime = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2006-07-19 21:25:08 +00:00
|
|
|
K_PROGRAMFUSEPULSEWIDTH TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->programfusepulsewidth = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_PROGRAMFUSEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->programfusepolltimeout = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_PROGRAMLOCKPULSEWIDTH TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->programlockpulsewidth = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_PROGRAMLOCKPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->programlockpolltimeout = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2006-07-21 21:53:49 +00:00
|
|
|
K_SYNCHCYCLES TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->synchcycles = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
K_HAS_JTAG TKN_EQUAL yesno
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES)
|
|
|
|
current_part->flags |= AVRPART_HAS_JTAG;
|
|
|
|
else if ($3->primary == K_NO)
|
|
|
|
current_part->flags &= ~AVRPART_HAS_JTAG;
|
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
K_HAS_DW TKN_EQUAL yesno
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES)
|
|
|
|
current_part->flags |= AVRPART_HAS_DW;
|
|
|
|
else if ($3->primary == K_NO)
|
|
|
|
current_part->flags &= ~AVRPART_HAS_DW;
|
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2008-07-26 22:53:40 +00:00
|
|
|
K_HAS_PDI TKN_EQUAL yesno
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES)
|
|
|
|
current_part->flags |= AVRPART_HAS_PDI;
|
|
|
|
else if ($3->primary == K_NO)
|
|
|
|
current_part->flags &= ~AVRPART_HAS_PDI;
|
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2017-11-29 23:09:51 +00:00
|
|
|
K_HAS_UPDI TKN_EQUAL yesno
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES)
|
|
|
|
current_part->flags |= AVRPART_HAS_UPDI;
|
|
|
|
else if ($3->primary == K_NO)
|
|
|
|
current_part->flags &= ~AVRPART_HAS_UPDI;
|
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2010-01-15 16:36:13 +00:00
|
|
|
K_HAS_TPI TKN_EQUAL yesno
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES)
|
|
|
|
current_part->flags |= AVRPART_HAS_TPI;
|
|
|
|
else if ($3->primary == K_NO)
|
|
|
|
current_part->flags &= ~AVRPART_HAS_TPI;
|
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2011-08-29 09:25:04 +00:00
|
|
|
K_IS_AT90S1200 TKN_EQUAL yesno
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES)
|
|
|
|
current_part->flags |= AVRPART_IS_AT90S1200;
|
|
|
|
else if ($3->primary == K_NO)
|
2011-12-30 23:03:42 +00:00
|
|
|
current_part->flags &= ~AVRPART_IS_AT90S1200;
|
2011-08-29 09:25:04 +00:00
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2009-10-10 20:09:52 +00:00
|
|
|
K_IS_AVR32 TKN_EQUAL yesno
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES)
|
|
|
|
current_part->flags |= AVRPART_AVR32;
|
|
|
|
else if ($3->primary == K_NO)
|
2011-12-30 23:03:42 +00:00
|
|
|
current_part->flags &= ~AVRPART_AVR32;
|
2009-10-10 20:09:52 +00:00
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
2011-08-29 09:25:04 +00:00
|
|
|
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL yesno
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES)
|
|
|
|
current_part->flags |= AVRPART_ALLOWFULLPAGEBITSTREAM;
|
|
|
|
else if ($3->primary == K_NO)
|
|
|
|
current_part->flags &= ~AVRPART_ALLOWFULLPAGEBITSTREAM;
|
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_ENABLEPAGEPROGRAMMING TKN_EQUAL yesno
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES)
|
|
|
|
current_part->flags |= AVRPART_ENABLEPAGEPROGRAMMING;
|
|
|
|
else if ($3->primary == K_NO)
|
|
|
|
current_part->flags &= ~AVRPART_ENABLEPAGEPROGRAMMING;
|
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_IDR TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->idr = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_RAMPZ TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->rampz = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_SPMCR TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->spmcr = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
Quite some cleanup of the JTAG ICE mkII stuff.
. Implement the new EECRAddress field in the device descriptor that is
required by the 4.x firmware; make an uneducated guess about what
firmware requires what length of device descriptor -- perhaps Atmel
can be convinced to publish an official matrix for that.
. Specify EECR in the config file where required. Obviously, only
locations that differ from the 0x3c default are mentioned in the
XML files, so by now, this only affects the AT90CAN128 for us.
. After clarification with Atmel, EnablePageProgramming should really
default to 1, and only cleared if specified by an XML parameter. So
far, only the XML files for the ATmega256x and ATmega406 do specify
it at all, and they specify a 1, too.
. Drop the entire OCDEN fuse heuristic. If OCDEN is unprogrammed at
startup, issue a warning that single-byte EEPROM updates won't be
possible. Leave it to the user to program the fuse if desired.
That way, we won't run into any issue of prematurely wearing out the
hfuse EEPROM cell. Interestingly enough, this also solved the
problem of the target not restarting from scratch upon sign-off.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@461 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-11 20:06:23 +00:00
|
|
|
K_EECR TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->eecr = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2012-04-13 15:25:41 +00:00
|
|
|
K_MCU_BASE TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->mcu_base = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2008-07-26 22:53:40 +00:00
|
|
|
K_NVM_BASE TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->nvm_base = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2017-11-29 23:09:51 +00:00
|
|
|
K_OCD_BASE TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->ocd_base = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2012-12-04 13:59:37 +00:00
|
|
|
K_OCDREV TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_part->ocdrev = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2003-02-20 19:46:23 +00:00
|
|
|
K_SERIAL TKN_EQUAL yesno
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES)
|
|
|
|
current_part->flags |= AVRPART_SERIALOK;
|
|
|
|
else if ($3->primary == K_NO)
|
|
|
|
current_part->flags &= ~AVRPART_SERIALOK;
|
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_PARALLEL TKN_EQUAL parallel_modes
|
|
|
|
{
|
|
|
|
if ($3->primary == K_YES) {
|
|
|
|
current_part->flags |= AVRPART_PARALLELOK;
|
|
|
|
current_part->flags &= ~AVRPART_PSEUDOPARALLEL;
|
|
|
|
}
|
|
|
|
else if ($3->primary == K_NO) {
|
|
|
|
current_part->flags &= ~AVRPART_PARALLELOK;
|
|
|
|
current_part->flags &= ~AVRPART_PSEUDOPARALLEL;
|
|
|
|
}
|
|
|
|
else if ($3->primary == K_PSEUDO) {
|
|
|
|
current_part->flags |= AVRPART_PARALLELOK;
|
|
|
|
current_part->flags |= AVRPART_PSEUDOPARALLEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2003-02-21 17:24:47 +00:00
|
|
|
K_RETRY_PULSE TKN_EQUAL retry_lines
|
|
|
|
{
|
|
|
|
switch ($3->primary) {
|
|
|
|
case K_RESET :
|
|
|
|
current_part->retry_pulse = PIN_AVR_RESET;
|
|
|
|
break;
|
|
|
|
case K_SCK :
|
|
|
|
current_part->retry_pulse = PIN_AVR_SCK;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
free_token($1);
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
2001-11-21 02:46:55 +00:00
|
|
|
/*
|
2001-10-14 23:17:26 +00:00
|
|
|
K_EEPROM { current_mem = AVR_M_EEPROM; }
|
|
|
|
mem_specs |
|
|
|
|
|
|
|
|
K_FLASH { current_mem = AVR_M_FLASH; }
|
2014-06-17 20:08:28 +00:00
|
|
|
mem_specs |
|
2001-11-21 02:46:55 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
K_MEMORY TKN_STRING
|
2014-06-17 20:08:28 +00:00
|
|
|
{
|
|
|
|
current_mem = avr_new_memtype();
|
|
|
|
if (current_mem == NULL) {
|
|
|
|
yyerror("could not create mem instance");
|
|
|
|
free_token($2);
|
|
|
|
YYABORT;
|
|
|
|
}
|
2020-09-10 21:43:23 +00:00
|
|
|
strncpy(current_mem->desc, $2->value.string, AVR_MEMDESCLEN - 1);
|
2011-12-17 13:45:54 +00:00
|
|
|
current_mem->desc[AVR_MEMDESCLEN-1] = 0;
|
2014-06-17 20:08:28 +00:00
|
|
|
free_token($2);
|
|
|
|
}
|
2001-11-21 02:46:55 +00:00
|
|
|
mem_specs
|
|
|
|
{
|
2012-01-17 20:56:37 +00:00
|
|
|
AVRMEM * existing_mem;
|
|
|
|
|
Alias keyword (#868)
Implementation for an "alias" keyword.
By now, only applied inside memory descriptions.
* Make "mem_alias" a separate nonterminal.
The previous implementation attempt caused a syntax error in
yacc code, and separating mem_alias on the same level as
mem_spec appears to be the cleaner solution anyway.
* Maintain real memory aliases.
Instead of duplicating the aliased memory with a new name, maintain a
second list of memory aliases (per device) that contains a pointer to
the memory area it is aliased to. That way, a memory name can be
clearly distinguished between the canonical one and any aliases.
* Check p->mem_alias != NULL before touching it
* Add avr_find_memalias()
This takes a memory region as input, and searches whether an
alias can be found for it.
* We need to add a list structure for the mem_alias list, always.
By that means, mem_alias won't ever be NULL, so no need to check
later.
Also, in avr_dup_part(), duplicate the alias list.
* In a memory alias, actually remember the current name.
* In avr_dup_part(), adjust pointers of aliased memories
While walking the list of memories, for each entry, see if there is an
alias pointing to it. If so, allocate a duplicated one, and fix its
aliased_mem pointer to point to the duplicated memory region instead
of the original one.
* Add avr_locate_mem_noalias()
When looking whether any memory region has already been defined for
the current part while parsing the config file, only non-aliased names
must be considered. Otherwise, a newly defined alias would kick out
the memory definition it is being aliased to.
* When defining a mem_alias, drop any existing one of that name.
* Actually use avr_find_memalias() to find aliases
* Add declaration for avr_find_memalias()
* When defining a memory, also search for an existing alias
If the newly defined name has the same as an existing alias, the alias
can be removed.
Note that we do explicitly *not* remove any memory by the same name of
a later defined alias, as this might invalidate another alias'es
pointer. If someone defines that, the alias name just won't ever be
found by avr_locate_mem().
2022-02-10 19:39:19 +00:00
|
|
|
existing_mem = avr_locate_mem_noalias(current_part, current_mem->desc);
|
2012-01-17 20:56:37 +00:00
|
|
|
if (existing_mem != NULL) {
|
|
|
|
lrmv_d(current_part->mem, existing_mem);
|
|
|
|
avr_free_mem(existing_mem);
|
|
|
|
}
|
Alias keyword (#868)
Implementation for an "alias" keyword.
By now, only applied inside memory descriptions.
* Make "mem_alias" a separate nonterminal.
The previous implementation attempt caused a syntax error in
yacc code, and separating mem_alias on the same level as
mem_spec appears to be the cleaner solution anyway.
* Maintain real memory aliases.
Instead of duplicating the aliased memory with a new name, maintain a
second list of memory aliases (per device) that contains a pointer to
the memory area it is aliased to. That way, a memory name can be
clearly distinguished between the canonical one and any aliases.
* Check p->mem_alias != NULL before touching it
* Add avr_find_memalias()
This takes a memory region as input, and searches whether an
alias can be found for it.
* We need to add a list structure for the mem_alias list, always.
By that means, mem_alias won't ever be NULL, so no need to check
later.
Also, in avr_dup_part(), duplicate the alias list.
* In a memory alias, actually remember the current name.
* In avr_dup_part(), adjust pointers of aliased memories
While walking the list of memories, for each entry, see if there is an
alias pointing to it. If so, allocate a duplicated one, and fix its
aliased_mem pointer to point to the duplicated memory region instead
of the original one.
* Add avr_locate_mem_noalias()
When looking whether any memory region has already been defined for
the current part while parsing the config file, only non-aliased names
must be considered. Otherwise, a newly defined alias would kick out
the memory definition it is being aliased to.
* When defining a mem_alias, drop any existing one of that name.
* Actually use avr_find_memalias() to find aliases
* Add declaration for avr_find_memalias()
* When defining a memory, also search for an existing alias
If the newly defined name has the same as an existing alias, the alias
can be removed.
Note that we do explicitly *not* remove any memory by the same name of
a later defined alias, as this might invalidate another alias'es
pointer. If someone defines that, the alias name just won't ever be
found by avr_locate_mem().
2022-02-10 19:39:19 +00:00
|
|
|
if (is_alias) {
|
|
|
|
avr_free_mem(current_mem); // alias mem has been already entered below
|
|
|
|
is_alias = false;
|
|
|
|
} else {
|
|
|
|
ladd(current_part->mem, current_mem);
|
|
|
|
}
|
2001-11-21 02:46:55 +00:00
|
|
|
current_mem = NULL;
|
|
|
|
} |
|
|
|
|
|
|
|
|
opcode TKN_EQUAL string_list {
|
|
|
|
{
|
|
|
|
int opnum;
|
|
|
|
OPCODE * op;
|
|
|
|
|
|
|
|
opnum = which_opcode($1);
|
2014-06-17 20:08:28 +00:00
|
|
|
if (opnum < 0) YYABORT;
|
2001-11-21 02:46:55 +00:00
|
|
|
op = avr_new_opcode();
|
2014-06-17 20:08:28 +00:00
|
|
|
if (op == NULL) {
|
|
|
|
yyerror("could not create opcode instance");
|
|
|
|
free_token($1);
|
|
|
|
YYABORT;
|
|
|
|
}
|
|
|
|
if(0 != parse_cmdbits(op)) YYABORT;
|
2011-12-17 17:00:51 +00:00
|
|
|
if (current_part->op[opnum] != NULL) {
|
2014-06-17 20:08:28 +00:00
|
|
|
/*yywarning("operation redefined");*/
|
2012-01-17 20:56:37 +00:00
|
|
|
avr_free_opcode(current_part->op[opnum]);
|
2011-12-17 17:00:51 +00:00
|
|
|
}
|
2001-11-21 02:46:55 +00:00
|
|
|
current_part->op[opnum] = op;
|
|
|
|
|
|
|
|
free_token($1);
|
|
|
|
}
|
|
|
|
}
|
2001-10-14 23:17:26 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
yesno :
|
|
|
|
K_YES | K_NO
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
mem_specs :
|
|
|
|
mem_spec TKN_SEMI |
|
Alias keyword (#868)
Implementation for an "alias" keyword.
By now, only applied inside memory descriptions.
* Make "mem_alias" a separate nonterminal.
The previous implementation attempt caused a syntax error in
yacc code, and separating mem_alias on the same level as
mem_spec appears to be the cleaner solution anyway.
* Maintain real memory aliases.
Instead of duplicating the aliased memory with a new name, maintain a
second list of memory aliases (per device) that contains a pointer to
the memory area it is aliased to. That way, a memory name can be
clearly distinguished between the canonical one and any aliases.
* Check p->mem_alias != NULL before touching it
* Add avr_find_memalias()
This takes a memory region as input, and searches whether an
alias can be found for it.
* We need to add a list structure for the mem_alias list, always.
By that means, mem_alias won't ever be NULL, so no need to check
later.
Also, in avr_dup_part(), duplicate the alias list.
* In a memory alias, actually remember the current name.
* In avr_dup_part(), adjust pointers of aliased memories
While walking the list of memories, for each entry, see if there is an
alias pointing to it. If so, allocate a duplicated one, and fix its
aliased_mem pointer to point to the duplicated memory region instead
of the original one.
* Add avr_locate_mem_noalias()
When looking whether any memory region has already been defined for
the current part while parsing the config file, only non-aliased names
must be considered. Otherwise, a newly defined alias would kick out
the memory definition it is being aliased to.
* When defining a mem_alias, drop any existing one of that name.
* Actually use avr_find_memalias() to find aliases
* Add declaration for avr_find_memalias()
* When defining a memory, also search for an existing alias
If the newly defined name has the same as an existing alias, the alias
can be removed.
Note that we do explicitly *not* remove any memory by the same name of
a later defined alias, as this might invalidate another alias'es
pointer. If someone defines that, the alias name just won't ever be
found by avr_locate_mem().
2022-02-10 19:39:19 +00:00
|
|
|
mem_alias TKN_SEMI |
|
2001-10-14 23:17:26 +00:00
|
|
|
mem_specs mem_spec TKN_SEMI
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
mem_spec :
|
2001-10-16 23:32:30 +00:00
|
|
|
K_PAGED TKN_EQUAL yesno
|
2001-10-14 23:17:26 +00:00
|
|
|
{
|
2001-11-21 02:46:55 +00:00
|
|
|
current_mem->paged = $3->primary == K_YES ? 1 : 0;
|
2001-10-14 23:17:26 +00:00
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_SIZE TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
2001-11-21 02:46:55 +00:00
|
|
|
current_mem->size = $3->value.number;
|
2001-10-14 23:17:26 +00:00
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
2001-10-16 23:32:30 +00:00
|
|
|
K_PAGE_SIZE TKN_EQUAL TKN_NUMBER
|
2001-10-14 23:17:26 +00:00
|
|
|
{
|
2020-09-10 21:37:34 +00:00
|
|
|
int ps = $3->value.number;
|
|
|
|
if (ps <= 0)
|
|
|
|
avrdude_message(MSG_INFO,
|
|
|
|
"%s, line %d: invalid page size %d, ignored\n",
|
|
|
|
infile, lineno, ps);
|
|
|
|
else
|
|
|
|
current_mem->page_size = ps;
|
2001-10-14 23:17:26 +00:00
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2001-10-16 23:32:30 +00:00
|
|
|
K_NUM_PAGES TKN_EQUAL TKN_NUMBER
|
2001-10-14 23:17:26 +00:00
|
|
|
{
|
2001-11-21 02:46:55 +00:00
|
|
|
current_mem->num_pages = $3->value.number;
|
2001-10-14 23:17:26 +00:00
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2008-07-26 22:53:40 +00:00
|
|
|
K_OFFSET TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_mem->offset = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
K_MIN_WRITE_DELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
2001-11-21 02:46:55 +00:00
|
|
|
current_mem->min_write_delay = $3->value.number;
|
2001-10-14 23:17:26 +00:00
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_MAX_WRITE_DELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
2001-11-21 02:46:55 +00:00
|
|
|
current_mem->max_write_delay = $3->value.number;
|
2001-10-14 23:17:26 +00:00
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2002-02-14 03:04:22 +00:00
|
|
|
K_PWROFF_AFTER_WRITE TKN_EQUAL yesno
|
2002-02-14 02:48:07 +00:00
|
|
|
{
|
2002-02-14 03:04:22 +00:00
|
|
|
current_mem->pwroff_after_write = $3->primary == K_YES ? 1 : 0;
|
2002-02-14 02:48:07 +00:00
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
2001-10-14 23:17:26 +00:00
|
|
|
K_READBACK_P1 TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
2001-11-21 02:46:55 +00:00
|
|
|
current_mem->readback[0] = $3->value.number;
|
2001-10-14 23:17:26 +00:00
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_READBACK_P2 TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
2001-11-21 02:46:55 +00:00
|
|
|
current_mem->readback[1] = $3->value.number;
|
2001-10-14 23:17:26 +00:00
|
|
|
free_token($3);
|
2001-11-21 02:46:55 +00:00
|
|
|
} |
|
|
|
|
|
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Erik's submission has been cleaned up a little bit, mostly to add his
name and the current year to the copyright of the new file, remove
trailing white space before importing the files, and fix the minor
syntax errors in his avrdude.conf.in additions (missing semicolons).
The JTAG ICE mkII support should be considered alpha to beta quality
at this point. Few things are still to be done, like defering the
hfuse (OCDEN) tweaks until they are really required. Also, for
reasons not yet known, the target MCU doesn't start to run after
signing off from the ICE, it needs a power-cycle first (at least on my
STK500).
Note that for the JTAG ICE, I did change a few things in the internal
API. Notably I made the serial receive timeout configurable by the
backends via an exported variable (done in both the Posix and the
Win32 implementation), and I made the serial_recv() function return a
-1 instead of bailing out with exit(1) upon encountering a receive
timeout (currently only done in the Posix implementation). Both
measures together allow me to receive a datastreem from the ICE at 115
kbps on a somewhat lossy PCI multi-UART card that occasionally drops a
character. The JTAG ICE mkII protocol has enough of safety layers to
allow recovering from these events, but the previous code wasn't
prepared for any kind of recovery. The Win32 change for this still
has to be done, and the traditional drivers need to be converted to
exit(1) upon encountering a timeout (as they're now getting a -1
returned they didn't see before in that case).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@451 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-10 19:17:12 +00:00
|
|
|
|
|
|
|
K_MODE TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_mem->mode = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_DELAY TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_mem->delay = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_BLOCKSIZE TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_mem->blocksize = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_READSIZE TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_mem->readsize = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
K_POLLINDEX TKN_EQUAL TKN_NUMBER
|
|
|
|
{
|
|
|
|
current_mem->pollindex = $3->value.number;
|
|
|
|
free_token($3);
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
2001-11-21 02:46:55 +00:00
|
|
|
opcode TKN_EQUAL string_list {
|
|
|
|
{
|
|
|
|
int opnum;
|
|
|
|
OPCODE * op;
|
|
|
|
|
|
|
|
opnum = which_opcode($1);
|
2014-06-17 20:08:28 +00:00
|
|
|
if (opnum < 0) YYABORT;
|
2001-11-21 02:46:55 +00:00
|
|
|
op = avr_new_opcode();
|
2014-06-17 20:08:28 +00:00
|
|
|
if (op == NULL) {
|
|
|
|
yyerror("could not create opcode instance");
|
|
|
|
free_token($1);
|
|
|
|
YYABORT;
|
|
|
|
}
|
|
|
|
if(0 != parse_cmdbits(op)) YYABORT;
|
2011-12-17 17:00:51 +00:00
|
|
|
if (current_mem->op[opnum] != NULL) {
|
2014-06-17 20:08:28 +00:00
|
|
|
/*yywarning("operation redefined");*/
|
2012-01-17 20:56:37 +00:00
|
|
|
avr_free_opcode(current_mem->op[opnum]);
|
2011-12-17 17:00:51 +00:00
|
|
|
}
|
2001-11-21 02:46:55 +00:00
|
|
|
current_mem->op[opnum] = op;
|
|
|
|
|
|
|
|
free_token($1);
|
2001-10-14 23:17:26 +00:00
|
|
|
}
|
2001-11-21 02:46:55 +00:00
|
|
|
}
|
2001-10-14 23:17:26 +00:00
|
|
|
;
|
|
|
|
|
Alias keyword (#868)
Implementation for an "alias" keyword.
By now, only applied inside memory descriptions.
* Make "mem_alias" a separate nonterminal.
The previous implementation attempt caused a syntax error in
yacc code, and separating mem_alias on the same level as
mem_spec appears to be the cleaner solution anyway.
* Maintain real memory aliases.
Instead of duplicating the aliased memory with a new name, maintain a
second list of memory aliases (per device) that contains a pointer to
the memory area it is aliased to. That way, a memory name can be
clearly distinguished between the canonical one and any aliases.
* Check p->mem_alias != NULL before touching it
* Add avr_find_memalias()
This takes a memory region as input, and searches whether an
alias can be found for it.
* We need to add a list structure for the mem_alias list, always.
By that means, mem_alias won't ever be NULL, so no need to check
later.
Also, in avr_dup_part(), duplicate the alias list.
* In a memory alias, actually remember the current name.
* In avr_dup_part(), adjust pointers of aliased memories
While walking the list of memories, for each entry, see if there is an
alias pointing to it. If so, allocate a duplicated one, and fix its
aliased_mem pointer to point to the duplicated memory region instead
of the original one.
* Add avr_locate_mem_noalias()
When looking whether any memory region has already been defined for
the current part while parsing the config file, only non-aliased names
must be considered. Otherwise, a newly defined alias would kick out
the memory definition it is being aliased to.
* When defining a mem_alias, drop any existing one of that name.
* Actually use avr_find_memalias() to find aliases
* Add declaration for avr_find_memalias()
* When defining a memory, also search for an existing alias
If the newly defined name has the same as an existing alias, the alias
can be removed.
Note that we do explicitly *not* remove any memory by the same name of
a later defined alias, as this might invalidate another alias'es
pointer. If someone defines that, the alias name just won't ever be
found by avr_locate_mem().
2022-02-10 19:39:19 +00:00
|
|
|
mem_alias :
|
|
|
|
K_ALIAS TKN_STRING
|
|
|
|
{
|
|
|
|
AVRMEM * existing_mem;
|
|
|
|
|
|
|
|
existing_mem = avr_locate_mem(current_part, $2->value.string);
|
|
|
|
if (existing_mem == NULL) {
|
|
|
|
yyerror("%s alias to non-existent memory %s",
|
|
|
|
current_mem->desc, $2->value.string);
|
|
|
|
free_token($2);
|
|
|
|
YYABORT;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if this alias does already exist, drop the old one
|
|
|
|
AVRMEM_ALIAS * alias = avr_locate_memalias(current_part, current_mem->desc);
|
|
|
|
if (alias) {
|
|
|
|
lrmv_d(current_part->mem_alias, alias);
|
|
|
|
avr_free_memalias(alias);
|
|
|
|
}
|
|
|
|
|
|
|
|
is_alias = true;
|
|
|
|
alias = avr_new_memalias();
|
|
|
|
|
|
|
|
// alias->desc and current_mem->desc have the same length
|
|
|
|
// definition, thus no need to check for length here
|
|
|
|
strcpy(alias->desc, current_mem->desc);
|
|
|
|
alias->aliased_mem = existing_mem;
|
|
|
|
ladd(current_part->mem_alias, alias);
|
|
|
|
|
|
|
|
free_token($2);
|
|
|
|
}
|
|
|
|
;
|
2001-10-14 23:17:26 +00:00
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
static char * vtypestr(int type)
|
|
|
|
{
|
|
|
|
switch (type) {
|
2012-11-13 21:34:02 +00:00
|
|
|
case V_NUM : return "INTEGER";
|
|
|
|
case V_NUM_REAL: return "REAL";
|
2001-10-14 23:17:26 +00:00
|
|
|
case V_STR : return "STRING";
|
|
|
|
default:
|
|
|
|
return "<UNKNOWN>";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2005-09-18 20:12:23 +00:00
|
|
|
static int assign_pin(int pinno, TOKEN * v, int invert)
|
2001-10-14 23:17:26 +00:00
|
|
|
{
|
|
|
|
int value;
|
|
|
|
|
|
|
|
value = v->value.number;
|
2011-12-17 13:45:54 +00:00
|
|
|
free_token(v);
|
2001-10-14 23:17:26 +00:00
|
|
|
|
2013-01-09 19:23:30 +00:00
|
|
|
if ((value < PIN_MIN) || (value > PIN_MAX)) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("pin must be in the range " TOSTRING(PIN_MIN) "-" TOSTRING(PIN_MAX));
|
|
|
|
return -1;
|
2001-10-14 23:17:26 +00:00
|
|
|
}
|
|
|
|
|
2013-05-03 22:35:00 +00:00
|
|
|
pin_set_value(&(current_prog->pin[pinno]), value, invert);
|
2001-10-14 23:17:26 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-11-13 21:34:02 +00:00
|
|
|
static int assign_pin_list(int invert)
|
|
|
|
{
|
|
|
|
TOKEN * t;
|
|
|
|
int pin;
|
2014-06-17 20:08:28 +00:00
|
|
|
int rv = 0;
|
2012-11-13 21:34:02 +00:00
|
|
|
|
|
|
|
current_prog->pinno[pin_name] = 0;
|
|
|
|
while (lsize(number_list)) {
|
|
|
|
t = lrmv_n(number_list, 1);
|
2014-06-17 20:08:28 +00:00
|
|
|
if (rv == 0) {
|
|
|
|
pin = t->value.number;
|
|
|
|
if ((pin < PIN_MIN) || (pin > PIN_MAX)) {
|
|
|
|
yyerror("pin must be in the range " TOSTRING(PIN_MIN) "-" TOSTRING(PIN_MAX));
|
|
|
|
rv = -1;
|
|
|
|
/* loop clears list and frees tokens */
|
|
|
|
}
|
|
|
|
pin_set_value(&(current_prog->pin[pin_name]), pin, invert);
|
2013-05-03 22:35:00 +00:00
|
|
|
}
|
2012-11-13 21:34:02 +00:00
|
|
|
free_token(t);
|
|
|
|
}
|
2014-06-17 20:08:28 +00:00
|
|
|
return rv;
|
2012-11-13 21:34:02 +00:00
|
|
|
}
|
|
|
|
|
2001-11-21 02:46:55 +00:00
|
|
|
static int which_opcode(TOKEN * opcode)
|
|
|
|
{
|
|
|
|
switch (opcode->primary) {
|
|
|
|
case K_READ : return AVR_OP_READ; break;
|
|
|
|
case K_WRITE : return AVR_OP_WRITE; break;
|
|
|
|
case K_READ_LO : return AVR_OP_READ_LO; break;
|
|
|
|
case K_READ_HI : return AVR_OP_READ_HI; break;
|
|
|
|
case K_WRITE_LO : return AVR_OP_WRITE_LO; break;
|
|
|
|
case K_WRITE_HI : return AVR_OP_WRITE_HI; break;
|
|
|
|
case K_LOADPAGE_LO : return AVR_OP_LOADPAGE_LO; break;
|
|
|
|
case K_LOADPAGE_HI : return AVR_OP_LOADPAGE_HI; break;
|
2006-05-23 22:27:43 +00:00
|
|
|
case K_LOAD_EXT_ADDR : return AVR_OP_LOAD_EXT_ADDR; break;
|
2001-11-21 02:46:55 +00:00
|
|
|
case K_WRITEPAGE : return AVR_OP_WRITEPAGE; break;
|
|
|
|
case K_CHIP_ERASE : return AVR_OP_CHIP_ERASE; break;
|
|
|
|
case K_PGM_ENABLE : return AVR_OP_PGM_ENABLE; break;
|
|
|
|
default :
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("invalid opcode");
|
|
|
|
return -1;
|
2001-11-21 02:46:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int parse_cmdbits(OPCODE * op)
|
|
|
|
{
|
|
|
|
TOKEN * t;
|
|
|
|
int bitno;
|
|
|
|
char ch;
|
|
|
|
char * e;
|
|
|
|
char * q;
|
|
|
|
int len;
|
2010-01-07 13:13:02 +00:00
|
|
|
char * s, *brkt = NULL;
|
2014-06-17 20:08:28 +00:00
|
|
|
int rv = 0;
|
2001-11-21 02:46:55 +00:00
|
|
|
|
2001-11-21 05:50:59 +00:00
|
|
|
bitno = 32;
|
2001-11-21 02:46:55 +00:00
|
|
|
while (lsize(string_list)) {
|
|
|
|
|
|
|
|
t = lrmv_n(string_list, 1);
|
|
|
|
|
2001-11-21 05:50:59 +00:00
|
|
|
s = strtok_r(t->value.string, " ", &brkt);
|
2014-06-17 20:08:28 +00:00
|
|
|
while (rv == 0 && s != NULL) {
|
2001-11-21 02:46:55 +00:00
|
|
|
|
2001-11-21 05:50:59 +00:00
|
|
|
bitno--;
|
|
|
|
if (bitno < 0) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("too many opcode bits for instruction");
|
|
|
|
rv = -1;
|
|
|
|
break;
|
2001-11-21 05:50:59 +00:00
|
|
|
}
|
2001-11-21 02:46:55 +00:00
|
|
|
|
2001-11-21 05:50:59 +00:00
|
|
|
len = strlen(s);
|
|
|
|
|
|
|
|
if (len == 0) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("invalid bit specifier \"\"");
|
|
|
|
rv = -1;
|
|
|
|
break;
|
2001-11-21 02:46:55 +00:00
|
|
|
}
|
2001-11-21 05:50:59 +00:00
|
|
|
|
|
|
|
ch = s[0];
|
|
|
|
|
|
|
|
if (len == 1) {
|
|
|
|
switch (ch) {
|
|
|
|
case '1':
|
|
|
|
op->bit[bitno].type = AVR_CMDBIT_VALUE;
|
|
|
|
op->bit[bitno].value = 1;
|
|
|
|
op->bit[bitno].bitno = bitno % 8;
|
|
|
|
break;
|
|
|
|
case '0':
|
|
|
|
op->bit[bitno].type = AVR_CMDBIT_VALUE;
|
|
|
|
op->bit[bitno].value = 0;
|
|
|
|
op->bit[bitno].bitno = bitno % 8;
|
|
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
op->bit[bitno].type = AVR_CMDBIT_IGNORE;
|
|
|
|
op->bit[bitno].value = 0;
|
|
|
|
op->bit[bitno].bitno = bitno % 8;
|
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
op->bit[bitno].type = AVR_CMDBIT_ADDRESS;
|
|
|
|
op->bit[bitno].value = 0;
|
|
|
|
op->bit[bitno].bitno = 8*(bitno/8) + bitno % 8;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
op->bit[bitno].type = AVR_CMDBIT_INPUT;
|
|
|
|
op->bit[bitno].value = 0;
|
|
|
|
op->bit[bitno].bitno = bitno % 8;
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
op->bit[bitno].type = AVR_CMDBIT_OUTPUT;
|
|
|
|
op->bit[bitno].value = 0;
|
|
|
|
op->bit[bitno].bitno = bitno % 8;
|
|
|
|
break;
|
|
|
|
default :
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("invalid bit specifier '%c'", ch);
|
|
|
|
rv = -1;
|
2001-11-21 05:50:59 +00:00
|
|
|
break;
|
2001-11-21 02:46:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2001-11-21 05:50:59 +00:00
|
|
|
if (ch == 'a') {
|
|
|
|
q = &s[1];
|
|
|
|
op->bit[bitno].bitno = strtol(q, &e, 0);
|
|
|
|
if ((e == q)||(*e != 0)) {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("can't parse bit number from \"%s\"", q);
|
|
|
|
rv = -1;
|
|
|
|
break;
|
2001-11-21 05:50:59 +00:00
|
|
|
}
|
|
|
|
op->bit[bitno].type = AVR_CMDBIT_ADDRESS;
|
|
|
|
op->bit[bitno].value = 0;
|
|
|
|
}
|
|
|
|
else {
|
2014-06-17 20:08:28 +00:00
|
|
|
yyerror("invalid bit specifier \"%s\"", s);
|
|
|
|
rv = -1;
|
|
|
|
break;
|
2001-11-21 05:50:59 +00:00
|
|
|
}
|
2001-11-21 02:46:55 +00:00
|
|
|
}
|
2001-11-21 05:50:59 +00:00
|
|
|
|
|
|
|
s = strtok_r(NULL, " ", &brkt);
|
2014-06-17 20:08:28 +00:00
|
|
|
} /* while */
|
2001-11-21 02:46:55 +00:00
|
|
|
|
2001-11-21 05:50:59 +00:00
|
|
|
free_token(t);
|
2001-11-21 02:46:55 +00:00
|
|
|
|
|
|
|
} /* while */
|
|
|
|
|
2014-06-17 20:08:28 +00:00
|
|
|
return rv;
|
2001-11-21 02:46:55 +00:00
|
|
|
}
|