/**************************************************************************************************
*******
**************************************************************************************************/


#ifndef _LL_HW_DRV_H_
#define _LL_HW_DRV_H_

#include "types.h"
#include "ll_def.h"
#include "bus_dev.h"
#include "rf_phy_driver.h"

// LL_HW_REGISTER_ADDRESS
#define BB_HW_BASE 					        	0x40030000			//BB_HW Base address
#define LL_HW_BASE 					        	0x40031000			//LL_HW Base address
#define LL_HW_TFIFO 		                	(LL_HW_BASE+0x400)
#define LL_HW_RFIFO 		                	(LL_HW_BASE+0xC00)

#define LL_HW_WRT_EMPTY_PKT			        	*(volatile uint32_t *)(LL_HW_TFIFO) = 0x00000001

//LL_HW_MODE
#define LL_HW_STX 				                0x0000
#define LL_HW_SRX 			                    0x0001

#define LL_HW_TRX			                    0x0010
#define LL_HW_RTX                               0x0012

#define LL_HW_TRLP                              0x0020
#define LL_HW_TRLP_EMPT		                    0x0022

#define LL_HW_RTLP                              0x0030
#define LL_HW_RTLP_1ST                          0x0031
#define LL_HW_RTLP_EMPT		                    0x0032

#define HCLK16M

//#define LL_HW_CYCLES_PER_US    			CYCLES_PER_US
#ifdef HCLK16M
#define LL_HW_HCLK_PER_US    						16 				//
#define LL_HW_HCLK_PER_US_BITS    					4 			
#else
#define LL_HW_HCLK_PER_US    						32 				//
#define LL_HW_HCLK_PER_US_BITS                      5
#endif

#define LL_HW_FIFO_MARGIN 					        70				//


// LL_HW_IRQ_STATUS
#define LIRQ_MD                                 0x0001              //bit00
#define LIRQ_CERR                               0x0002              //bit01
#define LIRQ_RTO                                0x0004              //bit02
#define LIRQ_RFULL                              0x0008              //bit03
#define LIRQ_RHALF                              0x0010              //bit04
#define LIRQ_BIT5                               0x0020              //bit05
#define LIRQ_BIT6                               0x0040              //bit06
#define LIRQ_BIT7                               0x0080              //bit07
#define LIRQ_TD                                 0x0100              //bit08
#define LIRQ_RD                                 0x0200              //bit09
#define LIRQ_COK                                0x0400              //bit10
#define LIRQ_CERR2                              0x0800              //bit11
#define LIRQ_LTO                                0x1000              //bit12
#define LIRQ_NACK                               0x2000              //bit13
#define LIRQ_BIT14                              0x4000              //bit14
#define LIRQ_BIT15                              0x8000              //bit15

#define LL_HW_IRQ_MASK 							0x3FFF				//total 14bit

// LL_HW_RFIFO_CTRL
#define LL_HW_IGN_EMP 							0x0001				//bit0
#define LL_HW_IGN_CRC 							0x0002				//bit1
#define LL_HW_IGN_SSN 							0x0004 				//bit2
#define LL_HW_IGN_ALL							0x0007 				//bit2
#define LL_HW_IGN_NONE							0x0000 				

// LL_MD_RX_INI
#define LL_HW_MD_RX_SET0 						0x4000				//set md_rx ini=0 and md_rx_soft=0
#define LL_HW_MD_RX_SET1 						0x4440				//set md_rx ini=1 and md_rx_soft=1

//LL FIFO DEPTH CONFIG
#define LL_HW_FIFO_TX_2K_RX_2K                  0x0200              //TX FIFO 512 Word 
#define LL_HW_FIFO_TX_3K_RX_1K                  0x0300              //TX FIFO 768 Word 
#define LL_HW_FIFO_TX_1K_RX_3K                  0x0100              //TX FIFO 256 Word 

//BB CRC Format Setting
#define LL_HW_CRC_BLE_FMT                       0x02
#define LL_HW_CRC_ZB_FMT                        0x03
#define LL_HW_CRC_16_FMT                        0x04
#define LL_HW_CRC_NULL                          0x00


//ANT SWITCH SLOT
#define LL_HW_ANT_WIN_1us                       4
#define LL_HW_ANT_SW_CTE_OFF                    0x00
#define LL_HW_ANT_SW_CTE_AUTO                   0x01
#define LL_HW_ANT_SW_TX_MANU                    0x02
#define LL_HW_ANT_SW_RX_MANU                    0x04

//CTE Supplement Config
#define CTE_SUPP_AUTO                           0xC0
#define CTE_SUPP_LEN_SET                        0x00
#define CTE_SUPP_NULL                           0x00

#define CONNLESS_CTE_TYPE_AOA                   0x00
#define CONNLESS_CTE_TYPE_AOD_1us               0x01
#define CONNLESS_CTE_TYPE_AOD_2us               0x02
#define CONN_CTE_TYPE_AOA                   	0x01
#define CONN_CTE_TYPE_AOD_1us               	0x02
#define CONN_CTE_TYPE_AOD_2us               	0x04


// 2020-01-21 add for CONN CTE REQ TYPE
#define CTE_REQ_TYPE_AOA						0x00
#define CTE_REQ_TYPE_AOD_1US					0x01
#define CTE_REQ_TYPE_AOD_2US					0x02

