#ifndef __WLP_INTERFACE_H__
#define __WLP_INTERFACE_H__

/** @file
 * @brief WLP SDK main header file
 * @author zhouty@dspchina.com
*/
 
#include <windows.h>

#define WLP_SUCCESS					0				/**< The function succeeded. Output data is valid. */
#define WLP_SUCC_PARTIAL			1				/**< The function succeeded. However, output has been truncated. */
#define WLP_ERR_NOT_FOUND			0x80000001		/**< No free WLP basic device with the specified serial number was found. */
#define WLP_ERR_DUPLICATE			0x80000002		/**< The WLP is already in use.  */
#define WLP_ERR_INIT				0x80000003		/**< WLP device initialization failed.  */
#define WLP_ERR_RESET				0x80000004		/**< WLP device initialization failed. Toggle reset switch and try again.  */
#define WLP_ERR_HDEVICE				0x80000005		/**< The device handle is invalid.  */
#define WLP_ERR_MT					0x80000006		/**< Multi threading: Another concurrently executed function denies this call. */
#define WLP_ERR_HALT				0x80000007		/**< The device has been halted. Resume it using WlpDevControl.  */
#define WLP_ERR_PARAM				0x80000008		/**< An argument has an invalid value.  */
#define WLP_ERR_USB					0x80000009		/**< USB write read error. */
#define WLP_NO_MEM					0x8000000A		/**< System memory not enough. */
#define WLP_ERR_START_DMD			0x8000000B		/**< The device has been started. halt it using WlpDevControl.  */
#define WLP_ERR_FRAME_FREQ			0x8000000C		/**< Set frame freq fail. May be error dmdtype or write to device fail .*/
#define WLP_ERR_DMDTYPE				0x8000000D		/**< Unknow dmdtype or set dmdtype to device error.*/
#define WLP_ERR_GRAY				0x8000000E		/**< unknow dev gray or set gray to device error.*/
#define WLP_ERR_DISPLAY_MODE		0x8000000F		/**< unknow dev display mode or set mode to device error.*/



//Control / query type
#define WLP_DEV_STATUS				0x00000000		/**< device status.*/
#define WLP_DEV_HALT				0x00000001		/**< halt device ,you can use WLP_DEV_DMD_START to restart it.*/
#define WLP_DEV_DRIVER_VER			0x00000002		/**< Device driver  version information.*/
#define WLP_DEV_FIRMWARE_DATA		0x00000003		/**< Version information of the USB controller firmware.*/
#define WLP_DEV_SERIAL				0x00000004		/**< Serial number of the WLP.*/




/** Configure WLP basic to use another DMD type. 
*	Parameter type: ULONG 
* - WLP_DMDTYPE_1080P_095A, 
* - WLP_DMDTYPE_XGA_07A, 
* - WLP_DMDTYPE_XGA_055A,   
*/
#define WLP_DEV_DMD_TYPE			0x00000005													
#define WLP_DEV_VERSION				0x00000006		/**< Read the WLP hardware version.*/
#define WLP_DEV_DDC_VERSION			0x00000007		/**< Read the DDC chipset version.*/
#define WLP_DEV_FLOAT				0x00000008		/**< float  DMD mirrors when power down.*/
#define WLP_DEV_DMD_STOP			0x00000009		/**< stop dmd. */
#define	WLP_DEV_DMD_START			0x0000000A		/**< start or resume dmd .*/
#define WLP_DEV_DMD_RESET			0x0000000B		/**< reset dmd .*/
#define WLP_DEV_RESET				0x0000000D		/**< reset device .*/
#define WLP_DEV_FRAME_FREQ			0x0000000E		/**< frame freq.*/
#define WLP_DEV_GRAY				0x0000000F		/**< gray of per frame.*/
#define WLP_DEV_DDR_SIZE			0x00000010		/**< DMD ddr memory size*/
#define WLP_DEV_FRAME_DOWNLOAD_ADDR 0x00000011		/**< set frame download addr. It is align in 512 byte.*/
#define WLP_DEV_TRIGGER_SETTING		0x00000012		/**< set frame display mode.*/
#define WLP_DEV_SIGNAL				0x00000013		/**< Analog hardware signal.*/
#define WLP_DEV_FRAME_CNT			0x00000014		/**< frame count.*/
#define WLP_DEV_NS_FLIP			    0x00000015		/**<  */    // LF
#define WLP_DEV_COMP_DATA			0x00000016		/**<  */    // LF

