Also changed usbdev, usbsn, usbvendor and usbproduct components from
PROGRAMMER structure to be cached string pointers rather than fixed-size
arrays. These will be initialised by pgm_new() with a pointer to nul;
As the address bit numbers in the SPI opcodes are highly systematic, they
don't really need to be specified. Each bit can therefore be described as one
of the characters 0 (always 0), 1 (always 1), x (don't care, but will be set
as 0), a (a copy of the correct bit of the byte or word address of read,
write, load, pagewrite or load extended address command of memories with more
than one byte), i (input bit for a load/write) or o (output bit from a read).
The bits therefore do not need to be individually separated.
If a string in the list of strings that describe an SPI opcode does *not*
contain a space *and* is longer than 7 characters, it is interpreted as a
compact bit-pattern representation. The characters 0, 1, x, a, i and o will
be recognised as the corresponding bit, whilst any of the characters ., -, _
or / can act as arbitrary visual separators, which are ignored. Examples:
loadpage_lo = "0100.0000--000x.xxxx--xxaa.aaaa--iiii.iiii";
loadpage_lo = "0100.0000", "000x.xxxx", "xxaa.aaaa", "iiii.iiii";
loadpage_lo = "0100.0000", "000x.xxxx.xxaa.aaaa", "iiii.iiii";
loadpage_lo = "0100.0000-000x.xxxx--xxaa.aaaa-iiii.iiii";
loadpage_lo = "0100.0000/000x.xxxx/xxaa.aaaa/iiii.iiii";
The compact format is an extension of the current format, which remains
valid. Both, the compact and the traditional specification can be mixed in
different strings, albeit not in the same string:
load_ext_addr = "0100.1101", "0000.0000.0000", "0 0 0 a16", "0000.0000";
This commit changes the philosophy whenever avrdude.conf encounters the
same memory of a part for the second time or whenever a memory is
described that, through inheritance, already existed: AVRDUDE no longer
zaps the memory, it rather extends it.
Therefore, avrdude.conf.in's entry for ATmega128RFA1, which inherits from
the ATmega2561, needs a line `load_ext_addr = NULL;` in its flash memory
description to zap the inherited load_ext_addr SPI command.
Other than this, avrdude.conf.in needs no other change in order to effect
the same internal representation proving earlier updates to the .conf.in
file correct that manually ensured inheritance of memory contents.
When an SPI command has a lone 'a' the initialisation now is as would be
expected by all commands that take an address. Atmel's opcodes for SPI
programming are consistent in this respect. This commit makes specifying
the bit number in avrdude.conf optional. Instead of
read_lo = "0 0 1 0 0 0 0 0 0 0 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
one can now use
read_lo = "0 0 1 0 0 0 0 0 0 0 a a a a a a a a a a a a a a o o o o o o o o";
Some 90% of the space of AVRPART and some 50% of PROGRAMMER is occupied by a
4 kB array config_file[] that contains the configuration file name. In
preparation of developer options that output a raw dump of the part
descriptions, this commit changes the config_file components from a large
array, which is duplicated in each part and programmer description, to a
cached string for each config file allowing for smaller raw dumps.
This commit also changes the config file name to its realpath(), eg, shortens
unwarranted `/bin/../etc/` file name components. It also changes the global
variable names `infile` and `fileno` to cfg_infile and cfg_fileno for an ever
so slight improvement of code clarity.
It breaks the alias handling completely as the search happens
way too late. So instead, just keep any possibly duplicate
name as it won't be in our way anyway.
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().
This feature has been designed with the sometimes quite flakey direct
(parallel or serial port attached) bitbang programming adapters in
mind that were quite common about two decades ago.
With parallel ports vanishing from modern PCs almost completely, and
the advent of various USB-attached low-cost programming devices,
this class of programmers disappeared almost completely.
Furthermore, the fuse combinations that were covered by the feature
are no longer around on all recent AVR devices, so for an ever
increasing number of devices, safemode already became meaningless and
was turned off anyway.
With the prospective version 7.x release, it's a good point in time to
introduce a major change like this one.