/*-------------------------------------------------------------------------------------------------
--
-- File Name    : coaxpressDevice.h



-- Description  : This module replicates the CoaXPress Device interface functionality.




-- Targeted device : Microchip FPGAs
-- Author          : India Solutions Team




--
-- COPYRIGHT 2023 BY MICROCHIP
-- THE INFORMATION CONTAINED IN THIS DOCUMENT IS SUBJECT TO LICENSING RESTRICTIONS
-- FROM MICROCHIP CORP.  IF YOU ARE NOT IN POSSESSION OF WRITTEN AUTHORIZATION FROM
-- MICROCHIP FOR USE OF THIS FILE, THEN THE FILE SHOULD BE IMMEDIATELY DESTROYED AND
-- NO BACK-UP OF THE FILE SHOULD BE MADE.
--



-------------------------------------------------------------------------------------------------*/

#ifndef COAXPRESSDEVICE_H
#define COAXPRESSDEVICE_H

#define CAM_CONFIG_4K_1_2M_1  1

#define LINE_SCAN	0
#define DEF_RATE    0x38 //0x38 - 3.125Gbps
#define NEW_RATE    0x58 //  0x28 - 1.25Gbps    0x30 - 2.5Gbps  //0x40 - 5Gbps     //0x48 - 6.25Gbps //0x50 - 10Gbps //0x58 - 12.5Gbps

#define DUAL_STREAM_ENABLE 1

enum manufacturer_reg
{
		WidthReg                   = 0x00100010,
		HeightReg                  = 0x00100014,
        OffsetXReg                 = 0x00100018,
        OffsetYReg                 = 0x0010001C,
		PixelFormatReg             = 0x00100024,
        DeviceTapGeometryReg       = 0x00100050,
		IMG1StreamIDReg            = 0x00100054,
		IMGNStreamIDReg            = 0x00100058,
		StreamIDSelectReg          = 0x0010005C,
		AcquisitionStartReg        = 0x00100100,
		AcquisitionStopReg         = 0x00100104,
		AcquisitionFrameRateReg    = 0x00100110,
		AcquisitionModeReg         = 0x0010011c,
		AcquisitionFrameRateMaxReg = 0x00100120,
		SensorWidthReg             = 0x00100150,
		SensorHeightReg            = 0x00100154,
		WidthMaxReg                = 0x00100158,
		HeightMaxReg               = 0x0010015C,
		PatternReg                 = 0x00100160,
		GainReg                    = 0x00100164,
        ReverseXReg                = 0x00100168,
        ReverseYReg                = 0x0010016C,
		ConnectionConfigDefaultReg = 0x00100200,
		TLPLockReg                 = 0x0010f000,

		//manufacturer specific boot strap registers
		Start_of_manufacturer_specific_register_space = 0x00006000,

		XML_ADD   = 0x00007000,
		XML_REQ   = 0x00008100,
};

#define COAXPRESS_DEVICE_APB_BASE_ADDRESS        (0x71000000)

enum device_apb_reg
{
    CMD_RATE_SEL_ADDR         = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x00,
    CMD_WRITE_ADDRESS         = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x08,
    LSUC_RX_SW_PKT_VAL        = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x0C,    
    CMD_READ_ADDRESS          = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x10,
    
    CMD_HB_EN_ADDR            = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x30,
    CMD_HB_ID_ADDR            = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x34,
    
    //Stream1
    CMD_DISP_PSIZE_ADDR       = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x40,
    CMD_DISP_XSIZE_ADDR       = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x44,
    CMD_DISP_YSIZE_ADDR       = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x48,
    CMD_DISP_DSIZE_ADDR       = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x4C,
    CMD_PIXEL_FORMAT_ADDR     = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x50,
    STREAM_EN                 = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x54,
	
	//Stream2
	CMD2_DISP_PSIZE_ADDR      = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x60,
    CMD2_DISP_XSIZE_ADDR      = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x64,
    CMD2_DISP_YSIZE_ADDR      = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x68,
    CMD2_DISP_DSIZE_ADDR      = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x6C,
    CMD2_PIXEL_FORMAT_ADDR    = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x70,
    STREAM2_EN                = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x74,
    
    TestModeReg               = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x20,
    TestPacketCountTxReg      = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x24,
    TestPacketCountRxReg      = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x28,
    TestErrorCountReg         = COAXPRESS_DEVICE_APB_BASE_ADDRESS+0x2C,

};


#define CXP_DEV_XCVR_BASE   0x60000000UL
// XVCR Register Offsets
#define DES_CDR_CTRL_2		0x01041008
#define DES_CDR_CTRL_3		0x0104100c
#define DES_DFEEM_CTRL_1	0x01041010
#define DES_DFEEM_CTRL_2	0x01041014
#define DES_DFEEM_CTRL_3	0x01041018
#define DES_DFE_CTRL_2		0x01041024
#define DES_EM_CTRL_2		0x0104102c
#define DES_RXPLL_DIV		0x01041040
#define DES_RSTPD			0x0104104c
#define SER_CLK_CTRL		0x01041074
#define SER_RSTPD			0x01041078

