/****************************************************************************** �� �� ����MSCAN0.h ����������MSCAN0�����շ����ƺ������ļ� �� �ߣ����� �� ����V1.0 �� �ڣ�2016.5.5 ******************************************************************************/ #include "MSCAN0.h" uint8_t WakeUpFlag; uint8_t WakeUpID; uint16_t MSCAN0TxID[3]; MSCAN0BusoffMonitorStruct MSCAN0Busoff; extern uint8_t NM_RECEIVE; extern void CoCAN_L_Data_Indication(uint16_t Identifier, uint8_t DLC, uint8_t *Data); extern void CoCAN_L_Data_Confirm(uint16_t Identifier, uint8_t TransferStatus); extern void DoCAN_L_Data_Indication(uint16_t Identifier, uint8_t dlc, uint8_t *pData); extern void DoCAN_L_Data_Confirm(uint16_t Identifier, uint8_t TransferStatus); extern FUNC(void, CANNM_CODE) CanNm_RxIndication ( PduIdType RxPudId, const uint16 RxId, P2CONST(PduInfoType, AUTOMATIC, CANNM_APPL_DATA)PduInfoPtr ); extern FUNC(void, CANNM_CODE) CanNm_TxConfirmation ( PduIdType TxPudId ); /****************************************************************************** ��������MSCAN0_L_Data_Request �� �ܣ��ú������ϲ����,���������������Ϸ���һ�鱨�� �� ����Identifier������ID DLC �����ij��� Data ���������� ����ֵ���� ******************************************************************************/ void MSCAN0_L_Data_Request(uint16_t Identifier, uint8_t DLC, uint8_t *Data) { uint8_t i; uint8_t BufDetect; uint8_t BufSel; //�������ݳ��ȴ���8��MSCAN��CAN BUS��ͬ����3�����ͻ�������û�п���ʱ��ID��Ч,�ϱ�����ʧ�ܲ��˳����� if ((DLC > 8) || (CAN0CTL0_SYNCH == 0) || (CAN0TFLG & 0x07 == 0) || (Identifier > 0x07FF)) { MSCAN0_L_Data_Confirm(Identifier, NOT_COMPLETE); return; } CAN0TBSEL = CAN0TFLG; //ѡ��ָ����еķ��ͻ�����(�������ѡ����͵�) BufSel = CAN0TBSEL; BufDetect = 0x01; for (i = 0; i < 3; i++) { if (BufDetect == BufSel) { if (MSCAN0TxID[i] != 0xFFFF) //ǰһ�α��ķ���δ�õ��������Buffer��������� { MSCAN0_L_Data_Confirm(MSCAN0TxID[i], NOT_COMPLETE); MSCAN0TxID[i] = 0xFFFF; } MSCAN0TxID[i] = Identifier; //����ID } BufDetect <<= 1; } CAN0TXIDR0 = (uint8_t)(Identifier >> 3); //д���ʶ��ID CAN0TXIDR1 = (uint8_t)(Identifier << 5); CAN0TXIDR1_SRR = 0; CAN0TXIDR1_IDE = 0; for (i = 0; i < DLC; i++) //д������ *((&CAN0TXDSR0) + i) = Data[i]; CAN0TXDLR = DLC; //CAN0TXTBPR = 0; //�������ȼ�,��Buffer���ȼ���ͬ,��BufferIDԽС,���ȼ�Խ�� CAN0TFLG = BufSel; //�������� CAN0TIER |= BufSel; //������ӦCAN�����ж� } /****************************************************************************** ��������MSCAN0_L_Data_Indication �� �ܣ��ú����������ϲ�ָʾһ֡���ĵĵ���,��ͬʱ���������ݴ������ϲ� ע�⣺1.ʹ��ʱӦ���ϲ�ı��Ĵ��ݺ��������ڱ�����֮��,���ĵ���ʱ������ ��Ӧ�ĺ������ݱ������� 2.���������ж����,�����õ��ϲ�ı��Ĵ��ݺ���Ӧ�����ܼ�� �� ����Identifier������ID DLC �����ij��� Data ���������� ����ֵ���� ******************************************************************************/ void MSCAN0_L_Data_Indication(uint16_t Identifier, uint8_t DLC, uint8_t *Data) { PduInfoType NW_MessageBuffer; if( ( Identifier >= 0x400 ) && ( Identifier <= 0x47F ) ) //����������� { NW_MessageBuffer.SduDataPtr = Data; NW_MessageBuffer.SduLength = DLC; CanNm_RxIndication(0, 0, &NW_MessageBuffer); NM_RECEIVE = 1; } else if ((Identifier == 0x7E3) || (Identifier == 0x7EB)) { DoCAN_L_Data_Indication(Identifier, DLC, Data); } else { //Ӧ�ñ��� if( sleepFlg == NET_WORK_STATE ) { CoCAN_L_Data_Indication(Identifier, DLC, Data); } else if( sleepFlg == PREPARE_BUS_SLEEP_STATE ) { } else if( sleepFlg == BUS_SLEEP_STATE ) { } else if( sleepFlg == START_INDICATION_STATE ) { CoCAN_L_Data_Indication(Identifier, DLC, Data); } } // if ((Identifier == 0x7E3) || (Identifier == 0x7EB)) // DoCAN_L_Data_Indication(Identifier, DLC, Data); // else // CoCAN_L_Data_Indication(Identifier, DLC, Data); } /****************************************************************************** ��������MSCAN0_L_Data_Confirm �� �ܣ��ú����������ϲ�ָʾ�����͵ı��ĵķ��ͽ�� ע�⣺1.ʹ��ʱӦ���ϲ�ı��ķ��ͽ�����ݺ��������ڱ�����֮��,���ķ����� ������ʱ��������Ӧ�ĺ������ݱ��ķ��ͽ�� 2.���������ж����,�����õ��ϲ�ı��ķ��ͽ�����ݺ���Ӧ�����ܼ�� �� ����Identifier ������ID TransferStatus�����ķ��ͽ����COMPLETE ������� NOT_COMPLETE ����δ�ܷ������ ����ֵ���� ******************************************************************************/ void MSCAN0_L_Data_Confirm(uint16_t Identifier, uint8_t TransferStatus) { if( ( Identifier >= 0x400 ) && ( Identifier <= 0x47F ) ) //����������� { CanNm_TxConfirmation(0); } else if (Identifier == 0x7E3) DoCAN_L_Data_Confirm(Identifier, TransferStatus); else { CoCAN_L_Data_Confirm(Identifier, TransferStatus); } //if (Identifier == 0x7E3) // DoCAN_L_Data_Confirm(Identifier, TransferStatus); // else // CoCAN_L_Data_Confirm(Identifier, TransferStatus); } /****************************************************************************** ��������MSCAN0_Bus_Off_Monitoring_Service �� �ܣ�MSCAN0 Bus-off״̬��ط���,���Bus-off״̬�����Իָ� �� ������ ����ֵ���� ******************************************************************************* ע �⣺�÷���������ÿ20ms������һ�� ******************************************************************************/ void MSCAN0_Bus_Off_Monitoring_Service(void) { #if !MSCAN0_BUS_OFF_AUTO_RECOVERY #if MSCAN0_BUS_LIMP_MODE_ENABLE if (MSCAN0Busoff.Status == MSCAN0_BUS_LIMP) return; //CAN�����Ѿ�������ģʽ(��λָ�ʧ��),���ٻָ� #endif if (CAN0MISC_BOHOLD) //���Bus-off���� { MSCAN0Busoff.Timer++; if (MSCAN0Busoff.Timer >= MSCAN0_BUS_OFF_RECOVERY_TIME / 20) { MSCAN0Busoff.Timer = 0; MSCAN0Busoff.Status = MSCAN0_BUS_OFF; //��¼Bus-off״̬ CAN0MISC_BOHOLD = 1; //д1����,����ָ�Bus-off #if MSCAN0_BUS_LIMP_MODE_ENABLE MSCAN0Busoff.Cnt++; if (MSCAN0Busoff.Cnt > MSCAN0_BUS_LIMP_MODE_THRESHOLD) { MSCAN0Busoff.Cnt = 0; CAN0MISC_BOHOLD = 1; //д1����,����ָ�Bus-off MSCAN0Busoff.Status = MSCAN0_BUS_LIMP; //����CAN��������ģʽ CAN0_STB = 1; //����ʡ��ģʽ MSCAN0_Init(); //ͨ����ʼ����ֹ����CAN�շ� CAN0RIER_RXFIE = 0; //��ֹCAN�����ж� CAN0RIER_WUPIE = 0; //�رջ����ж� CAN0CTL0_WUPE = 0; //��ֹ����ʹ�� if (CAN0RFLG_WUPIF) CAN0RFLG_WUPIF = 1; //����л����ж������־Ҳһ�����(д1����) } #endif } } else //��������,û��Bus-off���� { MSCAN0Busoff.Status = MSCAN0_BUS_STABLE; MSCAN0Busoff.Timer = 0; #if MSCAN0_BUS_LIMP_MODE_ENABLE MSCAN0Busoff.Cnt = 0; #endif } #endif } /****************************************************************************** ��������MSCAN0_Get_Bus_Status �� �ܣ���ȡMSCAN0����״̬ �� ������ ����ֵ��MSCAN0_BUS_STABLE����������,�ȶ����� MSCAN0_BUS_OFF �����ߴ���Bus-off״̬ MSCAN0_BUS_LIMP �����ߴ�������״̬(Bus-off���λָ���ʧ�ܶ��ر�����) ******************************************************************************/ uint8_t MSCAN0_Get_Bus_Status(void) { return MSCAN0Busoff.Status; } /****************************************************************************** ��������MSCAN0_Init �� �ܣ�MSCAN0��ʼ������ �� ������ ����ֵ���� ******************************************************************************/ void MSCAN0_Init(void) { uint8_t i; CAN0CTL0 = 0x01; //���� MSCAN�����ʼ��ģʽ while(!(CAN0CTL1_INITAK)); //�ȴ������ʼ��ģʽ CAN0IDAC = 0; //�����������ռĴ����Ĺ�����ʽ two 32-bit filter CAN0IDAR0 = 0x00; //�������ռĴ��� CAN0IDAR1 = 0x00; CAN0IDAR2 = 0x00; CAN0IDAR3 = 0x00; CAN0IDMR0 = 0xFF; //�������μĴ��� (��������Ϊ���б���ID������) CAN0IDMR1 = 0xFF; CAN0IDMR2 = 0xFF; CAN0IDMR3 = 0xFF; CAN0IDAR4 = 0x00; //�������ռĴ��� CAN0IDAR5 = 0x00; CAN0IDAR6 = 0x00; CAN0IDAR7 = 0x00; CAN0IDMR4 = 0xFF; //�������μĴ��� (��������Ϊ���б���ID������) CAN0IDMR5 = 0xFF; CAN0IDMR6 = 0xFF; CAN0IDMR7 = 0xFF; CAN0CTL1_CANE = 1; //ʹ��MSCANģ�� CAN0CTL1_CLKSRC = 0; //ѡ��OSCCLK(8MHz)ΪMSCAN��ʱ��Դ CAN0CTL1_LISTEN = 0; //��������ģʽ(�Ǽ���ģʽ) #if MSCAN0_BUS_OFF_AUTO_RECOVERY CAN0CTL1_BORM = 0; //�Զ�����BUS_OFF�ָ� #else CAN0CTL1_BORM = 1; //����BUS_OFF���û����ƻָ� #endif CAN0CTL1_WUPM = 1; //�����Ѽ��˲� CAN0BTR0 = MSCAN0_BTR0_VALUE; //���������� CAN0BTR1 = MSCAN0_BTR1_VALUE; CAN0CTL0 = 0x00; //�˳���ʼ��ģʽ while (CAN0CTL1_INITAK); //�ȴ��˳���ʼ��ģʽ while (!CAN0CTL0_SYNCH); //�ȴ�MSCAN��CAN����ͬ�� CAN0TIER = 0x00; //��ֹCAN�����ж� CAN0RIER_RXFIE = 1; //ʹ��CAN�����ж� CAN0RIER_WUPIE = 1; CAN0_STB = 0; //ʹ��CAN�շ��� MSCAN0Busoff.Status = MSCAN0_BUS_STABLE; MSCAN0Busoff.Timer = 0; #if MSCAN0_BUS_LIMP_MODE_ENABLE MSCAN0Busoff.Cnt = 0; #endif for(i = 0; i < 3; i++) MSCAN0TxID[i] = 0xFFFF; //0xFFFF��ʾ��ЧID } /****************************************************************************** ��������MSCAN0_Low_Power_Mode �� �ܣ���MSCAN0����͹���ģʽ �� ������ ����ֵ���� ******************************************************************************/ void MSCAN0_Low_Power_Mode(void) { //MSCAN����͹���ģʽ MSCAN0_Init(); //͸����ʼ����ֹCAN�շ� // CAN0_STB = 1; //ʹ��CAN�շ��� CAN0RIER_RXFIE = 0; //��ֹCAN�����ж� if(CAN0RFLG_WUPIF) //�����ж������־ = 1 ��д1��0 CAN0RFLG_WUPIF = 1; CAN0CTL0_WUPE = 1; //����ʹ�� //��1��,��MSCAN���з������(���Ͷ��п�),����Ҳ���(CAN���߿���)��, //MSCAN ����SLEEPģʽ,������ CAN0CTL1_SLPAK=1��ʾȷ�� //���ô�λǰ CAN0RFLG_WUPIF ������� //��CAN0CTL0_SLPRQ=1,��CAN0CTL1_SLPAK=1 ,��ʾMSCAN�Ѿ�����˯��ģʽ CAN0CTL0_SLPRQ = 1; //������MSCAN����˯��ģʽ //��MSCAN����˯��ģʽ��,��� CAN0CTL0_WUPE = 1 ���յ�CAN���ĺ�,MSCAN�˳�˯��,��CAN0RFLG_WUPIF��1 //ͬʱ CAN0CTL0_SLPRQ,CAN0CTL1_SLPAK Ҳ���Զ���0. //��MSCAN����˯��ģʽ��,����Ҳ����������CAN0CTL0_SLPRQ = 0,ʹ��MSCAN�˳�˯��,CAN0CTL1_SLPAK Ҳ���Զ���0. //�� CAN0CTL0_SLPRQ = 1��,���MSCAN��û�н���˯��ģʽ,��ô����������CAN0CTL0_SLPRQ = 0. CAN0TARQ = 0x07; //������ֹ���б��ķ���. } #pragma CODE_SEG __NEAR_SEG NON_BANKED //�������жϺ�������FLASH�ķǷ�ҳ�� /****************************************************************************** ��������MSCAN0_TX_ISR �� �ܣ�MSCAN0�����жϷ������� ����CAN���ķ�����ϻ���ֹ����ʱ��ִ�д˺��� �� ������ ����ֵ���� ******************************************************************************/ void interrupt MSCAN0_TX_ISR(void) { uint8_t i; uint8_t TxFlag; uint8_t TxBuf; uint8_t BufDetect; do { TxFlag = CAN0TFLG; TxBuf = CAN0TIER & TxFlag; //��ȡ������ϻ���ֹ���͵ı���Buffer CAN0TIER &= ~TxBuf; //�رշ�����ϻ���ֹ���͵ı���Buffer��Ӧ���ж� BufDetect = 1; for (i = 0; i < 3; i++) { if (BufDetect & TxBuf) { if (BufDetect & CAN0TAAK) //���ı��ɹ���ֹ���� MSCAN0_L_Data_Confirm(MSCAN0TxID[i], NOT_COMPLETE); else //���ķ��ͳɹ� MSCAN0_L_Data_Confirm(MSCAN0TxID[i], COMPLETE); MSCAN0TxID[i] = 0xFFFF; //������ļ�¼ } BufDetect <<= 1; } } while (TxFlag != CAN0TFLG); //�����жϴ����ڼ����µı��ķ������ } /****************************************************************************** ��������MSCAN0_RX_ISR �� �ܣ�MSCAN0�����жϷ������� ����CAN�����ʹ�ʱ������CAN���� �� ������ ����ֵ���� ******************************************************************************/ void interrupt MSCAN0_RX_ISR(void) { uint16_t CANMsgID; CAN0RIER_RXFIE = 0; //�Ƚ�ֹMSCAN�����ж� if (CAN0RXIDR1_IDE || CAN0RXIDR1_SRR) //����յ�������Ϊ��չ֡,��ΪԶ��֡ { CAN0RFLG_RXF = 1; //������жϱ�־ CAN0RIER_RXFIE = 1; //��������MSCAN�����ж� return; } CANMsgID = ((uint16_t)(CAN0RXIDR0 << 3)) | ((uint16_t)(CAN0RXIDR1 >> 5)); MSCAN0_L_Data_Indication(CANMsgID, CAN0RXDLR & 0x0F, &CAN0RXDSR0); CAN0RFLG_RXF = 1; //������жϱ�־ CAN0RIER_RXFIE = 1; //��������MSCAN�����ж� } /****************************************************************************** ��������MSCAN0_WAKEUP_ISR �� �ܣ�MSCAN0�����ж� �� ������ ����ֵ���� ******************************************************************************/ void interrupt MSCAN0_WAKEUP_ISR(void) { CAN0RFLG_WUPIF = 1; WakeUpFlag = 1; } uint8_t GetWakeUPFLAG(void) { return WakeUpFlag; } #pragma CODE_SEG DEFAULT Std_ReturnType CanIf_Transmit(PduIdType CanTxPduId, PduInfoType *PduInfoPtr) { MSCAN0_L_Data_Request( 0x402, (uint8_t)PduInfoPtr->SduLength, (uint8_t *)PduInfoPtr->SduDataPtr ); return E_OK; }