#ifndef RTL8710BX_H
#define RTL8710BX_H

typedef enum IRQn {
  Reset_IRQn = -15, /* Reset Vector, invoked on Power up and warm reset */
  NonMaskableInt_IRQn =
      -14, /* Non maskable Interrupt, cannot be stopped or preempted */
  HardFault_IRQn = -13,        /* Hard Fault, all classes of Fault */
  MemoryManagement_IRQn = -12, /* Memory Management, MPU mismatch, including
                                  Access Violation and No Match */
  BusFault_IRQn = -11,         /* Bus Fault, Pre-Fetch-, Memory Access, other
                                  address/memory Fault */
  UsageFault_IRQn =
      -10, /* Usage Fault, i.e. Undef Instruction, Illegal State Transition */
  SecureFault_IRQn = -9,  /* Secure Fault Interrupt */
  SVCall_IRQn = -5,       /* System Service Call via SVC instruction */
  DebugMonitor_IRQn = -4, /* Debug Monitor */
  PendSV_IRQn = -2,       /* Pendable request for system service */
  SysTick_IRQn = -1,      /* System Tick Timer */

  /* RTL8710BX specific interrupts */
  PWR_Wakeup_IRQn = 0,     /* System wakeup from power save interrupt */
  WDG_IRQn = 1,            /* Window watchdog interrupt */
  TIM0_IRQn = 2,           /* Timer 0 global interrupt */
  TIM1_IRQn = 3,           /* Timer 1 global interrupt */
  TIM2_IRQn = 4,           /* Timer 2 global interrupt */
  TIM3_IRQn = 5,           /* Timer 3 global interrupt */
  SPI0_IRQn = 6,           /* SPI0 global interrupt */
  GPIO_IRQn = 7,           /* GPIO global interrupt */
  UART0_IRQn = 8,          /* UART0 global interrupt */
  FLASH_IRQn = 9,          /* Flash memory global interrupt */
  UART1_IRQn = 10,         /* UART1 global interrupt */
  TIM4_IRQn = 11,          /* Timer 4 global interrupt */
  SDIO_IRQn = 12,          /* SDIO global interrupt */
  I2S0_PCM0_IRQn = 13,     /* I2S0/PCM0 global interrupt */
  TIM5_IRQn = 14,          /* Timer 5 global interrupt */
  WLAN_DMA_IRQn = 15,      /* WLAN DMA global interrupt */
  WLAN_Protocol_IRQn = 16, /* WLAN protocol global interrupt */
  Crypto_IRQn = 17,        /* Cryptography global interrupt */
  SPI1_IRQn = 18,          /* SPI1 global interrupt */
  Periph_IRQn = 19,        /* Peripheral global interrupt */
  DMA0_Channel0_IRQn = 20, /* DMA0 Channel 0 global interrupt */
  DMA0_Channel1_IRQn = 21, /* DMA0 Channel 1 global interrupt */
  DMA0_Channel2_IRQn = 22, /* DMA0 Channel 2 global interrupt */
  DMA0_Channel3_IRQn = 23, /* DMA0 Channel 3 global interrupt */
  DMA0_Channel4_IRQn = 24, /* DMA0 Channel 4 global interrupt */
  DMA0_Channel5_IRQn = 25, /* DMA0 Channel 5 global interrupt */
  I2C0_IRQn = 26,          /* I2C0 global interrupt */
  I2C1_IRQn = 27,          /* I2C1 global interrupt */
  UART_Log_IRQn = 28,      /* Log UART global interrupt */
  ADC_IRQn = 29,           /* ADC global interrupt */
  RDP_IRQn = 30,           /* CPU RDP protection interrupt */
  RTC_IRQn = 31,           /* RTC global interrupt */
  DMA1_Channel0_IRQn = 32, /* DMA1 Channel 0 global interrupt */
  DMA1_Channel1_IRQn = 33, /* DMA1 Channel 1 global interrupt */
  DMA1_Channel2_IRQn = 34, /* DMA1 Channel 2 global interrupt */
  DMA1_Channel3_IRQn = 35, /* DMA1 Channel 3 global interrupt */
  DMA1_Channel4_IRQn = 36, /* DMA1 Channel 4 global interrupt */
  DMA1_Channel5_IRQn = 37, /* DMA1 Channel 5 global interrupt */
  USB_IRQn = 38,           /* USB global interrupt */
  RXI300_IRQn = 39,        /* RXI300 global interrupt */
  USB_SIE_IRQn = 40,       /* USB SIE global interrupt */
} IRQn_Type;

#define __CM4_REV 0x0101          /* Core Revision r0p1 */
#define __Vendor_SysTickConfig 0U /* Standard ARM SysTick implementation */
#define __NVIC_PRIO_BITS 4U    /* Cortex-M4 uses 4 bits for priority levels */
#define __VTOR_PRESENT 1U      /* Vector Table Offset Register is present */
#define __MPU_PRESENT 1U       /* Memory Protection Unit is present */
#define __FPU_PRESENT 1U       /* Floating Point Unit is present on this M4 */
#define __FPU_DP 0U            /* Single-precision FPU */
#define __DSP_PRESENT 1U       /* DSP extensions are present on M4 */
#define __SAUREGION_PRESENT 0U /* No Security Attribution Unit */
#define __PMU_PRESENT 0U       /* No Performance Monitoring Unit */
#define __PMU_NUM_EVENTCNT 0U  /* Not applicable since no PMU */
#define __ICACHE_PRESENT 0U    /* No instruction cache */
#define __DCACHE_PRESENT 0U    /* No data cache */
#define __DTCM_PRESENT 0U      /* No DTCM */

#include "cmsis/core_cm4.h"

/* Device Specific Peripheral Section */

/* Analog to Digital Converter */
typedef struct {
  __IO uint32_t FIFO_READ;    /* FIFO read register for channels 0-3 */
  __IO uint32_t CONTROL;      /* Main ADC control register */
  __IO uint32_t INTR_EN;      /* Interrupt enable register */
  __IO uint32_t INTR_STS;     /* Interrupt status register */
  __IO uint32_t COMP_VALUE_L; /* Compare values for channels 0-1 */
  __IO uint32_t COMP_VALUE_H; /* Compare values for channels 2-3 */
  __IO uint32_t COMP_SET;     /* Compare configuration register */
  __IO uint32_t POWER;        /* Power management register */
  __IO uint32_t ANAPAR_AD0;   /* Analog parameters for channel 0 */
  __IO uint32_t ANAPAR_AD1;   /* Analog parameters for channel 1 */
  __IO uint32_t ANAPAR_AD2;   /* Analog parameters for channel 2 */
  __IO uint32_t ANAPAR_AD3;   /* Analog parameters for channel 3 */
  __IO uint32_t ANAPAR_AD4;   /* Analog parameters for channel 4 */
  __IO uint32_t ANAPAR_AD5;   /* Analog parameters for channel 5 */
  __IO uint32_t CALI_DATA;    /* Calibration data register */
} ADC_TypeDef;

/* AMEBAZ_BACKUP_REG */
typedef struct {
  __IO uint32_t DWORD[4]; /* 0x138 */
} BACKUP_REG_TypeDef;

/* GDMA channel */
typedef struct {
  __IO uint32_t SAR; /* Source Address, 0x000 */
  __O uint32_t RSAR; /* Source Address Read Back, 0x004 */
  __IO uint32_t DAR; /* Destination Address, 0x008 */
  __O uint32_t RDAR; /* Destination Address Read Back, 0x00C */
  __IO uint32_t LLP; /* Linked List Pointer, 0x010 */
  uint32_t RSVD2;
  __IO uint32_t CTL_LOW;  /* Control Low, 0x018 */
  __IO uint32_t CTL_HIGH; /* Control High, 0x01C */
  __IO uint32_t SSTAT;    /* Source Status, 0x020 */
  uint32_t RSVD4;
  __IO uint32_t DSTAT; /* Destination Status, 0x028 */
  uint32_t RSVD5;
  __IO uint32_t SSTATAR; /* Source Status Address, 0x030 */
  uint32_t RSVD6;
  __IO uint32_t DSTATAR; /* Destination Status Address, 0x038 */
  uint32_t RSVD7;
  __IO uint32_t CFG_LOW;  /* Config Low, 0x040 */
  __IO uint32_t CFG_HIGH; /* Config High, 0x044 */
  __IO uint32_t SGR;      /* Source Gather, 0x048 */
  uint32_t RSVD9;
  __IO uint32_t DSR; /* Destination Scatter, 0x050 */
  uint32_t RSVD10;   /* 0x054 */
} GDMA_ChannelTypeDef;

/* General Direct Memory Access (GDMA) */
typedef struct {
  GDMA_ChannelTypeDef CH[8]; /* 8 chs, we only have 5 though :) 0x000-0x2BC */
  __I uint32_t RAW_TFR;      /* Raw Transfer Status, 0x2C0 */
  uint32_t RSVD0;
  __I uint32_t RAW_BLOCK; /* Raw Block Status, 0x2C8 */
  uint32_t RSVD1;
  __I uint32_t RAW_SRC_TRAN; /* Raw Source Trans Status, 0x2D0 */
  uint32_t RSVD2;
  __I uint32_t RAW_DST_TRAN; /* Raw Dest Trans Status, 0x2D8 */
  uint32_t RSVD3;
  __I uint32_t RAW_ERR; /* Raw Error Status, 0x2E0 */
  uint32_t RSVD4;
  __I uint32_t STATUS_TFR; /* Transfer Status, 0x2E8 */
  uint32_t RSVD5;
  __I uint32_t STATUS_BLOCK; /* Block Status, 0x2F0 */
  uint32_t RSVD6;
  __I uint32_t STATUS_SRC_TRAN; /* Source Trans Status, 0x2F8 */
  uint32_t RSVD7;
  __I uint32_t STATUS_DST_TRAN; /* Dest Trans Status, 0x300 */
  uint32_t RSVD8;
  __I uint32_t STATUS_ERR; /* Error Status, 0x308 */
  uint32_t RSVD9;
  __IO uint32_t MASK_TFR; /* Transfer Mask, 0x310 */
  uint32_t RSVD10;
  __IO uint32_t MASK_BLOCK; /* Block Mask, 0x318 */
  uint32_t RSVD11;
  __IO uint32_t MASK_SRC_TRAN; /* Source Trans Mask, 0x320 */
  uint32_t RSVD12;
  __IO uint32_t MASK_DST_TRAN; /* Dest Trans Mask, 0x328 */
  uint32_t RSVD13;
  __IO uint32_t MASK_ERR; /* Error Mask, 0x330 */
  uint32_t RSVD14;
  __O uint32_t CLEAR_TFR; /* Transfer Clear, 0x338 */
  uint32_t RSVD15;
  __O uint32_t CLEAR_BLOCK; /* Block Clear, 0x340 */
  uint32_t RSVD16;
  __O uint32_t CLEAR_SRC_TRAN; /* Source Trans Clear, 0x348 */
  uint32_t RSVD17;
  __O uint32_t CLEAR_DST_TRAN; /* Dest Trans Clear, 0x350 */
  uint32_t RSVD18;
  __O uint32_t CLEAR_ERR; /* Error Clear, 0x358 */
  uint32_t RSVD19;
  __O uint32_t StatusInt; /* Interrupt Status, 0x360 */
  uint32_t RSVD191;
  __IO uint32_t ReqSrcReg; /* Source SW Request, 0x368 */
  uint32_t RSVD20;
  __IO uint32_t ReqDstReg; /* Dest SW Request, 0x370 */
  uint32_t RSVD21;
  __IO uint32_t SglReqSrcReg; /* Single Source Request, 0x378 */
  uint32_t RSVD22;
  __IO uint32_t SglReqDstReg; /* Single Dest Request, 0x380 */
  uint32_t RSVD23;
  __IO uint32_t LstSrcReg; /* Last Source Request, 0x388 */
  uint32_t RSVD24;
  __IO uint32_t LstDstReg; /* Last Dest Request, 0x390 */
  uint32_t RSVD25;
  __IO uint32_t DmaCfgReg; /* DMA Config, 0x398 */
  uint32_t RSVD26;
  __IO uint32_t ChEnReg; /* Channel Enable, 0x3A0 */
  uint32_t RSVD27;
  __I uint32_t DmaIdReg; /* DMA ID, 0x3A8 */
  uint32_t RSVD28;
  __IO uint32_t DmaTestReg; /* DMA Test, 0x3B0 */
  uint32_t RSVD29;
} GDMA_TypeDef;

