/******************************************************************************
*
* Revision: A
* Author: MAW
* Created:  17 Jan 2018
*
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*  FILE: IMX290.h
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*
* DESCRIPTION: Header file to define functions for the IMX290 CMOS imager.
*
*
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*	Copyright (c) 2018, Metrohm Raman
* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/

#ifndef _IMX290_H_
#define _IMX290_H_

/* Time for 1 horizontal line. */
#define IMX290_1H_TIME                  59.2e-6
#define IMX290_MIN_WINWV                304

/* I2C Address */
#define IMX290_ADDR                     0x1A

/* Registers */
/* Standby */
#define IMX290_STANDBY                  0x3000
#define IMX290_STANDBY_RUN              0x00
#define IMX290_STANDBY_STANDBY          0x01

/* Set to prevent register updates at frame reflection time. */
#define IMX290_REGHOLD                  0x3001
#define IMX290_REGHOLD_ON               0x01
#define IMX290_REGHOLD_OFF              0x00

/* Master mode control */
#define IMX290_XMSTA                    0x3002
#define IMX290_XMSTA_START              0x00
#define IMX290_XMSTA_STOP               0x01

/* 500 nS reset delay.  Self-clearing */
#define IMX290_SW_RESET                 0x3003
#define IMX290_SW_RESET_ACTIVE          0x01

#define IMX290_ADBIT                    0x3005
#define IMX290_ADBIT_10B                0x00
#define IMX290_ADBIT_12B                0x01
/* Init for no reversal, full frame, 12 bit. */
#define IMX290_ADBIT_INIT               0x01

#define IMX290_IMAGE_MODES              0x3007
#define IMX290_IMAGE_MODES_VREVERSE     0x01
#define IMX290_IMAGE_MODES_HREVERSE     0x02
#define IMX290_IMAGE_MODES_1080MODE     0x00
#define IMX290_IMAGE_MODES_720MODE      0x10
#define IMX290_IMAGE_MODES_CROPMODE     0x40

#define IMX290_RATE_GAIN                0x3009
#define IMX290_RATE_GAIN_120FPS         0x00
#define IMX290_RATE_GAIN_60FPS          0x01
#define IMX290_RATE_GAIN_30FPS          0x02
#define IMX290_RATE_GAIN_FDG_HIGH       0x10
#define IMX290_RATE_GAIN_FDG_LOW        0x00
#define IMX290_RATE_GAIN_INIT_HIGH      0x12
#define IMX290_RATE_GAIN_INIT_LOW       0x02

/* BLK_LEVEL is 9 bits across 0x300A and 0x300B */
#define IMX290_BLK_LEVEL                0x300A
#define IMX290_BLK_LEVEL_INIT           0x08

#define IMX290_0x300E                   0x300E
#define IMX290_0x300E_INIT              0x00
#define IMX290_0x300F                   0x300F
#define IMX290_0x300F_INIT              0x00
#define IMX290_0x3010                   0x3010
#define IMX290_0x3010_INIT              0x21
#define IMX290_0x3012                   0x3012
#define IMX290_0x3012_INIT              0x64
#define IMX290_0x3013                   0x3013
#define IMX290_0x3013_INIT              0x00

/* Gain in 0.3 dB steps.  Up to 0x64 is analog
 * gain. From 0x64 to 0xF0 is combined digital
 * and analog gain.
 */
#define IMX290_GAIN                     0x3014
#define IMX290_GAIN_INIT                0x64

#define IMX290_0x3016                   0x3016
#define IMX290_0x3016_INIT              0x09
/* IMX290 is little-endian */
/* Note: VMAX is 17 bits wide */
#define IMX290_VMAX_LOW                 0x3018
#define IMX290_VMAX_MID                 0x3019
#define IMX290_VMAX_HIGH                0x3020
#define IMX290_VMAX_INIT_1080P          0x465

/* IMX290 is little-endian */
/* Note: HMAX is 16 bits wide */
#define IMX290_HMAX_LOW                 0x301C
#define IMX290_HMAX_HIGH                0x301D
#define IMX290_HMAX_INIT                0x1130

/* IMX290 is little-endian */
/* Integration time in H units. 18 Bits wide.
 * Sets the shutter sweep time. 1 to
 * (number of lines per frame - 2)
 */
#define IMX290_SHS1_LOW                 0x3020
#define IMX290_SHS1_MID                 0x3021
#define IMX290_SHS1_HIGH                0x3022
#define IMX290_SHS1_INIT                0xFF


/* Crop Vertical direction effective OB */
#define IMX290_WINWV_OB                 0x303A
#define IMX290_WINWV_OB_INIT            0x08

