From 678b59babfdc30b473d43c0b054ad06938e23601 Mon Sep 17 00:00:00 2001
From: Angus Gratton <gus@projectgus.com>
Date: Thu, 30 Jun 2016 09:22:17 +1000
Subject: [PATCH] Honour values of configCPU_CLOCK_HZ & configTICK_RATE_HZ for
 tick rate

Fixes #147

* Can vary tick rate from 100Hz via configTICK_RATE_HZ. Note that the
  SDK binary libraries are hard-coded to assume the tick rate is 100Hz,
  so changing the tick rate may have unexpected consequences for lower
  layer WiFi behaviour (such as certain kinds of timeouts happening
  faster/slower.)

* Setting configCPU_CLOCK_HZ to 160MHz means ESP will set 160MHz during
  initialisation. Only 80MHz and 160MHz are supported.

* Timing of tasks is no longer affected by current CPU freq (whether set
  via configCPU_CLOCK_HZ or via sdk_system_update_cpu_freq().)
  Previously doubling the CPU frequency would double the tick rate.
---
 FreeRTOS/Source/include/FreeRTOSConfig.h | 7 +++++++
 core/app_main.c                          | 4 ++++
 examples/blink/blink.c                   | 1 +
 open_esplibs/include/esplibs/libmain.h   | 4 ++++
 open_esplibs/libmain/os_cpu_a.c          | 5 +++--
 5 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/FreeRTOS/Source/include/FreeRTOSConfig.h b/FreeRTOS/Source/include/FreeRTOSConfig.h
index 6604df3..d886828 100644
--- a/FreeRTOS/Source/include/FreeRTOSConfig.h
+++ b/FreeRTOS/Source/include/FreeRTOSConfig.h
@@ -34,6 +34,13 @@
 #define configUSE_TICK_HOOK			0
 #endif
 #ifndef configCPU_CLOCK_HZ
+/* This is the _default_ clock speed for the CPU. Can be either 80MHz
+ * or 160MHz, and the system will set the clock speed to match at startup.
+
+Note that it's possible to change the clock speed at runtime, so you
+can/should use sdk_system_get_cpu_frequency() in order to determine the
+current CPU frequency, in preference to this macro.
+*/
 #define configCPU_CLOCK_HZ			( ( unsigned long ) 80000000 )
 #endif
 #ifndef configTICK_RATE_HZ
diff --git a/core/app_main.c b/core/app_main.c
index ac74426..43fed17 100644
--- a/core/app_main.c
+++ b/core/app_main.c
@@ -382,6 +382,10 @@ static __attribute__((noinline)) void user_start_phase2(void) {
 
     srand(hwrand()); /* seed libc rng */
 
+    // Set intial CPU clock speed to 160MHz if necessary
+    _Static_assert(configCPU_CLOCK_HZ == 80000000 || configCPU_CLOCK_HZ == 160000000, "FreeRTOSConfig must define initial clock speed as either 80MHz or 160MHz");
+    sdk_system_update_cpu_freq(configCPU_CLOCK_HZ / 1000000);
+
     // Call gcc constructor functions
     void (**ctor)(void);
     for ( ctor = &__init_array_start; ctor != &__init_array_end; ++ctor) {
diff --git a/examples/blink/blink.c b/examples/blink/blink.c
index 9d2ae3c..1539b67 100644
--- a/examples/blink/blink.c
+++ b/examples/blink/blink.c
@@ -2,6 +2,7 @@
  *
  * This sample code is in the public domain.
  */
+#include <stdlib.h>
 #include "espressif/esp_common.h"
 #include "esp/uart.h"
 #include "FreeRTOS.h"
diff --git a/open_esplibs/include/esplibs/libmain.h b/open_esplibs/include/esplibs/libmain.h
index dc36117..98ccb54 100644
--- a/open_esplibs/include/esplibs/libmain.h
+++ b/open_esplibs/include/esplibs/libmain.h
@@ -1,3 +1,4 @@
+#include "sdk_internal.h"
 #ifndef _ESPLIBS_LIBMAIN_H
 #define _ESPLIBS_LIBMAIN_H
 
@@ -5,6 +6,9 @@
 
 // misc.c
 int sdk_os_get_cpu_frequency(void);
+
+/* Don't call this function from user code, it doesn't change the CPU
+ * speed. Call sdk_system_update_cpu_freq() instead. */
 void sdk_os_update_cpu_frequency(int freq);
 
 // user_interface.c
diff --git a/open_esplibs/libmain/os_cpu_a.c b/open_esplibs/libmain/os_cpu_a.c
index 7908b6f..dac5247 100644
--- a/open_esplibs/libmain/os_cpu_a.c
+++ b/open_esplibs/libmain/os_cpu_a.c
@@ -7,6 +7,7 @@
 #include "task.h"
 #include "xtensa_ops.h"
 #include "common_macros.h"
+#include "esplibs/libmain.h"
 
 // xPortSysTickHandle is defined in FreeRTOS/Source/portable/esp8266/port.c but
 // does not exist in any header files.
@@ -66,7 +67,7 @@ void IRAM sdk__xt_int_exit(void) {
 void IRAM sdk__xt_timer_int(void) {
     uint32_t trigger_ccount;
     uint32_t current_ccount;
-    uint32_t ccount_interval = portTICK_RATE_MS * 80000; //FIXME
+    uint32_t ccount_interval = portTICK_RATE_MS * sdk_os_get_cpu_frequency() * 1000;
 
     do {
         RSR(trigger_ccount, ccompare0);
@@ -87,7 +88,7 @@ void IRAM sdk__xt_timer_int1(void) {
 void IRAM sdk__xt_tick_timer_init(void) {
     uint32_t ints_enabled;
     uint32_t current_ccount;
-    uint32_t ccount_interval = portTICK_RATE_MS * 80000; //FIXME
+    uint32_t ccount_interval = portTICK_RATE_MS * sdk_os_get_cpu_frequency() * 1000;
 
     RSR(current_ccount, ccount);
     WSR(current_ccount + ccount_interval, ccompare0);