This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

using ADC and SD Streaming

Hi,

I've set up a streaming solution that is easily streaming 4+kBytes/s to an iPhone. I've also set up an ADC service that is sampling at 2,083 Hz 10 bit mode, using a PPI channel from timer2->compare[0] event to ADC->TASKS_START event. I've kept the ADC ISR very tight. The problem is when I combine the two and try to stream RT data. I get good reproduction of the input waveform except that every 0.027 sec, or so, it drops 6-7 samples. I've kept the ISR short enough that I am able to run the ADC interrupt in _HIGH mode without impacting the BLE (although if the SD is suppressing the PPI channel during the transmission then I'm not really testing that assertion).

I checked that the ADC ISR routine is NOT being called for the dropped samples.

Questions

  1. Has anyone run into this - and if so is there a solution? (I searched the data base to no avail)
  2. Does the SD suppress the PPI channels during radio use? I thought it would not.

I'm using 5.2 and SD 6.0 as I haven't had time to accommodate the changes in the new release yet.

Any help appreciated.

Scott

  • Hi Scott

    Sampling rate of 2kHz with the ADC not possible with the current softdevice and the current hardware. The reasons behind that are discussed on this thread. However, it should be possible to sample with several kHz with the third revision nRF51 hardware that will be released in a few weeks.

    It does not help in this case to set the priority of the ADC interrupt to "Application High", because the radio interrupts related to the BLE protocol still have higher priority. The BLE radio interrupts run with LowerStack priority, see figures 76 and 77 in the nRF51 Series Reference Manual v2.1.

    You are correct, by enabling PPI, you are independent of the CPU, but for the ADC sampling, you are using the PPI in one step and the CPU in another step. First, TIMER2 will start the ADC sampling, independent of the CPU, by triggering the ADC->START task (NRF_ADC->TASKS_START) and this is done via PPI channel. The ADC will use 68us to create the sample and then put the result in the ADC->RESULT register. The ADC->RESULT register only contains one sample, so you need the CPU to extract data from the ADC->RESULT register before the ADC samples again (typically performed in the ADC interrupt handler), if you fail to do so, the data in the ADC->RESULT register will be overridden. The CPU is blocked for ca 0.8-6.0 seconds by the S110 BLE softdevice because of BLE connection event. How long the CPU is blocked depends on the amount of data that are sent over the BLE link in each BLE connection event. This means that the CPU is not able to extract data from the ADC->RESULT register when it is blocked by the softdevice.

  • Stefan,

    Thanks. That helps a lot. Is there information available on the new hardware. I can sign an NDA.

    Specifically, is it pin compatible with the current hardware so we could re-work our current prototypes?

    Also, how do I sent the number of packets/transmission? I can't find a reference for that.

    Thanks again

  • A follow up question as well.

    Despite the warnings in the documentation I tried setting the priority to the ADC handling routine to _HIGH. The ADC start task is tied to the timer2 cpm[0] through ppi channel 0 as shown below. With this arrangement the BLE works fine but I'm still dropping the point during the transmission.

    My expectation would have been either to not drop points as the interrupt is HIGH or to have the BLE not work as it was interfering with the radio.

    I had thought the PPI channels and peripherals were independent of the CPU and therefore timer2 would trigger the ADC even during the radio usage AND given that the interrupt priority of the ADC was high the interrupt would get serviced resulting in one of the two above results.

    My question is why did neither of the two possible outcome occur? It seems like the SD is suppressing PPI channel 0? Is that correct?

    void ars_audio_init() {
    NRF_ADC->INTENSET   = ADC_INTENSET_END_Msk;
    NRF_ADC->CONFIG =   (ADC_CONFIG_RES_10bit               << ADC_CONFIG_RES_Pos)     |
                        (MICROPHONE_INPUT_PRESCALING        << ADC_CONFIG_INPSEL_Pos)  |
                        (MICROPHONE_REFERENCE_PRESCALING    << ADC_CONFIG_REFSEL_Pos)  |
                        (MICROPHONE_ANALOG_INPUT            << ADC_CONFIG_PSEL_Pos)    |
                        (ADC_CONFIG_EXTREFSEL_None          << ADC_CONFIG_EXTREFSEL_Pos);
    NRF_ADC->EVENTS_END = 0;
    NRF_ADC->ENABLE     = ADC_ENABLE_ENABLE_Enabled;
    
    // Enable ADC interrupt
    NVIC_ClearPendingIRQ(ADC_IRQn);
    NVIC_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_HIGH);
    NVIC_EnableIRQ(ADC_IRQn);
    
    //Setup the power control for the microphone
    
    //Also set up microphone pin with high drive
    
    NRF_GPIO->PIN_CNF[MICROPHONE_POWER_PIN_NUMBER] = 0x301;  //output and high drive
    nrf_gpio_pin_clear(MICROPHONE_POWER_PIN_NUMBER);
    
    sd_ppi_channel_assign(0, &(NRF_TIMER2->EVENTS_COMPARE[0]), &(NRF_ADC->TASKS_START));
    sd_ppi_channel_enable_clr(0x1);
    

    }

  • The third revision hardware will be pin compatible with the current second revision. for your other question/questions, I recommend to create other thread/threads to make it easier for other users to find our questions and answers, see devzone.nordicsemi.com/.../ devzone.nordicsemi.com/.../ devzone.nordicsemi.com/.../

  • I have added to my former reply in order to answer your questions.

Related