/* GPIO (General Purpose Input/Output) register definitions */
typedef struct {
  __IO uint32_t DR;   /* Data Register */
  __IO uint32_t DDR;  /* Direction Register */
  __IO uint32_t CTRL; /* Control Register */
} GPIO_Port_TypeDef;

typedef struct {
  GPIO_Port_TypeDef PORT[4];  /*GPIO IP have 4 ports */
  __IO uint32_t INT_EN;       /* GPIO interrupt enable register */
  __IO uint32_t INT_MASK;     /* GPIO interrupt mask register */
  __IO uint32_t INT_TYPE;     /* interrupt type(level/edge) register */
  __IO uint32_t INT_POLARITY; /* interrupt polarity(Active low/high) register */
  __IO uint32_t INT_STATUS;   /* interrupt status register */
  __IO uint32_t INT_RAWSTATUS; /* interrupt status without mask register */
  __IO uint32_t DEBOUNCE;      /* interrupt signal debounce register */
  __IO uint32_t PORTA_EOI;     /* clear interrupt register */
  __IO uint32_t EXT_PORT[4];   /* GPIO IN read or OUT read back register */
  __IO uint32_t LSSYNC;    /* level-sensitive synchronization enable register */
  __IO uint32_t IDCODE;    /* GPIO ID code register */
  __IO uint32_t RSVD2;     /* Reserved */
  __IO uint32_t VERIDCODE; /* component Version register */
  __IO uint32_t CONFIG2;   /* GPIO configuration Register 2 */
  __IO uint32_t CONFIG1;   /* GPIO configuration Register 1 */
} GPIO_TypeDef;

/* Inter Integrated Circuit Interface */
typedef struct {
  __IO uint32_t IC_CON;      /* Control register */
  __IO uint32_t IC_TAR;      /* Target address register */
  __IO uint32_t IC_SAR;      /* Slave0 address register */
  __IO uint32_t IC_HS_MADDR; /* HS master mode code address */

  __IO uint32_t IC_DATA_CMD;    /* RX/TX data buffer and command */
  __IO uint32_t IC_SS_SCL_HCNT; /* Standard speed SCL high count */
  __IO uint32_t IC_SS_SCL_LCNT; /* Standard speed SCL low count */
  __IO uint32_t IC_FS_SCL_HCNT; /* Fast speed SCL high count */

  __IO uint32_t IC_FS_SCL_LCNT; /* Fast speed SCL low count */
  __IO uint32_t IC_HS_SCL_HCNT; /* High speed SCL high count */
  __IO uint32_t IC_HS_SCL_LCNT; /* High speed SCL low count */
  __I uint32_t IC_INTR_STAT;    /* Interrupt status */

  __IO uint32_t IC_INTR_MASK;    /* Interrupt mask */
  __I uint32_t IC_RAW_INTR_STAT; /* Raw interrupt status */
  __IO uint32_t IC_RX_TL;        /* Receive FIFO threshold */
  __IO uint32_t IC_TX_TL;        /* Transmit FIFO threshold */

  __I uint32_t IC_CLR_INTR;     /* Clear combined interrupts */
  __I uint32_t IC_CLR_RX_UNDER; /* Clear RX_UNDER interrupt */
  __I uint32_t IC_CLR_RX_OVER;  /* Clear RX_OVER interrupt */
  __I uint32_t IC_CLR_TX_OVER;  /* Clear TX_OVER interrupt */

  __I uint32_t IC_CLR_RD_REQ;   /* Clear RD_REQ interrupt */
  __I uint32_t IC_CLR_TX_ABRT;  /* Clear TX_ABRT interrupt */
  __I uint32_t IC_CLR_RX_DONE;  /* Clear RX_DONE interrupt */
  __I uint32_t IC_CLR_ACTIVITY; /* Clear ACTIVITY interrupt */

  __I uint32_t IC_CLR_STOP_DET;  /* Clear STOP_DET interrupt */
  __I uint32_t IC_CLR_START_DET; /* Clear START_DET interrupt */
  __I uint32_t IC_CLR_GEN_CALL;  /* Clear GEN_CALL interrupt */
  __IO uint32_t IC_ENABLE;       /* Enable register */

  __I uint32_t IC_STATUS;    /* Status register */
  __I uint32_t IC_TXFLR;     /* Transmit FIFO level */
  __I uint32_t IC_RXFLR;     /* Receive FIFO level */
  __IO uint32_t IC_SDA_HOLD; /* SDA hold time length */

  __I uint32_t IC_TX_ABRT_SOURCE;      /* Transmit abort status */
  __IO uint32_t IC_SLV_DATA_NACK_ONLY; /* Generate SLV_DATA_NACK */
  __IO uint32_t IC_DMA_CR;             /* DMA control */
  __IO uint32_t IC_DMA_TDLR;           /* DMA transmit data level */

  __IO uint32_t IC_DMA_RDLR;         /* DMA receive data level */
  __IO uint32_t IC_SDA_SETUP;        /* SDA setup */
  __IO uint32_t IC_ACK_GENERAL_CALL; /* ACK general call */
  __IO uint32_t IC_ENABLE_STATUS;    /* Enable status */

  /* AmebaZ added New registers */
  __IO uint32_t IC_DMA_CMD;     /* DMA command */
  __IO uint32_t IC_DMA_DAT_LEN; /* DMA transmit data length */
  __IO uint32_t IC_DMA_MOD;     /* DMA mode */
  __IO uint32_t IC_SLEEP;       /* Sleep control */

  __IO uint32_t IC_RSVD1[4]; /* Reserved field */
  __I uint32_t IC_RSVD2[4];  /* Reserved field */
  __I uint32_t IC_RSVD3[4];  /* Reserved field */

  __I uint32_t IC_RSVD4;            /* Reserved field */
  __I uint32_t IC_CLR_ADDR_MATCH;   /* Clear ADDR_MATCH interrupt */
  __I uint32_t IC_CLR_DMA_I2C_DONE; /* Clear DMA_I2C_DONE interrupt */
  __IO uint32_t IC_FILTER;          /* Filter register */

  __I uint32_t IC_RSVD5;        /* Reserved field */
  __IO uint32_t IC_SAR1;        /* Slave1 address */
  __IO uint32_t IC_DATA_S1;     /* Slave1 RX/TX data buffer */
  __I uint32_t IC_COMP_VERSION; /* Component version ID */
} I2C_TypeDef;

/* Inter-Integrated Circuit Sound interface */
typedef struct {
  __IO uint32_t IS_CTL;         /* Main I2S control register */
  __IO uint32_t IS_TX_PAGE_PTR; /* TX page pointer */
  __IO uint32_t IS_RX_PAGE_PTR; /* RX page pointer */
  __IO uint32_t IS_SETTING;     /* Page size and sample rate settings */

  __IO uint32_t IS_TX_MASK_INT;   /* TX interrupt enable */
  __IO uint32_t IS_TX_STATUS_INT; /* TX interrupt status */
  __IO uint32_t IS_RX_MASK_INT;   /* RX interrupt enable */
  __IO uint32_t IS_RX_STATUS_INT; /* RX interrupt status */

  __IO uint32_t IS_TX_PAGE_OWN[4]; /* TX page ownership bits */
  __IO uint32_t IS_RX_PAGE_OWN[4]; /* RX page ownership bits */
} I2S_TypeDef;

/* Internet Protocol Security (IPsec) */
typedef struct {
  __IO uint32_t IPSSDAR; /* Source Descriptor Starting Address Register */
  __IO uint32_t IPSDDAR; /* Destination Descriptor Starting Address Register */
  __IO uint32_t IPSCSR;  /* Command/Status Register */
  __IO uint32_t IPSCTR;  /* Control Register */
} IPSEC_TypeDef;

/**
 * NCO32k (Numerically Controlled Oscillator) peripheral structure
 * Controls and monitors the 32KHz clock generation and calibration system
 */
typedef struct {
  __IO uint32_t CLK_INFO;  // [23:0] Unregulated clock frequency value
                           // [24] 32K clock output ready flag
                           // [25] 32K calibration ready flag

  __IO uint32_t CLK_OUT;  // Expected frequency of NCO calibration output clock

  __IO uint32_t CLK_REF;  // Lower 32 bits of reference clock frequency
                          // Used for clock output generation and input clock
                          // monitoring (ASIC: OSC8M, FPGA: 128K)

  __IO uint32_t CTRL;  // [9:0] Reference clock frequency (upper 10 bits)
                       // [16] 32K enable
                       // [17] Reference clock enable
                       // [23:20] 32K monitor
                       // [30:24] 32K threshold
} NCO32k_TypeDef;

/*
 * 8MHz NCO Register Declaration
 * [0]: function enable
 * [15:1]: expected frequency of nco output clk, unit is 1KHz
 * [31:16] frequency of nco input clk, unit is 1KHz
 */
typedef union {
  __IO uint32_t NCOReg; /* 32-bit access */
} NCO8M_TypeDef;

