diff --git a/Makefile b/Makefile index 6a4cec6..9e9fe03 100644 --- a/Makefile +++ b/Makefile @@ -16,8 +16,7 @@ RAM_START := 0x10002000 CFLAGS = -mcpu=$(MCU) -mthumb -mfloat-abi=hard -lm \ -Wall -Wextra -g3 \ -Os -ffunction-sections -fdata-sections \ - -nostartfiles -Wl,-T,$(LD_FILE) -u main -Wl,--gc-sections \ - -DLOAD_ADDRESS=$(LOAD_ADDRESS) + -nostartfiles -Wl,-T,$(LD_FILE) -u main -Wl,--gc-sections ASFLAGS = -mcpu=$(MCU) -mthumb -g diff --git a/include/rtl8710bx.h b/include/rtl8710bx.h index d1337c2..aad6923 100644 --- a/include/rtl8710bx.h +++ b/include/rtl8710bx.h @@ -100,9 +100,16 @@ typedef struct { __IO uint32_t CALI_DATA; /* Calibration data register */ } ADC_TypeDef; -/* AMEBAZ_BACKUP_REG */ +/* Main backup register structure */ typedef struct { - __IO uint32_t DWORD[4]; /* 0x138 */ + union { + struct { + __IO uint32_t SYSTEM_FLAGS : 8; /* System-defined flags */ + __IO uint32_t RTC_BACKUP : 8; /* RTC backup value */ + __IO uint32_t USER_DEFINED : 16; /* User-defined bits */ + } DWORD0; + __IO uint32_t DWORD[4]; /* 0x138 */ + }; } BACKUP_REG_TypeDef; /* GDMA channel */ @@ -538,27 +545,28 @@ typedef struct { uint32_t RESERVED0[1]; /* 0x0004 */ __IO uint32_t FUNC_EN; /* 0x0008 */ + uint32_t RESERVED1[1]; /* 0x000C */ __IO uint32_t CLK_CTRL0; /* 0x0010 */ __IO uint32_t CLK_CTRL1; /* 0x0014 */ - uint32_t RESERVED1[2]; /* 0x0018-0x001C */ + uint32_t RESERVED2[2]; /* 0x0018-0x001C */ /* EFUSE System Configuration Registers */ __IO uint32_t EFUSE_SYSCFG[8]; /* 0x0020-0x003C */ __IO uint32_t REGU_CTRL0; /* 0x0040 */ - uint32_t RESERVED2[1]; /* 0x0044 */ + uint32_t RESERVED3[1]; /* 0x0044 */ __IO uint32_t SWR_CTRL0; /* 0x0048 */ __IO uint32_t SWR_CTRL1; /* 0x004C */ - uint32_t RESERVED3[4]; /* 0x0050-0x005C */ + uint32_t RESERVED4[4]; /* 0x0050-0x005C */ /* Crystal Control Registers */ __IO uint32_t XTAL_CTRL0; /* 0x0060 */ __IO uint32_t XTAL_CTRL1; /* 0x0064 */ __IO uint32_t XTAL_CTRL2; /* 0x0068 */ - uint32_t RESERVED4[1]; /* 0x006C */ + uint32_t RESERVED5[1]; /* 0x006C */ /* System PLL Control Registers */ __IO uint32_t SYSPLL_CTRL0; /* 0x0070 */ @@ -566,24 +574,24 @@ typedef struct { __IO uint32_t SYSPLL_CTRL2; /* 0x0078 */ __IO uint32_t SYSPLL_CTRL3; /* 0x007C */ - uint32_t RESERVED5[4]; /* 0x0080-0x008C */ + uint32_t RESERVED6[4]; /* 0x0080-0x008C */ __IO uint32_t ANA_TIM_CTRL; /* 0x0090 */ __IO uint32_t DSLP_TIM_CTRL; /* 0x0094 */ __IO uint32_t DSLP_TIM_CAL_CTRL; /* 0x0098 */ - uint32_t RESERVED6[2]; /* 0x009C-0x00A0 */ + uint32_t RESERVED7[2]; /* 0x009C-0x00A0 */ __IO uint32_t DEBUG_CTRL; /* 0x00A0 */ __IO uint32_t PINMUX_CTRL; /* 0x00A4 */ __IO uint32_t GPIO_DSTBY_WAKE_CTRL0; /* 0x00A8 */ __IO uint32_t GPIO_DSTBY_WAKE_CTRL1; /* 0x00AC */ - uint32_t RESERVED7[3]; /* 0x00B0-0x00B8 */ + uint32_t RESERVED8[3]; /* 0x00B0-0x00B8 */ __IO uint32_t DEBUG_REG; /* 0x00BC */ - uint32_t RESERVED8[8]; /* 0x00C0-0x00DC */ + uint32_t RESERVED9[8]; /* 0x00C0-0x00DC */ __IO uint32_t EEPROM_CTRL0; /* 0x00E0 */ __IO uint32_t EEPROM_CTRL1; /* 0x00E4 */ @@ -601,18 +609,18 @@ typedef struct { __IO uint32_t SNF_WAKE_EVENT_STATUS; /* 0x0114 */ __IO uint32_t PWRMGT_CTRL; /* 0x0118 */ - uint32_t RESERVED9[1]; /* 0x011C */ + uint32_t RESERVED10[1]; /* 0x011C */ __IO uint32_t PWRMGT_OPTION; /* 0x0120 */ __IO uint32_t PWRMGT_OPTION_EXT; /* 0x0124 */ - uint32_t RESERVED10[2]; /* 0x0128-0x012C */ + uint32_t RESERVED11[2]; /* 0x0128-0x012C */ __IO uint32_t DSLP_WEVENT; /* 0x0130 */ __IO uint32_t PERI_MONITOR; /* 0x0134 */ __IO uint32_t NORESET_FF; /* 0x0138 */ - uint32_t RESERVED11[45]; /* 0x013C-0x01EC */ + uint32_t RESERVED12[45]; /* 0x013C-0x01EC */ __IO uint32_t SYSTEM_CFG0; /* 0x01F0 */ __IO uint32_t SYSTEM_CFG1; /* 0x01F4 */ @@ -679,7 +687,7 @@ typedef struct { __IO uint32_t TX_STUCK_TIMER; /* TX stuck timer */ __IO uint32_t RX_STUCK_TIMER; /* RX stuck timer */ __IO uint32_t QOS_CTRL; /* QoS control */ -} USOC_REG_TypeDef; +} USOC_TypeDef; /* 0x0000h ~ 0x00FFh System Configuration */ typedef struct { @@ -1163,6 +1171,12 @@ typedef struct { #define SYSTEM_CTRL ((SYSTEM_CTRL_TypeDef *)SYSTEM_CTRL_BASE) #define PERI_ON ((PERI_ON_TypeDef *)PERI_ON_BASE) +#define PINMUX ((PINMUX_TypeDef *)PINMUX_REG_BASE) + +#define GPIO ((GPIO_TypeDef *)(GPIO_REG_BASE)) +#define GPIOA ((GPIO_Port_TypeDef *)(GPIO_REG_BASE + 0x00)) +#define GPIOB ((GPIO_Port_TypeDef *)(GPIO_REG_BASE + 0x0C)) +#define GPIOC ((GPIO_Port_TypeDef *)(GPIO_REG_BASE + 0x18)) #define UART0 ((UART_TypeDef *)UART0_REG_BASE) #define UART1 ((UART_TypeDef *)UART1_REG_BASE) @@ -1183,20 +1197,218 @@ typedef struct { #define TIM4 ((RTIM_TypeDef *)TIM4_BASE) #define TIM5 ((RTIM_TypeDef *)TIM5_BASE) #define RTC ((RTC_TypeDef *)RTC_BASE) -#define PINMUX ((PINMUX_TypeDef *)PINMUX_REG_BASE) #define IPSEC ((IPSEC_TypeDef *)CRYPTO_REG_BASE) -#define USOC_REG ((USOC_REG_TypeDef *)USOC_REG_BASE) +#define WIFI ((WiFi_TypeDef *)WIFI_REG_BASE) +#define USOC ((USOC_TypeDef *)USOC_REG_BASE) #define NCO32k ((NCO32k_TypeDef *)NCO1_REG_BASE) #define NCO8M ((NCO8M_TypeDef *)NCO2_REG_BASE) #define BACKUP_REG ((BACKUP_REG_TypeDef *)BACKUP_REG_BASE) #define SPIC_CACHE ((SPIC_CACHE_TypeDef *)SPIC_CACHE_BASE) -#define WIFI ((WiFi_TypeDef *)WIFI_REG_BASE) -#define GPIOA ((GPIO_Port_TypeDef *)(GPIO_REG_BASE + 0x00)) -#define GPIOB ((GPIO_Port_TypeDef *)(GPIO_REG_BASE + 0x0C)) -#define GPIOC ((GPIO_Port_TypeDef *)(GPIO_REG_BASE + 0x18)) +/* rtl8710b_backup_reg.h */ +#define BKUP_BOR_DETECTION_EN (1 << 7) /* Enable BOR2 detection */ +#define BKUP_BOR2_TEMP (1 << 6) /* BOR2 HW temp bit */ +#define BKUP_SYS_RESET_FLAG (1 << 5) /* System reset indicator */ +#define BKUP_UART_DEBUG_FLAG (1 << 4) /* UART download debug flag */ +#define BKUP_UART_BOOT_FLAG (1 << 3) /* UART download flag */ +#define BKUP_RTC_RESTORE_FLAG (1 << 2) /* RTC init flag */ +#define BKUP_BOR2_RESET_FLAG (1 << 1) /* BOR2 reset indicator */ +#define BKUP_CPU_RESET_FLAG (1 << 0) /* CPU/Watchdog reset indicator */ -#define GPIO_COMMON ((GPIO_Common_TypeDef *)(GPIO_REG_BASE + 0x30)) +#define BKUP_RTC_BACKUP_MASK (0xFF << 8) /* RTC backup mask */ +#define BKUP_SYSTEM_RESERVED_MASK (0xFF) /* System reserved bits mask */ + +#define BKUP_GET_RTC_BACKUP(reg) (((reg)->DWORD[0] & BKUP_RTC_BACKUP_MASK) >> 8) +#define BKUP_SET_RTC_BACKUP(reg, val) \ + ((reg)->DWORD[0] = ((reg)->DWORD[0] & ~BKUP_RTC_BACKUP_MASK) | \ + (((uint32_t)(val) << 8) & BKUP_RTC_BACKUP_MASK)) + +/* rtl8710b_clk.h */ +/* Clock source position and mask */ +#define CPU_CLK_POS 4 + +/* Clock sources - values pre-shifted to position */ +#define CPU_CLK_125M (0 << CPU_CLK_POS) +#define CPU_CLK_62_5M (1 << CPU_CLK_POS) +#define CPU_CLK_31_25M (2 << CPU_CLK_POS) +#define CPU_CLK_16_625M (3 << CPU_CLK_POS) +#define CPU_CLK_XTAL (4 << CPU_CLK_POS) +#define CPU_CLK_ANA_4M (5 << CPU_CLK_POS) + +/* Clock control macro */ +#define SET_CPU_CLOCK(source) \ + (SYSTEM_CTRL->CLK_CTRL1 = (SYSTEM_CTRL->CLK_CTRL1 & ~CPU_CLK_MASK) | (source)) + +/* NCO32k (NCO1) CLK_INFO Register Bits */ +#define NCO1_CLK_INFO_FREQ_MASK 0x00FFFFFF /* Unregulated clock freq */ +#define NCO1_CLK_INFO_32K_RDY (1 << 24) /* 32K clock output rdy */ +#define NCO1_CLK_INFO_CAL_RDY (1 << 25) /* 32K calibration rdy */ + +/* NCO32k (NCO1) CTRL Register Bits */ +#define NCO1_REF_FREQ_MASK 0x000003FF /* Reference clock freq mask */ +#define NCO1_32K_EN (1 << 16) /* 32K clock output enable */ +#define NCO1_REF_EN (1 << 17) /* Reference clock enable */ +#define NCO1_CAL_CYCLES (0xF << 20) /* num of cycles used during cali */ +#define NCO1_THRESH_MASK (0x7F << 24) /* 32K threshold */ + +/* NCO2 Control Register Bits */ +#define NCO2_OUT_EN (1 << 0) /* Enable NCO2 clock output */ + +/* System Clock Control Registers (SYS_CLK_CTRL0) */ +#define SYS_CLK_IOBUS_EN (1 << 2) /* Enable IO bus clock */ +#define SYS_CLK_EELDR_EN (1 << 1) /* Enable EELDR clock */ +#define SYS_CLK_SYSREG_EN (1 << 0) /* Enable system register clock */ + +/* SYS_CLK_CTRL1 */ +#define SYS_CLK_EXT32K_SEL (1 << 8) /* Select external 32KHz clock */ +#define SYS_CLK_CPU_CLK_SEL (7 << CPU_CLK_POS) /* CPU clock selection mask */ +#define SYS_CLK_EELDR_SEL (1 << 0) /* EELDR clock selection */ + +/* Crystal Control Register 0 (XTAL_CTRL0) */ +#define XTAL_EN (1 << 1) /* Crystal oscillator enable */ +#define XTAL_BGMB_EN (1 << 0) /* Bandgap bias enable */ +/* 1: Gate PLL reference clock from XTAL; 0: not gated */ +#define XTAL_GSPL_EN (1 << 4) +#define XTAL_GMP_MASK (0x1F << 8) /* Crystal GM-P control */ +#define XTAL_GMN_MASK (0x1F << 13) /* Crystal GM-N control */ +#define XTAL_SC_XI_MASK (0x3F << 18) /* Crystal input scaling */ +#define XTAL_SC_XO_MASK (0x3F << 24) /* Crystal output scaling */ +#define XTAL_GATED_OK (1 << 30) /* Crystal gating status */ +#define XTAL_XQSEL_RF (1 << 31) /* RF crystal quality selection */ + +/* Crystal Control Register 1 (XTAL_CTRL1) */ +#define XTAL_DELAY_SYSPLL (1 << 25) /* System PLL delay enable */ +#define XTAL_DELAY_USB (1 << 24) /* USB delay enable */ +#define XTAL_DELAY_WLAFE (1 << 23) /* WLAN AFE delay enable */ +/* Automatic amplitude control GM enable */ +#define XTAL_AAC_GM_EN (1 << 21) +#define XTAL_AAC_PEAKDET_EN (1 << 20) /* Peak detector enable */ +#define XTAL_AGPIO_MASK (1 << 17) /* GPIO control mask */ +/* System PLL driver strength */ +#define XTAL_DRV_SYSPLL_MASK (0x3 << 15) +#define XTAL_GATE_SYSPLL (1 << 14) /* System PLL clock gating */ +#define XTAL_DRV_USB_MASK (0x3 << 12) /* USB driver strength */ +#define XTAL_GATE_USB (1 << 11) /* USB clock gating */ +#define XTAL_DRV_WLAFE_MASK (0x3 << 9) /* WLAN AFE driver strength */ +#define XTAL_GATE_WLAFE (1 << 8) /* WLAN AFE clock gating */ +#define XTAL_DRV_RF2_MASK (0x3 << 6) /* RF2 driver strength */ +#define XTAL_GATE_RF2 (1 << 5) /* RF2 clock gating */ +#define XTAL_DRV_RF1_MASK (0x3 << 3) /* RF1 driver strength */ +#define XTAL_GATE_RF1 (1 << 2) /* RF1 clock gating */ +#define XTAL_LDO_MASK (0x3 << 0) /* LDO control mask */ + +/* System PLL Control Register 0 (SYSPLL_CTRL0) */ +#define SYSPLL_CKTST_EN (1 << 22) /* Clock test enable */ +#define SYSPLL_MONCK_SEL_MASK (0x7 << 19) /* Monitor clock selection */ +#define SYSPLL_CP_IOFFSET_MASK (0x1F << 14) /* Charge pump current offset */ +#define SYSPLL_FREF_EDGE (1 << 9) /* Reference clock edge selection */ +#define SYSPLL_EN (1 << 1) /* PLL enable */ +#define SYSPLL_LVPC_EN (1 << 0) /* Low voltage PLL core enable */ + +/* System PLL Control Register 1 (SYSPLL_CTRL1) */ +/* Clock selection: 1=200MHz, 0=166.666MHz */ +#define SYSPLL_CL200M_SEL (1 << 17) +#define SYSPLL_CK500K_SEL (1 << 15) /* Clock source: 1=external, 0=PLL */ +#define SYSPLL_CK200M_EN (1 << 14) /* 200MHz clock enable */ +#define SYSPLL_CKSDR_EN (1 << 13) /* SDRAM clock enable */ +/* SDRAM clock divider: 00=off, 01=25MHz, 10=50MHz, 11=100MHz */ +#define SYSPLL_CKSDR_DIV_MASK (0x3 << 11) +#define SYSPLL_CK24P576_EN (1 << 10) /* 24.576MHz clock enable */ +#define SYSPLL_CK22P5792_EN (1 << 9) /* 22.5792MHz clock enable */ +#define SYSPLL_CK83P33M_EN (1 << 8) /* 83.33MHz clock enable */ +#define SYSPLL_PS_EN (1 << 7) /* Phase shift enable */ +/** + * Clock phase selection when reg_ps_enb: + * 000/001.../111 corresponds to phases: 0°, 45°...315° + */ +#define SYSPLL_PS_SEL_MASK (0x7 << 4) + +/* System PLL Control Register 2 (SYSPLL_CTRL2) */ +#define SYSPLL_ADC_EN (1 << 25) /* ADC PLL enable */ + +/* System PLL Control Register 3 (SYSPLL_CTRL3) */ +/* 500MHz clock divider: period = (value + 2) cycles */ +#define SYSPLL_DIV_MASK (0x1FF << 6) +/* Phase selection for 500MHz clock: + * 0=0°, 1=45°, 2=90°, 3=135° + * 4=180°, 5=225°, 6=270°, 7=315° */ +#define SYSPLL_PHASE_MASK (0x7 << 3) +#define SYSPLL_500M_PS_EN (1 << 2) /* Enable 500MHz phase-shifted clock */ +#define SYSPLL_500M_EN (1 << 1) /* Enable 500MHz clock (HW auto-enabled) */ + +/* 32KHz Oscillator Control Register (OSC32K_CTRL) */ +#define OSC32K_CKGEN_EN (1 << 0) /* Enable 32KHz clock generator */ +/* Calibration mode select: + * 1=New (REGUOUT=OSCIN=8MHz) + * 0=Original (REGUOUT=OSCIN=32KHz) */ +#define OSC32K_CAL_MODE (1 << 1) +#define OSC32K_COMP_RES_MASK (0x3 << 2) /* Compensation resistor control */ +#define OSC32K_8M_EN (1 << 4) /* Enable 8MHz oscillator clock */ +#define OSC32K_FREF_EN (1 << 5) /* Enable 25MHz reference clock */ +#define OSC32K_BIAS_MASK (0xFFFF << 16) /* Bias current control */ + +/* 32KHz Oscillator Register Control 0 (OSC32K_REG_CTRL0) */ +#define OSC32K_CMD_WRITE (1 << 23) /* Command type: 1=Write, 0=Read */ +#define OSC32K_ADDR_MASK (0x3F << 16) /* Register address */ +#define OSC32K_WDATA_MASK (0xFFFF << 0) /* Write data */ + +/* 32KHz Oscillator Register Control 1 (OSC32K_REG_CTRL1) */ +#define OSC32K_RDATA_MASK (0xFFFF << 0) /* Indirect read data */ + +/* rtl8711b_syscfg.h */ +/* SYSCFG Register Definitions */ + +/* EFUSE_SYSCFG0 Register */ +/* [29:24] EEROM SWR Parameter [5:0] */ +#define SYSCFG0_EEROM_SWR_PAR_MASK (0x3F << 24) +/* [23:20] EEROM LDO Parameter [7:4] */ +#define SYSCFG0_EEROM_LDO_PAR_MASK (0x0F << 20) +#define SYSCFG0_CHIPPDN_EN (1 << 17) /* Reset pin power down control */ +#define SYSCFG0_EEROM_B12V_EN (1 << 16) /* EEROM B12V enable */ +#define SYSCFG0_EEROM_VID1_MASK (0xFF << 8) /* [15:8] EEROM VID1 */ +#define SYSCFG0_EEROM_VID0_MASK 0xFF /* [7:0] EEROM VID0 */ + +/* EFUSE_SYSCFG1 Register */ +#define SYSCFG1_PDSPL_STL_MASK (0x03 << 24) /* [25:24] PDSPL STL */ +#define SYSCFG1_PDSOC_STL_MASK (0x03 << 22) /* [23:22] PDSOC STL */ +#define SYSCFG1_PDPON_STL_MASK (0x03 << 20) /* [21:20] PDPON STL */ +#define SYSCFG1_SWREG_XRT_MASK (0x03 << 18) /* [19:18] SWREG XRT */ +#define SYSCFG1_SWSLC_STL_MASK (0x03 << 16) /* [17:16] SWSLC STL */ +/* [15:14] SWR Parameter [46:45] */ +#define SYSCFG1_SWR_PAR_46_45_MASK (0x03 << 14) +/* [13:12] SWR Parameter [40:39] */ +#define SYSCFG1_SWR_PAR_40_39_MASK (0x03 << 12) +/* [11:4] SWR Parameter [33:26] */ +#define SYSCFG1_SWR_PAR_33_26_MASK (0xFF << 4) +/* [2:0] SWSLD Volume */ +#define SYSCFG1_SWSLD_VOL_MASK 0x07 + +/* EFUSE_SYSCFG2 Register */ +/* [30:21] ANAPAR SPLL [24:15] */ +#define SYSCFG2_ANAPAR_SPLL_24_15_MASK (0x3FF << 21) +/* [19:16] ANAPAR SPLL [5:2] */ +#define SYSCFG2_ANAPAR_SPLL_05_02_MASK (0x0F << 16) +/* [13:12] XTAL STEL Select */ +#define SYSCFG2_XTAL_STEL_SEL_MASK (0x03 << 12) +/* [11:8] XTAL Frequency Select */ +#define SYSCFG2_XTAL_FREQ_SEL_MASK (0x0F << 8) + +/* SYSTEM_CFG0 Register */ +#define SYSCFG0_RF_RL_ID_MASK 0x0F /* [3:0] RF Vendor ID */ +#define SYSCFG0_CUT_VER_MASK (0x0F << 4) /* [7:4] Cut Version */ +#define SYSCFG0_VENDOR_ID_MASK (0x0F << 8) /* [11:8] Vendor ID */ +#define SYSCFG0_CHIP_TYPE_MASK (1 << 16) /* Chip Type */ +#define SYSCFG0_BD_OPT_MASK (0x0F << 24) /* [27:24] Board Option */ +#define SYSCFG0_BD_PKG_SEL (1 << 31) /* Board Package Select */ + +/* SYSTEM_CFG1 Register */ +#define SYSCFG1_TRP_ICFG_MASK (0x0F << 28) /* [31:28] TRP ICFG */ +#define SYSCFG1_TRP_UART_IMAGE (1 << 27) /* TRP UART Image */ +#define SYSCFG1_TRP_SPSLDO_SEL (1 << 25) /* TRP SPSLDO Select */ +#define SYSCFG1_V15_VLD (1 << 16) /* V15 Valid */ +#define SYSCFG1_SYSPLL_CLK_RDY (1 << 9) /* System PLL Clock Ready */ +#define SYSCFG1_XCLK_VLD (1 << 8) /* XCLK Valid */ +#define SYSCFG1_ALDN_STS (1 << 0) /* ALDN Status */ /* rtl8711b_peri_on.h */ // 2 0x200 REG_PEON_PWR_CTRL diff --git a/linker.ld b/linker.ld index a2a1462..1f32680 100644 --- a/linker.ld +++ b/linker.ld @@ -24,10 +24,16 @@ SECTIONS . = ALIGN(4); . += 20; LONG(_init + 1) - LONG(0x88167923) /* ROM checks this @ 0x10002018 */ - . = ALIGN(8); + /* even though we can supposedly tell the ROM where to copy us to + * it will still check for this signature at 0x10002018... */ + LONG(0x88167923) + . = ALIGN(128); + _real_vector_table = .; *(.vectors) - *(.text* .rodata* .data*) + . = ALIGN(4); + *(.text*) + *(.rodata*) + *(.data*) } .bss : { diff --git a/src/main.c b/src/main.c index 00b9449..326ef24 100644 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,51 @@ typedef struct { int8_t rssi; } Network_Info_t; +__attribute__((interrupt)) void HardFault_Handler(void) { + __asm volatile( + "tst lr, #4\n" + "ite eq\n" + "mrseq r0, msp\n" + "mrsne r0, psp\n" + "mov r1, lr\n" + "ldr r2, [r0, #24]\n" + "ldr r3, =0xE000ED30\n" + "ldr r3, [r3]\n" + "bl fault_handler_c\n" + "bkpt #0\n"); +} + +void fault_handler_c(uint32_t *stack_frame, uint32_t lr, uint32_t pc, + uint32_t hfsr) { + volatile uint32_t r0 = stack_frame[0]; + volatile uint32_t r1 = stack_frame[1]; + volatile uint32_t r2 = stack_frame[2]; + volatile uint32_t r3 = stack_frame[3]; + volatile uint32_t r12 = stack_frame[4]; + volatile uint32_t lr_ret = stack_frame[5]; + volatile uint32_t pc_ret = stack_frame[6]; + volatile uint32_t psr = stack_frame[7]; + + printf("\n=== HARD FAULT ===\n"); + printf("HFSR: 0x%08lx\n", hfsr); + printf("Fault PC: 0x%08lx\n", pc); + printf("LR: 0x%08lx\n", lr); + printf("R0: 0x%08lx\n", r0); + printf("R1: 0x%08lx\n", r1); + printf("R2: 0x%08lx\n", r2); + printf("R3: 0x%08lx\n", r3); + printf("R12: 0x%08lx\n", r12); + printf("LR (ret): 0x%08lx\n", lr_ret); + printf("PC (ret): 0x%08lx\n", pc_ret); + printf("PSR: 0x%08lx\n", psr); + + volatile uint32_t cfsr = *((volatile uint32_t *)0xE000ED28); + printf("CFSR: 0x%08lx\n", cfsr); + + while (1) { + } +} + static void wifi_init(void) { PERI_ON->PESOC_CLK_CTRL |= BIT_SOC_ACTCK_BTCMD_EN | BIT_SOC_ACTCK_VENDOR_REG_EN; @@ -65,40 +110,6 @@ void print_wifi_version(void) { #define CLK_TABLE_ROM 0x00046E68 #define XTAL_TABLE_ROM 0x000046E10 -/* REG_SYS_CLK_CTRL1 */ -#define BIT_PESOC_EXT32K_CK_SEL (0x00000001 << 8) -#define BIT_PESOC_OCP_CPU_CK_SEL (0x00000007 << 4) -#define BIT_PESOC_EELDR_CK_SEL (0x00000001 << 0) - -/* REG_SYS_SYSPLL_CTRL1 */ -/* 1:200MHz, 0:166.666MHz */ -#define BIT_SYS_SYSPLL_CL200M_SEL (0x00000001 << 17) -/* 1:external source 0:PLL */ -#define BIT_SYS_SYSPLL_CK500K_SEL (0x00000001 << 15) -/* enable CK200M */ -#define BIT_SYS_SYSPLL_CK200M_EN (0x00000001 << 14) -/* 1: enable CK_SDRAM */ -#define BIT_SYS_SYSPLL_CKSDR_EN (0x00000001 << 13) -/* SDR PLL select: 00/01/10/11 no clock/25M/50M/100M */ -#define BIT_SYS_SYSPLL_CKSDR_DIV (0x00000003 << 11) -/* 1:enable CK24.576M PLL */ -#define BIT_SYS_SYSPLL_CK24P576_EN (0x00000001 << 10) -/* 1: enable CK22.5792M PLL */ -#define BIT_SYS_SYSPLL_CK22P5792_EN (0x00000001 << 9) -/* 1: enable CK83.33M PLL */ -#define BIT_SYS_SYSPLL_CK83P33M_EN (0x00000001 << 8) -/* reg_ps_en Enable phase shift */ -#define BIT_SYS_SYSPLL_CK_PS_EN (0x00000001 << 7) -/* Clock phase selection when reg_ps_enb: - 000/001.../111 corresponds to phases: 0°, 45°...315° */ -#define BIT_SYS_SYSPLL_CK_PS_SEL (0x00000007 << 4) - -/* REG_SYS_EFUSE_SYSCFG2 */ -#define BIT_MASK_SYS_EERROM_ANAPAR_SPLL_24_15 (0x000003ff << 21) -#define BIT_MASK_SYS_EEROM_ANAPAR_SPLL_05_02 (0x0000000f << 16) -#define BIT_MASK_SYS_EEROM_XTAL_STEL_SEL (0x00000003 << 12) -#define BIT_MASK_SYS_EEROM_XTAL_FREQ_SEL (0x0000000f << 8) - void dump_hex(const void *data, size_t size, const char *prefix) { const uint8_t *bytes = (const uint8_t *)data; for (size_t i = 0; i < size; i++) { @@ -108,59 +119,72 @@ void dump_hex(const void *data, size_t size, const char *prefix) { printf("\n"); } -void analyze_clock_config(void) { +void print_clock_config(void) { printf("\n=== CLOCK CONFIGURATION ===\n"); // all releveant regs printf("\nRegister Values (Raw):\n"); printf("CLK_CTRL1: 0x%08X\n", SYSTEM_CTRL->CLK_CTRL1); + printf("SYSPLL_CTRL0: 0x%08X\n", SYSTEM_CTRL->SYSPLL_CTRL0); printf("SYSPLL_CTRL1: 0x%08X\n", SYSTEM_CTRL->SYSPLL_CTRL1); + printf("SYSPLL_CTRL2: 0x%08X\n", SYSTEM_CTRL->SYSPLL_CTRL2); + printf("SYSPLL_CTRL3: 0x%08X\n", SYSTEM_CTRL->SYSPLL_CTRL3); + printf("XTAL_CTRL0: 0x%08X\n", SYSTEM_CTRL->XTAL_CTRL0); + printf("XTAL_CTRL1: 0x%08X\n", SYSTEM_CTRL->XTAL_CTRL1); printf("EFUSE_SYSCFG2: 0x%08X\n", SYSTEM_CTRL->EFUSE_SYSCFG[2]); // CLK_CTRL1 uint32_t clk_ctrl1 = SYSTEM_CTRL->CLK_CTRL1; printf("\nCLK_CTRL1:\n"); - printf(" EXT32K_CK_SEL: %d\n", - (clk_ctrl1 & BIT_PESOC_EXT32K_CK_SEL) ? 1 : 0); - printf(" OCP_CPU_CK_SEL: %d\n", - (clk_ctrl1 & BIT_PESOC_OCP_CPU_CK_SEL) >> 4); - printf(" EELDR_CK_SEL: %d\n", - (clk_ctrl1 & BIT_PESOC_EELDR_CK_SEL) ? 1 : 0); + printf(" EXT32K_CK_SEL: %d\n", (clk_ctrl1 & SYS_CLK_EXT32K_SEL) ? 1 : 0); + printf(" OCP_CPU_CK_SEL: %d\n", (clk_ctrl1 & SYS_CLK_CPU_CLK_SEL) >> 4); + printf(" EELDR_CK_SEL: %d\n", (clk_ctrl1 & SYS_CLK_EELDR_SEL) ? 1 : 0); + + uint32_t syspll_ctrl0 = SYSTEM_CTRL->SYSPLL_CTRL0; + printf("\nSYSPLL_CTRL0:\n"); + printf(" CKTST_EN: %d\n", (syspll_ctrl0 & SYSPLL_CKTST_EN) ? 1 : 0); + printf(" MONCK_SEL: %d\n", + (syspll_ctrl0 & SYSPLL_MONCK_SEL_MASK) >> 19); + printf(" CP_IOFFSET: %d\n", + (syspll_ctrl0 & SYSPLL_CP_IOFFSET_MASK) >> 14); + printf(" FREF_EDGE: %d\n", (syspll_ctrl0 & SYSPLL_FREF_EDGE) ? 1 : 0); + printf(" PLL_EN: %d\n", (syspll_ctrl0 & SYSPLL_EN) ? 1 : 0); + printf(" LVPC_EN: %d\n", (syspll_ctrl0 & SYSPLL_LVPC_EN) ? 1 : 0); // SYSPLL_CTRL1 uint32_t syspll_ctrl1 = SYSTEM_CTRL->SYSPLL_CTRL1; printf("\nSYSPLL_CTRL1:\n"); printf(" CL200M_SEL: %d\n", - (syspll_ctrl1 & BIT_SYS_SYSPLL_CL200M_SEL) ? 1 : 0); + (syspll_ctrl1 & SYSPLL_CL200M_SEL) ? 1 : 0); printf(" CK500K_SEL: %d\n", - (syspll_ctrl1 & BIT_SYS_SYSPLL_CK500K_SEL) ? 1 : 0); - printf(" CK200M_EN: %d\n", - (syspll_ctrl1 & BIT_SYS_SYSPLL_CK200M_EN) ? 1 : 0); - printf(" CKSDR_EN: %d\n", - (syspll_ctrl1 & BIT_SYS_SYSPLL_CKSDR_EN) ? 1 : 0); + (syspll_ctrl1 & SYSPLL_CK500K_SEL) ? 1 : 0); + printf(" CK200M_EN: %d\n", (syspll_ctrl1 & SYSPLL_CK200M_EN) ? 1 : 0); + printf(" CKSDR_EN: %d\n", (syspll_ctrl1 & SYSPLL_CKSDR_EN) ? 1 : 0); printf(" CKSDR_DIV: %d\n", - (syspll_ctrl1 & BIT_SYS_SYSPLL_CKSDR_DIV) >> 11); + (syspll_ctrl1 & SYSPLL_CKSDR_DIV_MASK) >> 11); printf(" CK24P576_EN: %d\n", - (syspll_ctrl1 & BIT_SYS_SYSPLL_CK24P576_EN) ? 1 : 0); + (syspll_ctrl1 & SYSPLL_CK24P576_EN) ? 1 : 0); printf(" CK22P5792_EN: %d\n", - (syspll_ctrl1 & BIT_SYS_SYSPLL_CK22P5792_EN) ? 1 : 0); + (syspll_ctrl1 & SYSPLL_CK22P5792_EN) ? 1 : 0); printf(" CK83P33M_EN: %d\n", - (syspll_ctrl1 & BIT_SYS_SYSPLL_CK83P33M_EN) ? 1 : 0); - printf(" CK_PS_EN: %d\n", - (syspll_ctrl1 & BIT_SYS_SYSPLL_CK_PS_EN) ? 1 : 0); - printf(" CK_PS_SEL: %d\n", - (syspll_ctrl1 & BIT_SYS_SYSPLL_CK_PS_SEL) >> 4); + (syspll_ctrl1 & SYSPLL_CK83P33M_EN) ? 1 : 0); + printf(" CK_PS_EN: %d\n", (syspll_ctrl1 & SYSPLL_PS_EN) ? 1 : 0); + printf(" CK_PS_SEL: %d\n", (syspll_ctrl1 & SYSPLL_PS_SEL_MASK) >> 4); + + uint32_t syspll_ctrl3 = SYSTEM_CTRL->SYSPLL_CTRL3; + printf("\nSYSPLL_CTRL3:\n"); + printf(" DIV_500M: %d\n", (syspll_ctrl3 & SYSPLL_DIV_MASK) >> 6); + printf(" PHASE_SEL: %d\n", (syspll_ctrl3 & SYSPLL_PHASE_MASK) >> 3); + printf(" 500M_PS_EN: %d\n", + (syspll_ctrl3 & SYSPLL_500M_PS_EN) ? 1 : 0); + printf(" 500M_EN: %d\n", (syspll_ctrl3 & SYSPLL_500M_EN) ? 1 : 0); // EFUSE_SYSCFG2 uint32_t efuse_syscfg2 = SYSTEM_CTRL->EFUSE_SYSCFG[2]; - uint32_t spll_24_15 = - (efuse_syscfg2 & BIT_MASK_SYS_EERROM_ANAPAR_SPLL_24_15) >> 21; - uint32_t spll_05_02 = - (efuse_syscfg2 & BIT_MASK_SYS_EEROM_ANAPAR_SPLL_05_02) >> 16; - uint32_t xtal_stel_sel = - (efuse_syscfg2 & BIT_MASK_SYS_EEROM_XTAL_STEL_SEL) >> 12; - uint32_t xtal_freq_sel = - (efuse_syscfg2 & BIT_MASK_SYS_EEROM_XTAL_FREQ_SEL) >> 8; + uint32_t spll_24_15 = (efuse_syscfg2 & SYSCFG2_ANAPAR_SPLL_24_15_MASK) >> 21; + uint32_t spll_05_02 = (efuse_syscfg2 & SYSCFG2_ANAPAR_SPLL_05_02_MASK) >> 16; + uint32_t xtal_stel_sel = (efuse_syscfg2 & SYSCFG2_XTAL_STEL_SEL_MASK) >> 12; + uint32_t xtal_freq_sel = (efuse_syscfg2 & SYSCFG2_XTAL_FREQ_SEL_MASK) >> 8; printf("\nEFUSE_SYSCFG2:\n"); printf(" SPLL 24:15 Config: 0x%03X\n", spll_24_15); @@ -168,6 +192,23 @@ void analyze_clock_config(void) { printf(" XTAL_STEL_SEL: 0x%X\n", xtal_stel_sel); printf(" XTAL_FREQ_SEL: 0x%X\n", xtal_freq_sel); + printf("\nEFUSE_SYSCFG Array Dump:\n"); + for (int i = 0; i < 32; i++) { + uint32_t val = SYSTEM_CTRL->EFUSE_SYSCFG[i]; + if (val != 0) { + printf("EFUSE_SYSCFG[%2d]: 0x%08X\n", i, val); + } + } + + printf("\nSurrounding Registers:\n"); + volatile uint32_t *base = (volatile uint32_t *)&SYSTEM_CTRL->EFUSE_SYSCFG[0]; + for (int i = -16; i < 48; i++) { + uint32_t val = base[i]; + if (val != 0) { + printf("Offset %3d: 0x%08X\n", i * 4, val); + } + } + // rom XTAL table printf("\nXTAL Table Contents (first 16 entries):\n"); const uint32_t *xtal_table = (const uint32_t *)XTAL_TABLE_ROM; @@ -181,31 +222,55 @@ void analyze_clock_config(void) { printf(" Index: %d\n", xtal_freq_sel); printf(" Frequency: %d Hz (0x%08X)\n", xtal_freq, xtal_freq); + uint32_t xtal_ctrl0 = SYSTEM_CTRL->XTAL_CTRL0; + printf("\nXTAL_CTRL0:\n"); + printf(" XTAL_EN: %d\n", (xtal_ctrl0 & XTAL_EN) ? 1 : 0); + printf(" BGMB_EN: %d\n", (xtal_ctrl0 & XTAL_BGMB_EN) ? 1 : 0); + printf(" GSPL_EN: %d\n", (xtal_ctrl0 & XTAL_GSPL_EN) ? 1 : 0); + printf(" GMP: 0x%02X\n", (xtal_ctrl0 & XTAL_GMP_MASK) >> 8); + printf(" GMN: 0x%02X\n", (xtal_ctrl0 & XTAL_GMN_MASK) >> 13); + printf(" SC_XI: 0x%02X\n", (xtal_ctrl0 & XTAL_SC_XI_MASK) >> 18); + printf(" SC_XO: 0x%02X\n", (xtal_ctrl0 & XTAL_SC_XO_MASK) >> 24); + printf(" GATED_OK: %d\n", (xtal_ctrl0 & XTAL_GATED_OK) ? 1 : 0); + printf(" XQSEL_RF: %d\n", (xtal_ctrl0 & XTAL_XQSEL_RF) ? 1 : 0); + + uint32_t xtal_ctrl1 = SYSTEM_CTRL->XTAL_CTRL1; + printf("\nXTAL_CTRL1:\n"); + printf(" DELAY_SYSPLL: %d\n", (xtal_ctrl1 & XTAL_DELAY_SYSPLL) ? 1 : 0); + printf(" DELAY_USB: %d\n", (xtal_ctrl1 & XTAL_DELAY_USB) ? 1 : 0); + printf(" DELAY_WLAFE: %d\n", (xtal_ctrl1 & XTAL_DELAY_WLAFE) ? 1 : 0); + printf(" AAC_GM_EN: %d\n", (xtal_ctrl1 & XTAL_AAC_GM_EN) ? 1 : 0); + printf(" AAC_PEAKDET_EN: %d\n", + (xtal_ctrl1 & XTAL_AAC_PEAKDET_EN) ? 1 : 0); + printf(" DRV_SYSPLL: %d\n", (xtal_ctrl1 & XTAL_DRV_SYSPLL_MASK) >> 15); + printf(" GATE_SYSPLL: %d\n", (xtal_ctrl1 & XTAL_GATE_SYSPLL) ? 1 : 0); + printf(" LDO: %d\n", (xtal_ctrl1 & XTAL_LDO_MASK)); + // dump clock table - printf("\nClock Table Contents (first 16 entries):\n"); - const uint8_t *clk_table = (uint8_t *)CLK_TABLE_ROM; - for (int i = 0; i < 16; i++) { - printf(" [%2d]: %d MHz (0x%x)\n", i, clk_table[i], clk_table[i]); + const uint32_t *clk_table = (uint32_t *)CLK_TABLE_ROM; + printf("\nFull table contents:\n"); + for (int i = 0; i < 6; i++) { + printf(" [%d]: %d Hz (%d MHz)\n", i, clk_table[i], clk_table[i] / 1000000); } // PLL freq uint32_t pll_base_freq = - (syspll_ctrl1 & BIT_SYS_SYSPLL_CL200M_SEL) ? 200000000 : 166666666; + (syspll_ctrl1 & SYSPLL_CL200M_SEL) ? 200000000 : 166666666; printf("\nPLL Frequencies:\n"); printf(" Base: %d Hz (0x%x)\n", pll_base_freq, pll_base_freq); - printf( - " SDR Clock: %d Hz (if enabled)\n", - pll_base_freq >> (2 - ((syspll_ctrl1 & BIT_SYS_SYSPLL_CKSDR_DIV) >> 11))); + printf(" SDR Clock: %d Hz (if enabled)\n", + pll_base_freq >> (2 - ((syspll_ctrl1 & SYSPLL_CKSDR_DIV_MASK) >> 11))); printf(" 83.33M: %d Hz (if enabled)\n", 83330000); printf(" 24.576M: %d Hz (if enabled)\n", 24576000); printf(" 22.5792M: %d Hz (if enabled)\n", 22579200); // some rom table - uint32_t cpu_clock_sel = (clk_ctrl1 & BIT_PESOC_OCP_CPU_CK_SEL) >> 4; + uint32_t cpu_clock_sel = (clk_ctrl1 & SYS_CLK_CPU_CLK_SEL) >> 4; uint32_t cpu_freq = clk_table[cpu_clock_sel]; printf("\nCPU Configuration:\n"); printf(" Clock Selection Index: %d\n", cpu_clock_sel); - printf(" Frequency: %d MHz (0x%x)\n", cpu_freq, cpu_freq); + printf(" Frequency: %d Hz (%d MHz) (0x%x)\n", cpu_freq, cpu_freq / 1000000, + cpu_freq); uint32_t xtal_to_pll = (pll_base_freq / (xtal_freq / 1000)); uint32_t pll_to_cpu = @@ -221,39 +286,87 @@ void analyze_clock_config(void) { xtal_to_cpu % 1000); } +extern uint32_t _vector_table; + +__attribute__((interrupt)) __attribute__((used)) void SysTick_Handler(void) { + GPIOA->DR ^= (1 << 23); +} + +// /* REG_SYS_CLK_CTRL1 */ +// #define BIT_PESOC_EXT32K_CK_SEL (0x00000001 << 8) +// #define BIT_PESOC_OCP_CPU_CK_SEL (0x00000007 << 4) +// #define BIT_PESOC_EELDR_CK_SEL (0x00000001 << 0) + +// unsigned int __fastcall CPU_ClkSet(int CpuType) +// { +// unsigned int result; // r0 + +// result = dword_40000014 & 0xFFFFFF8F | (16 * CpuType); +// dword_40000014 = result; +// return result; +// } + +uint32_t CPU_ClkGet(uint8_t Is_FPGA); +void CPU_ClkSet(uint8_t CpuType); + int main(void) { printf("[main]\n"); + printf("Vector table @ %p\n", &_vector_table); + printf("VTOR: 0x%08x\n", SCB->VTOR); + // printf("FUNC_EN ptr: 0x%08X\n", &SYSTEM_CTRL->FUNC_EN); + // printf("CLK_CTRL0 ptr: 0x%08X\n", &SYSTEM_CTRL->CLK_CTRL0); + // printf("CLK_CTRL1 ptr: 0x%08X\n", &SYSTEM_CTRL->CLK_CTRL1); + volatile uint32_t *raw_reg = (volatile uint32_t *)0x40000014; + printf("Raw register before: 0x%08x\n", *raw_reg); + printf("CLK_CTRL1 before: 0x%08x\n", SYSTEM_CTRL->CLK_CTRL1); - uint32_t primask = __get_PRIMASK(); __disable_irq(); - SYSTEM_CTRL->CLK_CTRL1 = (SYSTEM_CTRL->CLK_CTRL1 & ~0x70) | (2 << 4); + SYSTEM_CTRL->CLK_CTRL1 = + (SYSTEM_CTRL->CLK_CTRL1 & ~SYS_CLK_CPU_CLK_SEL) | CPU_CLK_125M; - if (!primask) { - __enable_irq(); - } + // ppll 200m + SYSTEM_CTRL->SYSPLL_CTRL1 |= SYSPLL_CK200M_EN; - analyze_clock_config(); + // Remove gating and increase drive strength + uint32_t new_ctrl1 = SYSTEM_CTRL->XTAL_CTRL1; + new_ctrl1 &= ~XTAL_GATE_SYSPLL; + new_ctrl1 |= (3 << 15); + SYSTEM_CTRL->XTAL_CTRL1 = new_ctrl1; - // __asm volatile("udf #0"); - // DelayMs(5000); - // NVIC_SystemReset(); + // cur value is 0x000000C2 (DIV_500M = 3) + // set DIV_500M to 0, (/ 2) + uint32_t new_ctrl3 = SYSTEM_CTRL->SYSPLL_CTRL3; + new_ctrl3 &= ~SYSPLL_DIV_MASK; + // keep the 500M_EN bit (0x02) that's already set + SYSTEM_CTRL->SYSPLL_CTRL3 = new_ctrl3; - // print_wifi_version(); - // wifi_init(); - // delay_ms(3000); + uint32_t new_ctrl0 = SYSTEM_CTRL->SYSPLL_CTRL0; + new_ctrl0 &= ~SYSPLL_CP_IOFFSET_MASK; + new_ctrl0 |= (0x10 << 14); + SYSTEM_CTRL->SYSPLL_CTRL0 = new_ctrl0; - // PERI_ON->SOC_PERI_FUNC1_EN |= BIT_PERI_GPIO_EN; - // PERI_ON->PESOC_CLK_CTRL |= APBPeriph_GPIO_CLOCK; + // CPU_ClkSet(CLK_62_5M); + + printf("Raw register after: 0x%08x\n", *raw_reg); + printf("CLK_CTRL1 after: 0x%08x\n", SYSTEM_CTRL->CLK_CTRL1); + + printf("CPU Clock: %d", CPU_ClkGet(0)); + + SysTick_Config(100); // tick every 100 cycles + __enable_irq(); + + print_clock_config(); + + PERI_ON->SOC_PERI_FUNC1_EN |= BIT_PERI_GPIO_EN; + PERI_ON->PESOC_CLK_CTRL |= APBPeriph_GPIO_CLOCK; // PINMUX_Config(_PA_0, PINMUX_FN_GPIO); + PINMUX_Config(_PA_23, PINMUX_FN_GPIO); // PINMUX_ConfigPadPull(_PA_0, GPIO_PuPd_DOWN); - // GPIOA->DDR |= (1 << 0); - // uint32_t c = 0; + PINMUX_ConfigPadPull(_PA_23, GPIO_PuPd_NOPULL); + // GPIOA->DDR |= (1 << 0) | (1 << 23); + GPIOA->DDR |= (1 << 23); while (1) { - // GPIOA->DR |= (1 << 0); - // delay_ms(1000); - // GPIOA->DR &= ~(1 << 0); - // delay_ms(1000); } } diff --git a/src/rtl8710bx.c b/src/rtl8710bx.c deleted file mode 100644 index e69de29..0000000