#define WLP_DEV_STATUS_ALLBITS		0x000000017		/**< device status.*/  // LF


/** @brief enum DMD type*/
#define WLP_DMDTYPE_UNKNOWN			0x00000000		/**< unknow dmd type.*/
#define WLP_DMDTYPE_1080P_095A		0x00000001		/**< 1080p */
#define WLP_DMDTYPE_XGA_07A			0x00000002		/**< .7 dlp mirror */
#define WLP_DMDTYPE_XGA_055A		0x00000003		/**< .55 dlp mirror */
#define WLP_DMDTYPE_DISCONNECT		255

#define WLP_TRIGGER_DISABLE			0x00000000		/**< ignore external or software trigger signal.*/
#define WLP_TRIGGER_ENABLE			0x00000001		/**< trigger is enable.*/



/** @brief enmu trigger mode */
#define WLP_TRIGGER_SINGLE_FRAME	0x00000000		/**< one trigger for one frame mode.*/
#define WLP_TRIGGER_FRAMES			0x00000002		/**< one trigger display all frames and then auto stop ,or stop by trigger.*/
#define WLP_TRIGGER_FRAMES_AND_AUTOSTOP	0x00000004		/**< display all frames  and ignore all trigger signal before it's auto stop.*/
#define WLP_TRIGGER_LOOP			0x00000006		/**< loop display all frames, at the end of the stream,first frame will be showed again.*/



/** @brief enmu output sync signal mode */
#define WLP_SYNC_ALL_FRAMES			0x00000000		/**< signal out after display all frames.*/
#define WLP_SYNC_SINGLE_FRAME		0x00000008		/**< signal out after display every frame.*/

#define WLP_INFINITE				0xFFFFFFFF
typedef ULONG WLP_HDEVICE;



/** @brief Version number about this SDK */
struct WLP_VERSION { 
   SHORT main;										/**< main version .*/
   SHORT build;										/**< build version .*/
}; 




