ch56x_sys.h 11.3 KB
Newer Older
1
/*
2
 * Copyright (c) 2006-2023, RT-Thread Development Team
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
 *
 * 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);

385
uint32_t sys_hclk_calc(void);
386 387 388 389 390 391 392 393 394 395 396
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