#define BLE_HEAD_WITH_CTE(x)                   (((x & 0x20)==0x00) ? 0:1)


    
void     ll_hw_set_stx(void);
void     ll_hw_set_srx(void);
void     ll_hw_set_trx(void);
void     ll_hw_set_rtx(void);
void     ll_hw_set_trlp(uint8_t snNesn,uint8_t txPktNum,uint8_t rxPktNum,uint8_t mdRx);
void     ll_hw_set_rtlp(uint8_t snNesn,uint8_t txPktNum,uint8_t rxPktNum,uint8_t mdRx,uint32_t rdCntIni);
void     ll_hw_set_rtlp_1st(uint8_t snNesn,uint8_t txPktNum,uint8_t rxPktNum,uint8_t mdRx);
void	 ll_hw_config(uint8_t ll_mode,uint8_t snNesn,uint8_t txPktNum,uint8_t rxPktNum,uint8_t mdRx,uint32_t rdCntIni);



void     ll_hw_go(void);
void     ll_hw_trigger(void);
void     ll_hw_clr_irq(void);
void     ll_hw_set_irq(uint32_t mask);
void     ll_hw_set_empty_head(uint16_t txHeader);
void     ll_hw_set_rx_timeout_1st(uint32_t rxTimeOut);    
void     ll_hw_set_rx_timeout(uint32_t rxTimeOut);    
void     ll_hw_set_tx_rx_release(uint16_t txTime,uint16_t rxTime);
void     ll_hw_set_rx_tx_interval(uint32_t intvTime);
void     ll_hw_set_tx_rx_interval(uint32_t intvTime);
void 	 ll_hw_set_trx_settle(uint8_t tmBb,uint8_t tmAfe,uint8_t tmPll);
void     ll_hw_set_loop_timeout(uint32_t loopTimeOut);
void     ll_hw_set_loop_nack_num(uint8_t nAckNum);
void 	 ll_hw_set_timing(uint8_t pktFmt);

void     ll_hw_set_tfifo_space(uint16 space);

void     ll_hw_set_ant_switch_mode(uint8_t mode);
void     ll_hw_set_ant_switch_timing(uint8_t antWin,uint8_t antDly);
void     ll_hw_set_ant_pattern(uint32_t ant1, uint32_t ant0);

void     ll_hw_set_cte_rxSupp(uint8_t rxSupp);
void     ll_hw_set_cte_txSupp(uint8_t txSupp);
uint8_t  ll_hw_get_iq_RawSample(uint16_t* p_iSample, uint16_t* p_qSample);


void     ll_hw_rst_rfifo(void);
void     ll_hw_rst_tfifo(void);

void     ll_hw_ign_rfifo(uint8_t ignCtrl);

void 	 ll_hw_get_tfifo_info(int* rdPtr,int* wrPtr,int* wrDepth);
void 	 ll_hw_get_rfifo_info(int* rdPtr,int* wrPtr,int* rdDepth);
void  	 ll_hw_get_rxPkt_stats(uint8_t *crcErrNum,uint8_t *rxTotalNum,uint8_t *rxPktNum);

uint8_t  ll_hw_read_rfifo(uint8_t* rxPkt, uint16_t* pktLen, uint32_t* pktFoot0, uint32_t* pktFoot1);
uint8_t  ll_hw_read_rfifo_zb(uint8_t* rxPkt, uint16_t* pktLen, uint32_t* pktFoot0, uint32_t* pktFoot1);
uint8_t  ll_hw_read_rfifo_pplus(uint8_t* rxPkt, uint16_t* pktLen, uint32_t* pktFoot0, uint32_t* pktFoot1);

uint8_t  ll_hw_write_tfifo(uint8_t* rxPkt, uint16_t pktLen);

void     ll_hw_set_crc_fmt(uint8_t txCrc,uint8_t rxCrc);
void     ll_hw_set_pplus_pktfmt(uint8_t plen);

uint8_t	 ll_hw_get_snNesn(void);
uint8_t	 ll_hw_get_txAck(void);
uint8_t	 ll_hw_get_nAck(void);
uint8_t  ll_hw_get_rxPkt_num(void);
uint32_t ll_hw_get_anchor(void);
uint32_t ll_hw_get_irq_status(void);
uint8_t  ll_hw_get_fsm_status(void);
uint8_t  ll_hw_get_last_ack(void);
uint32_t ll_hw_get_loop_cycle(void);

uint8_t  ll_hw_get_rxPkt_Total_num(void);
uint8_t  ll_hw_get_rxPkt_CrcErr_num(void);
uint8_t  ll_hw_get_rxPkt_CrcOk_num(void);

uint8_t  ll_hw_get_iq_RawSample(uint16_t* p_iSample, uint16_t* p_qSample);

uint8_t  ll_hw_update_rtlp_mode(uint8_t llMode);
uint8_t  ll_hw_update_trlp_mode(uint8_t llMode);
uint8_t  ll_hw_update(uint8_t llMode,uint8_t *txAck,uint8_t *rxRec,uint8_t *snNesn);


void     byte_to_bit(uint8_t byteIn,uint8_t* bitOut);
void     bit_to_byte(uint8_t* bitIn,uint8_t * byteOut);
void     zigbee_crc16_gen(uint8_t *dataIn,int length,uint8_t *seed,uint8_t *crcCode);


//  copy from rf.h by Zeng jiaping
void set_tx_rx_mode(uint8_t mode);

void set_channel(uint32_t  channel);

void set_access_address( uint32_t  access);
void set_crc_seed(uint32_t  seed);
void set_whiten_seed(uint32_t channel);

void set_max_length(uint32_t length);

void calculate_whiten_seed(void);


#endif
