?? sja_bcanfunc.c
字號:
/**
* @file
* Driver for the CAN chip SJA1000 in Basic CAN mode
*
* SJA_BCANFUNC.c
* Copyright(C) 2007 Agate Logic Corporation. All rights reserved.
* This file is licensed under the terms of Agate Logic SDK License Agreement.
*
* @author bxu@agatelogic.com.cn
*/
#define CAN_GLOBALS ///< define macro "CAN_GLOBALS" as empty
#include <ag1f1.h>
#include "SJA_BCANCONF.H"
#include <intrins.h>
#define ALLDELAY _nop_();_nop_();_nop_();_nop_();
/**
* @brief Write data to the specified register.
*
* The Function write the specified data to the specified register of CAN chip.
*
* @param Adr The address of the register to write to.
* @param Value The data to write.
*
* @return N/A
*/
void WriteSjaReg(uchar Adr, uchar Value)
{
CAN_CS=1;
ALLDELAY
CAN_RD=1;
ALLDELAY
CAN_WR=1;
ALLDELAY
CAN_DIR=0;//output direction
ALLDELAY
CAN_ALE=1;
ALLDELAY
CAN_ADDA=Adr;//addr output
ALLDELAY
CAN_ALE=0;//latch addr
ALLDELAY
CAN_CS=0;//chip select
ALLDELAY
CAN_ADDA=Value;//value output
ALLDELAY
CAN_WR=0;//WRITE start
ALLDELAY
CAN_WR=1;//WRITE end
ALLDELAY
CAN_CS=1;//chip unselect
ALLDELAY
}
/**
* @brief Read the specified register.
*
* The Function read the value of the specified register of CAN chip.
*
* @param Adr The address of the register to read from.
*
* @return The value of the specified register
*/
uchar ReadSjaReg(uchar Adr)
{
uchar uctmp=0;
CAN_CS=1;
ALLDELAY
CAN_RD=1;
ALLDELAY
CAN_WR=1;
ALLDELAY
CAN_DIR=0;//output direction
ALLDELAY
CAN_ALE=1;
ALLDELAY
CAN_ADDA=Adr;//addr output
ALLDELAY
CAN_ALE=0;//latch addr
ALLDELAY
CAN_DIR=1;//input direction
ALLDELAY
CAN_CS=0;//chip select
ALLDELAY
CAN_RD=0;//READ start
ALLDELAY
uctmp=CAN_ADDA;//value input
ALLDELAY
CAN_RD=1;//READ end
ALLDELAY
CAN_CS=1;//chip unselect
ALLDELAY
return uctmp;
}
/**
* @brief Test the interface of CAN chip.
*
* The Function first write the test register and then read back
* the value of the test register. If the value is equal the value written,
* that means the communication with CAN chip is right.
*
* @return The result of test.
* @retval 0 means the interface work right
* @retval 1 means the interface work wrong
*/
bit BCAN_CREATE_COMMUNATION(void)
{
WriteSjaReg(REG_TEST,0xaa);
if(ReadSjaReg(REG_TEST) == 0xaa)
{
return 0;
}
else
{
return 1;
}
}
/**
* @brief Drive the CAN chip enter the reset mode.
*
* The Function set the control register to drive the chip to enter the reset mode,
* then read back the value of the control register to check whether the chip has
* entered the reset mode.
*
* @return The result of the operation.
* @retval 0 means enter the reset mode successfully
* @retval 1 means enter the reset mode falsely
*/
bit BCAN_ENTER_RETMODEL(void)
{
unsigned char TempData;
TempData= ReadSjaReg(REG_CONTROL);
WriteSjaReg(REG_CONTROL, (TempData|0x01));
if((ReadSjaReg(REG_CONTROL)&0x01) == 1)
{
return 0;
}
else
{
return 1;
}
}
/**
* @brief Drive the CAN chip quit the reset mode.
*
* The Function set the control register to drive the chip to quit the reset mode,
* then read back the value of the control register to check whether the chip has
* quit the reset mode.
*
* @return The result of the operation.
* @retval 0 means quit the reset mode successfully
* @retval 1 means quit the reset mode falsely
*/
bit BCAN_QUIT_RETMODEL(void)
{
unsigned char TempData;
TempData= ReadSjaReg(REG_CONTROL);
WriteSjaReg(REG_CONTROL, (TempData&0xfe));
if((ReadSjaReg(REG_CONTROL)&0x01) == 0)
{
return 0;
}
else
{
return 1;
}
}
/// The present value to set the baud rate
unsigned char code SJA_BTR_CODETAB[]={
0xbf,0xff, //;5KBPS
0x67,0x2f, //;10KBPS
0x53,0x2F, //;20KBPS
0x87,0xFF, //;40KBPS
0x47,0x2F, //;50KBPS
0x83,0xFF, //;80KBPS
0x43,0x2f, //;100KBPS
0x03,0x1c, //;125KBPS
0x81,0xfa, //;200KBPS
0x01,0x1c, //;250KBPS
0x80,0xfa, //;400KBPS
0x00,0x1c, //;500KBPS
0x80,0xb6, //;666KBPS
0x00,0x16, //;800KBPS
0x00,0x14 //;1000KBPS
};
/**
* @brief Set the baud rate.
*
* The Function write the present value to the bus time register to set the baud rate as specified,
* then read back the value of the bus time register to check whether the register have set properly,
* if the register value is wrong then do the write and check operation again till 20 loops.
* This function can only run under reset mode.
*
* @param CAN_ByteRate The constant of the baud rate to set, refer to the header file.
*
* @return The result of the operation.
* @retval 0 means baud rate is set successfully
* @retval 1 means baud rate is set falsely
*/
bit BCAN_SET_BANDRATE(unsigned char CAN_ByteRate)
{
bit ErrorFlag = 1;
unsigned char ErrorCount = 0x20;
if(CAN_ByteRate>14)
{
ErrorFlag =1;
}
else
{
while(--ErrorCount)
{
WriteSjaReg(REG_BTR0,SJA_BTR_CODETAB[CAN_ByteRate*2]);
WriteSjaReg(REG_BTR1,SJA_BTR_CODETAB[CAN_ByteRate*2+1]);
if(ReadSjaReg(REG_BTR0) != SJA_BTR_CODETAB[CAN_ByteRate*2])continue;
if(ReadSjaReg(REG_BTR1) != SJA_BTR_CODETAB[CAN_ByteRate*2+1])continue;
ErrorFlag=0;
break;
}
}
return ErrorFlag ;
}
/**
* @brief Set the communication object.
*
* The Function set the acceptance code register and the acceptance mask register,
* then read back the value of the registers to check whether the register have set properly,
* This function can only run under reset mode.
*
* @param BCAN_ACR The value to write to the acceptance code register.
* @param BCAN_AMR The value to write to the acceptance mask register.
*
* @return The result of the operation.
* @retval 0 means set successfully
* @retval 1 means set falsely
*/
bit BCAN_SET_OBJECT(unsigned char BCAN_ACR,unsigned char BCAN_AMR)
{
WriteSjaReg(REG_ACR,BCAN_ACR);
if(ReadSjaReg(REG_ACR) != BCAN_ACR)
{
return 1;
}
WriteSjaReg(REG_AMR,BCAN_AMR);
if(ReadSjaReg(REG_AMR) != BCAN_AMR)
{
return 1;
}
return 0;
}
/**
* @brief Set the output mode and the output clock of CAN chip.
*
* The Function set the output control register and the clock divider register,
* then read back the value of the registers to check whether the register have set properly,
* This function can only run under reset mode.
*
* @param Out_Control The value to write to the output control register.
* @param Clock_Out The value to write to the clock divider register.
*
* @return The result of the operation.
* @retval 0 means set successfully
* @retval 1 means set falsely
*/
bit BCAN_SET_OUTCLK (unsigned char Out_Control, unsigned char Clock_Out)
{
WriteSjaReg(REG_OCR,Out_Control);
if(ReadSjaReg(REG_OCR) != Out_Control)
{
return 1;
}
WriteSjaReg(REG_CDR,Clock_Out);
return 0;
}
/**
* @brief Initialize the CAN chip.
*
* The Function write the specified value to the corresponding register
* to initialize the CAN chip.
* This function can only run under reset mode.
*
* @param BCAN_ACR The value to write to the acceptance code register.
* @param BCAN_AMR The value to write to the acceptance mask register.
* @param Bus_Timing0 The value to write to the bus time register 0.
* @param Bus_Timing1 The value to write to the bus time register 1.
* @param Out_Control The value to write to the output control register.
* @param Clock_Out The value to write to the clock divider register.
*
* @return The result of the operation.
* @retval 0 means the chip is initialized successfully
* @retval 1 means the chip is initialized falsely
*/
bit BCAN_HW_INIT(unsigned char BCAN_ACR,
unsigned char BCAN_AMR,
unsigned char Bus_Timing0,
unsigned char Bus_Timing1,
unsigned char Out_Control,
unsigned char Clock_Out
)
{
WriteSjaReg(REG_ACR,BCAN_ACR);
if(ReadSjaReg(REG_ACR) != BCAN_ACR)
{
return 1;
}
WriteSjaReg(REG_AMR,BCAN_AMR);
if(ReadSjaReg(REG_AMR) != BCAN_AMR)
{
return 1;
}
WriteSjaReg(REG_BTR0,Bus_Timing0);
if(ReadSjaReg(REG_BTR0) != Bus_Timing0)
{
return 1;
}
WriteSjaReg(REG_BTR1,Bus_Timing1);
if(ReadSjaReg(REG_BTR1) != Bus_Timing1)
{
return 1;
}
WriteSjaReg(REG_OCR,Out_Control);
if(ReadSjaReg(REG_OCR) != Out_Control)
{
return 1;
}
WriteSjaReg(REG_CDR,Clock_Out);
return 0;
}
/**
* @brief Write the data array to the transmit buffer.
*
* The Function write the specified data array to the transmit buffer.
*
* @param SendDataBuf The data array to write to the buffer.
*
* @return The result of the operation.
* @retval 0 means the data array is written successfully
* @retval 1 means the data array is written falsely
*/
bit BCAN_DATA_WRITE(unsigned char *SendDataBuf)
{
uchar TempCount,uctmp;
uctmp = ReadSjaReg(REG_STATUS);
if((uctmp & 0x08) == 0) //Check whether the last transmit operation has finished or not.
{
return 1;
}
if((uctmp & 0x04) == 0) //Check whether the transmit buffer is locked or not.
{
return 1;
}
if((SendDataBuf[1]&0x10)==0) //check the RTR bit
{
TempCount =(SendDataBuf[1]&0x0f)+2; //calculate the length of the data array
}
else
{
TempCount =2; //remote frame
}
for(uctmp=0;uctmp<TempCount;uctmp++)
{
WriteSjaReg(REG_TxBuffer1+uctmp,SendDataBuf[uctmp]);
}
return 0;
}
/**
* @brief Read the data array from the receive buffer.
*
* The Function read the data from the receive buffer and save them to the specified data array.
*
* @param RcvDataBuf The data array to save the data read from the recv buffer.
*
* @return The result of the operation.
* @retval 0 means receive successfully
* @retval 1 means receive falsely
*/
bit BCAN_DATA_RECEIVE(unsigned char *RcvDataBuf)
{
uchar TempCount,uctmp;
if((ReadSjaReg(REG_STATUS)&0x01)==0) //check the receive buffer is valid or not
{
return 1;
}
uctmp=ReadSjaReg(REG_RxBuffer2); //read recv buffer 2
if((uctmp&0x10)==0) // check the RTR bit
{
TempCount=(uctmp&0x0f)+2; //calculate the length of the data array
}
else
{
TempCount=2;
}
for(uctmp=0;uctmp<TempCount;uctmp++)
{
RcvDataBuf[uctmp]=ReadSjaReg(REG_RxBuffer1+uctmp);
}
return 0;
}
/**
* @brief Drive the CAN chip to do a command.
*
* The Function write the command to the command register to drive the chip to do this command.
*
* @param cmd The command to do.
*
* @return The result of the operation.
* @retval 0 means the command is done successfully
* @retval 1 means the command is done falsely
*/
bit BCAN_CMD_PRG(unsigned char cmd)
{
WriteSjaReg(REG_COMMAND,cmd);
switch(cmd)
{
case TR_CMD:
return 0;
break;
case AT_CMD:
if((ReadSjaReg(REG_STATUS) & 0x20)==0)
{
return 0;
}
else
{
return 1;
}
break;
case RRB_CMD:
if((ReadSjaReg(REG_STATUS) & 0x01)==1)
{
return 1;
}
else
{
return 0;
}
break;
case COS_CMD:
if((ReadSjaReg(REG_STATUS) & 0x02)==0)
{
return 0;
}
else
{
return 1;
}
break;
case GTS_CMD:
return 0;
break;
default:
return 1;
break;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -