I recently had a project using the Adafruit Feather nRF52840 Express to control a 2N2222 transistor being used as a high power switch. The nRF52840 SoC is a higher-end Bluetooth 5.2 SoC supporting Bluetooth Low Energy, Bluetooth mesh, NFC, Thread, and Zigbee. It has a 64MHz Arm Cortex-M4 with FPU, 1MB Flash, 256KB RAM and all the standard microcontroller features including UART, SPI, TWI, PDM, I2S, QSPI, PWM, and 12-bit ADCs. Adafruit has created a board support package for the Arduino development environment.
After building the code and making a test circuit with a 620 ohm base resistor, I measured the nRF52840 VOH and the voltage was much lower than expected. Reviewing the nRF52840 datasheet the IOH for standard drive is a minimum of 1mA and a maximum of 4mA. I was exceeding the GPIO pin guaranteed current drive capability.
The nRF52840 is an interesting microcontroller where you can control the GPIO drive between standard, high, and disconnect (open). You can specify both IOH and IOL and they can be different. The RW DRIVE parameter is set in the PIN_CNF[n] register as specified in the nRF52840 Product Specification v1.2. The high drive for a 3.3V VDD is a minimum of 6mA for both IOH and IOL.
First I needed to find the correct GPIO pin [n] value to set the drive parameters. Most of the parameters are set when creating the PWM object, but there is no method to set the RW DRIVE parameter. To find the correct pin number I needed to review variant.h and variant.cpp files in the directory containing the board support package …\packages\adafruit\hardware\nrf52\0.22.0\variants\feather_nrf52840_express.
I was using the Feather A0 pin, which is connected to the nRF52840 P0.04 pin. In variant.h file A0 is mapped to pin 14 (D14). From variant.cpp D14 is mapped to pin 4. This is the [n].
To set the RW DRIVE requires either writing directly to the register (NRF_GPIO->PIN_CNF = 0x203) or use a call to nrf_gpio_cnf with the desired parameters. See the file nrf_gpio.h for enum types and support functions. The following call was made to set VOH to high drive and VOL to standard drive (S0H1). Once this change was made the VOH was well within specification when turning the transistor switch on.
nrf_gpio_cfg(4, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0H1, NRF_GPIO_PIN_NOSENSE);