/***************************************************************************
 *    DESCRIPTION:   Can subroutines  
 *    SOURCE:        canroutines.c
 *    Date:         10-16-2005 
 *    AUTHOR:        Jianjian Song
 *    Reference:   page 633, Embedded Systems by Steven Barrett and Daniel Pack,
 ****************************************************************************/

#include "can.h"



// reference: Embedded Systems by Steven Barrett and Daniel Pack, page 633
//====================== can_initialize() ========================
void can_initialize(){
// Can0 is declared in projectglobals.h as tMSCAN can0
// PM0 is RxCAN pin and is forced to be input if MSCAN receiver is enabled.
// PM1 is TxCAN pin and is forced to be output if MSCAN transmit is enabled.
//	while (Can0.canctl1.bit.slpak==0)
 //   Can0.canctl0.bit.slprq = 1;  // put MSCAN to sleep
  Can0.canctl1.bit.cane = 1;  //enable MSCAN module 
// place CAN in init mode

  Can0.canctl0.bit.initrq = 1;  //make initialization mode request
  while (Can0.canctl1.bit.initak==0);

// register values can now be changed
  Can0.canctl1.bit.listen = 0;  //turn off listen mode
  Can0.canctl1.bit.clksrc = 1;  //use bus clock 
  Can0.canbtr0.byte=0b11111111;
  Can0.canbtr1.byte=0b11111111;  //can bit timing
  Can0.canidac.bit.idam1=1;
// initialize indentifier mask registers to 1 to ignore acceptance register bit checks 
  Can0.canid[0].canidmr.b[0] = 0xff;  // accept all messages
  Can0.canid[0].canidmr.b[1] = 0xff;
  Can0.canid[0].canidmr.b[2] = 0xff;
  Can0.canid[0].canidmr.b[3] = 0xff;
  Can0.canid[1].canidmr.b[0] = 0xff;  // accept all messages
  Can0.canid[1].canidmr.b[1] = 0xff;
  Can0.canid[1].canidmr.b[2] = 0xff;
  Can0.canid[1].canidmr.b[3] = 0xff;
// get out of initialization mode
  while (Can0.canctl1.bit.initak==1) {
    Can0.canctl0.bit.initrq=0;    
  }; 
  Can0.canctl1.bit.cane = 1;  //enable MSCAN module 
// wait until the module is synchronized with the CAN bus
  while ((Can0.canctl0.byte & SYNCH) ==0) {
  };
  return;
}; // end of initialize_can()

//====================== can_receive_message() ===================//
void can_receive_message(uchar *voltage){
uint  timestamp;
  while ((Can0.canctl0.byte & SYNCH) ==0) {
  };
  while(Can0.canrflg.bit.rxf==0) {
  } //wait until Receive Buffer is full
    *voltage =  Can0.rxbuf.dsr[0];
   timestamp = Can0.txbuf.tsr;  //get time stamp
  Can0.canrflg.bit.rxf=1; //clear the flag
  return;
};

//====================== can_send_message() ======================//
uchar can_send_message(uchar voltage){
// wait for synch
while ((Can0.canctl0.byte & SYNCH) ==0) {
  };

// select transmit buffer 0
  Can0.cantbsel.bit.tx=0b001;
//set up transmit buffer
  Can0.txbuf.id.b[0]=0xFF;  //any message ID
  Can0.txbuf.id.b[1]=0xFF;
  Can0.txbuf.id.b[2]=0xFF;
  Can0.txbuf.id.b[3]=0xFE;  //RTR=0 for data frame
  Can0.txbuf.dsr[0]= voltage;
  Can0.txbuf.dlr = 1; //one byte data
  Can0.txbuf.tbpr = 1;  //priority register. lowest priority number wins
  while(Can0.cantflg.bit.txe==0b110) {
  }// wait for previos transmission to be over
  Can0.cantflg.bit.txe = 0b001;  //set the flag to clear it to start tranmission
  return(1); 
};