/****************************************************************************** �� �� ����MSCAN0.h ����������MSCAN0�����շ����ƺ������ļ� �� �ߣ����� �� ����V1.0 �� �ڣ�2016.5.5 ******************************************************************************/ #include "MSCAN0_J1939.h" uint8_t WakeUpFlag; uint8_t WakeUpID; extern uint8_t NM_RECEIVE; extern uint8_t sleepFl1g; extern uint8_t CanFrameExist; extern INT8U BUS_OFF_FLAG; //----hyq--20180728 extern uint8_t DiagnosticReceived; uint32_t MSCAN0TxID[3]; MSCAN0BusoffMonitorStruct MSCAN0Busoff; // extern void CoCAN_L_Data_Indication(uint32_t Identifier, uint8_t DLC, uint8_t *Data); //extern void CoCAN_L_Data_Confirm(uint32_t Identifier, uint8_t TransferStatus); // extern void DoCAN_L_Data_Indication(uint32_t Identifier, uint8_t dlc, uint8_t *pData); extern void DoCAN_L_Data_Confirm(uint32_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 ���������� Priority ���������ȼ� 0 - 2 ����ԽС���ȼ�Խ�� ����ֵ���� ******************************************************************************/ //�ⷢ���ĵ�ID�б� static uint16_t CAN_TXIDS[] = {0x26D, 0x315, 0x530, 0x402, 0x7EB}; #define CAN_TXIDS_LEN 5 //CAN���ݷ������� void MSCAN0_L_Data_Request(uint32_t Identifier, uint8_t DLC, uint8_t *Data, uint8_t Priority) { uint8_t i; uint8_t BufSel; //MSCAN��CAN BUS��ͬ��,��ID��Ч,�������ݳ��ȴ���8,�����ȼ����ô���ʱ,�ϱ�����ʧ�ܲ��˳����� if ((CAN0CTL0_SYNCH == 0) || (DLC > 8) || (Priority > 2)) { MSCAN0_L_Data_Confirm(Identifier, NOT_COMPLETE); return; } //ID���ڷ��͵ı���ID�� /* for(i=0; i<CAN_TXIDS_LEN; i++) { if(Identifier==CAN_TXIDS[i]) break; } if(i>=CAN_TXIDS_LEN) return; */ //���ͻ���ָ�� BufSel = (0x01 << Priority); //��ǰ���ȼ��ķ��ͻ�����Ϊ��ʱ,�ϱ�����ʧ�ܲ��˳����� if (CAN0TFLG & BufSel == 0) { MSCAN0_L_Data_Confirm(Identifier, NOT_COMPLETE); return; } //ǰһ�α��ķ���δ�õ��������Buffer��������� if (MSCAN0TxID[Priority] != 0xFFFFFFFF) MSCAN0_L_Data_Confirm(MSCAN0TxID[Priority], NOT_COMPLETE); MSCAN0TxID[Priority] = Identifier; //����ID //!!�Ĵ������� //ѡ��ָ��ָ���ķ��ͻ����� CAN0TBSEL = BufSel; //д���ʶ��ID CAN0TXIDR0 = (uint8_t)(Identifier >> 21); CAN0TXIDR1 = ((uint8_t)(Identifier >> 13) & 0xE0) | ((uint8_t)(Identifier >> 15) & 0x07); CAN0TXIDR2 = (uint8_t)(Identifier >> 7); CAN0TXIDR3 = (uint8_t)(Identifier << 1) & 0xFE; //���ͣ���չ֡�� CAN0TXIDR1_SRR = 1; CAN0TXIDR1_IDE = 1; //д������ for (i = 0; i < DLC; i++) *((&CAN0TXDSR0)+i) = Data[i]; CAN0TXDLR = DLC;//DLC //CAN0TXTBPR = 0; //�������ȼ�,��Buffer���ȼ���ͬ,��BufferIDԽС,���ȼ�Խ�� CAN0TFLG = BufSel; //�������� CAN0TIER |= BufSel; //������ӦCAN�����ж� //end } /****************************************************************************** ��������MSCAN0_L_Data_Indication �� �ܣ� �ú����������ϲ�ָʾһ֡���ĵĵ���,��ͬʱ���������ݴ������ϲ� ע�⣺1.ʹ��ʱӦ���ϲ�ı��Ĵ��ݺ��������ڱ�����֮��,���ĵ���ʱ������ ��Ӧ�ĺ������ݱ������� 2.���������ж����,�����õ��ϲ�ı��Ĵ��ݺ���Ӧ�����ܼ�� �� ���� Identifier������ID DLC �����ij��� Data ���������� ����ֵ���� ******************************************************************************/ //��չ֡���ݽ��� unsigned long recv_id = 0UL; void MSCAN0_L_Data_Indication(uint32_t Identifier, uint8_t DLC, uint8_t *Data) { MSCANIDStruct * pID = (MSCANIDStruct*)(&Identifier); //����������Ĵ��� //���������ı��� //if(pID->PS==0x28 || pID->PS==0xBF || Identifier==0x1810A6A0) //----hyq--20180728 ID���� recv_id = Identifier; if ((Identifier == 0x18DB33F1UL) || (Identifier == 0x18DAFCF1UL)) { 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(uint32_t Identifier, uint8_t TransferStatus) { if (Identifier == 0x7EB)//0x7EB���DZ�����ӦID { DoCAN_L_Data_Confirm(Identifier, TransferStatus); } //����������� else if( ( Identifier >= 0x400 ) && ( Identifier <= 0x47F ) ) { ;//CanNm_TxConfirmation(0); } } /****************************************************************************** ��������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 //CAN�����Ѿ�������ģʽ(��λָ�ʧ��),���ٻָ� if (MSCAN0Busoff.Status == MSCAN0_BUS_LIMP) return; #endif //���Bus-off���� if (CAN0MISC_BOHOLD) { MSCAN0Busoff.Timer++;//bus off ��ʱ //����һ��bus off״̬ if(MSCAN0Busoff.Status == MSCAN0_BUS_STABLE) MSCAN0Busoff.Status = MSCAN0_BUS_OFF_LV1; //��һ��bus off״̬�� if (MSCAN0Busoff.Status == MSCAN0_BUS_OFF_LV1) { if (MSCAN0Busoff.Timer >= MSCAN0_BUS_OFF_LV1_RECOVERY_TIME / 20) { MSCAN0Busoff.Timer = 0; CAN0MISC_BOHOLD = 1; //д1����,����ָ�Bus-off MSCAN0Busoff.Cnt++; //����bus off ���� if (MSCAN0Busoff.Cnt >= 10) { BUS_OFF_FLAG = 1; MSCAN0Busoff.Cnt = 0; MSCAN0Busoff.Status = MSCAN0_BUS_OFF_LV2; } } } //����ģʽ else if (MSCAN0Busoff.Status == MSCAN0_BUS_OFF_LV2) { if (MSCAN0Busoff.Timer >= MSCAN0_BUS_OFF_LV2_RECOVERY_TIME / 20) { MSCAN0Busoff.Timer = 0; 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; MSCAN0Busoff.Status = MSCAN0_BUS_LIMP; //����CAN��������ģʽ CAN0_PHY_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���� { BUS_OFF_FLAG = 0; MSCAN0Busoff.Status = MSCAN0_BUS_STABLE; MSCAN0Busoff.Timer = 0; MSCAN0Busoff.Cnt = 0; } #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 = 0X43; //���������� 0x4314 250k 0x802B 500K CAN0BTR1 = 0X14; //�˳���ʼ��ģʽ CAN0CTL0 = 0x00; while (CAN0CTL1_INITAK); //�ȴ��˳���ʼ��ģʽ while (!CAN0CTL0_SYNCH); //�ȴ�MSCAN��CAN����ͬ�� CAN0TIER = 0x00; //��ֹCAN�����ж� //CAN���յ��������ݺ����ж� CAN0RIER_RXFIE = 1; //ʹ��CAN�����ж� CAN0RIER_WUPIE = 1; //ʹ��WakeUP�ж� 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_Enter_Low_Power_Mode �� �ܣ���MSCAN0�������ģʽ �� ������ ����ֵ���� ******************************************************************************/ void MSCAN0_Enter_Low_Power_Mode(void) { MSCAN0_Init(); //����ʼ����ֹCAN�շ� CAN0_STB = 1; //ʹ��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; //������ֹ���б��ķ���. //CAN0RIER_RXFIE = 0; //��ֹCAN�����ж� } /****************************************************************************** ��������MSCAN0_Exit_Low_Power_Mode �� �ܣ���MSCAN0�˳�����ģʽ �� ������ ����ֵ���� ******************************************************************************/ void MSCAN0_Exit_Low_Power_Mode(void) { CAN0CTL0_SLPRQ = 0; //ʹ��MSCAN�˳�˯�� if(CAN0RFLG_WUPIF) //�����ж������־ = 1 ��д1��0 CAN0RFLG_WUPIF = 1; CAN0CTL0_WUPE = 0; //���û��ѹ��� CAN0_STB = 0; //ʹ��CAN�շ��� CAN0RIER_RXFIE = 1; //ʹ��CAN�����ж� } /****************************************************************************** ��������MSCAN0_Get_Wake_Up_Flag �� �ܣ���ȡMSCAN0�Ļ���״̬ �� ������ ����ֵ��0 - δ������ 1 - �ѱ����� ******************************************************************************/ uint8_t MSCAN0_Get_Wake_Up_Flag(void) { if (CAN0CTL0_SLPRQ == 0) return 1; //if (WakeUpFlag) //{ // WakeUpFlag = 0; // return 1; //} return 0; } #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); //�����жϴ����ڼ����µı��ķ������ //end } /****************************************************************************** ��������MSCAN0_RX_ISR �� �ܣ�MSCAN0�����жϷ������� ����CAN�����ʹ�ʱ������CAN���� �� ������ ����ֵ���� ******************************************************************************/ //J1939Э���RX�жϽ��� void interrupt MSCAN0_RX_ISR(void) { uint32_t tmp; uint32_t CANMsgID; //CAN0RIER_RXFIE = 0; //�Ƚ�ֹMSCAN�����ж� //��ͨ֡ if(!CAN0RXIDR1_IDE) //��֡ʶ��� 0 ��֡ 11 λ 1 ��չ֡ 29 λ { CAN0RFLG_RXF = 1; //������жϱ�־ CAN0RIER_RXFIE = 1; //��������MSCAN�����ж� return; } //���ݽ��� tmp = (uint32_t)(CAN0RXIDR0) << 21; tmp &= 0x1FE00000; CANMsgID = tmp | ((uint32_t)(CAN0RXIDR1 & 0xE0) <<13) | ((uint32_t)(CAN0RXIDR1 & 0x07) <<15) | ((uint32_t)(CAN0RXIDR2) << 7) | ((uint32_t)(CAN0RXIDR3) >> 1);//ID MSCAN0_L_Data_Indication(CANMsgID, CAN0RXDLR & 0x0F, &CAN0RXDSR0); CanFrameExist=1; CAN0RFLG_RXF = 1; //������жϱ�־ //CAN0RIER_RXFIE = 1; //��������MSCAN�����ж� //end } /* 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)); if((CANMsgID >= 0x400) && (CANMsgID <= 0x47F)) MSCAN0_L_Data_Indication(CANMsgID, CAN0RXDLR & 0x0F, &CAN0RXDSR0); else { switch(CANMsgID) { case 0x068 : case 0x268 : case 0x2D7 : case 0x4D4 : case 0x1C8 : case 0x370 : case 0x1C9 : case 0x0F2 : case 0x0E2 : case 0x082 : case 0x094 : case 0x288 : case 0x088 : case 0x120 : case 0x293 : case 0x115 : case 0x160 : case 0x07A : case 0x30F : case 0x2F1 : case 0x10D : case 0x7E3 : case 0x7DF : case 0x279 : MSCAN0_L_Data_Indication(CANMsgID, CAN0RXDLR & 0x0F, &CAN0RXDSR0); break; default : break; } } CAN0RFLG_RXF = 1; //������жϱ�־ CAN0RIER_RXFIE = 1; //��������MSCAN�����ж� }*/ /****************************************************************************** ��������MSCAN0_WAKEUP_ISR �� �ܣ�MSCAN0�����ж� �� ������ ����ֵ���� ******************************************************************************/ void interrupt MSCAN0_WAKEUP_ISR(void) { CAN0RFLG_WUPIF = 1; CAN0_STB = 0; //----hyq--20180806 WakeUpFlag = 1; } #pragma CODE_SEG DEFAULT // /* Std_ReturnType CanIf_Transmit(PduIdType CanTxPduId, PduInfoType* PduInfoPtr) { (void)CanTxPduId; MSCAN0_L_Data_Request( 0x402, (uint8_t)PduInfoPtr->SduLength, (uint8_t*)PduInfoPtr->SduDataPtr, 0 ); return E_OK; } */