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

Compiler issues interfacing sensor with nRF52840-DK

Hello!  I'm interfacing a sensor with an nRF52840 development board and have run into a few issues:

1)  I have a check status function as shown below:

bool ADXL_check_status(int address)
{
   ret_code_t err_code;

    m_xfer_done = false;

    uint8_t reg[1] = {WHO_AM_I_Register};
    err_code = nrf_drv_twi_tx(&m_twi, address, reg, sizeof(reg), false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);

    m_xfer_done = false;

    err_code = nrf_drv_twi_rx(&m_twi, address, &m_sample, sizeof(m_sample));
    APP_ERROR_CHECK(err_code);

    if(m_sample==(uint8_t)WHO_AM_I_RESPONSE)
    {
        NRF_LOG_INFO("Device Detected");
        return true;
    }
    else
    {
        NRF_LOG_INFO("Device Not Detected");
        return false;
    }
}

If I place a breakpoint on the following line:

     if(m_sample==(uint8_t)WHO_AM_I_RESPONSE)

The code will run fine.  Obviously, this works fine with debug mode.  However, if I take away this debug statement (or I try and program the board, which obviously has no breakpoints), the code goes to the following line in app_error_weak.c:

     NRF_BREAKPOINT_COND;

Below is my call stack:

I've tried everything I can think of, including setting the optimization setting to "none" and nothing seems to resolve this issue.  Any ideas what might be causing the issue and how to resolve it?

2)  I'm trying to scale some sensor data using the following equation:

x * 5 *(2^4) / (2^20-1)

I've tried a number of different methods to get this to work but I think there might be an issue with the pow() function?

This line returns a value of 0:

     double scaling_factor = (5*(pow(2,range_val+1)))/(pow(2,20)-1);

This solution returns an infinite value (where x enters the equation with a value of around -9600 or so):

        x *= 5;
        x *= pow(2,4);
        x /= (pow(2,20)-1);

The result is infinite though (multiplying the value by 5 works correctly, multiplying it by 2^4 has no change and the final division sets the value to infinite). 

I even tried just multiplying it by the following line:

        x *= pow(7.6294,-5);

The value of x in this case doesn't change. 

I've tried setting x to be float and double and neither have yielded any changes.  Is there something I can do to achieve the desired math function described?

Any help you can give me would be greatly appreciated.  Thanks!

  • Karl,

    Sorry for the delay, didn't get a chance to respond until today!

    I did try your suggestion for the log:

    NRF_LOG_INFO("Error code: %lu", (unsigned long)err_code);

    It definitely output the error code but it took about 2.5 ms to run, so that will probably need to be saved for diagnostics rather than regular output!

    I didn't realize that any unhandled error defaults to resetting the device!  That's good to know!

    I ended up finding a solution that cut down the time considerably!  Instead of the 260 us (which, oddly enough, only seemed to add something like 160 us, according to the scope . . . which I won't lie, was a bit concerning.  Could be part of the reason for the error, I'm guessing.  It's likely exiting out of the code prior to it being completed so the hardware was playing catchup). 

    I ended up going with the following solution:

    while(nrf_drv_twi_tx(&m_twi, address, reg, sizeof(reg), false)!=0);
    //nrf_delay_us(230);
    //err_code = nrf_drv_twi_tx(&m_twi, address, reg, sizeof(reg), false);
    
    /* Removed - Takes about 2.5 ms */
    //NRF_LOG_INFO("Error code: %lu", (unsigned long)err_code);
    //APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);

    This code allows it to check constantly without sending anything.  Once it's ready, the data will send.  The delay is only around 16 us now, which is a pretty good timing improvement!

    Good learning experience though!  I'll have to go back and follow the code through and see what it's calling to set everything up using the TWIM mode though.  But you are correct, I did base the project around the TWI Sensor project!

    Thanks for all your help!

  • Hello,

    JayDev said:
    Sorry for the delay, didn't get a chance to respond until today!

    No problem at all, take all the time you need.

    JayDev said:
    It definitely output the error code but it took about 2.5 ms to run, so that will probably need to be saved for diagnostics rather than regular output!

    That seems a bit excessive - but logging will always add a delay to your program - what you can do however, such as in this case, is to use the deferred logging feature, which allows you to cache logs without processing them, and then instead running the process when you would be idling. You can see this done in many of our examples as part of the idle_state_handle() function call in the for(;;) loop.

    JayDev said:
    I didn't realize that any unhandled error defaults to resetting the device!  That's good to know!

    Great, I am glad that was helpful. You should also know that you may change this error handling, in the case that an error can be handled without resetting the device.

    JayDev said:
    Instead of the 260 us (which, oddly enough, only seemed to add something like 160 us, according to the scope . . . which I won't lie, was a bit concerning.  Could be part of the reason for the error, I'm guessing.  It's likely exiting out of the code prior to it being completed so the hardware was playing catchup).

    What the function does is schedule a given number of NOP cycles to achieve roughly the delay that is requested - but if a higher priority task comes along(such as the SoftDevice) then its execution time will be added to the delay, since the number of scheduled NOP cycles remains the same. This is one of the reasons why it is not recommended to use NOP(delay_ms/us) cycles for timing delays and scheduling. I agree with your reasoning that it sounds like the code moved on to the next sending before finishing the previous one, probably causing the error you received.

    JayDev said:
    This code allows it to check constantly without sending anything.  Once it's ready, the data will send.  The delay is only around 16 us now, which is a pretty good timing improvement!

    This is a good solution, and a huge time improvement on your previous delay, great!

    JayDev said:
    Good learning experience though!  I'll have to go back and follow the code through and see what it's calling to set everything up using the TWIM mode though.

    I am glad to hear that you see it this way, that is a great way of looking at it!
    Do not hesitate to open a new ticket about the TWIM if you should encounter any issues or questions.

    JayDev said:
    Thanks for all your help!

    No problem at all, I am happy to help.

    Good luck with your development!

    Best regards,
    Karl

Related