u-blox / ubxlib

Portable C libraries which provide APIs to build applications with u-blox products and services. Delivered as add-on to existing microcontroller and RTOS SDKs.
Apache License 2.0
287 stars 82 forks source link

ASSERTION FAIL with Zephyr and MIA-M10Q #199

Closed ValterMinute closed 4 months ago

ValterMinute commented 4 months ago

Hello, I am trying ubxlib on a custom device based on NRF52832-CIAA. The module is connected via I2C (pins 11-12) at address 0x42. I also have control of reset (RESET_N).

I have a very simple application that toggles the reset pin (I tried to remove this but I saw same behavior) and then performs the following operations:

   if (0 != (err = uPortInit())) {
    LOG_ERR("uPortInit failed %d", err);
    return err;
  }

  if (0 != (err = uPortI2cInit())) {
    LOG_ERR("uPortI2cInit failed %d", err);
    return err;
  }

  if (0 != (err = uDeviceInit())) {
    LOG_ERR("uDeviceInit failed %d", err);
    return err;
  }

  if (0 != (err = uDeviceOpen(NULL, &ubx_device_handle))) {
    LOG_ERR("uDeviceOpen failed %d", err);
    return err;
  }

  uGnssPwrOn(&ubx_device_handle);

  uGnssVersionType_t version;

  if (0 != (err = uGnssInfoGetVersions(&ubx_device_handle, &version))) {
    LOG_ERR("uDeviceOpen failed %d", err);
    return err;
  }

  LOG_INF("GNSS ver: %s", version.ver);
  LOG_INF("GNSS fw: %s", version.fw);
  LOG_INF("GNSS hw: %s", version.hw);
  LOG_INF("GNSS prot: %s", version.prot);
  LOG_INF("GNSS mod: %s", version.mod);

  uGnssPwrOff(&ubx_device_handle);

I configured the device via dts:

    gps {
        status = "okay";
        compatible = "u-blox,ubxlib-device-gnss";
        transport-type = "i2c0";
        i2c-already-open;
        i2c-address = <0x42>;
        module-type = "U_GNSS_MODULE_TYPE_M10";
    };

I enabled i2c0 via dts too...

When I run my application I get an assertion the the nordic HAL.

00> *** Booting nRF Connect SDK v2.5.1 ***
00> U_PORT_BOARD_CFG: using GNSS device "gps" from the device tree, module-type 2 with pin-enable-power -1, pin-data-ready -1...
00> U_PORT_BOARD_CFG: ...GNSS on I2C 0, i2c-address 66, i2c-clock-hertz 100000, i2c-already-open.
00> U_GNSS: initialising with ENABLE_POWER pin not connected, transport type I2C.
00> U_GNSS: sent command b5 62 0a 06 00 00 10 3a.
00> U_GNSS: decoded UBX response 0x0a 0x06: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [body 120 byte(s)].
00> U_GNSS: sent command b5 62 06 04 04 00 00 00 09 00 17 76.
00> ASSERTION FAIL [((((p_instance->drv_inst_idx) == NRFX_TWIM0_INST_IDX) && (((p_xfer_desc->primary_length) < (1U << 8)) && ((p_xfer_desc->secondary_length) < (1U << 8)))) || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0)] @ WEST_TOPDIR/modules/hal/nordic/nrfx/drivers/src/nrfx_twim.c:593
00> [00:00:01.407,531] <err> os: r0/a1:  0x00000004  r1/a2:  0x00000251  r2/a3:  0x00000000
00> [00:00:01.408,142] <err> os: r3/a4:  0x00000251 r12/ip:  0x0000000a r14/lr:  0x00023c03
00> [00:00:01.408,721] <err> os:  xpsr:  0x41000000
00> [00:00:01.409,149] <err> os: Faulting instruction address (r15/pc): 0x0002be8c
00> [00:00:01.409,698] <err> os: >>> ZEPHYR FATAL ERROR 4: Kernel panic on CPU 0
00> [00:00:01.410,217] <err> os: Current thread: 0x200026e0 (main)
00> [00:00:01.415,740] <err> os: Halting system

