summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cesar/ecos/packages/hal/sparc/leon/current/include/hal_clock.h5
-rw-r--r--cesar/ecos/packages/kernel/current/src/common/clock.cxx5
-rw-r--r--cesar/hal/Module2
-rw-r--r--cesar/hal/arch/time.h3
-rw-r--r--cesar/hal/boot_params/src/boot_params_handlers.c2
-rw-r--r--cesar/hal/sysclk/Module1
-rw-r--r--cesar/hal/sysclk/src/sysclk.c57
-rw-r--r--cesar/hal/sysclk/sysclk.h31
-rw-r--r--cesar/hal/sysclk/test/Makefile10
-rw-r--r--cesar/hal/sysclk/test/override/cyg/hal/hal_clock.h18
-rw-r--r--cesar/hal/sysclk/test/override/pkgconf/kernel.h18
-rw-r--r--cesar/hal/sysclk/test/src/test_sysclk.c71
-rw-r--r--common/tests/tests4
13 files changed, 223 insertions, 4 deletions
diff --git a/cesar/ecos/packages/hal/sparc/leon/current/include/hal_clock.h b/cesar/ecos/packages/hal/sparc/leon/current/include/hal_clock.h
index 51255b7325..87a90fe61f 100644
--- a/cesar/ecos/packages/hal/sparc/leon/current/include/hal_clock.h
+++ b/cesar/ecos/packages/hal/sparc/leon/current/include/hal_clock.h
@@ -99,10 +99,11 @@
#define SPARC_LEON_TI1_CONTROL (SPARC_LEON_REG + 0x48)
externC cyg_int32 cyg_hal_sparc_clock_period;
+externC cyg_int32 cyg_hal_system_clock_freq;
#define HAL_CLOCK_INITIALIZE( _period_ ) CYG_MACRO_START \
- HAL_WRITE_UINT32( SPARC_LEON_SCALER, (CYGNUM_HAL_SYSTEM_CLOCK_FREQ-1) );\
- HAL_WRITE_UINT32( SPARC_LEON_SRELOAD, (CYGNUM_HAL_SYSTEM_CLOCK_FREQ-1) );\
+ HAL_WRITE_UINT32( SPARC_LEON_SCALER, (cyg_hal_system_clock_freq-1) );\
+ HAL_WRITE_UINT32( SPARC_LEON_SRELOAD, (cyg_hal_system_clock_freq-1) );\
cyg_hal_sparc_clock_period = (_period_); \
HAL_WRITE_UINT32( SPARC_LEON_TI1_CRELOAD, (_period_) ); \
HAL_WRITE_UINT32( SPARC_LEON_TI1_COUNTER, (_period_) ); \
diff --git a/cesar/ecos/packages/kernel/current/src/common/clock.cxx b/cesar/ecos/packages/kernel/current/src/common/clock.cxx
index 917b588a39..1f21ddf369 100644
--- a/cesar/ecos/packages/kernel/current/src/common/clock.cxx
+++ b/cesar/ecos/packages/kernel/current/src/common/clock.cxx
@@ -71,6 +71,11 @@
// -------------------------------------------------------------------------
// Static variables
+/* Variable to configure the system clock.
+ * This variable is used for an automatic configuration for the SPC300 and the
+ * MSE500. */
+cyg_int32 cyg_hal_system_clock_freq = CYGNUM_HAL_SYSTEM_CLOCK_FREQ;
+
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
Cyg_Clock *Cyg_Clock::real_time_clock = NULL; // System real time clock
diff --git a/cesar/hal/Module b/cesar/hal/Module
index c9cdc9f5ec..22d0bed356 100644
--- a/cesar/hal/Module
+++ b/cesar/hal/Module
@@ -4,5 +4,5 @@ MODULES := hal/timer hal/watchdog \
hal/phy/soft/bridgedma
else
MODULES := hal/timer hal/watchdog hal/arch \
- hal/phy hal/ipmbox hal/leon hal/boot_params hal/mem
+ hal/phy hal/ipmbox hal/leon hal/boot_params hal/mem hal/sysclk
endif
diff --git a/cesar/hal/arch/time.h b/cesar/hal/arch/time.h
index f10fdfe78e..6700e6d7d2 100644
--- a/cesar/hal/arch/time.h
+++ b/cesar/hal/arch/time.h
@@ -41,7 +41,8 @@
# if defined (ECOS) && ECOS
# include <pkgconf/hal.h>
-# define ARCH_TIME_FREQ_MHZ CYGNUM_HAL_SYSTEM_CLOCK_FREQ
+# include <cyg/hal/hal_clock.h>
+# define ARCH_TIME_FREQ_MHZ cyg_hal_system_clock_freq
# else
# define ARCH_TIME_FREQ_MHZ @UNKNOWN@
# endif
diff --git a/cesar/hal/boot_params/src/boot_params_handlers.c b/cesar/hal/boot_params/src/boot_params_handlers.c
index 67a342273c..421d38de84 100644
--- a/cesar/hal/boot_params/src/boot_params_handlers.c
+++ b/cesar/hal/boot_params/src/boot_params_handlers.c
@@ -21,9 +21,11 @@
#include "hal/boot_params/inc/boot_params_handlers.h"
#include "hal/mem/mem.h"
+#include "hal/sysclk/sysclk.h"
BEGIN_BOOT_PARAM_HANDLERS
BOOT_PARAM_HANDLER ("mem", mem_handle_boot_param_mem)
+BOOT_PARAM_HANDLER ("sysclk_mhz", hal_sysclk_boot_param_sysclk_mhz)
END_BOOT_PARAM_HANDLERS
diff --git a/cesar/hal/sysclk/Module b/cesar/hal/sysclk/Module
new file mode 100644
index 0000000000..f3f5e61d55
--- /dev/null
+++ b/cesar/hal/sysclk/Module
@@ -0,0 +1 @@
+SOURCES := sysclk.c
diff --git a/cesar/hal/sysclk/src/sysclk.c b/cesar/hal/sysclk/src/sysclk.c
new file mode 100644
index 0000000000..4c6a62fcfd
--- /dev/null
+++ b/cesar/hal/sysclk/src/sysclk.c
@@ -0,0 +1,57 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/sysclk/src/sysclk.c
+ * \brief Boot param handler to get the system clock.
+ * \ingroup hal
+ */
+#include "common/std.h"
+#include "common/module.h"
+#include "hal/sysclk/sysclk.h"
+
+#include <cyg/hal/hal_clock.h>
+#include <pkgconf/kernel.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdio.h>
+
+/**
+ * Convert a system clock representation from a string to a numeric value.
+ * \param str system clock size as a string (e.g. "147", "250")
+ * \param num system clock as a numeric value
+ * \return true on success
+ */
+PRIVATE bool
+hal_sysclk_str_to_num (uint *num, const char *str)
+{
+ char *endptr;
+ unsigned long val = strtoul (str, &endptr, 10);
+ if (val <= UINT_MAX && endptr != str)
+ {
+ *num = val;
+ return true;
+ }
+ return false;
+}
+
+int
+hal_sysclk_boot_param_sysclk_mhz (const char *param_value)
+{
+ uint sysclk_mhz;
+ if (!hal_sysclk_str_to_num (&sysclk_mhz, param_value))
+ {
+ printf (
+ "boot parameters \"sysclk_mhz\": error while parsing value \"%s\"\n",
+ param_value);
+ return -1;
+ }
+ /* Set the system clock global variable to the correct value. */
+ cyg_hal_system_clock_freq = sysclk_mhz;
+ HAL_CLOCK_INITIALIZE( CYGNUM_KERNEL_COUNTERS_RTC_PERIOD );
+ return 0;
+}
diff --git a/cesar/hal/sysclk/sysclk.h b/cesar/hal/sysclk/sysclk.h
new file mode 100644
index 0000000000..43d5cf4d88
--- /dev/null
+++ b/cesar/hal/sysclk/sysclk.h
@@ -0,0 +1,31 @@
+#ifndef hal_sysclk_sysclk_h
+#define hal_sysclk_sysclk_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/sysclk/sysclk.h
+ * \brief Boot param handler to get the system clock.
+ * \ingroup hal
+ *
+ * For MSE500 the system clock differs from the one of the SPC300, the main
+ * objective is to keep the same binary for both chips.
+ */
+
+BEGIN_DECLS
+
+/**
+ * Handle the boot parameter "sysclk_mhz".
+ * \param param_value value passed for the "sysclk_mhz" parameter
+ * \return 0 on success, -1 otherwise
+ */
+int
+hal_sysclk_boot_param_sysclk_mhz (const char *param_value);
+
+END_DECLS
+
+#endif /* hal_sysclock_sysclock_h */
diff --git a/cesar/hal/sysclk/test/Makefile b/cesar/hal/sysclk/test/Makefile
new file mode 100644
index 0000000000..fa37f9ea3c
--- /dev/null
+++ b/cesar/hal/sysclk/test/Makefile
@@ -0,0 +1,10 @@
+BASE = ../../..
+
+INCLUDES = hal/sysclk/test/override
+DEFS = -DNO_PRIVATE
+
+HOST_PROGRAMS = test_sysclk
+test_sysclk_SOURCES = test_sysclk.c
+test_sysclk_MODULES = lib hal/sysclk
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/hal/sysclk/test/override/cyg/hal/hal_clock.h b/cesar/hal/sysclk/test/override/cyg/hal/hal_clock.h
new file mode 100644
index 0000000000..f1deda7599
--- /dev/null
+++ b/cesar/hal/sysclk/test/override/cyg/hal/hal_clock.h
@@ -0,0 +1,18 @@
+#ifndef hal_sysclock_test_override_cyg_hal_hal_clock_h
+#define hal_sysclock_test_override_cyg_hal_hal_clock_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/sysclock/test/override/cyg/hal/hal_clock.h
+ * \brief Override the HAL clock file of eCos.
+ * \ingroup hal
+ */
+
+extern uint cyg_hal_system_clock_freq;
+
+#endif /* hal_sysclock_test_override_cyg_hal_hal_clock_h */
diff --git a/cesar/hal/sysclk/test/override/pkgconf/kernel.h b/cesar/hal/sysclk/test/override/pkgconf/kernel.h
new file mode 100644
index 0000000000..8470ee350a
--- /dev/null
+++ b/cesar/hal/sysclk/test/override/pkgconf/kernel.h
@@ -0,0 +1,18 @@
+#ifndef hal_sysclk_override_pkgconf_kernel_h
+#define hal_sysclk_override_pkgconf_kernel_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/sysclk/override/pkgconf/kernel.h
+ * \brief Kernel package stub for the test.
+ * \ingroup hal
+ */
+
+#define HAL_CLOCK_INITIALIZE(val) ((void) 0)
+
+#endif /* hal_sysclk_override_pkgconf_kernel_h */
diff --git a/cesar/hal/sysclk/test/src/test_sysclk.c b/cesar/hal/sysclk/test/src/test_sysclk.c
new file mode 100644
index 0000000000..a137949cf9
--- /dev/null
+++ b/cesar/hal/sysclk/test/src/test_sysclk.c
@@ -0,0 +1,71 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/sysclk/test/src/test_sysclk.c
+ * \brief Test the sysclk dynamic configuration.
+ * \ingroup hal
+ */
+#include "common/std.h"
+#include "hal/sysclk/sysclk.h"
+
+#include "lib/test.h"
+
+uint cyg_hal_system_clock_freq = 0;
+
+bool
+hal_sysclk_str_to_num (uint *num, const char *str);
+
+void
+hal_sysclk_test_case_string_to_int (test_t t)
+{
+ test_case_begin (t, "Test function conversion");
+
+ test_begin (t, "spc300, mse500 frequency")
+ {
+ bool ret = false;
+ char frequency_mhz_str[][4] = {"147\0", "250\0"};
+ uint frequency_mhz = 0;
+ uint expected_freq_mhz[] = {147, 250};
+ uint i;
+
+ for (i = 0; i < COUNT (frequency_mhz_str); i++)
+ {
+ ret = hal_sysclk_str_to_num (&frequency_mhz,
+ frequency_mhz_str[i]);
+ test_fail_unless (ret);
+ test_fail_unless (frequency_mhz == expected_freq_mhz[i]);
+ }
+ }
+ test_end;
+
+ test_begin (t, "Error in parameter")
+ {
+ bool ret = false;
+ uint frequency_mhz = 0;
+ ret = hal_sysclk_str_to_num (&frequency_mhz, "\0");
+ test_fail_unless (!ret);
+ test_fail_unless (frequency_mhz == 0);
+ }
+ test_end;
+}
+
+void
+hal_sysclk_test_suite (test_t t)
+{
+ test_suite_begin (t, "System clock dynamic configuration");
+ hal_sysclk_test_case_string_to_int (t);
+}
+
+int main (int argc, char *argv[])
+{
+ test_t t;
+ test_init (t, argc, argv);
+ hal_sysclk_test_suite (t);
+ test_result (t);
+ return test_nb_failed (t);
+}
diff --git a/common/tests/tests b/common/tests/tests
index d061af7685..66f0a8e727 100644
--- a/common/tests/tests
+++ b/common/tests/tests
@@ -500,3 +500,7 @@ test_bufmgr: ./obj/test_bufmgr
cesar/projects/plc:
make
make traces: make PROJECT_CONFIG=Config.traces
+
+cesar/hal/sysclk/test:
+make
+sysclk: ./obj/test_sysclk