Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

timer: atomic reads

  • Loading branch information...
commit 581cf5bcb8985ca05de5dd38e53bbd0006a2114f 1 parent 9f81afb
Sébastien Bourdeauducq authored May 13, 2013
24  milkymist/timer/__init__.py
@@ -5,9 +5,11 @@
5 5
 
6 6
 class Timer(Module, AutoCSR):
7 7
 	def __init__(self, width=32):
8  
-		self._en = CSRStorage()
9  
-		self._value = CSRStorage(width, write_from_dev=True)
  8
+		self._load = CSRStorage(width)
10 9
 		self._reload = CSRStorage(width)
  10
+		self._en = CSRStorage()
  11
+		self._update_value = CSR()
  12
+		self._value = CSRStatus(width)
11 13
 		
12 14
 		self.submodules.ev = EventManager()
13 15
 		self.ev.zero = EventSourceProcess()
@@ -15,12 +17,18 @@ def __init__(self, width=32):
15 17
 
16 18
 		###
17 19
 
18  
-		self.comb += [
19  
-			If(self._value.storage == 0,
20  
-				self._value.dat_w.eq(self._reload.storage)
  20
+		value = Signal(width)
  21
+		self.sync += [
  22
+			If(self._en.storage,
  23
+				If(value == 0,
  24
+					# set reload to 0 to disable reloading
  25
+					value.eq(self._reload.storage)
  26
+				).Else(
  27
+					value.eq(value - 1)
  28
+				)
21 29
 			).Else(
22  
-				self._value.dat_w.eq(self._value.storage - 1)
  30
+				value.eq(self._load.storage)
23 31
 			),
24  
-			self._value.we.eq(self._en.storage),
25  
-			self.ev.zero.trigger.eq(self._value.storage != 0)
  32
+			If(self._update_value.re, self._value.status.eq(value))
26 33
 		]
  34
+		self.comb += self.ev.zero.trigger.eq(value != 0)
14  software/bios/boot.c
@@ -7,9 +7,9 @@
7 7
 #include <sfl.h>
8 8
 #include <string.h>
9 9
 #include <irq.h>
10  
-#include <timer.h>
11 10
 
12 11
 #include <hw/mem.h>
  12
+#include <hw/csr.h>
13 13
 
14 14
 #include <net/microudp.h>
15 15
 #include <net/tftp.h>
@@ -33,12 +33,13 @@ static int check_ack(void)
33 33
 	int recognized;
34 34
 	static const char str[SFL_MAGIC_LEN] = SFL_MAGIC_ACK;
35 35
 
36  
-	timer_enable(0);
37  
-	timer_set_reload(0);
38  
-	timer_set_counter(get_system_frequency()/4);
39  
-	timer_enable(1);
  36
+	timer0_en_write(0);
  37
+	timer0_reload_write(0);
  38
+	timer0_load_write(identifier_frequency_read()/4);
  39
+	timer0_en_write(1);
  40
+	timer0_update_value_write(1);
40 41
 	recognized = 0;
41  
-	while(timer_get()) {
  42
+	while(timer0_value_read()) {
42 43
 		if(uart_read_nonblock()) {
43 44
 			char c;
44 45
 			c = uart_read();
@@ -53,6 +54,7 @@ static int check_ack(void)
53 54
 					recognized = 0;
54 55
 			}
55 56
 		}
  57
+		timer0_update_value_write(1);
56 58
 	}
57 59
 	return 0;
58 60
 }
14  software/bios/main.c
@@ -8,8 +8,8 @@
8 8
 #include <irq.h>
9 9
 #include <version.h>
10 10
 #include <crc.h>
11  
-#include <timer.h>
12 11
 
  12
+#include <hw/csr.h>
13 13
 #include <hw/mem.h>
14 14
 #include <net/microudp.h>
15 15
 
@@ -459,11 +459,12 @@ static int test_user_abort(void)
459 459
 	printf("Q/ESC: abort boot\n");
460 460
 	printf("F7:    boot from serial\n");
461 461
 	printf("F8:    boot from network\n");
462  
-	timer_enable(0);
463  
-	timer_set_reload(0);
464  
-	timer_set_counter(get_system_frequency()*2);
465  
-	timer_enable(1);
466  
-	while(timer_get()) {
  462
+	timer0_en_write(0);
  463
+	timer0_reload_write(0);
  464
+	timer0_load_write(identifier_frequency_read()*2);
  465
+	timer0_en_write(1);
  466
+	timer0_update_value_write(1);
  467
+	while(timer0_value_read()) {
467 468
 		if(readchar_nonblock()) {
468 469
 			c = readchar();
469 470
 			if((c == 'Q')||(c == '\e')) {
@@ -479,6 +480,7 @@ static int test_user_abort(void)
479 480
 				return 0;
480 481
 			}
481 482
 		}
  483
+		timer0_update_value_write(1);
482 484
 	}
483 485
 	return 1;
484 486
 }
19  software/include/base/timer.h
... ...
@@ -1,19 +0,0 @@
1  
-#ifndef __TIMER_H
2  
-#define __TIMER_H
3  
-
4  
-#ifdef __cplusplus
5  
-extern "C" {
6  
-#endif
7  
-
8  
-unsigned int get_system_frequency(void);
9  
-void timer_enable(int en);
10  
-unsigned int timer_get(void);
11  
-void timer_set_counter(unsigned int value);
12  
-void timer_set_reload(unsigned int value);
13  
-void busy_wait(unsigned int ms);
14  
-
15  
-#ifdef __cplusplus
16  
-}
17  
-#endif
18  
-
19  
-#endif /* __TIMER_H */
2  software/libbase/Makefile
... ...
@@ -1,7 +1,7 @@
1 1
 M2DIR=../..
2 2
 include $(M2DIR)/software/common.mak
3 3
 
4  
-OBJECTS=setjmp.o libc.o errno.o crc16.o crc32.o console.o timer.o system.o board.o uart.o vsnprintf.o strtod.o qsort.o
  4
+OBJECTS=setjmp.o libc.o errno.o crc16.o crc32.o console.o system.o board.o uart.o vsnprintf.o strtod.o qsort.o
5 5
 
6 6
 all: libbase.a
7 7
 
3  software/libbase/board.c
@@ -3,7 +3,6 @@
3 3
 #include <stdlib.h>
4 4
 #include <string.h>
5 5
 #include <version.h>
6  
-#include <timer.h>
7 6
 #include <board.h>
8 7
 
9 8
 static const struct board_desc boards[1] = {
@@ -88,7 +87,7 @@ void board_init(void)
88 87
 	}
89 88
 	rev = get_pcb_revision();
90 89
 	get_soc_version_formatted(soc_version);
91  
-	printf("Detected SoC %s at %dMHz on %s (PCB revision %d)\n", soc_version, get_system_frequency()/1000000,
  90
+	printf("Detected SoC %s at %dMHz on %s (PCB revision %d)\n", soc_version, identifier_frequency_read()/1000000,
92 91
 	       brd_desc->name, rev);
93 92
 	if(strcmp(soc_version, VERSION) != 0)
94 93
 		printf("SoC and BIOS versions do not match!\n");
37  software/libbase/timer.c
... ...
@@ -1,37 +0,0 @@
1  
-#include <hw/csr.h>
2  
-
3  
-#include "timer.h"
4  
-
5  
-unsigned int get_system_frequency(void)
6  
-{
7  
-	return identifier_frequency_read();
8  
-}
9  
-
10  
-void timer_enable(int en)
11  
-{
12  
-	timer0_en_write(en);
13  
-}
14  
-
15  
-unsigned int timer_get(void)
16  
-{
17  
-	return timer0_value_read();
18  
-}
19  
-
20  
-void timer_set_counter(unsigned int value)
21  
-{
22  
-	timer0_value_write(value);
23  
-}
24  
-
25  
-void timer_set_reload(unsigned int value)
26  
-{
27  
-	timer0_reload_write(value);
28  
-}
29  
-
30  
-void busy_wait(unsigned int ds)
31  
-{
32  
-	timer_enable(0);
33  
-	timer_set_reload(0);
34  
-	timer_set_counter(get_system_frequency()/10*ds);
35  
-	timer_enable(1);
36  
-	while(timer_get());
37  
-}
11  software/libnet/microudp.c
... ...
@@ -1,7 +1,6 @@
1 1
 #include <stdio.h>
2 2
 #include <system.h>
3 3
 #include <crc.h>
4  
-#include <timer.h>
5 4
 #include <hw/csr.h>
6 5
 #include <hw/flags.h>
7 6
 #include <hw/mem.h>
@@ -388,6 +387,16 @@ void microudp_service(void)
388 387
 	}
389 388
 }
