#include "can_S12G.h"
//==============================================================================
tCAN_MSG canRxMsg, canTxMsg; // can structures of messages
//==============================================================================
void init_CAN(UBYTE _canbtr0, UBYTE _canbtr1, UBYTE loop)
{

 if(loop) loop=CANCTL1_LOOPB_MASK;
 
 CANCTL0 = CANCTL0_INITRQ_MASK;
 while(!(CANCTL1 & CANCTL1_INITAK_MASK));
 
 CANCTL1  = 0xC0 | loop;                  // Enables MSCAN, Bus Clock, Loop Enabled/Disabled and Normal Operation
 CANBTR0  = _canbtr0;                     //
 CANBTR1  = _canbtr1;                     //

 CANIDMR0 = CANIDMR1 = CANIDMR2 = CANIDMR3 = 0xFF;
 CANIDMR4 = CANIDMR5 = CANIDMR6 = CANIDMR7 = 0xFF;

 CANCTL0  = 0x00;													// restarts MSCAN peripheral
 while(CANCTL1 & CANCTL1_INITAK_MASK);   // wait for Initialization Mode exit
 while(!(CANCTL0 & CANCTL0_SYNCH_MASK)); // waits for MSCAN synchronization with the CAN bus
}
//==============================================================================
//typedef struct { UINT  id; BOOL  RTR; UBYTE data[8]; UBYTE len; UBYTE prty;}tCAN_MSG;
//==============================================================================
BOOL MSCANSendMsg(tCAN_MSG *msg)
{	 
 UBYTE tbuf_n_empty_flag = 0, i;
 UBYTE *can_DSR = &CANTXDSR0;
 
 if(msg->len > 8) return(0);
 if(!(CANCTL0 & CANCTL0_SYNCH_MASK)) return(0);
 
 
 while(!(CANTFLG & (0x01<<tbuf_n_empty_flag))) // find empty transmit buffer from 3 buffers
  {
    tbuf_n_empty_flag ++;
    if(tbuf_n_empty_flag == 3) tbuf_n_empty_flag=0;
  }

 CANTBSEL  = 0x01 << tbuf_n_empty_flag;   // select found empty transmit buffer

 CANTXIDR0 = (UBYTE)(msg->id>>3);         // insert ID MSB
 CANTXIDR1 = (UBYTE)(msg->id<<5);         // insert last 3 bits of ID to the msb

 if(msg->RTR) CANTXIDR1 |= 0x10;
 
 for(i = 0; i < msg->len; i++) 
                              can_DSR[i] = msg->data[i];

 CANTXDLR  = msg->len;										// set message data length
 CANTXTBPR = msg->prty;										// set message internal priority 
 CANTFLG   = (0x01<<tbuf_n_empty_flag);   // clear flag to send message

 return(1);
}
//==============================================================================

BOOL MSCANGetMsg(tCAN_MSG *msg)
{
 UBYTE i;
 UBYTE *can_DSR = &CANRXDSR0;

 
 if(!(CANRFLG & CANRFLG_RXF_MASK)) return(0); // if no new message=>return
 if(CANRXIDR1 & 0x08)               return(0); // if not standard identifier=>return
 msg->id = ((CANRXIDR0<<3)&0x0700) | (UBYTE)(CANRXIDR0<<3) | (UBYTE)(CANRXIDR1>>5);
 
 if(CANRXIDR1 & 0x10) msg->RTR = 1;
 else										msg->RTR = 0;
 
 msg->len = CANRXDLR;
 for(i = 0; i < msg->len; i++)
                              msg->data[i] = can_DSR[i];
 CANRFLG = CANRFLG_RXF_MASK;
 return(1);
}
//==============================================================================
BOOL MSCANCheckRcvdMsg()
{
  /*
  UBYTE x;
  
  x=CANRFLG;
  x=x & CANRFLG_RXF_MASK;
  if(x) return(1);
  return(0);
  */
  if(CANRFLG & CANRFLG_RXF_MASK) return(1);
  return(0);
}
//==============================================================================
void createMessage(tCAN_MSG *msg,UINT id,BOOL RTR,UBYTE len,UBYTE prty,
                   UBYTE d0,UBYTE d1,UBYTE d2,UBYTE d3,UBYTE d4,UBYTE d5,UBYTE d6,UBYTE d7 )
{
  msg->id  = id;
  msg->RTR = RTR; 
  msg->data[0]= d0;
  msg->data[1]= d1;
  msg->data[2]= d2;
  msg->data[3]= d3;
  msg->data[4]= d4;
  msg->data[5]= d5;
  msg->data[6]= d6;
  msg->data[7]= d7;
  msg->len =len;       
  msg->prty=prty;
}
//==============================================================================




