From c97eb85cd813aa5c686ce88323ee3fb46b395224 Mon Sep 17 00:00:00 2001
From: Stefan Rueger <stefan.rueger@urclocks.com>
Date: Wed, 24 Aug 2022 12:55:00 +0100
Subject: [PATCH] Fix reset=dedicated|io; in avrdude.conf.in

Done by adding code in developer_opts.c that allows to inject part
or memory parameters into a semi-automated rewrite of avrdude.conf
This is a generic method, whereby an external program can, eg.,
scrape atdf files for the right parameters and put them into a
source table into developer_opts.c
  - Then write parts description with -p*/i
  - Use the output in a new avrdude.conf
  - Output again with -p* (no /i) and use that for final avrdude.conf
  - Remove table entries
---
 src/avrdude.conf.in  | 34 ++++++++++++++++++++++++++++++++++
 src/developer_opts.c | 44 ++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in
index ab07d334..a5d32538 100644
--- a/src/avrdude.conf.in
+++ b/src/avrdude.conf.in
@@ -3501,6 +3501,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x96 0x02;
+    reset               = io;
     has_jtag            = yes;
     allowfullpagebitstream = yes;
     timeout             = 200;
@@ -3626,6 +3627,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x97 0x02;
+    reset               = io;
     has_jtag            = yes;
     allowfullpagebitstream = yes;
     timeout             = 200;
@@ -3752,6 +3754,7 @@ part
     bs2                 = 0xa0;
 #    avr910_devcode   = 0x43;
     signature           = 0x1e 0x97 0x81;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -3872,6 +3875,7 @@ part
     bs2                 = 0xa0;
 #    avr910_devcode   = 0x43;
     signature           = 0x1e 0x96 0x81;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -3992,6 +3996,7 @@ part
     bs2                 = 0xa0;
 #    avr910_devcode   = 0x43;
     signature           = 0x1e 0x95 0x81;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -4112,6 +4117,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x94 0x03;
+    reset               = io;
     has_jtag            = yes;
     allowfullpagebitstream = yes;
     timeout             = 200;
@@ -4233,6 +4239,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x95 0x08;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -4421,6 +4428,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x96 0x09;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -4567,6 +4575,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x97 0x06;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -4698,6 +4707,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x94 0x04;
+    reset               = io;
     has_jtag            = yes;
     allowfullpagebitstream = yes;
     timeout             = 200;
@@ -5031,6 +5041,7 @@ part parent "m169"
     desc                = "ATmega169A";
     id                  = "m169a";
     signature           = 0x1e 0x94 0x11;
+    reset               = io;
 ;
 
 #------------------------------------------------------------
@@ -5040,6 +5051,7 @@ part parent "m169"
 part parent "m169"
     desc                = "ATmega169P";
     id                  = "m169p";
+    reset               = io;
 ;
 
 #------------------------------------------------------------
@@ -5049,6 +5061,7 @@ part parent "m169"
 part parent "m169"
     desc                = "ATmega169PA";
     id                  = "m169pa";
+    reset               = io;
 ;
 
 #------------------------------------------------------------
@@ -5063,6 +5076,7 @@ part
     avr910_devcode      = 0x75;
     chip_erase_delay    = 9000;
     signature           = 0x1e 0x95 0x03;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -5252,6 +5266,7 @@ part
     avr910_devcode      = 0x75;
     chip_erase_delay    = 9000;
     signature           = 0x1e 0x96 0x03;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -5422,6 +5437,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x95 0x02;
+    reset               = io;
     has_jtag            = yes;
     allowfullpagebitstream = yes;
     timeout             = 200;
@@ -5629,6 +5645,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xc2;
     signature           = 0x1e 0x93 0x07;
+    reset               = io;
     timeout             = 200;
     stabdelay           = 100;
     cmdexedelay         = 25;
@@ -6500,6 +6517,7 @@ part
     bs2                 = 0xc2;
 #    avr910_devcode   = 0x;
     signature           = 0x1e 0x92 0x05;
