/*
 * C1_can.h
 *
 *  Author: Gasha
 *  The CAN driver for 320F2837x family of DSPs (28377 and 28379)
 *  Which use CAN D controller
 */

#define CAN_IF_DIR_READ      0
#define CAN_IF_DIR_WRITE     1

#define DO_NOT_USE           0
#define IEEE_FLOAT           1
#define UNSIGNED_16          2
#define SIGNED_16            3
#define UNSIGNED_32          4
#define SIGNED_32            5

#define CAN_RAM_INIT_UNLOCKED_KEY ((uint16_t)0x000Au)

/** Byte peripheral typedefs (CAN and USB peripherals all are byte addressed) @{ */
typedef unsigned int bp16_t __attribute__((byte_peripheral));
typedef unsigned long bp32_t __attribute__((byte_peripheral));

typedef enum
{   // Receive messages
    CAN_GUI_BROADCAST_MB_IDX          = 0,
    CAN_GUI_FLOAT_BROADCAST_MB_IDX,
    CAN_DAC1_MEM_MB_IDX,
    CAN_DAC1_GAIN_MB_IDX,
    CAN_DAC2_MEM_MB_IDX,
    CAN_DAC2_GAIN_MB_IDX,
    CAN_DAC3_MEM_MB_IDX,
    CAN_DAC3_GAIN_MB_IDX,
    CAN_DAC4_MEM_MB_IDX,
    CAN_DAC4_GAIN_MB_IDX,
    CAN_DEBUG_ARRAY_REQ_MB_IDX,
    CAN_DEBUG_RW_REQ_MB_IDX,
    // Transmit messages
//    CAN_NVM_INFO_MB_IDX,
//    CAN_NVM_START_MB_IDX,
//    CAN_NVM_EOF_MB_IDX,
    CAN_DEBUG_RW_RESP_MB_IDX,
    CAN_DEBUG_ARRAY_RESP_10_MB_IDX,
    CAN_DEBUG_ARRAY_RESP_32_MB_IDX,
    CAN_DEBUG_ARRAY_RESP_54_MB_IDX,
    CAN_FAULT_MB_IDX,
    CAN_STATUS_MB_IDX,
    CAN_FEEDBACK0_MB_IDX,
    CAN_FEEDBACK1_MB_IDX,
    CAN_FEEDBACK2_MB_IDX,
    CAN_FEEDBACK3_MB_IDX,
    CAN_FEEDBACK4_MB_IDX,
    CAN_FEEDBACK5_MB_IDX,
    CAN_NUMBER_OF_GUI_MAILBOXES
} TE_MC_CAN_MailboxEntryIndex;

/** Mailbox configuration, used for setting up a CAN mailbox */
typedef struct
{
   unsigned int    mb_number;     // ID/Mailbox number used; valid values [1..32]
   unsigned int    msg_len_bytes; // Length of the message in the mailbox, used to set DLC
   unsigned long   msg_id;        // ID of the message in the mailbox (either an 11 or 29 bit id allowed)
   unsigned long   msg_id_mask;   // message ID mask
   unsigned long   msg_dir;       // Direction of the mailbox Tx=1 /Rx=0
} TS_CAN_MsgBoxConfig;

typedef struct
{
    unsigned int     mailbox_num;
    union {
       struct {
           unsigned int     I0;
           unsigned int     I1;
           unsigned int     I2;
           unsigned int     I3;
       } Int;
       struct {
           unsigned long    L0;
           unsigned long    L1;
       } Long;
       struct {
          float             F0;
          float             F1;
       } Float;
    } Data;
} TS_CAN_MsgObj;

union GUI_CommandUnion {
   struct {
      unsigned int nStopStart     :  1; // 0     nStopStart
      unsigned int RunMode        :  2; // 1-2   RunMode1
      unsigned int CB_D3          :  1; // 3     CB_D3       (future GUI version)
      unsigned int PB_D4          :  1; // 4     PB_D4 - Middle Push button
      unsigned int MasterReset    :  1; // 5     PB_D5 - Right Push Button
      unsigned int CB_D6          :  1; // 6     CB_D6
      unsigned int CB_D7          :  1; // 7     CB_D7
      unsigned int EnablePanel    :  1; // 8     PB_D8 - Left Push button
      unsigned int CB_D9          :  1; // 9     CB_D9
      unsigned int CB_D10         :  1; // 10    CB_D10
      unsigned int CB_D11         :  1; // 11    CB_D11
      unsigned int CB_D12         :  1; // 12    CB_D12
      unsigned int RunMode2       :  2; // 13-14 RunMode2    (future GUI version)
      unsigned int CB_D15         :  1; // 15    CB_D15      (future GUI version)
      int          GUI_Int16      : 16; // 31-16 GUI_Int16
      int          GUI_Int16_2    : 16; // 47-32 GUI_Int16_2 (future GUI version)
      unsigned int reserved       : 16; // 63-48             (future GUI version)
   } Bit;
   struct {
      unsigned int I0;
      unsigned int I1;
      unsigned int I2;
      unsigned int I3;
   } Int;
   struct {
      unsigned long L0;
      unsigned long L1;
   } Long;
};

union DAC_MessageUnion {
   struct {
      unsigned long Addr;
      unsigned int  Reserved : 16;
      unsigned int  Type     : 15;
      unsigned int  Zero     : 1;
      float         Gain;
      float         Offset;

   } Bit;
   struct {
      unsigned int  I0;
      unsigned int  I1;
      unsigned int  I2;
      unsigned int  I3;
      unsigned int  I4;
      unsigned int  I5;
      unsigned int  I6;
      unsigned int  I7;
   } Int;
};

struct DebugArrayStruct {
   unsigned long    Address;
   unsigned int     Type;
};

union DebugRWUnion {
   struct {
      unsigned long Data;
      unsigned long Addr     : 24;
      unsigned long Type     :  7;
      unsigned long RnW      :  1;
   } Bit;
   struct {
      unsigned int I0;
      unsigned int I1;
      unsigned int I2;
      unsigned int I3;
   } Int;
};

void        InitCANA(void);
void        ReadMsgCANA(TS_CAN_MsgObj*);
void        SendMsgCANA(TS_CAN_MsgObj* p_tx_msg_obj);
void        RxCANA(void);
void        TxCANA(void);

