Created
August 30, 2011 11:20
-
-
Save steakunderscore/1180691 to your computer and use it in GitHub Desktop.
Example CAN imp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//CAN SAMPLE AT91SAM7X256 48MHz YAGARTO | |
//BRP = ((1 / (CAN_baudrate *16bit))* 48MHz) -1 | |
//sample: 500kbaud @48MHz ((1/(500000*16))*48MHz)-1 =5 =>CAN_BR = 0x053255; | |
//sample: 100kbaud @48MHz ((1/(100000*16))*48MHz)-1 =29 =>CAN_BR = 0x1D3255; | |
#define CAN_BR_500K 0x00053255 | |
#define CAN_BR_250K 0x000B3255 | |
#define CAN_BR_200K 0x000E3255 | |
#define CAN_BR_150K 0x00133255 | |
#define CAN_BR_125K 0x00173255 | |
#define CAN_BR_100K 0x001D3255 | |
#define CAN_BR_83K 0x00233255 | |
#define CAN_BR_75K 0x00273255 | |
#define CAN_BR_50K 0x003B3255 | |
#define CAN_BR_25K 0x00773255 | |
//can message structure | |
typedef struct s_can_message | |
{ | |
unsigned int ID; //ID | |
unsigned char DLC; //data length | |
unsigned int ML,MH; //l,h data | |
}can_message; | |
can_message rm[4]; //receive message | |
can_message tm[4]; //transmit message | |
unsigned int status; //status | |
unsigned char f_can0; //flag can receive message | |
unsigned short FILTER1 = 0x05AA;//filter ID | |
//CAN interrupt | |
void CANIrqHandler (void) | |
{ | |
//reset interrupt | |
status = AT91C_BASE_CAN->CAN_SR; | |
//check for enabled interrupt | |
status &= AT91C_BASE_CAN->CAN_IMR; | |
//WAKEUP interrupt | |
if(status & AT91C_CAN_WAKEUP) | |
{ | |
AT91C_BASE_CAN->CAN_IDR = AT91C_CAN_WAKEUP; | |
} | |
//MB0 INT | |
if(status & AT91C_CAN_MB0) | |
{ | |
//reset timer | |
AT91C_BASE_CAN->CAN_TCR = AT91C_CAN_MB0; | |
//get received ID | |
rm[0].ID =(unsigned int)((AT91C_BASE_CAN->CAN_MB0.CAN_MB_MID >> 18))& 0x07FF; | |
rm[0].DLC =(unsigned char)((AT91C_BASE_CAN->CAN_MB0.CAN_MB_MSR >>16) & 0x0F); | |
rm[0].ML =AT91C_BASE_CAN->CAN_MB0.CAN_MB_MDL; | |
rm[0].MH =AT91C_BASE_CAN->CAN_MB0.CAN_MB_MDH; | |
//set flag | |
f_can0 =1; | |
} | |
} | |
//init CAN | |
void can_init(void) | |
{ | |
//enable Pins | |
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA19_CANRX|AT91C_PA20_CANTX; | |
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA19_CANRX|AT91C_PA20_CANTX; | |
//enable Clock | |
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_CAN; | |
//init AIC-CAN | |
AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_CAN; | |
//disable Reception Mailbox 0 interrupt | |
AT91C_BASE_CAN->CAN_IDR = AT91C_CAN_MB0 | AT91C_CAN_MB1; | |
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_CAN] = 0x7; //set prior | |
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_CAN] = (unsigned int) CANIrqHandler; | |
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_CAN; //disable | |
AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_CAN; | |
//set baudrate | |
AT91C_BASE_CAN->CAN_BR = CAN_BR_100K; | |
//enable WAKEUP Int | |
AT91C_BASE_CAN->CAN_IER = AT91C_CAN_WAKEUP; | |
//enable Error Ints | |
AT91C_BASE_CAN->CAN_IER = AT91C_CAN_AERR | AT91C_CAN_CERR;// |AT91C_CAN_SERR;//| AT91C_CAN_BERR | |
// Configure Mailbox 0, RX | |
AT91C_BASE_CAN_MB0->CAN_MB_MMR = AT91C_CAN_MOT_RXOVERWRITE; | |
AT91C_BASE_CAN_MB0->CAN_MB_MAM = 0x000 << 18; //reset acceptance | |
AT91C_BASE_CAN_MB0->CAN_MB_MID = 0x000 << 18; //reset filter | |
//mailbox 1 transmission low byte first | |
AT91C_BASE_CAN_MB1->CAN_MB_MAM=0x00000000; //accept all | |
AT91C_BASE_CAN_MB1->CAN_MB_MMR=AT91C_CAN_MOT_TX;//enable TX and set MRDY | |
// Enable Reception Mailbox 0 interrupt | |
AT91C_BASE_CAN->CAN_IER = AT91C_CAN_MB0;// | AT91C_CAN_MB1; | |
// Clear and trigger Transfer | |
AT91C_BASE_CAN->CAN_TCR = AT91C_CAN_MB0; | |
AT91C_BASE_CAN->CAN_MB0.CAN_MB_MCR = AT91C_CAN_MTCR; | |
// Enable CAN | |
AT91C_BASE_CAN->CAN_MR = AT91C_CAN_CANEN; // | |
// Enable CAN in "Listen Only" mode | |
//AT91C_BASE_CAN->CAN_MR = AT91C_CAN_ABM | AT91C_CAN_CANEN; | |
} | |
//CAN_TX transmit data via MB1 | |
void can_tx(unsigned char tx_number) | |
{ | |
//set MB1 | |
AT91C_BASE_CAN_MB1->CAN_MB_MID=tm[tx_number].ID<<18; //11 bit Part A ID | |
AT91C_BASE_CAN_MB1->CAN_MB_MDH=tm[tx_number].MH; //data high | |
AT91C_BASE_CAN_MB1->CAN_MB_MDL=tm[tx_number].ML; //data low | |
if(AT91C_BASE_CAN->CAN_SR & AT91C_CAN_MB1) //if mailbox ready | |
{ | |
//send data | |
AT91C_BASE_CAN->CAN_MB1.CAN_MB_MCR =(tm[tx_number].DLC<<16)|AT91C_CAN_MTCR; | |
//wait until transmission ready | |
while(!(AT91C_BASE_CAN_MB1->CAN_MB_MSR & AT91C_CAN_MRDY)){} | |
} //end mailbox ready | |
} | |
... | |
//set and transmit data | |
tm[0].ID=0x55C<<18; //11 bit Part A ID | |
tm[0].MH=0x00000000; //data high | |
tm[0].ML=0x00000004; //data low | |
tm[0].DLC =8; | |
can_tx(0); | |
... | |
... | |
//set filter to read all | |
AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_CAN; | |
// Configure Mailbox 0, RX | |
AT91C_BASE_CAN_MB0->CAN_MB_MID = 0x000 << 18; | |
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_CAN; //enable | |
AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_CAN; | |
... | |
... | |
//set filter | |
AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_CAN; | |
// Configure Mailbox 0, RX | |
AT91C_BASE_CAN->CAN_MB0.CAN_MB_MID=FILTER1<<18; //11 bit Part A ID | |
AT91C_BASE_CAN_MB0->CAN_MB_MID = 0x000 << 18; | |
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_CAN; //enable | |
AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_CAN; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment