#ifndef UART_PROTOCOL_H
#define UART_PROTOCOL_H

#include <stdint.h>
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned char uint8_t;
#define UART_UPDATE_ACK_NONE 0
#define UART_UPDATE_ACK_OK 1
#define UART_UPDATE_ACK_WAIT 2
#define UART_UPDATE_ACK_FAIL 3
#define UART_UPDATE_ACK_TIMEOUT 4

#define GROUP_PIC_DIR_LEFT      0x80
#define GROUP_PIC_DIR_RIGHT     0x00
#define GROUP_PIC_USE_PSD_Y_POS -1

typedef enum {
    ALIVE_COUNTER_COMM,
    ALIVE_COUNTER_LCD0,
    ALIVE_COUNTER_LCD1,
    ALIVE_COUNTER_TOTAL,
}ALIVE_COUNTER_TYPE;

/* Generate Function */
extern void ResetInitedState(void); /* Called every time the AMT630 is powered on or the MCU wake up */
extern uint8_t GetAliveCounter(ALIVE_COUNTER_TYPE n); /* 0:ALIVE_COUNTER_COMM, 1:ALIVE_COUNTER_LCD0, 2:ALIVE_COUNTER_LCD1 */
extern uint32_t GetCrcErrCnts(void);
extern uint32_t GetRecvLenErrCnts(void);
extern uint8_t GetLcdInitSt(void);
extern uint8_t GetCameraSignalSt(void);
extern uint8_t GetVideoCaptureSt(void);
extern uint8_t GetAmt630InBoot(void); 
extern uint8_t *GetUartRecvData(uint32_t *UartRecvBufLen, uint32_t *UartRecvPos);
extern void UartSendData(uint8_t *data, uint32_t len);
extern void AnalysisUartData(void);
/* Generate Function end */

/* Sound */
#define SOUND_STATE_FREE 0
#define SOUND_STATE_BUSY 1
#define WAV_TEST_NUM_TIC 0xfd
#define WAV_TEST_NUM_TOC 0xfe
enum {
    AUDIO_FREQ_NONE,
    AUDIO_FREQ_8K,
    AUDIO_FREQ_11K,
    AUDIO_FREQ_16K,
    AUDIO_FREQ_22K,
    AUDIO_FREQ_32K,
    AUDIO_FREQ_44K,
    AUDIO_FREQ_48K,
    AUDIO_FREQ_96K,
    AUDIO_FREQ_128K,
    AUDIO_FREQ_160K,
    AUDIO_FREQ_172K,
    AUDIO_FREQ_192K,
    AUDIO_FREQ_TOTAL,
};
extern void PackedTransfer_SoundPlay(uint8_t Channel, uint8_t WavNum, uint16_t PlayTimes, uint16_t MinTimes, uint8_t Volume);
extern void PackedTransfer_SoundStop(uint8_t Channel);
extern void PackedTransfer_SoundChangeVolume(uint8_t Channel, uint8_t Volume);
extern uint8_t GetSoundChannelSta(uint8_t Channel);
/* Sound end */

/* Lcd Parameter */
#define LCD_WIRING_MODE_RGB 0
#define LCD_WIRING_MODE_RBG 1
#define LCD_WIRING_MODE_GRB 2
#define LCD_WIRING_MODE_GBR 3
#define LCD_WIRING_MODE_BRG 4
#define LCD_WIRING_MODE_BGR 5

#define LCD_INTERFACE_TTL 0
#define LCD_INTERFACE_LVDS 1

#define LCD_WIRING_BIT_ORDER_MSB 0
#define LCD_WIRING_BIT_ORDER_LSB 1

#define LVDS_PANEL_FORMAT_TI 0
#define LVDS_PANEL_FORMAT_NS 1

#define LVDS_PANEL_DATA_8BIT 0
#define LVDS_PANEL_DATA_6BIT 1

#define VIDEO_IN_NONE 0
#define VIDEO_IN_NTSC 1
#define VIDEO_IN_PAL 2

