From 9b3762a812f2fd9b769d27a97721ac427ad91c6b Mon Sep 17 00:00:00 2001
From: Joerg Wunsch <j@uriah.heep.sax.de>
Date: Fri, 18 Sep 2020 21:52:12 +0000
Subject: [PATCH] patch #9963: UsbAsp 3 MHz patch for UsbAsp-flash firmware *
 usbasp.c: Implement 3 MHz clock option including capability check * usbasp.h:
 (Dito.)

Submitted by Marcin Miskiewic



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1446 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog |  7 +++++++
 NEWS      |  1 +
 usbasp.c  | 24 +++++++++++++++++++-----
 usbasp.h  |  2 ++
 4 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 849ab277..3239724c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2020-09-18  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	Submitted by Marcin Miskiewic
+	patch #9963: UsbAsp 3 MHz patch for UsbAsp-flash firmware
+	* usbasp.c: Implement 3 MHz clock option including capability check
+	* usbasp.h: (Dito.)
+
 2020-09-18  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	Submitted by Sven Schwermer:
diff --git a/NEWS b/NEWS
index 25fdf1df..5951533f 100644
--- a/NEWS
+++ b/NEWS
@@ -75,6 +75,7 @@ Current:
     patch #9818: correct typos in SVN rev 1429
     patch #9732: usbtiny_paged_load overflows buffer e.g. when reading EEPROM
     patch #9966: Add JTAGICE3 in UPDI mode
+    patch #9963: UsbAsp 3 MHz patch for UsbAsp-flash firmware
 
   * Internals:
     - New avrdude.conf keyword "family_id", used to verify SIB attributes
diff --git a/usbasp.c b/usbasp.c
index 21fbb187..101a4a3a 100644
--- a/usbasp.c
+++ b/usbasp.c
@@ -121,6 +121,7 @@ struct pdata
   unsigned int capabilities;
   int use_tpi;
   int section_e;
+  int sck_3mhz;
 };
 
 #define PDATA(pgm) ((struct pdata *)(pgm->cookie))
@@ -597,6 +598,9 @@ static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
     pdata->capabilities = 0;
 
   pdata->use_tpi = ((pdata->capabilities & USBASP_CAP_TPI) != 0 && (p->flags & AVRPART_HAS_TPI) != 0) ? 1 : 0;
+  // query support for 3 MHz SCK in UsbAsp-flash firmware
+  // https://github.com/nofeletru/UsbAsp-flash
+  pdata->sck_3mhz = ((pdata->capabilities & USBASP_CAP_3MHZ) != 0) ? 1 :0;
 
   if(pdata->use_tpi)
   {
@@ -863,6 +867,7 @@ static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
 /* The list of SCK frequencies in Hz supported by USBasp */
 static struct sckoptions_t usbaspSCKoptions[] = {
+  { USBASP_ISP_SCK_3000, 3000000 },
   { USBASP_ISP_SCK_1500, 1500000 },
   { USBASP_ISP_SCK_750, 750000 },
   { USBASP_ISP_SCK_375, 375000 },
@@ -908,14 +913,23 @@ static int usbasp_spi_set_sck_period(PROGRAMMER *pgm, double sckperiod)
 
     avrdude_message(MSG_NOTICE2, "%s: try to set SCK period to %g s (= %i Hz)\n", progname, sckperiod, sckfreq);
 
-    if (sckfreq >= usbaspSCKoptions[0].frequency) {
-      clockoption = usbaspSCKoptions[0].id;
-      usefreq = usbaspSCKoptions[0].frequency;
+    /* Check if programmer is capable of 3 MHz SCK, if not then ommit 3 MHz setting */
+    int i;
+    if (PDATA(pgm)->sck_3mhz) {
+      avrdude_message(MSG_NOTICE2, "%s: connected USBasp is capable of 3 MHz SCK\n",progname);
+      i = 0;
+    } else {
+      avrdude_message(MSG_NOTICE2, "%s: connected USBasp is not cabable of 3 MHz SCK\n",progname);
+      i = 1;
+    }
+    if (sckfreq >= usbaspSCKoptions[i].frequency) {
+      clockoption = usbaspSCKoptions[i].id;
+      usefreq = usbaspSCKoptions[i].frequency;
     } else {
 
       /* find clock option next to given clock */
-      int i;
-      for (i = 0; i < sizeof(usbaspSCKoptions) / sizeof(usbaspSCKoptions[0]); i++) {
+
+      for (; i < sizeof(usbaspSCKoptions) / sizeof(usbaspSCKoptions[0]); i++) {
         if (sckfreq >= usbaspSCKoptions[i].frequency - 1) { /* subtract 1 to compensate round errors */
           clockoption = usbaspSCKoptions[i].id;
           usefreq = usbaspSCKoptions[i].frequency;
diff --git a/usbasp.h b/usbasp.h
index 573d2b85..11f98293 100644
--- a/usbasp.h
+++ b/usbasp.h
@@ -42,6 +42,7 @@
 
 /* USBASP capabilities */
 #define USBASP_CAP_TPI    0x01
+#define USBASP_CAP_3MHZ   (1 << 24)   // 3 MHz SCK in UsbAsp-flash firmware
 
 /* Block mode flags */
 #define USBASP_BLOCKFLAG_FIRST    1
@@ -65,6 +66,7 @@
 #define USBASP_ISP_SCK_375    10  /* 375 kHz   */
 #define USBASP_ISP_SCK_750    11  /* 750 kHz   */
 #define USBASP_ISP_SCK_1500   12  /* 1.5 MHz   */
+#define USBASP_ISP_SCK_3000   13  /*   3 MHz   only UsbAsp-flash firmware*/
 
 /* TPI instructions */
 #define TPI_OP_SLD      0x20