diff --git a/examples/sntp/sntp_example.c b/examples/sntp/sntp_example.c index 78601dd..96066a2 100644 --- a/examples/sntp/sntp_example.c +++ b/examples/sntp/sntp_example.c @@ -20,7 +20,7 @@ #include -// Add extras/sntp component to makefile for this include to work +/* Add extras/sntp component to makefile for this include to work */ #include #define SNTP_SERVERS "0.pool.ntp.org", "1.pool.ntp.org", \ @@ -29,71 +29,36 @@ #define vTaskDelayMs(ms) vTaskDelay((ms)/portTICK_RATE_MS) #define UNUSED_ARG(x) (void)x -// Use GPIO pin 2 -const int gpio_frc2 = 2; -// 1 Hz blink frequency -const int freq_frc2 = 1; - -void SntpTsk(void *pvParameters) +void sntp_tsk(void *pvParameters) { char *servers[] = {SNTP_SERVERS}; UNUSED_ARG(pvParameters); - // Wait until we have joined AP and are assigned an IP + /* Wait until we have joined AP and are assigned an IP */ while (sdk_wifi_station_get_connect_status() != STATION_GOT_IP) { vTaskDelayMs(100); } - // Start SNTP + /* Start SNTP */ printf("Starting SNTP... "); - sntp_set_update_delay(1*60000); - sntp_initialize(1, 0); + /* SNTP will request an update each 5 minutes */ + sntp_set_update_delay(5*60000); + /* Set GMT+1 zone, daylight savings off */ + const struct timezone tz = {1*60, 0}; + /* SNTP initialization */ + sntp_initialize(&tz); + /* Servers must be configured right after initialization */ sntp_set_servers(servers, sizeof(servers) / sizeof(char*)); printf("DONE!\n"); -// struct timespec ts; -// clock_getres(CLOCK_REALTIME, &ts); -// printf("Time resolution: %d secs, %d nanosecs\n", t.tv_sec, t.tv_nsec); -// -// clock_gettime(CLOCK_REALTIME, &t); -// printf("Time: %d secs, %d nanosecs\n", t.tv_sec, t.tv_nsec); - + /* Print date and time each 5 seconds */ while(1) { vTaskDelayMs(5000); - time_t ts = sntp_get_rtc_time(NULL); + time_t ts = time(NULL); printf("TIME: %s", ctime(&ts)); } } -void frc2_interrupt_handler(void) -{ - /* FRC2 needs the match register updated on each timer interrupt */ - timer_set_frequency(FRC2, freq_frc2); - gpio_toggle(gpio_frc2); -} - -// Configure FRC2 to blink the LED. I'm messing with FRC2 just to test if -// it does affect FreeRTOS. -void Frc2Config(void) { - /* configure GPIO */ - gpio_enable(gpio_frc2, GPIO_OUTPUT); - gpio_write(gpio_frc2, 1); - - /* stop timer and mask its interrupt as a precaution */ - timer_set_interrupts(FRC2, false); - timer_set_run(FRC2, false); - - /* set up ISR */ - _xt_isr_attach(INUM_TIMER_FRC2, frc2_interrupt_handler); - - /* configure timer frequency */ - timer_set_frequency(FRC2, freq_frc2); - - /* unmask interrupt and start timer */ - timer_set_interrupts(FRC2, true); - timer_set_run(FRC2, true); -} - void user_init(void) { uart_set_baud(0, 115200); @@ -108,9 +73,6 @@ void user_init(void) sdk_wifi_set_opmode(STATION_MODE); sdk_wifi_station_set_config(&config); - // Mess with FRC2 to test if it interferes with FreeRTOS - Frc2Config(); - - xTaskCreate(SntpTsk, (signed char *)"SNTP", 1024, NULL, 1, NULL); + xTaskCreate(sntp_tsk, (signed char *)"SNTP", 1024, NULL, 1, NULL); } diff --git a/extras/sntp/sntp.h b/extras/sntp/sntp.h index d284d5c..dde9331 100644 --- a/extras/sntp/sntp.h +++ b/extras/sntp/sntp.h @@ -9,48 +9,74 @@ #define _SNTP_H_ #include +#include #include -/// Update SNTP RTC timer -void sntp_update_rtc(time_t t, uint32_t us); - -/// Function used to update the date/time, with microseconds resolution. +/* + * Function used by lwIP sntp module to update the date/time, + * with microseconds resolution. + */ #define SNTP_SET_SYSTEM_TIME_US(sec, us) sntp_update_rtc(sec, us) -/// For the lwIP implementation of SNTP to allow using names for NTP servers. +/* + * For the lwIP implementation of SNTP to allow using names for NTP servers. + */ #define SNTP_SERVER_DNS 1 -/// Number of supported NTP servers +/* + * Number of supported NTP servers + */ #define SNTP_NUM_SERVERS_SUPPORTED 4 -/// Initialize the module, and start requesting SNTP updates. This function -/// must be called only once. -void sntp_initialize(int time_zone, int day_light); +/* + * Initialize the module, and start requesting SNTP updates. This function + * must be called only once. + * WARNING: tz->tz_dsttime doesn't have the same meaning as the standard + * implementation. If it is set to 1, a dst hour will be applied. If set + * to zero, time will not be modified. + */ +void sntp_initialize(const struct timezone *tz); -/// Sets time zone. Allowed values are in the range [-11, 13]. -/// NOTE: Settings do not take effect until SNTP time is updated. It is -void sntp_set_timezone(int time_zone); +/* + * Sets time zone. Allowed values are in the range [-11, 13]. + * NOTE: Settings do not take effect until SNTP time is updated. It is + * recommended to set these parameters only during initialization. + * WARNING: tz->tz_dsttime doesn't have the same meaning as the standard + * implementation. If it is set to 1, a dst hour will be applied. If set + * to zero, time will not be modified. + */ +void sntp_set_timezone(const struct timezone *tz); -/// Sets daylight. -/// NOTE: Settings do not take effect until SNTP time is updated. -void sntp_set_daylight(int day_light); - -/// Returns the time read from RTC counter, in seconds from Epoch. If -/// us is not null, it will be filled with the microseconds. -time_t sntp_get_rtc_time(int32_t *us); - -/// Returns the time in seconds since Epoch. If tloc is not NULL, return -/// value is also stored in the memory pointed by tloc. +/* + * Returns the time in seconds since Epoch. If tloc is not NULL, return + * value is also stored in the memory pointed by tloc. + */ time_t time(time_t *tloc); -/// Set SNTP servers. Up to SNTP_NUM_SERVERS_SUPPORTED can be set. -/// Returns 0 if OK, less than 0 if error. -/// NOTE: This function must NOT be called before sntp_initialize(). +/* + * Set SNTP servers. Up to SNTP_NUM_SERVERS_SUPPORTED can be set. + * Returns 0 if OK, less than 0 if error. + * NOTE: This function must NOT be called before sntp_initialize(). + */ int sntp_set_servers(char *server_url[], int num_servers); -/// Sets the update delay in ms. If requested value is less than 15s, -/// a 15s update interval will be set. +/* + * Sets the update delay in ms. If requested value is less than 15s, + * a 15s update interval will be set. + */ void sntp_set_update_delay(uint32_t ms); +/* + * Returns the time read from RTC counter, in seconds from Epoch. If + * us is not null, it will be filled with the microseconds. + */ +time_t sntp_get_rtc_time(int32_t *us); + +/* + * Update RTC timer. This function is called by the SNTP module each time + * an SNTP update is received. + */ +void sntp_update_rtc(time_t t, uint32_t us); + #endif /* _SNTP_H_ */ diff --git a/extras/sntp/sntp_fun.c b/extras/sntp/sntp_fun.c index efb6da8..35c068d 100644 --- a/extras/sntp/sntp_fun.c +++ b/extras/sntp/sntp_fun.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -15,7 +14,6 @@ #include "sntp.h" #define TIMER_COUNT RTC.COUNTER -#define __UNUSED(var) (void)var // daylight settings // Base calculated with value obtained from NTP server (64 bits) @@ -24,47 +22,35 @@ #define tim_ref (RTC.SCRATCH[2]) // Calibration value #define cal (RTC.SCRATCH[3]) -// Timezone (-11 to +13) -static int8_t tz; -// Daylight savings -static bool dst; -//// Setters and getters for CAL, TZ and DST. -//#define RTC_CAL_SET(val) (RTC.SCRATCH[3] |= (val) & 0x0000FFFF) -//#define RTC_DST_SET(val) (RTC.SCRATCH[3] |= ((val)<<16) & 0x00010000) -//#define RTC_TZ_SET(val) (RTC.SCRATCH[3] |= ((val)<<24) & 0xFF000000) -// -//#define RTC_CAL_GET() (RTC.SCRATCH[3] & 0x0000FFFF) -//#define RTC_DST_GET() ((RTC.SCRATCH[3] & 0x00010000)>>16) -//#define RTC_TZ_GET() ((((int)RTC.SCRATCH[3]) & ((int)0xFF000000))>>24) +// Timezone related data. +static struct timezone stz; // Implemented in sntp.c void sntp_init(void); -// Sets time zone. Allowed values are in the range [-11, 13]. +// Sets time zone. // NOTE: Settings do not take effect until SNTP time is updated. -void sntp_set_timezone(int time_zone) { - tz = time_zone; - //RTC_TZ_SET(time_zone); +void sntp_set_timezone(const struct timezone *tz) { + if (tz) { + stz = *tz; + } else { + stz.tz_minuteswest = 0; + stz.tz_dsttime = 0; + } } -// Sets daylight. -// NOTE: Settings do not take effect until SNTP time is updated. -void sntp_set_daylight(int day_light) { - dst = day_light; - //RTC_DST_SET(day_light); -} - - -void sntp_initialize(int time_zone, int day_light) { +// Initialization +void sntp_initialize(const struct timezone *tz) { + if (tz) { + stz = *tz; + } else { + stz.tz_minuteswest = 0; + stz.tz_dsttime = 0; + } sntp_base = 0; - tz = time_zone; - //RTC_TZ_SET(time_zone); - dst = day_light; - //RTC_DST_SET(day_light); // To avoid div by 0 exceptions if requesting time before SNTP config cal = 1; - //RTC_CAL_SET(1); tim_ref = TIMER_COUNT; sntp_init(); } @@ -91,25 +77,25 @@ inline time_t sntp_get_rtc_time(int32_t *us) { // Check for timer wrap sntp_check_timer_wrap(tim); base = sntp_base + tim - tim_ref; -// secs = base * RTC_CAL_GET() / (1000000U<<12); secs = base * cal / (1000000U<<12); if (us) { -// *us = base * RTC_CAL_GET() % (1000000U<<12); *us = base * cal % (1000000U<<12); } return secs; } -// Syscall implementation +// Syscall implementation. doesn't seem to use tzp. int _gettimeofday_r(struct _reent *r, struct timeval *tp, void *tzp) { - __UNUSED(r); - __UNUSED(tzp); + (void)r; + // Syscall defined by xtensa newlib defines tzp as void* + // So it looks like it is not used. Also check tp is not NULL + if (tzp || !tp) return EINVAL; - printf("DEB; gettimeofday called"); tp->tv_sec = sntp_get_rtc_time((int32_t*)&tp->tv_usec); return 0; } +// Added te get nearer the standard way of using time functions. time_t time(time_t *tloc) { time_t datetime; @@ -118,23 +104,18 @@ time_t time(time_t *tloc) { return datetime; } -/// Update RTC timer. Called by SNTP module each time it receives an update. +// Update RTC timer. Called by SNTP module each time it receives an update. void sntp_update_rtc(time_t t, uint32_t us) { // Apply daylight and timezone correction -// t += (RTC_TZ_GET() + RTC_DST_GET()) * 3600; - t += (tz + dst) * 3600; + t += (stz.tz_minuteswest + stz.tz_dsttime * 60) * 60; // DEBUG: Compute and print drift int64_t sntp_current = sntp_base + TIMER_COUNT - tim_ref; -// int64_t sntp_correct = (((uint64_t)us + (uint64_t)t * 1000000U)<<12) / RTC_CAL_GET(); int64_t sntp_correct = (((uint64_t)us + (uint64_t)t * 1000000U)<<12) / cal; -// printf("\nRTC Adjust: drift = %ld ticks, cal = %d\n", (time_t)(sntp_correct - sntp_current), RTC_CAL_GET()); printf("\nRTC Adjust: drift = %ld ticks, cal = %d\n", (time_t)(sntp_correct - sntp_current), cal); tim_ref = TIMER_COUNT; cal = sdk_system_rtc_clock_cali_proc(); -// RTC_CAL_SET(sdk_system_rtc_clock_cali_proc()); -// sntp_base = (((uint64_t)us + (uint64_t)t * 1000000U)<<12) / RTC_CAL_GET(); sntp_base = (((uint64_t)us + (uint64_t)t * 1000000U)<<12) / cal; }