#include "f28x_project.h"
#include "can.h"
#include "hw_can.h"
#include "charger_ecan.h"
#include "FunState.h"
#include "MonitorSci.h"
#include "ctrl.h"


Uint16 txMsgData[8];
Uint16 rxMsgData[8];
DATACanType CanRecData;
DATACanType CanTrsData;
struct MDADDRMES uMdlAddMes;
struct SCANMES sCanMes;

void InitECanaGpio(void)
{
   EALLOW;

/* Enable internal pull-up for the selected CAN pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0;	    // Enable pull-up for GPIO30 (CANRXA)
 	GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0;	    // Enable pull-up for GPIO31 (CANTXA)

/* Set qualification for selected CAN pins to asynch only */
// Inputs are synchronized to SYSCLKOUT by default.
// This will select asynch (no qualification) for the selected pins.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3;   // Asynch qual for GPIO30 (CANRXA)

/* Configure eCAN-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAN functional pins.

    GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1;	// Configure GPIO30 for CANRXA operation
 	GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;	// Configure GPIO31 for CANTXA operation

    EDIS;
}

static inline void CAN_initRAM(void)
{
    //
    // Check the arguments.
    //
    
    CanaRegs.CAN_RAM_INIT.all = ( CAN_RAM_INIT_CAN_RAM_INIT |CAN_RAM_INIT_KEY);

    while(!((CanaRegs.CAN_RAM_INIT.all& CAN_RAM_INIT_MASK) ==
            (CAN_RAM_INIT_RAM_INIT_DONE | CAN_RAM_INIT_KEY2 |
             CAN_RAM_INIT_KEY0)))
    {
        //
        // Wait until RAM Init is complete
        //
    }

}

static inline void CAN_initModule(void)
{
    
    CanaRegs.CAN_CTL.all |= ((Uint16)CAN_CTL_INIT |(Uint16)CAN_INIT_PARITY_DISABLE);

    //
    // Initialize the message RAM before using it.
    //
    CAN_initRAM();

    //
    // Force module to reset state
    //

    CanaRegs.CAN_CTL.all |=  CAN_CTL_SWR;

    //
    // Delay for 14 cycles
    //
    DELAY_US(14U);

    //
    // Enable write access to the configuration registers
    //
    CanaRegs.CAN_CTL.all |= CAN_CTL_CCE;
}

//*****************************************************************************
//
// CAN_setBitTiming
//
//*****************************************************************************
static inline void
CAN_setBitTiming(Uint16 prescaler,
                 Uint16 prescalerExtension, Uint16 tSeg1, Uint16 tSeg2,
                 Uint16 sjw)
{
    Uint16 savedInit;
    Uint32 bitReg;

    //
    // Check the arguments.
    //
//    ASSERT(CAN_isBaseValid(base));
//    ASSERT(prescaler < 64U);
//    ASSERT((tSeg1 > 0U) && (tSeg1 < 16U));
//    ASSERT(tSeg2 < 8U);
//    ASSERT(sjw < 4U);
//    ASSERT(prescalerExtension < 16U);

    //
    // To set the bit timing register, the controller must be placed in init
    // mode (if not already), and also configuration change bit enabled.
    // State of the init bit should be saved so it can be restored at the end.
    //
    savedInit = CanaRegs.CAN_CTL.all;
    CanaRegs.CAN_CTL.all = savedInit | CAN_CTL_INIT | CAN_CTL_CCE;

    //
    // Set the bit fields of the bit timing register
    //
    bitReg = (Uint32)((Uint32)prescaler & CAN_BTR_BRP_M);
    bitReg |= (Uint32)(((Uint32)sjw << CAN_BTR_SJW_S) & CAN_BTR_SJW_M);
    bitReg |= (Uint32)(((Uint32)tSeg1 << CAN_BTR_TSEG1_S) &
                         CAN_BTR_TSEG1_M);
    bitReg |= (Uint32)(((Uint32)tSeg2 << CAN_BTR_TSEG2_S) &
                         CAN_BTR_TSEG2_M);
    bitReg |= (Uint32)(((Uint32)prescalerExtension << CAN_BTR_BRPE_S) &
                         CAN_BTR_BRPE_M);

    (CanaRegs.CAN_BTR.all) = bitReg;

    //
    // Clear the config change bit, and restore the init bit.
    //
    savedInit &= ~((Uint16)CAN_CTL_CCE);

    CanaRegs.CAN_CTL.all = savedInit;
}

static inline  void CAN_setBitRate(Uint32 clockFreq, Uint32 bitRate,
               Uint16 bitTime)
{
    Uint16 brp;
    Uint16 tPhase;
    Uint16 phaseSeg2;
    Uint16 tSync = 1U;
    Uint16 tProp = 2U;
    Uint16 tSeg1;
    Uint16 tSeg2;
    Uint16 sjw;
    Uint16 prescaler;
    Uint16 prescalerExtension;

    //
    // Check the arguments.
    //
//    ASSERT(CAN_isBaseValid(base));
//    ASSERT((bitTime > 7U) && (bitTime < 26U));
//    ASSERT(bitRate <= 1000000U);

    //
    // Calculate bit timing values
    //
    brp = (Uint16)(clockFreq / (bitRate * bitTime));
    tPhase = bitTime - (tSync + tProp);
    if((tPhase / 2U) <= 8U)
    {
        phaseSeg2 = tPhase / 2U;
    }
    else
    {
        phaseSeg2 = 8U;
    }
    tSeg1 = ((tPhase - phaseSeg2) + tProp) - 1U;
    tSeg2 = phaseSeg2 - 1U;
    if(phaseSeg2 > 4U)
    {
        sjw = 3U;
    }
    else
    {
        sjw = tSeg2;
    }
    prescalerExtension = ((brp - 1U) / 64U);
    prescaler = ((brp - 1U) % 64U);

    //
    // Set the calculated timing parameters
    //
    CAN_setBitTiming(prescaler, prescalerExtension, tSeg1, tSeg2, sjw);
}
static inline void
CAN_startModule(void)
{
    //
    // Check the arguments.
    //
//    ASSERT(CAN_isBaseValid(base));

    //
    // Clear Init and CCE bits
    //
    CanaRegs.CAN_CTL.all &= ~(CAN_CTL_INIT | CAN_CTL_CCE);
}

static inline  void
CAN_setupMessageObject(Uint32 objID, Uint32 msgID,
                       CAN_MsgFrameType frame, CAN_MsgObjType msgType,
                       Uint32 msgIDMask, Uint32 flags, Uint32 msgLen)
{
    Uint32 cmdMaskReg = 0U;
    Uint32 maskReg = 0U;
    Uint32 arbReg = 0U;
    Uint32 msgCtrl = 0U;

    //
    // Check the arguments.
    //
//    ASSERT(CAN_isBaseValid(base));
//    ASSERT((objID <= 32U) && (objID > 0U));
//    ASSERT(msgLen <= 8U);

    //
    // Wait for busy bit to clear
    //
    while((CanaRegs.CAN_IF1CMD.all & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
    {
    }

    switch(msgType)
    {
        //
        // Transmit message object.
        //
        case CAN_MSG_OBJ_TYPE_TX:
        {
            //
            // Set message direction to transmit.
            //
            arbReg = CAN_IF1ARB_DIR;
            break;
        }

        //
        // Remote frame receive remote, with auto-transmit message object.
        //
        case CAN_MSG_OBJ_TYPE_RXTX_REMOTE:
        {
            //
            // Set message direction to Tx for remote receivers.
            //
            arbReg = CAN_IF1ARB_DIR;

            //
            // Set this object to auto answer if a matching identifier is seen.
            //
            msgCtrl = (Uint32)((Uint32)CAN_IF1MCTL_RMTEN |
                                 (Uint32)CAN_IF1MCTL_UMASK);

            break;
        }

        //
        // Transmit remote request message object (CAN_MSG_OBJ_TYPE_TX_REMOTE)
        // or Receive message object (CAN_MSG_OBJ_TYPE_RX).
        //
        default:
        {
           //
           // Set message direction to read.
           //
           arbReg = 0U;

           break;
        }
    }

    //
    // Set values based on Extended Frame or Standard Frame
    //
    if(frame == CAN_MSG_FRAME_EXT)
    {
        //
        // Configure the Mask Registers for 29 bit Identifier mask.
        //
        if((flags & CAN_MSG_OBJ_USE_ID_FILTER) == CAN_MSG_OBJ_USE_ID_FILTER)
        {
            maskReg = msgIDMask & CAN_IF1MSK_MSK_M;
        }

        //
        // Set the 29 bit version of the Identifier for this message
        // object. Mark the message as valid and set the extended ID bit.
        //
        arbReg |= (msgID & CAN_IF1ARB_ID_M) | CAN_IF1ARB_MSGVAL |
                  CAN_IF1ARB_XTD;
    }
    else
    {
        //
        // Configure the Mask Registers for 11 bit Identifier mask.
        //
        if((flags & CAN_MSG_OBJ_USE_ID_FILTER) == CAN_MSG_OBJ_USE_ID_FILTER)
        {
           maskReg = ((msgIDMask << CAN_IF1ARB_STD_ID_S) &
                      CAN_IF1ARB_STD_ID_M);
        }

        //
        // Set the 11 bit version of the Identifier for this message
        // object. The lower 18 bits are set to zero. Mark the message as
        // valid.
        //
        arbReg |= ((msgID << CAN_IF1ARB_STD_ID_S) & CAN_IF1ARB_STD_ID_M) |
                  CAN_IF1ARB_MSGVAL;
    }

    //
    // If the caller wants to filter on the extended ID bit then set it.
    //
    maskReg |= (flags & CAN_MSG_OBJ_USE_EXT_FILTER);

    //
    // The caller wants to filter on the message direction field.
    //
    maskReg |= (flags & CAN_MSG_OBJ_USE_DIR_FILTER);

    //
    // If any filtering is requested, set the UMASK bit to use mask register
    //
    if(((flags & CAN_MSG_OBJ_USE_ID_FILTER) |
        (flags & CAN_MSG_OBJ_USE_DIR_FILTER) |
        (flags & CAN_MSG_OBJ_USE_EXT_FILTER)) != 0U)
    {
        msgCtrl |= CAN_IF1MCTL_UMASK;
    }

    //
    // Set the data length for the transfers. This is applicable only for
    // Tx mailboxes. For Rx mailboxes, dlc is updated on receving a frame.
    //
    if((msgType == CAN_MSG_OBJ_TYPE_TX) ||
        (msgType == CAN_MSG_OBJ_TYPE_RXTX_REMOTE))
    {
        msgCtrl |= ((Uint32)msgLen & CAN_IF1MCTL_DLC_M);
    }

    //
    // If this is a single transfer or the last mailbox of a FIFO, set EOB bit.
    // If this is not the last entry in a FIFO, leave the EOB bit as 0.
    //
    if((flags & CAN_MSG_OBJ_FIFO) == 0U)
    {
        msgCtrl |= CAN_IF1MCTL_EOB;
    }

    //
    // Enable transmit interrupts if they should be enabled.
    //
    msgCtrl |= (flags & CAN_MSG_OBJ_TX_INT_ENABLE);

    //
    // Enable receive interrupts if they should be enabled.
    //
    msgCtrl |= (flags & CAN_MSG_OBJ_RX_INT_ENABLE);

    //
    // Set the Control, Arb, and Mask bit so that they get transferred to the
    // Message object.
    //
    cmdMaskReg |= CAN_IF1CMD_ARB;
    cmdMaskReg |= CAN_IF1CMD_CONTROL;
    cmdMaskReg |= CAN_IF1CMD_MASK;
    cmdMaskReg |= CAN_IF1CMD_DIR;

    //
    // Write out the registers to program the message object.
    //
    ( CanaRegs.CAN_IF1MSK.all) = maskReg;
    ( CanaRegs.CAN_IF1ARB.all) = arbReg;
    ( CanaRegs.CAN_IF1MCTL.all) = msgCtrl;

    //
    // Transfer data to message object RAM
    //
    ( CanaRegs.CAN_IF1CMD.all) =
    cmdMaskReg | (objID & CAN_IF1CMD_MSG_NUM_M);
}

//*****************************************************************************
//
// CAN_sendMessage
//
//*****************************************************************************
static inline void
CAN_writeDataReg(const Uint16 *const data)
{
    CanaRegs.CAN_IF1DATA.bit.Data_0 = data[0];
    CanaRegs.CAN_IF1DATA.bit.Data_1 = data[1];
    CanaRegs.CAN_IF1DATA.bit.Data_2 = data[2];
    CanaRegs.CAN_IF1DATA.bit.Data_3 = data[3];

    CanaRegs.CAN_IF1DATB.bit.Data_4 = data[4];
    CanaRegs.CAN_IF1DATB.bit.Data_5 = data[5];
    CanaRegs.CAN_IF1DATB.bit.Data_6 = data[6];
    CanaRegs.CAN_IF1DATB.bit.Data_7 = data[7];

}

static inline void
CAN_readDataReg(uint16_t *data)
{
    data[0] = CanaRegs.CAN_IF2DATA.bit.Data_0;
    data[1] = CanaRegs.CAN_IF2DATA.bit.Data_1;
    data[2] = CanaRegs.CAN_IF2DATA.bit.Data_2;
    data[3] = CanaRegs.CAN_IF2DATA.bit.Data_3;

    data[4] = CanaRegs.CAN_IF2DATB.bit.Data_4;
    data[5] = CanaRegs.CAN_IF2DATB.bit.Data_5;
    data[6] = CanaRegs.CAN_IF2DATB.bit.Data_6;
    data[7] = CanaRegs.CAN_IF2DATB.bit.Data_7;

}

static inline  bool
CAN_readMessage(Uint32 objID,Uint32 *addrid,
                Uint16 *msgData)
{
    bool status;
    Uint16 msgCtrl = 0U;

    //
    // Check the arguments.
    //
//    ASSERT(CAN_isBaseValid(base));
//    ASSERT((objID <= 32U) && (objID != 0U));

    //
    // Set the Message Data A, Data B, and control values to be read
    // on request for data from the message object.
    //
    // Transfer the message object to the message object IF register.
    //
    (CanaRegs.CAN_IF2CMD.all) =
    ((Uint32)CAN_IF2CMD_DATA_A | (Uint32)CAN_IF2CMD_DATA_B |
     (Uint32)CAN_IF2CMD_CONTROL | (objID & CAN_IF2CMD_MSG_NUM_M) |
     (Uint32)CAN_IF2CMD_ARB);

    //
    // Wait for busy bit to clear
    //
//    while(((CanaRegs.CAN_IF2CMD.all) & CAN_IF2CMD_BUSY) == CAN_IF2CMD_BUSY)
//    {
//    }

    //
    // Read out the IF control Register.
    //
    msgCtrl = (CanaRegs.CAN_IF2MCTL.all);

    //
    // See if there is new data available.
    //
    if((msgCtrl & CAN_IF2MCTL_NEWDAT) == CAN_IF2MCTL_NEWDAT)
    {
        //
        // Read out the data from the CAN registers.
        //
        CAN_readDataReg(msgData);

        status = true;

        //
        // Now clear out the new data flag
        //
        (CanaRegs.CAN_IF2CMD.all) = ((Uint32)CAN_IF2CMD_TXRQST |
                                        (objID & CAN_IF2CMD_MSG_NUM_M));

        //
        // Wait for busy bit to clear
        //
//        while(((CanaRegs.CAN_IF2CMD.all) & CAN_IF2CMD_BUSY) ==
//               CAN_IF2CMD_BUSY)
//        {
//        }
    }
    else
    {
        status = false;
    }

    *addrid  = (((CanaRegs.CAN_IF2ARB.all)) & CAN_IF2ARB_ID_M);
    
    return(status);
}


static inline  void
CAN_sendMessage(Uint32 objID, Uint16 msgLen,
                const Uint16 *msgData)
{
    Uint32 msgCtrl = 0U;

    //
    // Check the arguments.
    //
//    ASSERT(CAN_isBaseValid(base));
//    ASSERT((objID <= 32U) && (objID > 0U));
//    ASSERT(msgLen <= 8U);

    //
    // Set IF command to read message object control value
    //
    // Set up the request for data from the message object.
    // Transfer the message object to the IF register.
    //
    (CanaRegs.CAN_IF1CMD.all) = ((Uint32)CAN_IF1CMD_CONTROL |
                                     (objID & CAN_IF1CMD_MSG_NUM_M));

    //
    // Wait for busy bit to clear
    //
//    while(((CanaRegs.CAN_IF1CMD.all) & CAN_IF1CMD_BUSY) == CAN_IF1CMD_BUSY)
//    {
//    }

    //
    // Read IF message control
    //
    msgCtrl = (CanaRegs.CAN_IF1MCTL.all);

    //
    // Check provided DLC size with actual Message DLC size
    //
//    ASSERT((msgCtrl & CAN_IF1MCTL_DLC_M) == msgLen);

    //
    // Write the data out to the CAN Data registers.
    //
    CAN_writeDataReg(msgData);

    //
    //  Set Data to be transferred from IF
    //
    if(msgLen > 0U)
    {
        msgCtrl = CAN_IF1CMD_DATA_B | CAN_IF1CMD_DATA_A;
    }
    else
    {
        msgCtrl = 0U;
    }

    //
    // Set Direction to write
    //
    // Set Tx Request Bit
    //
    // Transfer the message object to the message object specified by
    // objID.
    //
    (CanaRegs.CAN_IF1CMD.all) = (msgCtrl | (Uint32)CAN_IF1CMD_DIR |
                                     (Uint32)CAN_IF1CMD_TXRQST |
                                     (objID & CAN_IF1CMD_MSG_NUM_M));
}



////////均流计算排序
////////

////////地址排序
////////
//////////
//////////////can接收解析
//static inline  void
//CAN_Message_ex(void)
//{
//    Uint16 uaddrcmd;
//    
//    uaddrcmd = CanRecData.CanId.bit.ADDRcmd;
//    
//    if(uaddrcmd==ADDRcmd_on)//1、当正常接收通信
//    {
//        
//    }
//
//}
//
////////////////////
void init_can_data(void)
{
    Uint16 i;
    uMdlAddMes.uIndex       = 0;
    uMdlAddMes.MDADDRID_num = 0; 
    for(i=0;i<=recnum;i++)
    {
        uMdlAddMes.MDADDRID[i] = 0;
    }
    uMdlAddMes.uSelfID           = 0x1234567;//自己的自身ID
    uMdlAddMes.uTranEND_num      = 0;
    sCanMes.uCalADDR_Cyle        = 0;
    sCanMes.uCanRec_count        = 0;

    uMdlAddMes.uCanState.all     = 0;
    uMdlAddMes.uCanState.bits.bCalIDCmd = 1;
    uMdlAddMes.uReqIDnum         = 0;
}

void init_can(void)
{
    EALLOW;
    InitECanaGpio();
    CAN_initModule();
    CAN_setBitRate( DEVICE_SYSCLK_FREQ, 500000, 20);
    
    EDIS;
////发送配置//
    CanTrsData.CanId.bit.ADDR     = TX_addrID_MBOX11;
    CanTrsData.CanId.bit.LogADDR  = 0xff;
    CanTrsData.CanId.bit.PTP      = BORAD_ALL;
    CanTrsData.CanId.bit.ADDRcmd  = ADDRcmd_on;
    
    CAN_setupMessageObject(TX_addr_MBOX11, CanTrsData.CanId.all,
                           CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_TX, 0,
                           CAN_MSG_OBJ_NO_FLAGS, 8);

////接受配置////
    //! The \e flags parameter can be set as \b CAN_MSG_OBJ_NO_FLAGS if no flags
    //! are required or the parameter can be a logical OR of any of the following
    //! values:
    //! - \b CAN_MSG_OBJ_TX_INT_ENABLE    - Enable Transmit Interrupts
    //! - \b CAN_MSG_OBJ_RX_INT_ENABLE    - Enable Receive Interrupts
    //! - \b CAN_MSG_OBJ_USE_ID_FILTER    - Use filtering based on the Message ID
    //! - \b CAN_MSG_OBJ_USE_EXT_FILTER   - Use filtering based on the Extended
    //!                                     Message ID
    //! - \b CAN_MSG_OBJ_USE_DIR_FILTER   - Use filtering based on the direction of
    //!                                     the transfer
    //! - \b CAN_MSG_OBJ_FIFO             - Message object is part of a FIFO
    //!                                     structure and isn't the final message
    //!                                     object in FIFO

    CAN_setupMessageObject(RX_MBOX1, RX_addrID,
                           CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                           (CAN_MSG_OBJ_USE_EXT_FILTER| CAN_MSG_OBJ_NO_FLAGS),
   						   8);
   						   

    CAN_setupMessageObject(RX_MBOX2, RX_addrID,
                           CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                           (CAN_MSG_OBJ_USE_EXT_FILTER| CAN_MSG_OBJ_NO_FLAGS),
   						   8);

    CAN_setupMessageObject(RX_MBOX3, RX_addrID,
                           CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                           (CAN_MSG_OBJ_USE_EXT_FILTER| CAN_MSG_OBJ_NO_FLAGS),
   						   8);

    CAN_setupMessageObject(RX_MBOX4, RX_addrID,
                           CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                           (CAN_MSG_OBJ_USE_EXT_FILTER| CAN_MSG_OBJ_NO_FLAGS),
   						   8);

    CAN_setupMessageObject(RX_MBOX5, RX_addrID,
                           CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                           (CAN_MSG_OBJ_USE_EXT_FILTER| CAN_MSG_OBJ_NO_FLAGS),
   						   8);
    CAN_setupMessageObject(RX_MBOX6, RX_addrID,
                           CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                           (CAN_MSG_OBJ_USE_EXT_FILTER| CAN_MSG_OBJ_NO_FLAGS),
   						   8);

    CAN_setupMessageObject(RX_MBOX7, RX_addrID,
                           CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX,0,
                           (CAN_MSG_OBJ_USE_EXT_FILTER| CAN_MSG_OBJ_NO_FLAGS),
   						   8);
   						   

    CAN_setupMessageObject(RX_MBOX8, RX_addrID,
                           CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX,0,
                           (CAN_MSG_OBJ_USE_EXT_FILTER| CAN_MSG_OBJ_NO_FLAGS),
   						   8);

    CAN_setupMessageObject(RX_MBOX9, RX_addrID,
                           CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX,0,
                           (CAN_MSG_OBJ_USE_EXT_FILTER| CAN_MSG_OBJ_NO_FLAGS),
   						   8);


    CAN_startModule();
    init_can_data();

    CAN_sendMessage(TX_addr_MBOX11, 8,
                        CanTrsData.CanData.Dat);
                        
    
}




