nrf-device-setup
is a Javascript module which ensures that Nordic devices are
programmed with configured firmwares. There are currently two categories of devices
which are programmed by different frameworks, one is programmed by JLink debugger,
the other is DFU'd (Device Firmware Upgrade) via USB CDC ACM transport.
By using this module the caller does not need to use pc-nrfjprog-js and pc-nrf-dfu-js directly,
only the device/firmware configuration shall be provided.
This module is primarily used by the nRF Connect framework and related nRF Connect apps.
The following devices are supported:
- JLink:
- PCA10028 nRF51 Development Kit
- PCA10031 nRF51 Dongle
- PCA10040 nRF52 Development Kit
- PCA10056 nRF52 Development Kit
- USB SDFU:
- PCA10059 nRF52 Dongle
$ npm install nrf-device-setup
Due to dependency on pc-nrfjprog-js, installation of lower level tools and libraries are required, for details please refer to required setup section.
In order to access Nordic USB devices specific drivers must be installed on Windows, which are automatically installed by nRF Connect for Desktop (starting from version 2.4). The drivers can be found here.
Linux requires correct permissions to access these devices. For this purpose please install udev rules from nrf-udev repository, follow instructions there.
import { setupDevice } from 'nrf-device-setup';
setupDevice(selectedDevice, configuration) // returns a Promise
.then(device => {
console.log(device);
});
In the above example selectedDevice
and also the device
as the resolved result is
an item from the deviceMap
of nrf-device-lister.
Each of these items have a serialNumber
of some kind which must identify the device regardless
of the means it is interacted with.
const configuration = {
jprog: {...}, // will be applied if selectedDevice is a JLink device
dfu: {...}, // will be applied if selectedDevice is a USB SDFU device
needSerialport: true, // after successful DFU serialport is expected
// These promises are not required for nRF Connect apps, they provide a way
// to handle user interaction when confirmation or choice is to be made, see example below
promiseConfirm,
promiseChoice,
};
For JLink devices pc-nrfjprog-js is used to check for fwVersion
at fwIdAddress
, and
in case of a mismatch the referenced fw
is flashed to the device. These values are grouped
under the device type or board version or family key which is resolved by specificity.
The keys are case-insensitive.
configuration.jprog = {
NRF52832_xxAA_REV2: {...},
// fallback if exact device type not specified
NRF52832: {...},
// fallback if device type not specified
PCA10040: {...},
// fallback to family if board version not specified
nrf52: {
fw: path.resolve(__dirname, 'fw/customfirmware-for-nrf52.hex'),
// fwVersion can be either a fixed string or an object:
fwVersion: 'magicstring',
fwVersion: {
length: 11, // number of bytes to read and provide to validator callback
validator: data => {
// return true if expected data is found
// return false if expected data is not found
return (data === 'magicstring');
}
},
fwIdAddress: 0x2000,
},
nrf51: {...},
}
For USB SDFU devices pc-nrf-dfu-js is used to perform the DFU.
configuration.dfu = {
pca10056: {
application: path.resolve(__dirname, 'fw/customfirmware-for-pca10056.hex'),
// softdevice is optional, depends on application firmware
softdevice: path.resolve(__dirname, 'fw/softdevice.hex'),
semver: 'my-fw-name 1.0.0+dfuJan-01-2018-01-01-01',
// DFU initPacket related parameters, optional, listed values are default:
params: {
hwVersion: 52,
fwVersion: 4,
sdReq: [],
sdId: [],
}
}
}
PCA10059 is a nRF52840 dongle which does not have a JLink debugger, so the USB device that the operating system sees depends on the firmware that is currently running on the Nordic chip.
This can be either a bootloader or an application firmware.
The bootloader provides a USB device with vendor ID 0x1915
and product ID 0x521f
.
This device has a USB CDC ACM (serialport) interface which handles the DFU operation.
In case you need to manually trigger the bootloader, press the RESET button on the dongle.
The dongle is in application mode if it has an application to run and is simply plugged in, or after a successful DFU operation.
In application mode the visible USB device depends on the application firmware. For further documentation please refer to the Nordic SDK.
In application mode it is expected that the visible USB device has a DFU trigger interface.
This interface provides a semver
string which identifies the application firmware currently running,
and is also able to reset the device into bootloader.
In case the semver
doesn't match the bootloader will be triggered.
Changing between bootloader and application also implies that the USB device is detached and attached, so there is an underlying functionality based on nrf-device-lister which looks for the newly attached USB device and tries to match by its serialNumber.
import { setupDevice } from 'nrf-device-setup';
setupDevice(
selectedDevice,
{
jprog: {
nrf52: {
fw: path.resolve(__dirname, 'fw/rssi-10040.hex'),
fwVersion: 'rssi-fw-1.0.0',
fwIdAddress: 0x2000,
},
},
dfu: {
pca10056: {
application: path.resolve(__dirname, 'fw/rssi-10056.hex'),
semver: 'rssi_cdc_acm 2.0.0+dfuMar-27-2018-12-41-04',
},
},
needSerialport: true,
// promise returning function that resolves with true/false
promiseConfirm: async message => (await inquirer.prompt([{
type: 'confirm',
name: 'isConfirmed',
message,
default: false,
}])).isConfirmed,
// promise returning function that resolves with an element of the input array
promiseChoice: async (message, choices) => (await inquirer.prompt([{
type: 'list',
name: 'choice',
message,
choices,
}])).choice,
}
) // => Promise with device that is running RSSI fw and has a serialport ready to be opened.
The project comes with automated integration tests in the test
directory. In order to run the test, at least one nRF51 device, nRF52 device, and nRF52840 dongle must be attached to the PC. To run the tests:
npm test
To run tests for only one device type, include the name of the test file e.g.
npm test -- nrf51
To include the tests for the nRF52840 dongle, you have to set the environment variable DONGLE_SERIAL_NUMBER
to the serial number of your dongle e.g.
DONGLE_SERIAL_NUMBER=E5530B54CD8C npm test