[beken-72xx] Implement micros() properly; use high-res timer for OS
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <arm_arch.h>
|
||||
#include <bk_timer.h>
|
||||
#include <bk_timer_pub.h>
|
||||
#include <rtos_pub.h>
|
||||
#include <sys_rtos.h>
|
||||
|
||||
@@ -22,8 +25,33 @@ unsigned long millis() {
|
||||
}
|
||||
|
||||
unsigned long micros() {
|
||||
// TODO implement this properly
|
||||
// copied from bk_timer_ctrl(), for speeds
|
||||
uint32_t timeout = 0;
|
||||
|
||||
#if (CFG_SOC_NAME == SOC_BK7231)
|
||||
#error "Not implemented"
|
||||
#endif
|
||||
|
||||
#if LT_MICROS_HIGH_RES
|
||||
REG_WRITE(TIMER0_2_READ_CTL, (BKTIMER0 << 2) | 1);
|
||||
while (REG_READ(TIMER0_2_READ_CTL) & 1) {
|
||||
timeout++;
|
||||
if (timeout > (120 * 1000))
|
||||
return 0;
|
||||
}
|
||||
return millis() * 1000 + REG_READ(TIMER0_2_READ_VALUE) / (CFG_XTAL_FREQUENCE / 1000 / 1000);
|
||||
#else
|
||||
#if 0
|
||||
REG_WRITE(TIMER3_5_READ_CTL, (BKTIMER3 << 2) | 1);
|
||||
while (REG_READ(TIMER3_5_READ_CTL) & 1) {
|
||||
timeout++;
|
||||
if (timeout > (120 * 1000))
|
||||
return 0;
|
||||
}
|
||||
return millis() * 1000 + REG_READ(TIMER3_5_READ_VALUE) / 32;
|
||||
#endif
|
||||
return millis() * 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
void yield() {
|
||||
|
||||
@@ -82,6 +82,10 @@
|
||||
#define LT_USE_TIME 0
|
||||
#endif
|
||||
|
||||
#ifndef LT_MICROS_HIGH_RES // NOTE: this is also defined in fixups/clock_rtos.c
|
||||
#define LT_MICROS_HIGH_RES 1
|
||||
#endif
|
||||
|
||||
// Per-module logging output - applies to all loglevels
|
||||
#ifndef LT_DEBUG_ALL
|
||||
#define LT_DEBUG_ALL 0
|
||||
|
||||
@@ -160,6 +160,8 @@ env.AddLibrary(
|
||||
srcs=[
|
||||
"+<arch_main.c>",
|
||||
"+<ate_app.c>",
|
||||
"+<clock_cal.c>",
|
||||
"+<clock_rtos.c>",
|
||||
"+<intc.c>",
|
||||
"+<wrap_BkDriverFlash.c>",
|
||||
*srcs_fixups,
|
||||
@@ -266,6 +268,7 @@ env.AddLibrary(
|
||||
"+<joint_up/*.c>",
|
||||
"+<lwip_intf/dhcpd/*.c>",
|
||||
"+<misc/*.c>",
|
||||
"-<misc/fake_clock.c>", # fixups
|
||||
"+<net_param_intf/*.c>",
|
||||
"+<power_save/*.c>",
|
||||
"+<rwnx_intf/*.c>",
|
||||
|
||||
127
platform/beken-72xx/fixups/clock_cal.c
Normal file
127
platform/beken-72xx/fixups/clock_cal.c
Normal file
@@ -0,0 +1,127 @@
|
||||
#include "include.h"
|
||||
|
||||
#include "bk_timer_pub.h"
|
||||
#include "drv_model_pub.h"
|
||||
#include "fake_clock_pub.h"
|
||||
#include "mcu_ps_pub.h"
|
||||
#include "power_save_pub.h"
|
||||
#include "pwm_pub.h"
|
||||
#include "sys_rtos.h"
|
||||
|
||||
static CAL_TICK_T cal_tick_save;
|
||||
UINT32 use_cal_net = 0;
|
||||
|
||||
UINT32 fclk_cal_endvalue(UINT32 mode) {
|
||||
UINT32 value = 1;
|
||||
|
||||
if (PWM_CLK_32K == mode) {
|
||||
/* 32 kHz clock */
|
||||
value = FCLK_DURATION_MS * 32;
|
||||
} else if (PWM_CLK_26M == mode) {
|
||||
/* 26 MHz clock */
|
||||
value = FCLK_DURATION_MS * 26000;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#if CFG_USE_TICK_CAL
|
||||
static UINT32 timer_cal_init(void) {
|
||||
UINT32 fclk;
|
||||
|
||||
fclk = BK_TICKS_TO_MS(fclk_get_tick());
|
||||
|
||||
cal_tick_save.fclk_tick = fclk;
|
||||
cal_tick_save.tmp1 = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int increase_tick;
|
||||
|
||||
static UINT32 timer_cal_tick(void) {
|
||||
UINT32 fclk, tmp2;
|
||||
UINT32 machw = 0;
|
||||
INT32 lost;
|
||||
GLOBAL_INT_DECLARATION();
|
||||
|
||||
GLOBAL_INT_DISABLE();
|
||||
|
||||
fclk = BK_TICKS_TO_MS(fclk_get_tick());
|
||||
cal_tick_save.tmp1 += ONE_CAL_TIME;
|
||||
|
||||
tmp2 = fclk;
|
||||
|
||||
lost = (INT32)(cal_tick_save.tmp1 - (UINT32)tmp2);
|
||||
|
||||
if ((lost >= (2 * FCLK_DURATION_MS))) {
|
||||
lost -= FCLK_DURATION_MS;
|
||||
fclk_update_tick(BK_MS_TO_TICKS(lost));
|
||||
increase_tick = 0;
|
||||
} else {
|
||||
if (lost <= (-(2 * FCLK_DURATION_MS))) {
|
||||
if (lost < (-50000)) {
|
||||
os_printf("m reset:%x %x\r\n", lost, machw);
|
||||
}
|
||||
increase_tick = lost + FCLK_DURATION_MS;
|
||||
}
|
||||
}
|
||||
|
||||
mcu_ps_machw_init();
|
||||
GLOBAL_INT_RESTORE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cal_timer_hdl(UINT8 param) {
|
||||
timer_cal_tick();
|
||||
}
|
||||
|
||||
static void cal_timer_set(void) {
|
||||
timer_param_t param;
|
||||
UINT32 ret;
|
||||
UINT32 timer_channel;
|
||||
|
||||
timer_cal_init();
|
||||
|
||||
param.channel = CAL_TIMER_ID;
|
||||
param.div = 1;
|
||||
param.period = ONE_CAL_TIME;
|
||||
param.t_Int_Handler = cal_timer_hdl;
|
||||
|
||||
ret = sddev_control(TIMER_DEV_NAME, CMD_TIMER_INIT_PARAM, ¶m);
|
||||
ASSERT(BK_TIMER_SUCCESS == ret);
|
||||
timer_channel = param.channel;
|
||||
ret = sddev_control(TIMER_DEV_NAME, CMD_TIMER_UNIT_ENABLE, &timer_channel);
|
||||
ASSERT(BK_TIMER_SUCCESS == ret);
|
||||
}
|
||||
|
||||
static void cal_timer_deset(void) {
|
||||
UINT32 ret;
|
||||
UINT32 timer_channel;
|
||||
|
||||
timer_channel = CAL_TIMER_ID;
|
||||
ret = sddev_control(TIMER_DEV_NAME, CMD_TIMER_UNIT_DISABLE, &timer_channel);
|
||||
ASSERT(BK_TIMER_SUCCESS == ret);
|
||||
timer_cal_init();
|
||||
}
|
||||
|
||||
UINT32 bk_cal_init(UINT32 setting) {
|
||||
GLOBAL_INT_DECLARATION();
|
||||
GLOBAL_INT_DISABLE();
|
||||
|
||||
if (1 == setting) {
|
||||
cal_timer_deset();
|
||||
use_cal_net = 1;
|
||||
mcu_ps_machw_init();
|
||||
os_printf("decset:%d %d %d %d\r\n", use_cal_net, fclk_get_tick(), fclk_get_second(), xTaskGetTickCount());
|
||||
} else {
|
||||
mcu_ps_machw_cal();
|
||||
cal_timer_set();
|
||||
use_cal_net = 0;
|
||||
mcu_ps_machw_reset();
|
||||
os_printf("cset:%d %d %d %d\r\n", use_cal_net, fclk_get_tick(), fclk_get_second(), xTaskGetTickCount());
|
||||
}
|
||||
GLOBAL_INT_RESTORE();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
125
platform/beken-72xx/fixups/clock_rtos.c
Normal file
125
platform/beken-72xx/fixups/clock_rtos.c
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "include.h"
|
||||
|
||||
#include "bk_timer_pub.h"
|
||||
#include "drv_model_pub.h"
|
||||
#include "fake_clock_pub.h"
|
||||
#include "icu_pub.h"
|
||||
#include "mcu_ps_pub.h"
|
||||
#include "power_save_pub.h"
|
||||
#include "pwm_pub.h"
|
||||
#include "rtos_pub.h"
|
||||
#include "sys_rtos.h"
|
||||
#include "uart_pub.h"
|
||||
|
||||
// from LibreTuyaConfig.h
|
||||
#ifndef LT_MICROS_HIGH_RES
|
||||
#define LT_MICROS_HIGH_RES 1
|
||||
#endif
|
||||
|
||||
// main FreeRTOS timer ID
|
||||
static BK_HW_TIMER_INDEX fclk_id = BK_PWM_TIMER_ID0;
|
||||
|
||||
extern UINT32 bk_cal_init(UINT32 setting);
|
||||
extern void mcu_ps_increase_clr(void);
|
||||
extern uint32_t preempt_delayed_schedule_get_flag(void);
|
||||
extern void preempt_delayed_schedule_clear_flag(void);
|
||||
|
||||
// forward definitions
|
||||
static void fclk_timer_hw_init(BK_HW_TIMER_INDEX timer_id);
|
||||
static void fclk_hdl(UINT8 param);
|
||||
|
||||
void fclk_init(void) {
|
||||
#if (CFG_SOC_NAME == SOC_BK7231)
|
||||
fclk_timer_hw_init(BK_PWM_TIMER_ID0);
|
||||
#elif LT_MICROS_HIGH_RES
|
||||
fclk_timer_hw_init(BK_TIMER_ID0);
|
||||
#else
|
||||
fclk_timer_hw_init(BK_TIMER_ID3);
|
||||
#endif
|
||||
|
||||
#if CFG_USE_TICK_CAL
|
||||
bk_cal_init(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* timer_id: BK_PWM_TIMER_ID0 or BK_TIMER_ID3 */
|
||||
static void fclk_timer_hw_init(BK_HW_TIMER_INDEX timer_id) {
|
||||
#if (CFG_SOC_NAME == SOC_BK7231)
|
||||
ASSERT(timer_id >= BK_PWM_TIMER_ID0);
|
||||
#endif
|
||||
|
||||
fclk_id = timer_id;
|
||||
if (fclk_id >= BK_PWM_TIMER_ID0) { // pwm timer
|
||||
pwm_param_t param;
|
||||
param.channel = (fclk_id - PWM0);
|
||||
param.cfg.bits.en = PWM_ENABLE;
|
||||
param.cfg.bits.int_en = PWM_INT_EN;
|
||||
param.cfg.bits.mode = PWM_TIMER_MODE;
|
||||
param.cfg.bits.clk = PWM_CLK_26M;
|
||||
param.p_Int_Handler = fclk_hdl;
|
||||
#if (CFG_SOC_NAME == SOC_BK7231N)
|
||||
param.duty_cycle1 = 0;
|
||||
#else
|
||||
param.duty_cycle = 0;
|
||||
#endif
|
||||
param.end_value = fclk_cal_endvalue((UINT32)param.cfg.bits.clk);
|
||||
|
||||
sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_PARAM, ¶m);
|
||||
} else { // timer
|
||||
timer_param_t param;
|
||||
param.channel = fclk_id;
|
||||
param.div = 1;
|
||||
#if LT_MICROS_HIGH_RES
|
||||
param.period = FCLK_DURATION_MS * 1000;
|
||||
#else
|
||||
param.period = FCLK_DURATION_MS;
|
||||
#endif
|
||||
param.t_Int_Handler = fclk_hdl;
|
||||
|
||||
#if LT_MICROS_HIGH_RES
|
||||
UINT32 ret = sddev_control(TIMER_DEV_NAME, CMD_TIMER_INIT_PARAM_US, ¶m);
|
||||
#else
|
||||
UINT32 ret = sddev_control(TIMER_DEV_NAME, CMD_TIMER_INIT_PARAM, ¶m);
|
||||
#endif
|
||||
ASSERT(BK_TIMER_SUCCESS == ret);
|
||||
sddev_control(TIMER_DEV_NAME, CMD_TIMER_UNIT_ENABLE, ¶m.channel);
|
||||
}
|
||||
}
|
||||
|
||||
static void fclk_hdl(UINT8 param) {
|
||||
#if CFG_USE_TICK_CAL
|
||||
if (!mcu_ps_need_pstick())
|
||||
return;
|
||||
#endif
|
||||
GLOBAL_INT_DECLARATION();
|
||||
GLOBAL_INT_DISABLE();
|
||||
if (xTaskIncrementTick() != pdFALSE || preempt_delayed_schedule_get_flag()) {
|
||||
preempt_delayed_schedule_clear_flag();
|
||||
/* Select a new task to run. */
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
GLOBAL_INT_RESTORE();
|
||||
}
|
||||
|
||||
UINT32 fclk_update_tick(UINT32 tick) {
|
||||
GLOBAL_INT_DECLARATION();
|
||||
if (tick == 0)
|
||||
return 0;
|
||||
GLOBAL_INT_DISABLE();
|
||||
mcu_ps_increase_clr();
|
||||
vTaskStepTick(tick);
|
||||
GLOBAL_INT_RESTORE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT64 fclk_get_tick(void) {
|
||||
return xTaskGetTickCount();
|
||||
}
|
||||
|
||||
UINT32 fclk_get_second(void) {
|
||||
return xTaskGetTickCount() / FCLK_SECOND;
|
||||
}
|
||||
|
||||
BK_HW_TIMER_INDEX fclk_get_tick_id(void) {
|
||||
return fclk_id;
|
||||
}
|
||||
Reference in New Issue
Block a user