1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
|
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#ifndef __CH56X_SYS_H__
#define __CH56X_SYS_H__
#include "soc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define sys_safe_access_enter(sys) \
do { \
sys->SAFE_ACCESS_SIG.reg = SAFE_ACCESS_SIG_1; \
sys->SAFE_ACCESS_SIG.reg = SAFE_ACCESS_SIG_2; \
} while(0)
#define sys_safe_access_leave(sys) \
do sys->SAFE_ACCESS_SIG.reg = 0; while(0)
union _sys_safe_access_sig
{
uint8_t reg;
struct
{
uint8_t safe_acc_mode : 2; // RO, current safe access, 11b => RWA ok
uint8_t resv_2 : 2;
uint8_t safe_acc_timer : 3; // RO, current safe access time count
uint8_t resv_7 : 1;
};
};
#define RB_SAFE_ACC_MODE 0x03
#define RB_SAFE_ACC_TIMER 0x70
#define SAFE_ACCESS_SIG_1 0x57
#define SAFE_ACCESS_SIG_2 0xa8
union _sys_glob_rom_cfg
{
uint8_t reg;
struct
{
uint8_t rom_ext_re : 1; // RO, allow programmer to read FlashROM
uint8_t code_ram_we : 1; // RWA, code SRAM writaboe
uint8_t rom_data_we : 1; // RWA, FlashROM data erasable/writable
uint8_t rom_code_we : 1; // RWA, FlashROM code erasable/writable
uint8_t rom_code_ofs : 1; // RWA, FlashROM offset for user code
uint8_t resv_5 : 3;
};
};
#define RB_ROM_EXT_RE 0x01
#define RB_CODE_RAM_WE 0x02
#define RB_ROM_DATA_WE 0x04
#define RB_ROM_CODE_WE 0x08
#define RB_ROM_CODE_OFS 0x10
#define ROM_CODE_OFS_0x00000 0
#define ROM_CODE_OFS_0x04000 1
union _sys_rst_boot_stat
{
uint8_t reg;
struct
{
uint8_t reset_flag : 2; // RO, last reset cause
uint8_t cfg_reset_en : 1; // RO, external reset pin (#RST) status
uint8_t cfg_boot_en : 1; // RO, reset as 1
uint8_t cfg_debug_en : 1; // RO
uint8_t boot_loader : 1; // RO
uint8_t resv_6 : 2;
};
};
#define RB_RESET_FLAG 0x03
#define RB_CFG_RESET_EN 0x04
#define RB_CFG_BOOT_EN 0x08
#define RB_CFG_DEBUG_EN 0x10
#define RB_BOOT_LOADER 0x20
#define RESET_FLAG_IS_SOFT 0
#define RESET_FLAG_IS_POR 1
#define RESET_FLAG_IS_WDOG 2
#define RESET_FLAG_IS_RSTPIN 3
union _sys_rst_wdog_ctrl
{
uint8_t reg;
struct
{
uint8_t software_reset : 1; // WA/WZ, system software reset, auto clear
#if defined(SOC_SERIES_CH569)
uint8_t wdog_rst_en : 1; // RWA, enable watchdog overflow to reset
uint8_t wdog_int_en : 1; // RWA, enable watchdog overflow interrupt
uint8_t wdog_int_flag : 1; // RW1, watchdog counter overflow
#else
uint8_t resv_2 : 3;
#endif
uint8_t resv_4 : 4; // RO, B.7-6 must write 01b
};
};
#define RB_SOFTWARE_RESET 0x01
#ifdef SOC_SERIES_CH569
#define RB_WDOG_RST_EN 0x02
#define RB_WDOG_INT_EN 0x04
#define RB_WDOG_INT_FLAG 0x08
#endif
#define wdog_ctrl_wdat(v) (0x40 | (v))
union _sys_clk_pll_div
{
uint8_t reg;
struct
{
uint8_t pll_div : 4; // RWA, min 2
uint8_t resv_4 : 4; // RWA, B.7-6 must write 01b
};
};
#define clk_pll_div_wdat(div) (0x40 | (div))
union _sys_clk_cfg_ctrl
{
uint8_t reg;
struct
{
uint8_t pll_sleep : 1; // RWA, PLL sleep control
uint8_t sel_pll : 1; // RWA, clock source select
uint8_t resv_6 : 6; // RWA, must write 10b
};
};
#define RB_CLK_PLL_SLEEP 0x01
#define RB_CLK_SEL_PLL 0x02
#define CLK_PLL_SLEEP_DISABLE 0
#define CLK_PLL_SLEEP_ENABLE 1
#define CLK_SEL_PLL_HSE_30M 0
#define CLK_SEL_PLL_USB_480M 1
#define clk_cfg_ctrl_wdat(v) (0x80 | (v))
union _sys_clk_mod_aux
{
uint8_t reg;
struct
{
uint8_t int_125m_en : 1; // RWA, USB PHY 125MHz to ETH
uint8_t ext_125m_en : 1; // RWA, external 125MHz to ETH
uint8_t mco_sel_msk : 2; // RWA, MCO output select
uint8_t mco_en : 1; // RWA, MCO output enable
uint8_t resv_5 : 3;
};
};
#define RB_INT_125M_EN 0x01
#define RB_EXT_125M_EN 0x02
#define RB_MCO_SEL_MSK 0x0c
#define RB_MCO_EN 0x10
#define MCO_SEL_MSK_125M 0
#define MCO_SEL_MSK_25M 1
#define MCO_SEL_MSK_2_5M 2
/* All bits are RWA (need safe_access_sig), 0/1 : clock on/off
*/
union _sys_slp_clk_off0
{
uint8_t reg;
struct
{
uint8_t tmr0 : 1;
uint8_t tmr1 : 1;
uint8_t tmr2 : 1;
uint8_t pwmx : 1;
uint8_t uart0 : 1;
uint8_t uart1 : 1;
uint8_t uart2 : 1;
uint8_t uart3 : 1;
};
};
#define RB_SLP_CLK_TMR0 0x01
#define RB_SLP_CLK_TMR1 0x02
#define RB_SLP_CLK_TMR2 0x04
#define RB_SLP_CLK_PWMX 0x08
#define RB_SLP_CLK_UART0 0x10
#define RB_SLP_CLK_UART1 0x20
#define RB_SLP_CLK_UART2 0x40
#define RB_SLP_CLK_UART3 0x80
#define SYS_SLP_CLK_ON 0
#define SYS_SLP_CLK_OFF 1
/* All writable bits are RWA (need safe_access_sig), 0/1 : clock on/off
*/
union _sys_slp_clk_off1
{
uint8_t reg;
struct
{
uint8_t spi0 : 1;
uint8_t spi1 : 1;
#if defined(SOC_CH567)
uint8_t sdc : 1;
uint8_t led : 1;
uint8_t usb0 : 1;
uint8_t usb1 : 1;
uint8_t resv_6 : 1;
#elif defined(SOC_CH568)
uint8_t sdc : 1;
uint8_t led : 1;
uint8_t resv_4 : 1;
uint8_t usb1 : 1;
uint8_t sata : 1;
uint8_t ecdc : 1;
#else
uint8_t emmc : 1;
uint8_t hspi : 1;
uint8_t usbhs : 1;
uint8_t usbss : 1;
uint8_t serd : 1;
uint8_t dvp : 1;
#endif
};
};
#define RB_SLP_CLK_SPI0 0x01
#define RB_SLP_CLK_SPI1 0x02
#if defined(SOC_WCH_CH567)
#define RB_SLP_CLK_SDC 0x04
#define RB_SLP_CLK_LED 0x08
#define RB_SLP_CLK_USB0 0x10
#define RB_SLP_CLK_USB1 0x20
#define RB_SLP_CLK_ECDC 0x80
#elif defined(SOC_WCH_CH568)
#define RB_SLP_CLK_SDC 0x04
#define RB_SLP_CLK_LED 0x08
#define RB_SLP_CLK_USB1 0x20
#define RB_SLP_CLK_SATA 0x40
#define RB_SLP_CLK_ECDC 0x80
#else
#define RB_SLP_CLK_EMMC 0x04
#define RB_SLP_CLK_HSPI 0x08
#define RB_SLP_CLK_USBHS 0x10
#define RB_SLP_CLK_USBSS 0x20
#define RB_SLP_CLK_SERD 0x40
#define RB_SLP_CLK_DVP 0x80
#endif
/* All writable bits are RWA (need safe_access_sig)
*/
union _sys_slp_wake_ctrl
{
uint8_t reg;
struct
{
#if defined(SOC_WCH_CH567)
uint8_t usb0_wake : 1;
uint8_t usb1_wake : 1;
uint8_t resv_2 : 2;
uint8_t gpio_wake : 1;
uint8_t resv_5 : 3;
#elif defined(SOC_WCH_CH568)
uint8_t resv_0 : 1;
uint8_t usb1_wake : 1;
uint8_t sata_wake : 1;
uint8_t resv_3 : 1;
uint8_t gpio_wake : 1;
uint8_t resv_5 : 3;
#else
uint8_t usbhs_wake : 1;
uint8_t usbss_wake : 1;
uint8_t clk_eth : 1;
uint8_t clk_ecdc : 1;
uint8_t gpio_wake : 1;
uint8_t eth_wake : 1;
uint8_t resv_6 : 2;
#endif
};
};
#if defined(SOC_WCH_CH567)
#define RB_SLP_USB0_WAKE 0x01
#define RB_SLP_USB1_WAKE 0x02
#define RB_SLP_GPIO_WAKE 0x10
#elif defined(SOC_WCH_CH568)
#define RB_SLP_USB1_WAKE 0x02
#define RB_SLP_SATA_WAKE 0x04
#define RB_SLP_GPIO_WAKE 0x10
#else
#define RB_SLP_USBHS_WAKE 0x01
#define RB_SLP_USBSS_WAKE 0x02
#define RB_SLP_CLK_ETH 0x04
#define RB_SLP_CLK_ECDC 0x08
#define RB_SLP_GPIO_WAKE 0x10
#define RB_SLP_ETH_WAKE 0x20
#endif
union _sys_slp_power_ctrl
{
uint8_t reg;
struct
{
uint8_t usbhs_pwrdn : 1; // RWA, USBHS power down (0:PWRUP)
uint8_t resv_2 : 7;
};
};
#define RB_SLP_USBHS_PWRDN 0x01
union _sys_serd_ana_cfg1
{
uint16_t reg;
struct
{
uint8_t serd_pll_cfg; // RWA, reset as 0x5a
uint8_t serd_30m_sel : 1; // RWA
uint8_t serd_dn_tst : 1; // RWA
uint8_t resv_10 : 6;
};
};
#define RB_SERD_PLL_CFG 0x0ff
#define RB_SERD_30M_SEL 0x100
#define RB_SERD_DN_TST 0x200
union _sys_serd_ana_cfg2
{
uint32_t reg;
struct
{
uint32_t serd_trx_cfg : 25; // RWA, reset as 423015h
uint32_t resv_25 : 7;
};
};
#define RB_SERD_TRX_CFG 0x1000000
/*
* 0x00 R8_SAFE_ACCESS_SIG: safe access signature register
* 0x01 R8_CHIP_ID: RF, chip ID register
* 0x02 R8_SAFE_ACCESS_ID: RF, read as 02h
* 0x03 R8_WDOG_COUNT RW, watchdog counter
* 0x04 R8_GLOB_ROM_CFG: ROM config register
* 0x05 R8_RST_BOOT_STAT: RO, boot state register
* 0x06 R8_RST_WDOG_CTRL: software reset & watchdog control register
* 0x07 R8_GLOB_RESET_KEEP: RW, only power-on-reset can clear this register
* 0x08 R8_CLK_PLL_DIV: RWA, PLL output divisor register
* 0x0a R8_CLK_CFG_CTRL: RWA, clock config register
* 0x0b R8_CLK_MOD_AUX: RWA, clock auxiliary register
* 0x0c R8_SLP_CLK_OFF0: RWA, sleep control register 0
* 0x0d R8_SLP_CLK_OFF1: RWA, sleep control register 1
* 0x0e R8_SLP_WAKE_CTRL: RWA, wakeup control register
* 0x0f R8_SLP_POWER_CTRL: RWA, low power management register
* 0x20 R16_SERD_ANA_CFG1: RWA, SerDes PHY analog param config register 1
* 0x24 R32_SERD_ANA_CFG2: RWA, SerDes PHY analog param config register 2
*
* CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test.
* Be careful for those with side effect for read.
*/
struct sys_registers
{
union _sys_safe_access_sig SAFE_ACCESS_SIG;
uint8_t CHIP_ID;
uint8_t SAFE_ACCESS_ID;
uint8_t WDOG_COUNT;
union _sys_glob_rom_cfg GLOB_ROM_CFG;
union _sys_rst_boot_stat RST_BOOT_STAT;
union _sys_rst_wdog_ctrl RST_WDOG_CTRL;
uint8_t GLOB_RESET_KEEP;
union _sys_clk_pll_div CLK_PLL_DIV;
uint8_t resv_9;
union _sys_clk_cfg_ctrl CLK_CFG_CTRL;
union _sys_clk_mod_aux CLK_MOD_AUX;
union _sys_slp_clk_off0 SLP_CLK_OFF0;
union _sys_slp_clk_off1 SLP_CLK_OFF1;
union _sys_slp_wake_ctrl SLP_WAKE_CTRL;
union _sys_slp_power_ctrl SLP_POWER_CTRL;
#if defined(SOC_SERIES_CH569)
uint32_t resv_10[4];
union _sys_serd_ana_cfg1 SERD_ANA_CFG1;
uint16_t resv_22;
union _sys_serd_ana_cfg2 SERD_ANA_CFG2;
#endif
} __packed;
CHECK_STRUCT_SIZE(struct sys_registers, 0x28);
uint32_t sys_hclk_calc(void);
uint32_t sys_hclk_get(void);
int sys_hclk_set(uint32_t freq);
int sys_clk_off_by_irqn(uint8_t irqn, int off);
void sys_slp_clk_off0(uint8_t bits, int off);
void sys_slp_clk_off1(uint8_t bits, int off);
#ifdef __cplusplus
}
#endif
#endif
|