#define SERDES_RTL_CTRL		0x010410c0
#define DES_DFE_CAL_CTRL_0	0x010410d0
#define DES_DFE_CAL_CTRL_1	0x010410d4
#define DES_DFE_CAL_CTRL_2	0x010410d8
#define DES_DFE_CAL_CMD		0x010410dc

#define TXPLL_DIV_1			0x01050010
#define TXPLL_DIV_2			0x01050014

#define WIDTH_MAX       3840
#define HEIGHT_MAX      2160
#if CAM_CONFIG_4K_1_2M_1
#define WIDTH		3840
#define HEIGHT		2160
#else
#define WIDTH		1920
#define HEIGHT		1080
#endif

#define CONTROL_CMD_WITHOUT_TAG 					0x02020202
#define CONTROL_CMD_WITH_TAG 						0x05050505
#define CONTROL_ACK_WITHOUT_TAG 					0x03030303
#define CONTROL_ACK_WITH_TAG 						0x06060606
#define CONTROL_CMD_READ	       					0x00000000
#define CONTROL_CMD_WRITE       					0x01000000
#define ACK_CMD_EXEC_OK_APPEND_REPLY				0x00000000
#define ACK_CMD_EXEC_OK_NO_APPEND_REPLY				0x01010101
#define ACK_CMD_INVALID_DATA_FOR_ADDRESS			0x41414141
#define ACK_CMD_INVALID_CONTROL_OPERATION			0x42424242
#define ACK_CMD_WRITE_ATTEMPT_TO_READONLY_ADDRESS	0x43434343
#define START_OF_THE_PACKET 						0xfbfbfbfb
#define END_OF_THE_PACKET 							0xfdfdfdfd


//Pixel format
#define BAYER_BG8	0x0311
#define BAYER_RG8	0x0321
#define BAYER_GB8	0x0331
#define YCBCR_422_8	0x0621

//Acquisition modes
#define ACQUISITION_MODE_SINGLE 		0
#define ACQUISITION_MODE_MULTIPLE 	    1
#define ACQUISITION_MODE_CONTINUOUS 	2

#define MAX_CONTROL_PACKET_SIZE			132
#define MAX_FRAME_COUNT					30

//Magic number is an approximation of �CoaXPress� which is indication that Device implements the CoaXPress standard
#define COAXPRESS_STANDARD				0xC0A79AE5

//VersionsSupported bits set
#define COAXPRESS_VERBIT_1DOT0			0x1		//bit 0
#define COAXPRESS_VERBIT_1DOT1			0x2		//bit 1
#define COAXPRESS_VERBIT_2DOT0			0x4		//bit 2
#define COAXPRESS_VERBIT_2DOT1			0x8		//bit 3
#define COAXPRESS_VERBIT_1DOT1_2DOT0	0x6		//bit 1 & 2

//VersionUsed  MSB 16bits - integer value, LSB 16bits - fraction value
#define COAXPRESS_VER_1DOT0			0x00010000
#define COAXPRESS_VER_1DOT1			0x00010001
#define COAXPRESS_VER_2DOT0			0x00020000
#define COAXPRESS_VER_2DOT1			0x00020001

#define COAXPRESS_VER_2DOT5_SUBVER2		0x2<<16|0x5<<8|0x2
#define COAXPRESS_VER_1DOT1_SUBVER0		0x1<<16|0x1<<8|0x0

#define NUM_CONNECTIONS		1<<16   //one connection

//Configuring different rates 1.25G, 2.5G, 3.125G, 5.0G, 6.25G, 10.0G, 12.5G
#define RATE_1DOT25G	0x28
#define RATE_2DOT5G		0x30
#define RATE_3DOT125G	0x38
#define RATE_5DOT0G		0x40
#define RATE_6DOT25G	0x48
#define RATE_10DOT0G	0x50
#define RATE_12DOT5G	0x58

void CoaxpressDeviceInit();
void CoaxpressDeviceMain();

void dataFromHostToDevice(uint32_t bs_reg_address, uint32_t data);
uint32_t dataFromDeviceToHost(uint32_t resp_size, uint32_t bs_reg_address, uint32_t count);
void sendPacketDataFromDevice(uint32_t ack_code, uint32_t count);
void update_cxp_xcvr_uplink_speed(uint8_t data);

extern uint32_t reply_acknowledge_cmd;
extern uint32_t control_cmd_tag_status;
extern uint32_t control_cmd_tag;
extern uint32_t control_cmd_read_write;
extern uint32_t control_cmd_size;
extern uint32_t control_cmd_address;
extern uint32_t control_cmd_data;

extern uint8_t def_rate;

extern uint8_t Pattern_st;
extern uint8_t pattern_en;
extern uint8_t ReverseX_st;
extern uint8_t reversex_en;
extern uint8_t ReverseY_st;
extern uint8_t reversey_en;
extern uint32_t Gain_st;
extern uint8_t gain_en;
extern uint32_t TLP_lock_st;
extern uint8_t width_en;
extern uint32_t width_reg_st;
extern uint8_t height_en;
extern uint32_t height_reg_st;

#endif  //#ifndef COAXPRESSDEVICE_H