It's a bit puzzling because I see that 1st command is sent correctly and seem to get a valid answer (that should mean that I2C communication is ok) and the 2nd one generate a low-level issue.

We tested the I2C and it seems that the HW connection is OK but if there's something else I should check, I'll be happy to provide any information you may need.

RobMeades commented 4 months ago

Hi there: we test GNSS with the board type ubx_evkninab4_nrf52833, working with MAX-M10 via I2C (0) but, if I've read the Nordic website correctly, nRF52832 has half the RAM of nRF52833 at 64 kbytes (v 128 kbytes for nRF52833); it would probably be worth looking at how RAM is allocated to stack and heap in your build on nRF52832 as lack of RAM (critically for stack) is most likely to lead to an assertion of this nature.

1st EDIT: to confirm, otherwise what you are doing looks perfectly fine; you don't need the call to uGnssPwrOn(), though it will do no harm (uDeviceOpen() will already do this: a device is powered-up and ready for use after uDeviceOpen() has returned success).

2nd EDIT: expanding on what might be the reason for the assert going off only on the second "send", during the U_GNSS log prints you have pasted in above, the CPU will be progressing through the uGnssPwrOn() function (when it is called by uDeviceOpen()) and, before the assert goes off, the response to the first GNSS message will just have been decoded into the stack variable char message[120], plus other stack variables, used by uGnssPrivateSendOnlyCheckStreamUbxMessage() and the functions it calls, hence my thinking that a lack of stack memory may be an issue. FYI, in our testing on ubx_evkninab4_nrf52833, we check the minimum value of the main task stack after each set of tests and, after the first few GNSS tests (each of which runs from uDeviceOpen() back to uDeviceClose()), from an allocated main task stack of 8192 bytes (sized, and checked by the testing, so that the actual application always has 5120 bytes free for itself) the low water mark is 6336 bytes and after all tests it is 6136 bytes.

ValterMinute commented 4 months ago

Hi @RobMeades. I added the uGnssPowerOn call for debugging (I was executing it step by step) and it was left there by mistake. I removed it. I had error -6 (ENOMEM) before, so I increased main stack thread to 8K (this code is called from main) and heap mem pool size to 8K (error -6 stop happening) and then 16K but I still get the same behavior. I also tried to reset the chip (I can control reset pin), but this also doesn't seem to solve the issue.

ValterMinute commented 4 months ago

Talking about code size, it's there a plan to have more granular control of which features are going to be built with ubxlib? For example, if I know that GNSS is connected via I2C I would like to get rid of the code managing SPI and UART interfaces...

RobMeades commented 4 months ago

but this also doesn't seem to solve the issue.

Sorry to hear you're still having trouble with this: can you post the debug output with your latest changes?

if I know that GNSS is connected via I2C I would like to get rid of the code managing SPI and UART interfaces...

You will lose some of that code if you are not using those interfaces since CONFIG_SPI will not be defined and the functions will not be being called (assuming you are compiling with --gc-sections -ffunction-sections) but, in general, we don't plan to put deep/granular conditional compilation into ubxlib - relatively small amounts of code are involved and our philosophy, as a library, is to be built once and be run-time configurable.

EDIT: if you can show that it is actually a large amount of code then we will change our minds for this case :-).

ValterMinute commented 4 months ago

Hi @RobMeades, thank you for your patience :)

The output hasn't changed:

