mirror of https://github.com/ARMmbed/mbed-os.git
778 lines
24 KiB
C++
778 lines
24 KiB
C++
/****************************************************************************
|
|
*
|
|
* Copyright 2020 Samsung Electronics All Rights Reserved.
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
* either express or implied. See the License for the specific
|
|
* language governing permissions and limitations under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "mbed.h"
|
|
#include "s5js100_dcxo.h"
|
|
#include "s5js100_type.h"
|
|
#include "mbed_trace.h"
|
|
#define TRACE_GROUP "DCXO"
|
|
|
|
#ifndef S5JS100_DCXO_DBG_ON
|
|
#define S5JS100_DCXO_DBG_ON 0
|
|
#endif
|
|
#define S5JS100_DCXO_DBG if (S5JS100_DCXO_DBG_ON) tr_info
|
|
|
|
#define DCXO_TEMPERATURE_RANGE 126 /* -40 ~ 85 */
|
|
#define DCXO_TSU_TABLE_MIN_TEMPERATURE (-40)
|
|
#define DCXO_TSU_TABLE_MAX_TEMPERATURE 85
|
|
#define DCXO_TSU_TABLE_MIN 10000
|
|
#define DCXO_TSU_TABLE_LENGTH 35
|
|
#define DCXO_TSU_TABLE_UNIT 5000
|
|
|
|
Thread *g_dcxo_tid;
|
|
static Semaphore dcxo_tbl_sem(1, 1);
|
|
|
|
static unsigned int tsu_code_to_temperature(unsigned int tsu_code);
|
|
static unsigned int tsu_temperature_to_code(unsigned int temp_celcius);
|
|
|
|
// table for KDS 9pF and SIDK board
|
|
// B constant : 3,380, T0 : 25'C
|
|
static const unsigned short g_dcxo_tsu_table[] = {
|
|
49690, //-40'C, 10,000
|
|
48942,
|
|
48194, //-30'C, 20,000
|
|
47446,
|
|
46698, //-20'C, 30,000
|
|
45639,
|
|
44316, //-10'C, 40,000
|
|
42776,
|
|
41063, //0'C, 50,000
|
|
39214,
|
|
37269, //10'C, 60,000
|
|
35261,
|
|
33221, //20'C, 70,000
|
|
31177,
|
|
29156, //30'C, 80,000
|
|
27180,
|
|
25267, //40'C, 90,000
|
|
23436,
|
|
21700, //50'C, 100,000
|
|
20069,
|
|
18553, //60'C, 110,000
|
|
17155,
|
|
15878, //70'C, 120,000
|
|
14721,
|
|
13681, //80'C, 130,000
|
|
12751,
|
|
11922, //90'C, 140,000
|
|
11181,
|
|
10513, //100'C, 150,000
|
|
9899,
|
|
9319, //110'C, 160,000
|
|
8749,
|
|
8162, //120'C, 170,000
|
|
7527,
|
|
6813, //130'C, 180,000
|
|
};
|
|
|
|
static volatile int tsu_interrupt_flag;
|
|
static int dcxo_init_flag;
|
|
static Full_set_table_t *dcxo_tbl;
|
|
|
|
// return value : (celcius temperature)*1000 + 50,000
|
|
static unsigned int tsu_code_to_temperature(unsigned int tsu_code)
|
|
{
|
|
unsigned int temp_code;
|
|
int index, base, ratio;
|
|
|
|
index = 0;
|
|
|
|
while (index < DCXO_TSU_TABLE_LENGTH) {
|
|
if (g_dcxo_tsu_table[index] <= tsu_code) {
|
|
break;
|
|
} else {
|
|
index++;
|
|
}
|
|
}
|
|
|
|
if (index <= 0) {
|
|
index = 1;
|
|
} else if (index >= DCXO_TSU_TABLE_LENGTH) {
|
|
index = DCXO_TSU_TABLE_LENGTH - 1;
|
|
}
|
|
|
|
base = (index - 1) * DCXO_TSU_TABLE_UNIT + DCXO_TSU_TABLE_MIN;
|
|
ratio = ((int)(g_dcxo_tsu_table[index - 1] - tsu_code) * DCXO_TSU_TABLE_UNIT)
|
|
/ (int)(g_dcxo_tsu_table[index - 1] - g_dcxo_tsu_table[index]);
|
|
temp_code = base + ratio;
|
|
return temp_code;
|
|
}
|
|
|
|
// temp_celcius : (celcius temperature)*1000 + 50,000
|
|
static unsigned int tsu_temperature_to_code(unsigned int temp_celcius)
|
|
{
|
|
int index, ratio;
|
|
|
|
index = (temp_celcius - DCXO_TSU_TABLE_MIN) / DCXO_TSU_TABLE_UNIT;
|
|
|
|
if (temp_celcius <= DCXO_TSU_TABLE_MIN) {
|
|
index = 0;
|
|
ratio = (int)(DCXO_TSU_TABLE_MIN + DCXO_TSU_TABLE_UNIT * index - temp_celcius) * (int)(g_dcxo_tsu_table[index] - g_dcxo_tsu_table[index + 1]) / DCXO_TSU_TABLE_UNIT;
|
|
} else if (index >= DCXO_TSU_TABLE_LENGTH - 1) {
|
|
index = DCXO_TSU_TABLE_LENGTH - 1;
|
|
ratio = (int)(DCXO_TSU_TABLE_MIN + DCXO_TSU_TABLE_UNIT * index - temp_celcius) * (int)(g_dcxo_tsu_table[index - 1] - g_dcxo_tsu_table[index]) / DCXO_TSU_TABLE_UNIT;
|
|
} else {
|
|
ratio = (int)(DCXO_TSU_TABLE_MIN + DCXO_TSU_TABLE_UNIT * index - temp_celcius) * (int)(g_dcxo_tsu_table[index] - g_dcxo_tsu_table[index + 1]) / DCXO_TSU_TABLE_UNIT;
|
|
}
|
|
|
|
//dbg("\nindex : %d , base : %d , ratio : %d\n", index, g_dcxo_tsu_table[index], ratio);
|
|
|
|
return g_dcxo_tsu_table[index] + ratio;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Function: up_timerisr
|
|
*
|
|
* Description:
|
|
* The timer ISR will perform a variety of services for various portions
|
|
* of the systems.
|
|
*
|
|
****************************************************************************/
|
|
int dcxo_tsu_isr(int irq, void *context, void *arg)
|
|
{
|
|
NVIC_DisableIRQ((IRQn_Type)irq);
|
|
|
|
tsu_interrupt_flag = 1;
|
|
|
|
if (irq == S5JS100_IRQ_TSU0) {
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 1, 1);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 0x10, 0x10);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF, 0x0);
|
|
//dbg("TSU0 interrupt\n");
|
|
} else if (irq == S5JS100_IRQ_TSU1) {
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 2, 2);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 0x20, 0x20);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF0000, 0xFFFF0000);
|
|
//dbg("TSU1 interrupt\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* Private Data
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
/****************************************************************************
|
|
* Name: s5js100_dcxo_ctb_loop
|
|
*
|
|
* Description:
|
|
* update DCXO value in every ms by parameter freq
|
|
*
|
|
* Returned Value:
|
|
* a NULL on failure
|
|
*
|
|
****************************************************************************/
|
|
int s5js100_dcxo_tbl_dump(void)
|
|
{
|
|
int i;
|
|
for (i = 0; i < DCXO_TEMPERATURE_RANGE; i++) {
|
|
S5JS100_DCXO_DBG("%d : CTB[%d]", i - 40, (dcxo_tbl + i)->ctb);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void dcxo_ctb_sem_wait(void)
|
|
{
|
|
dcxo_tbl_sem.try_acquire();
|
|
}
|
|
|
|
void dcxo_ctb_sem_release(void)
|
|
{
|
|
dcxo_tbl_sem.release();
|
|
}
|
|
|
|
void s5js100_dcxo_ctb_loop(void)
|
|
{
|
|
int tsu, index, ctb, ctb_prev;
|
|
int ctb_gap;
|
|
int loop_started = 0;
|
|
|
|
//s5js100_dcxo_tbl_dump();
|
|
|
|
while (1) {
|
|
// refer dcxo table
|
|
// read TSU
|
|
tsu = (int) s5js100_tsu_get_temperature();
|
|
index = (tsu - 10000) / 1000;
|
|
|
|
dcxo_ctb_sem_wait();
|
|
|
|
if (tsu < (50000 + DCXO_TSU_TABLE_MIN_TEMPERATURE * 1000)) {
|
|
index = 0;
|
|
ctb_gap = dcxo_tbl[index + 1].ctb - dcxo_tbl[index].ctb;
|
|
ctb = dcxo_tbl[index].ctb + (ctb_gap * (tsu - (50000 + DCXO_TSU_TABLE_MIN_TEMPERATURE * 1000))) / 1000;
|
|
} else if (tsu > (50000 + DCXO_TSU_TABLE_MAX_TEMPERATURE * 1000)) {
|
|
index = DCXO_TEMPERATURE_RANGE - 1;
|
|
ctb_gap = dcxo_tbl[index].ctb - dcxo_tbl[index - 1].ctb;
|
|
ctb = dcxo_tbl[index].ctb + (ctb_gap * (tsu - (50000 + DCXO_TSU_TABLE_MAX_TEMPERATURE * 1000))) / 1000;
|
|
} else {
|
|
ctb_gap = dcxo_tbl[index + 1].ctb - dcxo_tbl[index].ctb;
|
|
ctb = dcxo_tbl[index].ctb + ctb_gap * (tsu % 1000) / 1000;
|
|
}
|
|
|
|
if (ctb < 0) {
|
|
ctb = 0;
|
|
} else if (ctb > 16383) {
|
|
ctb = 16383;
|
|
}
|
|
|
|
if (!loop_started) {
|
|
S5JS100_DCXO_DBG("s5js100_dcxo_ctb_loop FIRST update temp(%d) coarse(%d -> %d)", tsu - 50000, s5js100_dcxo_get_coarse_tune_value, ctb);
|
|
s5js100_dcxo_set_tune_value(ctb, 4096);
|
|
} else {
|
|
ctb_prev = s5js100_dcxo_get_coarse_tune_value();
|
|
|
|
if (ctb > ctb_prev) {
|
|
ctb_prev++;
|
|
} else if (ctb < ctb_prev) {
|
|
ctb_prev--;
|
|
}
|
|
s5js100_dcxo_set_tune_value(ctb_prev, 4096);
|
|
}
|
|
|
|
if (ctb == 0) {
|
|
S5JS100_DCXO_DBG("[ERROR]CTB was 0x0[temp:%d]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", tsu);
|
|
}
|
|
|
|
loop_started = 1;
|
|
dcxo_ctb_sem_release();
|
|
osDelay(50);
|
|
}
|
|
}
|
|
|
|
int s5js100_tsu_get_code(void)
|
|
{
|
|
return (getreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_STA0) & 0xFFFF);
|
|
}
|
|
|
|
int s5js100_dcxo_force_update_ctb(void)
|
|
{
|
|
int tsu, index, ctb, code;
|
|
int ctb_gap;
|
|
|
|
// read TSU
|
|
code = s5js100_tsu_get_code();
|
|
tsu = (int) tsu_code_to_temperature(code);
|
|
|
|
index = (tsu - 10000) / 1000;
|
|
|
|
if (tsu < (50000 + DCXO_TSU_TABLE_MIN_TEMPERATURE * 1000)) {
|
|
index = 0;
|
|
ctb_gap = dcxo_tbl[index + 1].ctb - dcxo_tbl[index].ctb;
|
|
ctb = dcxo_tbl[index].ctb + (ctb_gap * (tsu - (50000 + DCXO_TSU_TABLE_MIN_TEMPERATURE * 1000))) / 1000;
|
|
} else if (tsu > (50000 + DCXO_TSU_TABLE_MAX_TEMPERATURE * 1000)) {
|
|
index = DCXO_TEMPERATURE_RANGE - 1;
|
|
ctb_gap = dcxo_tbl[index].ctb - dcxo_tbl[index - 1].ctb;
|
|
ctb = dcxo_tbl[index].ctb + (ctb_gap * (tsu - (50000 + DCXO_TSU_TABLE_MAX_TEMPERATURE * 1000))) / 1000;
|
|
} else {
|
|
ctb_gap = dcxo_tbl[index + 1].ctb - dcxo_tbl[index].ctb;
|
|
ctb = dcxo_tbl[index].ctb + ctb_gap * (tsu % 1000) / 1000;
|
|
}
|
|
|
|
if (ctb < 0) {
|
|
ctb = 0;
|
|
} else if (ctb > 16383) {
|
|
ctb = 16383;
|
|
}
|
|
|
|
s5js100_dcxo_set_tune_value(ctb, 4096);
|
|
|
|
if (ctb == 0) {
|
|
S5JS100_DCXO_DBG("Force CTB was 0x0[temp:%d, code:%d]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", tsu, code);
|
|
//asm("b .");
|
|
}
|
|
|
|
if ((tsu - 50000) > 0) {
|
|
//dcxollvdbg("TSU : %d.%03d 'C, CTB : %d ( %d )\n", (tsu - 50000) / 1000, (tsu) % 1000, ctb, tsu);
|
|
} else if ((tsu - 50000) > -1000) {
|
|
//dcxollvdbg("TSU : -%d.%03d 'C, CTB : %d ( %d )\n", (tsu - 50000) / 1000, (1000 - (tsu) % 1000) % 1000, ctb, tsu);
|
|
} else {
|
|
//dcxollvdbg("TSU : %d.%03d 'C, CTB : %d ( %d )\n", (tsu - 50000) / 1000, (1000 - (tsu) % 1000) % 1000, ctb, tsu);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
* Name: s5js100_dcxo_initialize
|
|
*
|
|
* Description:
|
|
* Initialize the DCXO.
|
|
*
|
|
* Returned Value:
|
|
* a NULL on failure
|
|
*
|
|
****************************************************************************/
|
|
int s5js100_dcxo_initialize(void)
|
|
{
|
|
if (dcxo_init_flag == 0) {
|
|
// initialize DOTSU, clk:100kHz
|
|
//putreg32(0x3E5, S5JS100_DCXO_CFG + DCXO_CFG_ADC_CFG);
|
|
//putreg32(0x1BE7, S5JS100_DCXO_CFG + DCXO_CFG_ADC_CFG); //ATE setting value
|
|
putreg32(0x13FE5, S5JS100_DCXO_CFG + DCXO_CFG_ADC_CFG); //Final setting value
|
|
putreg32(0x3A, S5JS100_DCXO_CFG + DCXO_CFG_DIV_CFG);
|
|
putreg32(0x30, S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1);
|
|
putreg32(0xFFFF0000, S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0);
|
|
|
|
// tsu sensing time by average unit
|
|
// 0:10us, 1:40us, 2:160us, 3:640us, 4:2.56ms, 5:10.24ms, 6:81.92ms, 7:327.68 ms
|
|
putreg32(0x3, S5JS100_DCXO_CFG + DCXO_CFG_AVR_CFG);
|
|
//putreg32(0x7, S5JS100_DCXO_CFG + DCXO_CFG_AVR_CFG);
|
|
|
|
// wait till update temperature
|
|
while (!(getreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_STA1) & 0xFFFF0000)) {
|
|
}
|
|
|
|
// initialize DCXO
|
|
// IDAC_SEL = 1
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x520, 1 << 3, 1 << 3);
|
|
|
|
#if 0
|
|
// IDAC_EX = 0xa0
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x524, 0xff << 5, 0xa0 << 5);
|
|
#else
|
|
// change tune parameter
|
|
// IDAC_EX = 100
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x524, 0xff << 5, 100 << 5);
|
|
|
|
// BUF_SEL = 8
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0xf << 3, 8 << 3);
|
|
#endif
|
|
|
|
#if defined(DCXO_FINE_PMU_COARSE_DCXO)
|
|
// Fine=FTUNE2, Coarse=DcxoFTune
|
|
// FuneMuxSel = 1
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 1, 1);
|
|
|
|
// FTSEL = 1
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 16, 1 << 16);
|
|
|
|
// FTSWP = 1
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 15, 1 << 15);
|
|
|
|
#elif defined(DCXO_FINE_PMU_COARSE_PMU)
|
|
// Fine=FTUNE2, Coarse=FTUNE
|
|
// FuneMuxSel = 0
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 1, 0);
|
|
|
|
// FTSEL = 1
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 16, 1 << 16);
|
|
|
|
// FTSWP = 1
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 15, 1 << 15);
|
|
#elif defined(DCXO_FINE_DCXO_COARSE_PMU)
|
|
// Fine=DcxoFTune, Coarse=FTUNE2
|
|
// FuneMuxSel = 1
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 1, 1);
|
|
|
|
// FTSEL = 1
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 16, 1 << 16);
|
|
|
|
// FTSWP = 0
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 1 << 15, 0);
|
|
#endif
|
|
dcxo_init_flag = 1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_start_ctb_loop(Full_set_table_t tbl[])
|
|
{
|
|
dcxo_tbl = tbl;
|
|
|
|
g_dcxo_tid = new rtos::Thread(osPriorityNormal, 2048, NULL, "ctbloop");
|
|
g_dcxo_tid->start(s5js100_dcxo_ctb_loop);
|
|
|
|
if (!g_dcxo_tid) {
|
|
return -ESRCH;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: s5js100_tsu_get_temperature
|
|
*
|
|
* Description:
|
|
* Read temperature of TSX.
|
|
*
|
|
* Returned Value:
|
|
* celcius temperature
|
|
*
|
|
****************************************************************************/
|
|
int s5js100_tsu_calculate_temperature(unsigned int code)
|
|
{
|
|
return tsu_code_to_temperature(code);
|
|
}
|
|
|
|
int s5js100_tsu_convert_code(unsigned int temperature)
|
|
{
|
|
return tsu_temperature_to_code(temperature);
|
|
}
|
|
|
|
int s5js100_tsu_get_temperature(void)
|
|
{
|
|
return tsu_code_to_temperature(s5js100_tsu_get_code());
|
|
}
|
|
|
|
int s5js100_tsu_set_interrupt(int high_interrupt, int temp)
|
|
{
|
|
unsigned int tsu_code, irq_no;
|
|
|
|
if (temp < DCXO_TSU_TABLE_MIN_TEMPERATURE) {
|
|
temp = DCXO_TSU_TABLE_MIN_TEMPERATURE;
|
|
} else if (temp > DCXO_TSU_TABLE_MIN_TEMPERATURE + DCXO_TSU_TABLE_LENGTH - 1) {
|
|
temp = DCXO_TSU_TABLE_MIN_TEMPERATURE + DCXO_TSU_TABLE_LENGTH - 1;
|
|
}
|
|
|
|
if (high_interrupt) {
|
|
tsu_code = tsu_temperature_to_code(temp - 1);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 1, 1);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 1, 0);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF, tsu_code);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 4), 0);
|
|
irq_no = S5JS100_IRQ_TSU0;
|
|
} else {
|
|
tsu_code = tsu_temperature_to_code(temp);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 2, 2);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 2, 0);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF0000, tsu_code << 16);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 5), 0);
|
|
irq_no = S5JS100_IRQ_TSU1;
|
|
}
|
|
|
|
//dbg("\ns5js100_tsu_set_interrupt(%d), tsu_code : 0x%x", high_interrupt, tsu_code);
|
|
|
|
NVIC_SetVector((IRQn_Type)irq_no, (uint32_t)dcxo_tsu_isr);
|
|
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
|
|
SCB_InvalidateICache();
|
|
#endif
|
|
NVIC_EnableIRQ((IRQn_Type)irq_no);
|
|
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 2), (1 << 2));
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 2), 0);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_tsu_set_interrupt_code(int high_interrupt, int tsu_code, int check)
|
|
{
|
|
unsigned int irq_no;
|
|
int ret = 1;
|
|
|
|
//dbg("s5js100_tsu_set_interrupt(%d), tsu_code : 0x%x\n", high_interrupt, tsu_code);
|
|
|
|
if (check) {
|
|
tsu_interrupt_flag = 0;
|
|
}
|
|
|
|
if (!high_interrupt) {
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 1, 1);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 1, 0);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF, tsu_code);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 4), 0);
|
|
irq_no = S5JS100_IRQ_TSU0;
|
|
} else {
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 2, 2);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, 2, 0);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG0, 0xFFFF0000, tsu_code << 16);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 5), 0);
|
|
irq_no = S5JS100_IRQ_TSU1;
|
|
}
|
|
|
|
NVIC_SetVector((IRQn_Type)irq_no, (uint32_t)dcxo_tsu_isr);
|
|
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
|
|
SCB_InvalidateICache();
|
|
#endif
|
|
NVIC_EnableIRQ((IRQn_Type)irq_no);
|
|
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 2), (1 << 2));
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_IRQ_CFG1, (1 << 2), 0);
|
|
|
|
if (check) {
|
|
//sleep(1);
|
|
|
|
if (!tsu_interrupt_flag) {
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int s5js100_dcxo_get_coarse_tune_value(void)
|
|
{
|
|
int coarse_tune;
|
|
|
|
#if defined(DCXO_FINE_PMU_COARSE_DCXO)
|
|
// Fine=DcxoFTune, Coarse=FTUNE2
|
|
coarse_tune = (getreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0) >> 1) & 0xFFFFF;
|
|
coarse_tune >>= 6;
|
|
#elif defined(DCXO_FINE_PMU_COARSE_PMU)
|
|
// Fine=FTUNE2, Coarse=FTUNE
|
|
|
|
// Coarse=FTUNE 14bit
|
|
// EVT0 : 0x81000524[26:13], EVT1 : 0x8100000C[13:0]
|
|
if (is_evt0()) {
|
|
coarse_tune = (getreg32(S5JS100_PMU_ALIVE + 0x524) >> 13) & 0x3FFF;
|
|
} else {
|
|
coarse_tune = (getreg32(S5JS100_PMU_ALIVE + 0xC) >> 0) & 0x3FFF;
|
|
}
|
|
#elif defined(DCXO_FINE_DCXO_COARSE_PMU)
|
|
// Fine=DcxoFTune, Coarse=FTUNE2
|
|
|
|
// Coarse=FTUNE2 14bit
|
|
// EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14]
|
|
if (is_evt0()) {
|
|
coarse_tune = (getreg32(S5JS100_PMU_ALIVE + 0x528) >> 17) & 0x3FFF;
|
|
} else {
|
|
coarse_tune = (getreg32(S5JS100_PMU_ALIVE + 0xC) >> 14) & 0x3FFF;
|
|
}
|
|
#endif
|
|
|
|
return coarse_tune;
|
|
}
|
|
|
|
|
|
int s5js100_dcxo_set_tune_value(unsigned int coarse_value, unsigned int fine_value)
|
|
{
|
|
#if defined(DCXO_FINE_PMU_COARSE_DCXO)
|
|
// Fine=DcxoFTune, Coarse=FTUNE2
|
|
coarse_value <<= 6;
|
|
|
|
// Coarse = DcxoFTune 20bit
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 0xFFFFF << 1, coarse_value << 1);
|
|
|
|
// Fine=FTUNE2 14bit
|
|
// EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14]
|
|
if (is_evt0()) {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, fine_value << 17);
|
|
} else {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, fine_value << 14);
|
|
}
|
|
#elif defined(DCXO_FINE_PMU_COARSE_PMU)
|
|
// Fine=FTUNE2, Coarse=FTUNE
|
|
|
|
// Fine = FTUNE2 13bit
|
|
// EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14]
|
|
if (is_evt0()) {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, fine_value << 17);
|
|
} else {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, fine_value << 14);
|
|
}
|
|
|
|
// Coarse=FTUNE 14bit
|
|
// EVT0 : 0x81000524[26:13], EVT1 : 0x8100000C[13:0]
|
|
if (is_evt0()) {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x524, (0x3FFF << 13), (coarse_value << 13));
|
|
} else {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 0, coarse_value << 0);
|
|
}
|
|
#elif defined(DCXO_FINE_DCXO_COARSE_PMU)
|
|
// Fine=DcxoFTune, Coarse=FTUNE2
|
|
fine_value <<= 6;
|
|
|
|
// Fine = DcxoFTune 20bit
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 0xFFFFF << 1, fine_value << 1);
|
|
|
|
// Coarse=FTUNE2 14bit
|
|
// EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14]
|
|
if (is_evt0()) {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, coarse_value << 17);
|
|
} else {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, coarse_value << 14);
|
|
}
|
|
#endif
|
|
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_set_tune_value_20bit(unsigned int coarse_value, unsigned int fine_value)
|
|
{
|
|
#if defined(DCXO_FINE_PMU_COARSE_DCXO)
|
|
// Coarse=DcxoFTune, Fine=FTUNE2
|
|
|
|
// Coarse = DcxoFTune 20bit
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 0xFFFFF << 1, coarse_value << 1);
|
|
|
|
// Fine=FTUNE2 14bit
|
|
// EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14]
|
|
if (is_evt0()) {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, fine_value << 17);
|
|
} else {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, fine_value << 14);
|
|
}
|
|
|
|
// toggle oSwRstDSM
|
|
//modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1<<3), 0);
|
|
//modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1<<3), (1<<3));
|
|
#elif defined(DCXO_FINE_PMU_COARSE_PMU)
|
|
// Fine=FTUNE2, Coarse=FTUNE
|
|
|
|
coarse_value >>= 6;
|
|
|
|
// Fine = FTUNE2 13bit
|
|
// EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14]
|
|
|
|
if (is_evt0()) {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, fine_value << 17);
|
|
} else {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, fine_value << 14);
|
|
}
|
|
|
|
// Coarse=FTUNE 14bit
|
|
// EVT0 : 0x81000524[26:13], EVT1 : 0x8100000C[13:0]
|
|
if (is_evt0()) {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x524, (0x3FFF << 13), (coarse_value << 13));
|
|
} else {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 0, coarse_value << 0);
|
|
}
|
|
#elif defined(DCXO_FINE_DCXO_COARSE_PMU)
|
|
// Fine=DcxoFTune, Coarse=FTUNE2
|
|
|
|
coarse_value >>= 6;
|
|
|
|
// Fine = DcxoFTune 20bit
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG0, 0xFFFFF << 1, fine_value << 1);
|
|
|
|
// Coarse=FTUNE2 14bit
|
|
// EVT0 : 0x81000528[31:17], EVT1 : 0x8100000C[28:14]
|
|
if (is_evt0()) {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x3FFF << 17, coarse_value << 17);
|
|
} else {
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0xC, 0x3FFF << 14, coarse_value << 14);
|
|
}
|
|
#endif
|
|
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_set_idac_ex(int value)
|
|
{
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x524, 0xff << 5, value << 5);
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_set_fb_res(int value)
|
|
{
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0x7 << 0, value << 0);
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_set_buf_sel(int value)
|
|
{
|
|
modifyreg32(S5JS100_PMU_ALIVE + 0x528, 0xf << 3, value << 3);
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_set_dsmdither(unsigned int dither_bit_sel)
|
|
{
|
|
#if defined(DCXO_FINE_PMU_COARSE_DCXO)
|
|
// set dither_bit_sel, iDsmType=1, iEnDsmDither=0, iPrbsSel=0, iEnDsm=1
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, 0x7F, (1 << 6) + (dither_bit_sel << 2) + 1);
|
|
|
|
// toggle oSwRstDSM
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3));
|
|
#else
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_set_dither_bit_sel(unsigned int dither_bit_sel)
|
|
{
|
|
#if defined(DCXO_FINE_PMU_COARSE_DCXO)
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, (7 << 2), (dither_bit_sel << 2));
|
|
// toggle oSwRstDSM
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3));
|
|
#else
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_set_dsm_type(unsigned int dsm_type)
|
|
{
|
|
#if defined(DCXO_FINE_PMU_COARSE_DCXO)
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, (1 << 6), (dsm_type << 6));
|
|
// toggle oSwRstDSM
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3));
|
|
#else
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_set_en_dsm_dither(unsigned int en_dsm_dither)
|
|
{
|
|
#if defined(DCXO_FINE_PMU_COARSE_DCXO)
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, (1 << 5), (en_dsm_dither << 5));
|
|
// toggle oSwRstDSM
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3));
|
|
#else
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_set_prbs_sel(unsigned int prbs_sel)
|
|
{
|
|
#if defined(DCXO_FINE_PMU_COARSE_DCXO)
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, (1 << 1), (prbs_sel << 1));
|
|
// toggle oSwRstDSM
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3));
|
|
#else
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
int s5js100_dcxo_en_dsm(unsigned int en_dsm)
|
|
{
|
|
#if defined(DCXO_FINE_PMU_COARSE_DCXO)
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_DSM_CFG1, (1 << 0), (en_dsm << 0));
|
|
// toggle oSwRstDSM
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), 0);
|
|
modifyreg32(S5JS100_DCXO_CFG + DCXO_CFG_SW_RESETN, (1 << 3), (1 << 3));
|
|
#else
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
extern "C" {
|
|
int s5js100_dcxo_force_initialize(void)
|
|
{
|
|
dcxo_init_flag = 0;
|
|
s5js100_dcxo_initialize();
|
|
s5js100_dcxo_force_update_ctb();
|
|
|
|
return 0;
|
|
}
|
|
}
|