Пример как есть:
настройка на прием 1 и 3го майлбокса
CODE
#define RECIEVE_MAILBOX_NUMBER_1 1
#define RECIEVE_MAILBOX_NUMBER_3 3
#define TRANSMIT_MAILBOX_NUMBER 2
__ramfunc void init_can_reception(struct can_cmd_s *p_can, Uint32 id)
{
//AT91PS_CAN base_can;
CanTransfer canTransfer1;
AT91PS_CAN_MB CAN_Mailbox;
CAN_Mailbox = AT91C_BASE_CAN0_MB0;
CAN_Mailbox =
(AT91PS_CAN_MB) ((unsigned int)(CAN_Mailbox +
RECIEVE_MAILBOX_NUMBER_1));
CAN_Mailbox->CAN_MB_MCR = 0x0;
CAN_Mailbox->CAN_MB_MMR = 0x00;
CAN_Mailbox->CAN_MB_MAM = AT91C_CAN_MIDvA & ((~id) << (18));
CAN_Mailbox->CAN_MB_MID = AT91C_CAN_MIDvA & (id << (18));
CAN_Mailbox->CAN_MB_MMR = AT91C_CAN_MOT_RX;
CAN_Mailbox = AT91C_BASE_CAN0_MB0;
CAN_Mailbox =
(AT91PS_CAN_MB) ((unsigned int)(CAN_Mailbox +
RECIEVE_MAILBOX_NUMBER_3));
CAN_Mailbox->CAN_MB_MCR = 0x0;
CAN_Mailbox->CAN_MB_MMR = 0x00;
CAN_Mailbox->CAN_MB_MAM = AT91C_CAN_MIDvA & ((~id) << (18));
CAN_Mailbox->CAN_MB_MID = AT91C_CAN_MIDvA & (id << (18));
p_can->accepted_id = AT91C_CAN_MIDvA & (id << (18));
CAN_Mailbox->CAN_MB_MMR = AT91C_CAN_MOT_RX;
AT91C_BASE_CAN0->CAN_IER = (1 << RECIEVE_MAILBOX_NUMBER_3);
AT91C_BASE_CAN0->CAN_IER = (1 << RECIEVE_MAILBOX_NUMBER_1);
}
//Начало передачи по кан:
if ((p_can->trans_state != CAN_SENDING) && (flag))
{
res = read_can_data(p_can, &hi, &low, &id);
if (res != 0)
{
CAN_Mailbox = AT91C_BASE_CAN0_MB0;
CAN_Mailbox =
(AT91PS_CAN_MB) ((unsigned int)(CAN_Mailbox +
TRANSMIT_MAILBOX_NUMBER));
status = disable_can_interrupt();
can_msr = CAN_Mailbox->CAN_MB_MSR;
if ((AT91C_CAN_MRDY & can_msr) != 0)
{
// dbg_send_str("Error busy");
enable_can_interrupt(status);
return 1;
}
CAN_Mailbox->CAN_MB_MCR = 0x0;
CAN_Mailbox->CAN_MB_MMR = 0x00;
CAN_Mailbox->CAN_MB_MID = AT91C_CAN_MIDvA & (id << 18); // ID 11
CAN_Mailbox->CAN_MB_MMR =
AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR;
CAN_Mailbox->CAN_MB_MDL = low;
CAN_Mailbox->CAN_MB_MDH = hi;
CAN_Mailbox->CAN_MB_MCR = AT91C_CAN_MTCR | (AT91C_CAN_MDLC & (res << 16));
// Mailbox Data Length Code
p_can->trans_state = CAN_SENDING;
enable_can_interrupt(status |
(1 << TRANSMIT_MAILBOX_NUMBER));
}
return 0;
}
Обработчик прерывания:
__ramfunc void CAN_Handler(void)
{
AT91PS_CAN_MB CAN_Mailbox;
unsigned int status;
unsigned int can_msr;
unsigned int message_mode;
unsigned int numMailbox;
int res;
int low,
hi;
unsigned short id;
status = (AT91C_BASE_CAN0->CAN_SR);
status &= (AT91C_BASE_CAN0->CAN_IMR);
if (status & AT91C_CAN_WAKEUP)
{
AT91C_BASE_CAN0->CAN_IDR = AT91C_CAN_WAKEUP;
pCAN0Transfer->test_can = AT91C_TEST_OK;
pCAN0Transfer->state = CAN_IDLE;
}
/*
if(status & AT91C_CAN_WARN){
can_cmd.error |= ERROR_CAN_WARN;
AT91C_BASE_CAN0->CAN_IDR = AT91C_CAN_WARN; // (CAN) Form Error
}
*/
// Mailbox event ?
if ((status & 0x0000FFFF) != 0)
{
for (numMailbox = 1; numMailbox < 4; numMailbox++)
{
CAN_Mailbox =
(AT91PS_CAN_MB) ((unsigned
int)(AT91C_BASE_CAN0_MB0 +
numMailbox));
can_msr = CAN_Mailbox->CAN_MB_MSR;
if ((AT91C_CAN_MMI & can_msr) == AT91C_CAN_MMI)
{
// test_error_cntr++;
can_cmd.error |= ERROR_CAN_MMI;
if (numMailbox == RECIEVE_MAILBOX_NUMBER_3)
{
can_cmd.error |=
ERROR_CAN_OVER_MAILBOX_3;
}
if (numMailbox == RECIEVE_MAILBOX_NUMBER_1)
{
can_cmd.error |=
ERROR_CAN_OVER_MAILBOX_1;
}
}
if ((AT91C_CAN_MABT & can_msr) == AT91C_CAN_MABT)
{
CAN_Mailbox->CAN_MB_MCR = AT91C_CAN_MACR;
// test_error_cntr++;
// can_cmd.error |= ERROR_CAN_ABT;
}
if ((AT91C_CAN_MRDY & can_msr) == AT91C_CAN_MRDY)
{
message_mode =
(CAN_Mailbox->CAN_MB_MMR >> 24) & 0x7;
if (message_mode == 0)
{
// test_error_cntr++;
can_cmd.error |= ERROR_CAN_MODE;
}
else if ((message_mode == CAN_MOT_RECEPT)
|| (message_mode ==
CAN_MOT_RECEPT_OW))
{
low = CAN_Mailbox->CAN_MB_MDL;
hi = CAN_Mailbox->CAN_MB_MDH;
dispatch_can_data(&can_cmd, hi, low,
(can_msr >> 16) &
0xF,
(CAN_Mailbox->
CAN_MB_MID &
AT91C_CAN_MIDvA) >>
18);
AT91C_BASE_CAN0->CAN_IER = 1 << numMailbox;
// test_all_recv += (can_msr>>16)&0xF;
CAN_Mailbox->CAN_MB_MMR = 0x0;
CAN_Mailbox->CAN_MB_MID =
can_cmd.accepted_id;
CAN_Mailbox->CAN_MB_MMR =
AT91C_CAN_MOT_RX;
CAN_Mailbox->CAN_MB_MCR =
AT91C_CAN_MTCR;
if (numMailbox ==
RECIEVE_MAILBOX_NUMBER_3)
{
// test_error_cntr++;
can_cmd.error |=
ERROR_CAN_OVER_MAILBOX;
}
}
else if (message_mode == CAN_MOT_TRANSMIT)
{
can_cmd.trans_state = CAN_IDLE;
can_msr = CAN_Mailbox->CAN_MB_MSR;
/*
if ((AT91C_CAN_MRDY & can_msr) == AT91C_CAN_MABT) {
CAN_Mailbox->CAN_MB_MCR = AT91C_CAN_MABT;
}
*/
if ((AT91C_CAN_MRDY & can_msr) ==
AT91C_CAN_MRDY)
{
CAN_Mailbox->CAN_MB_MCR = 0x0;
CAN_Mailbox->CAN_MB_MMR = 0x0;
res=0;
res = read_can_data(&can_cmd,
&hi, &low,
&id);
if (res)
{
CAN_Mailbox->CAN_MB_MID = AT91C_CAN_MIDvA & (id << 18); // ID 11
CAN_Mailbox->
CAN_MB_MMR =
AT91C_CAN_MOT_TX
|
AT91C_CAN_PRIOR;
CAN_Mailbox->
CAN_MB_MDL =
low;
CAN_Mailbox->
CAN_MB_MDH =
hi;
// Mailbox Data Length Code
CAN_Mailbox->CAN_MB_MCR = AT91C_CAN_MTCR | (AT91C_CAN_MDLC & (res << 16));
AT91C_BASE_CAN0->CAN_IER = 1 << numMailbox; //???????
can_cmd.trans_state =
CAN_SENDING;
}
}
else
{
can_cmd.error |=
ERROR_CAN_MRDY;
}
}
}
}
}
if ((status & 0xFFCF0000) != 0)
{
CAN_ErrorHandling(status, 0);
}
}
Сообщение отредактировал IgorKossak - Dec 9 2010, 11:35
Причина редактирования: Пользуйтесь тэгами