Same Bootloader, same softdevice different board different pins

Can someone walk me through how to deal with a situation that has the same bootloader, same softdevice but different board, different pins on PlatformIO?

I tried on the Arduino forum but getting no information.

I have the Nano 33 BLE working on PlatformIO but I also have the same bootloader installed on the very cheap Nordic nRF52840 dongle. (Used the Particle Debugger SWD to drag and drop .hex file bootloaders onto nRF52840 boards).

So I need to know on PlatformIO how to setup varients for slightly different boards. When the pins are just re-assigned this is easy, but I am lost at how to assign pins that are not defined with the original Arduino Nano 33 BLE setup.

Any suggestions would be appreciated.

So I found this file in the arduino github and it looks like for the arduino nano 33 BLE that all Port0 and port1 pins are pre-defined with constants like “P0_13” for pin 13 which is the arduino built in LED. I just replaced 13 wtih P0_13 and it compiled. Hopefully that means every pin can be accessed from code by simply using the Pin definition. P1_7 etc. Looks like you could also use codes like p0 up to p47 but that is a data abstraction that adds confusion. I think I will just use pin labels like P1_12 etc.

typedef enum {
PinDef(0 , 0), // P0_0 = 0...
PinDef(0 , 1),
PinDef(0 , 2),
PinDef(0 , 3),
PinDef(0 , 4),
PinDef(0 , 5),
PinDef(0 , 6),
PinDef(0 , 7),
PinDef(0 , 8),
PinDef(0 , 9),
PinDef(0 , 10),
PinDef(0 , 11),
PinDef(0 , 12),
PinDef(0 , 13),
PinDef(0 , 14),
PinDef(0 , 15),
PinDef(0 , 16),
PinDef(0 , 17),
PinDef(0 , 18),
PinDef(0 , 19),
PinDef(0 , 20),
PinDef(0 , 21),
PinDef(0 , 22),
PinDef(0 , 23),
PinDef(0 , 24),
PinDef(0 , 25),
PinDef(0 , 26),
PinDef(0 , 27),
PinDef(0 , 28),
PinDef(0 , 29),
PinDef(0 , 30),
PinDef(0 , 31),

PinDef(1 , 0), //P1_1 = 32...
PinDef(1 , 1),
PinDef(1 , 2),
PinDef(1 , 3),
PinDef(1 , 4),
PinDef(1 , 5),
PinDef(1 , 6),
PinDef(1 , 7),
PinDef(1 , 8),
PinDef(1 , 9),
PinDef(1 , 10),
PinDef(1 , 11),
PinDef(1 , 12),
PinDef(1 , 13),
PinDef(1 , 14),
PinDef(1 , 15),

// Port0
p0  = P0_0,
p1  = P0_1,
p2  = P0_2,
p3  = P0_3,
p4  = P0_4,
p5  = P0_5,
p6  = P0_6,
p7  = P0_7,
p8  = P0_8,
p9  = P0_9,
p10 = P0_10,
p11 = P0_11,
p12 = P0_12,
p13 = P0_13,
p14 = P0_14,
p15 = P0_15,
p16 = P0_16,
p17 = P0_17,
p18 = P0_18,
p19 = P0_19,
p20 = P0_20,
p21 = P0_21,
p22 = P0_22,
p23 = P0_23,
p24 = P0_24,
p25 = P0_25,
p26 = P0_26,
p27 = P0_27,
p28 = P0_28,
p29 = P0_29,
p30 = P0_30,
p31 = P0_31,

// Port1
p32 = P1_0,
p33 = P1_1,
p34 = P1_2,
p35 = P1_3,
p36 = P1_4,
p37 = P1_5,
p38 = P1_6,
p39 = P1_7,
p40 = P1_8,
p41 = P1_9,
p42 = P1_10,
p43 = P1_11,
p44 = P1_12,
p45 = P1_13,
p46 = P1_14,
p47 = P1_15,

I also found this bit of definitions for the particle Argon which describes RGBred as NRF_PORT_0, 13 which on the arduino should simple be P0_13

Just need to start testing things out. Can’t seem to find pin assignments for the Nordic nRF52840 USB dongle or the makerdiary dongle but that should just take some time.

static Hal_Pin_Info s_pin_map[TOTAL_PINS] = {
/* D0 / SDA      - 00 */ { NRF_PORT_0, 26, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* D1 / SCL      - 01 */ { NRF_PORT_0, 27, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* D2 /          - 02 */ { NRF_PORT_1, 1,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 3,                 0,                8, EXTI_CHANNEL_NONE},
/* D3 /          - 03 */ { NRF_PORT_1, 2,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 3,                 1,                8, EXTI_CHANNEL_NONE},
/* D4            - 04 */ { NRF_PORT_1, 8,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 1,                 0,                8, EXTI_CHANNEL_NONE},
/* D5            - 05 */ { NRF_PORT_1, 10, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 1,                 1,                8, EXTI_CHANNEL_NONE},
/* D6            - 06 */ { NRF_PORT_1, 11, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 1,                 2,                8, EXTI_CHANNEL_NONE},
/* D7            - 07 */ { NRF_PORT_1, 12, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 0,                 0,                8, EXTI_CHANNEL_NONE},
/* D8            - 08 */ { NRF_PORT_1, 3,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 1,                 3,                8, EXTI_CHANNEL_NONE},
/* D9            - 09 */ { NRF_PORT_0, 6,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* D10           - 10 */ { NRF_PORT_0, 8,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* D11           - 11 */ { NRF_PORT_1, 14, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* D12           - 12 */ { NRF_PORT_1, 13, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* D13           - 13 */ { NRF_PORT_1, 15, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* A5            - 14 */ { NRF_PORT_0, 31, PIN_MODE_NONE, PF_NONE, 7,                3,                 2,                8, EXTI_CHANNEL_NONE},
/* A4            - 15 */ { NRF_PORT_0, 30, PIN_MODE_NONE, PF_NONE, 6,                3,                 3,                8, EXTI_CHANNEL_NONE},
/* A3            - 16 */ { NRF_PORT_0, 29, PIN_MODE_NONE, PF_NONE, 5,                2,                 0,                8, EXTI_CHANNEL_NONE},
/* A2            - 17 */ { NRF_PORT_0, 28, PIN_MODE_NONE, PF_NONE, 4,                2,                 1,                8, EXTI_CHANNEL_NONE},
/* A1            - 18 */ { NRF_PORT_0, 4,  PIN_MODE_NONE, PF_NONE, 2,                2,                 2,                8, EXTI_CHANNEL_NONE},
/* A0            - 19 */ { NRF_PORT_0, 3,  PIN_MODE_NONE, PF_NONE, 1,                2,                 3,                8, EXTI_CHANNEL_NONE},
/* MODE BUTTON   - 20 */ { NRF_PORT_0, 11, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* RGBR          - 21 */ { NRF_PORT_0, 13, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 0,                 1,                8, EXTI_CHANNEL_NONE},
/* RGBG          - 22 */ { NRF_PORT_0, 14, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 0,                 2,                8, EXTI_CHANNEL_NONE},
/* RGBB          - 23 */ { NRF_PORT_0, 15, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, 0,                 3,                8, EXTI_CHANNEL_NONE},
/* TX1           - 24 */ { NRF_PORT_1, 5,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* RX1           - 25 */ { NRF_PORT_1, 4,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* CTS1          - 26 */ { NRF_PORT_1, 6,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* RTS1          - 27 */ { NRF_PORT_1, 7,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* ESPBOOT       - 28 */ { NRF_PORT_0, 16, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* ESPEN         - 29 */ { NRF_PORT_0, 24, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* HWAKE         - 30 */ { NRF_PORT_0, 7,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* ANTSW1        - 31 */ { NRF_PORT_0, 2,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* ANTSW2        - 32 */ { NRF_PORT_0, 25, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* BATT          - 33 */ { NRF_PORT_0, 5,  PIN_MODE_NONE, PF_NONE, 3,                PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* PWR           - 34 */ { NRF_PORT_0, 12, PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
/* CHG           - 35 */ { NRF_PORT_1, 9,  PIN_MODE_NONE, PF_NONE, ADC_CHANNEL_NONE, PWM_INSTANCE_NONE, PWM_CHANNEL_NONE, 8, EXTI_CHANNEL_NONE},
};



So here is the Makerdiary nRF52840 USB dongle pinout diagram. So “P0.10” on the diagram should be programmable with the Arduino IDE as “P0_10”

And for the Nordic nRF52840 USB dongle it looks like on this diagram the pins are labelled “0.11” which on Arduino would be “P0_11”

image

Got a lot of testing to do.

So today I loaded this code which shows A0 in the serial monitor and flashes the on-board LED onto multiple nRF52840 boards.


// Default Nano33BLE
//#define LED_BUILTIN  P0_13  // Default (13u) P0_13
//#define A0 P0_4             // Default A0 = P0_4


// Makerdiary nRF52840 USB Dongle
//#define LED_BUILTIN  P0_24  //  P0_23 RED LED, P0_24 BLUE LED    
//#define A0 P0_2             //  A0 P0_2        

// Nordic nRF52840 USB Dongle
#define LED_BUILTIN  P0_6  //  P0_6 Green LED, P0_8 RED LED    
#define A0 P0_2             //  A0 P0_2   not really sure      


// Particle Argon Xenon probably similar.
//#define LED_BUILTIN  P1_12  //  D7 board LED   P1_12 
//#define A0 P0_3             //   A0 P0_3        



void setup(){  
  
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  
}


void loop() {

  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (5.0 / 1023.0);
  Serial.print("blink4 fast, A0 Voltage: --> ");
  Serial.println(voltage);

  
  digitalWrite(LED_BUILTIN, HIGH);   
  delay(100);                      
  digitalWrite(LED_BUILTIN, LOW);    
  delay(100);                    

  
  digitalWrite(LED_BUILTIN, HIGH);   
  delay(100);                      
  digitalWrite(LED_BUILTIN, LOW);    
  delay(100);                    
  digitalWrite(LED_BUILTIN, HIGH);   
  delay(100);                      
  digitalWrite(LED_BUILTIN, LOW);    
  delay(3000);                     
}

And it worked on all my boards. I did try a weird port for the Nordic nRF52840 USB Dongle and it bricked it and was very dificult to reload the bootloader but it worked also.

Do you mean patching framework files? See Redirecting...

Thanks @ivankravets I will look into that technique but also will look into doing a custom board https://github.com/platformio/platform-nxplpc/tree/develop/examples/mbed-custom-target

I am always looking for the easiest approach, so was hoping I could just load a variants.h file somehow, assign specific pins for each board, and go from there. Unfortunately on Arduino it looks like the variants.cpp file is hard coded with the pin definitions so I will probably have to use your advanced scripting technique.

https://docs.platformio.org/en/latest/projectconf/advanced_scripting.html#override-package-files

Here is the Arduino Nano33BLE version 1.1.3 variant.cpp file

#include "Arduino.h"

PinDescription g_APinDescription[] = {
  // D0 - D7
  P1_3,  NULL, NULL,     // D0/TX
  P1_10, NULL, NULL,     // D1/RX
  P1_11, NULL, NULL,     // D2
  P1_12, NULL, NULL,     // D3
  P1_15, NULL, NULL,     // D4
  P1_13, NULL, NULL,     // D5
  P1_14, NULL, NULL,     // D6
  P0_23,  NULL, NULL,     // D7

  // D8 - D13
  P0_21, NULL, NULL,     // D8
  P0_27, NULL, NULL,     // D9
  P1_2,  NULL, NULL,     // D10
  P1_1,  NULL, NULL,     // D11/MOSI
  P1_8,  NULL, NULL,     // D12/MISO
  P0_13, NULL, NULL,     // D13/SCK/LED

  // A0 - A7
  P0_4,  NULL, NULL,     // A0
  P0_5,  NULL, NULL,     // A1
  P0_30, NULL, NULL,     // A2
  P0_29, NULL, NULL,     // A3
  P0_31, NULL, NULL,     // A4/SDA
  P0_2,  NULL, NULL,     // A5/SCL
  P0_28, NULL, NULL,     // A6
  P0_3,  NULL, NULL,     // A7

  // LEDs
  P0_24, NULL, NULL,     // LED R
  P0_16, NULL, NULL,     // LED G
  P0_6,  NULL, NULL,     // LED B
  P1_9,  NULL, NULL,     // LED PWR

  P0_19, NULL, NULL,     // INT APDS

  // PDM
  P0_17, NULL, NULL,     // PDM PWR
  P0_26, NULL, NULL,     // PDM CLK
  P0_25, NULL, NULL,     // PDM DIN

  // Internal I2C
  P0_14, NULL, NULL,     // SDA2
  P0_15, NULL, NULL,     // SCL2

  // Internal I2C
  P1_0,  NULL, NULL,     // I2C_PULL
  P0_22, NULL, NULL,     // VDD_ENV_ENABLE
};

extern "C" {
  unsigned int PINCOUNT_fn() {
    return (sizeof(g_APinDescription) / sizeof(g_APinDescription[0]));
  }
}

#include "nrf_rtc.h"

void initVariant() {
  // turn power LED on
  pinMode(LED_PWR, OUTPUT);
  digitalWrite(LED_PWR, HIGH);

  // Errata Nano33BLE - I2C pullup is on SWO line, need to disable TRACE
  // was being enabled by nrfx_clock_anomaly_132
  CoreDebug->DEMCR = 0;
  NRF_CLOCK->TRACECONFIG = 0;

  // FIXME: bootloader enables interrupt on COMPARE[0], which we don't handle
  // Disable it here to avoid getting stuck when OVERFLOW irq is triggered
  nrf_rtc_event_disable(NRF_RTC1, NRF_RTC_INT_COMPARE0_MASK);
  nrf_rtc_int_disable(NRF_RTC1, NRF_RTC_INT_COMPARE0_MASK);

  // FIXME: always enable I2C pullup and power @startup
  // Change for maximum powersave
  pinMode(PIN_ENABLE_SENSORS_3V3, OUTPUT);
  pinMode(PIN_ENABLE_I2C_PULLUP, OUTPUT);

  digitalWrite(PIN_ENABLE_SENSORS_3V3, HIGH);
  digitalWrite(PIN_ENABLE_I2C_PULLUP, HIGH);
 
  NRF_PWM_Type* PWM[] = {
    NRF_PWM0, NRF_PWM1, NRF_PWM2
#ifdef NRF_PWM3
    ,NRF_PWM3
#endif
  };

  for (unsigned int i = 0; i < (sizeof(PWM)/sizeof(PWM[0])); i++) {
    PWM[i]->ENABLE = 0;
    PWM[i]->PSEL.OUT[0] = 0xFFFFFFFFUL;
  } 
}

#ifdef SERIAL_CDC

static void utox8(uint32_t val, uint8_t* s) {
  for (int i = 0; i < 16; i=i+2) {
    int d = val & 0XF;
    val = (val >> 4);

    s[15 - i -1] = d > 9 ? 'A' + d - 10 : '0' + d;
    s[15 - i] = '\0';
  }
}

uint8_t getUniqueSerialNumber(uint8_t* name) {
  #define SERIAL_NUMBER_WORD_0  NRF_FICR->DEVICEADDR[1]
  #define SERIAL_NUMBER_WORD_1  NRF_FICR->DEVICEADDR[0]

  utox8(SERIAL_NUMBER_WORD_0, &name[0]);
  utox8(SERIAL_NUMBER_WORD_1, &name[16]);

  return 32;
}

void _ontouch1200bps_() {
  __disable_irq();
  NRF_POWER->GPREGRET = DFU_MAGIC_SERIAL_ONLY_RESET;
  NVIC_SystemReset();
}

#endif


Might as well include the Arduino Nano33BLE Version 1.1.3 pins_arduino.h file here as well


#pragma once
#include "mbed_config.h"
#include <stdint.h>
#include <macros.h>

#ifndef __PINS_ARDUINO__
#define __PINS_ARDUINO__

// Frequency of the board main oscillator
#define VARIANT_MAINOSC (32768ul)

// Master clock frequency
#define VARIANT_MCK     (64000000ul)

// Pins
// ----

// Number of pins defined in PinDescription array
#ifdef __cplusplus
extern "C" unsigned int PINCOUNT_fn();
#endif
#define PINS_COUNT           (PINCOUNT_fn())
#define NUM_DIGITAL_PINS     (21u)
#define NUM_ANALOG_INPUTS    (7u)
#define NUM_ANALOG_OUTPUTS   (0u)

// LEDs
// ----
#define PIN_LED     (13u)
#define LED_BUILTIN PIN_LED
#define LEDR        (22u)
#define LEDG        (23u)
#define LEDB        (24u)
#define LED_PWR     (25u)

// Analog pins
// -----------
#define PIN_A0 (14u)
#define PIN_A1 (15u)
#define PIN_A2 (16u)
#define PIN_A3 (17u)
#define PIN_A4 (18u)
#define PIN_A5 (19u)
#define PIN_A6 (20u)
#define PIN_A7 (21u)
static const uint8_t A0  = PIN_A0;
static const uint8_t A1  = PIN_A1;
static const uint8_t A2  = PIN_A2;
static const uint8_t A3  = PIN_A3;
static const uint8_t A4  = PIN_A4;
static const uint8_t A5  = PIN_A5;
static const uint8_t A6  = PIN_A6;
static const uint8_t A7  = PIN_A7;
#define ADC_RESOLUTION 12

/*
 * Serial interfaces
 */
// Serial (EDBG)
#define PIN_SERIAL_RX (1ul)
#define PIN_SERIAL_TX (0ul)

// SPI
#define PIN_SPI_MISO  (12u)
#define PIN_SPI_MOSI  (11u)
#define PIN_SPI_SCK   (13u)
#define PIN_SPI_SS    (10u)

static const uint8_t SS   = PIN_SPI_SS;   // SPI Slave SS not used. Set here only for reference.
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK  = PIN_SPI_SCK;

// Wire
#define PIN_WIRE_SDA        (18u)
#define PIN_WIRE_SCL        (19u)

#define PIN_WIRE_SDA1       (30u)
#define PIN_WIRE_SCL1       (31u)

#define PIN_ENABLE_SENSORS_3V3     (32u)
#define PIN_ENABLE_I2C_PULLUP      (33u)

#define PIN_INT_APDS (26u)

// PDM Interfaces
// ---------------
#define PIN_PDM_PWR	 (27)
#define PIN_PDM_CLK	 (28)
#define PIN_PDM_DIN	 (29)

// These serial port names are intended to allow libraries and architecture-neutral
// sketches to automatically default to the correct port name for a particular type
// of use.  For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
//
// SERIAL_PORT_MONITOR        Port which normally prints to the Arduino Serial Monitor
//
// SERIAL_PORT_USBVIRTUAL     Port which is USB virtual serial
//
// SERIAL_PORT_LINUXBRIDGE    Port which connects to a Linux system via Bridge library
//
// SERIAL_PORT_HARDWARE       Hardware serial port, physical RX & TX pins.
//
// SERIAL_PORT_HARDWARE_OPEN  Hardware serial ports which are open for use.  Their RX & TX
//                            pins are NOT connected to anything by default.
#define SERIAL_PORT_USBVIRTUAL      SerialUSB
#define SERIAL_PORT_MONITOR         SerialUSB
#define SERIAL_PORT_HARDWARE        Serial1
#define SERIAL_PORT_HARDWARE_OPEN   Serial1


// Mbed specific defines
#define SERIAL_HOWMANY		1
#define SERIAL1_TX			(digitalPinToPinName(PIN_SERIAL_TX))
#define SERIAL1_RX			(digitalPinToPinName(PIN_SERIAL_RX))

#define SERIAL_CDC			1
#define HAS_UNIQUE_ISERIAL_DESCRIPTOR
#define BOARD_VENDORID		0x2341
#define BOARD_PRODUCTID		0x805a
#define BOARD_NAME			"Nano 33 BLE"

#define DFU_MAGIC_SERIAL_ONLY_RESET   0xb0

#define I2C_SDA				(digitalPinToPinName(PIN_WIRE_SDA))
#define I2C_SCL				(digitalPinToPinName(PIN_WIRE_SCL))
#define I2C_SDA1			(digitalPinToPinName(PIN_WIRE_SDA1))
#define I2C_SCL1			(digitalPinToPinName(PIN_WIRE_SCL1))

#define SPI_MISO			(digitalPinToPinName(PIN_SPI_MISO))
#define SPI_MOSI			(digitalPinToPinName(PIN_SPI_MOSI))
#define SPI_SCK				(digitalPinToPinName(PIN_SPI_SCK))

#define digitalPinToPort(P)		(digitalPinToPinName(P)/32)

uint8_t getUniqueSerialNumber(uint8_t* name);
void _ontouch1200bps_();

#endif //__PINS_ARDUINO__


So I thought the Arduino would map ports P0_0, P0_1 …P0_31, P1_0…P1_15 to specific numbers that correspond to specific pins on the arduino Nano 33 BLE but was surprised after running this code, to get the following very boring output:

  
  Serial.print("P0_0: ");
  Serial.println(P0_0);
 
  Serial.print("P0_1: ");
  Serial.println(P0_1);
 
  Serial.print("P0_2: ");
  Serial.println(P0_2);


etc, etc, etc


THE FOLLOWING LIST IS NOT USEFUL AND ACTUALLY CONFUSES THE ENTIRE SITUATION. NOT SURE WHY ARDUINO HAS IT PROGRAMMED INTO THEIR CODE.

P0_0: 0
P0_1: 1
P0_2: 2
P0_3: 3
P0_4: 4
P0_5: 5
P0_6: 6
P0_7: 7
P0_8: 8
P0_9: 9
P0_10: 10
P0_11: 11
P0_12: 12
P0_13: 13
P0_14: 14
P0_15: 15
P0_16: 16
P0_17: 17
P0_18: 18
P0_19: 19
P0_20: 20
P0_21: 21
P0_22: 22
P0_23: 23
P0_24: 24
P0_25: 25
P0_26: 26
P0_27: 27
P0_28: 28
P0_29: 29
P0_30: 30
P0_31: 31
P1_0: 32
P1_1: 33
P1_2: 34
P1_3: 35
P1_4: 36
P1_5: 37
P1_6: 38
P1_7: 39
P1_8: 40
P1_9: 41
P1_10: 42
P1_11: 43
P1_12: 44
P1_13: 45
P1_14: 46
P1_15: 47

THE ABOVE LIST IS NOT USEFUL AND ACTUALLY CONFUSES THE ENTIRE SITUATION. NOT SURE WHY ARDUINO HAS IT PROGRAMMED INTO THEIR CODE.

So a number between 0 and 47 represents every GPIO pin on the nRF52840 SOC? Hopefully that means I should be able to set up a “for” loop that tests all 0-47 pins and then see the response from each pin on whatever board I am using. Perhaps make an LED flash that communicates which number it is flashing. A long flash for pin numbers divisible by 5, short flash for individual numbers:

pin 3 = 3 short flashes,
pin 6 = 1 long, 1 short,
pin 11 = 2 long 1 short

pin 44 = 8 long, 4 short.

This should make it really easy to brick boards, LOL.

Can anybody think of any pins I should not set as output. I think I tried P1_06 on my nordic nrf52840 usb dongle which I thought was the user button and bricked it.

Here is an image for the nano33Ble which uses the uBlox version of the nrf52840 SOC

and here is the nordic

sorry about the image quality can’t seem to find better images.

Reminder of the question. Can anyone think of pins that I should not set as output and try various flashes (setting the pin high and low) so I can connect an LED to the pin and see which one it is on my various boards.

The info you’re after is available without needing to probe using an LED. Just find the corresponding pin on whatever board your running the software on. Most boards have pinouts to make that easy. You already showed it for the Nordic dongle. For the two arduino nRF52840 boards (the BLE33 Sense and the regular BLE33), it would be:


and

For the adafruit nRF52840 feather you can find the pin mapping shown on the schematic:

If the different boards are exposing different pins, then either you loose access to the pins that aren’t exposed or you’ve got work to do to force a re-mapping to the available pins at the software level. You won’t be getting that for free. Or get a full-on development board, like the Nordic SDK or maybe roll-your-own more cheaply, which has all the pins exposed, and then you can mix and match your software more easily.

To illustrate, I did a couple minimalist breakout boards for the nRF52832:

and

You could fairly easily do something similar for the nRF52840 in order to cheaply gain access to all the pins, again for the purpose of mixing/matching or trialing different software’s, if that’s what you’re wanting to do.

1 Like

So today I ran a fun little program that serial output the pin number from 0 to 47 and then flashed that pin. I ran it on a Particle Argon (same pins as the Xenon) that has the Arduino bootloader. I hooked up a few LED’s and waited and watched. Here is the code.


//#include <Arduino.h>
// 13 LED arduino   3 for argon


void setup()
{
  Serial.begin(9600);  
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  pinMode(3, OUTPUT);

}

void loop(){
  
  Serial.println("Start");   

  for (int myLoop=0; myLoop <= 47; myLoop++){ 
    if (myLoop == 34 || myLoop == 35 || myLoop == 36   ){ 
      Serial.print("Pin #: ");   
      Serial.print(myLoop);   
      Serial.println(" possible reset"); 
    } else {
      pinMode(myLoop, OUTPUT); 
      Serial.print("Start Pin #: ");   
      Serial.print(myLoop);   
      digitalWrite(3, HIGH);
      digitalWrite(myLoop, HIGH);
      delay(1000); 
      digitalWrite(3, LOW);  
      digitalWrite(myLoop, LOW);  
      delay(200);     
      digitalWrite(3, HIGH);
      digitalWrite(myLoop, HIGH);
      delay(1000); 
      digitalWrite(3, LOW);
      digitalWrite(myLoop, LOW);
      Serial.println(" end.");     
      delay(2000);    
      pinMode(myLoop, INPUT); // back to default input
    }
  }

  Serial.println("End.");   
  delay(7000);
}


And here is the results for the Particle Argon/Xenon

And here is what I should get for for the Nano 33 BLE Sense. Ignore the “u” or “ul” they are not relevant.


What I find interesting is that these boards are in agreement for the Port numbers but not in agreement from my previous test that showed the port numbers increasing chronologically. So at least this data makes some sense.

The following Makerdiary Dognle does not match up as well, but I did find the pins for a few of the locations.

And here is the Nordic nRF52840 USB Dongle with the Arduino Nano33BLE pins that are working

So without assigning any brand new pins just changing the pre-defined Arduino Nano 33 BLE pin assignments. This is my summary so far.

Once again, if anyone knows how to define pins from scratch, I could probably get a few more pins working on the other boards.

Arduino Name Arduino Pin # Port Particle Xenon/Argon Nordic
TX 0 P1.03
RX 1 P1.10
D2 2 P1.11 D6
D3 3 P1.12 D7 User LED (blue)
D4 4 P1.15 SCK(D14) Pin1.15
D5 5 P1.13 MOSI(D12) Pin1.13
D6 6 P1.14 MISO(D11)
D7 7 P0.09 Causes RESET
D8 8 P0.10 Causes RESET
D9 9 P0.27 SCL/D1
D10 10 P1.02 D3
D11 11 P1.01 D2
D12 12 P1.08 D4
D13 13 P0.13 RED LED Pin0.13
A0 14 P0.04 A1(D18)
A1 15 P0.05
A2 16 P0.30 A4(D15) (User LED orange)
A3 17 P0.29 A3(D16) Pin0.29
A4 18 P0.31 A5(D14)
A5 19 P0.02 Pin0.02
A6 20 P0.28 A2(D17)
A7 21 P0.03 A0(D19)
22 P0_24 LED Red Pin0.24
23 P0_16 LED Green
24 P0_6 LED Blue LED1
25 P1_9 LED Power LED2
26 P0_19 PIN_INT_APDS Causes RESET
27 P0_17 PIN_PDM_PWR Pin0.17
28 P0_26 PIN_PDM_CLK SDA/D0
29 P0_25 PIN_PDM_DIN Causes RESET
30 P0_14 PIN_WIRE_SDA1 GREEN LED
31 P0_15 PIN_WIRE_SCL1 BLE LED
32 P1_0 PIN_ENABLE_SENSORS_3V3
33 P0_22 PIN_ENABLE_I2C_PULLUP
34 RESET
35 RESET Causes RESET
36 RESET Causes RESET
37
38
39
40
41
42
43
44
45
46
47

Just trashed this post as I made a logic error.

To make a long story short: have similiar problem:
I have installed adafruit drduino bootloader , for Arduino nano 33BLE

https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases

Within plattform io it works only if used boarddefinotion for adafruit featherexpress nrf52840.

As a result is uses same pinmap, bevause pinmap for arduino is diferent you have to use ovveriude technique here to or overwrite nrf52840 boarddef permanantly.

BecaUSE I WILL USE BOTH BOARDS THAT IS NOT AN OPTION

@hpssjellis @Ruppie would you have modify memory sections in the linker script and the source code and recompile a given bootloader when being used for a different board because of the differences in the hardware specs (RAM and Storage), additonal addons like SD card storage for OTA DFU (Adafruit support OTA DFU but using an additional SD Card)?

What Parameters should be looked for when using a bootloader to port to different boards?

1 Like