nickgammon/arduino_sketches

Options for Hex uploader to use same SPI bit banged port as Board Programmer

Closed this issue · 1 comments

The Atmega_Hex_Uploader uses a bit banged SPI port which differ from the Atmega_Board_programmer. The later uses the native SPI port.

When switching between the two there is the inconvenience for having to rewire everything.
I am looking for a solution to get Atmega_Board_Programmer to use the bit banged SPI port instead (pins 4-5-6-7).

I took the ino file then added the define line below:

// make true to use bit-banged SPI for programming
#define USE_BIT_BANGED_SPI true

Then I added definitions for the port:

#if USE_BIT_BANGED_SPI

  // bit banged SPI pins
  #ifdef __AVR_ATmega2560__
    // Atmega2560
    #if USE_ETHERNET_SHIELD
      const byte MSPIM_SCK = 3;  // port E bit 5
    #else
      const byte MSPIM_SCK = 4;  // port G bit 5
    #endif
    const byte MSPIM_SS  = 5;  // port E bit 3
    const byte BB_MISO   = 6;  // port H bit 3
    const byte BB_MOSI   = 7;  // port H bit 4
  #elif defined(__AVR_ATmega1284P__)
    // Atmega1284P
    const byte MSPIM_SCK = 11;  // port D bit 3
    const byte MSPIM_SS  = 12;  // port D bit 4
    const byte BB_MISO   = 13;  // port D bit 5
    const byte BB_MOSI   = 14;  // port D bit 6
  #else
    // Atmega328
    #if USE_ETHERNET_SHIELD
      const byte MSPIM_SCK = 3;  // port D bit 3
    #else
      const byte MSPIM_SCK = 4;  // port D bit 4
    #endif
    const byte MSPIM_SS  = 5;  // port D bit 5
    const byte BB_MISO   = 6;  // port D bit 6
    const byte BB_MOSI   = 7;  // port D bit 7
  #endif


  /*

  Connect target processor like this:

    D4: (SCK)   --> SCK as per datasheet (If using Ethernet shield, use D3 instead)
    D5: (SS)    --> goes to /RESET on target
    D6: (MISO)  --> MISO as per datasheet
    D7: (MOSI)  --> MOSI as per datasheet

    D9: 8 Mhz clock signal if required by target

  Connect SD card like this:

    D10: SS   (chip select)
    D11: MOSI (DI - data into SD card)
    D12: MISO (DO - data out from SD card)
    D13: SCK  (CLK - clock)

  Both SD card and target processor will need +5V and Gnd connected.

  */

  // for fast port access
  #ifdef __AVR_ATmega2560__
    // Atmega2560
    #define BB_MISO_PORT PINH
    #define BB_MOSI_PORT PORTH
    #if USE_ETHERNET_SHIELD
      #define BB_SCK_PORT PORTE   // Pin D3
    #else
      #define BB_SCK_PORT PORTG   // Pind D4
    #endif
    const byte BB_SCK_BIT = 5;
    const byte BB_MISO_BIT = 3;
    const byte BB_MOSI_BIT = 4;
  #elif defined(__AVR_ATmega1284P__)
    // Atmega1284P
    #define BB_MISO_PORT PIND
    #define BB_MOSI_PORT PORTD
    #define BB_SCK_PORT PORTD
    const byte BB_SCK_BIT = 3;
    const byte BB_MISO_BIT = 5;
    const byte BB_MOSI_BIT = 6;
  #else
    // Atmega328
    #define BB_MISO_PORT PIND
    #define BB_MOSI_PORT PORTD
    #define BB_SCK_PORT PORTD
    #if USE_ETHERNET_SHIELD
      const byte BB_SCK_BIT = 3;  // Pin D3
    #else
      const byte BB_SCK_BIT = 4;  // Pind D4
    #endif
    const byte BB_MISO_BIT = 6;
    const byte BB_MOSI_BIT = 7;
  #endif

  // control speed of programming
  const byte BB_DELAY_MICROSECONDS = 6;

#endif // USE_BIT_BANGED_SPI

And also added the function below:

#if USE_BIT_BANGED_SPI

  // Bit Banged SPI transfer
  byte BB_SPITransfer (byte c)
  {
    byte bit;

    for (bit = 0; bit < 8; bit++)
      {
      // write MOSI on falling edge of previous clock
      if (c & 0x80)
          BB_MOSI_PORT |= bit (BB_MOSI_BIT);
      else
          BB_MOSI_PORT &= ~bit (BB_MOSI_BIT);
      c <<= 1;

      // read MISO
      c |= (BB_MISO_PORT & bit (BB_MISO_BIT)) != 0;

     // clock high
      BB_SCK_PORT |= bit (BB_SCK_BIT);

      // delay between rise and fall of clock
      delayMicroseconds (BB_DELAY_MICROSECONDS);

      // clock low
      BB_SCK_PORT &= ~bit (BB_SCK_BIT);

      // delay between rise and fall of clock
      delayMicroseconds (BB_DELAY_MICROSECONDS);
      }

    return c;
    }  // end of BB_SPITransfer

#endif // USE_BIT_BANGED_SPI

This compiles correctly. However the ICSP programming mode fails

Compiled on May 24 2023 at 19:11:23 with Arduino IDE 10819.
Attempting to enter ICSP programming mode ......................................................
Failed to enter programming mode. Double-check wiring!
Type 'C' when ready to continue with another chip ...

Any idea how I could get this operational?

alright I got it to work.
Somewhere in the sketch there is a line

const byte RESET = 10; // --> goes to reset on the target board

That I had to change to

const byte RESET = 5; // --> goes to reset on the target board

This is just to make it work.
To do thing cleanly I take this should be written with some #if conditions with USE_BIT_BANGED_SPI.