#ifdef __cplusplus
extern "C" {
#endif

/**
 *	Open the WLP basic device. The returned handle *hDevice is used to identify this device in 
 *	subsequent function calls. If non-zero the device with the serial number specified by 
 *	DeviceNum is allocated. If DeviceNum is 0 (zero) then the first free device is used.
 *	Release the device after usage using the function WlpDevFree. 
 * \param DeviceNum Serial number of the device to allocate or 0 (zero) 
 * \param hDevice Out pointer to an WLP device handle variable 
 * \return Return value maybe: \n
 * 	- WLP_SUCCESS 
 *	- WLP_ERR_NOT_FOUND 
 *	- WLP_ERR_MT 
 *	- WLP_NO_MEM 
 */

LONG WlpDevAlloc(ULONG DeviceNum, WLP_HDEVICE *hDevice) ;


/**
 *	Init the WLP basic device.Before you use dev, you must use this function to 
 *  init the device.Otherwise the device maybe work in unknown status.
 *  \param hDevice	device handle returned by WlpDevAlloc.
 *	\param pDevInit point to device init struct.
 *
 *	\return Return value maybe:\n
 *
 *	- WLP_SUCCESS
 *	- WLP_ERR_HANDLE
 *	- WLP_ERR_DMDTYPE
 *	- WLP_ERR_FRAME_FREQ
 *	- WLP_ERR_GRAY
 *
 */
 


typedef struct {

	ULONG dmdtype;			/**< device dmdtype, more infomation looking discription on WlpDevControl.*/

	/**< device frame freq, more infomation looking discription on WlpDevControl.
 * The min value of frame_freq is 1.
 * for .7:
 * gray = 1: max frame_freq = 20000 / 1;
 * gray = 2; max frame_freq = 20000 / 2 ^ 2;
 * gray = 4; max frame_freq = 20000 / 2 ^ 4;
 * gray = 6; max frame_freq = 20000 / 2 ^ 6;
 * gray = 8; max frame_freq = 20000 / 2 ^ 8;
 * for .95:
*/

	ULONG frame_freq;
	ULONG gray;				/**< device gray, more infomation looking discription on WlpDevControl.*/
	ULONG trigger_setting;  /**< device trigger setting, more infomation looking discription on WlpDevControl.*/

}DEVINIT , *PDEVINIT ;


LONG WlpDevInit(WLP_HDEVICE  hDevice, PDEVINIT pDevInit);


/**
 *	Change device settings or status. ControlType selects what to adjust. Because the data can have 
 *	different types, the value (*pValue) is provided as the data addressed by the void pointer 
 *	pValue. 
 * \param hDevice pointer to an WLP device handle variable 
 * \param ControlType Out pointer to an WLP device handle variable
 *  - WLP_DEV_HALT:	To Be Define.
 *  - WLP_DEV_DMD_STOP:
 *		Halt device. You can use WLP_DEV_DMD_START to restart it, pValue no use.
 *  - WLP_DEV_DMD_TYPE: 
 *		After allocation the api is atuomatically set to the connected DMD type.pValue may be:
 *      - WLP_DMDTYPE_1080P_095A,current not support.
 *      - WLP_DMDTYPE_XGA_07A, 
 *      - WLP_DMDTYPE_XGA_055A
 *      . 
 *  - WLP_DEV_FLOAT:
 *		float all DMD mirrors when power down operation if pValue =  1 ,pValue = 0 to cancle it.
 *  - WLP_DEV_DMD_START:
 *		Start dmd.value no use.
 *  - WLP_DEV_DMD_RESET:
 *		Reset DMD.value no use.
 *  - WLP_DEV_RESET:
 *		Reset device.DMD is part of device.value no use.
 *  - WLP_DEV_FRAME_FREQ:
 *		Set Frame freqence. value is frames per second.
 *		Waring : Now, support 1 - 100 when gray = 1. Support 70 wen gray is 2,4,6.Support 39 when gray is 8.Don't use the other value.
 *  - WLP_DEV_GRAY:
 *		Set gray.value is 1,2,4,6,8.After you have call WlpInitDec,if you modify gray setting, you must to reset freq again.
 *  - WLP_DEV_FRAME_DOWNLOAD_ADDR:
 *		Set frame download addr before you use WlpDevLoadFrame to download frames.After WlpDevLoadFrame the addr
 *		will be added the downloadlen.
 *		pValue is addr to be downloaded.It is align in 512 byte.If not setting ,the default is 0.
 *  - WLP_DEV_TRIGGER_SETTING:
 *		trigger setting. the format is:  (CONTROL|TRIGGER_MODE|SYNC_MODE) \n
 *    CONTROL can be the value:
 *		<ul><li>
 *       WLP_TRIGGER_DISABLE  Disable trigger and signal.</li><li>
 *       WLP_TRIGGER_ENABLE   Enable trigger and signal.</li></ul>
 *    TRIGGER_MODE can be the value:
 *		<ul><li>
 *	     WLP_TRIGGER_SINGLE_FRAME:  When a signal inputed, display a frame.</li><li>
 *	     WLP_TRIGGER_FRAMES:        When a signal inputed, start display.Then input a signal , stop.When all frames displayed ,stop.</li><li>
 *	     WLP_TRIGGER_FRAMES_AND_STOP:  When a signal inputed, display all frames, then stop.Ignore all signal before stop.</li><li>
 *	     WLP_TRIGGER_LOOP:    When a signal inputed, display all frames loop.</li></ul>
 *    SYNC_MODE can be the value:
 *		<ul><li>
 *      WLP_SYNC_ALL_FRAMES:  When all frames display off, output a high level signal.</li><li>
 *      WLP_SYNC_SINGLE_FRAME:  When a frame displays off, output a high level signal.</li></ul>
 *    We can write data to WLP_DEV_SIGNAL to analog a input signal.
 *  - WLP_DEV_SIGNAL:
 *    Analog hardware signal when pValue = 0x00000001;
 *  .
 * \param pValue pointer to an user variable.
 * \return Return value maybe: \n
 *  - WLP_SUCCESS 
 *  - WLP_ERR_PARAM 
 *  - WLP_ERR_INIT 
 *  - WLP_ERR_RESET 
 *  - WLP_ERR_MT  
 *  - WLP_ERR_USB 
 *  - WLP_ERR_DISPLAY_MODE
 *        
 */
LONG WlpDevControl(WLP_HDEVICE hDevice, LONG ControlType, PVOID pValue ) ;



/**
 *	Query information about a specific device. ControlType acts as a selectro whilst pValue points to a variable of the
 *	according data type.
 *	The caller must support enough area to receive data readed from device by pValue.
 *	Valid query types are a superset of the control types used int the function WlpDevControl.
 *	This function always checks if the device is connected to the USB, and returns WLP_ERR_DISCONNECT if not.
 * \param hDevice pointer to an WLP device handle variable 	
 * \param QueryType See the fllowing list: \n
 *	<table><tr>
 *   <td>QueryType   </td><td>   type    </td><td>  *pValue</td></tr><tr>
 *   <td>WLP_DEV_STATUS </td><td>				ULONG(4)	</td><td>	The return pValue = 1, running.pValue = 0 , halt</td></tr><tr>
 *   <td>WLP_DEV_DRIVER_VER </td><td>			WLP_VERSION(4)	</td><td> Get driver version</td></tr><tr>
 *   <td>WLP_DEV_SERIAL	</td><td>			ULONG(4)	</td><td>	Get device serial.</td></tr><tr>
 *   <td>WLP_DEV_DMD_TYPE </td><td>			ULONG(4)	</td><td>	Get device dmdtype.</td></tr><tr>
 *   <td>WLP_DEV_VERSION </td><td>				ULONG(4) </td><td>		Get	device version</td></tr><tr>
 *   <td>WLP_DEV_DDC_VERSION </td><td>			ULONG(4)	</td><td>	Get ddc version</td></tr><tr>
 *   <td>WLP_DEV_DDR_SIZE	</td><td>		ULONG(4)	</td><td>	Get dmd device ddr memory size in byte.current not support.</td></tr><tr>
 *   <td>WLP_DEV_FRAME_DOWNLOAD_ADDR </td><td>	ULONG(4)	</td><td>	Get download addr.</td></tr></table>
 * \param pValue XXXXXXXXXXXXX
 * \return Return value maybe: \n
 *  - WLP_SUCCESS 
 *  - WLP_ERR_HANDLE
 *  - WLP_ERR_MT 
 *  - WLP_ERR_USB 
 *  - WLP_ERR_PARAM 
 *  - WLP_ERR_DMDTYPE
 * 
 */
LONG WlpDevInquire(WLP_HDEVICE hDevice, LONG QueryType, PVOID pValue) ;

/**
 *	Release the device. Subsequent API function calls refering this device can only be done after 
 *	re-allocation using the function WlpDevAlloc. 
 *  It don't stop the device.If you want to stop it ,you should call WlpDevControl to stop it.
 *	All mirrors are released from their active position to the floating position. No further 
 *	precautions have to be done prior to power off. 
 *	The multi threading error WLP_ERR_MT can only occur when one of the functions 
 *	WlpDevLoadRows, WlpDevClear, and WlpDevReset is currently executed. 
 * \param hDevice  WLP basic device handle (retrieve it using the function WlpDevAlloc) 
 * \return Return value maybe: \n
 * 	- WLP_SUCCESS 
 *	- WLP_ERR_HDEVICE 
 *	- WLP_ERR_MT
 * 
 */
LONG WlpDevFree(WLP_HDEVICE hDevice);

/**
 *	Transmit the bitmap *pImage to the DMD via USB. It is an array of bytes. The MSB 
 *	of each byte specifies the value of one pixel, 0 means black, 1 is white.\n
 *	Waring:Before call WlpDevLoadFrame, you should set download addr at ddr in device.Then 
 *	WlpDevLoadFrame can calc the size will be tranferred to ddr memory.
 *  Before call this function, please set dmdtype first.
 *  If the pImage is not enough to read, it may occur unknow error.
 * \param hDevice  WLP basic device handle ,retrieve it using the function WlpDevAlloc.
 * \param pImage  In pointer to the bitmap data of the image to load 
 *	The array defined in C should be: \n
 *    - unsigned char pImage[768*1024];   for XGA image
 *    - unsigned char pImage[1050*1400];  for SXGA+ image 
 *    - unsigned char pImage[1080*1920];  for 1080p image \n 
 * \param pImageSize	pImageSize is the size of pImageSize,It is align in 512 byte.
 *  How to calc size of pImage: PictureSize = (PictureWidth * PictureHeight / 8);	for example PictureSize = 768*1024/8
 *    - gray = 1: pImageSize = PictureSize * 1 * frameCnt
 *    - gray = 2: pImageSize = PictureSize * 2 * frameCnt
 *    - gray = 4: pImageSize = PictureSize * 4 * frameCnt
 *    - gray = 6: pImageSize = PictureSize * 6 * frameCnt
 *    - gray = 8: pImageSize = PictureSize * 8 * frameCnt \n 
 *  Attention:
 *      WlpDevLoadFrame can't load data out of DDR.
 *      For .7:  The max pImageSize =  total DDR size. Example ,if ddr is 1G, the sum of start download addr and pImageSize 
 *               can't bigger than 1G.If then, data will be lost and unknow error.
 *      For .95: The max pImageSize = total DDR size / (2048 * 1080) * (1920 * 1080).Because every line ( 1920 bit) store in DDR cast 2048 bit.
 * \return Return value maybe: \n
 *  - WLP_SUCCESS
 *  - WLP_ERR_HANDLE
 *  - WLP_ERR_MT
 *  - WLP_ERR_USB
 *  - WLP_ERR_PARAM
 *  - WLP_ERR_DMDTYPE
 *  
 */
LONG WlpDevLoadFrame(WLP_HDEVICE hDevice, PUCHAR pImage, ULONG pImageSize);

/**
 *	Execute the clear operation on multiple  blocks of the DMD bweetn FirstBlock and LastBlock.
 *  Screen From top to bottom is divided to 16 blocks averagely .
 *	Prerequisite: 0<=FirstBlock<=LastBlock<=15 
 *	current not support.
 * \param hDevice  WLP basic device handle (retrieve it using the function WlpDevAlloc)
 * \param FirstBlock  First  block to be cleared
 * \param LastBlock  Last  block to be cleared
 *
 * \return Return value maybe:
 *  - WLP_SUCCESS
 *  - WLP_ERR_HDEVICE
 *  - WLP_ERR_MT
 *  - WLP_ERR_USB
 *  - WLP_ERR_PARAM
 *  
 */
LONG WlpDevBlockClear(WLP_HDEVICE hDevice, LONG FirstBlock, LONG LastBlock) ;


/** @ example to use API.
 * - 1.open device ,get handle.
 * - 2.reset device,wait 100ms.
 * - 3.reset dmd, wait 100ms.
 * - 4.init device, set dmdtype, freq, gray, trigger setting.
 * - 5.Set frame cnt.
 * - 6.set dmd download addr.
 * - 7.calc dmd download len calced by dmdtype, frameCnt, gray.
 * - 8.download frame data to device.
 * - 9.start display,wait 100ms for dmd to start.
 * - 10.trigger the device.
 * - 11.halt device(option).
 * - 12.free device.
*/

#ifdef __cplusplus
}
#endif

#endif /*__WLP_INTERFACE_H__*/