/* Peripheral and clock control register definitions */
typedef struct {
  __IO uint32_t PEON_PWR_CTRL;         /* 0x0200 */
  __IO uint32_t PON_ISO_CTRL;          /* 0x0204 */
  uint32_t RESERVED0[2];               /* 0x0208-0x020C */
  __IO uint32_t SOC_FUNC_EN;           /* 0x0210 */
  __IO uint32_t SOC_HCI_COM_FUNC_EN;   /* 0x0214 */
  __IO uint32_t SOC_PERI_FUNC0_EN;     /* 0x0218 */
  __IO uint32_t SOC_PERI_FUNC1_EN;     /* 0x021C */
  __IO uint32_t SOC_PERI_BD_FUNC0_EN;  /* 0x0220 */
  uint32_t RESERVED1[3];               /* 0x0224-0x022C */
  __IO uint32_t PESOC_CLK_CTRL;        /* 0x0230 */
  __IO uint32_t PESOC_PERI_CLK_CTRL0;  /* 0x0234 */
  __IO uint32_t PESOC_PERI_CLK_CTRL1;  /* 0x0238 */
  __IO uint32_t PESOC_CLK_CTRL3;       /* 0x023C */
  __IO uint32_t PESOC_HCI_CLK_CTRL0;   /* 0x0240 */
  __IO uint32_t PESOC_COM_CLK_CTRL1;   /* 0x0244 */
  __IO uint32_t PESOC_HW_ENG_CLK_CTRL; /* 0x0248 */
  uint32_t RESERVED2[1];               /* 0x024C */
  __IO uint32_t PESOC_CLK_SEL;         /* 0x0250 */
  uint32_t RESERVED3[6];               /* 0x0254-0x0268 */
  __IO uint32_t UART_NCO_CTRL;         /* 0x026C */
  uint32_t RESERVED4[1];               /* 0x0270 */
  __IO uint32_t OSC32K_REG_CTRL0;      /* 0x0274 */
  __IO uint32_t OSC32K_REG_CTRL1;      /* 0x0278 */
  __IO uint32_t THERMAL_METER_CTRL;    /* 0x027C */
  __IO uint32_t GPIO_PINMUX_CTRL[24];  /* 0x0280-0x02DC */
  __IO uint32_t PON_PINMUX_CTRL;       /* 0x02E0 */
  uint32_t RESERVED5[6];               /* 0x02E4-0x02F8 */
  __IO uint32_t FW_PPROTECT_KEY_CTRL;  /* 0x02FC */
  uint32_t RESERVED6[1];               /* 0x0300 */
  __IO uint32_t PESOC_SOC_CTRL;        /* 0x0304 */
} PERI_ON_TypeDef;

/* Pin Multiplexing */
typedef struct {
  __IO uint32_t PADCTR[21]; /*Pad control register */
} PINMUX_TypeDef;

/*
 * AMEBAZ_TIMER Register Declaration
 * TIM1 have 6 CCR registers: bit[15:0] is CCR, bit[31:24] is CCMR
 * TIM3 have 1 CCR registesr: bit[15:0] is CCR, bit[31:24] is CCMR
 * TIM5-8 dont have CCR register
 */

/* RTK Timer (RTIM) registers */
typedef struct {
  __IO uint32_t EN;       /* Timer enable */
  __IO uint32_t CR;       /* Main control settings */
  __IO uint32_t DIER;     /* DMA/Interrupt configuration */
  __IO uint32_t SR;       /* Status flags */
  __IO uint32_t EGR;      /* Event generation control */
  __IO uint32_t CNT;      /* Counter value */
  __IO uint32_t PSC;      /* Clock prescaler */
  __IO uint32_t ARR;      /* Auto-reload value */
  __IO uint32_t CCMRx[6]; /* Capture/Compare modes */
} RTIM_TypeDef;

/* RTIM TIM CCR */
typedef struct {
  __IO uint16_t CCRx; /* TIM capture/compare register */
  __IO uint8_t RSVD;  /* TIM capture/compare rsvd register */
  __IO uint8_t CCMRx; /* TIM capture/compare register */
} RTIM_CCR_TypeDef;

/* Real-Time Clock (RTC) registers */
typedef struct {
  __IO uint32_t TR;     /* Time value */
  __IO uint32_t CR;     /* Control settings */
  __IO uint32_t ISR;    /* Status and initialization */
  __IO uint32_t PRER;   /* Clock prescaler */
  __IO uint32_t CALIBR; /* Calibration settings */
  __IO uint32_t ALMR1;  /* Alarm 1 configuration */
  __IO uint32_t ALMR2;  /* Alarm 2 configuration */
  __IO uint32_t WPR;    /* Write protection */
} RTC_TypeDef;

/* Serial Peripheral Interface (SPI) */
typedef struct {
  __IO uint32_t CTRLR0;          /* Control register 0 */
  __IO uint32_t CTRLR1;          /* Control register 1 */
  __IO uint32_t SSIENR;          /* SSI enable */
  __IO uint32_t MWCR;            /* Microwire control */
  __IO uint32_t SER;             /* Slave enable */
  __IO uint32_t BAUDR;           /* Baud rate select */
  __IO uint32_t TXFTLR;          /* TX FIFO threshold level */
  __IO uint32_t RXFTLR;          /* RX FIFO threshold level */
  __I uint32_t TXFLR;            /* TX FIFO level */
  __I uint32_t RXFLR;            /* RX FIFO level */
  __I uint32_t SR;               /* Status */
  __IO uint32_t IMR;             /* Interrupt mask */
  __I uint32_t ISR;              /* Interrupt status */
  __I uint32_t RISR;             /* Raw interrupt status */
  __I uint32_t TXOICR;           /* TX FIFO overflow interrupt clear */
  __I uint32_t RXOICR;           /* RX FIFO overflow interrupt clear */
  __I uint32_t RXUICR;           /* RX FIFO underflow interrupt clear */
  __I uint32_t MSTICR;           /* Multi-master interrupt clear */
  __I uint32_t ICR;              /* Interrupt clear */
  __IO uint32_t DMACR;           /* DMA control */
  __IO uint32_t DMATDLR;         /* DMA TX data level */
  __IO uint32_t DMARDLR;         /* DMA RX data level */
  __I uint32_t IDR;              /* Identification */
  __I uint32_t SSI_COMP_VERSION; /* CoreKit version ID */
  __IO uint32_t DR[36];          /* Data register array */
  __IO uint32_t RX_SAMPLE_DLY;   /* RX sample delay */
} SPI_TypeDef;

/* SPI Flash Controller (SPIC) */
typedef struct {
  __IO uint32_t ctrlr0;            /* Control register 0 */
  __IO uint32_t ctrlr1;            /* Control register 1 */
  __IO uint32_t ssienr;            /* SPI enable */
  __IO uint32_t mwcr;              /* Reserved */
  __IO uint32_t ser;               /* Slave enable */
  __IO uint32_t baudr;             /* Baudrate select */
  __IO uint32_t txftlr;            /* TX FIFO threshold level */
  __IO uint32_t rxftlr;            /* RX FIFO threshold level */
  __IO uint32_t txflr;             /* TX FIFO level */
  __IO uint32_t rxflr;             /* RX FIFO level */
  __IO uint32_t sr;                /* Status register */
  __IO uint32_t imr;               /* Interrupt mask */
  __IO uint32_t isr;               /* Interrupt status */
  __IO uint32_t risr;              /* Raw interrupt status */
  __IO uint32_t txoicr;            /* TX FIFO overflow interrupt clear */
  __IO uint32_t rxoicr;            /* RX FIFO overflow interrupt clear */
  __IO uint32_t rxuicr;            /* RX FIFO underflow interrupt clear */
  __IO uint32_t msticr;            /* Master error interrupt clear */
  __IO uint32_t icr;               /* Interrupt clear */
  __IO uint32_t dmacr;             /* Reserved */
  __IO uint32_t dmatdlr;           /* Reserved */
  __IO uint32_t dmardlr;           /* Reserved */
  __IO uint32_t idr;               /* Identification register */
  __IO uint32_t spi_flash_version; /* Version ID */
  union {
    __IO uint8_t byte;
    __IO uint16_t half;
    __IO uint32_t word;
  } dr[32];                     /* Data register array */
  __IO uint32_t rd_fast_single; /* Flash fast read command */
  __IO uint32_t rd_dual_o;      /* Flash dual output read */
  __IO uint32_t rd_dual_io;     /* Flash dual I/O read */
  __IO uint32_t rd_quad_o;      /* Flash quad output read */
  __IO uint32_t rd_quad_io;     /* Flash quad I/O read */
  __IO uint32_t wr_single;      /* Flash page program */
  __IO uint32_t wr_dual_i;      /* Flash dual input program */
  __IO uint32_t wr_dual_ii;     /* Flash dual addr/data program */
  __IO uint32_t wr_quad_i;      /* Flash quad input program */
  __IO uint32_t wr_quad_ii;     /* Flash quad addr/data program */
  __IO uint32_t wr_enable;      /* Flash write enable */
  __IO uint32_t rd_status;      /* Flash read status */
  __IO uint32_t ctrlr2;         /* Control register 2 */
  __IO uint32_t fbaudr;         /* Fast baudrate select */
  __IO uint32_t addr_length;    /* Address length */
  __IO uint32_t auto_length;    /* Auto address length */
  __IO uint32_t valid_cmd;      /* Valid command */
  __IO uint32_t flash_size;     /* Flash size */
  __IO uint32_t flush_fifo;     /* Flush FIFO */
} SPIC_TypeDef;

/* AMEBAZ_CACHE Register Declaration */
typedef struct {
  __IO uint32_t SPICC_EN;                /* Enable control */
  __IO uint32_t SPICC_FLUSH;             /* Cache flush control */
  __IO uint32_t SPICC_INTR;              /* Interrupt status/control */
  __IO uint32_t SPICC_RST_CUNT;          /* Reset counter */
  __IO uint32_t SPICC_RD_EVT_CUNT;       /* Read events counter */
  __IO uint32_t SPICC_HIT_EVT_CUNT;      /* Cache hit counter */
  __IO uint32_t SPICC_HIT_LSTW_EVT_CUNT; /* Last-way hit counter */
  __IO uint32_t SPICC_RD_PEND_CUNT;      /* Pending read counter */
} SPIC_CACHE_TypeDef;

