This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

re-init or resetting nrf52 dongle with pc-ble-driver-py

Hi,

I have a python program using an NRF52 dongle and its working great with the a minor detail that if the program crashes and does not get a chance to close the adapter, then it does not allow you to open it again until the dongle is unplugged and plugged back in.

I've tried opening and closing the device through the library and I've also tried using pyserial to do something similar, but in every case I get either "NordicSemiException: Failed to ble_enable. Error code: 3" or Error Code 13. once the device is power cycled, it works great.

Is there anyway to programmatically ensure that the device is reset when the program loads so that a physical action is not necessary?

Thanks,

Gabe

  • Hi @Einar,

    I gave it shot at adding the sd_rpc_conn_reset() to the python library.

    I added these lines to the blue_driver.py file under the BLEDriver(object): class. 

        @NordicSemiErrorCheck
        @wrapt.synchronized(api_lock
        def reset(self):
            return driver.sd_rpc_conn_reset(self.rpc_adapter)

    But it seems the sd_rpc_conn_reset() function has a second argument:  sd_rpc_reset_t reset_mode, as per this code:
    https://github.com/NordicSemiconductor/pc-ble-driver/blob/236d10fc939b5db5e9c11b46b488e4b8dfb44438/src/common/sd_rpc_impl.cpp

    So when I try to call it I get this error:

    exception=Failed to reset. Error code: 8

    Do you know what the sd_rpc_reset_t reset_mode variable value and type needs to be to make the reset function work? 

    I'm using an "nRF52 Connectivity" dongle for my python application.

    Thank you!

     

  • Hi,

    Yes, if you are using a pc-ble-driver version that has the reset_mode (sd_rpc_reset_t) option for sd_rpc_conn_reset() (for instance the master branch), then you sould set it. It is either SYS_RESET (0) or SOFT_RESET (1). I assume SYS_RESET is what you want.

  • Hi Einar,

    Thanks for the info. So does this mean I simply need the function to be:

    def reset(self):
            return driver.sd_rpc_conn_reset(self.rpc_adapter,0)

    So that SYS_RESET is chosen? 

    I tried this and I'm still seeing the error:

    NordicSemiException: Failed to reset. Error code: 8

    What does error code 8 mean exactly?

  • Hi,

    Error code 8 is NRF_ERROR_INVALID_STATE. Looking tha the pc-ble-driver C++ implementation this comes from the send() function and is set if the current transport state is other than STATE_ACTIVE. It is not possible to send any commands in this state (without a working transport).

  • Using the comments from this thread I was able to come up with a solution that does not require modification of the pc-ble-driver-py library. For anyone else looking for an answer, here is my code snippet:

    def parametrizedDecorator(dec):
        def layer(*args, **kwargs):
            def repl(f):
                return dec(f, *args, **kwargs)
            return repl
        return layer
    
    @parametrizedDecorator
    def extendClass(func, c):
        setattr(c, func.__name__, func)
        return func
    
    from pc_ble_driver_py import config
    config.__conn_ic_id__ = "NRF52"
    from pc_ble_driver_py.ble_driver import NordicSemiErrorCheck
    from pc_ble_driver_py.ble_driver import driver
    
    @NordicSemiErrorCheck
    @wrapt.synchronized(BLEDriver.api_lock)
    @extendClass(BLEDriver)
    def reset(self, resetType=0):
        return driver.sd_rpc_conn_reset(self.rpc_adapter, resetType) 

    and to use it you should do something like this:

    def reset_function():
        driver = BLEDriver(serial_port=self.serial_port, auto_flash=False)
        adapter = BLEAdapter(driver)
        adapter.driver.reset(resetType)
        time.sleep(1)

Related