+    reset               = io;
     has_debugwire       = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -6664,6 +6682,7 @@ part
     bs2                 = 0xc2;
 #    avr910_devcode   = 0x;
     signature           = 0x1e 0x93 0x0a;
+    reset               = io;
     has_debugwire       = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -6829,6 +6848,7 @@ part
     bs2                 = 0xc2;
     # avr910_devcode = 0x;
     signature           = 0x1e 0x94 0x06;
+    reset               = io;
     has_debugwire       = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -6994,6 +7014,7 @@ part
     bs2                 = 0xc2;
     # avr910_devcode = 0x;
     signature           = 0x1e 0x93 0x14;
+    reset               = io;
     has_debugwire       = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -7376,6 +7397,7 @@ part
     bs2                 = 0xc2;
 #    avr910_devcode   = 0x;
     signature           = 0x1e 0x92 0x09;
+    reset               = io;
     has_debugwire       = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -7501,6 +7523,7 @@ part
     bs2                 = 0xc2;
 #    avr910_devcode   = 0x;
     signature           = 0x1e 0x93 0x11;
+    reset               = io;
     has_debugwire       = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -7626,6 +7649,7 @@ part
     bs2                 = 0xc2;
     # avr910_devcode    = 0x;
     signature           = 0x1e 0x95 0x14;
+    reset               = io;
     has_debugwire       = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -8671,6 +8695,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x96 0x08;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -8791,6 +8816,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x97 0x03;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -8922,6 +8948,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x98 0x01;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -9749,6 +9776,7 @@ part
     bs2                 = 0xa0;
     signature           = 0x1e 0x94 0x88;
     usbpid              = 0x2ff4;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -9870,6 +9898,7 @@ part
     bs2                 = 0xa0;
     signature           = 0x1e 0x95 0x87;
     usbpid              = 0x2ff4;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -9991,6 +10020,7 @@ part
     bs2                 = 0xa0;
     signature           = 0x1e 0x96 0x82;
     usbpid              = 0x2ff9;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -10122,6 +10152,7 @@ part
     bs2                 = 0xa0;
     signature           = 0x1e 0x97 0x82;
     usbpid              = 0x2ffb;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -11013,6 +11044,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x95 0x05;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -11164,6 +11196,7 @@ part
     pagel               = 0xd7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x96 0x05;
+    reset               = io;
     has_jtag            = yes;
     timeout             = 200;
     stabdelay           = 100;
@@ -12842,6 +12875,7 @@ part
     pagel               = 0xa7;
     bs2                 = 0xa0;
     signature           = 0x1e 0x95 0x07;
+    reset               = io;
     has_jtag            = yes;
     serial              = no;
     # STK500v2 HV programming parameters, from XML
diff --git a/src/developer_opts.c b/src/developer_opts.c
index 2aee8b10..e88c9a21 100644
--- a/src/developer_opts.c
+++ b/src/developer_opts.c
@@ -53,6 +53,27 @@
 #include "developer_opts.h"
 #include "developer_opts_private.h"
 