typedef struct {
    uint16_t LcdWidth;
    uint16_t LcdHeight;
    uint8_t LcdVideoInputValid : 2;
    uint8_t LcdBpp : 6;
	uint8_t Ark7116ResetPin;
    uint8_t LcdInterfaceType : 4;
    uint8_t LcdWiringMode : 4;
    uint8_t LcdWiringBitOrder : 2;
    uint8_t LcdDotClkReverse : 2;
    uint8_t LvdsPanelFormat : 2;
    uint8_t LvdsPanelData : 2;
    uint16_t LcdTimingVBP;
    uint16_t LcdTimingVFP;
    uint16_t LcdTimingVSW;
    uint16_t LcdTimingHBP;
    uint16_t LcdTimingHFP;
    uint16_t LcdTimingHSW;
    uint32_t LcdClkFreq;
    uint8_t SoundFreq;
    uint8_t SoundChannelNum;
} LCD_TFT_SOUND_PARA_ST;
extern void SetLcdSoundParameter(LCD_TFT_SOUND_PARA_ST *pData);
/* Lcd Parameter end */

/* Amt Software */
typedef struct {
    uint8_t AmtLdrVer[8];
    uint8_t StepLdrVer[8];
    uint8_t AmtAppVer[8];
    uint8_t UiVer[8];
    uint8_t SoundVer[8];
    uint8_t FontVer[8];
} SOFTWARE_VERSION_ST;
extern void SetSwVerBuf(uint8_t *buf);
extern void PackedTransfer_GetSwVer(void);
/* Amt Software end */

/* Pic Index */
extern void SetPicIndexData(uint8_t *data, uint32_t len, uint32_t crc);
/* Pic Index end */

/* Sequence Frame */
#define SE_FRAME_PIC_MAX 100
enum {
    SE_TYPE_NONE,
    SE_TYPE_ONE_SHOT,
    SE_TYPE_CONTINUOUS,
};
typedef struct {
    uint16_t Pic;
} SEQUENCE_FRAME_PIC_ST;
typedef struct {
    uint8_t SeFrameType;
    uint8_t SeFrameNumTotal;
    uint16_t SeFrameTotalTime;
    uint16_t SeFrameValidTime;
    SEQUENCE_FRAME_PIC_ST SeFramePicList[SE_FRAME_PIC_MAX];
} SEQUENCE_FRAME_ST;
extern SEQUENCE_FRAME_ST SeFrameData;
extern void PackedTransfer_SequenceFrame(uint8_t *SeData, uint16_t SeLen);
extern void PackedTransfer_SequenceFrameOff(void);
/* Sequence Frame end */

/* Pointer Move Type */
typedef enum {
    POINTER_TYPE_SPEED,
    POINTER_TYPE_ENGINE,
    POINTER_TYPE_COOLANT_FUEL,
    POINTER_TYPE_CUSTOMIZE,
    POINTER_TYPE_MAX,
} POINTER_MOVE_TYPE_ENUM;
typedef enum {
    POINTER_RENDER_TYPE_POINTER,
    POINTER_RENDER_TYPE_SEQUENCE_PIC,
} POINTER_RENDER_TYPE_ENUM;
typedef struct {
    uint32_t PointerAngleP;     /* 10:0.1, 15:0.15, 100:1 .... POINTER_TYPE_SPEED default:30 */
    uint32_t PointerAngleD;     /* 10:0.1, 15:0.15, 100:1 .... POINTER_TYPE_SPEED default:18 */
    uint32_t PointerAngleSlowP; /* 10:0.1, 15:0.15, 100:1 .... POINTER_TYPE_SPEED default:10 */
    uint32_t PointerAngleSlowD; /* 10:0.1, 15:0.15, 100:1 .... POINTER_TYPE_SPEED default:18 */
    uint32_t MaxInterval;       /* 10:0.1, 15:0.15, 100:1 .... POINTER_TYPE_SPEED default:340 */
} POINTER_MOVE_PARA;
extern void PackedTransfer_SetPointerMoveType(POINTER_MOVE_PARA *Data, POINTER_MOVE_TYPE_ENUM MoveType);
/* Pointer Move Type end */

/* Pointer */
typedef enum {
    POINTER_0,
    POINTER_1,
    POINTER_2,
    POINTER_3,
    POINTER_MAX,
} POINTER_ENUM;
extern void PackedTransfer_InitPointer(POINTER_ENUM PointerN, uint8_t *data, uint16_t len, POINTER_MOVE_TYPE_ENUM MoveType, POINTER_RENDER_TYPE_ENUM RenderType);
extern uint8_t GetPointerInitSt(POINTER_ENUM PointerN);
extern void PackedTransfer_SetPointerDestVal(POINTER_ENUM PointerN, uint16_t DestVal, uint8_t NoDamping); /* DestVal:0~1000, NoDamping: 0-have damping, 1:no damping */
extern uint16_t GetPointerCurVal(POINTER_ENUM PointerN);                               /* CurVal:0~1000 */

