본문 바로가기
Study/nRF51xxx(BLE)

nRF51 DK 예제 14 -Real Time Counter(RTC)

by Answer Choi 2015. 3. 12.
반응형


이번 예제는 Real Time Counter입니다.


첨에 RTC(Real Time Clock)인줄 알았는데 


Clock이 아니라 Counter군요.


LED1은 Real Time Counter로 toggle하고, 


LED2는 Counter Compare해서 켜줍니다.



main.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main(void)
{
    leds_config();
 
    lfclk_config();
 
    rtc_config();
   
    while (true)
    {
        __SEV();
        __WFE();
        __WFE();
    }
}
cs


단촐한 main문입니다.


Line 3 : LED를 설정해줍니다.


1
2
3
4
5
static void leds_config(void)
{
    LEDS_CONFIGURE(((1<<COMPARE_EVENT_OUTPUT) | (1<<TICK_EVENT_OUTPUT)));
    LEDS_OFF((1<<COMPARE_EVENT_OUTPUT) | (1<<TICK_EVENT_OUTPUT));
}
cs


Line 5 : LFCLK(Low Frequency Clock)를 설정합니다.


1
2
3
4
5
6
7
static void lfclk_config(void)
{
    ret_code_t err_code = nrf_drv_clock_init(NULL);
    APP_ERROR_CHECK(err_code);
 
    nrf_drv_clock_lfclk_request();
}
cs


3: CLOCK설정을 초기화합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
ret_code_t nrf_drv_clock_init(nrf_drv_clock_config_t const * p_config)
{
    uint32_t result = NRF_SUCCESS;
 
    if (m_clock_cb.module_initialized == false)
    {
        m_clock_cb.hfclk_requests     = 0;
#ifndef SOFTDEVICE_PRESENT
        m_clock_cb.lfclk_requests     = 0;
 
        nrf_clock_xtalfreq_set(CLOCK_CONFIG_XTAL_FREQ);
        nrf_clock_lf_src_set((nrf_clock_lf_src_t)CLOCK_CONFIG_LF_SRC);
 
#if CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC
 
        m_clock_cb.calibration_in_progress = false;
 
        nrf_clock_event_clear(NRF_CLOCK_EVENTS_HFCLKSTARTED);
        nrf_clock_event_clear(NRF_CLOCK_EVENTS_LFCLKSTARTED);
        nrf_clock_event_clear(NRF_CLOCK_EVENTS_DONE);
        nrf_clock_event_clear(NRF_CLOCK_EVENTS_CTTO);
 
        if (p_config == NULL)
        {
            p_config = &m_default_config;
        }
 
        nrf_clock_cal_timer_timeout_set(p_config->cal_interval);
        nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, p_config->interrupt_priority);
 
#endif // CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC
#else // SOFTDEVICE_PRESENT
        uint8_t is_enabled;
        result = sd_softdevice_is_enabled(&is_enabled);
        if((result == NRF_SUCCESS) && !is_enabled)
        {
            result = NRF_ERROR_SOFTDEVICE_NOT_ENABLED;
        }
#endif // SOFTDEVICE_PRESENT
    }
    else
    {
        result = NRF_ERROR_INVALID_STATE;
    }
 
    if (result == NRF_SUCCESS)
    {
        m_clock_cb.module_initialized = true;
    }
 
    return result;
}
cs


5~12 : softdevice가 없으므로 이부분이 실행된 후 값을 return합니다.


7~9 : hfclk와 lfclk를 0으로 초기화합니다.


11: 메인 클럭인 xtal을 16MHz로 설정합니다.


12 : LFCLK source를 32.769kHz crystal oscillator로 설정합니다.


46~51 : 초기화 완료로 설정후 값을 return합니다.


Line 7 : RTC를 초기화합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
static void rtc_config(void)
{
    uint32_t err_code;
 
    err_code = nrf_drv_rtc_init(&rtc, NULL, rtc_handler);
    APP_ERROR_CHECK(err_code);
 
    nrf_drv_rtc_tick_enable(&rtc,true);
 
    err_code = nrf_drv_rtc_cc_set(&rtc,0,COMPARE_COUNTERTIME*RTC0_CONFIG_FREQUENCY,true);
    APP_ERROR_CHECK(err_code);
 
    nrf_drv_rtc_enable(&rtc);
}
cs


