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);

}

Parents
  • 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 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 (*cal_event_callback)(void) = 0;
    
    void nrf_cal_print_current_time(void) {
        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));
    }
    
    void nrf_cal_updated(void) {
        nrf_cal_print_current_time();
    }
    
    void nrf_cal_set_callback(void (*callback)(void), uint32_t interval) {
        NRF_LOG_DEBUG("nrf_cal_set_callback() e\n");
        // Set the calendar callback, and set the callback interval in seconds
        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;
        NRF_LOG_DEBUG("nrf_cal_set_callback() x\n");
    }
    
    void nrf_cal_init(void) {
        NRF_LOG_DEBUG("nrf_cal_init() e\n");
        // Select the 32 kHz crystal and start the 32 kHz clock
        NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos;
        NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_LFCLKSTART = 1;
        while(NRF_CLOCK->EVENTS_LFCLKSTARTED == 0);
        NRF_LOG_DEBUG("1\n");
        
        // 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;
        NRF_LOG_DEBUG("2\n");
        NVIC_SetPriority(CAL_RTC_IRQn, CAL_RTC_IRQ_Priority);
        NRF_LOG_DEBUG("3\n");
        NVIC_EnableIRQ(CAL_RTC_IRQn);
        NRF_LOG_DEBUG("4\n");
        nrf_cal_set_callback(nrf_cal_updated, 4);
        NRF_LOG_DEBUG("nrf_cal_init() x\n");
    }
     
    void nrf_cal_set_time(uint32_t year, uint32_t month, uint32_t day, uint32_t hour, uint32_t minute, uint32_t 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;
    }    
    
    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) {
        NRF_LOG_DEBUG("CAL_RTC_IRQHandler()\n");
        if(CAL_RTC->EVENTS_COMPARE[0])
        {
            CAL_RTC->EVENTS_COMPARE[0] = 0;
            
            CAL_RTC->TASKS_CLEAR = 1;
            
            m_time += m_rtc_increment;
            if(cal_event_callback) cal_event_callback();
        }
    }
    

Reply Children
No Data
Related