#define POINTER_NUM_LIST_MAX 20
extern void SetPointerNumPic(POINTER_ENUM PointerN, uint8_t n, uint16_t PicIndex, uint16_t PointerVal);
extern void SetPointerNumZoomPara(POINTER_ENUM PointerN, uint16_t ZoomRange, float ZoomMax);
extern void PackedTransfer_PointerNumData(POINTER_ENUM PointerN);
/* Pointer end */

/* Page Data */
typedef enum {
    GRAPHICS_PAGE_0,
    GRAPHICS_PAGE_1,
    GRAPHICS_PAGE_2,
    GRAPHICS_PAGE_MAX,
} GRAPHICS_PAGE_ENUM;

typedef enum {
    SWITCH_EFFECT_NONE,
    SWITCH_EFFECT_ONLY_ALPHA,
    SWITCH_EFFECT_ONLY_OFFSET,
    SWITCH_EFFECT_ALPHA_OFFSET,
} EFFECT_VALID_ENUM;

typedef enum {
    SWITCH_EFFECT_OFFSET_FADE_IN_RIGHT_TO_LEFT,
    SWITCH_EFFECT_OFFSET_FADE_IN_LEFT_TO_RIGHT,
    SWITCH_EFFECT_OFFSET_FADE_IN_UP_TO_DOWN,
    SWITCH_EFFECT_OFFSET_FADE_IN_DOWN_TO_UP,
} OFFSET_EFFECT_ENUM;

typedef enum {
    ALIGN_LEFT,
    ALIGN_CENTER,
    ALIGN_RIGHT,
} TEXT_ALIGN_TYPE;

typedef enum {
    TFT_ROT_0,
    TFT_ROT_90,
    TFT_ROT_180,
    TFT_ROT_270,
} TFT_ROT_TYPE;

#define TEXT_ROT_SCALE (r, s) ((((r) & 0xffff) << 16) | ((s) & 0xffff))
#define TEXT_COLOR(r, g, b, a) ((((r) & 0xff) << 24) | (((g) & 0xff) << 16) | (((b) & 0xff) << 8) | ((a) & 0xff)
#define TEXT_LINE_OFFSET(x, y) ((((x) & 0xffff) << 16) | ((y) & 0xffff))

#define GROUP_ALIGN_LEFT 0x0
#define GROUP_ALIGN_CENTER 0x40
extern void SetPageGuid(GRAPHICS_PAGE_ENUM page, uint8_t h, uint8_t m, uint8_t l);
extern void SetPageBackground(GRAPHICS_PAGE_ENUM page, uint16_t PicIndex);
extern void SetPagePic(GRAPHICS_PAGE_ENUM page, uint16_t PicIndex);
extern void SetPagePicPointerNum(GRAPHICS_PAGE_ENUM page, POINTER_ENUM PointN, uint16_t PicIndex);
extern void SetPagePicFree(GRAPHICS_PAGE_ENUM page, uint16_t PicIndex, int16_t PosX, int16_t PosY);
extern void SetPagePicFreeAppend(GRAPHICS_PAGE_ENUM page, uint16_t pic, int16_t PosX, int16_t PosY);
extern void SetPagePicGroup(GRAPHICS_PAGE_ENUM page, int16_t Interval, int16_t PosX, int16_t PosY, uint16_t *PicList, uint32_t Align_Num, uint16_t Dot_Itv, TFT_ROT_TYPE TftRot);
extern void SetPageText(GRAPHICS_PAGE_ENUM page, uint16_t LabelNum, int16_t PosX, int16_t PosY, int16_t MaxX, TEXT_ALIGN_TYPE AlginType, uint32_t RotScale, uint32_t Color, uint32_t LineOffset);	/* TEXT_ROT_SCALE:use TEXT_ROT_SCALE macro, (r:0~3600); (s:-1000 ~ 1000, 0:no scale, 1 ~ 1000:zoom in, -1 ~ -1000:zoom out); Color:use TEXT_COLOR macro; LineOffset:use TEXT_LINE_OFFSET macro */
extern void SetPagePointerPic(GRAPHICS_PAGE_ENUM page, POINTER_ENUM PointN, uint16_t PicIndex);
extern void SetPagePointerSePic(GRAPHICS_PAGE_ENUM page, POINTER_ENUM PointN);
extern void SetPagePointerTrackPic(GRAPHICS_PAGE_ENUM page, POINTER_ENUM PointN, uint16_t PicIndex);

