Clock frequency detection
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 22 May 2012 11:23:44 +0000 (13:23 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 22 May 2012 11:23:44 +0000 (13:23 +0200)
12 files changed:
milkymist/identifier/__init__.py
software/bios/Makefile
software/bios/boot.c
software/bios/main.c
software/bios/timer.c [deleted file]
software/bios/timer.h [deleted file]
software/include/base/timer.h [new file with mode: 0644]
software/include/hw/id.h
software/libbase/Makefile
software/libbase/board.c
software/libbase/timer.c [new file with mode: 0644]
top.py

index 380022520b82fe15413e4a07b4df8596f2b40963..9ddeda789d717af5ac55c3338ba7ba558783c579 100644 (file)
@@ -16,17 +16,21 @@ def encode_version(version):
        return r
 
 class Identifier:
-       def __init__(self, address, sysid, version):
+       def __init__(self, address, sysid, version, frequency):
                self.sysid = sysid
                self.version = encode_version(version)
+               self.frequency = frequency
                
                self._r_sysid = RegisterField("sysid", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
                self._r_version = RegisterField("version", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
-               self.bank = csrgen.Bank([self._r_sysid, self._r_version], address=address)
+               self._r_frequency = RegisterField("frequency", 32, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
+               regs = [self._r_sysid, self._r_version, self._r_frequency]
+               self.bank = csrgen.Bank(regs, address=address)
                
        def get_fragment(self):
                comb = [
                        self._r_sysid.field.w.eq(self.sysid),
-                       self._r_version.field.w.eq(self.version)
+                       self._r_version.field.w.eq(self.version),
+                       self._r_frequency.field.w.eq(self.frequency)
                ]
                return self.bank.get_fragment() + Fragment(comb)
index 1410b63d6f8e6f13a31577dab66b27f58a5d15c9..e96ef44692b6ee1cece2ffda40883c0b7e28a580 100644 (file)
@@ -1,7 +1,7 @@
 M2DIR=../..
 include $(M2DIR)/software/include.mak
 
-OBJECTS=crt0.o isr.o ddrinit.o timer.o main.o microudp.o tftp.o boot-helper.o boot.o
+OBJECTS=crt0.o isr.o ddrinit.o main.o microudp.o tftp.o boot-helper.o boot.o
 
 all: bios.bin
 
index f4227e315e76fac462e44b7f2eead5a2234473bb..3ea515fdd1955eab20c0353513f5724a921cd00a 100644 (file)
 #include <sfl.h>
 #include <string.h>
 #include <irq.h>
+#include <timer.h>
 
 #include <hw/flash.h>
 #include <hw/mem.h>
 
-#include "timer.h"
 #include "microudp.h"
 #include "tftp.h"
 #include "boot.h"
index dc5a3e2039c7aa786c4f1b29c860bd0067fd1b9d..1aeb4c654145dcf486893b149bc57b6db15f1557 100644 (file)
 #include <irq.h>
 #include <version.h>
 #include <extra/crc.h>
+#include <timer.h>
 
 #include <hw/flash.h>
 #include <hw/minimac.h>
 
 #include "ddrinit.h"
-#include "timer.h"
 #include "boot.h"
 
 enum {
diff --git a/software/bios/timer.c b/software/bios/timer.c
deleted file mode 100644 (file)
index 14e6a8c..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Milkymist SoC (Software)
- * Copyright (C) 2012 Sebastien Bourdeauducq
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <hw/timer.h>
-
-#include "timer.h"
-
-unsigned int get_system_frequency(void)
-{
-       return 83333333; /* TODO */
-}
-
-void timer_enable(int en)
-{
-       CSR_TIMER0_EN = en;
-}
-
-unsigned int timer_get(void)
-{
-       return (CSR_TIMER0_COUNT3 << 24)
-               |(CSR_TIMER0_COUNT2 << 16)
-               |(CSR_TIMER0_COUNT1 << 8)
-               |CSR_TIMER0_COUNT0;
-}
-
-void timer_set_counter(unsigned int value)
-{
-       CSR_TIMER0_COUNT3 = (value & 0xff000000) >> 24;
-       CSR_TIMER0_COUNT2 = (value & 0x00ff0000) >> 16;
-       CSR_TIMER0_COUNT1 = (value & 0x0000ff00) >> 8;
-       CSR_TIMER0_COUNT0 = value & 0x000000ff;
-}
-
-void timer_set_reload(unsigned int value)
-{
-       CSR_TIMER0_RELOAD3 = (value & 0xff000000) >> 24;
-       CSR_TIMER0_RELOAD2 = (value & 0x00ff0000) >> 16;
-       CSR_TIMER0_RELOAD1 = (value & 0x0000ff00) >> 8;
-       CSR_TIMER0_RELOAD0 = value & 0x000000ff;
-}
-
-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());
-}
diff --git a/software/bios/timer.h b/software/bios/timer.h
deleted file mode 100644 (file)
index a7810ed..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Milkymist SoC (Software)
- * Copyright (C) 2012 Sebastien Bourdeauducq
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __TIMER_H
-#define __TIMER_H
-
-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);
-
-#endif /* __TIMER_H */
diff --git a/software/include/base/timer.h b/software/include/base/timer.h
new file mode 100644 (file)
index 0000000..a7810ed
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2012 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TIMER_H
+#define __TIMER_H
+
+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);
+
+#endif /* __TIMER_H */
index 48c928ea54ba8624092ce6e3fc54c8e5b550948f..ae564e5faba2c3ba76fac73c229236f5aab94079 100644 (file)
 #define CSR_ID_SYSTEMH         ID_CSR(0x00)
 #define CSR_ID_SYSTEML         ID_CSR(0x04)
 #define CSR_ID_VERSIONH                ID_CSR(0x08)
-#define CSR_ID_VERSIONL                ID_CSR(0x0c)
+#define CSR_ID_VERSIONL                ID_CSR(0x0C)
+#define CSR_ID_FREQ3           ID_CSR(0x10)
+#define CSR_ID_FREQ2           ID_CSR(0x14)
+#define CSR_ID_FREQ1           ID_CSR(0x18)
+#define CSR_ID_FREQ0           ID_CSR(0x1C)
 
 #endif /* __HW_ID_H */
index 0ee64cc6debb45d3ed0638c088e7a22ca639f83c..e3ddbfb8ee12fd7c16b24617d74a410282aa4e97 100644 (file)
@@ -1,7 +1,7 @@
 M2DIR=../..
 include $(M2DIR)/software/include.mak
 
-OBJECTS=divsi3.o libc.o console.o system.o board.o uart.o softfloat.o softfloat-glue.o vsnprintf.o atof.o
+OBJECTS=divsi3.o libc.o console.o timer.o system.o board.o uart.o softfloat.o softfloat-glue.o vsnprintf.o atof.o
 
 all: libbase.a
 
index b8adcfe96b9f592376126e10de806dd9d725b687..fc9a122de09fc49177aa1c25e866f03f6b44571d 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <version.h>
+#include <timer.h>
 #include <board.h>
 
 static const struct board_desc boards[1] = {
@@ -106,7 +107,8 @@ void board_init(void)
        }
        rev = get_pcb_revision();
        get_soc_version_formatted(soc_version);
-       printf("Detected SoC %s on %s (PCB revision %d)\n", soc_version, brd_desc->name, rev);
+       printf("Detected SoC %s at %dMHz on %s (PCB revision %d)\n", soc_version, get_system_frequency()/1000000,
+              brd_desc->name, rev);
        if(strcmp(soc_version, VERSION) != 0)
                printf("SoC and BIOS versions do not match!\n");
        if(rev > 2)
diff --git a/software/libbase/timer.c b/software/libbase/timer.c
new file mode 100644 (file)
index 0000000..98bb879
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2012 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <hw/timer.h>
+#include <hw/id.h>
+
+#include "timer.h"
+
+unsigned int get_system_frequency(void)
+{
+       return (CSR_ID_FREQ3 << 24)
+               |(CSR_ID_FREQ2 << 16)
+               |(CSR_ID_FREQ1 << 8)
+               |CSR_ID_FREQ0;
+}
+
+void timer_enable(int en)
+{
+       CSR_TIMER0_EN = en;
+}
+
+unsigned int timer_get(void)
+{
+       return (CSR_TIMER0_COUNT3 << 24)
+               |(CSR_TIMER0_COUNT2 << 16)
+               |(CSR_TIMER0_COUNT1 << 8)
+               |CSR_TIMER0_COUNT0;
+}
+
+void timer_set_counter(unsigned int value)
+{
+       CSR_TIMER0_COUNT3 = (value & 0xff000000) >> 24;
+       CSR_TIMER0_COUNT2 = (value & 0x00ff0000) >> 16;
+       CSR_TIMER0_COUNT1 = (value & 0x0000ff00) >> 8;
+       CSR_TIMER0_COUNT0 = value & 0x000000ff;
+}
+
+void timer_set_reload(unsigned int value)
+{
+       CSR_TIMER0_RELOAD3 = (value & 0xff000000) >> 24;
+       CSR_TIMER0_RELOAD2 = (value & 0x00ff0000) >> 16;
+       CSR_TIMER0_RELOAD1 = (value & 0x0000ff00) >> 8;
+       CSR_TIMER0_RELOAD0 = value & 0x000000ff;
+}
+
+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());
+}
diff --git a/top.py b/top.py
index 53b4c04d85cd1c2587abc6348c23e66e8c4beb3c..0c146287e5b5add7ebbc4ccc8324449d07dcb269 100644 (file)
--- a/top.py
+++ b/top.py
@@ -120,7 +120,7 @@ def get():
        # CSR
        #
        uart0 = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
-       identifier0 = identifier.Identifier(csr_offset("ID"), 0x4D31, version)
+       identifier0 = identifier.Identifier(csr_offset("ID"), 0x4D31, version, int(clk_freq))
        timer0 = timer.Timer(csr_offset("TIMER0"))
        csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
                uart0.bank.interface,