changeset 30:435c6330896c

Set tv_usec in gettimeofday() by using the prescaler counter.
author Daniel O'Connor <darius@dons.net.au>
date Tue, 27 Nov 2012 13:19:11 +1030
parents 077cdff4662a
children 03592ca4d37e
files hw.c rtc.h syscalls.c
diffstat 3 files changed, 16 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/hw.c	Tue Nov 27 13:17:42 2012 +1030
+++ b/hw.c	Tue Nov 27 13:19:11 2012 +1030
@@ -4,9 +4,9 @@
 
 #include "1wire.h"
 #include "lcd.h"
+#include "rtc.h"
 
 #define I2C_TIMEOUT 10000
-
 static void	hw_port_cfg(void);
 
 /* Wait for cnt microseconds */
@@ -77,7 +77,7 @@
     RTC_WaitForLastTask();
 
     /* Set RTC prescaler: set RTC period to 1sec */
-    RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
+    RTC_SetPrescaler(RTC_PRESCALE);
 
     /* Wait until last write operation on RTC registers has finished */
     RTC_WaitForLastTask();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtc.h	Tue Nov 27 13:19:11 2012 +1030
@@ -0,0 +1,11 @@
+/* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
+#define RTC_PRESCALE 32768
+
+/* usec = x * 1e6 / 32768
+ * However, 1e6 / 32768 = 30.5 which will result in a large error (max of 15807 usec), so we use
+ * some extra bits to get more precision. We can scale up until 32768 * n is > 2^32.
+ * This results in a maximum error of 1 usec.
+ */
+#define RTC_PS2USEC(x) ( \
+	(uint32_t)( \
+	    (uint32_t)((1 << 9) * (1e6 / RTC_PRESCALE)) * (RTC_PRESCALE - (x))) >> 9)
--- a/syscalls.c	Tue Nov 27 13:17:42 2012 +1030
+++ b/syscalls.c	Tue Nov 27 13:19:11 2012 +1030
@@ -14,6 +14,7 @@
 #include <sys/time.h>
 
 #include "comm.h"
+#include "rtc.h"
 #include "stm32f10x.h" /* for _get_PSP() from core_cm3.h*/
 
 #undef errno
@@ -120,8 +121,8 @@
 int
 _gettimeofday_r(struct _reent *reent __attribute__((unused)), struct timeval *tp, void *tzp __attribute__((unused))) {
     tp->tv_sec = RTC_GetCounter();
-    tp->tv_usec = 0;
-
+    tp->tv_usec = RTC_PS2USEC(RTC_GetDivider());
+    
     return 0;
 }