temperature_compensation.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /********************************************************************************
  2. * USDK(ZS283A)
  3. * Module: SYSTEM
  4. * Copyright(c) 2003-2017 Actions Semiconductor,
  5. * All Rights Reserved.
  6. *
  7. * History:
  8. * <author> <time> <version > <desc>
  9. * wuyufan 2019-2-18-3:20:35 1.0 build this file
  10. ********************************************************************************/
  11. /*!
  12. * \file temperature_compensation.c
  13. * \brief
  14. * \author
  15. * \version 1.0
  16. * \date 2019-2-18-3:20:35
  17. *******************************************************************************/
  18. #include <kernel.h>
  19. #include <init.h>
  20. #include <soc.h>
  21. #include "temp_comp.h"
  22. #include <soc_atp.h>
  23. #include <compensation.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #define SYS_LOG_DOMAIN "cap comp"
  27. #include <logging/log.h>
  28. LOG_MODULE_REGISTER(cap_comp, CONFIG_LOG_DEFAULT_LEVEL);
  29. extern void ipmsg_btc_soc_set_hosc_cap(int cap);
  30. static cap_temp_comp_ctrl_t cap_temp_comp_ctrl;
  31. #if 0 /* Sample rable relate to crystal oscillator */
  32. // <"temperature compensation", CFG_CATEGORY_BLUETOOTH>
  33. static const CFG_Struct_Cap_Temp_Comp CFG_Cap_Temp_Comp_Tbl =
  34. {
  35. // <"enable temperature compensation", CFG_TYPE_BOOL>
  36. .Enable_Cap_Temp_Comp = true,
  37. // <"temperature compensation", CFG_Type_Cap_Temp_Comp>
  38. .Table =
  39. {
  40. { CAP_TEMP_N_40, (0x100 - (1.6f * 10))}, /* HOSONIC crystal oscillator */
  41. { CAP_TEMP_N_30, (0x100 - (0.6f * 10))},
  42. { CAP_TEMP_N_20, (0.3f * 10)},
  43. { CAP_TEMP_0, (0.7f * 10)},
  44. { CAP_TEMP_P_25, (0.0f * 10)},
  45. { CAP_TEMP_P_45, (0x100 - (0.6f * 10))},
  46. { CAP_TEMP_P_65, (0x100 - (0.6f * 10))},
  47. { CAP_TEMP_P_80, (0.0f * 10)},
  48. { CAP_TEMP_NA, 0.0f * 10 },
  49. { CAP_TEMP_NA, 0.0f * 10 }
  50. },
  51. };
  52. #elif 0
  53. // <"temperature compensation", CFG_CATEGORY_BLUETOOTH>
  54. static const CFG_Struct_Cap_Temp_Comp CFG_Cap_Temp_Comp_Tbl =
  55. {
  56. // <"enable temperature compensation", CFG_TYPE_BOOL>
  57. .Enable_Cap_Temp_Comp = true,
  58. // <"temperature compensation", CFG_Type_Cap_Temp_Comp>
  59. .Table =
  60. {
  61. { CAP_TEMP_N_40, (0x100 - (2.0f * 10))}, /* SEIKO crystal oscillator */
  62. { CAP_TEMP_N_20, (0x100 - (0.6f * 10))},
  63. { CAP_TEMP_N_10, (0x100 - (0.2f * 10))},
  64. { CAP_TEMP_0, (0x100 - (0.1f * 10))},
  65. { CAP_TEMP_P_10, (0x100 - (0.2f * 10))},
  66. { CAP_TEMP_P_40, (0x100 - (0.8f * 10))},
  67. { CAP_TEMP_P_60, (0x100 - (0.9f * 10))},
  68. { CAP_TEMP_P_80, (0x100 - (0.1f * 10))},
  69. { CAP_TEMP_NA, 0.0f * 10 },
  70. { CAP_TEMP_NA, 0.0f * 10 }
  71. },
  72. };
  73. #else
  74. static const CFG_Struct_Cap_Temp_Comp CFG_Cap_Temp_Comp_Tbl =
  75. {
  76. // <"enable temperature compensation", CFG_TYPE_BOOL>
  77. .Enable_Cap_Temp_Comp = true,
  78. // <"temperature compensation", CFG_Type_Cap_Temp_Comp>
  79. .Table =
  80. {
  81. { CAP_TEMP_N_40, 0.0f * 10 },
  82. { CAP_TEMP_N_20, 0.0f * 10 },
  83. { CAP_TEMP_P_5, 0.0f * 10 },
  84. { CAP_TEMP_P_25, 0.0f * 10 },
  85. { CAP_TEMP_P_45, 0.0f * 10 },
  86. { CAP_TEMP_P_60, 0.0f * 10 },
  87. { CAP_TEMP_P_80, 0.0f * 10 },
  88. { CAP_TEMP_NA, 0.0f * 10 },
  89. { CAP_TEMP_NA, 0.0f * 10 },
  90. { CAP_TEMP_NA, 0.0f * 10 }
  91. },
  92. };
  93. #endif
  94. /*temperature compensation process */
  95. static void cap_temp_comp_proc(int temp)
  96. {
  97. cap_temp_comp_ctrl_t *p = &cap_temp_comp_ctrl;
  98. int comp = 0;
  99. LOG_DBG("cur temp %d, last temp %d", temp, p->last_temp);
  100. if (abs(temp - p->last_temp) <= 2) {
  101. return;
  102. }
  103. p->last_temp = temp;
  104. if (temp <= (s8_t)p->configs.Table[0].Cap_Temp) {
  105. comp = (s8_t)p->configs.Table[0].Cap_Comp;
  106. } else if (temp >= (s8_t)p->configs.Table[p->table_size - 1].Cap_Temp) {
  107. comp = (s8_t)p->configs.Table[p->table_size - 1].Cap_Comp;
  108. } else {
  109. int i;
  110. for (i=0; i<(p->table_size - 1); i++) {
  111. CFG_Type_Cap_Temp_Comp* t1 = &p->configs.Table[i];
  112. CFG_Type_Cap_Temp_Comp* t2 = &p->configs.Table[i + 1];
  113. if (temp >= (s8_t)t1->Cap_Temp && temp < (s8_t)t2->Cap_Temp) {
  114. comp = (temp - (s8_t)t1->Cap_Temp) *
  115. ((s8_t)t2->Cap_Comp - (s8_t)t1->Cap_Comp) /
  116. ((s8_t)t2->Cap_Temp - (s8_t)t1->Cap_Temp) +
  117. (s8_t)t1->Cap_Comp;
  118. break;
  119. }
  120. }
  121. }
  122. LOG_INF("temp %d, cap base %d comp %s%d.%d", temp, p->normal_cap,
  123. ((comp < 0) ? "-" : ""), abs(comp) / 10, abs(comp) % 10);
  124. ipmsg_btc_soc_set_hosc_cap((int)p->normal_cap + comp);
  125. }
  126. void cap_temp_do_comp(int temp)
  127. {
  128. if (!cap_temp_comp_ctrl.enabled) {
  129. return;
  130. }
  131. cap_temp_comp_proc(temp);
  132. }
  133. /* Hosc cap temperature compensate.
  134. * base_cap : base cap
  135. */
  136. int cap_temp_comp_init(uint8_t base_cap)
  137. {
  138. int i;
  139. memset(&cap_temp_comp_ctrl, 0, sizeof(cap_temp_comp_ctrl));
  140. cap_temp_comp_ctrl.normal_cap = base_cap;
  141. memcpy(&cap_temp_comp_ctrl.configs, &CFG_Cap_Temp_Comp_Tbl, sizeof(CFG_Struct_Cap_Temp_Comp));
  142. for (i=0; i<CFG_MAX_CAP_TEMP_COMP; i++) {
  143. if (cap_temp_comp_ctrl.configs.Table[i].Cap_Temp == CAP_TEMP_NA) {
  144. break;
  145. }
  146. cap_temp_comp_ctrl.table_size += 1;
  147. }
  148. cap_temp_comp_ctrl.last_temp = CAP_TEMP_NA;
  149. if (cap_temp_comp_ctrl.table_size == 0) {
  150. return -1;
  151. }
  152. if (!cap_temp_comp_ctrl.configs.Enable_Cap_Temp_Comp) {
  153. return -1;
  154. }
  155. cap_temp_comp_ctrl.enabled = true;
  156. return 0;
  157. }