From 97ae2c8c423f64de4ea4c1c64558f518608109a3 Mon Sep 17 00:00:00 2001 From: per1234 Date: Tue, 1 Sep 2020 21:17:15 -0700 Subject: [PATCH 1/2] Fix SPISettings name collision in ArduinoISP sketch when compiled in bitbanged SPI mode for board using ArduinoCore-API When using bit banged SPI, which the sketch did when compiled for any architecture other than AVR, a `SPISettings` class was declared by the sketch. At the time the sketch was written, it was reasonable to expect this would not cause a name collision, since SPI.h is not `#include`d when doing bit banged SPI. However, since then a `SPISettings` class has been declared in [ArduinoCore-API's HardwareSPI.h](https://github.com/arduino/ArduinoCore-API/blob/932c7c7d4d4d334b10484284cc846672ad59607c/api/HardwareSPI.h#L37), causing the ArduinoISP sketch to not compile for any board whose core uses ArduinoCoreAPI (currently Arduino Mega AVR Boards, "Arduino nRF528x Boards (Mbed OS]", and "Arduino Mbed OS Boards (nRF52840 / STM32H747)"): ``` /github/workspace/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino:191:27: error: reference to 'SPISettings' is ambiguous void beginTransaction(SPISettings settings) { ^~~~~~~~~~~ /github/workspace/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino:167:7: note: candidates are: class SPISettings class SPISettings { ^~~~~~~~~~~ In file included from /github/home/.arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/api/ArduinoAPI.h:31:0, from /github/home/.arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/Arduino.h:23, from /github/workspace/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino:39: /github/home/.arduino15/packages/arduino/hardware/megaavr/1.8.6/cores/arduino/api/HardwareSPI.h:37:7: note: class arduino::SPISettings class SPISettings { ^~~~~~~~~~~ ``` The fix is to use the `ARDUINO_API_VERSION` macro defined by ArduinoCore-API to detect when it is in use and make the bitbanged SPI code use the `SPISettings` class from ArduinoCore-API in this case. --- examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino b/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino index 8186a0f..16d2862 100644 --- a/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino +++ b/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino @@ -164,19 +164,23 @@ void pulse(int pin, int times); #define SPI_MODE0 0x00 +#if !defined(ARDUINO_API_VERSION) // A SPISettings class is declared by ArduinoCore-API class SPISettings { public: // clock is in Hz - SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) : clock(clock) { + SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) : clockFreq(clock) { (void) bitOrder; (void) dataMode; }; - private: - uint32_t clock; + uint32_t getClockFreq() const { + return clockFreq; + } - friend class BitBangedSPI; + private: + uint32_t clockFreq; }; +#endif // !defined(ARDUINO_API_VERSION) class BitBangedSPI { public: @@ -189,7 +193,7 @@ class BitBangedSPI { } void beginTransaction(SPISettings settings) { - pulseWidth = (500000 + settings.clock - 1) / settings.clock; + pulseWidth = (500000 + settings.getClockFreq() - 1) / settings.getClockFreq(); if (pulseWidth == 0) { pulseWidth = 1; } From 98ce44479e7e37193265906b0847983b459eb54c Mon Sep 17 00:00:00 2001 From: per1234 Date: Tue, 1 Sep 2020 21:37:13 -0700 Subject: [PATCH 2/2] Fix name collision in ArduinoISP sketch with function declared by Mbed OS The name collision between the variable named "error" in the ArduinoISP sketch and a function of that name declared by Mbed OS causes compilation of the sketch to fail for boards that use the "Arduino nRF528x Boards (Mbed OS)" or "Arduino Mbed OS Boards (nRF52840 / STM32H747)" cores. --- .../11.ArduinoISP/ArduinoISP/ArduinoISP.ino | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino b/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino index 16d2862..43a91d3 100644 --- a/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino +++ b/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino @@ -233,7 +233,7 @@ void setup() { } -int error = 0; +int ISPError = 0; int pmode = 0; // address for reading and writing, set by 'U' command unsigned int here; @@ -293,7 +293,7 @@ void loop(void) { digitalWrite(LED_PMODE, LOW); } // is there an error? - if (error) { + if (ISPError) { digitalWrite(LED_ERR, HIGH); } else { digitalWrite(LED_ERR, LOW); @@ -344,7 +344,7 @@ void empty_reply() { SERIAL.print((char)STK_INSYNC); SERIAL.print((char)STK_OK); } else { - error++; + ISPError++; SERIAL.print((char)STK_NOSYNC); } } @@ -355,7 +355,7 @@ void breply(uint8_t b) { SERIAL.print((char)b); SERIAL.print((char)STK_OK); } else { - error++; + ISPError++; SERIAL.print((char)STK_NOSYNC); } } @@ -494,7 +494,7 @@ void write_flash(int length) { SERIAL.print((char) STK_INSYNC); SERIAL.print((char) write_flash_pages(length)); } else { - error++; + ISPError++; SERIAL.print((char) STK_NOSYNC); } } @@ -523,7 +523,7 @@ uint8_t write_eeprom(unsigned int length) { unsigned int start = here * 2; unsigned int remaining = length; if (length > param.eepromsize) { - error++; + ISPError++; return STK_FAILED; } while (remaining > EECHUNK) { @@ -564,7 +564,7 @@ void program_page() { SERIAL.print((char) STK_INSYNC); SERIAL.print(result); } else { - error++; + ISPError++; SERIAL.print((char) STK_NOSYNC); } return; @@ -608,7 +608,7 @@ void read_page() { length += getch(); char memtype = getch(); if (CRC_EOP != getch()) { - error++; + ISPError++; SERIAL.print((char) STK_NOSYNC); return; } @@ -624,7 +624,7 @@ void read_page() { void read_signature() { if (CRC_EOP != getch()) { - error++; + ISPError++; SERIAL.print((char) STK_NOSYNC); return; } @@ -647,7 +647,7 @@ void avrisp() { uint8_t ch = getch(); switch (ch) { case '0': // signon - error = 0; + ISPError = 0; empty_reply(); break; case '1': @@ -656,7 +656,7 @@ void avrisp() { SERIAL.print("AVR ISP"); SERIAL.print((char) STK_OK); } else { - error++; + ISPError++; SERIAL.print((char) STK_NOSYNC); } break; @@ -706,7 +706,7 @@ void avrisp() { universal(); break; case 'Q': //0x51 - error = 0; + ISPError = 0; end_pmode(); empty_reply(); break; @@ -718,13 +718,13 @@ void avrisp() { // expecting a command, not CRC_EOP // this is how we can get back in sync case CRC_EOP: - error++; + ISPError++; SERIAL.print((char) STK_NOSYNC); break; // anything else we will return STK_UNKNOWN default: - error++; + ISPError++; if (CRC_EOP == getch()) { SERIAL.print((char)STK_UNKNOWN); } else {