• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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