/* IMX290 is little-endian */
/* Crop window vertical posistion, 11 bits. */
#define IMX290_WINPV_LOW                0x303C
#define IMX290_WINPV_HIGH               0x303D

/* Crop window vertical size, 11 bits. */
#define IMX290_WINWV_LOW                0x303E
#define IMX290_WINWV_HIGH               0x303F

/* IMX290 is little-endian */
/* Crop window horizontal position, 11 Bits.
 * must be divisible by 4. */
#define IMX290_WINPH                    0x3040

/* Crop window horizontal size, 11 bits.
 * Must be divisible by 4. */
#define IMX290_WINWH_LOW                0x3042
#define IMX290_WINWH_HIGH               0x3043

#define IMX290_RESOLUTION_PORT_SEL      0x3046
#define IMX290_RESOLUTION_10B           0x00
#define IMX290_RESOLUTION_12B           0x01
#define IMX290_PORT_CMOS_PARALLEL       0x00
#define IMX290_PORT_2CH_LVDS            0xD0
#define IMX290_PORT_4CH_LVDS            0xE0
#define IMX290_PORT_8CH_LVDS            0xF0
#define IMX290_RESOLUTION_PORT_SEL_INIT 0xD1

/* XVS low level pulse width */
#define IMX290_XVSLNG                   0x3048
#define IMX290_XVSLNG_1H                0x00
#define IMX290_XVSLNG_2H                0x10
#define IMX290_XVSLNG_4H                0x20
#define IMX290_XVSLNG_8H                0x30

/* XHS low level pulse width */
#define IMX290_XHSLNG                   0x3049
#define IMX290_XVSLNG_0                 0x00
#define IMX290_XVSLNG_1                 0x10
#define IMX290_XVSLNG_2                 0x20
#define IMX290_XVSLNG_3                 0x30

/* Set pin behavior for VS and HS pins */
#define XVS_XHS_OUTSEL                  0x304B
#define XVS_OUTSEL_HIGH                 0x00
#define XVS_OUTSEL_VSYNC                0x02
#define XHS_OUTSEL_HIGH                 0x00
#define XHS_OUTSEL_HSYNC                0x08

/* Incksel init values set for 37.125MHz */
#define IMX290_INCKSEL1                 0x305C
#define IMX290_INCKSEL1_INIT            0x18
#define IMX290_INCKSEL2                 0x305D
#define IMX290_INCKSEL2_INIT            0x00
#define IMX290_INCKSEL3                 0x305E
#define IMX290_INCKSEL3_INIT            0x20
#define IMX290_INCKSEL4                 0x305F
#define IMX290_INCKSEL4_INIT            0x01

#define IMX290_0x3070                   0x3070
#define IMX290_0x3070_INIT              0x02
#define IMX290_0x3071                   0x3071
#define IMX290_0x3071_INIT              0x11
#define IMX290_0x309B                   0x309B
#define IMX290_0x309B_INIT              0x10
#define IMX290_0x309C                   0x309C
#define IMX290_0x309C_INIT              0x22
#define IMX290_0x30A2                   0x30A2
#define IMX290_0x30A2_INIT              0x02
#define IMX290_0x30A6                   0x30A6
#define IMX290_0x30A6_INIT              0x20
#define IMX290_0x30A8                   0x30A8
#define IMX290_0x30A8_INIT              0x20
#define IMX290_0x30AA                   0x30AA
#define IMX290_0x30AA_INIT              0x20
#define IMX290_0x30AC                   0x30AC
#define IMX290_0x30AC_INIT              0x20
#define IMX290_0x30B0                   0x30B0
#define IMX290_0x30B0_INIT              0x43
#define IMX290_0x3119                   0x3119
#define IMX290_0x3119_INIT              0x9E
#define IMX290_0x311C                   0x311C
#define IMX290_0x311C_INIT              0x1E
#define IMX290_0x311E                   0x311E
#define IMX290_0x311E_INIT              0x08
#define IMX290_0x3128                   0x3128
#define IMX290_0x3128_INIT              0x05

#define IMX290_ADBIT1                   0x3129
#define IMX290_ADBIT1_INIT_10B          0x1D
#define IMX290_ADBIT1_INIT_12B          0x00

#define IMX290_0x313D                   0x313D
#define IMX290_0x313D_INIT              0x83
#define IMX290_0x3150                   0x3150
#define IMX290_0x3150_INIT              0x03

#define IMX290_INCKSEL5                 0x315E
#define IMX290_INCKSEL5_INIT            0x1A
#define IMX290_INCKSEL6                 0x3164
#define IMX290_INCKSEL6_INIT            0x1A

