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

What exactly do nrf_drv_twi_disable() and _enable() do?

I am working with a sensor which has a programmable configuration register. After changing this register, I have to reboot the sensor. To do this, I need to temporarily suspend a TWI master driver and manipulate the SCL and SDA GPIO lines directly, as described in this earlier discussion:

devzone.nordicsemi.com/.../

Looking through the Nordic documentation, I'm trying to figure out how to get this done.

In the SDK docs I have found the functions nrf_drv_twi_disable() and nrf_drv_twi_enable(). These functions are sparsely documented. Nor are these functions used in any of the software examples. What exactly do they do?

In the hardware docs (Section 47) I found references to the registers PSELSCL and PSELSDA. These registers determine the pins that are driven by the TWI. I found these elements within the NRF_TWI_Type data structure, and I can read their values. The documentation says I can only WRITE these registers when the TWI is disabled.

I started with a pretty simple modification to an existing program; just adding calls to nrf_drv_twi_disable() and nrf_drv_twi_enable() after some data transfers have completed, with short delays in between each call (0.5 seconds each). I haven't tried to modify PSELSCL or PSELSDA yet, or to write to the GPIO lines. Still, this simple change crashes. APP_ERROR_CHECK fails, my program reboots, and then the first new thing that my program tries to do on the TWI (just reading a register) causes another APP_ERROR_CHECK failure.

I don't know that any of this is Nordic's fault, since the slave device is obviously a little strange. But the failure is profound. When my system gets into an error state, I can only solve the problem by completely unplugging everything. I have to turn off my nRF52 board, and disconnect it from USB. I even have to unplug my slave device from the Nordic board (which is also its power source).

After I reboot, provided that a working program is in flash, everything functions again. By "working program" I mean that one which changes the configuration register, but doesn't (yet) perform the sleep-and-wake cycle that I want.

I am using a the nRF52 Preview board and SDK 0.9.2 (the highest revision that I can use).

Thanks for any help you can provide!

  • Which APP_ERROR_CHECKS() fail? ie which calls are you getting error codes from which are non-zero? And what is the non-zero value of the errors? That should help narrow down what the TWI driver is upset about.

  • Getting error codes has sometimes been frustrating. I am using UART to observe the behavior of my device. If I don't include calls to fflush() and nrf_delay_ms() after every printf(), part or all of the error message that I want to read will fail to print before APP_ERROR_CHECK reboots the nRF52.

    Still, what I've seen is that, when an error actually prints, I get error code 3. I went hunting through the source code and error code 3 is NRF_ERROR_INTERNAL, which is generated "if an NRF_TWI_EVENTS_ERROR or a time-out has occurred (only in blocking mode)." That doesn't tell me much. I have to dig deeper.

    I may just take a hardware approach to solve my problem. I might route the power supply of my sensor through an analog switch, and control that switch with a GPIO. That would prevent me from having to figure out the problems I'm having with suspending Nordic's TWI.

  • UART debugging is like trying to drive a bus with your nose. The preview board has a whole segger debugger on it which can print things out, breakpoint the code .. you're making life way harder for yourself not using it. Even RTT is a better way of outputting data than UART, it doesn't need flushing, it doesn't take any time to be transmitted. Yes once you break with the softdevice running you can't resume, but it's way better than using the UART.

    All you would then have to do is put a breakpoint on the line(s) which return that error, run your code, and when it breaks you inspect the state, which should tell you why it failed.

    There's lots of places seem to return that error code but it shouldn't be that hard to work out which one of them it was.

Related