305 lines
7.7 KiB
C
305 lines
7.7 KiB
C
|
|
#include "Includes.h"
|
|
|
|
|
|
#if 1
|
|
|
|
//#define printf(...) (0)
|
|
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t AO_TIMER_VALUE:16;
|
|
uint32_t AO_TIMER_CLR:1;
|
|
uint32_t AO_TIMER_EN:1;
|
|
uint32_t FREQ_TIMER_EN:1;
|
|
uint32_t RESERVED:13;
|
|
}AO_TIMER_CTL_T;
|
|
|
|
static AO_TIMER_CTL_T* ao_timer_ctl = (AO_TIMER_CTL_T*)AO_TIMER_CTL;
|
|
|
|
|
|
|
|
/*
|
|
3fff 3044 --50K
|
|
2fff 4132 --39K
|
|
1fff 5229 --31K
|
|
0fff 6326 --25K
|
|
*/
|
|
#define MAX_LPO_RTM 0x3fff
|
|
#define MIN_LPO_RTM 0x0
|
|
#define MID_LPO_RTM 0x1fff
|
|
#define RANGE_LPO_RTM 0x400
|
|
#define GEARS_HZ 1.56
|
|
#define _32K_STAND_HZ 32000
|
|
|
|
#define CALIB_STEP_CYCLE_32K 32 //#define CALIB_STEP_CYCLE_32K 10
|
|
#define COUNT_16M 16000 //#define COUNT_16M 5000
|
|
static void LPO_RTM_SET(uint16_t val)
|
|
{
|
|
*((volatile unsigned *)0x40002084)=0x1fff4000|val; //*((volatile unsigned *)0x40002084)=0x1fff4000|0x22C0; //printf("LPO_RTM:%08x\n",*((volatile unsigned *)0x40002084));
|
|
}
|
|
/**
|
|
* Copyright (c) 2022 - 2025, XinChip
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Author :
|
|
*
|
|
*/
|
|
static uint8_t calib_step(uint32_t _cycle_32k,uint32_t *FREQ_VAL)
|
|
{
|
|
uint32_t tsd;
|
|
ao_timer_ctl->AO_TIMER_VALUE = _cycle_32k;//32 cycle == 1ms
|
|
ao_timer_ctl->AO_TIMER_EN = 0;
|
|
ao_timer_ctl->AO_TIMER_CLR = 0; //中断使用在timer 使能之前
|
|
ao_timer_ctl->FREQ_TIMER_EN = 1;
|
|
do{
|
|
__read_hw_reg32(AO_ALL_INTR, tsd);
|
|
}while((tsd&0x20)==0);
|
|
__read_hw_reg32(FREQ_TIMER_VAL, *FREQ_VAL);//
|
|
ao_timer_ctl->AO_TIMER_CLR = 1; // rtc 必须清理中断
|
|
ao_timer_ctl->FREQ_TIMER_EN = 0;
|
|
if(*FREQ_VAL==COUNT_16M) return 0;
|
|
return ((*FREQ_VAL<COUNT_16M)? 1:2);
|
|
}
|
|
|
|
|
|
/**
|
|
* Copyright (c) 2022 - 2025, XinChip
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Describe : init calib clk
|
|
*
|
|
*/
|
|
static volatile uint32_t mid=MID_LPO_RTM;
|
|
void calib_init(void)
|
|
{
|
|
//config clk
|
|
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x00020002);
|
|
__write_hw_reg32(CPR_AOCLKEN_GRCTL,0x00020002);
|
|
|
|
LPO_RTM_SET(mid);
|
|
}
|
|
/**
|
|
* Copyright (c) 2022 - 2025, XinChip
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Describe : "linear regression" calibration
|
|
*
|
|
*/
|
|
void rc32k_calib(uint16_t cts)
|
|
{
|
|
uint32_t tsd,frac;
|
|
while(cts--)
|
|
{
|
|
__disable_irq();
|
|
calib_step(CALIB_STEP_CYCLE_32K,&tsd);
|
|
__enable_irq();
|
|
printf("FREQ_TIMER_VAL:%d\n",tsd);
|
|
|
|
frac=(uint32_t)((((float)((16.0)*CALIB_STEP_CYCLE_32K))/tsd)*1000000);
|
|
if(frac > _32K_STAND_HZ)
|
|
{
|
|
mid=mid-((uint32_t)(((float)(frac-_32K_STAND_HZ))/GEARS_HZ));
|
|
}
|
|
else if(frac < _32K_STAND_HZ)
|
|
{
|
|
mid=mid+((uint32_t)(((float)(_32K_STAND_HZ-frac))/GEARS_HZ));
|
|
}
|
|
LPO_RTM_SET(mid);
|
|
|
|
}
|
|
printf("@@LPO_RTM_SET:0x%08x\n",mid);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
//////////////////////////校准三次 每次校准用的时间如下//////////////////////////
|
|
//低电压下
|
|
//*((volatile unsigned *)(0x40002400 + 0x20)) =0x44;
|
|
//*((volatile unsigned *)(0x40002400 + 0x48)) =0x01;
|
|
//@@LPO_RTM_SET:0x00002704 32 //1ms校准一次
|
|
//@@LPO_RTM_SET:0x00002709 32*5 //5ms校准一次
|
|
//@@LPO_RTM_SET:0x0000270b 320*2 //20ms校准一次
|
|
//@@LPO_RTM_SET:0x00002708 320*4 //40ms校准一次
|
|
//@@LPO_RTM_SET:0x00002706 320*6 //60ms校准一次
|
|
//@@LPO_RTM_SET:0x0000270a 320*8 //80ms校准一次
|
|
|
|
//@@LPO_RTM_SET:0x00002706 3200 //100ms校准一次
|
|
//@@LPO_RTM_SET:0x00002705 3200*2 //200ms校准一次
|
|
//@@LPO_RTM_SET:0x00002708 3200*3 //300ms校准一次
|
|
//@@LPO_RTM_SET:0x00002705 3200*4 //400ms校准一次
|
|
//@@LPO_RTM_SET:0x00002705 3200*5 //400ms校准一次
|
|
//@@LPO_RTM_SET:0x0000270a 3200*6 //600ms校准一次
|
|
//@@LPO_RTM_SET:0x00002708 3200*7 //700ms校准一次
|
|
//@@LPO_RTM_SET:0x00002708 3200*8 //800ms校准一次
|
|
//@@LPO_RTM_SET:0x00002707 3200*9 //900ms校准一次
|
|
|
|
|
|
//正常电压下:
|
|
//@@LPO_RTM_SET:0x000026db 32 //1ms校准一次
|
|
//@@LPO_RTM_SET:0x000026da 32*5 //5ms校准一次
|
|
//@@LPO_RTM_SET:0x000026dc 320*2 //20ms校准一次
|
|
//@@LPO_RTM_SET:0x000026da 320*4 //40ms校准一次
|
|
//@@LPO_RTM_SET:0x000026e0 320*6 //60ms校准一次
|
|
//@@LPO_RTM_SET:0x000026dc 320*8 //80ms校准一次
|
|
|
|
//@@LPO_RTM_SET:0x000026dc 3200 //100ms校准一次
|
|
//@@LPO_RTM_SET:0x000026dc 3200*2 //200ms校准一次
|
|
//@@LPO_RTM_SET:0x000026df 3200*3 //300ms校准一次
|
|
//@@LPO_RTM_SET:0x000026dd 3200*4 //400ms校准一次
|
|
//@@LPO_RTM_SET:0x000026db 3200*5 //400ms校准一次
|
|
//@@LPO_RTM_SET:0x000026db 3200*6 //600ms校准一次
|
|
//@@LPO_RTM_SET:0x000026de 3200*7 //700ms校准一次
|
|
//@@LPO_RTM_SET:0x000026dd 3200*8 //800ms校准一次
|
|
//@@LPO_RTM_SET:0x000026e0 3200*9 //900ms校准一次
|
|
|
|
//#define printf(...) (0)
|
|
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t AO_TIMER_VALUE:16;
|
|
uint32_t AO_TIMER_CLR:1;
|
|
uint32_t AO_TIMER_EN:1;
|
|
uint32_t FREQ_TIMER_EN:1;
|
|
uint32_t RESERVED:13;
|
|
}AO_TIMER_CTL_T;
|
|
|
|
static AO_TIMER_CTL_T* ao_timer_ctl = (AO_TIMER_CTL_T*)AO_TIMER_CTL;
|
|
|
|
|
|
|
|
/*
|
|
3fff 3044 --50K
|
|
2fff 4132 --39K
|
|
1fff 5229 --31K
|
|
0fff 6326 --25K
|
|
*/
|
|
#define MAX_LPO_RTM 0x3fff
|
|
#define MIN_LPO_RTM 0x0
|
|
#define MID_LPO_RTM 0x1fff
|
|
#define RANGE_LPO_RTM 0x400
|
|
#define GEARS_HZ 1.56
|
|
#define _32K_STAND_HZ 32000
|
|
|
|
//#define CALIB_STEP_CYCLE_32K 32 //#define CALIB_STEP_CYCLE_32K 10
|
|
//#define COUNT_16M 16000 //#define COUNT_16M 5000
|
|
|
|
#define TMP_VAL 1
|
|
#define CALIB_STEP_CYCLE_32K 32*TMP_VAL //#define CALIB_STEP_CYCLE_32K 10
|
|
#define COUNT_16M 16000*TMP_VAL //#define COUNT_16M 5000
|
|
|
|
static void LPO_RTM_SET(uint16_t val)
|
|
{
|
|
*((volatile unsigned *)0x40002084)=0x1fff4000|val; //*((volatile unsigned *)0x40002084)=0x1fff4000|0x22C0; //printf("LPO_RTM:%08x\n",*((volatile unsigned *)0x40002084));
|
|
}
|
|
/**
|
|
* Copyright (c) 2022 - 2025, XinChip
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Author :
|
|
*
|
|
*/
|
|
static uint8_t calib_step(uint32_t _cycle_32k,uint32_t *FREQ_VAL)
|
|
{
|
|
uint32_t tsd;
|
|
ao_timer_ctl->AO_TIMER_VALUE = _cycle_32k;//32 cycle == 1ms
|
|
ao_timer_ctl->AO_TIMER_EN = 0;
|
|
ao_timer_ctl->AO_TIMER_CLR = 0; //中断使用在timer 使能之前
|
|
ao_timer_ctl->FREQ_TIMER_EN = 1;
|
|
do{
|
|
__read_hw_reg32(AO_ALL_INTR, tsd);
|
|
//if(*FREQ_TIMER_VAL>=16777210) printf("***********\n");
|
|
}while((tsd&0x20)==0);
|
|
__read_hw_reg32(FREQ_TIMER_VAL, *FREQ_VAL);//
|
|
ao_timer_ctl->AO_TIMER_CLR = 1; // rtc 必须清理中断
|
|
ao_timer_ctl->FREQ_TIMER_EN = 0;
|
|
if(*FREQ_VAL==COUNT_16M) return 0;
|
|
return ((*FREQ_VAL<COUNT_16M)? 1:2);
|
|
}
|
|
|
|
|
|
/**
|
|
* Copyright (c) 2022 - 2025, XinChip
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Describe : init calib clk
|
|
*
|
|
*/
|
|
static volatile uint32_t mid=MID_LPO_RTM;
|
|
void calib_init(void)
|
|
{
|
|
//config clk
|
|
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x00020002);
|
|
__write_hw_reg32(CPR_AOCLKEN_GRCTL,0x00020002);
|
|
|
|
LPO_RTM_SET(mid);
|
|
}
|
|
/**
|
|
* Copyright (c) 2022 - 2025, XinChip
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Describe : "linear regression" calibration
|
|
*
|
|
*/
|
|
void rc32k_calib(uint16_t cts)
|
|
{
|
|
uint32_t tsd,frac;
|
|
while(cts--)
|
|
{
|
|
__disable_irq();
|
|
calib_step(CALIB_STEP_CYCLE_32K,&tsd);
|
|
__enable_irq();
|
|
printf("FREQ_TIMER_VAL:%d\n",tsd);
|
|
|
|
frac=(uint32_t)((((float)((16.0)*CALIB_STEP_CYCLE_32K))/tsd)*1000000);
|
|
if(frac > _32K_STAND_HZ)
|
|
{
|
|
mid=mid-((uint32_t)(((float)(frac-_32K_STAND_HZ))/GEARS_HZ));
|
|
}
|
|
else if(frac < _32K_STAND_HZ)
|
|
{
|
|
mid=mid+((uint32_t)(((float)(_32K_STAND_HZ-frac))/GEARS_HZ));
|
|
}
|
|
LPO_RTM_SET(mid);
|
|
|
|
}
|
|
printf("@@LPO_RTM_SET:0x%08x\n",mid);
|
|
|
|
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
void test_main(void)
|
|
{
|
|
printf("TEST CALIB\n");
|
|
Init_gpio();
|
|
// *((volatile unsigned *)(0x40002400 + 0x20)) =0x44;
|
|
// *((volatile unsigned *)(0x40002400 + 0x48)) =0x01;
|
|
gpio_output_high(26);
|
|
gpio_output_low(26);
|
|
//3.19ms
|
|
calib_init();
|
|
rc32k_calib(3);
|
|
gpio_output_high(26);
|
|
gpio_output_low(26);
|
|
xc_ao_timer_calib_test();
|
|
|
|
|
|
}
|
|
#endif
|
|
|
|
//cmp
|
|
|