#define IMX290_ADBIT2                   0x317C
#define IMX290_ADBIT2_INIT_10B          0x12
#define IMX290_ADBIT2_INIT_12B          0x00

#define IMX290_0x317E                   0x317E
#define IMX290_0x317E_INIT              0x00

#define IMX290_ADBIT3                   0x31EC
#define IMX290_ADBIT3_INIT_10B          0x37
#define IMX290_ADBIT3_INIT_12B          0x0E

#define IMX290_0x32B8                   0x32B8
#define IMX290_0x32B8_INIT              0x50
#define IMX290_0x32B9                   0x32B9
#define IMX290_0x32B9_INIT              0x10
#define IMX290_0x32BA                   0x32BA
#define IMX290_0x32BA_INIT              0x00
#define IMX290_0x32BB                   0x32BB
#define IMX290_0x32BB_INIT              0x04
#define IMX290_0x32C8                   0x32C8
#define IMX290_0x32C8_INIT              0x50
#define IMX290_0x32C9                   0x32C9
#define IMX290_0x32C9_INIT              0x10
#define IMX290_0x32CA                   0x32CA
#define IMX290_0x32CA_INIT              0x00
#define IMX290_0x32CB                   0x32CB
#define IMX290_0x32CB_INIT              0x04
#define IMX290_0x332C                   0x332C
#define IMX290_0x332C_INIT              0xD3
#define IMX290_0x332D                   0x332D
#define IMX290_0x332D_INIT              0x10
#define IMX290_0x332E                   0x332E
#define IMX290_0x332E_INIT              0x0D
#define IMX290_0x3358                   0x3358
#define IMX290_0x3358_INIT              0x06
#define IMX290_0x3359                   0x3359
#define IMX290_0x3359_INIT              0xE1
#define IMX290_0x335A                   0x335A
#define IMX290_0x335A_INIT              0x11
#define IMX290_0x3360                   0x3360
#define IMX290_0x3360_INIT              0x1E
#define IMX290_0x3361                   0x3361
#define IMX290_0x3361_INIT              0x61
#define IMX290_0x3362                   0x3362
#define IMX290_0x3362_INIT              0x10
#define IMX290_0x33B0                   0x33B0
#define IMX290_0x33B0_INIT              0x50
#define IMX290_0x33B2                   0x33B2
#define IMX290_0x33B2_INIT              0x1A
#define IMX290_0x33B3                   0x33B3
#define IMX290_0x33B3_INIT              0x04

/* Bits 4 and 5 are active in REPETITION. For CSI-2 */
#define IMX290_REPETITION               0x3405

/* 6 Bits.*/
#define IMX290_OPB_SIZE_V               0x3414

/* Y OUT SIZE 13 BITS */
#define IMX290_Y_OUT_SIZE               0x3418

/* IMX290 is little-endian */
/* EXTCLK_FREQ 16 Bits */
#define IMX290_EXTCLK_FREQ_LOW          0x3444
#define IMX290_EXTCLK_FREQ_HIGH         0x3445
#define IMX290_EXTCLK_FREQ_37_125M      0x2520
#define IMX290_EXTCLK_FREQ_74_250M      0x4A40

/* 0x3446 - 0x3454 Global Timing settings */

/* Horizontal direction effective pixel width setting.
 * default 0x079C (1948) */
#define X_OUT_SIZE                      0x3472

#define IMX290_INCKSEL7                 0x3480
#define IMX290_INCKSEL7_INIT            0x49

/* Functions */
extern void IMX290_Power(bool control);
extern bool IMX290_Init(void);
extern bool IMX290_Write(uint16_t reg_addr, uint8_t value);
/* Write specified number of bytes to the register up to I2C_BUFF_SIZE-2 */
extern bool IMX290_MultiWrite(uint16_t reg_addr, uint8_t *values, uint8_t numBytes);
/* Read specified number of bytes from the register up to I2C_BUFF_SIZE */
extern bool IMX290_MultiRead(uint16_t reg_addr, uint8_t *values, uint8_t numBytes);
extern uint8_t IMX290_Read(uint16_t reg_addr);
extern void IMX_290_Reset(void);
extern bool IMX290_Start(void);
extern void IMX290_AcquireSpectrum(float IntTime);
extern bool IMX290_ReadSpectrum(void);
extern bool IMX290_SetWindow(uint16_t xStart, uint16_t xSize, uint16_t yStart, uint16_t ySize);
extern void IMX290_RegWrite(uint16_t reg_addr, uint8_t LSB_Position,  uint8_t Field_Width, uint32_t New_Value);

#endif

/******************************************************************************
* Done.
*/