+  // Inject part parameters into a semi-automated rewrite of avrdude.conf
+  //  - Add entries to the tables below; they get written on -p*/i
+  //  - Use the output in a new avrdude.conf
+  //  - Output again with -p* (no /i) and use that for final avrdude.conf
+  //  - Remove entries from below tables
+
+static struct {
+  const char *mcu, *var, *value;
+} ptinj[] = {
+  // Add triples here, eg, {"ATmega328P", "mcuid", "999"},
+};
+
+static struct {
+  const char *mcu, *mem, *var, *value;
+} meminj[] = {
+  // Add quadruples here, eg, {"ATmega328P", "flash", "page_size", "128"},
+};
+
+
+
+
 // Return 0 if op code would encode (essentially) the same SPI command
 static int opcodecmp(const OPCODE *op1, const OPCODE *op2, int opnum) {
   char *opstr1, *opstr2, *p;
@@ -525,7 +546,7 @@ static void dev_part_raw(const AVRPART *part) {
 }
 
 
-static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base) {
+static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool injct) {
   char *descstr = cfg_escape(p->desc);
   COMMENT *cp;
 
@@ -690,6 +711,12 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base) {
       if(!bm || opcodecmp(bm->op[i], m->op[i], i))
         dev_part_strct_entry(tsv, ".ptmmop", p->desc, m->desc, opcodename(i), opcode2str(m->op[i], i, !tsv), m->comments);
 
+    if(injct)
+      for(size_t i=0; i<sizeof meminj/sizeof*meminj; i++)
+        if(strcmp(meminj[i].mcu, p->desc) == 0 && strcmp(meminj[i].mem, m->desc) == 0)
+          dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc,
+            meminj[i].var, cfg_strdup("meminj", meminj[i].value), NULL);
+
     if(!tsv) {
       dev_cout(m->comments, ";", 0, 0);
       dev_info("    ;\n");
@@ -706,6 +733,12 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base) {
     }
   }
 
+  if(injct)
+    for(size_t i=0; i<sizeof ptinj/sizeof*ptinj; i++)
+      if(strcmp(ptinj[i].mcu, p->desc) == 0)
+        dev_part_strct_entry(tsv, ".pt", p->desc, NULL,
+          ptinj[i].var, cfg_strdup("ptinj", ptinj[i].value), NULL);
+
   if(!tsv) {
     dev_cout(p->comments, ";", 0, 0);
     dev_info(";\n");
@@ -742,7 +775,7 @@ void dev_output_pgm_part(int dev_opt_c, char *programmer, int dev_opt_p, char *p
 
 // -p */[dASsrcow*t]
 void dev_output_part_defs(char *partdesc) {
-  bool cmdok, waits, opspi, descs, astrc, strct, cmpst, raw, all, tsv;
+  bool cmdok, waits, opspi, descs, astrc, strct, cmpst, injct, raw, all, tsv;
   char *flags;
   int nprinted;
   AVRPART *nullpart = avr_new_part();
@@ -753,7 +786,7 @@ void dev_output_part_defs(char *partdesc) {
   if(!flags && !strcmp(partdesc, "*")) // Treat -p * as if it was -p */s
     flags = "s";
 
-  if(!*flags || !strchr("cdoASsrw*t", *flags)) {
+  if(!*flags || !strchr("cdoASsrw*ti", *flags)) {
     dev_info("%s: flags for developer option -p <wildcard>/<flags> not recognised\n", progname);
     dev_info(
       "Wildcard examples (these need protecting in the shell through quoting):\n"
@@ -772,6 +805,7 @@ void dev_output_part_defs(char *partdesc) {
       "       w  wd_... constants for ISP parts\n"
       "       *  all of the above except s and S\n"
       "       t  use tab separated values as much as possible\n"
+      "       i  inject assignments from source code table\n"
       "Examples:\n"
       "  $ avrdude -p ATmega328P/s\n"
       "  $ avrdude -p m328*/st | grep chip_erase_delay\n"
@@ -798,6 +832,7 @@ void dev_output_part_defs(char *partdesc) {
   strct = !!strchr(flags, 'S');
   cmpst = !!strchr(flags, 's');
   tsv   = !!strchr(flags, 't');
+  injct = !!strchr(flags, 'i');
 
 
   // Go through all memories and add them to the memory order list
@@ -834,7 +869,8 @@ void dev_output_part_defs(char *partdesc) {
       dev_part_strct(p, tsv,
         astrc? NULL:
         strct? nullpart:
-        p->parent_id && *p->parent_id? locate_part(part_list, p->parent_id): nullpart);
+        p->parent_id && *p->parent_id? locate_part(part_list, p->parent_id): nullpart,
+        injct);
 
     if(raw)
       dev_part_raw(p);