00> *** Booting nRF Connect SDK v2.5.1 ***
00> U_PORT_BOARD_CFG: using GNSS device "gps" from the device tree, module-type 2 with pin-enable-power -1, pin-data-ready -1...
00> U_PORT_BOARD_CFG: ...GNSS on I2C 0, i2c-address 66, i2c-clock-hertz 100000, i2c-already-open.
00> U_GNSS: initialising with ENABLE_POWER pin not connected, transport type I2C.
00> U_GNSS: sent command b5 62 0a 06 00 00 10 3a.
00> U_GNSS: decoded UBX response 0x0a 0x06: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [body 120 byte(s)].
00> U_GNSS: sent command b5 62 06 04 04 00 00 00 09 00 17 76.
00> ASSERTION FAIL [((((p_instance->drv_inst_idx) == NRFX_TWIM0_INST_IDX) && (((p_xfer_desc->primary_length) < (1U << 8)) && ((p_xfer_desc->secondary_length) < (1U <<

For code size I will try with the optimization you suggested. I was mostly concerned by the code I saw debugging the issue where in many places I had tests to check connectivity type inside the same function, but probably this isn't a large amount of code. I understand your point in keeping the library configurable at runtime and that code may became an issue only when trying to squeeze the last free byte out of the flash :) I hope to not have that need.

RobMeades commented 4 months ago

thank you for your patience :)

NP, I quite like puzzles, and this is definitely one of those: very weird indeed.

I think we need to find out which of those parameters in the ASSERTION FAIL it is asserting on. If a debugger is not an option, could you maybe hack nrfconnectsdk-v2.5.1\modules\hal\nordic\nrfx\drivers\src\nrfx_twim.c to print them all out on entry to nrfx_twim_xfer(), so something like the following (with the ### just to make the prints stand out):

nrfx_err_t nrfx_twim_xfer(nrfx_twim_t           const * p_instance,
                          nrfx_twim_xfer_desc_t const * p_xfer_desc,
                          uint32_t                      flags)
{
    printf("### p_instance %p, p_xfer_desc %p.\n", p_instance, p_xfer_desc);
    if (p_instance != NULL) {
        printf("### drv_inst_idx %d.\n", p_instance->drv_inst_idx);
    }
    if (p_xfer_desc != NULL) {
        printf("### primary_length %d, secondary_length %d.\n", p_xfer_desc->primary_length, p_xfer_desc->secondary_length);
    }
    NRFX_ASSERT(TWIM_LENGTH_VALIDATE(p_instance->drv_inst_idx,
                                     p_xfer_desc->primary_length,
                                     p_xfer_desc->secondary_length));

...and post the debug output here?

RobMeades commented 4 months ago

heap mem pool size to 8K

Just to be certain, I guess you changed the heap mem pool size by modifying the parameter CONFIG_HEAP_MEM_POOL_SIZE in your prj.conf?

ValterMinute commented 4 months ago

heap mem pool size to 8K

Just to be certain, I guess you changed the heap mem pool size by modifying the parameter CONFIG_HEAP_MEM_POOL_SIZE in your prj.conf?

Yes. I tried increasing it up to 16K, but with no luck.

ValterMinute commented 4 months ago

thank you for your patience :)

NP, I quite like puzzles, and this is definitely one of those: very weird indeed.

I think we need to find out which of those parameters in the ASSERTION FAIL it is asserting on. If a debugger is not an option, could you maybe hack nrfconnectsdk-v2.5.1\modules\hal\nordic\nrfx\drivers\src\nrfx_twim.c to print them all out on entry to nrfx_twim_xfer(), so something like the following (with the ### just to make the prints stand out):

nrfx_err_t nrfx_twim_xfer(nrfx_twim_t           const * p_instance,
                          nrfx_twim_xfer_desc_t const * p_xfer_desc,
                          uint32_t                      flags)
{
    printf("### p_instance %p, p_xfer_desc %p.\n", p_instance, p_xfer_desc);
    if (p_instance != NULL) {
        printf("### drv_inst_idx %d.\n", p_instance->drv_inst_idx);
    }
    if (p_xfer_desc != NULL) {
        printf("### primary_length %d, secondary_length %d.\n", p_xfer_desc->primary_length, p_xfer_desc->secondary_length);
    }
    NRFX_ASSERT(TWIM_LENGTH_VALIDATE(p_instance->drv_inst_idx,
                                     p_xfer_desc->primary_length,
                                     p_xfer_desc->secondary_length));

...and post the debug output here?

I tried with the debugger, but all the values seemed OK every time I reached the BP, then the system froze... I'll try adding the message. TY for the suggestion

ValterMinute commented 4 months ago

I added some additional prints, to see the values of the struct data members and I think this may be the issue:

### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 256, p_xfer_desc->secondary_length 0

All other transfers seem shorter and probably 256 is above the limit. I am trying to understand if there's a way to increase this in the SDK configuration.

*** Booting nRF Connect SDK v2.5.2 ***
00> U_PORT_BOARD_CFG: using GNSS device "gps" from the device tree, module-type 2 with pin-enable-power -1, pin-data-ready -1...
00> U_PORT_BOARD_CFG: ...GNSS on I2C 0, i2c-address 66, i2c-clock-hertz 100000, i2c-already-open.
00> U_GNSS: initialising with ENABLE_POWER pin not connected, transport type I2C.
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f0c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f04. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f0c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f04. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f0c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f04. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f0c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f04. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f0c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f04. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f0c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f04. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f0c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f04. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f44. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 8, p_xfer_desc->secondary_length 0
00> U_GNSS: sent command b5 62 0a 06 00 00 10 3a.
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f2c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 161, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e94. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006e8c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> U_GNSS: decoded UBX response 0x0a 0x06: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [body 120 byte(s)].
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f6c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 12, p_xfer_desc->secondary_length 0
00> U_GNSS: sent command b5 62 06 04 04 00 00 00 09 00 17 76.
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f0c. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 1, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006f04. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 2, p_xfer_desc->secondary_length 0
00> ### p_instance 0x35adc, p_xfer_desc 0x20006fa4. 0
00> ### p_instance->drv_inst_idx 0, p_xfer_desc->primary_length 256, p_xfer_desc->secondary_length 0
00> ASSERTION FAIL [((((p_instance->drv_inst_idx) == NRFX_TWIM0_INST_IDX) && (((p_xfer_desc->primary_length) < (1U << 8)) && ((p_xfer_desc->secondary_length) < (1U << 8)))) || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0)] @ WEST_TOPDIR/modules/hal/nordic/nrfx/drivers/src/nrfx_twim.c:595
00> [00:00:01.411,315] <err> os: r0/a1:  0x00000004  r1/a2:  0x00000253  r2/a3:  0x00000000
00> [00:00:01.411,895] <err> os: r3/a4:  0x00000253 r12/ip:  0x0000000a r14/lr:  0x00023c81
00> [00:00:01.412,475] <err> os:  xpsr:  0x41000000
00> [00:00:01.412,902] <err> os: Faulting instruction address (r15/pc): 0x0002bf10
00> [00:00:01.413,452] <err> os: >>> ZEPHYR FATAL ERROR 4: Kernel panic on CPU 0
00> [00:00:01.413,970] <err> os: Current thread: 0x200026e0 (main)
00> [00:00:01.419,494] <err> os: Halting system
ValterMinute commented 4 months ago

I think that the problem is due to tx/rx length of I2C transfers length being limited to a uint_8: https://devzone.nordicsemi.com/f/nordic-q-a/74224/unable-to-write-8210-bytes-on-i2c-bus It's there a way to split those into multiple transfers inside ubxlib? P.S. I also updated my dev environment to v 2.5.2

ValterMinute commented 4 months ago

Now I was able to add a conditional BP and I can see the stack:

nrfx_twim_xfer(const nrfx_twim_t * p_instance, const nrfx_twim_xfer_desc_t * p_xfer_desc, uint32_t flags) (c:\nordic\v2.5.2\modules\hal\nordic\nrfx\drivers\src\nrfx_twim.c:593)
i2c_nrfx_twim_transfer(const struct device * dev, struct i2c_msg * msgs, uint8_t num_msgs, uint16_t addr) (c:\nordic\v2.5.2\zephyr\drivers\i2c\i2c_nrfx_twim.c:127)
i2c_transfer(uint16_t addr, uint8_t num_msgs, struct i2c_msg * msgs, const struct device * dev) (c:\nordic\kippy_zephyr\build\zephyr\include\generated\syscalls\i2c.h:86)
uPortI2cControllerSendReceive(int32_t handle, uint16_t address, const char * pSend, size_t bytesToSend, char * pReceive, size_t bytesToReceive) (c:\nordic\kippy_zephyr\submodules\ubxlib\port\platform\zephyr\src\u_port_i2c.c:414)
uGnssPrivateStreamFillRingBuffer(uGnssPrivateInstance_t * pInstance, int32_t timeoutMs, int32_t maxTimeMs) (c:\nordic\kippy_zephyr\submodules\ubxlib\gnss\src\u_gnss_private.c:2188)
uGnssPrivateReceiveStreamMessage(uGnssPrivateInstance_t * pInstance, uGnssPrivateMessageId_t * pPrivateMessageId, int32_t readHandle, char ** ppBuffer, size_t size, int32_t timeoutMs, _Bool (*)(uDeviceHandle_t) pKeepGoingCallback) (c:\nordic\kippy_zephyr\submodules\ubxlib\gnss\src\u_gnss_private.c:2421)
receiveUbxMessageStream(uGnssPrivateInstance_t * pInstance, uGnssPrivateUbxReceiveMessage_t * pResponse, int32_t timeoutMs, _Bool printIt) (c:\nordic\kippy_zephyr\submodules\ubxlib\gnss\src\u_gnss_private.c:464)
sendReceiveUbxMessage(uGnssPrivateInstance_t * pInstance, int32_t messageClass, int32_t messageId, const char * pMessageBody, size_t messageBodyLengthBytes, uGnssPrivateUbxReceiveMessage_t * pResponse) (c:\nordic\kippy_zephyr\submodules\ubxlib\gnss\src\u_gnss_private.c:701)
uGnssPrivateSendReceiveUbxMessage(uGnssPrivateInstance_t * pInstance, int32_t messageClass, int32_t messageId, const char * pMessageBody, size_t messageBodyLengthBytes, char * pResponseBody, size_t maxResponseBodyLengthBytes) (c:\nordic\kippy_zephyr\submodules\ubxlib\gnss\src\u_gnss_private.c:2555)
uGnssPrivateSendOnlyCheckStreamUbxMessage(uGnssPrivateInstance_t * pInstance, int32_t messageClass, int32_t messageId, const char * pMessageBody, size_t messageBodyLengthBytes) (c:\nordic\kippy_zephyr\submodules\ubxlib\gnss\src\u_gnss_private.c:2358)
uGnssPwrOn(uDeviceHandle_t gnssHandle) (c:\nordic\kippy_zephyr\submodules\ubxlib\gnss\src\u_gnss_pwr.c:578)
addDevice(uGnssTransportHandle_t gnssTransportHandle, uDeviceTransportType_t deviceTransportType, const uDeviceCfgGnss_t * pCfgGnss, uDeviceHandle_t * pDeviceHandle) (c:\nordic\kippy_zephyr\submodules\ubxlib\common\device\src\u_device_private_gnss.c:181)
uDevicePrivateGnssAdd(const uDeviceCfg_t * pDevCfg, uDeviceHandle_t * pDeviceHandle) (c:\nordic\kippy_zephyr\submodules\ubxlib\common\device\src\u_device_private_gnss.c:303)
uDeviceOpen(const uDeviceCfg_t * pDeviceCfg, uDeviceHandle_t * pDeviceHandle) (c:\nordic\kippy_zephyr\submodules\ubxlib\common\device\src\u_device.c:289)
gnss_init() (c:\nordic\kippy_zephyr\src\gnss.c:108)
main() (c:\nordic\kippy_zephyr\src\main.c:32)

In uGnssPrivateStreamFillRingBuffer receivesize is calculated by calling uGnssPrivateStreamGetReceiveSize.

RobMeades commented 4 months ago

I think that the problem is due to tx/rx length of I2C transfers length being limited to a uint_8:

Oh! That's odd, we don't have that problem with nRF52833, hadn't appreciated that nRF52832 was different in the respect, and it's a bit difficult to tell from the assert macro madness.

but there's no check that the value is actually supported by the underlying layers

No, never found a layer with a limitation of any significance before - there are circumstances where the send can be larger than 256...

ValterMinute commented 4 months ago

I see that receive size is actually limited to 256 here:

                    if (receiveSize > U_GNSS_MSG_TEMPORARY_BUFFER_LENGTH_BYTES) {
                        receiveSize = U_GNSS_MSG_TEMPORARY_BUFFER_LENGTH_BYTES;
                    }
RobMeades commented 4 months ago

I see that receive size is actually limited to 256 here:

Purely an implementation matter in order that the code works nicely with SPI as well: you could try making that 255?

ValterMinute commented 4 months ago

I see that receive size is actually limited to 256 here:

Purely an implementation matter in order that the code works nicely with SPI as well: you could try making that 255?

I was thinking about that :) maybe 128 (just in case underlying layer complains with buffer alignment).

ValterMinute commented 4 months ago

Is there a clean way to define U_GNSS_MSG_TEMPORARY_BUFFER_LENGTH_BYTES? I see that the .h file checks for it being defined. And I also see that function calling uPortI2cControllerSend like uGnssMsgSend don't do any splitting of the message....

ValterMinute commented 4 months ago

Ok, I see a small progress here:

00> *** Booting nRF Connect SDK v2.5.2 ***
00> U_PORT_BOARD_CFG: using GNSS device "gps" from the device tree, module-type 2 with pin-enable-power -1, pin-data-ready -1...
00> U_PORT_BOARD_CFG: ...GNSS on I2C 0, i2c-address 66, i2c-clock-hertz 100000, i2c-already-open.
00> U_GNSS: initialising with ENABLE_POWER pin not connected, transport type I2C.
00> U_GNSS: sent command b5 62 0a 06 00 00 10 3a.
00> U_GNSS: decoded UBX response 0x0a 0x06: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [body 120 byte(s)].
00> U_GNSS: sent command b5 62 06 04 04 00 00 00 09 00 17 76.
00> U_GNSS: sent command b5 62 0a 06 00 00 10 3a.
00> U_GNSS: decoded UBX response 0x0a 0x06: 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [body 120 byte(s)].
00> [00:00:02.390,014] <err> gnss: uDeviceOpen failed -5

Now I need to figure out error -5 :) but probably first I'll need to limit the size of transaction on I2C bus. I think I can do that in u_port_i2c.c, but that would probably need an additional CONFIG.

RobMeades commented 4 months ago

-5 is U_ERROR_COMMON_INVALID_PARAMETER, though I must admit that all of your parameters seem fine.

ValterMinute commented 4 months ago

I think that this value is returned also when i2c_transfer fails in uPortI2CControllerSend and uPortI2cControllerSendReceive, isn't it?

RobMeades commented 4 months ago

Is there a clean way to define U_GNSS_MSG_TEMPORARY_BUFFER_LENGTH_BYTES? I see that the .h file checks for it being defined.

Yes, you can just define U_GNSS_MSG_TEMPORARY_BUFFER_LENGTH_BYTES=128 for your build (it is done this way deliberately).

And I also see that function calling uPortI2cControllerSend like uGnssMsgSend don't do any splitting of the message....

No, as indicated, we've not yet hit a platform where there is a limitation of any significance. Would need to decide how to do this: it seems that Zephyr doesn't hide it, which means our Zephyr port now has to be different depending on the chipset!

RobMeades commented 4 months ago

I think that this value is returned also when i2c_transfer fails in uPortI2CControllerSend and uPortI2cControllerSendReceive, isn't it?

Shouldn't be: that should be U_ERROR_COMMON_DEVICE_ERROR.

RobMeades commented 4 months ago

Google is getting quite clever:

image

ValterMinute commented 4 months ago

I think that this value is returned also when i2c_transfer fails in uPortI2CControllerSend and uPortI2cControllerSendReceive, isn't it?

Shouldn't be: that should be U_ERROR_COMMON_DEVICE_ERROR.

Yes, sorry, missed the assignment further down the code.

ValterMinute commented 4 months ago

Google is getting quite clever:

image

But this is about UART, not I2C :)

RobMeades commented 4 months ago

Ah, yes, missed that, but likely it's the same EasyDMA. And so UART has the same problem!

ValterMinute commented 4 months ago

Could maximum length be an additional parameter in the dts? It would keep the lib configurable and can be easily tied to a board (and its MCU)

ValterMinute commented 4 months ago

I think that since the module I2C interface works as a data stream splitting one long read/write in multiple ones shouldn't be an issue. Is that true? IE: I need to write a 256 bytes command and I split it in two 128 bytes writes (with start and stop) or instead of reading 300 bytes in a single read transaction I perform 3...

RobMeades commented 4 months ago

I think that since the module I2C interface works as a data stream splitting one long read/write in multiple ones shouldn't be an issue. Is that true?

It is, but I'd kinda hoped Zephyr would be the level that did that, rather than the "application" having to do it. If ubxlib has to do it then a concept of what that length is needs to come from somewhere and we need to test it (currently the "lowest" we go in the test system is nRF52833). Also, it seems the problem is not limited to I2C, we would have to do the same thing for UART and [I guess?] SPI.

Before going any further, I suggest we prove that you have a viable way forward with the 64 kbytes RAM limitation by persisting with U_GNSS_MSG_TEMPORARY_BUFFER_LENGTH_BYTES=128 and getting everything running; then we can decide the best way forward.

ValterMinute commented 4 months ago

This makes sense. But there's also the issue of the limitation on send, so I would probably need to split transactions anyway. Not sure I'll be able to do this tomorrow, but I'll post as soon as I have some news. I see the issue with RAM size. I liked the idea of using a supported lib rather than writing my own protocol parser, but if this requires too many resources I'll have to change my plans.

RobMeades commented 4 months ago

But there's also the issue of the limitation on send,

Yes: depending on your application you might not hit that, at least initially, while we feel for the RAM limitation.

I liked the idea of using a supported lib rather than writing my own protocol parser, but if this requires too many resources I'll have to change my plans.

You can, of course, use ubxlib as a starting point, if it helps, and just make your own thing out of it that fits into the space you have available.

cturvey commented 4 months ago

@ValterMinute "I need to write a 256 bytes command and I split it in two 128 bytes writes (with start and stop) or instead of reading 300 bytes in a single read transaction I perform 3..."

I'd probably decompose I2C transactions. Some like the Arduino AVR had a 32-byte buffer, but not sure where that came from, but could just have been a composition buffer, that was accumulated and then flushed. With I2C you're likely sharing with others, so holding the bus excessively might be undesirable for a number of reasons.

Out-bound (to receiver) the maximal UBX packet is 1000 bytes, from the receiver it can be much larger for diagnostic and RXM type messages, which can notionally get to 6-8 KB. RTCM3 around 1024, SPARTN don't recall off the top of my head, but no more than 1.5KB

Personally, I'd probably opt to take data in a piecemeal manner, feeding that into a parser/demuxer with a deeper frame buffer, and skip packets exceeding client side buffering limits. Plus the ability to push data requests into the receiver.

I can't say I've seen the 0xFFFF size reporting, but the LA trace looks compelling, seen other reports on the forum for getting 0x8000. One could decompose to smaller transfer, and then recheck the pending length.

RobMeades commented 4 months ago

From this question on the Nordic forums comes this useful comparison table which includes the width of the MAXCNT variable of EasyDMA (in bits) for each peripheral of each nRF52 series MCU:

image

It is a bit weird that the limiting value is on nRF52832, but anyway, the limitation applies for I2C, UART and SPI. I doubt that it is an application-level issue for UART since the Zephyr function on the send-end of the UART is k_fifo_put(), i.e. there should be a FIFO in the way, but it will be an issue for both I2C and SPI.

Thinking out load, assuming nRF52832 works for your application, we would probably end up adding uPortI2cSetMaxSegmentSize()/uPortI2cGetMaxSegmentSize()/uPortSpiSetMaxSegmentSize()/uPortSpiGetMaxSegmentSize(), with 0 meaning "none" [the default, which would also apply for the non-Zephyr platforms]. uDeviceCfgI2c_t and uDeviceCfgSpi_t would both gain a maxSegmentSize parameter on the end, which would default to zero for those who don't populate it; this parameter would come through in the .dts file as i2c-max-segment-size and spi-max-segment-size and uDeviceOpen() would call the relevant new port function to set it up.

How i2c_transfer() ends up being called ref. max segment size for the uPortI2cControllerSendReceive() case would need some care, otherwise it doesn't look too difficult to do and we could add an nRF52832-based board to the ubxlib test system to test it.

ValterMinute commented 4 months ago

@ValterMinute "I need to write a 256 bytes command and I split it in two 128 bytes writes (with start and stop) or instead of reading 300 bytes in a single read transaction I perform 3..."

I'd probably decompose I2C transactions. Some like the Arduino AVR had a 32-byte buffer, but not sure where that came from, but could just have been a composition buffer, that was accumulated and then flushed. With I2C you're likely sharing with others, so holding the bus excessively might be undesirable for a number of reasons.

Out-bound (to receiver) the maximal UBX packet is 1000 bytes, from the receiver it can be much larger for diagnostic and RXM type messages, which can notionally get to 6-8 KB. RTCM3 around 1024, SPARTN don't recall off the top of my head, but no more than 1.5KB

Personally, I'd probably opt to take data in a piecemeal manner, feeding that into a parser/demuxer with a deeper frame buffer, and skip packets exceeding client side buffering limits. Plus the ability to push data requests into the receiver.

I can't say I've seen the 0xFFFF size reporting, but the LA trace looks compelling, seen other reports on the forum for getting 0x8000. One could decompose to smaller transfer, and then recheck the pending length.

I see the point about shared bus. It's not a concern in my current design, but it could be for future ones. Since the device is not relying on having a whole message transferred in a single I2C transaction, splitting it would definitely be a good idea when you have multiple devices. It may just slow down transfers a bit, but by setting the right value for your scenario you may reach a good compromise.

ValterMinute commented 4 months ago

I made some (ugly) changes to support i2c-max-segment-size. I currently changed only I2C and support only Rx in Send/Receive function (it's used only in this way from gnss layer).

https://github.com/ValterMinute/ubxlib/tree/support_max_segment_size

Now I can get version information and communication works as expected.

RobMeades commented 4 months ago

Woohoo! So that resolved the U_ERROR_COMMON_INVALID_PARAMETER as well?

ValterMinute commented 4 months ago

Yep, that was my dumb mistake :) Thank you for your support @RobMeades

RobMeades commented 4 months ago

Excellent: I have a change already prepared which looks remarkably similar to yours (just has the SPI bit as well). Let me spend the morning testing it and I will post a preview branch here that you could try if you have time. My testing will not be on nRF52832 as I don't currently have one of those but I will set a segment size for the current MCU types, just for the purposes of testing.

Will get back to you soon.

RobMeades commented 4 months ago

Find here:

https://github.com/u-blox/ubxlib/tree/preview_port_i2c_spi_segment_size_rmea

...a preview branch that introduces maxSegmentSize for both the uDeviceCfgI2c_t and uDeviceCfgSpi_t structures. I have tested it with a segment size of 32 bytes and it seems to work fine but I have not tested it on a device that actually has a HW limitation yet (nRF52832). .dts/.overlay entries i2c-max-segment-size and spi-max-segment-size will be obeyed.

If you have the time, please give it a spin for I2C on nRF52832 and see if it resolves your problem. All feedback welcomed.

Assuming it works for you I will get it reviewed internally and then pushed out to master here and will delete the preview branch some time after that.

ValterMinute commented 4 months ago

@RobMeades Thank you, I'll try to test this ASAP.

ValterMinute commented 4 months ago

I tested it on my setup and it works perfectly. Thank you again for the good work!

RobMeades commented 4 months ago

Phew, thanks for confirming, I will update this issue once it is pushed to master here.

RobMeades commented 4 months ago

The change is now on master here, see commit https://github.com/u-blox/ubxlib/commit/93e3ccae2c194781cdd216b0720e0147a4824d0f. I will delete the preview branch sometime next week. Will close this issue now: please feel free to re-open, or open a new issue, if there is more to discuss.