/* Control register definitions for system-level configurations */
typedef struct {
  /* 0x0000 - Power/Isolation Control */
  union {
    struct {
      __IO uint16_t PWR_CTRL; /* 0x0000 */
      __IO uint16_t ISO_CTRL; /* 0x0002 */
    } PWR_ISO;
    __IO uint32_t PWR_ISO_CTRL; /* 0x0000 */
  };

  uint32_t RESERVED0[1];   /* 0x0004 */
  __IO uint32_t FUNC_EN;   /* 0x0008 */
  __IO uint32_t CLK_CTRL0; /* 0x0010 */
  __IO uint32_t CLK_CTRL1; /* 0x0014 */

  uint32_t RESERVED1[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 */
  __IO uint32_t SWR_CTRL0;  /* 0x0048 */
  __IO uint32_t SWR_CTRL1;  /* 0x004C */

  uint32_t RESERVED3[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 */

  /* System PLL Control Registers */
  __IO uint32_t SYSPLL_CTRL0; /* 0x0070 */
  __IO uint32_t SYSPLL_CTRL1; /* 0x0074 */
  __IO uint32_t SYSPLL_CTRL2; /* 0x0078 */
  __IO uint32_t SYSPLL_CTRL3; /* 0x007C */

  uint32_t RESERVED5[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 */

  __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 */

  __IO uint32_t DEBUG_REG; /* 0x00BC */

  uint32_t RESERVED8[8]; /* 0x00C0-0x00DC */

  __IO uint32_t EEPROM_CTRL0;           /* 0x00E0 */
  __IO uint32_t EEPROM_CTRL1;           /* 0x00E4 */
  __IO uint32_t EFUSE_CTRL;             /* 0x00E8 */
  __IO uint32_t EFUSE_TEST;             /* 0x00EC */
  __IO uint32_t OSC32K_CTRL;            /* 0x00F0 */
  __IO uint32_t OSC32K_RCAL;            /* 0x00F4 */
  __IO uint32_t DSTBY_INFO0;            /* 0x00F8 */
  __IO uint32_t DSTBY_INFO1;            /* 0x00FC */
  __IO uint32_t SLP_WAKE_EVENT_MSK0;    /* 0x0100 */
  __IO uint32_t SLP_WAKE_EVENT_MSK1;    /* 0x0104 */
  __IO uint32_t SLP_WAKE_EVENT_STATUS0; /* 0x0108 */
  __IO uint32_t SLP_WAKE_EVENT_STATUS1; /* 0x010C */
  __IO uint32_t SNF_WAKE_EVENT_MSK0;    /* 0x0110 */
  __IO uint32_t SNF_WAKE_EVENT_STATUS;  /* 0x0114 */
  __IO uint32_t PWRMGT_CTRL;            /* 0x0118 */

  uint32_t RESERVED9[1]; /* 0x011C */

  __IO uint32_t PWRMGT_OPTION;     /* 0x0120 */
  __IO uint32_t PWRMGT_OPTION_EXT; /* 0x0124 */

  uint32_t RESERVED10[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 */

  __IO uint32_t SYSTEM_CFG0; /* 0x01F0 */
  __IO uint32_t SYSTEM_CFG1; /* 0x01F4 */
  __IO uint32_t SYSTEM_CFG2; /* 0x01F8 */
} SYSTEM_CTRL_TypeDef;

/* Universal asynchronous receiver-transmitter (UART) */
typedef struct {
  __IO uint32_t DLL;       /* Divisor Latch (unused in Amebaz) */
  __IO uint32_t DLH_INTCR; /* Interrupt Enable */
  __IO uint32_t INTID;     /* Interrupt Identification */
  __IO uint32_t LCR;       /* Line Control */
  __IO uint32_t MCR;       /* Modem Control */
  __I uint32_t LSR;        /* Line Status */
  __I uint32_t MDSR;       /* Modem Status */
  __IO uint32_t SPR;       /* Scratch Pad */
  __IO uint32_t STSR;      /* STS Register */
  __IO uint32_t RB_THR;    /* Receive Buffer/Transmit Holding */
  __IO uint32_t MISCR;     /* Misc Control */
  __IO uint32_t TXPLSR;    /* IrDA TX Pulse Width Control */

  __IO uint32_t RXPLSR;   /* IrDA RX Pulse Width Control */
  __IO uint32_t BAUDMONR; /* Baud Monitor */
  __IO uint32_t RSVD2;    /* Reserved */
  __IO uint32_t DBG_UART; /* Debug */

  /* Power save features */
  __IO uint32_t RX_PATH;       /* RX Path Control */
  __IO uint32_t MON_BAUD_CTRL; /* Monitor Baud Rate Control */
  __IO uint32_t MON_BAUD_STS;  /* Monitor Baud Rate Status */
  __IO uint32_t MON_CYC_NUM;   /* Monitor Cycle Number */
  __IO uint32_t RX_BYTE_CNT;   /* RX Byte Counter */

  __IO uint32_t FCR; /* FIFO Control */
} UART_TypeDef;

/* USB System-on-Chip (USOC) */
typedef struct {
  __IO uint32_t SIE_CR;           /* SIE control */
  __IO uint32_t CLK_RST_CTRL;     /* Clock and reset control */
  __IO uint32_t CHANN_CTRL;       /* Channel control */
  __IO uint32_t BUFF_SIZE_CTRL;   /* TX/RX buffer size control */
  __IO uint32_t TXBD_BAR;         /* TX buffer descriptor base address */
  __IO uint32_t RXBD_BAR;         /* RX buffer descriptor base address */
  __IO uint32_t RING_SIZE_CTRL;   /* Ring size control */
  __IO uint32_t RSVD1;            /* Reserved */
  __I uint32_t TXBD_HW_IDX;       /* TX hardware index */
  __IO uint32_t TXBD_SW_IDX;      /* TX software index */
  __I uint32_t RXBD_HW_IDX;       /* RX hardware index */
  __IO uint32_t RXBD_SW_IDX;      /* RX software index */
  __IO uint32_t INTR_MASK;        /* Interrupt mask */
  __IO uint32_t INTR_CLR;         /* Interrupt clear */
  __IO uint32_t INTR_STAT;        /* Interrupt status */
  __IO uint32_t RSVD2;            /* Reserved */
  __IO uint32_t TX_MIT;           /* TX mitigation */
  __IO uint32_t RX_MIT;           /* RX mitigation */
  __IO uint32_t RSVD3[2];         /* Reserved */
  __IO uint32_t IOREG_MAR;        /* Host device access */
  __IO uint32_t RSVD4[3];         /* Reserved */
  __IO uint32_t TX_MAIN_BUF_CTRL; /* TX main buffer control */
  __IO uint32_t TX_DEST_BUF_CTRL; /* TX destination buffer control */
  __IO uint32_t RX_MAIN_BUF_CTRL; /* RX main buffer control */
  __IO uint32_t RX_SRC_BUF_CTRL;  /* RX source buffer control */
  __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;

/* 0x0000h ~ 0x00FFh System Configuration */
typedef struct {
  __IO uint16_t ISO_CTRL;           // 0x0000, 2 Byte
  __IO uint16_t FUNC_EN;            // 0x0002, 2 Byte
  __IO uint32_t APS_FSMCO;          // 0x0004, 4 Byte
  __IO uint16_t CLKR;               // 0x0008, 2 Byte
  __IO uint16_t CR_9346;            // 0x000A, 2 Byte
  __IO uint16_t EE_VPD;             // 0x000C, 2 Byte
  __IO uint8_t AFE_MISC;            // 0x0010, 1 Byte
  __IO uint8_t SPS0_CTRL[7];        // 0x0011, 7 Byte
  __IO uint32_t SPS_OCP_CFG;        // 0x0018, 4 Byte
  __IO uint8_t RSV_CTRL[3];         // 0x001C, 3 Byte
  __IO uint8_t RF_CTRL;             // 0x001F, 1 Byte
  __IO uint8_t LPLDO_CTRL;          // 0x0023, 1 Byte
  __IO uint32_t AFE_XTAL_CTRL;      // 0x0024, 4 Byte
  __IO uint32_t AFE_PLL_CTRL;       // 0x0028, 4 Byte
  __IO uint32_t MAC_PLL_CTRL_EXT;   // 0x002C, 4 Byte
  __IO uint32_t EFUSE_CTRL;         // 0x0030
  __IO uint32_t EFUSE_TEST;         // 0x0034
  __IO uint32_t PWR_DATA;           // 0x0038
  __IO uint32_t CAL_TIMER;          // 0x003C
  __I uint16_t ACLK_MON;            // 0x003E, Read-only
  __IO uint16_t GPIO_MUXCFG;        // 0x0040
  __IO uint16_t GPIO_IO_SEL;        // 0x0042
  __IO uint8_t MAC_PINMUX_CFG;      // 0x0043
  __IO uint32_t GPIO_PIN_CTRL;      // 0x0044
  __IO uint32_t GPIO_INTM;          // 0x0048
  __IO uint8_t LEDCFG0;             // 0x004C
  __IO uint8_t LEDCFG1;             // 0x004D
  __IO uint8_t LEDCFG2;             // 0x004E
  __IO uint8_t LEDCFG3;             // 0x004F
  __IO uint32_t FSIMR;              // 0x0050
  __I uint32_t FSISR;               // 0x0054, Status register
  __IO uint32_t HSIMR;              // 0x0058
  __I uint32_t HSISR;               // 0x005C, Status register
  __IO uint32_t GPIO_EXT_CTRL;      // 0x0060
  __IO uint32_t MULTI_FUNC_CTRL;    // 0x0068
  __I uint32_t GPIO_STATUS;         // 0x006C, Status register
  __IO uint32_t SDIO_CTRL;          // 0x0070
  __IO uint32_t OPT_CTRL;           // 0x0074
  __IO uint32_t AFE_XTAL_CTRL_EXT;  // 0x0078
  __IO uint32_t MCUFWDL;            // 0x0090
  __I uint32_t BT_PATCH_STATUS;     // 0x0088, Status register
  __IO uint32_t HIMR0;              // 0x00B0
  __I uint32_t HISR0;               // 0x00B4, Status register
  __IO uint32_t HIMR1;              // 0x00B8
  __I uint32_t HISR1;               // 0x00BC, Status register
  __IO uint32_t PMC_DBG_CTRL2;      // 0x00CC
  __IO uint8_t EFUSE_BURN_GNT;      // 0x00CF
  __I uint32_t HPON_FSM;            // 0x00EC, FSM state
  __IO uint32_t SYS_CFG;            // 0x00F0
  __IO uint32_t SYS_CFG1;           // 0x00FC
  __I uint8_t ROM_VERSION;          // 0x00FD, Read-only version
} WiFi_SYS_TypeDef;

/* 0x0100h ~ 0x01FFh MACTOP General Configuration */
typedef struct {
  __IO uint32_t CR;                   /* 0x0100 Control Register */
  __IO uint32_t PBP;                  /* 0x0104 Packet Buffer Parameter */
  __IO uint16_t PKT_BUFF_ACCESS_CTRL; /* 0x0106 Packet Buffer Access Control */
  uint16_t RESERVED0;                 /* 0x0108-0x0109 */
  __IO uint32_t TRXDMA_CTRL;          /* 0x010C TRX DMA Control */
  uint8_t RESERVED1[4];               /* 0x0110-0x0113 */
  __IO uint32_t TRXFF_BNDY;           /* 0x0114 TRX FIFO Boundary */
  __I uint32_t TRXFF_STATUS;          /* 0x0118 TRX FIFO Status */
  __I uint32_t RXFF_PTR;              /* 0x011C RX FIFO Pointer */
  uint8_t RESERVED2[0x12];            /* 0x0120-0x012E */
  __IO uint8_t CPWM;                  /* 0x012F Control Power Management */
  uint8_t RESERVED3[8];               /* 0x0130-0x0137 */
  __IO uint32_t FTIMR;            /* 0x0138 FW Timer Interrupt Mask Register */
  uint8_t RESERVED4[4];           /* 0x013C-0x013F */
  __IO uint16_t PKTBUF_DBG_CTRL;  /* 0x0140 Packet Buffer Debug Control */
  __IO uint16_t RXPKTBUF_CTRL;    /* 0x0142 RX Packet Buffer Control */
  __I uint32_t PKTBUF_DBG_DATA_L; /* 0x0144 Packet Buffer Debug Data Low */
  __I uint32_t PKTBUF_DBG_DATA_H; /* 0x0148 Packet Buffer Debug Data High */
  __IO uint32_t TC0_CTRL;         /* 0x0150 TC0 Control Register */
  __IO uint32_t TC1_CTRL;         /* 0x0154 TC1 Control Register */
  __IO uint32_t TC2_CTRL;         /* 0x0158 TC2 Control Register */
  __IO uint32_t TC3_CTRL;         /* 0x015C TC3 Control Register */
  __IO uint32_t TC4_CTRL;         /* 0x0160 TC4 Control Register */
  __IO uint32_t TCUNIT_BASE;      /* 0x0164 TC Unit Base */
  __IO uint32_t RSVD3;            /* 0x0168 Reserved */
  uint8_t RESERVED5[0x34];        /* 0x016C-0x019F */
  __I uint8_t C2HEVT_MSG_NORMAL;  /* 0x01A0 C2H Event Message Normal */
  __I uint8_t C2HEVT_CMD_SEQ;     /* 0x01A1 C2H Event Command Sequence */
  __I uint8_t
      C2HEVT_CMD_CONTENT[12]; /* 0x01A2-0x01AD C2H Event Command Content */
  __I uint8_t C2HEVT_CMD_LEN; /* 0x01AE C2H Event Command Length */
  __O uint8_t C2HEVT_CLEAR;   /* 0x01AF C2H Event Clear */
  __IO uint32_t MCUTST_1;     /* 0x01C0 MCU Test 1 */
  uint8_t RESERVED6[3];       /* 0x01C4-0x01C6 */
  __IO uint8_t MCUTST_WOWLAN; /* 0x01C7 MCU Test WOWLAN */
  __IO uint32_t FMETHR;       /* 0x01C8 FW Message Exchange Threshold */
  __IO uint32_t HMETFR;       /* 0x01CC Host Message Exchange Threshold */
  __IO uint32_t HMEBOX_0;     /* 0x01D0 Host Message Box 0 */
  __IO uint32_t HMEBOX_1;     /* 0x01D4 Host Message Box 1 */
  __IO uint32_t HMEBOX_2;     /* 0x01D8 Host Message Box 2 */
  __IO uint32_t HMEBOX_3;     /* 0x01DC Host Message Box 3 */
  __IO uint32_t LLT_INIT;     /* 0x01E0 LLT Init */
  uint8_t RESERVED7[0xC];     /* 0x01E4-0x01EF */
  __IO uint32_t HMEBOX_EXT0;  /* 0x01F0 Host Message Box Extension 0 */
  __IO uint32_t HMEBOX_EXT1;  /* 0x01F4 Host Message Box Extension 1 */
  __IO uint32_t HMEBOX_EXT2;  /* 0x01F8 Host Message Box Extension 2 */
  __IO uint32_t HMEBOX_EXT3;  /* 0x01FC Host Message Box Extension 3 */
} WiFi_MAC_TypeDef;

/* 0x0200h ~ 0x027Fh TXDMA Configuration */
typedef struct {
  __IO uint32_t RQPN;             /* 0x0200 Release Queue Page Number */
  __IO uint32_t FIFOPAGE;         /* 0x0204 FIFO Page */
  __IO uint32_t TDECTRL;          /* 0x0208 TX DMA Engine Control */
  __IO uint32_t TXDMA_OFFSET_CHK; /* 0x020C TX DMA Offset Check */
  __I uint32_t TXDMA_STATUS;      /* 0x0210 TX DMA Status */
  __IO uint32_t RQPN_NPQ;         /* 0x0214 Release Queue Page Number NPQ */
  uint8_t RESERVED1[0x10];        /* 0x0218-0x0227 */
  __IO uint32_t TDECTRL1;         /* 0x0228 TX DMA Engine Control 1 */
  uint8_t RESERVED2[0x54];        /* 0x022C-0x027F */
} WiFi_TXDMA_TypeDef;
/* 0x0280h ~ 0x02FFh RXDMA Configuration */
typedef struct {
  __IO uint32_t RXDMA_AGG_PG_TH; /* 0x0280 RX DMA Aggregation Page Threshold */
  __IO uint32_t FW_UPD_RDPTR;    /* 0x0284 Firmware Update Read Pointer */
  __IO uint16_t RXDMA_CONTROL;   /* 0x0286 RX DMA Control */
  __I uint8_t RXPKT_NUM;         /* 0x0287 RX Packet Number */
  __I uint32_t RXDMA_STATUS;     /* 0x0288 RX DMA Status */
  uint8_t RESERVED1[4];          /* 0x028C-0x028F */
  __IO uint32_t RXDMA_PRO;       /* 0x0290 RX DMA PRO */
  uint8_t RESERVED2[0x28];       /* 0x0294-0x02BB */
  __IO uint32_t EARLY_MODE_CONTROL; /* 0x02BC Early Mode Control */
  uint8_t RESERVED3[0x30];          /* 0x02C0-0x02EF */
  __IO uint32_t RSVD5;              /* 0x02F0 Reserved */
  __IO uint32_t RSVD6;              /* 0x02F4 Reserved */
  uint8_t RESERVED4[8];             /* 0x02F8-0x02FF */
} WiFi_RXDMA_TypeDef;

/* 0x0300h ~ 0x03FFh	LxBUS hal_com_reg.h */
/**
 * TODO: this is VERY LIKELY wrong, lxbus_ops.o
 * DMA descriptors aren't arranged sequentially
 * spacing between TX descriptors is unusual
 * 32K control register (at 0x3D9)???
 */
typedef struct {
  /* 0x0300 - Control Register */
  volatile uint32_t CTRL;          /* 0x0300 - Control register */
  volatile uint32_t RESERVED1[1];  /* 0x0304 */
  volatile uint32_t TX4_DESC;      /* 0x0308 - TX Ring 4 Descriptor */
  volatile uint32_t RESERVED2[1];  /* 0x030C */
  volatile uint32_t TX5_DESC;      /* 0x0310 - TX Ring 5 Descriptor */
  volatile uint32_t RESERVED3[1];  /* 0x0314 */
  volatile uint32_t TX0_DESC;      /* 0x0318 - TX Ring 0 Descriptor */
  volatile uint32_t RESERVED4[1];  /* 0x031C */
  volatile uint32_t TX1_DESC;      /* 0x0320 - TX Ring 1 Descriptor */
  volatile uint32_t RESERVED5[1];  /* 0x0324 */
  volatile uint32_t TX2_DESC;      /* 0x0328 - TX Ring 2 Descriptor */
  volatile uint32_t RESERVED6[1];  /* 0x032C */
  volatile uint32_t TX3_DESC;      /* 0x0330 - TX Ring 3 Descriptor */
  volatile uint32_t RESERVED7[1];  /* 0x0334 */
  volatile uint32_t RX_DESC;       /* 0x0338 - RX Ring Descriptor */
  volatile uint32_t RESERVED8[1];  /* 0x033C */
  volatile uint32_t TX6_DESC;      /* 0x0340 - TX Ring 6 Descriptor */
  volatile uint32_t RESERVED9[15]; /* 0x0344-0x037F */

  /* DMA Configuration Registers */
  volatile uint16_t
      DMA_CFG[14]; /* 0x0380-0x039B - DMA Configuration registers */
  volatile uint8_t RESERVED10[61]; /* 0x039C-0x03D8 */

  /* 32K Control Register */
  volatile uint8_t K32_CTRL;       /* 0x03D9 - 32K Control register */
  volatile uint8_t RESERVED11[14]; /* 0x03DA-0x03E7 */

  /* Additional Control Registers */
  volatile uint32_t INT_MASK;   /* 0x03E8 - Interrupt Mask */
  volatile uint32_t INT_STATUS; /* 0x03EC - Interrupt Status */
} WiFi_LXBUS_TypeDef;
/* bits */
#define LXBUS_CTRL_BIT8 (1 << 8)     /* Control register bit 8 */
#define LXBUS_K32_CTRL_BIT0 (1 << 0) /* 32K Control bit 0 */
#define LXBUS_K32_CTRL_BIT6 (1 << 6) /* 32K Control bit 6 */
#define LXBUS_K32_CTRL_BIT7 (1 << 7) /* 32K Control bit 7 */

/* DMA config */
#define LXBUS_DMA_CFG_TYPE1 0x1004 /* DMA config type 1 */
#define LXBUS_DMA_CFG_TYPE2 0x2004 /* DMA config type 2 */
#define LXBUS_DMA_CFG_TYPE3 0x1002 /* DMA config type 3 */

/* 0x0400h ~ 0x047Fh Protocol Configuration */
typedef struct {
  /* Queue Information Registers */
  __IO uint32_t VOQ_INFORMATION;  /* 0x0400 VO Queue Information */
  __IO uint32_t VIQ_INFORMATION;  /* 0x0404 VI Queue Information */
  __IO uint32_t BEQ_INFORMATION;  /* 0x0408 BE Queue Information */
  __IO uint32_t BKQ_INFORMATION;  /* 0x040C BK Queue Information */
  __IO uint32_t MGQ_INFORMATION;  /* 0x0410 MG Queue Information */
  __IO uint32_t HGQ_INFORMATION;  /* 0x0414 HG Queue Information */
  __IO uint32_t BCNQ_INFORMATION; /* 0x0418 BCN Queue Information */
  __I uint16_t TXPKT_EMPTY;       /* 0x041A TX Packet Empty */
  uint8_t RESERVED1[4];           /* 0x041C-0x041F */

  /* Control Registers */
  __IO uint32_t FWHW_TXQ_CTRL;     /* 0x0420 FWHW TX Queue Control */
  __IO uint8_t HWSEQ_CTRL;         /* 0x0423 HW Sequence Control */
  __IO uint8_t TXPKTBUF_BCNQ_BDNY; /* 0x0424 TX Packet Buffer BCNQ Boundary */
  __IO uint8_t TXPKTBUF_MGQ_BDNY;  /* 0x0425 TX Packet Buffer MGQ Boundary */
  __IO uint8_t LIFECTRL_CTRL;      /* 0x0426 Life Control */
  __IO uint8_t MULTI_BCNQ_OFFSET;  /* 0x0427 Multi BCNQ Offset */
  __IO uint16_t SPEC_SIFS;         /* 0x0428 Specific SIFS */
  __IO uint16_t RL;                /* 0x042A Retry Limit */
  __IO uint32_t TXBF_CTRL;         /* 0x042C TX Beamforming Control */

  /* Frame Rate Control */
  __IO uint64_t
      DARFRC; /* 0x0430-0x0437 Data Auto Response Frame Rate Control */
  __IO uint64_t
      RARFRC; /* 0x0438-0x043F Response Auto Response Frame Rate Control */
  __IO uint32_t RRSR;           /* 0x0440 Response Rate Set */
  __IO uint64_t ARFR0;          /* 0x0444-0x044B Auto Response Frame Rate 0 */
  __IO uint64_t ARFR1;          /* 0x044C-0x0453 Auto Response Frame Rate 1 */
  __IO uint16_t CCK_CHECK;      /* 0x0454 CCK Check */
  __IO uint16_t AMPDU_MAX_TIME; /* 0x0456 AMPDU Max Time */
  __IO uint8_t
      TXPKTBUF_BCNQ_BDNY1; /* 0x0457 TX Packet Buffer BCNQ Boundary 1 */
  /* AMPDU and Buffer Control */
  __IO uint32_t AMPDU_MAX_LENGTH; /* 0x0458 AMPDU Max Length */
  uint8_t RESERVED2[1];           /* 0x045C */
  __IO uint8_t
      TXPKTBUF_WMAC_LBK_BF_HD;      /* 0x045D TX Packet Buffer WMAC LBK BF HD */
  uint8_t RESERVED3[1];             /* 0x045E */
  __IO uint8_t NDPA_OPT_CTRL;       /* 0x045F NDPA Option Control */
  __IO uint32_t FAST_EDCA_CTRL;     /* 0x0460 Fast EDCA Control */
  __IO uint8_t RD_RESP_PKT_TH;      /* 0x0463 RD Response Packet Threshold */
  uint8_t RESERVED4[0x1A];          /* 0x0464-0x047D */
  __IO uint8_t SPC_W_PTR;           /* 0x047E SPC Write Pointer */
  __IO uint8_t SPC_R_PTR;           /* 0x047F SPC Read Pointer */
  uint8_t RESERVED5[3];             /* 0x0480-0x0482 */
  __IO uint8_t DATA_SC;             /* 0x0483 Data Sequence Control */
  uint8_t RESERVED6[0x28];          /* 0x0484-0x04AB */
  __IO uint32_t TXRPT_START_OFFSET; /* 0x04AC TX Report Start Offset */
  uint8_t RESERVED7[4];             /* 0x04B0-0x04B3 */
  __IO uint32_t POWER_STAGE1;       /* 0x04B4 Power Stage 1 */
  __IO uint32_t POWER_STAGE2;       /* 0x04B8 Power Stage 2 */
  __IO uint32_t AMPDU_BURST_MODE;   /* 0x04BC AMPDU Burst Mode */
  __IO uint16_t PKT_VO_VI_LIFE_TIME; /* 0x04C0 Packet VO/VI Life Time */
  __IO uint16_t PKT_BE_BK_LIFE_TIME; /* 0x04C2 Packet BE/BK Life Time */
  __IO uint32_t STBC_SETTING;        /* 0x04C4 STBC Setting */
  __IO uint8_t HT_SINGLE_AMPDU;      /* 0x04C7 HT Single AMPDU */
  __IO uint32_t PROT_MODE_CTRL;      /* 0x04C8 Protection Mode Control */
  __IO uint16_t MAX_AGGR_NUM;        /* 0x04CA Maximum Aggregation Number */
  __IO uint8_t RTS_MAX_AGGR_NUM;     /* 0x04CB RTS Maximum Aggregation Number */
  __IO uint32_t BAR_MODE_CTRL;       /* 0x04CC BAR Mode Control */
  __IO uint8_t RA_TRY_RATE_AGG_LMT;  /* 0x04CF RA Try Rate Aggregation Limit */
  __IO uint32_t MACID_PKT_DROP0;     /* 0x04D0 MACID Packet Drop 0 */
  uint8_t RESERVED[0x2C];            /* 0x04D4-0x04FF */
} WiFi_PROT_TypeDef;

/* 0x0500h ~ 0x05FFh	EDCA Configuration */
typedef struct {
  __IO uint32_t VO_PARAM;        /* 0x0500 EDCA VO parameter */
  __IO uint32_t VI_PARAM;        /* 0x0504 EDCA VI parameter */
  __IO uint32_t BE_PARAM;        /* 0x0508 EDCA BE parameter */
  __IO uint32_t BK_PARAM;        /* 0x050C EDCA BK parameter */
  __IO uint32_t BCNTCFG;         /* 0x0510 Beacon configuration */
  __IO uint16_t PIFS;            /* 0x0512 PIFS timing */
  __IO uint8_t RDG_PIFS;         /* 0x0513 RDG PIFS timing */
  __IO uint16_t SIFS_CTX;        /* 0x0514 SIFS context timing */
  __IO uint16_t SIFS_TRX;        /* 0x0516 SIFS TRX timing */
  __IO uint16_t AGGR_BREAK_TIME; /* 0x051A Aggregation break time */
  __IO uint8_t SLOT;             /* 0x051B Slot time */
  __IO uint32_t TX_PTCL_CTRL;    /* 0x0520 TX protocol control */
  __IO uint8_t TXPAUSE;          /* 0x0522 TX pause */
  __IO uint8_t DIS_TXREQ_CLR;    /* 0x0523 Disable TX request clear */
  __IO uint32_t RD_CTRL;         /* 0x0524 RD control */
  uint8_t RESERVED1[24];         /* 0x528-0x540 */
  // Format for offset 540h-542h:
  //	[3:0]:   TBTT prohibit setup in unit of 32us. The time for HW getting
  // beacon content before TBTT. 	[7:4]:   Reserved. 	[19:8]:  TBTT
  // prohibit hold in unit of 32us. The time for HW holding to send the beacon
  // packet. 	[23:20]: Reserved
  // Description:
  //	              |
  //     |<--Setup--|--Hold------------>|
  //	--------------|----------------------
  //                |
  //               TBTT
  // Note: We cannot update beacon content to HW or send any AC packets during
  // the time between Setup and Hold. Described by Designer Tim and Bruce,
  // 2011-01-14.
  __IO uint32_t TBTT_PROHIBIT;     /* 0x0540 TBTT prohibit */
  __IO uint32_t RD_NAV_NXT;        /* 0x0544 RD NAV next */
  __IO uint16_t NAV_PROT_LEN;      /* 0x0546 NAV protection length */
  uint8_t RESERVED2[8];            /* 0x548-0x550 */
  __IO uint8_t BCN_CTRL;           /* 0x0550 Beacon control */
  __IO uint8_t BCN_CTRL_1;         /* 0x0551 Beacon control 1 */
  __IO uint8_t MBID_NUM;           /* 0x0552 MBID number */
  __IO uint8_t DUAL_TSF_RST;       /* 0x0553 Dual TSF reset */
  __IO uint16_t BCN_INTERVAL;      /* 0x0554 Beacon interval */
  uint8_t RESERVED3[2];            /* 0x556-0x558 */
  __IO uint8_t DRVERLYINT;         /* 0x0558 Driver early interrupt */
  __IO uint8_t BCNDMATIM;          /* 0x0559 Beacon DMA timing */
  __IO uint16_t ATIMWND;           /* 0x055A ATIM window */
  __IO uint16_t USTIME_TSF;        /* 0x055C US time TSF */
  __IO uint8_t BCN_MAX_ERR;        /* 0x055D Beacon max error */
  __IO uint8_t RXTSF_OFFSET_CCK;   /* 0x055E RX TSF offset CCK */
  __IO uint8_t RXTSF_OFFSET_OFDM;  /* 0x055F RX TSF offset OFDM */
  __IO uint32_t TSFTR;             /* 0x0560 TSF timer */
  uint8_t RESERVED4[14];           /* 0x564-0x572 */
  __IO uint8_t CTWND;              /* 0x0572 CT window */
  __IO uint8_t BCNIVLCUNT;         /* 0x0573 Beacon interval count */
  uint8_t RESERVED5[3];            /* 0x574-0x577 */
  __IO uint8_t SECONDARY_CCA_CTRL; /* 0x0577 Secondary CCA control */
  uint8_t RESERVED6[8];            /* 0x578-0x580 */
  __IO uint32_t PSTIMER;           /* 0x0580 PS timer */
  __IO uint32_t TIMER0;            /* 0x0584 Timer 0 */
  __IO uint32_t TIMER1;            /* 0x0588 Timer 1 */
  uint8_t RESERVED7[52];           /* 0x58C-0x5C0 */
  __IO uint32_t ACMHWCTRL;         /* 0x05C0 ACM hardware control */
  uint8_t RESERVED8[52];           /* 0x5C4-0x5F8 */
  __IO uint32_t SCH_TXCMD;         /* 0x05F8 Schedule TX command */
  uint8_t RESERVED9[4];            /* 0x5FC-0x600 */
} WiFi_EDCA_TypeDef;

/* 0x0600h ~ 0x07FFh	WMAC Configuration */
typedef struct {
  /* MAC Configuration (0x0600-0x060F) */
  __IO uint32_t MAC_CR;       /* 0x0600 MAC Configuration Register */
  __IO uint32_t TCR;          /* 0x0604 Transmission Configuration Register */
  __IO uint32_t RCR;          /* 0x0608 Receive Configuration Register */
  __IO uint8_t RX_PKT_LIMIT;  /* 0x060C RX Packet Limit */
  __IO uint8_t RX_DLK_TIME;   /* 0x060D RX Deadlock Time */
  uint8_t RESERVED1[1];       /* 0x060E */
  __IO uint8_t RX_DRVINFO_SZ; /* 0x060F RX Driver Info Size */

  /* ID Configuration (0x0610-0x0628) */
  __IO uint32_t MACID[2];   /* 0x0610 MAC ID */
  __IO uint32_t BSSID[2];   /* 0x0618 BSSID */
  __IO uint32_t MAR[2];     /* 0x0620 Multicast Address */
  __IO uint32_t MBIDCAMCFG; /* 0x0628 MBSSID CAM Configuration */

  uint8_t RESERVED2[12]; /* 0x062C-0x0637 */

  /* Timing Configuration (0x0638-0x0642) */
  __IO uint16_t USTIME_EDCA;    /* 0x0638 US Time EDCA */
  __IO uint16_t MAC_SPEC_SIFS;  /* 0x063A MAC Specific SIFS */
  __IO uint16_t RESP_SIFP_CCK;  /* 0x063C Response SIFS CCK */
  __IO uint16_t RESP_SIFS_OFDM; /* 0x063E Response SIFS OFDM */
  __IO uint8_t ACKTO;           /* 0x0640 ACK Timeout */
  __IO uint8_t CTS2TO;          /* 0x0641 CTS2 Timeout */
  __IO uint16_t EIFS;           /* 0x0642 Extended InterFrame Space */

  uint8_t RESERVED3[13]; /* 0x0644-0x0650 */

  /* Protocol Control (0x0652-0x0668) */
  __IO uint16_t NAV_UPPER;   /* 0x0652 NAV Upper (unit of 128) */
  uint8_t RESERVED4[14];     /* 0x0654-0x0661 */
  __IO uint16_t RTR;         /* 0x0662 Response Time Report */
  uint8_t RESERVED5[4];      /* 0x0664-0x0667 */
  __IO uint32_t TRXPTCL_CTL; /* 0x0668 TRX Protocol Control */

  uint8_t RESERVED6[4]; /* 0x066C-0x066F */

  /* Security (0x0670-0x0680) */
  __IO uint32_t CAMCMD;   /* 0x0670 CAM Command */
  __IO uint32_t CAMWRITE; /* 0x0674 CAM Write */
  __IO uint32_t CAMREAD;  /* 0x0678 CAM Read */
  __IO uint32_t CAMDBG;   /* 0x067C CAM Debug */
  __IO uint32_t SECCFG;   /* 0x0680 Security Configuration */

  uint8_t RESERVED7[12]; /* 0x0684-0x068F */

  /* Power Management (0x0690-0x06A8) */
  __IO uint16_t WOW_CTRL;    /* 0x0690 WoW Control */
  __IO uint8_t PS_RX_INFO;   /* 0x0692 Power Save RX Info */
  __IO uint8_t UAPSD_TID;    /* 0x0693 UAPSD TID */
  uint8_t RESERVED8[4];      /* 0x0694-0x0697 */
  __IO uint32_t WKFMCAM_CMD; /* 0x0698 Wake FM CAM Command */
  __IO uint32_t WKFMCAM_RWD; /* 0x069C Wake FM CAM Read/Write Data */
  __IO uint16_t RXFLTMAP0;   /* 0x06A0 RX Filter Map 0 */
  __IO uint16_t RXFLTMAP1;   /* 0x06A2 RX Filter Map 1 */
  __IO uint16_t RXFLTMAP2;   /* 0x06A4 RX Filter Map 2 */
  uint8_t RESERVED9[2];      /* 0x06A6-0x06A7 */
  __IO uint32_t BCN_PSR_RPT; /* 0x06A8 Beacon Parser Report */

  uint8_t RESERVED10[20]; /* 0x06AC-0x06BF */

  /* Coexistence & Beamforming (0x06C0-0x06FC) */
  __IO uint32_t BT_COEX_TABLE[9];   /* 0x06C0 BT Coexistence Table */
  __IO uint32_t BFMER0_INFO[2];     /* 0x06E4 Beamformer 0 Information */
  __IO uint32_t BFMER1_INFO[2];     /* 0x06EC Beamformer 1 Information */
  __IO uint32_t CSI_RPT_PARAM_BW20; /* 0x06F4 CSI Report Parameter BW20 */
  __IO uint32_t CSI_RPT_PARAM_BW40; /* 0x06F8 CSI Report Parameter BW40 */
  __IO uint32_t CSI_RPT_PARAM_BW80; /* 0x06FC CSI Report Parameter BW80 */

  /* Hardware Port 2 (0x0700-0x0718) */
  __IO uint32_t MACID1[2];     /* 0x0700 MAC ID 1 */
  __IO uint32_t BSSID1[2];     /* 0x0708 BSSID 1 */
  uint8_t RESERVED11[4];       /* 0x0710-0x0713 */
  __IO uint32_t BFMEE_SEL;     /* 0x0714 Beamformee Selection */
  __IO uint32_t SND_PTCL_CTRL; /* 0x0718 Sound Protocol Control */
} WiFi_WMAC_TypeDef;

typedef struct {
  WiFi_SYS_TypeDef SYS;     /* 0x0000-0x00FF */
  WiFi_MAC_TypeDef MAC;     /* 0x0100-0x01FF */
  WiFi_TXDMA_TypeDef TXDMA; /* 0x0200-0x027F */
  WiFi_RXDMA_TypeDef RXDMA; /* 0x0280-0x02FF */
  WiFi_LXBUS_TypeDef LXBUS; /* 0x0300-0x03FF */
  WiFi_PROT_TypeDef PROT;   /* 0x0400-0x047F */
  WiFi_EDCA_TypeDef EDCA;   /* 0x0500-0x05FF */
  WiFi_WMAC_TypeDef WMAC;   /* 0x0600-0x07FF */
} WiFi_TypeDef;

/* Peripheral memory map */
#define SPI_FLASH_BASE 0x08000000

#define SYSTEM_CTRL_BASE 0x40000000
#define PERI_ON_BASE (SYSTEM_CTRL_BASE + 0x200)

#define NCO1_REG_BASE 0x40000080
#define BACKUP_REG_BASE 0x40000138
#define NCO2_REG_BASE 0x4000026C
#define PINMUX_REG_BASE 0x40000280

#define GPIO_REG_BASE 0x40001000
#define TIMER_REG_BASE 0x40002000
#define VENDOR_REG_BASE 0x40002800
#define LOG_UART_REG_BASE 0x40003000
#define RTC_BASE 0x40003400
#define SPIC_CACHE_BASE 0x40003C00
#define ADC_REG_BASE 0x40010000
#define SPI_FLASH_CTRL_BASE 0x40020000
#define UART0_REG_BASE 0x40040000
#define UART1_REG_BASE 0x40040400
#define UART2_REG_BASE LOG_UART_REG_BASE
#define SPI0_REG_BASE 0x40042000
#define SPI1_REG_BASE 0x40042400
#define I2C0_REG_BASE 0x40044000
#define I2C1_REG_BASE 0x40044400
#define SDIO_DEVICE_REG_BASE 0x40050000
#define GDMA0_REG_BASE 0x40060000
#define GDMA1_REG_BASE 0x40061000
#define I2S0_REG_BASE 0x40062000
#define CRYPTO_REG_BASE 0x40070000
#define WIFI_REG_BASE 0x40080000
#define SIE_REG_BASE 0x400C0000
#define USOC_REG_BASE 0x400C2000

#define TIM0_BASE (TIMER_REG_BASE)
#define TIM1_BASE (TIMER_REG_BASE + 0x040)
#define TIM2_BASE (TIMER_REG_BASE + 0x080)
#define TIM3_BASE (TIMER_REG_BASE + 0x0C0)
#define TIM4_BASE (TIMER_REG_BASE + 0x100)
#define TIM5_BASE (TIMER_REG_BASE + 0x140)

/* Peripheral declaration */
// TODO: ida :)
// VENDOR_REG (base: 0x40002800)
// SDIO_DEVICE_REG (base: 0x40050000)
// WIFI_REG (base: 0x40080000)
// SIE_REG (base: 0x400C0000)

#define SYSTEM_CTRL ((SYSTEM_CTRL_TypeDef *)SYSTEM_CTRL_BASE)
#define PERI_ON ((PERI_ON_TypeDef *)PERI_ON_BASE)

#define UART0 ((UART_TypeDef *)UART0_REG_BASE)
#define UART1 ((UART_TypeDef *)UART1_REG_BASE)
#define UART2 ((UART_TypeDef *)LOG_UART_REG_BASE)
#define SPI0 ((SPI_TypeDef *)SPI0_REG_BASE)
#define SPI1 ((SPI_TypeDef *)SPI1_REG_BASE)
#define SPIC ((SPIC_TypeDef *)SPI_FLASH_CTRL_BASE)
#define ADC ((ADC_TypeDef *)ADC_REG_BASE)
#define I2C0 ((I2C_TypeDef *)I2C0_REG_BASE)
#define I2C1 ((I2C_TypeDef *)I2C1_REG_BASE)
#define GDMA0 ((GDMA_TypeDef *)GDMA0_REG_BASE)
#define GDMA1 ((GDMA_TypeDef *)GDMA1_REG_BASE)
#define I2S ((I2S_TypeDef *)I2S0_REG_BASE)
#define TIM0 ((RTIM_TypeDef *)TIM0_BASE)
#define TIM1 ((RTIM_TypeDef *)TIM1_BASE)
#define TIM2 ((RTIM_TypeDef *)TIM2_BASE)
#define TIM3 ((RTIM_TypeDef *)TIM3_BASE)
#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 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))

#define GPIO_COMMON ((GPIO_Common_TypeDef *)(GPIO_REG_BASE + 0x30))

/* rtl8711b_peri_on.h */
// 2 0x200 REG_PEON_PWR_CTRL
#define BIT_SOC_UAHV_EN (1 << 2)
#define BIT_SOC_UALV_EN (1 << 1)
#define BIT_SOC_USBD_EN (1 << 0)

// 2 0x210 REG_SOC_FUNC_EN
#define BIT_SOC_BOOT_FROM_JTAG (1 << 31)
#define BIT_SOC_UNLOCK_FROM_JTAG (1 << 30)
#define BIT_SOC_WAKE_FROM_PS (1 << 29)
#define BIT_SOC_PATCH_FUNC0 (1 << 28)
#define BIT_SOC_PATCH_FUNC1 (1 << 27)
#define BIT_SOC_PATCH_FUNC2 (1 << 26)

#define BIT_SOC_XMODEM_PAGE_PG (1 << 25)
#define BIT_SOC_XMODEM_FLASH_EMPTY (1 << 24)

#define BIT_SOC_SECURITY_ENGINE_EN (1 << 20)
#define BIT_SOC_GTIMER_EN (1 << 16)
#define BIT_SOC_GDMA1_EN (1 << 14)
#define BIT_SOC_GDMA0_EN (1 << 13)
#define BIT_SOC_LOG_UART_EN (1 << 12)
#define BIT_SOC_CPU_EN (1 << 8)
#define BIT_SOC_MEM_CTRL_EN (1 << 6)
#define BIT_SOC_FLASH_EN (1 << 4)
#define BIT_SOC_LXBUS_EN (1 << 2)
#define BIT_SOC_OCP_EN (1 << 1)
#define BIT_SOC_FUN_EN (1 << 0)

// 2 0x0214 REG_SOC_HCI_COM_FUNC_EN
#define BIT_SOC_HCI_WL_MACON_EN (1 << 16)
#define BIT_SOC_HCI_SM_SEL (1 << 13)
#define BIT_SOC_HCI_OTG_RST_MUX (1 << 5)
#define BIT_SOC_HCI_OTG_EN (1 << 4)
#define BIT_SOC_HCI_SDIOD_ON_RST_MUX (1 << 3)
#define BIT_SOC_HCI_SDIOD_OFF_EN (1 << 1)
#define BIT_SOC_HCI_SDIOD_ON_EN (1 << 0)

// 2 0x0218 REG_SOC_PERI_FUNC0_EN
#define BIT_PERI_I2S0_EN (1 << 24)
#define BIT_PERI_I2C1_EN (1 << 17)
#define BIT_PERI_I2C0_EN (1 << 16)
#define BIT_PERI_SPI1_EN (1 << 9)
#define BIT_PERI_SPI0_EN (1 << 8)
#define BIT_PERI_UART2_EN (1 << 2)
#define BIT_PERI_UART1_EN (1 << 1)
#define BIT_PERI_UART0_EN (1 << 0)

// 2 0x021C REG_SOC_PERI_FUNC1_EN
#define BIT_PERI_GPIO_EN (1 << 8)
#define BIT_PERI_ADC0_EN (1 << 0)

// 2 0x0220 REG_SOC_PERI_BD_FUNC0_EN
#define BIT_PERI_UART2_BD_EN (1 << 2)
#define BIT_PERI_UART1_BD_EN (1 << 1)
#define BIT_PERI_UART0_BD_EN (1 << 0)

// 2 0x0230 REG_PESOC_CLK_CTRL
#define BIT_SOC_SLPCK_BTCMD_EN (1 << 29)
#define BIT_SOC_ACTCK_BTCMD_EN (1 << 28)
#define BIT_SOC_ACTCK_GPIO_EN (1 << 24)
#define BIT_SOC_ACTCK_GDMA1_EN (1 << 18)
#define BIT_SOC_ACTCK_GDMA0_EN (1 << 16)
#define BIT_SOC_ACTCK_TIMER_EN (1 << 14)
#define BIT_SOC_ACTCK_LOG_UART_EN (1 << 12)
#define BIT_SOC_ACTCK_FLASH_EN (1 << 8)
#define BIT_SOC_ACTCK_VENDOR_REG_EN (1 << 6)
#define BIT_SOC_ACTCK_TRACE_EN (1 << 4)
#define BIT_SOC_CKE_PLFM (1 << 2)
#define BIT_SOC_CKE_OCP (1 << 0)

// 2 0x0234 REG_PESOC_PERI_CLK_CTRL0
#define BIT_SOC_ACTCK_SPI1_EN (1 << 18)
#define BIT_SOC_ACTCK_SPI0_EN (1 << 16)
#define BIT_SOC_ACTCK_UART1_EN (1 << 2)
#define BIT_SOC_ACTCK_UART0_EN (1 << 0)

// 2 0x0238 REG_PESOC_PERI_CLK_CTRL1
#define BIT_SOC_ACTCK_ADC_EN (1 << 24)
#define BIT_SOC_ACTCK_I2S_EN (1 << 16)
#define BIT_SOC_ACTCK_I2C1_EN (1 << 2)
#define BIT_SOC_ACTCK_I2C0_EN (1 << 0)

// 2 0x0240 REG_PESOC_HCI_CLK_CTRL0
#define BIT_SOC_ACTCK_OTG_EN (1 << 4)
#define BIT_SOC_ACTCK_SDIO_HST_EN \
  (1 << 2)  // SDIO_HST clock enable in CPU run mode
#define BIT_SOC_ACTCK_SDIO_DEV_EN \
  (1 << 0)  // SDIO_DEV clock enable in CPU run mode

/* REG_PESOC_CLK_SEL 0x0250 */
#define BIT_SHIFT_PESOC_UART1_SCLK_SEL 26
/* [27:26] uart1 rx clock, 01: osc 8m;   00: xtal;    10: xtal nco */
#define BIT_MASK_PESOC_UART1_SCLK_SEL 0x03
#define BIT_SHIFT_PESOC_UART0_SCLK_SEL 19
/* [20:19] uart0 rx clock, 01: osc 8m;   00: xtal;    10: xtal nco */
#define BIT_MASK_PESOC_UART0_SCLK_SEL 0x03

/* 1: enable to generate flash clock (with phase shift) divided by 500M pll
 * clock, HW detect this signal's rising edge to start the phase shift clock
 * division circuit. */
#define BIT_FLASH_CK_PS_DIV_EN (1 << 25)
/* 1: enable to generate flash clock (no phase shift) divided by 500M pll clock,
 * HW detect this signal's rising edge to start the no phase shift division
 * circuit. */
#define BIT_FLASH_CK_DIV_EN (1 << 24)
/* 1: delay flash sout for calibration;  0: bypass flash sout to spic */
#define BIT_FLASH_CAL_EN (1 << 23)
#define BIT_SHIFT_FLASH_CK_PS_INT 12
/* [14:12] Flash clock phase shift in units of 500M pll clock cycels */
#define BIT_MASK_FLASH_CK_PS_INT 0x03
/* ready flag of Flash clock with phase shift, Read only */
#define BIT_FLASH_PS_DIV_RDY (1 << 7)
/* ready flag of Flash clock, Read only */
#define BIT_FLASH_DIV_RDY (1 << 6)
#define BIT_SHIFT_PESOC_TRACE_CK_SEL 4
/* [5:4] "Trace clock select0: 12.5MH1: 25MHz2: 50MHz3: 100MHz" */
#define BIT_MASK_PESOC_TRACE_CK_SEL 0x03
/* "Only valid when r_FLASH_DIV_FRAC= 1, it decides the duty cycle of flash
 * clock when not divided by integer1: duty cycle > 50% ; 0: duty cycle < 50%"
 */
#define BIT_FLASH_DIV_HIGH_FRAC (1 << 3)
/* "Flash clock division ratio, fractional part0: no fraction, only divided by
 * integer set by bit[1:0],  1: 0.5" */
#define BIT_FLASH_DIV_FRAC (1 << 2)
#define BIT_SHIFT_DIV_INT 0
/* [1:0] "Flash clock division ratio, integrate part0: divided by 21: divided by
 * 32: divided by 43: divided by 5" */
#define BIT_MASK_FLASH_DIV_INT 0x03

// 0x0244 REG_PESOC_COM_CLK_CTRL1
#define BIT_SOC_ACTCK_SECURITY_ENG_EN (1 << 4)
// spec name is wrong (BIT_SOC_ACTCK_WL_EN)
#define BIT_SOC_ACTCK_LXBUS_EN (1 << 0)

// 0x02E0 REG_PON_PINMUX_CTRL
#define BIT_HCI_SDIOD_PIN_EN (1 << 0)

// 0x0304 REG_PESOC_SOC_CTRL
#define BIT_PESOC_LX_SLV_SWAP_SEL (1 << 10)
#define BIT_PESOC_LX_MST_SWAP_SEL (1 << 9)
#define BIT_PESOC_LX_WL_SWAP_SEL (1 << 8)

// 0x2FC REG_FW_PPROTECT_KEY_CTRL
#define BIT_RDP_EN (1 << 3) /* load from efuse */
#define BIT_RDP_EN_LOAD (1 << 2)
#define BIT_RDP_KEY_REQ (1 << 1)
#define BIT_OTF_KEY_REQ (1 << 0)

/* rtl8711b_pinmux.h */
#define _PA_0 (0x00)
#define _PA_1 (0x01)
#define _PA_2 (0x02)
#define _PA_3 (0x03)
#define _PA_4 (0x04)
#define _PA_5 (0x05)
#define _PA_6 (0x06)
#define _PA_7 (0x07)
#define _PA_8 (0x08)
#define _PA_9 (0x09)
#define _PA_10 (0x0A)
#define _PA_11 (0x0B)
#define _PA_12 (0x0C)
#define _PA_13 (0x0D)
#define _PA_14 (0x0E)
#define _PA_15 (0x0F)
#define _PA_16 (0x10)
#define _PA_17 (0x11)
#define _PA_18 (0x12)
#define _PA_19 (0x13)
#define _PA_20 (0x14)
#define _PA_21 (0x15)
#define _PA_22 (0x16)
#define _PA_23 (0x17)
#define _PA_24 (0x18)
#define _PA_25 (0x19)
#define _PA_26 (0x1A)
#define _PA_27 (0x1B)
#define _PA_28 (0x1C)
#define _PA_29 (0x1D)
#define _PA_30 (0x1E)
#define _PA_31 (0x1F)
#define _PB_0 (0x20)
#define _PB_1 (0x21)
#define _PB_2 (0x22)
#define _PB_3 (0x23)
#define _PB_4 (0x24)
#define _PB_5 (0x25)
#define _PB_6 (0x26)
#define _PB_7 (0x27)
#define _PB_8 (0x28)
#define _PNC (0xFFFFFFFF)

// PINMUX function modes
#define PINMUX_FN_GPIO 0x100      // Normal GPIO mode
#define PINMUX_FN_UART 0x101      // UART function
#define PINMUX_FN_SPIM 0x102      // SPI1 function (why diff function code?)
#define PINMUX_FN_SPIS 0x103      // SPI0 function
#define PINMUX_FN_SPIF 0x104      // SPI Flash interface
#define PINMUX_FN_I2C 0x105       // I2C function
#define PINMUX_FN_SDIO 0x106      // SDIO function
#define PINMUX_FN_PWM 0x107       // PWM
#define PINMUX_FN_TIMINPUT 0x107  // PWM
#define PINMUX_FN_SWD 0x108
#define PINMUX_FN_EXT32K 0x108
#define PINMUX_FN_RTCOUT 0x108
#define PINMUX_FN_SWD 0x108  // SWD/JTAG function
#define PINMUX_FN_I2S 0x109  // I2S function
#define PINMUX_FN_COEX_EXT32K 0x10a
#define PINMUX_FN_BTCOEX 0x10a
#define PINMUX_FN_WLLED 0x10a

#define PAD_DRV_STRENGTH_0 (0x00000000 << 9)
#define PAD_DRV_STRENGTH_1 (0x00000001 << 9)
#define PAD_DRV_STRENGTH_2 (0x00000002 << 9)
#define PAD_DRV_STRENGTH_3 (0x00000003 << 9)
#define PAD_DRV_STRENGTH_4 (0x00000004 << 9)
#define PAD_DRV_STRENGTH_5 (0x00000005 << 9)
#define PAD_DRV_STRENGTH_6 (0x00000006 << 9)
#define PAD_DRV_STRENGTH_7 (0x00000007 << 9)

static inline void PINMUX_Config(uint32_t pin, uint32_t func) {
  volatile uint32_t *reg = &PERI_ON->GPIO_PINMUX_CTRL[pin >> 1];
  uint32_t shift = (pin & 1) << 4;
  uint32_t mask = 0xFFFF << shift;
  *reg = (*reg & ~mask) | (func << shift);
}

static inline void PINMUX_ConfigPadPull(uint8_t pin, uint8_t pull_type) {
  uint32_t reg_index = pin >> 1;
  uint32_t bit_pos = (pin & 1) << 4;
  uint32_t mask = 0xC0U << bit_pos;

  PINMUX->PADCTR[reg_index] =
      (PINMUX->PADCTR[reg_index] & ~mask) | (pull_type << bit_pos);
}

/* rtl8711b_gpio.h */

/* GPIO_Pull_parameter_definitions */
#define GPIO_PuPd_NOPULL 0x00    // 00
#define GPIO_PuPd_SHUTDOWN 0x00  // 00
#define GPIO_PuPd_DOWN 0x80      // 10
#define GPIO_PuPd_UP 0x40        // 01

/* GPIO_INT_Trigger_parameter_definitions  */
#define GPIO_INT_Trigger_LEVEL 0x0 /*This interrupt is level trigger  */
#define GPIO_INT_Trigger_EDGE 0x1  /*This interrupt is edge trigger  */

#define IS_GPIOIT_LEVEL_TYPE(TYPE) \
  (((TYPE) == GPIO_INT_Trigger_LEVEL) || ((TYPE) == GPIO_INT_Trigger_EDGE))

/* GPIO_INT_Polarity_parameter_definitions */
/*Setting interrupt to low active: falling edge or low level  */
#define GPIO_INT_POLARITY_ACTIVE_LOW 0x0
/*Setting interrupt to high active: rising edge or high level */
#define GPIO_INT_POLARITY_ACTIVE_HIGH 0x1

#define IS_GPIOIT_POLARITY_TYPE(TYPE)          \
  (((TYPE) == GPIO_INT_POLARITY_ACTIVE_LOW) || \
   ((TYPE) == GPIO_INT_POLARITY_ACTIVE_HIGH))

/* GPIO_INT_Debounce_parameter_definitions */
#define GPIO_INT_DEBOUNCE_DISABLE 0x0 /*Disable interrupt debounce */
#define GPIO_INT_DEBOUNCE_ENABLE 0x1  /*Enable interrupt debounce */

#define IS_GPIOIT_DEBOUNCE_TYPE(TYPE)       \
  (((TYPE) == GPIO_INT_DEBOUNCE_DISABLE) || \
   ((TYPE) == GPIO_INT_DEBOUNCE_ENABLE))

/* rtl8711b_rcc.h */

/* 0x230 REG_PESOC_CLK_CTRL */
#define APBPeriph_GPIO_CLOCK (BIT_SOC_ACTCK_GPIO_EN)
#define APBPeriph_GDMA1_CLOCK (BIT_SOC_ACTCK_GDMA1_EN)
#define APBPeriph_GDMA0_CLOCK (BIT_SOC_ACTCK_GDMA0_EN)
#define APBPeriph_GTIMER_CLOCK (BIT_SOC_ACTCK_TIMER_EN)
#define APBPeriph_LOGUART_CLOCK (BIT_SOC_ACTCK_LOG_UART_EN)
#define APBPeriph_FLASH_CLOCK (BIT_SOC_ACTCK_FLASH_EN)
#define APBPeriph_VENDOR_REG_CLOCK (BIT_SOC_ACTCK_VENDOR_REG_EN)
#define APBPeriph_TRACE_CLOCK (BIT_SOC_ACTCK_TRACE_EN)

/* 0x210 REG_SOC_FUNC_EN */
#define APBPeriph_SECURITY_ENGINE BIT_SOC_SECURITY_ENGINE_EN
#define APBPeriph_GTIMER BIT_SOC_GTIMER_EN
#define APBPeriph_GDMA1 BIT_SOC_GDMA1_EN
#define APBPeriph_GDMA0 BIT_SOC_GDMA0_EN
#define APBPeriph_FLASH BIT_SOC_FLASH_EN
#define APBPeriph_LXBUS BIT_SOC_LXBUS_EN

#endif
