Not a working example, just excerpt from code.
ast_timer.h
#define IS_LEAP_YEAR(a) ((a % 400) == 0 || ((a % 4) == 0 && (a % 100)))
#pragma anon_unions
struct ast_calv {
/** Seconds in the range 0 to 59. */
uint32_t sec : 6;
/** Minutes in the range range 0 to 59. */
uint32_t min : 6;
/** Hours in the range 0 to 23. */
uint32_t hour : 5;
/** Day in the range 1 to 31. */
uint32_t day : 5;
/** Month in the range 1 to 12. */
uint32_t month : 4;
/** Year in the range 0 to 63. */
uint32_t year : 6;
};
typedef struct {
union {
uint32_t field;
struct ast_calv FIELD;
};
} ast_calendar_t;
static void sys_tick_cb(void * p_context);
ast_timer.c
static void sys_tick_cb(void * p_context)
{
if( ++Time.FIELD.sec % 60 == 0 ){
Time.FIELD.sec = 0;
Time.FIELD.min++;
if(Time.FIELD.min % 60 == 0 ){
Time.FIELD.min = 0;
Time.FIELD.hour++;
if(Time.FIELD.hour % 24 == 0 ){
Time.FIELD.hour = 0;
Time.FIELD.day++;
switch(Time.FIELD.month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if(Time.FIELD.day % 32 == 0){
Time.FIELD.day = 1;
Time.FIELD.month++;
}
break;
case 4:
case 6:
case 9:
case 11:
if(Time.FIELD.day % 31 == 0){
Time.FIELD.day = 1;
Time.FIELD.month++;
}
break;
case 2:
if( IS_LEAP_YEAR(Time.FIELD.year) ){
if(Time.FIELD.day > 29){
Time.FIELD.day = 1;
Time.FIELD.month++;
}
}else{
if(Time.FIELD.day > 28){
Time.FIELD.day = 1;
Time.FIELD.month++;
}
}
break;
}
if( Time.FIELD.month > 12 ){
Time.FIELD.month = 1;
Time.FIELD.year++;
}
}// end if(Time.FIELD.hour % 24 == 0 )
}
}
}
nRF5x Example
// ticks per second.
#define SYS_TIME_TICK_INTERVAL APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER)
APP_TIMER_DEF(m_sys_timer_id);
void bt_init(void)
{
uint32_t err_code;
// Initialize timer module.
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
err_code = app_timer_create(&m_sys_timer_id, APP_TIMER_MODE_REPEATED, sys_tick_cb );
APP_ERROR_CHECK(err_code);
// Start Timer
err_code = app_timer_start(m_sys_timer_id, SYS_TIME_TICK_INTERVAL, NULL);
APP_ERROR_CHECK(err_code);
}
// Time initialization 2016-01-01T00:00:00
volatile ast_calendar_t Time = {
.FIELD.year = 16,
.FIELD.month = 1,
.FIELD.day = 1,
.FIELD.hour = 0,
.FIELD.min = 0,
.FIELD.sec = 0
};