extern void PackedTransfer_BgJpg(uint32_t PicIndex);
extern void PackedTransfer_Page(void);
extern void PackedTransfer_PageEffect(GRAPHICS_PAGE_ENUM page, EFFECT_VALID_ENUM EffectValid, OFFSET_EFFECT_ENUM OffsetEffect);
extern void PackedTransfer_ClearPageData(GRAPHICS_PAGE_ENUM page);
/* Page Data end */

/* Compose Pic */
extern void PackedTransfer_ComposeData(uint8_t *data, uint8_t len);
/* Compose Pic end */

/* Label List */
extern uint8_t GetLanguageInitSt(void);
extern void PackedTransfer_InitLanguageFont(uint8_t Language, uint8_t Font);
extern void PackedTransfer_LabelsList(uint16_t LabelNum, uint8_t *LabelBuf, uint32_t LabelLen);
/* Label List end */

/* Flash Check */
typedef enum {
    DISPLAY_CHECKING,
    DISPLAY_CHECK_PASS,
    DISPLAY_CHECK_FAIL,
}FLASH_CHECK_FORCE_DISPLAY_TYPE;
extern void PackedTransfer_CheckFlash(void);
extern uint8_t PackedTransfer_CheckFlashGetResult(void);	/*return value 0xff:checking, 0:fail, 1:success */
extern void PackedTransfer_CheckFlashForceDisplay(FLASH_CHECK_FORCE_DISPLAY_TYPE type, uint16_t timerMs);
/* Flash Check end */

/* Video Input */
extern void PackedTransfer_VedioInputOn(uint32_t PosX, uint32_t PosY, uint32_t Wdith, uint32_t Height, uint32_t CutX, uint32_t CutY);
extern void PackedTransfer_VedioInputOff(void);
/* Video Input end */

/* Get Mcu or Backup Data */
typedef enum {
	REQ_DATA,
	GET_STATUS,
	GET_APP_DATA_OFFSET,
    GET_BACKUP_DATA_OFFSET,
    GET_BACKUP_DATA_CRC,
    WRITE_BACKUP_DATA,
} READ_ARK630_CMD;

typedef enum {
    RECV_TYPE_DATA,
    RECV_TYPE_OFFSET_LEN,
    RECV_TYPE_WRITE_BACKUP_RESP,
    RECV_TYPE_BACKUP_CRC,
}RECV_MCU_DATA_TYPE;
extern void GetDataBuf(uint32_t *pAddr, uint32_t *pLen);
extern void SetRecvDataSt(RECV_MCU_DATA_TYPE type, uint32_t addr, uint32_t len, uint32_t crc);
extern void PackedTransfer_GetMcuData(uint32_t addr, uint16_t len);
extern void PackedTransfer_GetDataOffsetLen(uint8_t type);
extern void PackedTransfer_GetBackupDataCrc(uint32_t addr, uint32_t len);
extern void PackedTransfer_WriteBackupData(uint32_t addr, uint8_t *data, uint16_t len);
/* Get Mcu or Backup Data end */

/* Set tft io mode */
extern void PackedTransfer_SetTftIoMode(uint8_t st);	/*st 0:normal gpio, 1:TFT io*/
/* Set tft io mode end */

enum {NUM_0, NUM_1, NUM_2, NUM_3, NUM_4, NUM_5, NUM_6, NUM_7, NUM_8, NUM_9, NUM_POINT, NUM_LINE};
typedef struct {
    const uint16_t *NumList;
    int16_t NumInterval;
    int16_t x;
    int16_t y;
    uint8_t DecimalNum;
    uint8_t MinDigits;
} DISPLAY_NUM_ST;

extern void DisplayNum(uint8_t page, DISPLAY_NUM_ST *pNumData, int32_t NumVal);

/*
note:
Update630HBegin UDS 34 Seriver call and power on 630H and lcd by your self
Update630HWrite UDS 36 Seriver call
Update630HEnd   UDS 37 Seriver call

return 0 is wait, return 1 is success, return 2 is fail.
*/
extern uint8_t Update630HBegin(uint32_t TimerCnts);
extern uint8_t Update630HWrite(uint32_t TimerCnts, uint8_t *data, uint32_t len);
extern uint8_t Update630HEnd(uint32_t TimerCnts);

#endif
