Files
hpw421/component/boot2/bsp/bsp_calib_rc16m.c
T
2026-07-03 18:08:25 +08:00

232 lines
7.3 KiB
C

#include "Includes.h"
#define PULSE_DET_PIN 4 //采样脚(对方通过pwm向此脚灌入百分之五十占空比的方波)
#define CALIB_TIMES 2 //校准2次
#define CYCLE_TIMES 3 //循环次数 3次--
#define COLLECT_NUM ((CYCLE_TIMES*2)-1) //循环3次有六个采样点 可以得到五个采样值
#define TIMER_REFER 3 //选择的timer3作为计数参考
#define GEAR_HZ 71160.0 //总共128个档位 每个步长调节71160HZ的频率
#define RC16M_COEFFI 400 //rc16M 实际频率的计算系数:(1000ms/5ms)*2
#define RC16M_STD 16000000.0 //rc16M
void timer_cnt(uint8_t ch)//8 cycle is 1us
{
__write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL,0x80008); //TIMER_PCLK 时钟使能
__write_hw_reg32(CPR_TIMER_CLK_CTL(ch),0x00); //TIMERx_CLK 时钟控制寄存器 mclk_in(rc16M)/(2*(0x00 + 0x1))=8M
__write_hw_reg32(TIMERx_TCR(ch),0x0); //不屏蔽定时器中断,不使能定时器timer_num,
__write_hw_reg32(TIMERx_TCR(ch),0x2); //设置定时器工作在用户定义计数模式
__write_hw_reg32(TIMERx_TLC(ch),0xffffffff); //载入计数器计数初值(32bits),该值应大于等于 0x4
__write_hw_reg32(TIMERx_TCR(ch),0x3); //使能定时器timer_num
}
void BubbleSort(uint32_t *arr,uint32_t length)
{
for(int i=0;i<length-1;i++){
for(int j=0;j<length-1-i;j++){
if(arr[j]>arr[j+1]){ //相邻两个元素作比较,如果前面元素大于后面,进行交换
uint32_t temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
}
uint32_t get_average(uint32_t *p,uint32_t len)
{
uint32_t sum=0;
BubbleSort(p,len);
for(int i=0;i<len-2;i++)
{
sum+=p[i+1];
}
return sum/(len-2);
}
void calib_rc16m_step(void)
{
float freq_hz;
uint32_t t1,t2;
uint32_t rc16m_buf[CYCLE_TIMES*2];
uint32_t collect_buf[COLLECT_NUM];
for(int i=0,j=0;i<CYCLE_TIMES;i++)
{
while(gpio_input_val(PULSE_DET_PIN)==0);
rc16m_buf[j++]= *TIMERx_TCV(TIMER_REFER);
while(gpio_input_val(PULSE_DET_PIN)==1);
rc16m_buf[j++]= *TIMERx_TCV(TIMER_REFER);
}
for(int i=0;i<COLLECT_NUM;i++)
collect_buf[i]=rc16m_buf[i]-rc16m_buf[i+1];
freq_hz=RC16M_COEFFI*get_average(collect_buf+1,COLLECT_NUM-1);
if(freq_hz>RC16M_STD){
float tv=(freq_hz - RC16M_STD)/GEAR_HZ;
uint32_t t1=(((uint32_t)(tv*100))%100)>50 ? 1:0 ;
CPR_RF_REG0->rc16m_rtune -= (t1+((uint32_t)tv));
}else if(freq_hz<RC16M_STD){
float tv=(RC16M_STD-freq_hz)/GEAR_HZ;
uint32_t t1=(((uint32_t)(tv*100))%100)>50 ? 1:0 ;
CPR_RF_REG0->rc16m_rtune += (t1+((uint32_t)tv));
}
}
void calib_rc16m(void)
{
//[00-OSC32M],[01-bbpll direct output],[10-bbpll div output],[11-rc16M]
*((volatile unsigned *)(0x40000000+ 0x130)) |=0x06; //select clk source rc16M
//config pin
gpio_mux_ctl(PULSE_DET_PIN,0); gpio_fun_inter(PULSE_DET_PIN,0);
gpio_fun_sel(PULSE_DET_PIN,0); gpio_direction_input(PULSE_DET_PIN,1);//50HZ(10ms)
__write_hw_reg32((GPIO_DEBOUNCE0+(PULSE_DET_PIN>>4)),((0x10000)<<(PULSE_DET_PIN&0x0F))); //disable debounce
//CPR_RF_REG0->rc16m_rtune=0x3f;//set rc16m rtune default 0x3f (0-0x7f)
//calib start
timer_cnt(TIMER_REFER);//timer cnt,8 cycle is 1us
for(int i=0;i<CALIB_TIMES;i++) calib_rc16m_step();//calib 2 timrs , 60ms
//save calib val to 62 sector offset 32byte
//[00-OSC32M],[01-bbpll direct output],[10-bbpll div output],[11-rc16M]
*((volatile unsigned *)(0x40000000+ 0x130)) &=~0x06; //select clk source OSC32M
printf("CPR_RF_REG0->rc16m_rtune=0x%X\n",CPR_RF_REG0->rc16m_rtune);
}
#if 0
uint32_t rc16m_buf[50];
void calib_rc16m(void)
{
#if 0
uint32_t t1,t2;
*((volatile unsigned *)(0x40000000+ 0x130)) |=0x06; //[00-OSC32M],[01-bbpll direct output],[10-bbpll div output],[11-rc16M] //115200
CPR_RF_REG0->rc16m_rtune=0x7E;//set rc16m rtune
gpio_mux_ctl(7,0);gpio_fun_inter(7,0);gpio_fun_sel(7,0); gpio_direction_input(7,1);
__write_hw_reg32(GPIO_DEBOUNCE0,0xffff0000);
xc_timer_init(0,4000000);
uint8_t timers=50;
while(gpio_input_val(7)==0);
while(gpio_input_val(7)==1);
while(timers--)
{
while(gpio_input_val(7)==0);
t1=*TIMERx_TCV(0);
while(gpio_input_val(7)==1);
t2=*TIMERx_TCV(0);
rc16m_buf[timers]=t1-t2;
//printf("%d\n",t1-t2);
while(gpio_input_val(7)==0);
while(gpio_input_val(7)==1);
}
*((volatile unsigned *)(0x40000000+ 0x130)) &=~0x06;
printf("****\n");
for(int i=0;i<50;i++) printf("%d\n",rc16m_buf[i]);
while(1);
#endif
#if 0
uint32_t t1,t2;
//*((volatile unsigned *)(0x40000000+ 0x130)) |=0x06; //[00-OSC32M],[01-bbpll direct output],[10-bbpll div output],[11-rc16M] //115200
SET_RC16M_BBPLL_32M();
CPR_RF_REG0->rc16m_rtune=0xf0;//set rc16m rtune
gpio_mux_ctl(7,0);gpio_fun_inter(7,0);gpio_fun_sel(7,0); gpio_direction_input(7,1);
__write_hw_reg32(GPIO_DEBOUNCE0,0xffff0000);
xc_timer_init(0,4000000);
uint8_t timers=50;
while(gpio_input_val(7)==0);
while(gpio_input_val(7)==1);
while(timers--)
{
while(gpio_input_val(7)==0);
t1=*TIMERx_TCV(0);
while(gpio_input_val(7)==1);
t2=*TIMERx_TCV(0);
rc16m_buf[timers]=t1-t2;
//printf("%d\n",t1-t2);
while(gpio_input_val(7)==0);
while(gpio_input_val(7)==1);
}
*((volatile unsigned *)(0x40000000+ 0x130)) &=~0x06;
printf("****\n");
for(int i=0;i<50;i++) printf("%d\n",rc16m_buf[i]);
while(1);
#endif
}
void test_drift_rc16m(void)
{
}
void test_linear_rc16m(void)
{
}
void test_calib_rc16m(void)
{
calib_rc16m();
//gpio_output_high(26);
//gpio_output_low(26);
// //3.19ms
// calib_init();
// rc32k_calib(3);
//gpio_output_high(26);
//gpio_output_low(26);
#if 0
SET_RC16M_BBPLL_32M();
//CPR_RF_REG0->rc16m_rtune=0x00;//set rc16m rtune uart-89847-bps 415047
//CPR_RF_REG0->rc16m_rtune=0x20;//set rc16m rtune uart-100401-bps 464796
//CPR_RF_REG0->rc16m_rtune=0x40;//set rc16m rtune uart-107032-bps 530170
//CPR_RF_REG0->rc16m_rtune=0x60;//set rc16m rtune uart-134048-bps 619766
//CPR_RF_REG0->rc16m_rtune=0x80;//set rc16m rtune uart-107101-bps 534492
//CPR_RF_REG0->rc16m_rtune=0xa0;//set rc16m rtune uart-134124-bps 618613
// CPR_RF_REG0->rc16m_rtune=0xc0;//set rc16m rtune uart-161290-bps 744983
// CPR_RF_REG0->rc16m_rtune=0xE0;//set rc16m rtune uart-202839-bps 930793
// CPR_RF_REG0->rc16m_rtune=0xff;//set rc16m rtune uart-134048-bps 618332
CPR_RF_REG0->rc16m_rtune=0xf0;//set rc16m rtune uart-231481-bps 1069864
#endif
#if 0
*((volatile unsigned *)(0x40000000+ 0x130)) |=0x06; //[00-OSC32M],[01-bbpll direct output],[10-bbpll div output],[11-rc16M] //115200
CPR_RF_REG0->rc16m_rtune=0x00;//set rc16m rtune uart-45004-bps 207574
// CPR_RF_REG0->rc16m_rtune=0x20;//set rc16m rtune uart-50479-bps 233145
// CPR_RF_REG0->rc16m_rtune=0x40;//set rc16m rtune uart-57570-bps 266167
// CPR_RF_REG0->rc16m_rtune=0x60;//set rc16m rtune uart-67114-bps 309918
// CPR_RF_REG0->rc16m_rtune=0x80;//set rc16m rtune uart-57670-bps 266128
// CPR_RF_REG0->rc16m_rtune=0xa0;//set rc16m rtune uart-66979-bps 309810
// CPR_RF_REG0->rc16m_rtune=0xc0;//set rc16m rtune uart-80645-bps 371919
// CPR_RF_REG0->rc16m_rtune=0xE0;//set rc16m rtune uart-100704-bps 465464
// CPR_RF_REG0->rc16m_rtune=0xff;//set rc16m rtune uart-134048-bps 618221
// *((volatile unsigned *)(0x40002400 + 0x20)) =0x44;
// *((volatile unsigned *)(0x40002400 + 0x48)) =0x01;
#endif
xc_ao_timer_calib_test();
}
#endif