390 389
 
  390
+static void busy_wait(unsigned int ds)
  391
+{
  392
+	timer0_en_write(0);
  393
+	timer0_reload_write(0);
  394
+	timer0_load_write(identifier_frequency_read()/10*ds);
  395
+	timer0_en_write(1);
  396
+	timer0_update_value_write(1);
  397
+	while(timer0_value_read()) timer0_update_value_write(1);
  398
+}
  399
+
391 400
 void ethreset(void)
392 401
 {
393 402
 	minimac_phy_reset_write(0);
10  software/videomixer/time.c
@@ -4,7 +4,12 @@
4 4
 
5 5
 void time_init(void)
6 6
 {
7  
-	timer0_reload_write(2*identifier_frequency_read());
  7
+	int t;
  8
+
  9
+	timer0_en_write(0);
  10
+	t = 2*identifier_frequency_read();
  11
+	timer0_reload_write(t);
  12
+	timer0_load_write(t);
8 13
 	timer0_en_write(1);
9 14
 }
10 15
 
@@ -12,7 +17,8 @@ int elapsed(int *last_event, int period)
12 17
 {
13 18
 	int t, dt;
14 19
 
15  
-	t = timer0_reload_read() - timer0_value_read(); // TODO: atomic read
  20
+	timer0_update_value_write(1);
  21
+	t = timer0_reload_read() - timer0_value_read();
16 22
 	dt = t - *last_event;
17 23
 	if(dt < 0)
18 24
 		dt += timer0_reload_read();

0 notes on commit 581cf5b

Please sign in to comment.
Something went wrong with that request. Please try again.