Attaching RTTviewer significantly changes interrupt characteristics

Hello,

nRF52840

ncs-v2.5.0-rc2

I am using a GPIO interrupt to trigger a callback on every edge on a particular GPIO. I am then timing the difference in time between interrupts in order to make calculations, such as decoding FSK and Manchester data. I got this to work really well but I was using the RTTviewer as my terminal. As soon as I disconnect the RTT terminal my algorithm stops working. I have discovered that the FSK data that I am getting is very well defined when the RTTviewer is attached. That is, there are very distinct frequencies. When I disconnect RTT the frequencies are much less defined and it becomes impossible to recover data from them.

Any reason why attaching RTTviewer would change the behavior of the interrupt? Timer? execution speed? thread handling (not that I even have extra threads..)?

I have attached two histograms, showing time_diffs between interrupts with RTTviewer both attached and unattached.

(psuedo code snippet)

void gpio_cb()
{
    this_time = get_time()
    time_diff = this_time - last_time // time_diff used later to make calculations and decide which frequency the FSK is operating at. WORKS WHEN RTTviewer IS ATTACHED!
    last_time = this_time
    ...
    //other calculations are made
    //works GREAT when RTTviewer is attached
    ...
}

Histogram of "time_diff" values without RTTviewer

Histogram of "time_diff" values with RTTviewer (literally just clicked connect->select correct options and MCU->okay, without even restarting it)

Thanks,

Nathan

Parents
  • Just to add some more explanation to the histograms above:

    I'm expecting two distinct frequencies (and therefore, periods) from my digital FSK signal. So by measuring the time_diff I'm able to measure the period between oscillations and decide which frequency it belongs to. If I take many time_diff (period) readings and plot them on a histogram, I should see two very distinct periods begin to emerge. The more clear these two periods are the better, as the algorithm would be able to place each time_diff reading in the correct category easier. I get a really good histogram when I attach the RTTviewer, as shown in the second histogram. However, in the first histogram the periods are more scattered about and less consistent. This leads to inconsistent behavior of the algorithm, especially down the line when it uses the demodulated FSK data to make more decisions.

    This could probably be handled in software by just fiddling with the quantization parameters. However, there are more problems still down the line when it comes to the timing of flipping between the two frequencies that I don't know would be fixed.

  • Debugging and RTT forces  HFCLK to be set.
    See SPIS: last byte missing if JTAG RTT disabled, otherwise ok

    Could this be the cause of your problem?

    Regards,
    Sigurd Hellesvik

  • For anyone wondering how to make GPIOTE NRFX drivers play nicely with Zephyr GPIO APIs, this post should help

    devzone.nordicsemi.com/.../ncs-v2-6-0-instructions-to-use-gpiote-and-zephyr-gpio-api

  • Nathan45 said:
    I'm not seeing a significant improvement between using the PPI to trigger the capture task of the clock vs doing all of that within the interrupt just testing them head to head. I'm going to try my use case again using PPI to see if it works better than before with and without RTT connected.

    Oh well, I guess the main reason to put this on PPI is to avoid issues with timing when you introduce BLE later.

    That being said, let us figure out what does not work here.

    Could you specify in what regard you do not see any improvement?
    It would be interesting to see if RTT has any effect on the PPI here as well, so I am looking forward to those results.

  • What I mean by not seeing any improvement is this:

    Run a test by writing a stripped down program that only contains a zephyr API gpio callback that captures time differentials and record those in an array.

    Tun another test by writing a stripped down program that only contains a program which uses PPI to capture the clock and uses either the zephyr gpio interrupts or EGU interrupts to record the differentials to an array.

    If you compare the two array's standard deviation and means they are not very different. HOWEVER. When I looked at the data in excel It turns out it makes more of a difference than I initially thought. For example, here is a capture of the data that I received. On the top is the old way (Zephyr APIs) and the bottom is the new way (GPIOTE+PPI+CLOCK+EGU). Significantly less noise. MOST IMPORTANTLY! I can confirm that this method is NOT affected by RTT!

    I'm not sure if I'm out of the woods yet for this project but for now I think the RTT issue is bypassed at least.

    Was there ever an answer on why RTT was causing a problem to begin with? I had an idea. In my original Zephyr API callback that contained my FSK algorithm, I was starting a k_timer over and over so I could tell when the whole thing was over. The reasoning was that so long as I kept kicking the timer it wouldn't expire so once the data stopped coming in the timer would expire and signal that data had stopped coming in. However, I noticed that even after I got the new way working, adding this k_timer_start() function into the new EGU callback was enough to ruin the algorithm. Let me put it this way:

    Old way + k_timer_start() + RTT-connected = works

    Old way + k_timer_start() = doesn't work

    New way + k_timer_start() + RTT-connected = works very poorly

    New way + k_timer_start() = works but not well

    New way = works 

    Could RTT and k_timer APIs have an interaction? Just a thought. 

    Thanks for your help, I think this issue can be closed.

  • Good to hear that the new method solves the RTT problem!

    And thanks for the summary, always helps a ton of other customers or people from support find the same issue later. For that reason I will mark your previous comment as "Verified Answer", so people find it easier.

    For the rest of your thoughts: I have a colleague who I think might have some insight into this, but he is busy the next couple of days. After that, I will ask him to read over and return here with what we think.

  • Hear thy, hear thy: the thoughts have arrived:

    Firstly, some times running things from interrupts can be a poor idea in zephyr. Maybe start the timer from something else than interrupt context?

    Secondly, you already have a timer running, no? Instead of starting a new timer for your timeout, you can create a new CC value with its own interrupt and then use that one for your timeout.

    If you want to discuss this further I suggest that you start a new ticket, so we do not clog this one.

Reply
  • Hear thy, hear thy: the thoughts have arrived:

    Firstly, some times running things from interrupts can be a poor idea in zephyr. Maybe start the timer from something else than interrupt context?

    Secondly, you already have a timer running, no? Instead of starting a new timer for your timeout, you can create a new CC value with its own interrupt and then use that one for your timeout.

    If you want to discuss this further I suggest that you start a new ticket, so we do not clog this one.

Children
No Data
Related