nRF51 Espruino build problem

Posted on
Page
of 2
/ 2
Next
  • Hello,

    I've always thought the Nordic nRF chip looks to have lots of uses, and wondered about porting Espruino to it. I was very excited to discover that it looks as though lots has been done already.

    It looks as though it should run on the Adafruit Flora sewable BTLE module (https://www.adafruit.com/products/2487) - which has the 256k flash nrf51822 chip - Wearing a Javascript interpreter just sounds super geeky :-)

    I was curious to try building it and have a problem:

    NRF51822DK=1 SOFTDEVICE=1 BLE_INTERFACE=1 RELEASE=1 make

    ...gives:

    LD espruino_1v84.60_nrf51822.elf
    /home/colinp/espruino/Espruino/targetlib­s/nrf5x/nrf51_sdk/components/toolchain/g­cc/gcc_startup_nrf51.o: In function Reset_Handler': (.text+0x40): undefined reference toSystemInit'
    /usr/local/gcc-arm-none-eabi-4_8-2014q1/­bin/../lib/gcc/arm-none-eabi/4.8.3/../..­/../../arm-none-eabi/lib/armv6-m/crt0.o:­ In function _start': (.text+0x4e): undefined reference tomain'
    collect2: error: ld returned 1 exit status
    make: *** [espruino_1v84.60_nrf51822.elf] Error 1

    Main for this board appears to be in targets/nrf5x/main.c, which is defined in the Makefile. main.o appears, which implies it is being compiled, but not linked.

    I tried various hacks to get it to compile, and encountered different problems. When I got to the stage of patching the include path in the auto-generated gen/platform_config.h I figured I was probably doing something wrong.

    I thought perhaps nrf51 build had fallen out of use as nrf52 was in there. If I try to build for nrf52 using the command in README_Building.md I get a different error:

    NRF52832DK=1 RELEASE=1 make

    targets/nrf5x/jshardware.c:482:23: error: 'nrf_adc_config_t' undeclared (first use in this function)

    I'm using commit 6dbda86c of Friday 8th Jan 2016.

    I'm using gcc-arm-none-eabi-4_8-2014q1 (I can't remember where it came from) but I think this should be OK - the stm32 Espruino compiles fine.

    I get the problem even when using commit 904ca0ac8c19828 which is marked "nRF51 now working". This makes me think I'm doing something dumb.

    Am I missing some sort of Make flag or something?

    Thanks,

    Colin

  • Hi Colin,

    I'm afraid it's a compiler issue. I think 4.9 should work, but if not, go ingot the Makefile, search for where -flto is (outside of the ESP8266 stuff) and comment the two lines about link time optimisation. That should fix it..

    You don't need all the environment vars any more (did you read that somewhere? it should probably be corrected) - just do:

    NRF51822DK=1 RELEASE=1 make
    

    Once running, you can communicate at 9600 baud on the UART and can also connect via BLE and use Nordic's BLE UART app to control it/send code to it (you just need to add a newline to the end of each command :) )

    Hope that helps!

  • Hello,

    It did help very much. Thanks!

    I tried using gcc-arm-none-eabi-4_9-2015q1 and it compiled:

    arm-none-eabi-size espruino_1v84.60_nrf51822.elf
    text data bss dec hex filename
    119996 196 4820 125012 1e854 espruino_1v84.60_nrf51822.elf

    I'll need to wire up a flash programmer and I'll let you know how I get on. I have to admit that fiddling problems like this with gcc are what draws me to an easy to use development environment like Espruino!

    I might not get round to programming it for a while, but I'll let you know what happens. It looks like there is more to be added for the nrf51 so when I get time (which might not be for a while) I will see if I can add anything.

    Thanks,

    Colin

  • Hi Colin,

    That'd be great - thanks! Support for I2C is something that's be really useful :) There's no hardware SPI at the moment either, but Espruino does at least have software SPI.

    There's one gotcha at the moment, which is that (at least on the micro:bit) it doesn't run off battery power - I think it's related to the UART perhaps receiving random data, so it might be that if it doesn't work, you can get it going by pulling UART RX high, or ideally connecting a USB-Serial converter to it.

  • Hello,

    Some sort of progress (for a short period anyway)....

    I tried using the raspberry pi GPIO version of openocd to program the nrf51822, as described in:

    https://github.com/adafruit/Adafruit_nRF­51822_Flasher

    This successfully flashed the Adafruit files for the Flora module, so I figured I was good to restore in case of problems.

    I flashed the Espruino hex file I built with gcc4.9, which flashed and verified OK.

    I used the Nordic toolbox, and "Espruino NRF51822DK" appeared as a BTLE device, which looked promising.
    When I tried to connect using the Nordic nRF UART 2.0 a connection was made. When I tried entering text something obviously went wrong, as the UART app reported a "This device does not support the UART service" or similar error message, and closed the connection.

    I now seem unable to reprogram the device using openocd.

    pi@raspberrypi ~/Adafruit_nRF51822_Flasher $ sudo ./openocd-0.9.0/rpi_gpio/openocd -s openocd-0.9.0/scripts -f interface/raspberrypi-native.cfg -c "transport select swd" -c "set WORKAREASIZE 0" -f target/nrf51.cfg -c init -c "reset init" -c halt -c "nrf51 mass_erase" -c "program /tmp/espruino_1v84.60_nrf51822.hex verify" -c reset -c exit
    Open On-Chip Debugger 0.10.0-dev-00002-g3397eae (2015-06-24-16:08)
    Licensed under GNU GPL v2
    For bug reports, read
    	http://openocd.org/doc/doxygen/bugs.html­
    BCM2835 GPIO nums: swclk = 25, swdio = 24
    BCM2835 GPIO config: srst = 18
    srst_only separate srst_gates_jtag srst_push_pull connect_deassert_srst
    swd
    0
    cortex_m reset_config sysresetreq
    adapter speed: 1000 kHz
    Info : BCM2835 GPIO JTAG/SWD bitbang driver
    Info : SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)
    Info : clock speed 1006 kHz
    Info : SWD IDCODE 0x0bb11477
    Info : nrf51.cpu: hardware has 4 breakpoints, 2 watchpoints
    Error: timed out while waiting for target halted
    TARGET: nrf51.cpu - Not halted
    in procedure 'reset' 
    in procedure 'ocd_bouncer'
    

    Worse, the device doesn't seem to be advertising any more after power cycling. Perhaps it managed to slightly flash some firmware (I tried reflashing a few times so maybe it progressed slightly).

    There doesn't seem to be much on the module which would cause a problem (Schematic is at https://learn.adafruit.com/assets/25434), though I did have an FTDI 3v3 cable connected to its UART ports. I wonder if Espruino was driving a GPIO with opposite polarity to the FTDI chip which has upset things?

    Failing that, I suppose the other reason might be the pi GPIO bit bang being "a bit iffy". It looks as though it successfully recognises the SWD IDCODE - Googling 0x0bb11477 suggests a Cortex-M0 which is correct, and suggests things aren't completely dead.

    I actually have a JLink adapter from the older nrf51822 dev kit, but the pin pitch is so small I have no chance of soldering to it. This comes with a USB module with JLink and nrf51822 on, which would be perfect for debugging Espruino, but the chip is the older 128k flash/16k RAM version which I think might be a bit too small for Espruino.

    Has anyone else tried the Raspberry Pi GPIO bit bang method? Maybe I'd have better luck with a ST-Link or something instead. Of course, I'm hoping I haven't just simply fried the Pi or the BTLE module...

    Colin

  • Hello,

    I did some more investigations, trying a Nordic PCA10006 board which had SWD pins that I could solder onto the Raspberry Pi. I noticed it has the 256k flash, 16k ram variant (opposed to the 128k I originally thought). So I compiled with ram set to 16k, modifying boards/NRF51822DK.py and also setting variables to 100.

    The same thing happened - espruino programmed OK first time

    Info : SWD IDCODE 0x0bb11477
    Info : nrf51.cpu: hardware has 4 breakpoints, 2 watchpoints
    target state: halted
    target halted due to debug-request, current mode: Handler HardFault
    xPSR: 0xc1000003 pc: 0xfffffffe msp: 0xffffffd8
    Info : nRF51822-QFAA(build code: E0) 256kB Flash
    verified 210504 bytes in 4.054331s (50.704 KiB/s)
    ** Verified OK **

    ...then the next time

    Info : SWD IDCODE 0x0bb11477
    Info : nrf51.cpu: hardware has 4 breakpoints, 2 watchpoints
    Error: timed out while waiting for target halted
    TARGET: nrf51.cpu - Not halted

    Fortunately I was able to connect the JLink programmer to this board, and was able to reflash it. So I will assume that the problem is down to openocd or the GPIO bit bang. Not sure why it flashed OK with the Adafruit code running but not with Espruino.

    Having said that, I didn't get any device adverts appearing on my phone. Is it feasible for Espruino to run in a 16k RAM variant? I think the soft device uses about 8k which might not leave much for the JS interpreter. Developing on the board with JLink would be much easier.

    Colin

  • Hello,

    Following up to my own posts:

    I realised the JLink had an unpopulated connector, and sure enough it carries signals. So I was able to solder the Adafruit board onto the JLink connector and reflash the Adafruit firmware, and the board worked. Phew! So I'm going to assume that the pi openocd stuff isn't working reliably and put it aside for now.

    I built from a clean github clone:

    NRF51822DK=1 RELEASE=1 make

    I'm not getting any advertisements from the device however. JLink seems to report that it is flashing ~120kbytes, which is slightly more than the size reported by 'size' for the espruino elf file. I suspect this doesn't include the soft device.

    JLink flash report:

    Cortex-M0 identified.
    Target interface speed: 100 kHz
    J-Link>loadfile espruino_1v84.60_nrf51822.hex
    Downloading file [espruino_1v84.60_nrf51822.hex]...Info: J-Link: Flash download: Flash programming performed for 1 range (120832 bytes)
    Info: J-Link: Flash download: Total time needed: 19.748s (Prepare: 0.562s, Compare: 0.875s, Erase: 2.307s, Program: 15.940s, Verify: 0.005s, Restore: 0.057s)
    O.K.

    I tried manually loading the soft device - looks like it was already flashed - looks like JLink skips programming matching parts which explains the size.

    loadfile s110_nrf51_8.0.0_softdevice.hex
    Downloading file [s110_nrf51_8.0.0_softdevice.hex]...Info­: J-Link: Flash download: Flash download into internal flash skipped. Flash contents already match

    ...and tried manually flashing the .bin file just to be sure (.text segment starts at 0x18000 I believe)

    espruino_1v84.60_nrf51822.elf: file format elf32-littlearm
    SYMBOL TABLE:
    00018000 l d .text 00000000 .text

    J-Link>loadbin espruino_1v84.60_nrf51822.bin 0x18000
    Halting CPU for downloading file.
    Downloading file [espruino_1v84.60_nrf51822.bin]...Info: J-Link: Flash download: Flash programming performed for 2 ranges (113664 bytes)
    Info: J-Link: Flash download: Total time needed: 18.553s (Prepare: 0.678s, Compare: 0.192s, Erase: 2.630s, Program: 14.971s, Verify: 0.021s, Restore: 0.058s)
    O.K.
    J-Link>r
    Reset delay: 0 ms
    Reset type NORMAL: Resets core & peripherals via SYSRESETREQ & VECTRESET bit.
    J-Link>g (I believe runs the CPU)

    I might have to begin debugging to see why there are no advertisements. Very strange that the same build did advertise yesterday!

  • I've hit some problems with the micro:bit - it'll work when running from USB power, but not from battery.

    Right now I think it could be to do with the UART RX pin getting pulled low (and spamming the chip with 0 characters) but I'm really not sure. Is it possible that could be the problem you're having too?

    Espruino runs fine in 16kB RAM - but you might have to adjust the amount of variables it uses (copy from microbit, which I know works). It's just a bit limited by the amount of code you can write - at least until it gets optimised a bit :)

    PS. when you're posting up areas of code, please can you surround them with 3 backticks and a blank line before and after - like this - it makes it a whole lot easier to read :)

    When you get it working you might also be interested in this

    :)

  • Actually I just fixed that problem - so if you try now, it should work (hopefully!)

  • Hello,

    The Youtube video looks really nice.

    I modified boards.py and communication_interface.c for 16k and to use the flow control pins+hardware flow control and I can now at least get it to start up on the Nordic dev kit USB dongle (which is much nicer as it means I can develop on my laptop without accidentally pulling a pile of hastily soldered together debug cables off...)

    The serial shell appears to be working OK, but Bluetooth is unreliable. I can sometimes connect and it works, but other times connect with immediate disconnect. At least having a reliable programmer and serial port makes it much easier to begin to debug!

    Anyway - it looks like you've made lots of changes to the uart in your last commit so I'll update to that and see what happens...

    Oh - something else I discovered the other night should anyone else be reading this. The FTDI TTL 3v3 dongle only has 3v3 levels on its UART lines. The Vdd line is 5volts, NOT 3v3 as I thought. So it turns out I've verified the nrf51822 will operate at 5v supply. cough...

  • Great! It'd be good if you could share your BOARD.py for the devkit dongle at some point...

    I'd hope that now the uart has been fixed, hardware flow control may not actually be needed (I think a dead byte at startup was killing it) unless the USB dongle itself really cares.

    If it is, I guess it'll need some nRF-specific hack at the moment, as there's no way to specify flow control pins normally in Espruino.

    I wonder what's up with the BLE connection - that's been pretty good for me so far (although the Chromebook Web Bluetooth is a bit flakey!).

  • Hello,

    Flow control (or at least the RTS (or CTS?) pin being asserted) seems to be needed before the JLink dongle serial interface will transmit anything. To begin with I only got data from the console but couldn't send it anything and couldn't find the correct incantation to turn off flow control.

    It turns out that the Bluetooth flakiness was caused as both the "nRF toolbox" and "nRF UART v2.0" apps were running on my phone. It looks as though one of them was trying to reconnect in the background. I rebooted my phone to stop any services that were running, or in case the Android BTL stack was upset, and Bluetooth seems reliable now. I have noticed that after closing a connection it stops advertising and hence I cannot reconnect. Not sure if this is intentional or not.

    I'll try the Adafruit board later to see if it now works without a serial connection.

    In the meantime, for anyone interested, my quick hacks to get it working with the Nordic PCA10000 dongle are:

    Install JLink_Linux_V492_i386 and gcc-arm-none-eabi-4_9-2015q1-20150306-li­nux.tar.bz2 and add to PATH

    Change RAM size in boards.py to run with 16k RAM, as copied from MICROBIT.py:

    diff --git a/boards/NRF51822DK.py b/boards/NRF51822DK.py
    index 0ebc85e..a7be363 100644
    --- a/boards/NRF51822DK.py
    +++ b/boards/NRF51822DK.py
    @@ -23,7 +23,7 @@ info = {
      'default_console_tx' : "D9",
      'default_console_rx' : "D11",
      'default_console_baudrate' : "9600",
    - 'variables' : 200, # How many variables are allocated for Espruino to use. RAM will be overflowed if this number is too high and code won't compile.
    + 'variables' : 145, # How many variables are allocated for Espruino to use. RAM will be overflowed if this number is too high and code won't compile.
      'binary_name' : 'espruino_%v_nrf51822.bin',
      'build' : {
       'defines' : [
    @@ -36,13 +36,13 @@ chip = {
       'part' : "NRF51822",
       'family' : "NRF51",
       'package' : "QFN48",
    -  'ram' : 32,
    +  'ram' : 16,
       'flash' : 256,
    

    Hack serial port config to allow HW flow control:

    diff --git a/targets/nrf5x/jshardware.c b/targets/nrf5x/jshardware.c
    index e30afc8..5ae69fa 100644
    --- a/targets/nrf5x/jshardware.c
    +++ b/targets/nrf5x/jshardware.c
    @@ -400,9 +400,9 @@ void jshUSARTSetup(IOEventFlags device, JshUSARTInfo *inf) {
       const app_uart_comm_params_t comm_params = {
           pinInfo[inf->pinRX].pin,
           pinInfo[inf->pinTX].pin,
    -      UART_PIN_DISCONNECTED,
    -      UART_PIN_DISCONNECTED,
    -      APP_UART_FLOW_CONTROL_DISABLED,
    +      8, //UART_PIN_DISCONNECTED,
    +      10, //UART_PIN_DISCONNECTED,
    +      APP_UART_FLOW_CONTROL_ENABLED, //APP_UART_FLOW_CONTROL_DISABLED,
           inf->parity!=0, // TODO: ODD or EVEN parity?
           baud
       };
    

    I created a script to allow easier flashing - save as 'flash.jlink':

    device nrf51822
    speed 1000
    w4 4001e504 1
    loadfile espruino_1v84.70_nrf51822.hex
    r
    g
    q
    

    build and flash using:

    NRF51822DK=1 RELEASE=1 make && JLinkExe flash.jlink
    

    and access the serial console provided by the JLink using (on Linux):

    screen /dev/ttyACM0 9600
    
  • I tried flashing the same hex file onto the Adafruit board. Terminal over Bluetooth now seems to work so I'll assume the fix you posted earlier has done the trick. The serial Rx and Tx lines (P0.9 and 0.11) are unconnected.

    I have to reset it after every terminal connection as it stops advertising. I had earmarked other things to do today so had better get around to them, but I'll try to have a look at that later.

  • That'd be great - thanks! Strange about the advertising... it's possible it drops it, but I hadn't noticed anything.

    To get it running with serial on the Adafruit dongle, try editing the BOARD.py file and changing default_console_rx and so on - you might want to disable your flow control I guess?

    just a thought, but might it be that Linux was actually asking the JLink to use hardware flow control? If you use minicom on linux you can:

    Ctrl-A then O
    'Serial Port Setup'
    F -> change from hardware flow control
    
  • ...miss Espruino in Partnership and Software sections in https://en.wikipedia.org/wiki/Micro_Bit's entry. If Python is there, why not Javascript...

  • Very good point - I'll come up with a micro:bit page on Espruino.com and will then try and submit an update. I might see if I can get any proof of 'official support' or the Wikipedia admins might take it out - they don't like people dropping links to products into it :)

  • I thought previously about flow control being set in Linux - I tried disabling it with screen but no change. Minicom was actually worse - I found it appeared to hang quite often and I had to kill -9 it. I decided to stick with hardware flow control and screen (that I knew worked previously rather than trying to debug problems with the hardware dongle/Linux serial). I'm actually using OS X with Linux in VMWare, so I might try native OS X serial sometime.

    The schematic for the Adafruit board shows it uses P0.9 and P0.11 for serial, which is already defined in the NRF51822DK.py file . As it has the 32k RAM variant of the chip I guess it should work with no changes.

    I had a look into the advertising, and it definitely stops advertising (or at least Nordic UART 2.0 does not see it to allow reconnecting after disconnection). I noticed that running "NRF.wake()" from the terminal allowed it to be seen again and reconnect.

    I made the following change:

    diff --git a/libs/bluetooth/jswrap_bluetooth.c b/libs/bluetooth/jswrap_blue
    index 6ecd36c..b8aec46 100644
    --- a/libs/bluetooth/jswrap_bluetooth.c
    +++ b/libs/bluetooth/jswrap_bluetooth.c
    @@ -261,6 +261,7 @@ static void on_ble_evt(ble_evt_t * p_ble_evt) {
           case BLE_GAP_EVT_DISCONNECTED:
             m_conn_handle = BLE_CONN_HANDLE_INVALID;
             jsiSetConsoleDevice( DEFAULT_CONSOLE_DEVICE );
    +        jswrap_nrf_bluetooth_startAdvertise();
             break;
    

    I'm not 100% sure if this is correct as I don't really understand the Nordic UART states enough. I had a look around, and the Nordic code at:

    https://github.com/NordicSemiconductor/n­rf51-UART-examples/blob/master/ble_app_u­art_low_power/ble_app_uart_low_power_sla­ve/main.c

    calls advertising_start() on handling BLE_GAP_EVT_DISCONNECTED...looks to be the same as my change.

  • Ok, thanks - just added.

    I think the idea was that you'd connect and then it's still connectable, it's just not advertising that it is? But I guess that may not work...

  • MicroBit page is now up: http://www.espruino.com/MicroBit

  • Great news! Entry model for Espruino...

    @Gordon, did you ever think to put communication directly on pico? it has the space when moving the 0.05" pins as 0.1" into the rows to make PICO a 2x14 (28) pin JEDEC format 'thing'.

    I know that in the past I suggested an after-production, user defined combination gives more flexibility, IoT things just need a wireless connection... but as a next option, it would be a good option...

  • You mean to make a new board with BLE on it?

    I'm considering it - but the 16kB chip in the micro:bit has only 200 variables available, so is only really useful as a toy. I can use the 32kB chip which should give around 1000, which would be pretty good - but it's still pushing the limits.

    Nordic are releasing the nRF52 - which is much more powerful, and I'm definitely interested in doing something with that (especially as it will be able to do IPv6 over BLE).

    For the moment I'm actually considering just getting some pre-made iBeacons (possibly like this: http://www.alibaba.com/product-detail/No­rdic-nrf51822-Chip-Button-iBeacon-Long_6­0407442183.html) programmed up with Espruino. It'd be relatively cheap and easy to do, and would be quite fun.

  • I think you're right in that it is certainly possible to pair with a device and then reconnect to the service without advertising and I notice some Bluetooth devices have a specific "pair" button to initiate this. The Nordic UART app only seems to be able to connect to devices which advertise, so maybe it is best to keep advertising in for now if that is the sort of app that people are likely to use - at least initially until something else is written. Maybe it is a "depends on the use case" decision.

    I saw a project: https://github.com/pauloborges/blessed which looks interesting - an open source BTLE stack for nrf51822. It would be interesting to see if the softdevice could be replaced with something simpler to give extra flash and RAM, and could potentially allow the device to talk to nrf24l01 style radios as well (which I think it should be capable of doing). If I have got my head around the acronym-soup that is BTLE the GAP and GATT layers would need implementing to allow something like a UART to work. More studying required...

  • Yes, I think there's quite a bit of work involved to reimplement Nordic's softdevice - and then there's the issue of certification. As I understand it, it's only locked down so that it's easier to BT certify your devices - you wouldn't actually be able to sell anything developed using an OSS stack.

    Nordic developers are actually super helpful - if enough people pushed them about developing a totally cut-down bluetooth stack they might do it.

    I went to a Nordic developer day a few months ago, and it sure sounded like you could use the nRF51822 as a nRF24 clone without needing any of the softdevice at all. That'd be pretty cool for home automation stuff.

  • Out of curiosity I flashed the Nordic sniffer software and watched the trace between my phone and Espruino using Wireshark. Outside of the datalink layer that is implemented by the project I linked to there doesn't seem to be a huge amount - the L2CAP "layer" just seems to be 2 bytes of packet saying "This is L2CAP" followed by the GAP "layer?" which is a single byte opcode of 'read','write' etc. I don't particularly fancy reimplementing it - just curious.

    I notice the devices continually send a "I have nothing to say" packet between them every few milliseconds when connected and idle. For a low energy protocol this seems like a strange choice.

    If I remember correctly, the Nordic SDK has an example of using the radio raw which I think can work with an nRF24. http://dmitry.gr/index.php?r=05.Projects­&proj=11.%20Bluetooth%20LE%20fakery is interesting too - he sends out BTLE advertisements using an nRF24 - I guess similar code would work on nrf51x.

  • Wow, interesting - maybe it isn't that hard after all. I'd assumed that timing would be a bit of an issue (making sure that you only turned on the receiver at the correct times). But almost certainly the softdevice has loads of bloat that isn't needed.

    I love the idea of sending out advertisements with nRF24, that's very cool...

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

nRF51 Espruino build problem

Posted by Avatar for ColinP @ColinP

Actions