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 <stdio.h>
18 #include "duet_cm4.h"
19 #include "duet_common.h"
20 #include "duet_rf_spi.h"
spi_sw_protect_write(uint16_t addr,uint16_t data)21 void spi_sw_protect_write(uint16_t addr, uint16_t data)
22 {
23 *((volatile int *) (SPI_COMMAND + TRANS_MODE_OFT)) = 0;
24 *((volatile int *) (SPI_COMMAND + PRESCALER_OFT)) = 3; // 8:80M/16=5M, 2:80M/4=20M
25 *((volatile int *) (SPI_COMMAND + ADDR_REG_OFT)) = addr;
26 *((volatile int *) (SPI_COMMAND + READNOTWRITE_OFT)) = 0;
27 *((volatile int *) (SPI_COMMAND + WDATA_REG_OFT)) = data;
28 *((volatile int *) (SPI_COMMAND + START_FLAG_OFT)) = 1;
29
30 while (1) {
31 // printf("\n rdate:%08x\n",((uint32_t)*((volatile uint32_t *)(SPI_RDATA + RDATA_REG_OFT)) &0x00010000));
32 if (((uint32_t) * ((volatile uint32_t *)(SPI_RDATA + RDATA_REG_OFT)) & 0x00010000) == 0) {
33 break;
34 } else {
35 *((volatile int *) (SPI_COMMAND + START_FLAG_OFT)) = 1;
36 }
37 }
38
39 while (1) {
40 if (*((volatile int *)(SPI_COMMAND + START_FLAG_OFT)) == 0) {
41 break;
42 }
43 }
44
45 }
46
spi_sw_protect_read(uint16_t addr)47 uint16_t spi_sw_protect_read(uint16_t addr)
48 {
49 *((volatile int *)(SPI_COMMAND + TRANS_MODE_OFT)) = 0;
50 *((volatile int *)(SPI_COMMAND + PRESCALER_OFT)) = 8;
51 *((volatile int *)(SPI_COMMAND + ADDR_REG_OFT)) = addr;
52 *((volatile int *)(SPI_COMMAND + READNOTWRITE_OFT)) = 1;
53 *((volatile int *)(SPI_COMMAND + START_FLAG_OFT)) = 1;
54
55 while (1) {
56 // printf("\n rdate:%08x\n",((uint32_t)*((volatile uint32_t *)(SPI_RDATA + RDATA_REG_OFT)) &0x00010000));
57 if (((uint32_t) * ((volatile uint32_t *)(SPI_RDATA + RDATA_REG_OFT)) & 0x00010000) == 0) {
58 break;
59 } else {
60 *((volatile int *) (SPI_COMMAND + START_FLAG_OFT)) = 1;
61 }
62 }
63
64 while (1) {
65 if (*((volatile int *)(SPI_COMMAND + START_FLAG_OFT)) == 0) {
66 return ((uint16_t) *((volatile uint32_t *)(SPI_RDATA + RDATA_REG_OFT)));
67 }
68 }
69
70 }
71
rf_sw_set_reg_bit(uint16_t reg,uint8_t start_bit,uint8_t len,uint16_t src_val)72 void rf_sw_set_reg_bit(uint16_t reg, uint8_t start_bit, uint8_t len, uint16_t src_val)
73 {
74 uint16_t tmp, mask, val;
75
76 if ((reg < 0xFF) && (start_bit < 16) && (len <= 16) && (src_val < (1 << len))) {
77 tmp = spi_sw_protect_read(reg);
78
79 mask = (1 << len) - 1; // 1. clear dst bit. eg: len=4, mask = 0xf, 1111
80 mask = ~(mask << start_bit); // ~(mask<<4):0xff0f: 1111 1111 0000 1111
81
82 val = tmp & mask; // 2.val =spi_read() & 0xff0f, clear [7:4]
83
84 src_val = (src_val << start_bit);
85 val = val | src_val; // 3. val spi_read & 0xff0f | val << 4
86
87 spi_sw_protect_write(reg, val);
88 } else {
89 printf("set_reg input parms not support \r\n");
90 return;
91 }
92 }
93
rf_sw_get_reg_bit(uint16_t reg,uint8_t start_bit,uint8_t len)94 uint16_t rf_sw_get_reg_bit(uint16_t reg, uint8_t start_bit, uint8_t len)
95 {
96 uint16_t mask, val;
97
98 if ((reg < 0xFF) && (start_bit < 16) && (len <= 16)) {
99 val = spi_sw_protect_read(reg); // 1. read reg val
100
101 mask = (1 << len) - 1; // eg: len =4, 0xf,1111
102 mask = mask << start_bit; // 0x0f00;
103 val = val & mask; // 2. get dst bit
104
105 val = (val >> start_bit); // 3. ror
106
107 return val;
108 } else {
109 return -1;
110 }
111 }
112
113 /// single wifi run and without PTA init,these api is useful
114 uint8_t hw_spi_pta = 0;
115
spi_mst_write(uint16_t addr,uint16_t data)116 FLASH_COMMON2_SEG void spi_mst_write(uint16_t addr, uint16_t data)
117 {
118 uint32_t var = 0;
119
120 *((volatile int *) (SPI_COMMAND + TRANS_MODE_OFT)) = 0;
121 *((volatile int *) (SPI_COMMAND + PRESCALER_OFT)) = 8; // 8:80M/16=5M, 2:80M/4=20M
122 *((volatile int *) (SPI_COMMAND + ADDR_REG_OFT)) = addr;
123 *((volatile int *) (SPI_COMMAND + READNOTWRITE_OFT)) = 0;
124 *((volatile int *) (SPI_COMMAND + WDATA_REG_OFT)) = data;
125 *((volatile int *) (SPI_COMMAND + START_FLAG_OFT)) = 1;
126
127 if (hw_spi_pta == 0) {
128 do {
129 var = (*((volatile int *)(SPI_COMMAND + START_FLAG_OFT)));
130 } while (var);
131 } else if (hw_spi_pta == 1) {
132 while (1) {
133 // printf("\n rdate:%08x\n",((uint32_t)*((volatile uint32_t *)(SPI_RDATA + RDATA_REG_OFT)) &0x00010000));
134 if (((uint32_t) * ((volatile uint32_t *)(SPI_RDATA + RDATA_REG_OFT)) & 0x00010000) == 0) {
135 break;
136 } else {
137 *((volatile int *) (SPI_COMMAND + START_FLAG_OFT)) = 1;
138 }
139 }
140
141 while (1) {
142 if (*((volatile int *)(SPI_COMMAND + START_FLAG_OFT)) == 0) {
143 break;
144 }
145 }
146 }
147 delay(40);
148 }
149
spi_mst_read(uint16_t addr)150 FLASH_COMMON2_SEG uint16_t spi_mst_read(uint16_t addr)
151 {
152 uint32_t var = 0;
153
154 *((volatile int *)(SPI_COMMAND + TRANS_MODE_OFT)) = 0;
155 *((volatile int *)(SPI_COMMAND + PRESCALER_OFT)) = 8;
156 *((volatile int *)(SPI_COMMAND + ADDR_REG_OFT)) = addr;
157 *((volatile int *)(SPI_COMMAND + READNOTWRITE_OFT)) = 1;
158 *((volatile int *)(SPI_COMMAND + START_FLAG_OFT)) = 1;
159
160 if (hw_spi_pta == 0) {
161 do {
162 var = (*((volatile int *)(SPI_COMMAND + START_FLAG_OFT)));
163 } while (var);
164
165 return ((uint16_t) * ((volatile uint32_t *)(SPI_RDATA + RDATA_REG_OFT)));
166 } else if (hw_spi_pta == 1) {
167 while (1) {
168 if (((uint32_t) * ((volatile uint32_t *)(SPI_RDATA + RDATA_REG_OFT)) & 0x00010000) == 0) {
169 break;
170 } else {
171 *((volatile int *) (SPI_COMMAND + START_FLAG_OFT)) = 1;
172 }
173 }
174
175 while (1) {
176 if (*((volatile int *)(SPI_COMMAND + START_FLAG_OFT)) == 0) {
177 delay(40);
178 return ((uint16_t) * ((volatile uint32_t *)(SPI_RDATA + RDATA_REG_OFT)));
179 }
180 }
181 }
182
183 return 0;
184 }
185
rf_set_reg_bit(uint16_t reg,uint8_t start_bit,uint8_t len,uint16_t src_val)186 FLASH_COMMON2_SEG void rf_set_reg_bit(uint16_t reg, uint8_t start_bit, uint8_t len, uint16_t src_val)
187 {
188 uint16_t tmp, mask, val;
189
190 if ((reg < 0xFF) && (start_bit < 16) && (len <= 16) && (src_val < (1 << len))) {
191 tmp = spi_mst_read(reg);
192
193 mask = (1 << len) - 1; // 1. clear dst bit. eg: len=4, mask = 0xf, 1111
194 mask = ~(mask << start_bit); // ~(mask<<4):0xff0f: 1111 1111 0000 1111
195
196 val = tmp & mask; // 2.val =spi_read() & 0xff0f, clear [7:4]
197
198 src_val = (src_val << start_bit);
199 val = val | src_val; // 3. val spi_read & 0xff0f | val << 4
200
201 spi_mst_write(reg, val);
202 } else {
203 printf("set_reg input parms not support \r\n");
204 return;
205 }
206 }
207
rf_get_reg_bit(uint16_t reg,uint8_t start_bit,uint8_t len)208 uint16_t rf_get_reg_bit(uint16_t reg, uint8_t start_bit, uint8_t len)
209 {
210 uint16_t mask, val;
211
212 if ((reg < 0xFF) && (start_bit < 16) && (len <= 16)) {
213 val = spi_mst_read(reg); // 1. read reg val
214
215 mask = (1 << len) - 1; // eg: len =4, 0xf,1111
216 mask = mask << start_bit; // 0x0f00;
217 val = val & mask; // 2. get dst bit
218
219 val = (val >> start_bit); // 3. ror
220
221 return val;
222 } else {
223 return -1;
224 }
225 }
226
227