📄 flexcan.c
字号:
/*
static unsigned char can_buf_data[10]="1 2 a b c";
static unsigned char *can_buf = can_buf_data;
static unsigned char buf_rec[10]={0};
static unsigned char *rec_buf = buf_rec;
static char err = 0;
*/
#include "common.h"
#include "FlexCAN.h"
#define debug_can 1
#undef debug_can
/*
*NOTE:#define MCF_CAN_IMASK (*(vuint16*)(&__IPSBAR[0x1C002A]))
#define MCF_CAN_IFLAG (*(vuint16*)(&__IPSBAR[0x1C0032]))
与pdf上定义的寄存器地址不同。
*/
void FlexCAN_init (void)
{
int i=0;
// printf("\nStart init the FlexCAN module!\n ");
#ifdef debug_can
printf("MCF_GPIO_PUAPAR=%x\n",MCF_GPIO_PUAPAR);
#endif
//configue the PIN
MCF_GPIO_PUAPAR |= 0xa0;//select the pin as can
#ifdef debug_can
printf("had configured the can pin!\n");
printf("MCF_GPIO_PUAPAR=%x\n",MCF_GPIO_PUAPAR);
#endif
MCF_CAN_CANCTRL = 0;
MCF_CAN_CANMCR |= MCF_CAN_CANMCR_MDIS;//disable can module
MCF_CAN_CANCTRL |= MCF_CAN_CANCTRL_CLKSRC;//select the fsys as the clock
MCF_CAN_CANMCR &= ~MCF_CAN_CANMCR_MDIS;//enable can module
MCF_CAN_CANMCR |= MCF_CAN_CANMCR_FRZ;//freeze mode enable
MCF_CAN_CANMCR |= MCF_CAN_CANMCR_HALT;//enter freeze mode
#ifdef debug_can
//for debug
printf("start entering the freeze mode !\n");
printf("MCF_CAN_CANMCR=%x\n",MCF_CAN_CANMCR);
#endif
while( (MCF_CAN_CANMCR & MCF_CAN_CANMCR_FRZACK) == 0);//wait until have enter freeze mode
#ifdef debug_can
//for debug
printf("enter freeze mode!\n");
#endif
/*********************************************************
*1. Initialize all operation modes in the CANCTRL register.
**********************************************************/
//Initialize the bit timing parameters PROPSEG, PSEGS1, PSEG2, and RJW.
MCF_CAN_CANCTRL |= MCF_CAN_CANCTRL_PROPSEG(7);//??? can be changed. the value is 0-7;set the Propagation segment max
MCF_CAN_CANCTRL |= MCF_CAN_CANCTRL_PSEG1(7);//??can be changed. hte value is 0-7;
MCF_CAN_CANCTRL |= MCF_CAN_CANCTRL_PSEG2(7);//??can be changed. the value is 1-7;
MCF_CAN_CANCTRL |= MCF_CAN_CANCTRL_RJW(3);//??can be changed.the value is 0-3;
//Select the S-clock rate by programming the PRESDIV field.
MCF_CAN_CANCTRL |= MCF_CAN_CANCTRL_PRESDIV(0x0f);//??set S-clock
//Select the internal arbitration mode via the LBUF bit.
MCF_CAN_CANCTRL |= MCF_CAN_CANCTRL_LBUF;//select Lowest numbered buffer is transmitted first
//for debug
//set loop_mode
//printf("set loop mode !\n");
//MCF_CAN_CANCTRL |= (1)<<12;//set loop_mode
MCF_CAN_CANCTRL |= (1<<7);//set SMP
/********************************************************************
*2. Initialize message buffers.
*********************************************************************/
//here we set 0-6,14 MBs to transmit.set 7-13,15MBs to receive.
for(i = 0; i < 7; i++)
{
MCF_CAN_MB_CS(i) = (0b1000)<<24;//set transmit inactive
#ifdef debug_can
printf("MCF_CAN_MB_CS(%d)=%x\n",i,MCF_CAN_MB_CS(i));
#endif
}
MCF_CAN_MB_CS(14) = 0x08<<24;
for (i=7; i<14; i++)
{
MCF_CAN_MB_CS(i) = 0b0000<<24;//set receive active and empty
#ifdef debug_can
printf("MCF_CAN_MB_CS(%d)=%x\n",i,MCF_CAN_MB_CS(i));
#endif
}
MCF_CAN_MB_CS(15) =0x0<<24;
//All other entries in each message buffer should be initialized as required.
for(i=0;i<16;i++)
{
MCF_CAN_MB_CS(i) &= ~(1<<21);//select Standard frame format
//MCF_CAN_MB_ID(i) = i<<18;//set ID,you can chang it as you like
//for debug
if(i == 7)
{
MCF_CAN_MB_ID(i) = 0b10101010101<<18;
}
else
{
MCF_CAN_MB_ID(i) = i<<18;//set ID,you can chang it as you like
}
}
//Control/status word to mark the Rx MB as active and empty (CODE = 1000)
for (i=7; i<14; i++)
{
MCF_CAN_MB_CS(i) = 0b0100<<24;//set receive active and empty
#ifdef debug_can
printf("MCF_CAN_MB_CS(%d)=%x\n",i,MCF_CAN_MB_CS(i));
#endif
}
MCF_CAN_MB_CS(15) =0b0100<<24;
/*****************************************************************
*3. Initialize RXGMASK, RX14MASK, and RX15MASK registers for acceptance mask as needed.
******************************************************************/
MCF_CAN_RXGMASK = MCF_CAN_RXGMASK_MI(0x1FFFFFFF);//compare every ID bit
MCF_CAN_RX14MASK = MCF_CAN_RX14MASK_MI(0x1FFFFFFF);//compare every ID bit
MCF_CAN_RX15MASK = MCF_CAN_RX15MASK_MI(0x1FFFFFFF);//compare every ID bit
/*****************************************************************
*4. Initialize FlexCAN interrupt handler.
******************************************************************/
//here we mask all FlexCAN interrupt
//Initialize the interrupt controller registers for any needed interrupts.
//Set the required mask bits in the IMASK register (for all message buffer interrupts) and the CANCTRL (for bus off and error interrupts).
MCF_CAN_IMASK = 0x0;//mask all 16 MB interrupt
MCF_CAN_CANCTRL &= ~MCF_CAN_CANCTRL_BOFFMSK;
MCF_CAN_CANCTRL &= ~MCF_CAN_CANCTRL_ERRMSK;
/****************************************************************
*5. Clear the CANMCR[HALT] bit. At this point, the FlexCAN will attempt to synchronize with the CAN bus.
******************************************************************/
MCF_CAN_CANMCR &= ~MCF_CAN_CANMCR_HALT;//exit freeze mode
MCF_CAN_CANMCR &= ~(1<<23); //set no supervisor visit mode
// printf("exit freeze mode, end of init!\n");
#ifdef debug_can
printf("MCF_CAN_CANCTRL=%x\n",MCF_CAN_CANCTRL);
printf("MCF_CAN_IMASK=%x\n",MCF_CAN_IMASK);
printf("MCF_CAN_CANMCR=%x\n",MCF_CAN_CANMCR);
printf("MCF_CAN_MB_CS(1)=%x\n",MCF_CAN_MB_CS(1));
printf("MCF_CAN_MB_ID(7)=%d",MCF_CAN_MB_ID(7)>>18);
printf("MCF_CAN_MB_CS(7)=%x\n",MCF_CAN_MB_CS(7));
#endif
//release the mb,read the free-running timer
i = MCF_CAN_TIMER;
return;
}
/****************************************************************
*function: transmit data from mb_no
*err : 0-done right 1-done wrong
*******************************************************************/
void transmit_data(char mb_no,uint32 id,unsigned char *databuf,unsigned char data_length,char transmit_code,char rtr,char ide,char *err)
{
//the MB should be inactive
uint32 i=0;
if(mb_no > 15 || mb_no < 0)
{
printf("\nmb_no = %d is not valid!\n",mb_no);
*err = 1;
return;
}
if(data_length>8 || data_length < 0)
{
printf("\n length is not valid\n");
*err =1;
return;
}
if(rtr != 0 && rtr != 1)
{
printf("\nrtr should be 0 or 1");
*err = 1;
return;
}
if(ide != 0 && ide != 1)
{
printf("\nide should be 0 or 1");
*err = 1;
return;
}
#ifdef debug_can
printf("enter transmit_data function\n");
#endif
#ifdef debug_can
printf("MCF_CAN_MB_CS(%d)= %x\n",mb_no,MCF_CAN_MB_CS(mb_no));
#endif
if ( ( (MCF_CAN_MB_CS(mb_no) & MCF_CAN_MB_CODE_MASK) != MCF_CAN_MB_CODE_RX_INACTIVE)
&& ( (MCF_CAN_MB_CS(mb_no) & MCF_CAN_MB_CODE_MASK) != MCF_CAN_MB_CODE_TX_INACTIVE) )
{
printf("no.%d of mbs is active,make the inactive\n ",mb_no);
printf("MCF_CAN_MB_CS(%d)= %x\n",mb_no,MCF_CAN_MB_CS(mb_no));
*err = 1;
//release the mb,read the free-running timer
i = MCF_CAN_TIMER;
return;
}
else//inactive
{
#ifdef debug_can
printf("inactive\n");
#endif
printf("transmit form mb%d to ID %x(16 format)!\n",mb_no,id);
//MCF_CAN_MB_CS(mb_no) &= ~MCF_CAN_MB_RTR_MASK;
#ifdef debug_can
printf("MCF_CAN_MB_CS(%d)= %x\n",mb_no,MCF_CAN_MB_CS(mb_no));
#endif
#ifdef debug_can
printf("rtr=%d\n",rtr<<20);
#endif
//i = MCF_CAN_MB_CS(mb_no) ;
//MCF_CAN_MB_CS(mb_no) = ( ( i & (~MCF_CAN_MB_RTR_MASK) ) | (rtr<<20) );
//MCF_CAN_MB_CS(mb_no) = MCF_CAN_MB_CS(mb_no)|(rtr<<20); //set rtr of C/S
#ifdef debug_can
printf("MCF_CAN_MB_CS(%d)= %x\n",mb_no,MCF_CAN_MB_CS(mb_no));
#endif
MCF_CAN_MB_ID(mb_no) = id; //ID
//for debug
//printf("MCF_CAN_MB_ID(%d)=%d\n",mb_no,MCF_CAN_MB_ID(mb_no)>>18);
printf("MCF_CAN_MB_ID(%d)=%x\n",mb_no,MCF_CAN_MB_ID(mb_no));
#ifdef debug_can
printf("transmit data is as below:\n");
#endif
for(i=0;i<data_length;i++) //data bytes
{
//for deubg
MCF_CAN_MB_DATAFIELDS(mb_no,i) = *(databuf+i);
//MCF_CAN_MB_DATAFIELDS(mb_no,i) = 255;
#ifdef debug_can
printf("data[%d]=%d\n",i,MCF_CAN_MB_DATAFIELDS(mb_no,i));
#endif
}
#ifdef debug_can
printf("MCF_CAN_MB_CS(%d)= %x\n",mb_no,MCF_CAN_MB_CS(mb_no));
#endif
i = MCF_CAN_MB_CS(mb_no);
MCF_CAN_MB_CS(mb_no) = ( (i & 0xF0C0FFFF)
| (data_length<<16)
| (transmit_code<<24)
| (rtr<<20)
| (ide<<21));
//MCF_CAN_MB_CS(mb_no) &= ~0x000F0000;//chang the length
#ifdef debug_can
printf("MCF_CAN_MB_CS(%d)= %x\n",mb_no,MCF_CAN_MB_CS(mb_no));
printf("MCF_CAN_MB_CS(%d)= %x\n",mb_no,MCF_CAN_MB_CS(mb_no));
printf("MCF_CAN_MB_CS(%d)= %x\n",mb_no,MCF_CAN_MB_CS(mb_no));
printf("MCF_CAN_MB_CS(%d)= %x\n",mb_no,MCF_CAN_MB_CS(mb_no));
#endif
//MCF_CAN_MB_CS(mb_no) = MCF_CAN_MB_CS(mb_no)|(data_length<<16);
//MCF_CAN_MB_CS(mb_no) = MCF_CAN_MB_CS(mb_no)&(~MCF_CAN_MB_CODE_MASK);//active code
//active code
//i = MCF_CAN_MB_CS(mb_no);
//MCF_CAN_MB_CS(mb_no) = (i & 0xF0FFFFFF) | (transmit_code<<24);
#ifdef debug_can
printf("MCF_CAN_MB_CS(%d)= %x\n",mb_no,MCF_CAN_MB_CS(mb_no));
#endif
//to transmit correctly ,we must printf below ,i'm sorry and i dont't konw why? :(
//#ifdef debug_can
printf("transmit_code=%x\n",transmit_code<<24);
//#endif
//wait transmit compelet
for(i = 0; i < 6553500; i++)
{
if( (MCF_CAN_IFLAG & (1<<mb_no)) != 0)
{
MCF_CAN_IFLAG = 1<<mb_no;//transmit compelet
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -