b-parasite-esp32/resources.md
rbaron 850df22f1a Removes custom board lnker scripts
For now let's use adafruit_feather_nrf52832.
2021-02-11 18:29:44 +01:00

10 KiB

My development board

Articles

  • Great article about using Rust and Apache Mynewt, but also covers J-Link, ST-Link, openocd, unlocking the nrf52. Link on medium

nrf command line utilities

  • nrfjprog Used for programming hex files using the J-Link programmer.
  • nrfutil Used for DFU - device firmware update - via the USB port. No J-Link. This is what Adafruit uses for uploading code via USB. This is "higher level" and requires a pre-existing bootloader in the nrf52 chip that understands DFU. The Adafruit_nRF52_Bootloader is such a bootloader, which we can burn using nrfjprog + J-Link once. Adafruit has its own version, adafruit-nrfutil.

SWD vs. Bootloader vs. DFU

  • How nrfutil is used in the platformio nordicnrf52 package: link
  • Seems like we can use DFU if we install a DFU-enabled bootloader like the Adafruit_nRF52_Bootloader
  • Using the adafruit nrf52 bootloader with the E73-TBB link

Burning the Adafruit bootloader

  1. $ brew cask install nordic-nrf-command-line-tools -> Didn't work. I had to manually install the pkgs from nordic
  2. pip install intelhex
  3. PATH=$PATH:/Users/rbaron/.platformio/packages/framework-arduinoadafruitnrf52/tools/adafruit-nrfutil/macos make BOARD=feather_nrf52840_express all

Burning our custom bootloader

The error I was making was using a non-softdevice bootloader. The following works:

# Compile
$ PATH=$PATH:/Users/rbaron/.platformio/packages/framework-arduinoadafruitnrf52/tools/adafruit-nrfutil/macos make BOARD=e73_tbb all

# Flash (make sure you use the _s132_ hex file)
$ JAVA_HOME=/Users/rbaron/homebrew/Cellar/openjdk/15.0.1 nrfjprog --program _build/build-e73_tbb/e73_tbb_bootloader-0.4.0-2-g4ba802d_s132_6.1.1.hex --sectoranduicrerase -f nrf52 --reset

Now we can drop the JLink and use the USB serial for uploading/monitoring.

Uploading with nrfutil

$ ~/.platformio/packages/framework-arduinoadafruitnrf52/tools/adafruit-nrfutil/macos/adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0x00B7 --application .pio/build/e73-tbb/firmware.hex dfu-pkg.zip
Zip created at dfu-pkg.zip

$ ~/.platformio/packages/framework-arduinoadafruitnrf52/tools/adafruit-nrfutil/macos/adafruit-nrfutil dfu serial --package dfu-pkg.zip -p /dev/cu.usbserial-14330 -b 115200
Upgrading target on /dev/cu.usbserial-14330 with DFU package /Users/rbaron/dev/parasite/code/parasite/dfu-pkg.zip. Flow control is disabled, Dual bank, Touch disabled
########################################
########################################
########################################
########################################
########################################
#######################
Activating new firmware
Device programmed.

Linking

In platformio-core/tools/pioplatform.py:

if "build.ldscript" in board_config:
    env.Replace(LDSCRIPT_PATH=board_config.get("build.ldscript"))

In platformio-core/platformio.py:

# append into the beginning a main LD script
if env.get("LDSCRIPT_PATH") and not any("-Wl,-T" in f for f in env["LINKFLAGS"]):
    env.Prepend(LINKFLAGS=["-T", env.subst("$LDSCRIPT_PATH")])

The -T flag expects a path to a linker script, as per ld docs.

Frameworks, such as the nordicnrf52, contain boards definitions that specify the ldscript.

  1. For the adafruit_feather_nrf52832 board, we have:
"arduino":{
  "ldscript": "nrf52832_s132_v6.ld"
},

Which is defined here.

  1. For the nrf52_dk, we have:
"arduino":{
  "ldscript": "nrf52_xxaa.ld"
},

Which is the most common linker script, and is part of the nordic official SDK, it seems, available here. For reference, check out the linker for the Adafruit nRF52 Bootloader. Here you can see the memory map of the nRF52 Feather.

Same platform, different framework

Both the Feather nRF52832 and the Generic boards above point to the same platform, the nordicnrf52. Inside this platorm, there's a switch for selecting which framework to use, based on the board name, here:

if self.board_config(board).get("build.bsp.name",
                                            "nrf5") == "adafruit":
                self.frameworks["arduino"][
                    "package"] = "framework-arduinoadafruitnrf52"

What does each line in the linker mean?

Memory layout

The SoftDevice S132 spec specifies the layout as the soft device begins at addr 0x0 and the application code comes after it, at the address APP_CODE_BASE.

PWM

Analog to digital converter (ADC)

  • In nrf52-land, the ADC is called SSADC
  • Example in the sdk: in examples/peripheral/saadc/main.c
  • Docs from Adafruit. It uses Arduino's analogRead.

Resoultion

The default resolution is 10 bits (1024 values),

Reference value

The default reference is an internally supplied 3.6V. It seems like we woulld only be able to read values up to 3.6V. This might be enough if we're using a CR2032 coin cell, but might not if we use a LiPo (4.2V fully charged).

Question: what happens if Vcc < 3.6?

There is a possibility of using Vcc as a reference. Then I imagine 0 -> 0V; 1024 -> Vcc. This might be exactly what we want: In a PWM positive pulse, our RC_parasitic will rise to 0.63Vcc in R*C_para time. If we use Vcc as a reference for the ADC, I think we "cancel out" the Vcc factor.

  • How adafruit uses the Vcc reference: link
  • How arduino-nRF5 uses the Vcc refenrece: link

So in Arduino land, using AR_VDD4 does all we need: use nrf's SAADC_CH_CONFIG_REFSEL_VDD1_4 (Vcc/4 ref) and a gain of 4 (SAADC_CH_CONFIG_GAIN_Gain1_4). While connected via USB, with:

analogReference(AR_VDD4);
int sens_val = analogRead(kSensAnalogPin);

I'm getting ~680 when in the air; ~65 while holding the sensor. The default resolution is 10 bits, so 1024 -> 3.3V. On the scope, I'm reading the sensor output value to be 2.16V. This matches the value I'm reading: 1024/3.3 * 2.15 = 667. Nice.

Battery

  • CR2032 datasheet
    • 235 mAh (from 3.0V to 2.0V)
    • Typical discharge current: 0.19 mA -> 1200 hours

Battery monitoring

  • Good post on how to measure lipo batteries: link

BLE

  • BLE examples for platformio with nordicnrf52 platform: link
  • BLEPeripheral seems to be a popular library choice
  • nrf5 BLE examples are way more complicated than I need for now

OTA