1 /*
2 * Copyright (c) 2022 ASR Microelectronics (Shanghai) Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdint.h>
17 #include <math.h>
18 #include <stdio.h>
19 #include "duet_cm4.h"
20 #include "duet_common.h"
21 #include "duet_rf_spi.h"
22 #include "duet_cm4.h"
23 #include "duet.h"
24 #include "duet_gpio.h"
25 #include "duet_adc.h"
26
27 #if defined ADC_ENABLE
28 duet_adc_callback_func g_duet_adc_callback_handler;
29 uint16_t reg_f_value = 0;
duet_rf_auxadc_mode(AUX_ADC_MOD mode)30 static void duet_rf_auxadc_mode(AUX_ADC_MOD mode)
31 {
32 // have verify on case 12,pass.
33 spi_mst_write(0x06, 0x07AF);
34 spi_mst_write(0x07, 0xBFF3);
35 rf_set_reg_bit(0x1E, 3, 3, 0x7);
36 spi_mst_write(0x0F, 0x8000);
37 spi_mst_write(0x75, 0xE9C0);
38 if (mode == MOD_TRIG) {
39 rf_set_reg_bit(0xA3, 6, 1, 0x0);
40 } else if (mode == MOD_CNT10) {
41 rf_set_reg_bit(0xA3, 6, 1, 0x1);
42 }
43 delay(250);
44 }
45
duet_adc_init(duet_adc_dev_t * adc_config)46 int32_t duet_adc_init(duet_adc_dev_t *adc_config)
47 {
48 uint32_t reg_value;
49 uint8_t temp_chan;
50 duet_gpio_dev_t config_gpio;
51 if (adc_config->port > 9) {
52 return 0;
53 }
54 config_gpio.port = adc_config->port + 4;
55 config_gpio.config = DUET_INPUT_HIGH_IMPEDANCE;
56 config_gpio.priv = NULL;
57 duet_gpio_init(&config_gpio);
58 reg_value = REG_RD(HW_CTRL_PE_PS);
59 REG_WR(HW_CTRL_PE_PS, (reg_value & (~(1 << config_gpio.port)))); // cfg by// user
60 reg_value = REG_RD(PAD_PE_REG); //
61 // REG_WR(PAD_PE_REG, (reg_value|((1 << gpio->port))));
62 REG_WR(PAD_PE_REG, (reg_value & (~(1 << config_gpio.port))));
63 // adc_config->duet_adc_handler_struct.cb = adc_config->priv;
64 if (adc_config->priv) {
65 duet_rf_auxadc_mode(MOD_CNT10);
66 } else {
67 duet_rf_auxadc_mode(MOD_TRIG);
68 }
69 // duet_rf_auxadc_mode(adc_config->mode);
70 rf_set_reg_bit(0xa3, 12, 2, ADC_SAMPLE_125K);
71 // Enable AUXADC
72 rf_set_reg_bit(0x06, 14, 1, 0x0);
73 // Enable TMMT
74 rf_set_reg_bit(0x07, 4, 1, 0x0);
75 // Enable CLK AUXADC13M; D_XO_CLK_AUXADC13M_EN= 1
76 rf_set_reg_bit(0x75, 14, 1, 0x1);
77 // Enable XO CLK AUCADC, DFF's RB;D_RST_XO_CLK_AUXADC= 0
78 rf_set_reg_bit(0x0F, 11, 1, 0);
79 delay(250); // delay(2000)
80 // Open channel 1
81 if (adc_config->port <= 7) {
82 REG_WR(SYS_REG_BASE_CLKCTRL_ENABLE, REG_RD(SYS_REG_BASE_CLKCTRL_ENABLE) | AUX_ADC_CLK);
83 REG_WR(SYS_REG_BASE_IRQ_ENABLE, REG_RD(SYS_REG_BASE_IRQ_ENABLE) | AUX_ADC_IRQ);
84 REG_WR(SYS_REG_BASE_XOCTRL2, ((REG_RD(SYS_REG_BASE_XOCTRL2) & (~(uint32_t)0x7)) | (uint32_t)adc_config->port) | ((
85 uint32_t)(BIT(9))));
86 REG_WR(SYS_REG_BASE_AUXADC, REG_RD(SYS_REG_BASE_AUXADC) | ((uint32_t)(BIT(9))));
87 } else {
88 temp_chan = adc_config->port - 8;
89 REG_WR(SYS_REG_BASE_XOCTRL2, ((REG_RD(SYS_REG_BASE_XOCTRL2) & (~(uint32_t)0x7)) | (uint32_t)temp_chan) & (~(uint32_t)(
90 BIT(9))));
91 }
92 delay(200);
93 if (adc_config->priv) {
94 g_duet_adc_callback_handler = (duet_adc_callback_func)(adc_config->priv);
95 ADC->BITS_ADC_CTRL.adc_int_clr = 0;
96 ADC->BITS_ADC_CTRL.adc_int_mode = MOD_CNT10;
97 ADC->BITS_ADC_CTRL.adc_int_en = 1;
98 NVIC_EnableIRQ(AUX_ADC_IRQn);
99 } else {
100 g_duet_adc_callback_handler = NULL;
101 ADC->BITS_ADC_CTRL.adc_int_clr = 0;
102 ADC->BITS_ADC_CTRL.adc_int_mode = MOD_TRIG;
103 ADC->BITS_ADC_CTRL.adc_int_en = 0;
104 }
105 return 0;
106 }
107
duet_adc_get(duet_adc_dev_t * adc_config)108 int32_t duet_adc_get(duet_adc_dev_t *adc_config)
109 {
110 int32_t vol_value = 0;
111 if (rf_get_reg_bit(0x06, 14, 1)) {
112 return 0;
113 }
114 vol_value = (ADC->ADC_DATA & 0xFFF0) >> 4;
115 if (adc_config->port < 8) {
116 return (int32_t)(0.4243 * vol_value + 6.9805);
117 } else {
118 return 0;
119 }
120 }
duet_tempr_get(duet_adc_dev_t * adc_config)121 int32_t duet_tempr_get(duet_adc_dev_t *adc_config)
122 {
123 static int16_t temp_n, temp_p;
124 static uint8_t tp_flag = 0;
125 if (adc_config->port < 8) {
126 return 0;
127 }
128 if (adc_config->port == ADC_CHANNEL_TEMN) {
129 temp_n = (int16_t)((ADC->ADC_DATA & 0xFFF0) >> 4);
130 tp_flag |= 0x1;
131 } else {
132 temp_p = (int16_t)((ADC->ADC_DATA & 0xFFF0) >> 4);
133 tp_flag |= 0x2;
134 }
135 if (tp_flag == 0x3) {
136 tp_flag = 0;
137 return (int32_t)((0.29 * (temp_n - temp_p)) / 5.25 + 41.5);
138 } else {
139 return 0;
140 }
141 }
142
duet_adc_finalize(duet_adc_dev_t * adc_config)143 int32_t duet_adc_finalize(duet_adc_dev_t *adc_config)
144 {
145 // Close AUXADC
146 rf_set_reg_bit(0x06, 14, 1, 0x1);
147 // Close XO CLK AUCADC; D_RST_XO_CLK_AUXADC= 1
148 spi_mst_write(0x0f, reg_f_value);
149 // Close CLK AUXADC13M; D_XO_CLK_AUXADC13M_EN= 0
150 rf_set_reg_bit(0x75, 14, 1, 0x0);
151 ADC->BITS_ADC_CTRL.adc_int_clr = 0;
152 ADC->BITS_ADC_CTRL.adc_int_mode = 0;
153 ADC->BITS_ADC_CTRL.adc_int_en = 0;
154 NVIC_DisableIRQ(AUX_ADC_IRQn);
155 return 0;
156 }
157
AUX_ADC_IRQHandler(void)158 void AUX_ADC_IRQHandler(void)
159 {
160 uint32_t vol_value[10] = {0};
161 if (g_duet_adc_callback_handler) {
162 for (uint8_t i = 0; i < 10; i++) {
163 vol_value[i] = (ADC->ADC_DATA & 0xFFF0) >> 4;
164 }
165 g_duet_adc_callback_handler(vol_value);
166 }
167 ADC->BITS_ADC_CTRL.adc_int_clr = 1;
168 while (ADC->BITS_ADC_CTRL.adc_int_clr) {
169 ADC->BITS_ADC_CTRL.adc_int_clr = 0;
170 }
171 }
172
173 #endif
174