5~6 : rtc를 초기화 합니다.

nrf_drv_rtc.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
ret_code_t nrf_drv_rtc_init(nrf_drv_rtc_t const * const p_instance,
                            nrf_drv_rtc_config_t const * p_config,
                            nrf_drv_rtc_handler_t handler)
{
    if (handler)
    {
        m_handlers[p_instance->instance_id] = handler;
    }
    else
    {
        return NRF_ERROR_INVALID_PARAM;
    }
 
    if (p_config == NULL)
    {
        p_config = &m_default_config[p_instance->instance_id];
    }
 
    if (m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED)
    {
        return NRF_ERROR_INVALID_STATE;
    }
 
    nrf_drv_common_irq_enable(p_instance->irq, p_config->interrupt_priority);
    nrf_rtc_prescaler_set(p_instance->p_reg, p_config->prescaler);
    m_cb[p_instance->instance_id].reliable     = p_config->reliable;
    m_cb[p_instance->instance_id].tick_latency = p_config->tick_latency;
    m_cb[p_instance->instance_id].state        = NRF_DRV_STATE_INITIALIZED;
 
    return NRF_SUCCESS;
}
cs


5~8 : rtc_handler변수 m_handlers[0]에 handler를 넣어줍니다.


14~17 : p_config에 default값을 넣어줍니다.


default 값은 아래와 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define RTC0_CONFIG_FREQUENCY 8
#define RTC0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#define RTC0_CONFIG_RELIABLE     false
#define RTC0_INSTANCE_INDEX      0
#define NRF_MAXIMUM_LATENCY_US 2000
 
#define NRF_DRV_RTC_DEFAULT_CONFIG(id)                                                            
        {                                                                                        
         .prescaler          = (uint16_t)(RTC_INPUT_FREQ/RTC##id##_CONFIG_FREQUENCY)-1,    
         .interrupt_priority = RTC##id##_CONFIG_IRQ_PRIORITY,                              
         .reliable           = RTC##id##_CONFIG_RELIABLE,                                  
         .tick_latency       = RTC_US_TO_TICKS(NRF_MAXIMUM_LATENCY_US,RTC##id##_CONFIG_FREQUENCY),
 
        }
cs


24~28 : 위 값들을 기준으로 설정해줍니다.


prescaler=(32768/8)-1=4095

interrupt_priority=APP_IRQ_PRIORITY_LOW

reliable=false

tick_latency=0.016


8 : 설정한 rtc tick을 enable 시킵니다.


10~11 : rtc_CC를 설정합니다.


1
nrf_rtc_cc_set(p_instance->p_reg,channel,val);
cs


CC[0]=24가 됩니다.


prescaler가 4095이므로 4095/32768=0.125 즉, CC는 0.125*24일때 들어오게 됩니다.


Line 11~13


SEV : 다중프로세서의 모든코어에 신호를 보낼 이벤트를 발생시킨다라고 되어있네요.


WFE : 이벤트가 설정될 경우 이를 즉시해제하고 원래상태로 되돌린다고 되어있네요;


아직 정확히 이해가 되지는 않습니다. 이부분이 없어도 동작은 합니다;;


더 자세한 정보는 ARM information center에서~


1
2
3
4
5
6
7
8
9
10
11
static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
{
    if (int_type == NRF_DRV_RTC_INT_COMPARE0)
    {
        nrf_gpio_pin_toggle(COMPARE_EVENT_OUTPUT);
    }
    else if (int_type == NRF_DRV_RTC_INT_TICK)
    {
        nrf_gpio_pin_toggle(TICK_EVENT_OUTPUT);
    }
}
cs


이부분이 LED를 토글하는 부분입니다.


코드 대로하면 LED1은 0.125초마다 토글되고, LED2는 3초마다 토글되야하는데


LED2는 켜지고는 그대로있네요;;




반응형

'Study > nRF51xxx(BLE)' 카테고리의 다른 글

nRF51 DK 예제 16 -TIMER  (0) 2015.03.13
nRF51 DK 예제 15 -TEMPERATURE  (0) 2015.03.12
nRF51 DK 예제 13 - Random Number Generator(RNG)  (0) 2015.03.12
nRF51 DK 예제 12 - ram retention  (0) 2015.03.12
nRF51 SDK 업데이트  (0) 2015.03.09

인기글