nrf5-calendar-example SOFTDEVICE: INVALID MEMORY ACCESS

I try to integrate https://github.com/NordicPlayground/nrf5-calendar-example into Keil project. But the following error messages shown when accessing NRF_CLOCK.

error messages

nrf5-calendar-example SOFTDEVICE: INVALID MEMORY ACCESS

source code

int main(void) {
    _initVariables();
    

    // Initialize.
    log_init(); // Power_saving
    uart_init(); // Power_saving
    //_showInfo();
    fstorageInit();
    batteryVoltageInit();
    timerInit();
    button_events_init();
    scheduler_init();
    power_management_init();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    db_discovery_init();
    services_init();
    advertising_init();
    conn_params_init();
    timerPeriodStart();
    timerStart();
    

    //  SOFTDEVICE: INVALID MEMORY ACCESS occurred when running the following code
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
    
     nrf_cal_init();
     nrf_cal_set_callback(calendar_updated, 4);

}

  • No assert now. But time is not correct after calling nrf_cal_set_time(). The log message is as follows.

     <debug> app: 2022-6-28 17:24:45
     0>
     0> <debug> app: nrf_cal_set_time(2022, 6, 28, 17, 24, 45
     0>
     0> <info> app:
     0>
     0> <debug> app: Uncalibrated time:    07/28/22 - 17:39:40
     0>

  • 4657.nrf_calendar.h

    /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
     *
     * The information contained herein is property of Nordic Semiconductor ASA.
     * Terms and conditions of usage are described in detail in NORDIC
     * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
     *
     * Licensees are granted free, non-transferable use of the information. NO
     * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
     * the file.
     *
     */
     
    #include "nrf_calendar.h"
    #include "nrf.h"
    #include "nrf_log.h"
    
    static bool gCalTimeSet = false;
    static struct tm time_struct, m_tm_return_time; 
    static time_t m_time, m_last_calibrate_time = 0;
    static float m_calibrate_factor = 0.0f;
    static uint32_t m_rtc_increment = 60;
    static void (*nrf_cal_event_callback)(void) = 0;
    
    void nrf_cal_updated(void) {
        //nrf_cal_print_current_time();
    }
    
    void nrf_cal_init(void) {
        gCalTimeSet          = false;
        CAL_RTC->EVTENSET    = RTC_EVTENSET_COMPARE0_Msk;
        CAL_RTC->INTENSET    = RTC_INTENSET_COMPARE0_Msk;
        CAL_RTC->CC[0]       = m_rtc_increment * 8;
        CAL_RTC->TASKS_START = 1;
        NVIC_SetPriority(CAL_RTC_IRQn, CAL_RTC_IRQ_Priority);
        NVIC_EnableIRQ(CAL_RTC_IRQn);
        nrf_cal_set_callback(nrf_cal_updated, 4);
    }
    
    void nrf_cal_set_callback(void (*callback)(void), uint32_t interval) {
        // Set the calendar callback, and set the callback interval in seconds
        nrf_cal_event_callback = callback;
        m_rtc_increment = interval;
        m_time += CAL_RTC->COUNTER / 8;
        CAL_RTC->TASKS_CLEAR = 1;
        CAL_RTC->CC[0] = interval * 8;  
    }
     
    void nrf_cal_set_time(uint32_t year, uint32_t month, uint32_t day, uint32_t hour, uint32_t minute, uint32_t second) {
        NRF_LOG_DEBUG("nrf_cal_set_time(%u, %u, %u, %u, %u, %u\n", year, month, day, hour, minute, second);
        static time_t uncal_difftime, difftime, newtime;
        time_struct.tm_year = year - 1900;
        time_struct.tm_mon  = month;
        time_struct.tm_mday = day;
        time_struct.tm_hour = hour;
        time_struct.tm_min  = minute;
        time_struct.tm_sec  = second;   
        newtime = mktime(&time_struct);
        CAL_RTC->TASKS_CLEAR = 1;  
        
        // Calculate the calibration offset 
        if (m_last_calibrate_time != 0) {
            difftime = newtime - m_last_calibrate_time;
            uncal_difftime = m_time - m_last_calibrate_time;
            m_calibrate_factor = (float)difftime / (float)uncal_difftime;
        }
        
        // Assign the new time to the local time variables
        m_time = m_last_calibrate_time = newtime;
        gCalTimeSet = true;
    }    
    
    struct tm *nrf_cal_get_time(void) {
        time_t return_time;
        return_time = m_time + CAL_RTC->COUNTER / 8;
        m_tm_return_time = *localtime(&return_time);
        return &m_tm_return_time;
    }
    
    struct tm *nrf_cal_get_time_calibrated(void) {
        time_t uncalibrated_time, calibrated_time;
        if(m_calibrate_factor != 0.0f)
        {
            uncalibrated_time = m_time + CAL_RTC->COUNTER / 8;
            calibrated_time = m_last_calibrate_time + (time_t)((float)(uncalibrated_time - m_last_calibrate_time) * m_calibrate_factor + 0.5f);
            m_tm_return_time = *localtime(&calibrated_time);
            return &m_tm_return_time;
        }
        else return nrf_cal_get_time();
    }
    
    char *nrf_cal_get_time_string(bool calibrated) {
        static char cal_string[80];
        strftime(cal_string, 80, "%x - %H:%M:%S", (calibrated ? nrf_cal_get_time_calibrated() : nrf_cal_get_time()));
        return cal_string;
    }
     
    void CAL_RTC_IRQHandler(void) {
        if (CAL_RTC->EVENTS_COMPARE[0]) {
            CAL_RTC->EVENTS_COMPARE[0] = 0;
            CAL_RTC->TASKS_CLEAR = 1;
            m_time += m_rtc_increment;
            if (nrf_cal_event_callback != NULL) {
                nrf_cal_event_callback();
            }    
        }
    }
    void nrf_cal_print_current_time(void) {
        if (gCalTimeSet) {
            NRF_LOG_DEBUG("Uncalibrated time:\t%s\r\n", nrf_cal_get_time_string(false));
            NRF_LOG_DEBUG("Calibrated time:\t%s\r\n", nrf_cal_get_time_string(true));
        }    
    }
    # SEGGER J-Link RTT Viewer V6.32i Terminal Log File
    # Compiled: 15:22:50 on Jul 24 2018
    # Logging started @ 28 Jun 2022 17:23:49
     0> <info> app: ========| flash info |========
     0> <info> app: erase unit:   4096 bytes
     0> <info> app: program unit: 4 bytes
     0> <info> app: end address: 0x7FFFF
     0> <info> app: ==============================
     0> <info> app_timer: RTC: initialized.
     0> <debug> app: NOR_DATA_PERIOD=819
     0> 
     0> <debug> app: NOR_RECORD_PERIOD=8192
     0> 
     0> <info> app: bsp_button_longkey_handler 0.
     0> <info> app: POWER_ON.
     0> <info> app: External devices initializing start
     0> <info> app: Reg 0 20
     0> <info> app: Reg 9 A
     0> <info> app: Reg A D
     0> <info> app: Reg 1 B
     0> <info> app: Reg 2 D
     0> <info> app: Reg D F
     0> <info> app: Reg E 13
     0> <info> app: Reg 36 10
     0> <info> app: Reg 37 13
     0> <info> app: Reg 5 11
     0> <info> app: Reg 6 13
     0> <info> app: Reg F 15
     0> <info> app: Reg 10 19
     0> <info> app: Reg 3 16
     0> <info> app: Reg 4 19
     0> <info> app: Reg 7 17
     0> <info> app: Reg 8 19
     0> <info> app: Reg 11 1B
     0> <info> app: Reg 12 1F
     0> <info> app: Reg 43 0
     0> <info> app: Reg 44 0
     0> <info> app: Reg B 1D
     0> <info> app: Reg C 1F
     0> <info> app: Reg 13 21
     0> <info> app: Reg 14 25
     0> <info> app: Reg 1D 3F
     0> <info> app: Reg 64 0
     0> <info> app: Reg 65 27
     0> <info> app: Reg 66 0
     0> <info> app: Reg 67 27
     0> <info> app: Reg 68 0
     0> <info> app: Reg 69 27
     0> <info> app: Reg 52 2C
     0> <info> app: Reg 53 2C
     0> <info> app: Reg 6A 32
     0> <info> app: Reg 6B 38
     0> <info> app: Reg 1E 101
     0> <info> app: Reg 20 3
     0> <info> app: Reg 21 2
     0> <info> app: Reg 22 802084
     0> <info> app: Reg 23 124218
     0> <info> app: Reg 4B F
     0> <info> app: Reg 50 18
     0> <info> app: Reg 31 20
     0> <info> app: Reg 39 5
     0> <info> app: Reg 4E 0
     0> <info> app: Reg 4E 8
     0> <info> app: Reg 45 8
     0> <info> app: Reg 46 13
     0> <info> app: Reg 47 14
     0> <info> app: Reg 48 1F
     0> <info> app: Reg 0 21
     0> <info> app: External devices initializing finish
     0> <info> app: bsp_button_longkey_handler 1.
     0> <debug> nrf_ble_gatt: Requesting to update ATT MTU to 185 bytes on connection 0x0.
     0> <info> app: Connected.
     0> <debug> nrf_ble_gatt: Peer on connection 0x0 requested an ATT MTU of 527 bytes.
     0> <debug> nrf_ble_gatt: Updating ATT MTU to 185 bytes (desired: 185) on connection 0x0.
     0> <debug> nrf_ble_gatt: ATT MTU updated to 185 bytes on connection 0x0 (response).
     0> <debug> nrf_ble_gatt: Peer on connection 0x0 requested a data length of 251 bytes.
     0> <debug> nrf_ble_gatt: Updating data length to 27 on connection 0x0.
     0> <debug> nrf_ble_gatt: Data length updated to 27 on connection 0x0.
     0> <debug> nrf_ble_gatt: max_rx_octets: 27
     0> <debug> nrf_ble_gatt: max_tx_octets: 27
     0> <debug> nrf_ble_gatt: max_rx_time: 2120
     0> <debug> nrf_ble_gatt: max_tx_time: 2120
     0> <info> app: Received data from BLE NUS. Writing data on UART.
     0> <debug> app:  54 49 4D 45 20 32 30 32|TIME 202
     0> <debug> app:  32 2D 30 36 2D 32 38 20|2-06-28 
     0> <debug> app:  31 37 3A 32 34 3A 34 35|17:24:45
     0> <debug> app: length=24
     0> <debug> app: data[0]=0x54 T
     0> <debug> app: data[1]=0x49 I
     0> <debug> app: data[2]=0x4D M
     0> <debug> app: data[3]=0x45 E
     0> <debug> app: data[4]=0x20  
     0> <debug> app: data[5]=0x32 2
     0> <debug> app: data[6]=0x30 0
     0> <debug> app: data[7]=0x32 2
     0> <debug> app: data[8]=0x32 2
     0> <debug> app: data[9]=0x2D -
     0> <debug> app: data[10]=0x30 0
     0> <debug> app: data[11]=0x36 6
     0> <debug> app: data[12]=0x2D -
     0> <debug> app: data[13]=0x32 2
     0> <debug> app: data[14]=0x38 8
     0> <debug> app: data[15]=0x20  
     0> <debug> app: data[16]=0x31 1
     0> <debug> app: data[17]=0x37 7
     0> <debug> app: data[18]=0x3A :
     0> <debug> app: data[19]=0x32 2
     0> <debug> app: data[20]=0x34 4
     0> <debug> app: data[21]=0x3A :
     0> <debug> app: data[22]=0x34 4
     0> <debug> app: data[23]=0x35 5
     0> <debug> app: state=1
     0> 
     0> <debug> app: 2 2
     0> 
     0> <debug> app: 0 0
     0> 
     0> <debug> app: 2 2
     0> 
     0> <debug> app: 2 2
     0> 
     0> <debug> app: 6 6
     0> 
     0> <debug> app: 0 0
     0> 
     0> <debug> app: 8 8
     0> 
     0> <debug> app: 2 2
     0> 
     0> <debug> app: 7 7
     0> 
     0> <debug> app: 1 1
     0> 
     0> <debug> app: 4 4
     0> 
     0> <debug> app: 2 2
     0> 
     0> <debug> app: 5 5
     0> 
     0> <debug> app: 4 4
     0> 
     0> <debug> app: 2022-6-28 17:24:45
     0> 
     0> <debug> app: nrf_cal_set_time(2022, 6, 28, 17, 24, 45
     0> 
     0> <info> app: 
     0> 
     0> <debug> app: Uncalibrated time:	07/28/22 - 17:39:40
     0> 
     0> <debug> app: Calibrated time:	07/28/22 - 17:39:40
     0> 
     0> <debug> app: Uncalibrated time:	07/28/22 - 18:12:48
     0> 
     0> <debug> app: Calibrated time:	07/28/22 - 18:12:48
     0> 
     0> <debug> app: Uncalibrated time:	07/28/22 - 18:45:52
     0> 
     0> <debug> app: Calibrated time:	07/28/22 - 18:45:52
     0> 
     0> <debug> app: Uncalibrated time:	07/28/22 - 19:18:56
     0> 
     0> <debug> app: Calibrated time:	07/28/22 - 19:18:56
     0> 
     0> <debug> app: Uncalibrated time:	07/28/22 - 19:52:04
     0> 
     0> <debug> app: Calibrated time:	07/28/22 - 19:52:04
     0> 
     0> <debug> app: Uncalibrated time:	07/28/22 - 20:25:03
     0> 
     0> <debug> app: Calibrated time:	07/28/22 - 20:25:03
     0> 
     0> <debug> app: Uncalibrated time:	07/28/22 - 20:58:11
     0> 
     0> <debug> app: Calibrated time:	07/28/22 - 20:58:11
     0> 
     0> <debug> app: Uncalibrated time:	07/28/22 - 21:31:11
     0> 
     0> <debug> app: Calibrated time:	07/28/22 - 21:31:11
     0> 
    

  • After I modified nrf_cal_init() as follows. Time is almost correct except month.

    void nrf_cal_init(void) {
        gCalTimeSet          = false;
        // Configure the RTC for 1 minute wakeup (default)
        CAL_RTC->PRESCALER   = 0xFFF;
        CAL_RTC->EVTENSET    = RTC_EVTENSET_COMPARE0_Msk;
        CAL_RTC->INTENSET    = RTC_INTENSET_COMPARE0_Msk;
        CAL_RTC->CC[0]       = m_rtc_increment * 8;
        CAL_RTC->TASKS_START = 1;
        NVIC_SetPriority(CAL_RTC_IRQn, CAL_RTC_IRQ_Priority);
        NVIC_EnableIRQ(CAL_RTC_IRQn);
        nrf_cal_set_callback(nrf_cal_updated, 4);
    }

    Log messages.

    <debug> app: nrf_cal_set_time(2022, 6, 28, 18, 0, 14)
     0>
     0> <info> app:
     0>
     0> <debug> app: Uncalibrated time:    07/28/22 - 18:00:14

  • The month is off by one because time.h counts the first month from zero.

Related