#include "can/can.h"
#include "leds/leds.h"
#include "bootloader/bootloader.h"
#include "queue/queue.h"
CanRxMsg RxMessage;
extern Uint16 upgrade_flag;
/**
* @brief can½ÓÊÕÖжÏ
*
*/
interrupt void can_rx_isr(void)
{
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
Uint32 can_id = 0;
Uint16 group;
volatile struct MBOX *Mailbox;
group = (ECanaRegs.CANGIF0.all) & 0x3F; // ÅжÏÊÇÄĸö½ÓÊÕÓÊÏä´¥·¢µÄÖжÏ
Mailbox = &ECanaMboxes.MBOX0 + group; // È¡´¥·¢ÖжÏÓÊÏäµÄµØÖ·
if (Mailbox->MSGID.bit.IDE == 1)
{ // IDE =1 ÊÕµ½µÄÏûÏ¢ÓÐÀ©Õ¹±êʶλ
can_id = Mailbox->MSGID.all & 0x1FFFFFFF;
}
else
{
can_id = Mailbox->MSGID.bit.STDMSGID;
}
switch (group)
{
case 0:
if ((can_id & 0x107020A0) == 0x107020A0)
{
// »ñÈ¡¶ÓÁеØÖ·
cmd_queue_t *queue = app_can_queue_get();
// Èë¶Ó½ÓÊÕµ½µÄcanÊý¾ÝÖ¡
queue_push(queue, (can_id >> 24) & 0xff);
queue_push(queue, (can_id >> 16) & 0xff);
queue_push(queue, (can_id >> 8) & 0xff);
queue_push(queue, (can_id >> 0) & 0xff);
queue_push(queue, Mailbox->MDL.byte.BYTE0);
queue_push(queue, Mailbox->MDL.byte.BYTE1);
queue_push(queue, Mailbox->MDL.byte.BYTE2);
queue_push(queue, Mailbox->MDL.byte.BYTE3);
queue_push(queue, Mailbox->MDH.byte.BYTE4);
queue_push(queue, Mailbox->MDH.byte.BYTE5);
queue_push(queue, Mailbox->MDH.byte.BYTE6);
queue_push(queue, Mailbox->MDH.byte.BYTE7);
//Éý¼¶±ê־λÖÃλ
upgrade_flag = 1;
}
break;
}
ECanaRegs.CANRMP.all = 0x0000003F; // Çå³ýGIF0.GMIF룬¼´Öжϱê־λ
}
/**
* @brief can³õʼ»¯
*
*/
void can_init(void)
{
struct ECAN_REGS ECanaShadow;
// ÅäÖÃÒý½Å
InitECanaGpio();
// ÅäÖÃÒý½ÅÓÃÓÚCAN
EALLOW;
ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
ECanaShadow.CANTIOC.bit.TXFUNC = 1;
ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;
ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
ECanaShadow.CANRIOC.bit.RXFUNC = 1;
ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;
EDIS;
EALLOW;
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.STM = 0; // Í˳ö²âÊÔģʽ
ECanaShadow.CANMC.bit.SCB = 1; // eCAN mode (reqd to access 32 mailboxes)
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
EDIS;
// ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
ECanaRegs.CANTA.all = 0xFFFFFFFF; // Clear all TAn bits
ECanaRegs.CANRMP.all = 0xFFFFFFFF; // Clear all RMPn bits
ECanaRegs.CANGIF0.all = 0xFFFFFFFF; // Clear all interrupt flag bits
ECanaRegs.CANGIF1.all = 0xFFFFFFFF;
// ²¨ÌØÂÊÉèÖÃ
EALLOW;
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.CCR = 1;
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
EDIS;
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all;
} while (ECanaShadow.CANES.bit.CCE != 1);
ECanaShadow.CANBTC.all = 0;
EALLOW;
ECanaShadow.CANBTC.all = ECanaRegs.CANBTC.all;
ECanaShadow.CANBTC.bit.BRPREG = 39;//ÉèÖò¨ÌØÂÊ125K
ECanaShadow.CANBTC.bit.TSEG2REG = 2;
ECanaShadow.CANBTC.bit.TSEG1REG = 10;
ECanaShadow.CANBTC.bit.SAM = 1;
ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.CCR = 0;
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
EDIS;
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all;
} while (ECanaShadow.CANES.bit.CCE != 0);
ECanaRegs.CANME.all = 0;
// ÕâÀïÊÇÉèÖýÓÊÕÌض¨IDµÄ¹¦ÄÜ
ECanaMboxes.MBOX0.MSGID.all = 0x107020A0; // ÉèÖýÓÊÕÏûÏ¢µÄÓÐЧID
ECanaMboxes.MBOX0.MSGID.bit.AME = 1; // AMEλΪ1ʹÄÜÑéÊÕÆÁ±Îλ
ECanaMboxes.MBOX0.MSGID.bit.IDE = 1;
ECanbLAMRegs.LAM0.all = 0xFFFFFFFF;
// ECanbLAMRegs.LAM0.all=0x000F0000;//ÓÊÏä0µÄ¾Ö²¿ÑéÊÕÆÁ±Î¼Ä´æÆ÷ÖÃλ¿É½ÓÊÕÈκÎidµÄ±¨ÎÄ(È«¾ÖÑéÊÕÆÁ±Î¼Ä´æÆ÷ÓÃÓÚsccģʽ)
ECanbLAMRegs.LAM0.bit.LAMI = 1;
// ÉèÖÃÓÊÏäÊǽÓÊÕ»¹ÊÇ·¢ËÍ
ECanaRegs.CANME.all = 0; // ÏȽûÓÃËùÓÐÓÊÏ䣬ºóÃæ»á´ò¿ªÖ¸¶¨Ê¹ÓõÄÓÊÏä
EALLOW;
ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
ECanaShadow.CANMD.bit.MD0 = 1; // Rx
ECanaShadow.CANMD.bit.MD16 = 0; // Tx
ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;
// ÉèÖÃÓÊÏäʹÄܺͽûÓÃ
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME0 = 1;
ECanaShadow.CANME.bit.ME16 = 1;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
EDIS;
DINT;
// ÖжÏÉèÖÃ
EALLOW;
ECanaRegs.CANGIM.all = 0;
ECanaRegs.CANMIM.all = 0x0001; // ʹÄÜÉÏÃæµÄ½ÓÊÕÓÊÏä(0)ÖжÏ
ECanaRegs.CANMIL.all = 0;
ECanaShadow.CANGIM.all = ECanaRegs.CANGIM.all;
ECanaShadow.CANGIM.bit.I0EN = 1; // Ñ¡ÔñÖжÏÏß0
ECanaRegs.CANGIM.all = ECanaShadow.CANGIM.all;
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
PieCtrlRegs.PIEIER9.bit.INTx5 = 1; // 9.5
PieVectTable.ECAN0INTA = &can_rx_isr;
IER |= M_INT9;
EINT;
EDIS;
}
/**
* @brief can·¢Ëͺ¯Êý
*
* @param TxMessage Can_IdΪCAN_ID, lengthΪCANÊý¾Ý³¤¶È(µ¥Î»ÊÇ×Ö½Ú), Data_LΪµÍËÄλ×Ö½Ú£¬Data_HΪ¸ßËÄλ×Ö½Ú
*/
void can_tx_msg(CanTxMsg *TxMessage)
{
struct ECAN_REGS ECanaShadow;
// ÐÞ¸ÄIDÇ°Òª½ûÖ¹ÓÊÏä²ÅÄÜÍù¼Ä´æÆ÷ÀïÃæдֵ
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME16 = 0;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
/* Write to the MSGID field */
ECanaMboxes.MBOX16.MSGID.all = TxMessage->ExtId; // stand Identifier
// ʹÄÜÓÊÏä
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME16 = 1;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
/* Write to DLC field in Master Control reg */
ECanaMboxes.MBOX16.MSGCTRL.bit.DLC = 8; // 8;
ECanaMboxes.MBOX16.MSGCTRL.bit.RTR = 0;
/* Write to the mailbox RAM field */
ECanaMboxes.MBOX16.MDL.byte.BYTE0 = TxMessage->data[0];
ECanaMboxes.MBOX16.MDL.byte.BYTE1 = TxMessage->data[1];
ECanaMboxes.MBOX16.MDL.byte.BYTE2 = TxMessage->data[2];
ECanaMboxes.MBOX16.MDL.byte.BYTE3 = TxMessage->data[3];
ECanaMboxes.MBOX16.MDH.byte.BYTE4 = TxMessage->data[4];
ECanaMboxes.MBOX16.MDH.byte.BYTE5 = TxMessage->data[5];
ECanaMboxes.MBOX16.MDH.byte.BYTE6 = TxMessage->data[6];
ECanaMboxes.MBOX16.MDH.byte.BYTE7 = TxMessage->data[7];
// struct ECAN_REGS ECanaShadow;
ECanaShadow.CANTRS.all = 0;
ECanaShadow.CANTRS.bit.TRS16 = 1; // Set TRS for mailbox under test
ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
do
{
ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;
} while (ECanaShadow.CANTA.bit.TA16 == 0); // Wait for TA16 bit to be set..
ECanaShadow.CANTA.all = 0;
ECanaShadow.CANTA.bit.TA16 = 1; // Clear TA16
ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;
}