0

Issue running TWI/SPI on nRF52832, works with Kiel but not GCC

dhariharan gravatar image

asked 2017-10-12 18:29:28 +0100

Hi,

Just curious to know if anyone else had this issue and how they solved it.

My colleagues and I are working on code based on the Nordic Uart Service, in SDK13.1.0 with SD132v4.0.2 on an nRF52832 chip. For better context, colleagues develop using Kiel on Windows, where as I am developing on a Mac (NetBeans + GCC setup, GNU_VERSION = 6.3.1).

Our test project interfaces with sensors via TWI and SPI and sends data over BLE. When programmed through kiel, the device works fine (i.e. can set up interfaces, collect data, connect and send data etc.).

The same project when downloaded into my environment, can compile, build and flash code just fine. Except the following: - TWI init() works fine. - on attempting to initialize the first sensor and writing to it over TWI, the twi handler never gets called, and hence hangs. (e.g. nrf_drv_twi_tx() returns NRF_SUCCESS)

Similar behavior is also seen with the SPI.

I know my development environment works fine when I have to program a PCA10040 dev kit, with code from the example projects for testing. I also have a pretty good understanding of setting up the Makefile and adjusting the RAM allocations through the .ld file. sdk_config.h also has the necessary flags enabled for running the interfaces (else they wouldn't work when programmed through Kiel either). I am confused as to why a project would compile and run fine through Kiel, but will not run the same through GCC.

I have also tried flashing the twi_scanner project to a devkit, without the soft device, which works fine too.

I am guessing that I may be missing something else in my development setup, but it just does not seem obvious to me. I would be glad if some one has found the solution to this before!

Thanks, Jai

edit retag flag offensive close delete report spam

1 answer

Sort by » oldest newest most voted
0
hnhoan gravatar image

answered 2017-10-12 20:07:19 +0100

There are a few bugs in the .ld for GCC. The new stuffs with Section after the FLASH & RAM setting. Look for > RAM and replace it with '> RAM AT > FLASH'. This affects project using Softdevice. That was one of the problem I found since SDK12.

edit flag offensive delete publish link more

Comments

Thanks for your response @Nguyen. I am not sure I understand what that code changes, but I still seem to see the same behavior.

But we noticed something else that may be the root cause - After programming (soft device + application) from my system (Mac / NetBeans / GCC for clarity) and moving it to nRFGo Studio on Windows, the software showed that there was no Softdevice in the specified region.

Could it be that the nrfjprog command in the makefile needs to explicitly mention the start address for loading the soft device and application code?

For reference, this is what our memory config looks like in the linker file

MEMORY
{
      FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x54000
      RAM (rwx) :  ORIGIN = 0x20005f40, LENGTH = 0xa0c0
}

If the memory regions are off, then the interrupt callbacks end up in the wrong space?

Jai ( 2017-10-12 22:34:04 +0100 )editconvert to answer

To further clarify, I am flashing and setting the soft device in the makefile commands.

`.PHONY: $(TARGETS) default all clean help flash_softdevice flash

# Default target - first one defined
default: nrf52832_xxaa

# Print all targets that can be built
help:
    @echo following targets are available:
    @echo   nrf52832_xxaa

TEMPLATE_PATH := <path>

include $(TEMPLATE_PATH)/Makefile.common

$(foreach target, $(TARGETS), $(call define_target, $(target)))

# Flash the program
flash: $(OUTPUT_DIRECTORY)/nrf52832_xxaa.hex
    @echo Flashing: $<
    nrfjprog --program $< -f nrf52 --sectorerase --verify
    nrfjprog --reset -f nrf52

# Flash softdevice
flash_softdevice:
    @echo Flashing: s132_nrf52_4.0.2_softdevice.hex
    nrfjprog --program $(SDK_ROOT)/components/softdevice/s132/hex/s132_nrf52_4.0.2_softdevice.hex -f nrf52 --chiperase --verify
    nrfjprog --reset -f nrf52

erase:
    nrfjprog --eraseall -f nrf52`
Jai ( 2017-10-12 22:37:04 +0100 )editconvert to answer

The flash origin must be set to the correct address for it to work. Softdevice must be flashed first. As for the RAM thing in the ld. It is to ensure that the initialized global are kept. If you don't do that, it may only work when debugging but after a power cycle, your app won't work.

Nguyen Hoan Hoang ( 2017-10-13 00:12:44 +0100 )editconvert to answer

I suspect my issue may be something like that, although I don't know if I need to explicitly mention the addresses for flashing. I found this post which talks about the various code region registers, but I am unsure of how to work them into my linker file.

I have yet to try to use the jlinkexe method for flashing and explicitly setting the memory location. That may the solution...

Jai ( 2017-10-13 15:36:59 +0100 )editconvert to answer

The jlinkexe method of flashing yields the same results, which makes me think that the built output from my GCC-Make config is the issue, specifically the .map output file. Would it be worth comparing the memory locations for the IRQHandler (s) in the map files generated by GCC and Kiel? Thanks for sticking with this conversation!

Jai ( 2017-10-13 16:07:24 +0100 )editconvert to answer

Are you compiling in C++ mode with GCC? which I doubt. Have you added the require sections ? Look at the .ld from hrs example. See if you are missing something.

Nguyen Hoan Hoang ( 2017-10-13 20:10:34 +0100 )editconvert to answer

I am quite sure I am compiling in C mode... As for my sections, they seem the same as the other projects.

SECTIONS
{
  .fs_data :
  {
    PROVIDE(__start_fs_data = .);
    KEEP(*(.fs_data))
    PROVIDE(__stop_fs_data = .);
  } > RAM AT > FLASH
} INSERT AFTER .data;

SECTIONS
{
  .pwr_mgmt_data :
  {
    PROVIDE(__start_pwr_mgmt_data = .);
    KEEP(*(SORT(.pwr_mgmt_data*)))
    PROVIDE(__stop_pwr_mgmt_data = .);
  } > FLASH
} INSERT AFTER .text

INCLUDE "nrf5x_common.ld"
Jai ( 2017-10-13 21:55:18 +0100 )editconvert to answer

So compiling stuff seems to be in order. Check in the sdk_config.h to see to make sure the TWI stuffs are enabled. Min 2 enable need to be set, one to enable the driver and one to enable the instance of twi0, twi1...

Nguyen Hoan Hoang ( 2017-10-13 22:26:50 +0100 )editconvert to answer

Checked that too! TWI_ENABLED and TWI0_ENABLED as well.

I am currently looking through the forum post on setting up GCC+Segger Embedded Studio, and I noticed it includes steps for setting up specifics for flash placement and modifying the .s file. Perhaps there might be something similar I need to do.. Might consider using Segger Embedded Studio if I am able to set it up and if it seems to work.

Jai ( 2017-10-14 00:46:36 +0100 )editconvert to answer

I am out of ideas too. I am using Eclipse and develop on Mac exclusively. I have written a generic version of the i2c driver and startup code that works for all Cortex-M series. Check it out on this blog, there are links to the Github repo. The code currently compile with latest GCCC 6.3 and SDK14.

Nguyen Hoan Hoang ( 2017-10-14 03:36:52 +0100 )editconvert to answer

Thanks for the link! Looking at getting SES running, but will also see if I should set up Eclipse instead. Will post back here on my results. Jai

Jai ( 2017-10-16 16:40:23 +0100 )editconvert to answer
  1. Have you tried debugging to see if your code might assert anywhere?
  2. Maybe you can try to read out the TWI registers, just to see if it is being configured the same way by both applications.
  3. You are doing a --chiperase when flashing your softdevice, and while it shouldn't be a big issue, I imagine it can cause some confusion if you forget about it and assume your application is still in place after flashing the softdevice.
  4. Maybe you can upload your code and then we can try to compile and debug it. It can be difficult though, if you have sensors etc. that we don't. You can upload the code in confidence on MyPage if your prefer that.
Martin Børs-Lind ( 2017-10-17 09:44:52 +0100 )editconvert to answer

Hi @Martin, Here's what I have tried with regards to your suggestions:

  1. I have mostly been debugging using the logger and LEDs. From this I have observed that after calling nrf_drv_twi_tx(), the code is stuck waiting for the callback handler to return (blocking call).
  2. Since all my calls with TWI hang, I can't seem to do anything. The same project and code works fine via Kiel though.
  3. For each build and run, I follow the --chiperase with flashing soft device and app, so it shouldn't pose a problem. Can compile example projects for DK, but not our custom board..
  4. I will consider this as my last resort if I cannot seem to get it to work in any way on my end.

As @Nguyen suggested, I am looking to set up Segger Embedded Studio, which has explicit instructions for setting flash placement. I suspect this part is ...(more)

Jai ( 2017-10-18 05:25:02 +0100 )editconvert to answer

Code stuck waiting for callbacks could indicate issues with interrupt priorities or interrupt nesting. Or maybe it could be a problem with volatile variables used in the callbacks? I'm far from a compiler expert, but I believe different compilers might treat volatile variables differently and maybe that is why it works for your colleagues, but not you.

Martin Børs-Lind ( 2017-10-18 08:43:43 +0100 )editconvert to answer

Hi @Martin, thanks for your suggestions! - Given that our application is using interrupts from TIMER, TWI, SPIM & SPIS, all of our interrupt priorities are set to low. - In this specific event, after a call to nrf_drv_twi_tx() which returns success, we wait in a while loop for a flag to get set, which happens in the callback. The callbacks only sets this flag to true for the moment. - And the above-mentioned flag is declared as volatile, which I believe is being used correctly in this scenario, according to the article provided..

Jai ( 2017-10-19 17:43:34 +0100 )editconvert to answer

I keep thinking back to my first comment under this thread, where I mention that after programming SoftDevice + application to the device from GCC, when this device is observed on nRF Go Studio, it can only something in the application area, but the soft device region is said to be empty.

I followed the steps for setting up Netbeans + GCC using this article. I believe the author also posted the link to it on the forums here.

I have yet to give Nguyen's post or the Segger Studio installations a proper, so that's my fault for not getting on it yet!

Jai ( 2017-10-19 17:49:26 +0100 )editconvert to answer

Did you try to program the softdevice and application separately with nrfjprog? And are you using the latest version of nRFgo Studio (v1.21.2.10)? I seem to recall that once there were some issues with new softdevices and nRFgo Studio.

Martin Børs-Lind ( 2017-10-20 12:29:50 +0100 )editconvert to answer

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer. Do not ask a new question or reply to an answer here.

[hide preview]

User menu

    or sign up

Recent questions

Question Tools

1 follower

Stats

Asked: 2017-10-12 18:29:28 +0100

Seen: 101 times

Last updated: okt. 12