5ad2a35796
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.
127 lines
3.8 KiB
C
127 lines
3.8 KiB
C
#include "open_esplibs.h"
|
|
#if OPEN_LIBMAIN_OS_CPU_A
|
|
// The contents of this file are only built if OPEN_LIBMAIN_OS_CPU_A is set to true
|
|
|
|
#include "esp/types.h"
|
|
#include "FreeRTOS.h"
|
|
#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.
|
|
void xPortSysTickHandle(void);
|
|
|
|
/* The following "functions" manipulate the stack at a low level and thus cannot be coded directly in C */
|
|
|
|
void IRAM vPortYield(void) {
|
|
asm(" wsr a0, excsave1 \n\
|
|
addi sp, sp, -80 \n\
|
|
s32i a0, sp, 4 \n\
|
|
addi a0, sp, 80 \n\
|
|
s32i a0, sp, 16 \n\
|
|
rsr a0, ps \n\
|
|
s32i a0, sp, 8 \n\
|
|
rsr a0, excsave1 \n\
|
|
s32i a0, sp, 12 \n\
|
|
movi a0, _xt_user_exit \n\
|
|
s32i a0, sp, 0 \n\
|
|
call0 sdk__xt_int_enter \n\
|
|
call0 vPortEnterCritical \n\
|
|
call0 vTaskSwitchContext \n\
|
|
call0 vPortExitCritical \n\
|
|
call0 sdk__xt_int_exit \n\
|
|
");
|
|
}
|
|
|
|
void IRAM sdk__xt_int_enter(void) {
|
|
asm(" s32i a12, sp, 60 \n\
|
|
s32i a13, sp, 64 \n\
|
|
mov a12, a0 \n\
|
|
call0 sdk__xt_context_save \n\
|
|
movi a0, pxCurrentTCB \n\
|
|
l32i a0, a0, 0 \n\
|
|
s32i sp, a0, 0 \n\
|
|
mov a0, a12 \n\
|
|
");
|
|
}
|
|
|
|
void IRAM sdk__xt_int_exit(void) {
|
|
asm(" s32i a14, sp, 68 \n\
|
|
s32i a15, sp, 72 \n\
|
|
movi sp, pxCurrentTCB \n\
|
|
l32i sp, sp, 0 \n\
|
|
l32i sp, sp, 0 \n\
|
|
movi a14, pxCurrentTCB \n\
|
|
l32i a14, a14, 0 \n\
|
|
addi a15, sp, 80 \n\
|
|
s32i a15, a14, 0 \n\
|
|
call0 sdk__xt_context_restore \n\
|
|
l32i a14, sp, 68 \n\
|
|
l32i a15, sp, 72 \n\
|
|
l32i a0, sp, 0 \n\
|
|
");
|
|
}
|
|
|
|
void IRAM sdk__xt_timer_int(void) {
|
|
uint32_t trigger_ccount;
|
|
uint32_t current_ccount;
|
|
uint32_t ccount_interval = portTICK_RATE_MS * sdk_os_get_cpu_frequency() * 1000;
|
|
|
|
do {
|
|
RSR(trigger_ccount, ccompare0);
|
|
WSR(trigger_ccount + ccount_interval, ccompare0);
|
|
ESYNC();
|
|
xPortSysTickHandle();
|
|
ESYNC();
|
|
RSR(current_ccount, ccount);
|
|
} while (current_ccount - trigger_ccount > ccount_interval);
|
|
}
|
|
|
|
void IRAM sdk__xt_timer_int1(void) {
|
|
vTaskSwitchContext();
|
|
}
|
|
|
|
#define INTENABLE_CCOMPARE BIT(6)
|
|
|
|
void IRAM sdk__xt_tick_timer_init(void) {
|
|
uint32_t ints_enabled;
|
|
uint32_t current_ccount;
|
|
uint32_t ccount_interval = portTICK_RATE_MS * sdk_os_get_cpu_frequency() * 1000;
|
|
|
|
RSR(current_ccount, ccount);
|
|
WSR(current_ccount + ccount_interval, ccompare0);
|
|
ints_enabled = 0;
|
|
XSR(ints_enabled, intenable);
|
|
WSR(ints_enabled | INTENABLE_CCOMPARE, intenable);
|
|
}
|
|
|
|
void IRAM sdk__xt_isr_unmask(uint32_t mask) {
|
|
uint32_t ints_enabled;
|
|
|
|
ints_enabled = 0;
|
|
XSR(ints_enabled, intenable);
|
|
WSR(ints_enabled | mask, intenable);
|
|
}
|
|
|
|
void IRAM sdk__xt_isr_mask(uint32_t mask) {
|
|
uint32_t ints_enabled;
|
|
|
|
ints_enabled = 0;
|
|
XSR(ints_enabled, intenable);
|
|
WSR(ints_enabled & mask, intenable);
|
|
}
|
|
|
|
uint32_t IRAM sdk__xt_read_ints(void) {
|
|
uint32_t ints_enabled;
|
|
|
|
RSR(ints_enabled, intenable);
|
|
return ints_enabled;
|
|
}
|
|
|
|
void IRAM sdk__xt_clear_ints(uint32_t mask) {
|
|
WSR(mask, intclear);
|
|
}
|
|
|
|
#endif /* OPEN_LIBMAIN_OS_CPU_A */
|