#include "stdint.h"

#define BSL_DELAY                                                           (5000)
//#define MAX_PACKET_SIZE                                            (uint8_t) (255)

extern uint8_t BSL_buffer[255];

// ! Define BSL CORE commands
#define CMD_RX_DATA_BLOCK                                                   (0x10)
#define CMD_RX_PASSWORD                                                     (0x11)
#define CMD_PASSWORD_VALID                                                  (0x3B)
#define CMD_MASS_ERASE                                                      (0x15)
#define CMD_CRC_CHECK                                                       (0x16)
#define CMD_LOAD_PC                                                         (0x17)
#define CMD_TX_DATA_BLOCK                                                   (0x18)
#define CMD_TX_BSL_VERSION                                                  (0x19)
#define CMD_RX_DATA_BLOCK_FAST                                              (0x1B)
#define CMD_CHANGE_BAUDRATE                                                 (0x52)

// ! Other useful macros
#define PASSWORD_ADDRESS                                        (uint16_t)(0xFFD8)
#define PASSWORD_SIZE                                                (uint8_t)(32)
#define PASSWORD_RX_PACKET_SIZE                                (PASSWORD_SIZE + 6)
#define PASSWORD_TX_PACKET_SIZE                                      (uint8_t)(11)
#define CMD_BYTE                                                               (1)
#define ACK_BYTE                                                               (1)
#define HDR_LEN_CRC_BYTES                                                      (5)
#define CMD_ADDRS_BYTES                                                        (4)
#define CMD_ADDRS_DATA_BYTES                                                   (6)
#define CMD_MSG_BYTES                                                          (2)
#define PACKET_HEADER                                                       (0x80)
#define CRC_BYTES                                                              (2)
#define PC_BYTES                                                               (3)
// ! Define BYTE positions in a RESPONSE packet
//#define RESPONSE_ACK_POS                                                       (0)
//#define RESPONSE_HEADER_POS                                                    (1)
//#define RESPONSE_LENGTH_POS                                                    (2)
//#define RESPONSE_CMD_POS                                                       (4)
//#define RESPONSE_DATA_POS                                                      (5)
//define RESPONSE_MSG_POS                                                       (5)

#define RESPONSE_CRC_LENGTH                                                    (2)
#define RESPONSE_CRC_POS                                                       (5)



//================================================================================
// ! Conversion MACROS
#define LSB(x)                                                        (x & 0x00FF)
#define MSB(x)                                                 ((x & 0xFF00) >> 8)


// ! IMPORTANT - MSP430FR2633 target BSL is limited to 260 byte buffer.
// ! Our MSP430 HOST MCU is hardware limited to 255 bytes per packet so we
// ! set the MAX_PACKET_SIZE = 255.
// ! Change this to match your I2C driver
#define MAX_PACKET_SIZE                                            (uint8_t) (255)
#define MAX_PAYLOAD_SIZE            (uint8_t)(MAX_PACKET_SIZE - HDR_LEN_CRC_BYTES)
#define MAX_PAYLOAD_DATA_SIZE                                               (128)



enum
{
    //! No Error Occurred! The operation was successful.
    eBSL_success = 0,

    //! Flash write check failed. After programming, a CRC is run on the programmed data
    //! If the CRC does not match the expected result, this error is returned.
    eBSL_flashWriteCheckFailed = 1,

    //! BSL locked.  The correct password has not yet been supplied to unlock the BSL.
    eBSL_locked = 4,

    //! BSL password error. An incorrect password was supplied to the BSL when attempting an unlock.
    eBSL_passwordError = 5,

    //! Unknown error.  The command given to the BSL was not recognized
    eBSL_unknownError = 7,

    eBSL_responseCommand = 0x3B

};
typedef uint8_t BSL_error_t;

enum
{
   uart_noError = 0,           //normal ACK
   header_Error = 0x51,        //Header incorrect
   checksum_Error = 0x52,      //Checksum incorrect.
//   packetsize0_Error = 0x53,   //Packet size zero.
//   packetsizemax_Error = 0x54, //Packet size exceeds buffer.
   unknown_Error = 0x55,       //Unknown error
//   baudrate_Error = 0x56,      //Unknown baud rate.
   packetsize_Error = 0x57,    //Packet Size Error.

};

typedef uint8_t  uart_error_t;





void Host_BSL_entry_sequence(void);
BSL_error_t Host_BSL_loadPassword(uint8_t* pPassword);
uint16_t softwareCRC(const uint8_t* data, uint8_t length);
BSL_error_t Host_BSL_getResponse(void);
BSL_error_t Host_BSL_writeMemory(uint32_t addr, const uint8_t* data,  uint32_t len);
void SetPC(const uint8_t* PCaddress);

