对比新文件 |
| | |
| | | /* |
| | | * Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and |
| | | * its subsidiaries and affiliates (collectly called MKSEMI). |
| | | * |
| | | * All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * 1. Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * |
| | | * 2. Redistributions in binary form, except as embedded into an MKSEMI |
| | | * integrated circuit in a product or a software update for such product, |
| | | * must reproduce the above copyright notice, this list of conditions and |
| | | * the following disclaimer in the documentation and/or other materials |
| | | * provided with the distribution. |
| | | * |
| | | * 3. Neither the name of MKSEMI nor the names of its contributors may be used |
| | | * to endorse or promote products derived from this software without |
| | | * specific prior written permission. |
| | | * |
| | | * 4. This software, with or without modification, must only be used with a |
| | | * MKSEMI integrated circuit. |
| | | * |
| | | * 5. Any software provided in binary form under this license must not be |
| | | * reverse engineered, decompiled, modified and/or disassembled. |
| | | * |
| | | * THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED |
| | | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| | | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| | | * DISCLAIMED. IN NO EVENT SHALL MKSEMI OR CONTRIBUTORS BE LIABLE FOR ANY |
| | | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| | | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| | | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| | | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | |
| | | #include "mk_calib.h" |
| | | #include "mk_clock.h" |
| | | #include "mk_reset.h" |
| | | #include "mk_trace.h" |
| | | #include "mk_misc.h" |
| | | #include "mk_rtc.h" |
| | | |
| | | #include "board.h" |
| | | |
| | | int calib_open(void) |
| | | { |
| | | // enable CAL clock |
| | | clock_enable(CLOCK_CALIB); |
| | | reset_module(RESET_MODULE_CALIB); |
| | | return DRV_OK; |
| | | } |
| | | |
| | | int calib_close(void) |
| | | { |
| | | // disable CAL clock |
| | | clock_disable(CLOCK_CALIB); |
| | | return DRV_OK; |
| | | } |
| | | |
| | | void calib_start(uint32_t items) |
| | | { |
| | | REG_WRITE(CALIB_BASE, items | CALIB_START); |
| | | } |
| | | |
| | | void calib_check(uint32_t done) |
| | | { |
| | | while ((REG_READ(CALIB_BASE + 0x4) & done) != done) |
| | | { |
| | | } |
| | | } |
| | | |
| | | void calib_chip(void) |
| | | { |
| | | uint32_t val; |
| | | |
| | | // load cap |
| | | if (board_param.flag & (1 << BOARD_LOAD_CAP)) |
| | | { |
| | | calib_xtal38m4_load_cap_set(board_param.load_cap); |
| | | } |
| | | if (board_param.flag & (1 << BOARD_X32K_LOAD_CAP)) |
| | | { |
| | | calib_xtal32k_load_cap_set(board_param.x32k_load_cap); |
| | | } |
| | | |
| | | clock_enable(CLOCK_CALIB); |
| | | |
| | | // fix DCDC_EN |
| | | val = REG_READ(0x40000204) & ~0x3U; |
| | | REG_WRITE(0x40000204, val | 0x2); |
| | | |
| | | // LO PLL configure |
| | | REG_WRITE(0x4000060c, 0x0A106BAF); |
| | | |
| | | #if HIGH_PERFORMANCE_MODE_EN |
| | | // LPF_BM |
| | | REG_WRITE(0x40000608, 0x03E80004); |
| | | // increase Trim current to promote RF performance |
| | | REG_WRITE_BYTE(0x40010072, 0x77); |
| | | #else |
| | | // decrease Trim current |
| | | // REG_WRITE_BYTE(0x40010072, 0x88); // lowest |
| | | |
| | | // clear Trim code |
| | | REG_WRITE_BYTE(0x40010072, 0x00); // middle |
| | | |
| | | val = REG_READ_BYTE(0x40010071) & 0x1F; |
| | | REG_WRITE_BYTE(0x40010071, (uint8_t)val); |
| | | #endif |
| | | |
| | | #define LO_L (77 + (56 << 8) + (54 << 16) + (80 << 24)) |
| | | #define LO_H (49 + (46 << 8) + (50 << 16) + (54 << 24)) |
| | | #define WF (7 + (52 << 8)) |
| | | |
| | | // patch for buck calibration voltage |
| | | uint8_t x = REG_READ_BYTE(0x40010075); |
| | | if ((READ_WORD(0x4001007C) == LO_L) && (READ_WORD(0x40010078) == LO_H) && (READ_SHORT(0x40010076) == WF) && (x >= 1) && (x <= 19)) |
| | | { |
| | | REG_WRITE_BYTE(0x40010073, 0x20); |
| | | } |
| | | |
| | | // patch for ADC trim code |
| | | val = REG_READ_BYTE(0x4001006B); |
| | | if ((val & 0x1F) == 0) |
| | | { |
| | | REG_WRITE_BYTE(0x4001006B, (uint8_t)(val | 0x10)); |
| | | } |
| | | |
| | | // Open RCO for calibration |
| | | SYSCON->PMU_CTRL0 &= ~(1U << 5); |
| | | |
| | | // calibrate |
| | | REG_WRITE(0x40006000, 0x80001cfe); |
| | | |
| | | while ((REG_READ(0x40006004) & 0x80000000) == 0) |
| | | { |
| | | } |
| | | |
| | | uint32_t id = mk_chip_id(); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "Chip ID: %08x\r\n", id); |
| | | if (id == 0x0 || id == 0x400 || id == 0x800 || id == 0xC00) |
| | | { |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "Old chip model is not supported by this SDK!!!\r\n"); |
| | | while (1) |
| | | { |
| | | } |
| | | } |
| | | |
| | | // Reduce next PA calibration time |
| | | val = REG_READ(0x400060d4) & ~0xfU; |
| | | REG_WRITE(0x400060d4, val); |
| | | |
| | | val = REG_READ(0x400060c8) & ~((0xfU << 18) | (0x1)); |
| | | REG_WRITE(0x400060c8, val); |
| | | |
| | | // Reduce turnaround time |
| | | REG_WRITE(0x40000410, 400); |
| | | REG_WRITE(0x4000040c, 0x1f); |
| | | |
| | | // val = REG_READ(0x4000020c) & ~(0x1fU << 7); |
| | | // REG_WRITE(0x4000020c, val | (0x18 << 7)); |
| | | |
| | | #if (LOW_POWER_EN) && (XTAL32K_EN == 0) |
| | | rco32k_clk_calibrate(RCO32K_MEAS_TIME_64_CYCLES); |
| | | #endif |
| | | } |
| | | |
| | | void calib_xtal38m4_load_cap_auto_tune(int32_t ppm) |
| | | { |
| | | uint32_t tmp_val = REG_READ(0x40000048); |
| | | uint8_t val = (tmp_val & 0x7FU); |
| | | |
| | | if (ppm > 2) |
| | | { |
| | | val += 1; |
| | | } |
| | | else if (ppm < -2) |
| | | { |
| | | val -= 1; |
| | | } |
| | | else |
| | | { |
| | | return; |
| | | } |
| | | 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)); |
| | | } |
| | | |
| | | void calib_xtal38m4_load_cap_set(uint8_t val) |
| | | { |
| | | uint32_t tmp_val = REG_READ(0x40000048); |
| | | |
| | | tmp_val &= ~0x7FU; |
| | | val &= 0x7FU; |
| | | |
| | | REG_WRITE(0x40000048, tmp_val | val); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "XTAL load cap val %d\r\n", REG_READ(0x40000048) & 0x7FU); |
| | | } |
| | | |
| | | void calib_xtal38m4_with_clock_out(uint8_t val) |
| | | { |
| | | /* Setting GPIO17 output 38.4M clock. */ |
| | | uint32_t tmp_val = REG_READ(0x4000003C); |
| | | tmp_val &= ~0x70U; |
| | | tmp_val |= (0x1U << 4); |
| | | REG_WRITE(0x4000003C, tmp_val); |
| | | |
| | | /* Setting internal load cap of MK8000, the valid value is from 0 ot 127. */ |
| | | tmp_val = REG_READ(0x40000048); |
| | | |
| | | tmp_val &= ~0x7FU; |
| | | val &= 0x7FU; |
| | | |
| | | 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); |
| | | } |
| | | |
| | | void calib_xtal32k_load_cap_set(uint8_t val) |
| | | { |
| | | uint32_t tmp_val = REG_READ(0x4000004C); |
| | | |
| | | tmp_val &= ~0x7FU; |
| | | val &= 0x7FU; |
| | | |
| | | REG_WRITE(0x4000004C, tmp_val | val); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "32K load cap val %d\r\n", REG_READ(0x4000004C) & 0x7FU); |
| | | } |
| | | |
| | | void calib_xtal32k_with_clock_out(uint8_t val) |
| | | { |
| | | /* Setting GPIO02 output 32K clock. */ |
| | | uint32_t tmp_val = REG_READ(0x40000234); |
| | | tmp_val |= (0x1U << 10); |
| | | REG_WRITE(0x40000234, tmp_val); |
| | | |
| | | /* Setting GPIO02 oupt 32K clock by pin mux. */ |
| | | tmp_val = REG_READ(0x40000034); |
| | | tmp_val &= ~(0xFU << 8); |
| | | tmp_val |= (0x4U << 8); |
| | | REG_WRITE(0x40000034, tmp_val); |
| | | |
| | | /* Setting internal load cap of MK8000, the valid value is from 0 ot 127. */ |
| | | tmp_val = REG_READ(0x4000004C); |
| | | |
| | | tmp_val &= ~0x7FU; |
| | | val &= 0x7FU; |
| | | |
| | | REG_WRITE(0x4000004C, tmp_val | val); |
| | | LOG_INFO(TRACE_MODULE_DRIVER, "32K load cap val %d\r\n", REG_READ(0x4000004C) & 0x7FU); |
| | | } |
| | | |
| | | void CALIB_IRQHandler(void) |
| | | { |
| | | } |