| | |
| | | uint32_t val; |
| | | |
| | | // load cap |
| | | if (board_param.flag & (1 << BOARD_LOAD_CAP)) |
| | | if (board_param.flag & (1 << BOARD_X38M4_LOAD_CAP)) |
| | | { |
| | | calib_xtal38m4_load_cap_set(board_param.load_cap); |
| | | calib_xtal38m4_load_cap_set(board_param.x38m4_load_cap); |
| | | } |
| | | if (board_param.flag & (1 << BOARD_X32K_LOAD_CAP)) |
| | | { |
| | |
| | | // REG_WRITE(0x4000020c, val | (0x18 << 7)); |
| | | |
| | | #if (LOW_POWER_EN) && (XTAL32K_EN == 0) |
| | | rco32k_clk_calibrate(RCO32K_MEAS_TIME_64_CYCLES); |
| | | clk32k_ppm_calibrate(CLK32K_MEAS_TIME_64_CYCLES); |
| | | #endif |
| | | } |
| | | |
| | |
| | | tmp_val &= ~0x7FU; |
| | | tmp_val |= (val & 0x7FU); |
| | | REG_WRITE(0x40000048, tmp_val); |
| | | LOG_INFO(TRACE_NO_REPORT_HOST | TRACE_MODULE_DRIVER, "XTAL load cap tune %d : %d\r\n", ppm, (tmp_val & 0x7FU)); |
| | | LOG_INFO(TRACE_NO_REPORT_HOST | TRACE_MODULE_DRIVER, "X38M4 load cap tune %d : %d\r\n", ppm, (tmp_val & 0x7FU)); |
| | | } |
| | | |
| | | void calib_xtal38m4_load_cap_auto_tune_to_center(int32_t ppm, uint8_t calib_load_cap) |
| | | { |
| | | // unit is 0.01pm, the value 478 is the frequency offset that the loadcap value from 0 to 1 |
| | | int32_t load_cap_ppm_offset[128] = {0, 478, 465, 449, 441, 421, 410, 398, 379, 374, 365, 353, 350, 333, 328, 315, 320, 300, 292, 285, 282, 271, |
| | | 265, 257, 249, 245, 241, 235, 234, 225, 220, 215, 249, 205, 200, 197, 195, 189, 185, 180, 175, 174, 171, 166, |
| | | 167, 161, 157, 155, 157, 148, 147, 143, 143, 138, 137, 133, 130, 130, 127, 125, 126, 121, 120, 116, 182, 112, |
| | | 111, 110, 108, 106, 105, 102, 98, 100, 97, 97, 96, 95, 92, 91, 92, 88, 87, 86, 86, 83, 83, 81, |
| | | 78, 80, 78, 77, 77, 75, 75, 73, 85, 71, 71, 70, 70, 67, 67, 66, 65, 65, 63, 63, 63, 61, |
| | | 61, 60, 61, 60, 57, 58, 57, 56, 56, 55, 53, 53, 53, 53, 52, 52, 51, 50}; |
| | | uint8_t load_cap_value = 0; |
| | | if (ppm >= 0) |
| | | { |
| | | for (uint8_t ii = calib_load_cap; ii < 127; ii++) |
| | | { |
| | | if (ppm > load_cap_ppm_offset[ii + 1]) |
| | | { |
| | | ppm -= load_cap_ppm_offset[ii + 1]; |
| | | } |
| | | else if (ppm > (load_cap_ppm_offset[ii + 1] / 2)) |
| | | { |
| | | ppm -= load_cap_ppm_offset[ii + 1]; |
| | | load_cap_value = ii + 1; |
| | | break; |
| | | } |
| | | else |
| | | { |
| | | load_cap_value = ii; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | ppm = ABS(ppm); |
| | | for (uint8_t ii = calib_load_cap; ii > 0; ii--) |
| | | { |
| | | if (ppm > load_cap_ppm_offset[ii]) |
| | | { |
| | | ppm -= load_cap_ppm_offset[ii]; |
| | | } |
| | | else if (ppm > (load_cap_ppm_offset[ii] / 2)) |
| | | { |
| | | load_cap_value = ii; |
| | | break; |
| | | } |
| | | else |
| | | { |
| | | ppm -= load_cap_ppm_offset[ii]; |
| | | load_cap_value = ii - 1; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | uint8_t load_cap_current = REG_READ(0x40000048) & 0x7FU; |
| | | if (load_cap_current != load_cap_value) |
| | | { |
| | | calib_xtal38m4_load_cap_set(load_cap_value); |
| | | } |
| | | } |
| | | |
| | | void calib_xtal38m4_load_cap_set(uint8_t val) |
| | |
| | | val &= 0x7FU; |
| | | |
| | | REG_WRITE(0x40000048, tmp_val | val); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "XTAL load cap val %d\r\n", REG_READ(0x40000048) & 0x7FU); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "X38M4 load cap val %d\r\n", REG_READ(0x40000048) & 0x7FU); |
| | | } |
| | | |
| | | void calib_xtal38m4_with_clock_out(uint8_t val) |
| | |
| | | |
| | | REG_WRITE(0x40000048, tmp_val | val); |
| | | REG_WRITE(0x40000104, 0x3FFF); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "XTAL load cap val %d\r\n", REG_READ(0x40000048) & 0x7FU); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "X38M4 load cap val %d\r\n", REG_READ(0x40000048) & 0x7FU); |
| | | } |
| | | |
| | | void calib_xtal32k_load_cap_set(uint8_t val) |
| | |
| | | val &= 0x7FU; |
| | | |
| | | REG_WRITE(0x4000004C, tmp_val | val); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "32K load cap val %d\r\n", REG_READ(0x4000004C) & 0x7FU); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "X32K load cap val %d\r\n", REG_READ(0x4000004C) & 0x7FU); |
| | | } |
| | | |
| | | void calib_xtal32k_with_clock_out(uint8_t val) |
| | |
| | | val &= 0x7FU; |
| | | |
| | | REG_WRITE(0x4000004C, tmp_val | val); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "32K load cap val %d\r\n", REG_READ(0x4000004C) & 0x7FU); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "X32K load cap val %d\r\n", REG_READ(0x4000004C) & 0x7FU); |
| | | } |
| | | |
| | | void CALIB_IRQHandler(void) |