1
2 /*
3 * Copyright (c) 2024 HPMicro
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 */
8
9 /*---------------------------------------------------------------------
10 * Include
11 *---------------------------------------------------------------------
12 */
13 #include "hpm_ppi.h"
14 #include "hpm_clock_drv.h"
15
ppi_ns2cycle(uint32_t ns)16 static uint32_t ppi_ns2cycle(uint32_t ns)
17 {
18 uint32_t ppi_freq = clock_get_frequency(clock_ppi0);
19 uint32_t max_cycle = PPI_CMD_CMD_CFG_CYCLE_NUM_MASK >> PPI_CMD_CMD_CFG_CYCLE_NUM_SHIFT;
20 uint32_t ns_per_cycle;
21 uint32_t cycle;
22
23 ns_per_cycle = 1000000000 / ppi_freq;
24 cycle = ns / ns_per_cycle;
25 if (cycle > max_cycle) {
26 cycle = max_cycle;
27 }
28
29 return cycle;
30 }
31
32 /* API */
ppi_config_async_sram(PPI_Type * ppi,uint8_t cs_index,uint8_t cmd_start_index,ppi_async_sram_config_t * config)33 void ppi_config_async_sram(PPI_Type *ppi, uint8_t cs_index, uint8_t cmd_start_index, ppi_async_sram_config_t *config)
34 {
35 ppi_cs_pin_config_t cs_config;
36 ppi_cmd_config_t cmd_config;
37
38 assert(!config->ad_mux_mode && (config->port_size != ppi_port_size_32bits));
39 assert(((config->base_address & 0xFFFFF) == 0) && (config->size_in_byte > 0)); /* Addr should be aligned by 1MB */
40
41 /*
42 * Pin polarity Config
43 */
44 if (config->cs_valid_polarity) {
45 ppi_config_cs_pin_polarity(ppi, cs_index, ppi_cs_idle_pol_low);
46 } else {
47 ppi_config_cs_pin_polarity(ppi, cs_index, ppi_cs_idle_pol_high);
48 }
49
50 if (config->ad_mux_mode) {
51 ppi_set_ctrl_pin_dir(ppi, config->adv_ctrl_pin, ppi_ctrl_pin_dir_output);
52 ppi_config_ctrl_pin_polarity(ppi, config->adv_ctrl_pin, ppi_ctrl_pol_low);
53 }
54 ppi_set_ctrl_pin_dir(ppi, config->rel_ctrl_pin, ppi_ctrl_pin_dir_output);
55 ppi_config_ctrl_pin_polarity(ppi, config->rel_ctrl_pin, ppi_ctrl_pol_low);
56 ppi_set_ctrl_pin_dir(ppi, config->wel_ctrl_pin, ppi_ctrl_pin_dir_output);
57 ppi_config_ctrl_pin_polarity(ppi, config->wel_ctrl_pin, ppi_ctrl_pol_low);
58
59 /*
60 * Read Cmd
61 */
62 /* common */
63 cmd_config.cs_pin_value = config->cs_valid_polarity;
64 cmd_config.clk_output = false;
65 if (config->ad_mux_mode) {
66 cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
67 cmd_config.byte_sel[1] = ppi_byte_sel_8_15_bits;
68 cmd_config.byte_sel[2] = ppi_byte_sel_16_23_bits;
69 cmd_config.byte_sel[3] = ppi_byte_sel_24_31_bits;
70 } else {
71 if (config->port_size == ppi_port_size_8bits) {
72 cmd_config.ad_func_sel[0] = ppi_ad_func_data;
73 cmd_config.ad_pin_dir[0] = ppi_ad_pin_dir_input;
74 cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
75 for (uint8_t i = 1; i < 4; i++) {
76 cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
77 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
78 }
79 cmd_config.byte_sel[1] = ppi_byte_sel_0_7_bits;
80 cmd_config.byte_sel[2] = ppi_byte_sel_8_15_bits;
81 cmd_config.byte_sel[3] = ppi_byte_sel_16_23_bits;
82 } else if (config->port_size == ppi_port_size_16bits) {
83 for (uint8_t i = 0; i < 2; i++) {
84 cmd_config.ad_func_sel[i] = ppi_ad_func_data;
85 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_input;
86 }
87 cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
88 cmd_config.byte_sel[1] = ppi_byte_sel_8_15_bits;
89 for (uint8_t i = 2; i < 4; i++) {
90 cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
91 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
92 }
93 cmd_config.byte_sel[2] = ppi_byte_sel_0_7_bits;
94 cmd_config.byte_sel[3] = ppi_byte_sel_8_15_bits;
95 } else {
96 ; /* Not Support */
97 }
98 }
99 cmd_config.ctrl_pin_value[config->wel_ctrl_pin] = true;
100
101 /* AS Stage */
102 cmd_config.cmd_cycle = ppi_ns2cycle(config->as_in_ns);
103 if (config->ad_mux_mode) {
104 for (uint8_t i = 0; i < 4; i++) {
105 cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
106 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
107 }
108 cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = config->addr_valid_polarity;
109 }
110 cmd_config.ctrl_pin_value[config->rel_ctrl_pin] = true;
111 ppi_config_cmd(ppi, cmd_start_index, &cmd_config);
112
113 /* AH Stage */
114 cmd_config.cmd_cycle = ppi_ns2cycle(config->ah_in_ns);
115 if (config->ad_mux_mode) {
116 for (uint8_t i = 0; i < 4; i++) {
117 cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
118 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
119 }
120 cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
121 }
122 cmd_config.ctrl_pin_value[config->rel_ctrl_pin] = true;
123 ppi_config_cmd(ppi, cmd_start_index + 1, &cmd_config);
124
125 /* REL Stage */
126 cmd_config.cmd_cycle = ppi_ns2cycle(config->rel_in_ns);
127 if (config->ad_mux_mode) {
128 for (uint8_t i = 0; i < 4; i++) {
129 cmd_config.ad_func_sel[i] = ppi_ad_func_data;
130 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_input;
131 }
132 cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
133 }
134 cmd_config.ctrl_pin_value[config->rel_ctrl_pin] = false;
135 ppi_config_cmd(ppi, cmd_start_index + 2, &cmd_config);
136
137 /* REH Stage */
138 cmd_config.cmd_cycle = ppi_ns2cycle(config->reh_in_ns);
139 if (config->ad_mux_mode) {
140 for (uint8_t i = 0; i < 4; i++) {
141 cmd_config.ad_func_sel[i] = ppi_ad_func_data;
142 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_input;
143 }
144 cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
145 }
146 cmd_config.ctrl_pin_value[config->rel_ctrl_pin] = true;
147 ppi_config_cmd(ppi, cmd_start_index + 3, &cmd_config);
148
149 /*
150 * Write Cmd
151 */
152 /* common */
153 cmd_config.cs_pin_value = config->cs_valid_polarity;
154 cmd_config.clk_output = false;
155 if (config->ad_mux_mode) {
156 cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
157 cmd_config.byte_sel[1] = ppi_byte_sel_8_15_bits;
158 cmd_config.byte_sel[2] = ppi_byte_sel_16_23_bits;
159 cmd_config.byte_sel[3] = ppi_byte_sel_24_31_bits;
160 } else {
161 if (config->port_size == ppi_port_size_8bits) {
162 cmd_config.ad_func_sel[0] = ppi_ad_func_data;
163 cmd_config.ad_pin_dir[0] = ppi_ad_pin_dir_output;
164 cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
165 for (uint8_t i = 1; i < 4; i++) {
166 cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
167 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
168 }
169 cmd_config.byte_sel[1] = ppi_byte_sel_0_7_bits;
170 cmd_config.byte_sel[2] = ppi_byte_sel_8_15_bits;
171 cmd_config.byte_sel[3] = ppi_byte_sel_16_23_bits;
172 } else if (config->port_size == ppi_port_size_16bits) {
173 for (uint8_t i = 0; i < 2; i++) {
174 cmd_config.ad_func_sel[i] = ppi_ad_func_data;
175 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
176 }
177 cmd_config.byte_sel[0] = ppi_byte_sel_0_7_bits;
178 cmd_config.byte_sel[1] = ppi_byte_sel_8_15_bits;
179 for (uint8_t i = 2; i < 4; i++) {
180 cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
181 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
182 }
183 cmd_config.byte_sel[2] = ppi_byte_sel_0_7_bits;
184 cmd_config.byte_sel[3] = ppi_byte_sel_8_15_bits;
185 } else {
186 ; /* Not Support */
187 }
188 }
189 cmd_config.ctrl_pin_value[config->rel_ctrl_pin] = true;
190
191 /* AS Stage */
192 cmd_config.cmd_cycle = ppi_ns2cycle(config->as_in_ns);
193 if (config->ad_mux_mode) {
194 for (uint8_t i = 0; i < 4; i++) {
195 cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
196 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
197 }
198 cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = config->addr_valid_polarity;
199 }
200 cmd_config.ctrl_pin_value[config->wel_ctrl_pin] = true;
201 ppi_config_cmd(ppi, cmd_start_index + 4, &cmd_config);
202
203 /* AH Stage */
204 cmd_config.cmd_cycle = ppi_ns2cycle(config->ah_in_ns);
205 if (config->ad_mux_mode) {
206 for (uint8_t i = 0; i < 4; i++) {
207 cmd_config.ad_func_sel[i] = ppi_ad_func_addr;
208 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
209 }
210 cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
211 }
212 cmd_config.ctrl_pin_value[config->wel_ctrl_pin] = true;
213 ppi_config_cmd(ppi, cmd_start_index + 5, &cmd_config);
214
215 /* WEL Stage */
216 cmd_config.cmd_cycle = ppi_ns2cycle(config->wel_in_ns);
217 if (config->ad_mux_mode) {
218 for (uint8_t i = 0; i < 4; i++) {
219 cmd_config.ad_func_sel[i] = ppi_ad_func_data;
220 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
221 }
222 cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
223 }
224 cmd_config.ctrl_pin_value[config->wel_ctrl_pin] = false;
225 ppi_config_cmd(ppi, cmd_start_index + 6, &cmd_config);
226
227 /* WEH Stage */
228 cmd_config.cmd_cycle = ppi_ns2cycle(config->weh_in_ns);
229 if (config->ad_mux_mode) {
230 for (uint8_t i = 0; i < 4; i++) {
231 cmd_config.ad_func_sel[i] = ppi_ad_func_data;
232 cmd_config.ad_pin_dir[i] = ppi_ad_pin_dir_output;
233 }
234 cmd_config.ctrl_pin_value[config->adv_ctrl_pin] = !config->addr_valid_polarity;
235 }
236 cmd_config.ctrl_pin_value[config->wel_ctrl_pin] = true;
237 ppi_config_cmd(ppi, cmd_start_index + 7, &cmd_config);
238
239 /*
240 * CS Config
241 */
242 cs_config.addr_start_high_12bits = (config->base_address & 0xFFF00000u) >> 20u;
243 cs_config.addr_end_high_12bits = ((config->base_address + (config->size_in_byte - 1u)) & 0xFFF00000u) >> 20u;
244 cs_config.port_size = config->port_size;
245 cs_config.addr_mask = 0xFFFFu;
246 cs_config.sync_clk_en = false;
247 cs_config.sync_clk_sel = 0;
248 cs_config.interval_cycle = 2;
249 cs_config.rcmd_start0 = cmd_start_index;
250 cs_config.rcmd_end0 = cmd_start_index + 3;
251 cs_config.rcmd_start1 = cmd_start_index;
252 cs_config.rcmd_end1 = cmd_start_index + 3;
253 cs_config.wcmd_start0 = cmd_start_index + 4;
254 cs_config.wcmd_end0 = cmd_start_index + 7;
255 cs_config.wcmd_start1 = cmd_start_index + 4;
256 cs_config.wcmd_end1 = cmd_start_index + 7;
257 #if defined(HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS) && HPM_IP_FEATURE_PPI_DM_POLARITY_EACH_CS
258 if (config->dm_valid_polarity) {
259 cs_config.dm_polarity = ppi_dm_valid_pol_high;
260 } else {
261 cs_config.dm_polarity = ppi_dm_valid_pol_low;
262 }
263 #else
264 if (config->dm_valid_polarity) {
265 ppi_config_dm_pin_polarity(ppi, cs_index, ppi_dm_valid_pol_high);
266 } else {
267 ppi_config_dm_pin_polarity(ppi, cs_index, ppi_dm_valid_pol_low);
268 }
269 #endif
270 ppi_config_cs_pin(ppi, cs_index, &cs_config);
271 }
272