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