class Timer(Module, AutoCSR):
def __init__(self, width=32):
- self._en = CSRStorage()
- self._value = CSRStorage(width, write_from_dev=True)
+ self._load = CSRStorage(width)
self._reload = CSRStorage(width)
+ self._en = CSRStorage()
+ self._update_value = CSR()
+ self._value = CSRStatus(width)
self.submodules.ev = EventManager()
self.ev.zero = EventSourceProcess()
###
- self.comb += [
- If(self._value.storage == 0,
- self._value.dat_w.eq(self._reload.storage)
+ value = Signal(width)
+ self.sync += [
+ If(self._en.storage,
+ If(value == 0,
+ # set reload to 0 to disable reloading
+ value.eq(self._reload.storage)
+ ).Else(
+ value.eq(value - 1)
+ )
).Else(
- self._value.dat_w.eq(self._value.storage - 1)
+ value.eq(self._load.storage)
),
- self._value.we.eq(self._en.storage),
- self.ev.zero.trigger.eq(self._value.storage != 0)
+ If(self._update_value.re, self._value.status.eq(value))
]
+ self.comb += self.ev.zero.trigger.eq(value != 0)
#include <sfl.h>
#include <string.h>
#include <irq.h>
-#include <timer.h>
#include <hw/mem.h>
+#include <hw/csr.h>
#include <net/microudp.h>
#include <net/tftp.h>
int recognized;
static const char str[SFL_MAGIC_LEN] = SFL_MAGIC_ACK;
- timer_enable(0);
- timer_set_reload(0);
- timer_set_counter(get_system_frequency()/4);
- timer_enable(1);
+ timer0_en_write(0);
+ timer0_reload_write(0);
+ timer0_load_write(identifier_frequency_read()/4);
+ timer0_en_write(1);
+ timer0_update_value_write(1);
recognized = 0;
- while(timer_get()) {
+ while(timer0_value_read()) {
if(uart_read_nonblock()) {
char c;
c = uart_read();
recognized = 0;
}
}
+ timer0_update_value_write(1);
}
return 0;
}
#include <irq.h>
#include <version.h>
#include <crc.h>
-#include <timer.h>
+#include <hw/csr.h>
#include <hw/mem.h>
#include <net/microudp.h>
printf("Q/ESC: abort boot\n");
printf("F7: boot from serial\n");
printf("F8: boot from network\n");
- timer_enable(0);
- timer_set_reload(0);
- timer_set_counter(get_system_frequency()*2);
- timer_enable(1);
- while(timer_get()) {
+ timer0_en_write(0);
+ timer0_reload_write(0);
+ timer0_load_write(identifier_frequency_read()*2);
+ timer0_en_write(1);
+ timer0_update_value_write(1);
+ while(timer0_value_read()) {
if(readchar_nonblock()) {
c = readchar();
if((c == 'Q')||(c == '\e')) {
return 0;
}
}
+ timer0_update_value_write(1);
}
return 1;
}
+++ /dev/null
-#ifndef __TIMER_H
-#define __TIMER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-unsigned int get_system_frequency(void);
-void timer_enable(int en);
-unsigned int timer_get(void);
-void timer_set_counter(unsigned int value);
-void timer_set_reload(unsigned int value);
-void busy_wait(unsigned int ms);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __TIMER_H */
M2DIR=../..
include $(M2DIR)/software/common.mak
-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
+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
all: libbase.a
#include <stdlib.h>
#include <string.h>
#include <version.h>
-#include <timer.h>
#include <board.h>
static const struct board_desc boards[1] = {
}
rev = get_pcb_revision();
get_soc_version_formatted(soc_version);
- printf("Detected SoC %s at %dMHz on %s (PCB revision %d)\n", soc_version, get_system_frequency()/1000000,
+ printf("Detected SoC %s at %dMHz on %s (PCB revision %d)\n", soc_version, identifier_frequency_read()/1000000,
brd_desc->name, rev);
if(strcmp(soc_version, VERSION) != 0)
printf("SoC and BIOS versions do not match!\n");
+++ /dev/null
-#include <hw/csr.h>
-
-#include "timer.h"
-
-unsigned int get_system_frequency(void)
-{
- return identifier_frequency_read();
-}
-
-void timer_enable(int en)
-{
- timer0_en_write(en);
-}
-
-unsigned int timer_get(void)
-{
- return timer0_value_read();
-}
-
-void timer_set_counter(unsigned int value)
-{
- timer0_value_write(value);
-}
-
-void timer_set_reload(unsigned int value)
-{
- timer0_reload_write(value);
-}
-
-void busy_wait(unsigned int ds)
-{
- timer_enable(0);
- timer_set_reload(0);
- timer_set_counter(get_system_frequency()/10*ds);
- timer_enable(1);
- while(timer_get());
-}
#include <stdio.h>
#include <system.h>
#include <crc.h>
-#include <timer.h>
#include <hw/csr.h>
#include <hw/flags.h>
#include <hw/mem.h>
}
}
+static void busy_wait(unsigned int ds)
+{
+ timer0_en_write(0);
+ timer0_reload_write(0);
+ timer0_load_write(identifier_frequency_read()/10*ds);
+ timer0_en_write(1);
+ timer0_update_value_write(1);
+ while(timer0_value_read()) timer0_update_value_write(1);
+}
+
void ethreset(void)
{
minimac_phy_reset_write(0);
void time_init(void)
{
- timer0_reload_write(2*identifier_frequency_read());
+ int t;
+
+ timer0_en_write(0);
+ t = 2*identifier_frequency_read();
+ timer0_reload_write(t);
+ timer0_load_write(t);
timer0_en_write(1);
}
{
int t, dt;
- t = timer0_reload_read() - timer0_value_read(); // TODO: atomic read
+ timer0_update_value_write(1);
+ t = timer0_reload_read() - timer0_value_read();
dt = t - *last_event;
if(dt < 0)
dt += timer0_reload_read();