ADC interrupted with BLE activity

ID: LPCBARESDK-683

Status: Open

First reported: 6.0.14.1114

Fixed in: TBD

Description

If an application enables DMA with the ADC functionality an issue can be observed.

Current situation: During the execution of schedule_while_ble_on API, the application first tries to execute the pending events serialized in the kernel message queue. Then the application reads out the low power clock LPC frequency, if there is still enough time the application will perform the radio calibration based on the time and temperature read out. By default, if the time is >= 2 seconds from the the time of last radio calibration, then it will store the ADC register values in a set of temporary variables. Initialize the ADC for temperature readings, if the temperature is >= 8degC by default, then radio recalibration will be performed by calling rf_recalibration API. After these sets of operation, the ADC values will be reassigned from the old set of temporary values.

At this point, the ADC does not allow the peripheral to trigger the next DMA event. This could be observed when the application is using the BAS service when the ADC is sampling the battery.

Workaround

  • Location: sdk/platform/arch/main

  • Filename: arch_main.c

  • API name: schedule_while_ble_on

Current code

#if !defined(__FPGA__)
        if (arch_rwble_last_event == BLE_EVT_END)
        {
#if defined (__DA14531__)
            rcx20_read_freq(true);
#else
            rcx20_read_freq();
#endif

            uint32_t sleep_duration = 0;
            //if you have enough time run a temperature calibration of the radio
            if (ea_sleep_check(&sleep_duration, 4)) //6 slots -> 3.750 ms
            {
                // check time and temperature to run radio calibrations.
                conditionally_run_radio_cals();
            }
        }
#endif

Modified code

The following code snippet will resolve the issue:

#if !defined(__FPGA__)
        if (arch_rwble_last_event == BLE_EVT_END)
        {
#if defined (__DA14531__)
            rcx20_read_freq(true);
#else
            rcx20_read_freq();
#endif

            uint32_t sleep_duration = 0;
            //if you have enough time run a temperature calibration of the radio
            if (ea_sleep_check(&sleep_duration, 4)) //6 slots -> 3.750 ms
            {

                if (GetBits16(GP_ADC_CTRL_REG, GP_ADC_EN) == 0) // POST SDK6 ENHANCED MODIFICATION
                {
                    // check time and temperature to run radio calibrations.
                    conditionally_run_radio_cals();
                }
            }
        }
#endif