Skip to content

Instantly share code, notes, and snippets.

@steakunderscore
Created August 30, 2011 11:20
Show Gist options
  • Save steakunderscore/1180691 to your computer and use it in GitHub Desktop.
Save steakunderscore/1180691 to your computer and use it in GitHub Desktop.
Example CAN imp
//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