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

DMA for SPI master

I'm reading AD-converter data usin nRF51822 SPI-Master. BLE-stack is active so I can't use interrupts with SPI. I get data every 2 ms. Sometimes Events are delayed so long that I get erroneous data from AD.

Is there some way to implement DMA for the SPI-Master, maybe using SPI-slave some way?

Juha Okkonen

  • Hi Bruce,

    the radio notification functionality is a feature that triggers a software interrupt prior to, or after a radio interrupt (see https://devzone.nordicsemi.com/documentation/nrf51/5.0.0/html/group__t__s110___n_r_f___s_o_c___f_u_n_c_t_i_o_n_s.html#ga15378609daca09588e620b64555fc2e8). So if you need to perform stuff uninterrupted between radio events, or synchronize application tasks with radio activity, this is the best way.

    In your case, you could enable the radio notifications to give you an interrupt when the radio interrupt is finished. When the radio event finishes, you can start a repeated timer with your AD interrupt frequency. If the bluetooth connection parameters doesnt crash with your AD frequency, you should be able to get a stable AD read frequency. Note that there will be some drift (depending on your clock source), and you would probably want to add some logic to keep your AD timer synchronized with the radio notifications.

  • Thanks for your reply, Audun.

    But unfortunately our AD runs on its own Crystal Oscillator and for sure it will collide with the radio events. Which also implies that we cannot sync AD to radio notifications.

    I'm just wondering if there's a way to guarantee AD GPIOTE interrupt is serviced within 2ms (maybe 4ms or 8ms) with radio turned on?

    Thanks, Bruce

  • Ah, I understand better now. Length of the radio interrupt is determined by: a) How much data you have put in the softdevice TX buffer b) Procedures initiated by the Master (channel map update, encryption, etc.)

    The softdevice will always try to send as many packets as possible during a single connection event. If you are sending multiple packets, the radio interrupt could be significantly longer (the Master actually decides how many packets can be sent during a connection interval). So, dont put more than X packets (I'm not sure of the exact number) in the TX buffer at a time. Then wait until you get a BLE_EVT_TX_COMPLETE event until you put in more. Secondly, there are control procedures that can happen at any time. There will typically be channel map updates once in a while, but I'm not sure exactly how long radio interrupt that will cause.

    Anyway, I suggest using the radio notifications to trigger a GPIO, and use a logic analyzer or oscilloscope to see how long each interrupt actually takes. You can also have a main loop that toggles a GPIO, and you will see the toggling stopping during interrupts. This will give you a better feel of exactly how long each interrupt is. Note that some control procedures, such as channel map updates, is not something the application is aware of, and you would need a BLE sniffer to see when this is happening.

  • Thanks Audun. I was just doing something similar to what you suggested. I'm toggling a debug GPIO in AD's interrupt GPIOTE interrupt handler. However, from the debug GPIO captured by oscilloscope, I'm missing some interrupts if I turn on advertisement or if I'm in a connection.

    One thing puzzles me is the GPIOTE interrupt is not skewed, but some of them are missing completely. I would imagine in this case a lower stack interrupt pushes GPIOTE interrupt, but not making it disappear.

    Any thought on that?

    Thanks, Bruce

  • Thanks Audun. I was just doing something similar to what you suggested. I'm toggling a debug GPIO in AD's interrupt GPIOTE interrupt handler. However, from the debug GPIO captured by oscilloscope, I'm missing some interrupts if I turn on advertisement or if I'm in a connection.

    One thing puzzles me is the GPIOTE interrupt is not skewed, but some of them are missing completely. I would imagine in this case a lower stack interrupt pushes GPIOTE interrupt, but not making it disappear.

    Any thought on that?

    Thanks, Bruce

1 2 3