#ifndef _YC11XX_H_
#define _YC11XX_H_

#include "type.h"
#include "btreg.h"


#ifdef __cplusplus
extern "C" {
#endif

#ifndef  OS_ENTER_CRITICAL
#define OS_ENTER_CRITICAL __disable_irq
#define OS_EXIT_CRITICAL __enable_irq
#endif

/* -------------------------  Interrupt Number Definition  ------------------------ */


/** @addtogroup Configuration_of_CMSIS
  * @{
  */


/* ================================================================================ */
/* ================      Processor and Core Peripheral Section     ================ */
/* ================================================================================ */


/** @} */ /* End of group Configuration_of_CMSIS */
typedef enum 
{
/* -------------------  Cortex-M0 Processor Exceptions Numbers  -------------------                                                                 */
			Reset_IRQn                    = -15,              /*!<   1  Reset Vector, invoked on Power up and warm reset                  */
			NonMaskableInt_IRQn           = -14,              /*!<   2  Non maskable Interrupt, cannot be stopped or preempted         */
    	HardFault_IRQn                = -13,              /*!<   3  Hard Fault, all classes of Fault                                                 */
    	SVCall_IRQn                   =  -5,              /*!<  11  System Service Call via SVC instruction                                  */
    	DebugMonitor_IRQn             =  -4,              /*!<  12  Debug Monitor    	*/
    	PendSV_IRQn                   =  -2,              /*!<  14  Pendable request for system service                                       */
    	SysTick_IRQn                  =  -1,              /*!<  15  System Tick Timer                                                                */
/* ---------------------  xx Specific Interrupt Numbers  --------------------                                                                     */
			usb_handler_IRQn              =   0,
			iicd_handler_IRQn             =   1,
			qspi_handler_IRQn             =   2,
			spid_handler_IRQn             =   3,
			uart_handler_IRQn             =   4,
			uartb_handler_IRQn            =   5,
			adcd_handler_IRQn             =   6,
			i2s_handler_IRQn              =   7,
			bt_handler_IRQn               =   8,
			gpio0_handler_IRQn            =   9,
			gpio8_handler_IRQn            =   17,
			gpio9_handler_IRQn            =   18,
			gpio10_handler_IRQn            =   19,
			gpio11_handler_IRQn            =   20,
			gpio12_handler_IRQn            =   21,
			gpio13_handler_IRQn            =   22,
			gpio14_handler_IRQn            =   23,
			gpio15_handler_IRQn            =   24,
			gpio16_handler_IRQn            =   25,
			gpio17_handler_IRQn            =   26,
			gpio18_handler_IRQn            =   27,
			gpio19_handler_IRQn            =   28,
			gpio20_handler_IRQn            =   29,
			gpio21_handler_IRQn            =   30,
			gpio22_handler_IRQn            =   31,
} IRQn_Type;

/* ----------------Configuration of the Cortex-M0 Processor and Core Peripherals---------------- */
/** @} */ /* End of group Configuration_of_CMSIS */



//******************************************************************************************
//start define reg address
//******************************************************************************************

#define CORE_DMA_START                       0x800A
#define CORE_RESET                           0x8010
#define CORE_OTP_RDATA						 0x8047
                                        


#define CORE_ADCD_DELAY                      0x803A
#define CORE_ADCD_CTRL                       0x803B
#define CORE_ADCD_SADDR                      0x803C
#define CORE_ADCD_EADDR                      0x803E
#define CORE_CLKSEL							 0x8042
#define CORE_CONFIG                          0x8043
#define CORE_UART_CLKSEL                     0x8043
#define CORE_OTP_ADDR						 0x8044
#define CORE_OTP_DIN						 0x8046
#define CORE_OTP_CTRL						 0x8047
#define CORE_OTP_RXADDR						 0x8048
#define CORE_OTP_RXLEN						 0x804a

#define CORE_CLKOFF                          0x8050
#define CORE_UART_BAUD                       0x8052
#define CORE_UART_RX_SADDR                   0x8054
#define CORE_UART_RX_EADDR                   0x8056
#define CORE_UART_RX_RPTR                    0x8058
#define CORE_UART_TX_SADDR                   0x805A
#define CORE_UART_TX_EADDR                   0x805C
#define CORE_UART_TX_WPTR                    0x805E
#define CORE_UART_CTRL                       0x8060
#define CORE_GPIO_KEY0                       0x8061
#define CORE_GPIO_KEY1                       0x8062
#define CORE_GPIO_KEY2                       0x8063
#define CORE_SUM_EN                          0x8063
                                         
                                         
#define CORE_UARTB_CTRL                      0x8071
#define CORE_UARTB_BAUD                      0x8072
#define CORE_UARTB_RX_SADDR                  0x8074
#define CORE_UARTB_RX_EADDR                  0x8076
#define CORE_UARTB_RX_RPTR                   0x8078
#define CORE_UARTB_TX_SADDR                  0x807A
#define CORE_UARTB_TX_EADDR                  0x807C
#define CORE_UARTB_TX_WPTR                   0x807E
#define CORE_GPIO_CONF                       0x8080
#define CORE_QSPI_CTRL				         0x80A0
#define CORE_QSPI_DELAY                      0x80A1
#define CORE_QSPI_TXLEN			             0x80A2
#define CORE_QSPI_TXADDR			         0x80A4
#define CORE_QSPI_RXADDR			         0x80A6
#define CORE_QSPI_RXLEN			             0x80A8
#define CORE_IICD_CTRL				         0x80AA
#define CORE_IICD_SCL_LOW                    0x80AB
#define CORE_IICD_SCL_HIGH                   0x80AC
#define CORE_IICD_START_SETUP                0x80AD
#define CORE_IICD_START_HOLD                 0x80AE
#define CORE_IICD_STOP_SETUP                 0x80AF
#define CORE_IICD_DATA_SETUP                 0x80B0
#define CORE_IICD_DATA_HOLD                  0x80B1
#define CORE_IICD_TXLEN			             0x80B2
#define CORE_IICD_TXADDR			         0x80B4
#define CORE_IICD_RXADDR			         0x80B6
#define CORE_IICD_RXLEN			             0x80B8
#define CORE_SPID_CTRL				         0x80BA
#define CORE_SPID_DELAY                      0x80BB
#define CORE_SPID_TXLEN			             0x80BC
#define CORE_SPID_TXADDR			         0x80BE
#define CORE_SPID_RXADDR			         0x80C0
#define CORE_SPID_RXLEN			             0x80C2


                                          
#define CORE_PWM0_PCNT                       0x80CD
#define CORE_PWM0_NCNT                       0x80CF
#define CORE_PWM0_CTRL				         0x80D1
#define CORE_PWM1_PCNT                       0x80D2
#define CORE_PWM1_NCNT                       0x80D4
#define CORE_PWM1_CTRL				         0x80D6
#define CORE_PWM2_PCNT                       0x80D7
#define CORE_PWM2_NCNT                       0x80D9
#define CORE_PWM2_CTRL				         0x80Db
#define CORE_PWM3_PCNT                       0x80Dc
#define CORE_PWM3_NCNT                       0x80DE
#define CORE_PWM3_CTRL				         0x80e0
#define CORE_PWM4_PCNT                       0x80E1
#define CORE_PWM4_NCNT                       0x80E3
#define CORE_PWM4_CTRL				         0x80E5 
#define CORE_PWM5_PCNT                       0x80E6
#define CORE_PWM5_NCNT                       0x80E8
#define CORE_PWM5_CTRL				         0x80Ea
#define CORE_PWM6_PCNT                       0x80Eb
#define CORE_PWM6_NCNT                       0x80Ed
#define CORE_PWM6_CTRL				         0x80ef
#define CORE_PWM7_PCNT                       0x80f0
#define CORE_PWM7_NCNT                       0x80f2
#define CORE_PWM7_CTRL				         0x80f4

#define CORE_MIC_HPF                         0x8114
#define CORE_MIC_HPF_CTRL              	 	 0x8115
#define CORE_CLKN                            0x8300                                     
#define CORE_UART_STATUS                     0x830C
#define CORE_UART_RBAUD                      0x830C
#define CORE_UART_TX_ITEMS                   0x830E
#define CORE_UART_TX_RPTR                    0x8310
#define CORE_UART_RX_ITEMS                   0x8312
#define CORE_UART_RX_WPTR                    0x8314
#define CORE_ADCD_ADDR                       0x8316
#define CORE_GPIO_IN                         0x831C
#define CORE_GPIO_IN1                        0x831D
#define CORE_SPID_REMAIN                     0x8324
#define CORE_QSPI_REMAIN                     0x8328
#define CORE_ADC_IN                          0x832C
#define CORE_DMA_STATUS                      0x8330
#define CORE_GPIO_WAKEUP_LOW                 0x8342
#define CORE_GPIO_WAKEUP_HIGH                0x8346
                                          
#define CORE_SUMDATA                         0x8352
#define CORE_UARTB_STATUS                    0x8354
#define CORE_UARTB_RBAUD                     0x8354
#define CORE_UARTB_TX_ITEMS                  0x8356
#define CORE_UARTB_TX_RPTR                   0x8358
#define CORE_UARTB_RX_ITEMS                  0x835A
#define CORE_UARTB_RX_WPTR                   0x835C
                                                         
                                         
                                       
                                          
#define RFEN_ADC                             0x8906
#define RF_ADC_MODE                          0x8971
#define RF_ADC_GC                            0x8972
#define RF_ADC_CH                            0x8973
#define RFEN_CHGPUMP						 0x8973
                                                                               
                                        
#define CORE_USB_CONFIG		                 0x8C00
#define CORE_USB_INT_MASK	                 0x8C01
#define CORE_USB_ADDR                        0x8C04
#define CORE_USB_TRIG	                     0x8C10
#define CORE_USB_STALL		                 0x8C11
#define CORE_USB_CLEAR		                 0x8C12
#define CORE_USB_EP                          0x8C18
#define CORE_USB_DFIFO0                      0x8C18
#define CORE_USB_DFIFO1                      0x8C19
#define CORE_USB_DFIFO2                      0x8C1A
#define CORE_USB_EP_LEN                      0x8C20
#define CORE_USB_STATUS		                 0x8C26
#define CORE_USB_FIFO_EMPTY                  0x8C27
#define CORE_USB_FIFO_FULL                   0x8C28


//************************************************************************************************
//end define reg address
//************************************************************************************************

//*****************************************************************************
//config gpio selected function
//*****************************************************************************
#define  GPCFG_INPUT						0  
#define  GPCFG_QSPI_NCS        	2  
#define  GPCFG_QSPI_SCK        	3  
#define  GPCFG_QSPI_IO0        	4  
#define  GPCFG_QSPI_IO1        	5  
#define  GPCFG_QSPI_IO2        	6  
#define  GPCFG_QSPI_IO3        	7  
#define  GPCFG_UART_TXD        	8  
#define  GPCFG_UART_RXD        	9  
#define  GPCFG_UART_RTS        	10 
#define  GPCFG_UART_CTS        	11 
#define  GPCFG_UARTB_TXD       	12 
#define  GPCFG_UARTB_RXD       	13 
#define  GPCFG_UARTB_RTS       	14 
#define  GPCFG_UARTB_CTS       	15 
#define  GPCFG_PWM_OUT0        	16 
#define  GPCFG_PWM_OUT1        	17 
#define  GPCFG_PWM_OUT2        	18 
#define  GPCFG_PWM_OUT3        	19 
#define  GPCFG_PWM_OUT4        	20 
#define  GPCFG_PWM_OUT5        	21 
#define  GPCFG_PWM_OUT6        	22 
#define  GPCFG_PWM_OUT7        	23 
#define  GPCFG_I2S_DOUT        	24 
#define  GPCFG_I2S_LRCKOUT     	25 
#define  GPCFG_I2S_CLKOUT      	26 
#define  GPCFG_I2S_DIN         	28 
#define  GPCFG_I2S_LRCKIN      	29 
#define  GPCFG_I2S_CLKIN       	30 
#define  GPCFG_SPID_MISO       	31 
#define  GPCFG_SPID_NCS        	32 
#define  GPCFG_SPID_SCK        	33 
#define  GPCFG_SPID_MOSI       	34 
#define  GPCFG_SPID_SDIO       	35  
#define  GPCFG_QDEC_X0         	38 
#define  GPCFG_QDEC_X1         	39 
#define  GPCFG_QDEC_Y0         	40 
#define  GPCFG_QDEC_Y1         	41 
#define  GPCFG_QDEC_Z0         	42 
#define  GPCFG_QDEC_Z1         	43 
#define  GPCFG_IIC_SCL         	44 
#define  GPCFG_IIC_SDA        	45 
#define  GPCFG_JTAG_SWCLK      	60 
#define  GPCFG_JTAG_SWDAT      	61
#define  GPCFG_OUTPUT_LOW      	62 
#define  GPCFG_OUTPUT_HIGH     	63
#define  GPCFG_PULLUP			0x40 
#define  GPCFG_PULLDOWN        	0x80 
#define  GPCFG_NO_IE           	0xc0
//*****************************************************************************
//end config gpio selected function
//*****************************************************************************


/**
  *@brief GPIO number.
  */
typedef enum
{
	GPIO_0 = 0,
	GPIO_1,
	GPIO_2,
	GPIO_3,
	GPIO_4,
	GPIO_5,
	GPIO_6,
	GPIO_7,
	GPIO_8,
	GPIO_9,
	GPIO_10,
	GPIO_11,
	GPIO_12,
	GPIO_13,
	GPIO_14,
	GPIO_15,
	GPIO_16,
	GPIO_17,
	GPIO_18,
	GPIO_19,
	GPIO_20,
	GPIO_21,
	GPIO_22,
	GPIO_23,
	GPIO_24,
	GPIO_25,
	GPIO_26,
	GPIO_27,
	GPIO_28,
	GPIO_29,
	GPIO_30,
	GPIO_31,
	GPIO_MAX_NUM,
	GPIO_ACTIVE_BIT=0x80,
}GPIO_NUM;


//*************************************************************************************
//interrupt id
//*************************************************************************************
#define	USB_INTID			0
#define	IICD_INTID		1
#define	QSPI_INTID		2
#define	SPID_INTID		3
#define	UART_INTID		4
#define	UARTB_INTID		5
#define	ADCD_INTID		6
#define	I2S_INTID			7
#define	BT_INTID			8
//*************************************************************************************
//end interrupt id
//*************************************************************************************


#define reg_map(reg)						((int)(reg) | 0x10000000)
#define reg_map_m0(reg)					((int)(reg) | 0x10010000)
#define PREFETCH_LINE(addr)			*(volatile int*)0x20000000 = addr
#define des_ctrl								*(volatile uint8_t*)0x30000002
#define des_key(x)							*(volatile uint8_t*)(0x30000003 + x)
#define des_in(x)								*(volatile uint8_t*)(0x30000018 + x)
#define crypt_status						*(volatile uint8_t*)0x30010000
#define des_out(x)							*(volatile uint8_t*)(0x30010004 + x)
#define des_start								*(volatile uint8_t*)0x30008000
#define rsa_exp(x)							*(volatile int32_t*)(0x30020000 + x*4)
#define rsa_out(x)							*(volatile int32_t*)(0x30020000 + x*4)
#define rsa_in(x)								*(volatile int32_t*)(0x30020080 + x*4)
#define rsa_mod(x)							*(volatile int32_t*)(0x30020100 + x*4)
#define rsa_ctrl								*(volatile int32_t*)0x30020180

#define TRACE_FIFO				      *(volatile int*)0xe0002020
#define NVIC_ISER				        *(volatile int*)0xe000e100
#define NVIC_ICER				        *(volatile int*)0xe000e180
	

static inline void enable_intr(int intid)   { NVIC_ISER |= 1 << intid;}
static inline void disable_intr(int intid)  { NVIC_ICER |= 1 << intid;}
#define CPU_MHZ        (48*1000000)
/* SysTick registers */  
/* SysTick control & status */ 
#define INITCPU_SYST_CSR     ((volatile unsigned int *)0xE000E010)
/* SysTick Reload value */ 
#define INITCPU_SYST_RVR     ((volatile unsigned int *)0xE000E014)
/* SysTick Current value */ 
#define INITCPU_SYST_CVR     ((volatile unsigned int *)0xE000E018)
/* SysTick CSR register bits */ 
#define INITCPU_SYST_CSR_COUNTFLAG (1 << 16)
#define INITCPU_SYST_CSR_CLKSOURCE (1 << 2)
#define INITCPU_SYST_CSR_TICKINT   (1 << 1)
#define INITCPU_SYST_CSR_ENABLE    (1 << 0)



typedef unsigned char byte;
typedef unsigned short word;

void _nop(void) __attribute__((optimize("O0")));

#define TO_16BIT_ADDR(A) (((int)A)&0xFFFF)

#define HREAD(reg)		*(volatile byte*)(reg_map(reg))
#define HREADW(reg)		(int)HREAD(reg) | HREAD(reg + 1) << 8
#define HWRITE(reg, val)	HREAD(reg) = (byte)(val)
#define HWRITEW(reg, val)	do { HWRITE(reg, (int)(val));HWRITE(reg + 1, (int)(val) >> 8); }while(0)

#define HWRITE24BIT(reg,val) do { HWRITE(reg, (int)(val));HWRITE(reg + 1, (int)(val) >> 8); HWRITE(reg + 2, (int)(val) >> 16); }while(0)
//#define HWOR(reg, val)	HWRITE(reg, HREAD(reg) | (val))

#define HREADL(reg)		(int)(HREAD(reg)) | (HREAD(reg + 1) << 8)| (HREAD(reg + 2) << 16)| (HREAD(reg + 3) << 24)

#define HWOR(reg, val)	HWRITE(reg, ((HREAD(reg) )| (val)))
#define HWCOR(reg, val)	HWRITE(reg, HREAD(reg) & ~(val))

//#define SETBIT(reg, val)	HWRITE(reg, HREAD(reg) | (val))
//#define CLRBIT(reg, val)	HWRITE(reg, HREAD(reg) & ~(val))

#define BW(addr) (int)*(addr) << 24 | (int)*(addr + 1) << 16 | (int)*(addr + 2) << 8 | *(addr + 3)

#define HREAD32(reg)		(uint32_t)(HREAD(reg) | HREAD(reg + 1) << 8|HREAD(reg + 2) << 16| HREAD(reg + 3) << 24)
#define HWRITE32(reg,val) do { HWRITE(reg, (uint32_t)(val));HWRITE(reg + 1, (uint32_t)(val) >> 8); HWRITE(reg + 2, (uint32_t)(val) >> 16); HWRITE(reg + 3, (uint32_t)(val) >> 24);}while(0)


static inline void hw_delay()
{
	__asm__ __volatile__("nop");
	__asm__ __volatile__("nop");
	__asm__ __volatile__("nop");
	__asm__ __volatile__("nop");
	__asm__ __volatile__("nop");
}


/***********************************CONFIG**********************************************/
#define BASE_ADDR                                   			0x10000000
#define CONFIG_UART_TXD                                    0x08
#define CONFIG_UART_RXD                                    0x09
#define CONFIG_UART_RTS                                    0x0a
#define CONFIG_UART_CTS                                    0x0b
#define CONFIG_UARTB_TXD                                   0x0C
#define CONFIG_UARTB_RXD                                   0x0D
#define CONFIG_UARTB_RTS                                   0x0E
#define CONFIG_UARTB_CTS                                   0x0F

/***********************************MEM CONFIG*******************************************/
/***************************UART A CONFIG BUFF***************************/
#define UART_A_RX_BUFF_START   0x1800
#define UART_A_TX_BUFF_START   0x1900
#define UART_A_RX_BUFF_END     0x18ff
#define UART_A_TX_BUFF_END     0x19ff

/***************************UART B CONFIG BUFF***************************/
#define UART_B_RX_BUFF_START   0x1a00
#define UART_B_TX_BUFF_START   0x1b00
#define UART_B_RX_BUFF_END     0x1aff
#define UART_B_TX_BUFF_END     0x1bff

/***************************RING CONFIG BUFF***************************/
#define RING_RX_BUFF_START   0x4B00
#define RING_TX_BUFF_START   0x4D00
#define RING_RX_BUFF_END     0x4Cff
#define RING_TX_BUFF_END     0x4Eff

/***********************************REG*************************************************/
#define REG_CLOCK_SELECT_RW_11BIT                  0x10008042
#define REG_CONFIG_RW_H5BIT                        0x10008043
#define REG_CLOCK_OFF_1_RW_8BIT                    0x10008050
#define REG_CLOCK_OFF_2_RW_8BIT                    0x10008051
#define REG_GPIO_CONFIG(X)                   			(0x10008080+(X))
/* ----------------UART---------------- */
#define REG_UART_A_BAUD_RATE_RW_15BIT              0x10008052
#define REG_UART_A_RX_START_ADDR_RW_16BIT          0x10008054
#define REG_UART_A_RX_END_ADDR_RW_16BIT            0x10008056
#define REG_UART_A_RX_RPTR_RW_16BIT                0x10008058
#define REG_UART_A_TX_START_ADDR_RW_16BIT          0x1000805A
#define REG_UART_A_TX_END_ADDR_RW_16BIT            0x1000805C
#define REG_UART_A_TX_WPTR_RW_16BIT                0x1000805E
#define REG_UART_A_CONTROL_RW_8BIT                 0x10008060

#define REG_UART_B_BAUD_RATE_RW_15BIT              0x10008072
#define REG_UART_B_RX_START_ADDR_RW_16BIT          0x10008074
#define REG_UART_B_RX_END_ADDR_RW_16BIT            0x10008076
#define REG_UART_B_RX_RPTR_RW_16BIT                0x10008078
#define REG_UART_B_TX_START_ADDR_RW_16BIT          0x1000807A
#define REG_UART_B_TX_END_ADDR_RW_16BIT            0x1000807C
#define REG_UART_B_TX_WPTR_RW_16BIT                0x1000807E
#define REG_UART_B_CONTROL_RW_8BIT                 0x10008071

#define REG_UART_A_STATE_R_4BIT                    0x1000810C
#define REG_UART_A_DET_BAUD_R_8BIT                 0x1000810D
#define REG_UART_A_TX_ITEMS_R_16BIT                0x1000810E
#define REG_UART_A_TX_RPTR_R_16BIT                 0x10008110
#define REG_UART_A_RX_ITEMS_R_16BIT                0x10008112
#define REG_UART_A_RX_RPTR_R_16BIT                 0x10008114

#define REG_UART_B_STATE_R_4BIT                    0x10008152
#define REG_UART_B_DET_BAUD_R_8BIT                 0x10008153
#define REG_UART_B_TX_ITEMS_R_16BIT                0x10008154
#define REG_UART_B_TX_RPTR_R_16BIT                 0x10008156
#define REG_UART_B_RX_ITEMS_R_16BIT                0x10008158
#define REG_UART_B_RX_RPTR_R_16BIT                 0x1000815A


#define REG_M0_LOCK_FLAG_RW_16BIT                  0x10004A00
#define REG_BT_LOCK_FLAG_R_16BIT                   0x10004A02
#define REG_LOCK_VICTIM(X)                         (0x10004A04+(X))
#define REG_RING_RX_START_ADDR_RW_16BIT            0x10004A14
#define REG_RING_RX_END_ADDR_RW_16BIT              0x10004A16
#define REG_RING_RX_RPTR_RW_16BIT                  0x10004A18
#define REG_RING_TX_START_ADDR_RW_16BIT            0x10004A1a
#define REG_RING_TX_END_ADDR_RW_16BIT              0x10004A1c
#define REG_RING_TX_WPTR_RW_16BIT                  0x10004A1e

//#define REG_RING_TX_S_ITEMS_R_16BIT               0x10004A20
#define REG_RING_TX_S_RPTR_R_16BIT                	0x10004A20
//#define REG_RING_RX_S_ITEMS_R_16BIT               0x10004A24
#define REG_RING_RX_S_RPTR_R_16BIT                	0x10004A22

#ifndef __RTOS__
#define SystemCoreClock 24000000
#endif
#define M0_MEMORY_BASE  0x10010000

#define _ALIGN_SIZE 4


#define GPIO_CONFIG(x)			*(volatile uint8_t*)((0x10000000|CORE_GPIO_CONF) + x)
#ifdef __cplusplus
}
#endif


#endif //_YC11XX_H