/* --COPYRIGHT--,BSD
 * Copyright (c) 2012, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/
#ifndef I2CBSLHOST_H_
#define I2CBSLHOST_H_

// BSL Characters
#define SYNC_CHAR       0x80                /*! SYNC char to BSL    */
#define ACK_CHAR        0x00                /*! ACK char from BSL   */
#define NACK_CHAR       0xA0                /*! NACK char from BSL  */

// BSL Message Reply Types
#define BSL_ACK_REPLY   0x01                /*! Wait for ACK from BSL   */
#define BSL_MSG_REPLY   0x02                /*! Wait for msg from BSL   */
                                    
// BSL Commands
#define BSL_COMMAND_RX_DATA_BLOCK       0x10    /*! Writes a block of data  */
#define BSL_COMMAND_ERASE_SEGMENT       0x12    /*! Erases a segment        */
#define BSL_COMMAND_MASS_ERASE          0x15    /*! Erases Application area */
#define BSL_COMMAND_BSL_VERSION         0x19    /*! Request BSL Version     */
#define BSL_COMMAND_JUMP2APP            0x1C    /*! Jump to Application     */

// Error Definitions
#define BSL_ERROR_OK                    (0x00)  /*! No error                   */
#define BSL_PI_ERROR                    -3      /*! Communication error        */
#define BSL_RESPONSE_ERROR              -2      /*! Error in target's response */

// Type definitions
/*! BSL Command structure */
typedef struct _i2cBslCmd
{
  uint8_t header;                       /*! Header byte                     */
  uint8_t bslResponseMsgLen;            /*! Expected response lenght        */
  uint8_t NL;                           /*! Number of bytes in BSL Core CMD */
  uint8_t bslCoreCommand[250];          /*! Core Command: Cmd + Addr + Data */
  uint16_t checksum;                    /*! Checksum                        */
  uint32_t retries;                     /*! Number of Retry attempts        */
} I2cBslCmd;


/*! BSL Response structure */
typedef struct _i2cBslResponse
{
  uint8_t i2cBslPiMessage;          /*! Response from BSL Peripheral Interface */
  uint8_t bslCoreResponseLength;    /*! Length of response data or message     */
  uint8_t bslCoreResponse[256];     /*! Response data or message               */
} I2cBslResponse;

/*! SMBus Command structure */
typedef struct _i2cSMBCmd
{
  uint8_t buf[36];          /*! Data buffer: Cmd + Addr + Data  */
  uint8_t pec;              /*! calculated PEC                  */ 
  uint8_t len;              /*! Lenght of Data                  */
  uint8_t resp_len;         /*! Lenght of expected response     */
  uint32_t retries;         /*! Number of retry attempts        */
} I2cSMBCmd;


//
// Function prototypes
//
//  BSL-protocol 
int16_t i2cBsl_ProcessCmd(I2cBslCmd* pCmd, I2cBslResponse* pResponse);
int16_t i2cBsl_DownloadtoTarget(const uint8_t *programCode, uint16_t startaddr, uint16_t length);
void i2cBsl_CmdRxDataBlock(I2cBslCmd* pCmd, uint32_t addr, uint16_t len, uint8_t* pData);
void i2cBsl_CmdVersion(I2cBslCmd* pCmd);
void i2cBsl_CmdBadVersion(I2cBslCmd* pCmd);
void i2cBsl_CmdMassErase(I2cBslCmd* pCmd);
void i2cBsl_CmdJmptoApp(I2cBslCmd* pCmd);
void i2cBsl_CmdEraseSeg(I2cBslCmd* pCmd, uint32_t addr);

//  Application 
int16_t i2CApp_LED1(void);
int16_t i2CApp_LED2(void);
int16_t i2CApp_LEDBoth(void);
int16_t i2CApp_ForceBSL(void);

// Simple protocol
int16_t i2CSimple_DownloadtoTarget(const uint8_t *programCode, uint16_t length);

// SMBus protocol
int16_t i2cSMB_ProcessCmd(I2cSMBCmd* pCmd, I2cSMBCmd* pResponse);
void i2cSMB_CmdVersion(I2cSMBCmd * pCmd);
void i2cSMB_CmdAppErasePEC(I2cSMBCmd * pCmd);
void i2cSMB_CmdBadAppErasePEC(I2cSMBCmd * pCmd);
int16_t i2CSMB_DownloadtoTarget(const uint8_t *programCode, uint16_t startaddr, uint16_t length);
void i2cSMB_CmdRxDataBlock(I2cSMBCmd* pCmd, uint32_t addr, uint16_t len, uint8_t* pData);

#endif /*I2CBSLHOST_H_*/
