• Hi,

    i have successfully compiled an Espruino 2V22 binary for the NRF52840-DK using the NRF52840DK.py board definition file.
    However if i try to compile without bluetooth i get the following errors:

    targets/nrf5x/jshardware.c: In function 'jshInit':
    targets/nrf5x/jshardware.c:987:3: error: implicit declaration of function 'softdevice_sys_evt_handler_set' [-Werror=implicit-function-declaration]
      987 |   softdevice_sys_evt_handler_set(jsh_sys_e­vt_handler);
            |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    targets/nrf5x/jshardware.c:1005:5: error: 'ret' undeclared (first use in this function)
     1005 |     ret = app_usbd_power_events_enable();
             |     ^~~
    

    any advice on how to get espruino working on the NRF52840DK without Bluetooth?


    1 Attachment

  • oh, looks like nobody tested this combination, at least 52832/SDK12 worked some time ago, hopefully the fix won't be too hard. Anyway, why do you need it? I have a patch with something like NRF.stop()/start() where I can turn softdevice completely off and later back on and it seems to work with Nordic 52840 dongle, would that help?

  • First of all thanks for your reply.
    The idea was to compile a minimal binary with only the Espruino core functionality to reduce flash usage. If softdevice is not needed necessarily for this I could try to compile without softdevice entirely.

  • Ah, OK, so that won't help you. Softdevice takes over hardware when enabled and breaks precise timing, so after NRF.stop() one can freely poke radio and other registers that are protected when softdevice is enabled and also interrupts go directly to the application and some reserved hardware is free to use. So that is not the reason for you.

    Looks like the issue goes deeper, it seems to be it is not that much supported now. I just tried build for NRF52832DK with bluetooth off and it breaks in one place

    diff --git a/src/jswrap_process.c b/src/jswrap_process.c
    index b25720ff5..60f1e3870 100644
    --- a/src/jswrap_process.c
    +++ b/src/jswrap_process.c
    @@ -155,7 +155,7 @@ JsVar *jswrap_process_env() {
     [#ifndef](https://forum.espruino.com/sea­rch/?q=%23ifndef) SAVE_ON_FLASH
       // Pointer to a list of predefined exports - eventually we'll get rid of the array above
       jsvObjectSetChildAndUnLock(obj, "EXPTR", jsvNewFromInteger((JsVarInt)(size_t)expo­rtPtrs));
    -#ifdef NRF5X
    +#if defined(NRF5X) && defined(BLUETOOTH)
       extern uint32_t app_ram_base;
       if (app_ram_base)
         jsvObjectSetChildAndUnLock(obj, "APP_RAM_BASE", jsvNewFromInteger((JsVarInt)app_ram_base­));
    

    but then it still links softdevice into binary so no big flash saving happens, that would need different linker script which is not there (and never was?).

    I made such linker script now and yet it needs Makefile tunings as it still tries to merge softdevice in (and fails), anyway I quickly hacked that and produced a hex file, I wonder if it even starts in your board? attached is hex file built with SDK12 but I cannot test it right now. it should run both on 52832 and 52840 (but uses only 64K ram and 512K flash) and takes over whole device - no SoftDevice or bootloader

    if you want, you can try it, if it even starts and you get espruino console on serial it is promising

    I may look into this soon for 52840/SDK15 as I plan to try Enhanced ShockBurst radio protocol in Espruino with 52840 dongle and need USB which is not in SDK12

    But anyway, it looks like running without softdevice is not really there and probably never was, without Bluetooth != without softdevice.


    1 Attachment

  • But anyway, it looks like running without softdevice is not really there and probably never was, without Bluetooth != without softdevice.

    Yes, checked more and when BLUETOOTH library is disabled it does not mean that softdevice is not needed. Some code always expects softdevice to be present - at least the flash erasing/writing code like jshFlashErasePages and jshFlashWrite in jshardware.c calls softdevice methods (that work even if softdevice and bluetooth is not enabled at startup)

    https://github.com/espruino/Espruino/blo­b/52352efac4f8f40976a4d268a0a074ad15251b­29/targets/nrf5x/jshardware.c#L2483
    https://github.com/espruino/Espruino/blo­b/52352efac4f8f40976a4d268a0a074ad15251b­29/targets/nrf5x/jshardware.c#L2673

    So no need to try that hex above, most probably it won't work at all or at least flash storage writing won't work.

    Also here it is hardcoded that softdevice is always present
    https://github.com/espruino/Espruino/blo­b/52352efac4f8f40976a4d268a0a074ad15251b­29/make/family/NRF52.make#L109

    So basically it is doable to remove softdevice dependency but needs some work. What can be done easily is to just remove BLUETOOTH to trim the espruino binary down but softdevice still needs to be there for now.

    TO fix the error you are having with 52840DK/SDK15 you can try this change

    diff --git a/targets/nrf5x/jshardware.c b/targets/nrf5x/jshardware.c
    index 879942b42..8a7299953 100644
    --- a/targets/nrf5x/jshardware.c
    +++ b/targets/nrf5x/jshardware.c
    @@ -93,6 +93,8 @@ void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) {
     [#if](https://forum.espruino.com/search/­?q=%23if) NRF_SD_BLE_API_VERSION<5
     [#include](https://forum.espruino.com/se­arch/?q=%23include) "softdevice_handler.h"
     [#else](https://forum.espruino.com/searc­h/?q=%23else)
    +#include "nrf_sdh.h"
    +#include "nrf_sdh_soc.h"
     [#include](https://forum.espruino.com/se­arch/?q=%23include) "nrfx_spim.h"
     [#endif](https://forum.espruino.com/sear­ch/?q=%23endif)
    
    @@ -984,7 +986,13 @@ void jshInit() {
     [#else](https://forum.espruino.com/searc­h/?q=%23else) // !BLUETOOTH
       // because the code in bluetooth.c will call jsh_sys_evt_handler for us
       // if we were using bluetooth
    +#ifdef SOFTDEVICE_PRESENT
    +#if NRF_SD_BLE_API_VERSION<5
       softdevice_sys_evt_handler_set(jsh_sys_e­vt_handler);
    +#else
    +     NRF_SDH_SOC_OBSERVER(m_soc_observer, 1, jsh_sys_evt_handler, NULL);
    +#endif
    +#endif
     [#endif](https://forum.espruino.com/sear­ch/?q=%23endif)
    

    It builds for me with that but don't have any device to test around me now.

  • Thanks for the detailed explanation!
    The hex file you provided indeed does not run on the NRF52840DK. But i tried your fixes in jshardware.c and they worked. Even tho i got a linker error here (undefined reference to app_ram_base):
    https://github.com/espruino/Espruino/blo­b/edc64ce1ab231c608110797546ffa9d4457454­25/src/jswrap_process.c#L159

    I just added defines to ignore these lines if bluetooth is disabled.

    diff --git a/src/jswrap_process.c b/src/jswrap_process.c
    index b25720f..288fb93 100644
    --- a/src/jswrap_process.c
    +++ b/src/jswrap_process.c
    @@ -156,9 +156,11 @@ JsVar *jswrap_process_env() {
       // Pointer to a list of predefined exports - eventually we'll get rid of the array above
       jsvObjectSetChildAndUnLock(obj, "EXPTR", jsvNewFromInteger((JsVarInt)(size_t)expo­rtPtrs));
     [#ifdef](https://forum.espruino.com/sear­ch/?q=%23ifdef) NRF5X
    +  [#ifdef](https://forum.espruino.com/sear­ch/?q=%23ifdef) BUETOOTH
       extern uint32_t app_ram_base;
       if (app_ram_base)
         jsvObjectSetChildAndUnLock(obj, "APP_RAM_BASE", jsvNewFromInteger((JsVarInt)app_ram_base­));
    +  [#endif](https://forum.espruino.com/sear­ch/?q=%23endif)
     [#endif](https://forum.espruino.com/sear­ch/?q=%23endif)
     [#endif](https://forum.espruino.com/sear­ch/?q=%23endif)
       return obj;
    

    It compiles and runs on the NRF52840DK and is the desired result i was looking for.
    I think removing Softdevice entirely would save a lot more memory but it is not needed for my application.
    Thanks alot!

  • Does flash writing work too? You can test by creating one file via Storage API or uploading file via IDE. The jsh_sys_evt_handler mainly handles waiting for flash operations to finish so if it does not work properly it may be stuck at writing.

  • No this unfortunately does not work.
    I get an InternalError: Timeout on jshFlashWrite if i write to a file.
    But if i try to read the same file afterwards, i can obtain the contents of it with no errors.

  • Yes, I thought so. I was afraid the code

    [#if](https://forum.espruino.com/search/­?q=%23if) NRF_SD_BLE_API_VERSION<5
       softdevice_sys_evt_handler_set(jsh_sys_e­vt_handler);
    [#else](https://forum.espruino.com/searc­h/?q=%23else)
         NRF_SDH_SOC_OBSERVER(m_soc_observer, 1, jsh_sys_evt_handler, NULL);
    [#endif](https://forum.espruino.com/sear­ch/?q=%23endif)
    

    actually does not work well when softdevice is disabled and both those parts should probably be removed. Attached is something I use in my version with NRF.stop()/start(). In my experience when softdevice is off the events do not come and those same sd_flash_xx calls block and directly return success/error without invoking the handler.


    1 Attachment

  • It is actually documented here https://infocenter.nordicsemi.com/topic/­com.nordic.infocenter.s132.api.v3.0.0/gr­oup___n_r_f___s_o_c___f_u_n_c_t_i_o_n_s.­html?cp=5_7_3_9_2_7_2_9#ga8b49f2e72e9729­1aecc18ce396956eed

    If the SoftDevice is enabled: This call initiates the flash access
    command, and its completion will be communicated to the application
    with exactly one of the following events:

    NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully
    completed. NRF_EVT_FLASH_OPERATION_ERROR - The command could not be
    started.

    If the SoftDevice is not enabled no event will be generated,
    and this call will return NRF_SUCCESS when the write has been
    completed

    so I think registering jsh_sys_evt_handler above when BLUETOOTH is not defined is actually not needed, all it does now is here
    https://github.com/espruino/Espruino/blo­b/52352efac4f8f40976a4d268a0a074ad15251b­29/targets/nrf5x/jshardware.c#L638

  • Now i understand what is happening. So the lines in
    https://github.com/espruino/Espruino/blo­b/52352efac4f8f40976a4d268a0a074ad15251b­29/targets/nrf5x/jshardware.c#L984
    are not needed at all, because there are no events generated.
    I used your suggested changes from #9 and that works so far for writing to flash.
    Thanks again for your help!

  • So the lines ...
    are not needed at all, because there are no events generated.

    Yes, I think it is there just in case there are more events handled in future but so far there are none other than the flash related ones that will not arrive. Also in your case the

      uint8_t sd_enabled;
      sd_softdevice_is_enabled(&sd_enabled);
    

    could be simplified to have sd_enabled to be 0, so something like

      uint8_t sd_enabled=0;
     [#ifdef](https://forum.espruino.com/sear­ch/?q=%23ifdef) BLUETOOTH
      sd_softdevice_is_enabled(&sd_enabled);
     [#endif](https://forum.espruino.com/sear­ch/?q=%23endif)
    

    could be a better patch handling both cases, but it doesn't matter that much. There is actually slight nuance because there is sd_softdevice_enable and also sd_ble_enable and you can enable softdevice without enabling BLE so then the sd_softdevice_is_enabled will return true even if BLE is not enabled. But when BLUETOOTH library is enabled both are enabled and when disabled both are disabled. But we could in theory have bare softdevice enabled with BLUETOOTH disabled.

    https://infocenter.nordicsemi.com/topic/­com.nordic.infocenter.s132.api.v6.1.1/gr­oup___b_l_e___c_o_m_m_o_n___e_n_a_b_l_e.­html?cp=5_7_3_4_2_0_4_0

  • I tried a little more and found out that that setIntervaland setTimeout do not work anymore when compiling without bluetooth. The function does not fail with an error and return the correct index, but they never execute the callback function. Could it be that the interrupts are handled differently?

  • oh, yes, that's probably RTC not running because low frequency 32kHz source and/or RTC is not enabled, that is what sd_softdevice_enable does too :-( so looks like this was not really tested/used for a long time (or ever).

    there is poke32 command that can access all hardware

    in my NRF.stop() I have this code to let intervals running

        NRF_RTC0->TASKS_START=1; // disabling softdevice stops it, start again
    

    so that's basically poke32(0x4000B000,1)

    https://infocenter.nordicsemi.com/topic/­com.nordic.infocenter.nrf52832.ps.v1.1/r­tc.html?cp=5_2_0_24_9#topic

    but maybe even the crystal or RC oscillator is not running?
    https://infocenter.nordicsemi.com/topic/­com.nordic.infocenter.nrf52832.ps.v1.1/r­tc.html?cp=5_2_0_24_0#concept_fms_bjj_sr­

    try the poke above first if it helps

  • if even 32kHz is not running then maybe

    poke32(0x40000000+0x518,1) // LFCLKSRC = XTAL
    poke32(0x40000000+0x008,1) // TASKS_LFCLKSTART
    

    https://infocenter.nordicsemi.com/topic/­com.nordic.infocenter.nrf52832.ps.v1.1/c­lock.html?cp=5_2_0_18_2#topic

    or maybe try peek32(0x40000000+0x418) first to see LFCLKSTAT to test if it is already running

  • however at least the LF clock should be started
    https://github.com/espruino/Espruino/blo­b/52352efac4f8f40976a4d268a0a074ad15251b­29/targets/nrf5x/jshardware.c#L868

    so maybe it is just RTC0 that was forgotten to be started(?) when BLUETOOTH is disabled

    so maybe into that

    else // !BLUETOOTH
    

    you can put NRF_RTC0->TASKS_START=1 if the poke32(0x4000B000,1) helps

    EDIT: not sure about PRESCALER for the RTC, maybe default is OK? if not then the clock will run too fast

  • Hi,
    if i do peek32(0x40000000+0x418) i get STATE = running and SRC = RC, so thats not the problem. However if i execute poke32(0x4000B000,1) the setInterval() works so i assume that the RTC0 has not been started.

    So i made your suggested changes:

    diff --git a/targets/nrf5x/jshardware.c b/targets/nrf5x/jshardware.c
    index 879942b..de94214 100644
    --- a/targets/nrf5x/jshardware.c
    +++ b/targets/nrf5x/jshardware.c
    
    @@ -984,7 +987,14 @@ void jshInit() {
     [#else](https://forum.espruino.com/searc­h/?q=%23else) // !BLUETOOTH
       // because the code in bluetooth.c will call jsh_sys_evt_handler for us
       // if we were using bluetooth
    +#ifdef SOFTDEVICE_PRESENT
    +#if NRF_SD_BLE_API_VERSION<5
       softdevice_sys_evt_handler_set(jsh_sys_e­vt_handler);
    +#else
    +  NRF_SDH_SOC_OBSERVER(m_soc_observer, 1, jsh_sys_evt_handler, NULL);
    +#endif
    +#endif
    +NRF_RTC0->TASKS_START = 1;
     [#endif](https://forum.espruino.com/sear­ch/?q=%23endif)
    

    It looks like the PRESCALER configuration works like this. At least the setInterval() calls execute with the right interval.
    For now everything works so far i think. You helped me a lot! Thanks.

    I've attached the complete changes. If anyone needs this too it can be found here.


    1 Attachment

  • I've attached the complete changes. If anyone needs this too it can be found here.

    For calling the sd_softdevice_is_enabled you have ifndef BLUETOOTH there, it should be ifdef to skip this call in your case when bluetooth ( => and softdevice) is not enabled. The extra call won't hurt of course, just mentioning this in case anyone needs this too.

    In fact if BLUETOOTH is enabled it can be set to 1. It is only my case, where I can turn it off and on via NFC.stop()/start(), that needs this call.

  • Ahh! I don't know why this happened! So i just reversed it.

    diff --git a/targets/nrf5x/jshardware.c b/targets/nrf5x/jshardware.c
    index ca501bb..ac937f4 100644
    --- a/targets/nrf5x/jshardware.c
    +++ b/targets/nrf5x/jshardware.c
    @@ -54,8 +54,8 @@ USB data receive is broken, although examples+config seem almost identical.
     [#include](https://forum.espruino.com/se­arch/?q=%23include) "bluetooth.h"
     [#include](https://forum.espruino.com/se­arch/?q=%23include) "bluetooth_utils.h"
     [#include](https://forum.espruino.com/se­arch/?q=%23include) "jswrap_bluetooth.h"
    -#else
     [#include](https://forum.espruino.com/se­arch/?q=%23include) "nrf_sdm.h"
    +#else
     [#include](https://forum.espruino.com/se­arch/?q=%23include) "nrf_temp.h"
     void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) {
     }
    @@ -2493,7 +2493,7 @@ bool jshFlashErasePages(uint32_t addr, uint32_t byteLength) {
       uint8_t sd_enabled = 0;
    -  [#ifndef](https://forum.espruino.com/sea­rch/?q=%23ifndef) BLUETOOTH
    +  [#ifdef](https://forum.espruino.com/sear­ch/?q=%23ifdef) BLUETOOTH
       sd_softdevice_is_enabled(&sd_enabled);
       [#endif](https://forum.espruino.com/sear­ch/?q=%23endif)
       while (byteLength>=4096 && !jspIsInterrupted()) {
    @@ -2662,7 +2662,7 @@ void jshFlashWrite(void * buf, uint32_t addr, uint32_t len) {
       if (jshFlashWriteProtect(addr)) return;
       uint32_t err = 0;
    

    1 Attachment

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

Compiling Espruino for NRF52840DK without Blutetooth

Posted by Avatar for Chris3006 @Chris3006

Actions