diff --git a/Protocol/CAN.cpp b/Protocol/CAN.cpp index 1c94aac..a8018b3 100644 --- a/Protocol/CAN.cpp +++ b/Protocol/CAN.cpp @@ -3,7 +3,7 @@ namespace canSpace { -void CAN::transmitMsg(Uint16 boxNumber, const MBOX& message){ +void CAN::transmitMsg(Uint16 boxNumber, const CANMessage& message){ Uint32 mboxControl(0); mboxControl = 1ul << boxNumber; @@ -13,15 +13,15 @@ void CAN::transmitMsg(Uint16 boxNumber, const MBOX& message){ p_MailBox->MDH.all = 0x0; p_MailBox->MDL.all = 0x0; - p_MailBox->MSGCTRL.bit.DLC = message.MSGCTRL.bit.DLC; - p_MailBox->MDH.all = message.MDH.all; - p_MailBox->MDL.all = message.MDL.all; + p_MailBox->MSGCTRL.bit.DLC = message.msgctrl.bit.DLC; + p_MailBox->MDH.all = message.mdh.all; + p_MailBox->MDL.all = message.mdl.all; CanShadow_.CANTRS.all = 0; CanShadow_.CANTRS.all |= mboxControl; // Set TRS for mailbox under test p_CanRegs_->CANTRS.all = CanShadow_.CANTRS.all; - do { CanShadow_.CANTA.all = p_CanRegs_->CANTA.all; } + do { CanShadow_.CANTA.all = p_CanRegs_->CANTA.all; } // TODO add tx error somewhere here while((CanShadow_.CANTA.all & mboxControl) == 0 );// Wait for TA1 bit to be set CanShadow_.CANTA.all = 0; @@ -29,19 +29,79 @@ void CAN::transmitMsg(Uint16 boxNumber, const MBOX& message){ p_CanRegs_->CANTA.all = CanShadow_.CANTA.all; } -void CAN::receiveMsg(Uint16 boxNumber){ + +bool CAN::isNewMessage(){ + return static_cast(p_CanRegs_->CANRMP.all); +} + + +bool CAN::isNewMessage(Uint16 boxNumber){ + Uint32 mboxControl(0); + mboxControl = 1ul << boxNumber; + + bool isNewMessageInBox = p_CanRegs_->CANRMP.all & mboxControl; + return isNewMessageInBox; +} + + +bool CAN::receiveMsg(Uint16 boxNumber, CANMessage& rxMessage){ // TODO faults just return -1 Uint32 mboxControl(0); mboxControl = 1ul << boxNumber; volatile MBOX* p_MailBox(NULL); p_MailBox = &(p_CanMBoxes_->MBOX0) + boxNumber; - volatile MBOX message; + bool isNewMessageInBox = p_CanRegs_->CANRMP.all & mboxControl; + if(!isNewMessageInBox) return -1; + p_CanRegs_->CANRMP.all &= mboxControl; + rxMessage.msgctrl.all = p_MailBox->MSGCTRL.all; + rxMessage.mdl.all = p_MailBox->MDL.all; + rxMessage.mdh.all = p_MailBox->MDH.all; + bool newMessage; + bool lostMessage; + newMessage = p_CanRegs_->CANRMP.all & mboxControl; + lostMessage = p_CanRegs_->CANRML.all & mboxControl; + + if(newMessage || lostMessage) { + return -1; + // set_fault(); + } + + return 0; } +/* CANMessage CAN::receiveMsg(Uint16 boxNumber){ + Uint32 mboxControl(0); + mboxControl = 1ul << boxNumber; + + volatile MBOX* p_MailBox(NULL); + p_MailBox = &(p_CanMBoxes_->MBOX0) + boxNumber; + CANMessage rxMessage; + + p_CanRegs_->CANRMP.all &= mboxControl; + + rxMessage.MSGCTRL.all = p_MailBox->MSGCTRL.all; + rxMessage.MDL.all = p_MailBox->MDL.all; + rxMessage.MDH.all = p_MailBox->MDH.all; + + bool newMessage; + bool lostMessage; + + newMessage = p_CanRegs_->CANRMP.all & mboxControl; + lostMessage = p_CanRegs_->CANRML.all & mboxControl; + + if(newMessage || lostMessage) { + counter_fault_rx++; // TODO delete after debug + // set_fault(); + } + + return rxMessage; +} */ + + } // canSpace diff --git a/Protocol/CAN.h b/Protocol/CAN.h index 1faaa0f..e37fb78 100644 --- a/Protocol/CAN.h +++ b/Protocol/CAN.h @@ -11,17 +11,101 @@ enum CAN_VARIANT{ CANB }; +// eCAN Message Control Register (MSGCTRL) bit definitions +struct MsgCtrlBits { // bits description + Uint16 DLC:4; // 0:3 + Uint16 RTR:1; // 4 + Uint16 rsvd1:3; // 7:5 reserved + Uint16 TPL:5; // 12:8 + Uint16 rsvd2:3; // 15:13 reserved +}; + +union MsgCtrlReg { + Uint16 all; + struct MsgCtrlBits bit; + + MsgCtrlReg(){ + all = 0; + } + + MsgCtrlReg(Uint16 configData){ + all = configData; + } +}; + +struct MsgID_Bits { // bits description + Uint16 EXTMSGID_L:16; // 0:15 + Uint16 EXTMSGID_H:2; // 16:17 + Uint16 STDMSGID:11; // 18:28 + Uint16 AAM:1; // 29 + Uint16 AME:1; // 30 + Uint16 IDE:1; // 31 +}; + +// Allow access to the bit fields or entire register +union ConfigMsgID { + Uint32 all; + struct MsgID_Bits bit; + + ConfigMsgID(bool isExtendedID, Uint16 standartID, Uint32 extendedID, bool isAAM, bool isAME) + { + if(!isExtendedID){ + bit.EXTMSGID_H = 0; + bit.EXTMSGID_L = 0; + bit.STDMSGID = standartID; + } + else{ all = extendedID; } + + bit.AAM = isAAM; + bit.AME = isAME; + bit.IDE = isExtendedID; + } +}; + +struct ConfigMBox{ + ConfigMsgID msgID; + MsgCtrlReg msgCtrlReg; + + ConfigMBox(bool isExtendedID, Uint16 standartID, Uint32 extendedID, bool isAAM, bool isAME, Uint16 ctrlReg) : + msgID(isExtendedID, standartID, extendedID, isAAM, isAME), + msgCtrlReg(ctrlReg) + {} +}; + +struct CANMessage { + union MsgCtrlReg msgctrl; + union CANMDL_REG mdl; + union CANMDH_REG mdh; + + CANMessage(){ + msgctrl.all = 0; + mdl.all = 0; + mdh.all = 0; + } + + // CANMessage(const CANMessage& copyStruct){ + // msgctrl.all = copyStruct.msgctrl.all; + // mdl.all = copyStruct.mdl.all; + // mdh.all = copyStruct.mdh.all; + // } +}; + class CAN{ public: CAN(); void initGpio(CAN_VARIANT canVarinat); void config(CAN_VARIANT canVarinat, Uint16 baudrate); - void configRxMBoxes(); - void configTxMBoxes(); + // void configRxMBoxes(); + void configRxMBoxes(Uint16 boxNumber, const ConfigMBox& configData); + // void configTxMBoxes(); //TODO delete + void configTxMBox(Uint16 boxNumber, const ConfigMBox& configData); - void transmitMsg(Uint16 boxNumber, const MBOX& message); - void receiveMsg(Uint16 boxNumber); + void transmitMsg(Uint16 boxNumber, const CANMessage& message); + bool receiveMsg(Uint16 boxNumber, CANMessage& rxMessage); + // CANMessage receiveMsg(Uint16 boxNumber); + bool isNewMessage(); + bool isNewMessage(Uint16 boxNumber); private: volatile ECAN_REGS* p_CanRegs_; diff --git a/Protocol/CANConfig.cpp b/Protocol/CANConfig.cpp index 922c3df..cc97086 100644 --- a/Protocol/CANConfig.cpp +++ b/Protocol/CANConfig.cpp @@ -1,10 +1,11 @@ #include "CAN.h" +#include "DSP2833x_ECan.h" #include namespace canSpace { CAN::CAN(){ - // todo Make it impossible to create 2 CANA/CANB objects. Give CANA/CANB as a constructor parameter + // TODO Make it impossible to create 2 CANA/CANB objects. Give CANA/CANB as a constructor parameter } void CAN::initGpio(CAN_VARIANT canVarinat){ @@ -40,9 +41,7 @@ void CAN::config(CAN_VARIANT canVarinat, Uint16 baudrate){ EALLOW; // EALLOW enables access to protected bits - // // Configure eCAN RX and TX pins for CAN operation using eCAN regs - // CanShadow_.CANTIOC.all = p_CanRegs_->CANTIOC.all; CanShadow_.CANTIOC.bit.TXFUNC = 1; p_CanRegs_->CANTIOC.all = CanShadow_.CANTIOC.all; @@ -51,15 +50,14 @@ void CAN::config(CAN_VARIANT canVarinat, Uint16 baudrate){ CanShadow_.CANRIOC.bit.RXFUNC = 1; p_CanRegs_->CANRIOC.all = CanShadow_.CANRIOC.all; - // + // Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) // HECC mode also enables time-stamping feature - // CanShadow_.CANMC.all = p_CanRegs_->CANMC.all; CanShadow_.CANMC.bit.SCB = 1; p_CanRegs_->CANMC.all = CanShadow_.CANMC.all; - // + // Initialize all bits of 'Master Control Field' to zero // Some bits of MSGCTRL register come up in an unknown state. For proper // operation, all bits (including reserved bits) of MSGCTRL must be @@ -96,10 +94,9 @@ void CAN::config(CAN_VARIANT canVarinat, Uint16 baudrate){ p_CanMBoxes_->MBOX29.MSGCTRL.all = 0x00000000; p_CanMBoxes_->MBOX30.MSGCTRL.all = 0x00000000; p_CanMBoxes_->MBOX31.MSGCTRL.all = 0x00000000; - // + // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again // as a matter of precaution. - // p_CanRegs_->CANTA.all = 0xFFFFFFFF; // Clear all TAn bits p_CanRegs_->CANRMP.all = 0xFFFFFFFF; // Clear all RMPn bits @@ -107,9 +104,8 @@ void CAN::config(CAN_VARIANT canVarinat, Uint16 baudrate){ p_CanRegs_->CANGIF0.all = 0xFFFFFFFF; // Clear all interrupt flag bits p_CanRegs_->CANGIF1.all = 0xFFFFFFFF; - // + // Configure bit timing parameters for eCANA - // CanShadow_.CANMC.all = p_CanRegs_->CANMC.all; CanShadow_.CANMC.bit.CCR = 1 ; // Set CCR = 1 p_CanRegs_->CANMC.all = CanShadow_.CANMC.all; @@ -117,7 +113,7 @@ void CAN::config(CAN_VARIANT canVarinat, Uint16 baudrate){ do { CanShadow_.CANES.all = p_CanRegs_->CANES.all; } while(CanShadow_.CANES.bit.CCE != 1 ); // Wait for CCE bit to be set - // CanShadow_.CANMC.all = p_CanRegs_->CANMC.all; //todo удалить + // CanShadow_.CANMC.all = p_CanRegs_->CANMC.all; //TODO delete // CanShadow_.CANMC.bit.DBO = 1 ; // Set DBO = 1 // p_CanRegs_->CANMC.all = CanShadow_.CANMC.all; @@ -125,7 +121,6 @@ void CAN::config(CAN_VARIANT canVarinat, Uint16 baudrate){ // The following block for all 150 MHz SYSCLKOUT // (75 MHz CAN clock) - default. Bit rate = 1 Mbps / 500 kbps / 250 kbps / 100 kbps - // switch (baudrate) { case 1000: @@ -159,25 +154,19 @@ void CAN::config(CAN_VARIANT canVarinat, Uint16 baudrate){ p_CanRegs_->CANBTC.all = CanShadow_.CANBTC.all; CanShadow_.CANMC.all = p_CanRegs_->CANMC.all; - CanShadow_.CANMC.bit.CCR = 0 ; // Set CCR = 0 + CanShadow_.CANMC.bit.CCR = 0 ; p_CanRegs_->CANMC.all = CanShadow_.CANMC.all; do { CanShadow_.CANES.all = p_CanRegs_->CANES.all; } while(CanShadow_.CANES.bit.CCE != 0 ); // Wait for CCE bit to be cleared - // // Disable all Mailboxes - // p_CanRegs_->CANME.all = 0; // Required before writing the MSGIDs - CanShadow_.CANTRR.all = p_CanRegs_->CANTRR.all; - CanShadow_.CANTRR.bit.TRR0 = 1; - p_CanRegs_->CANTRR.all = CanShadow_.CANTRR.all; - - CanShadow_.CANTRS.all = p_CanRegs_->CANTRS.all; - + // Reset all transmittions + p_CanRegs_->CANTRR.all = 0xFFFFFFFF; // 0x1111_1111 do {CanShadow_.CANTRS.all = p_CanRegs_->CANTRS.all;} - while(CanShadow_.CANTRS.bit.TRS0 != 0); // Wait for TRS bit to be cleared + while(CanShadow_.CANTRS.all != 0); // Wait for TRS bit to be cleared // // Debug feature @@ -191,54 +180,130 @@ void CAN::config(CAN_VARIANT canVarinat, Uint16 baudrate){ } -void CAN::configTxMBoxes(){ +// void CAN::configTxMBoxes(){ - // Write to the MSGID field - p_CanMBoxes_->MBOX1.MSGID.all = 0x0; // IDE-0, AME-0, AAM-0 - p_CanMBoxes_->MBOX1.MSGID.bit.STDMSGID = 0xAAA; +// // Write to the MSGID field +// p_CanMBoxes_->MBOX1.MSGID.all = 0x0; // IDE-0, AME-0, AAM-0 +// p_CanMBoxes_->MBOX1.MSGID.bit.STDMSGID = 0xAAA; + +// p_CanMBoxes_->MBOX1.MSGCTRL.bit.DLC = 8; // Data length in bytes (0-8) +// p_CanMBoxes_->MBOX1.MSGCTRL.bit.RTR = 0; // Remote Transmission Request + +// CanShadow_.CANMD.all = p_CanRegs_->CANMD.all; +// CanShadow_.CANMD.bit.MD1 = 0; // Mailbox direction - transmit +// p_CanRegs_->CANMD.all = CanShadow_.CANMD.all; + +// CanShadow_.CANME.all = p_CanRegs_->CANME.all; +// CanShadow_.CANME.bit.ME1 = 1; +// p_CanRegs_->CANME.all = CanShadow_.CANME.all; +// } // TODO delete - p_CanMBoxes_->MBOX1.MSGCTRL.bit.DLC = 8; // Data length in bytes (0-8) - p_CanMBoxes_->MBOX1.MSGCTRL.bit.RTR = 0; // Remote Transmission Request +void CAN::configTxMBox(Uint16 boxNumber, const ConfigMBox& configData){ + volatile MBOX* p_MailBox(NULL); + p_MailBox = &(p_CanMBoxes_->MBOX0) + boxNumber; + + Uint32 mboxControl(0); + mboxControl = 1ul << boxNumber; + + // Reset transmittion + CanShadow_.CANTRR.all = p_CanRegs_->CANTRR.all; + CanShadow_.CANTRR.all |= mboxControl; + p_CanRegs_->CANTRR.all = CanShadow_.CANTRR.all; + do {CanShadow_.CANTRS.all = p_CanRegs_->CANTRS.all;} + while((CanShadow_.CANTRS.all & mboxControl) != 0); // Wait for TRS bit to be cleared + + // Mailbox disable + CanShadow_.CANME.all = p_CanRegs_->CANME.all; + CanShadow_.CANME.all &= ~(mboxControl); + p_CanRegs_->CANME.all = CanShadow_.CANME.all; + + // Write to the MSGID field + p_MailBox->MSGID.all = configData.msgID.all; + + // Mailbox direction - transmit CanShadow_.CANMD.all = p_CanRegs_->CANMD.all; - CanShadow_.CANMD.bit.MD1 = 0; // Mailbox direction - transmit + CanShadow_.CANMD.all &= ~(mboxControl); p_CanRegs_->CANMD.all = CanShadow_.CANMD.all; + // Write to RTR and TPL field in control reg + p_MailBox->MSGCTRL.bit.RTR = configData.msgCtrlReg.bit.RTR; + // p_MailBox->MSGCTRL.bit.TPL = configData.msgCtrlReg.bit.TPL; // enable if you need to set msg priority lvl + + // Mailbox enable CanShadow_.CANME.all = p_CanRegs_->CANME.all; - CanShadow_.CANME.bit.ME1 = 1; + CanShadow_.CANME.all |= mboxControl; p_CanRegs_->CANME.all = CanShadow_.CANME.all; } -void CAN::configRxMBoxes(){ +// void CAN::configRxMBoxes(){ // TODO make this method with parameters + +// // Write to the MSGID field +// p_CanMBoxes_->MBOX25.MSGID.all = 0x0; +// p_CanMBoxes_->MBOX25.MSGID.bit.STDMSGID = 0xAAA; + +// // Write to DLC field in Master Control reg +// p_CanMBoxes_->MBOX25.MSGCTRL.bit.DLC = 8; +// p_CanMBoxes_->MBOX25.MSGCTRL.bit.RTR = 0; + +// // +// // Configure Mailbox under test as a Receive mailbox +// // +// CanShadow_.CANMD.all = p_CanRegs_->CANMD.all; +// CanShadow_.CANMD.bit.MD25 = 1; +// p_CanRegs_->CANMD.all = CanShadow_.CANMD.all; + +// // Overwrite protection +// // CanShadow_.CANOPC.all = p_CanRegs_->CANOPC.all; +// // CanShadow_.CANOPC.bit.OPC1 = 1; // Should be one more mailbox to store 'overflow' messages +// // p_CanRegs_->CANOPC.all = CanShadow_.CANOPC.all; + +// // Enable Mailbox +// CanShadow_.CANME.all = p_CanRegs_->CANME.all; +// CanShadow_.CANME.bit.ME25 = 1; +// p_CanRegs_->CANME.all = CanShadow_.CANME.all; + +// // Write to the mailbox RAM field +// p_CanMBoxes_->MBOX25.MDL.all = 0x55555555; +// p_CanMBoxes_->MBOX25.MDH.all = 0x55555555; +// } + + +void CAN::configRxMBoxes(Uint16 boxNumber, const ConfigMBox& configData){ + + volatile MBOX* p_MailBox(NULL); + p_MailBox = &(p_CanMBoxes_->MBOX0) + boxNumber; + + Uint32 mboxControl(0); + mboxControl = 1ul << boxNumber; // Write to the MSGID field - p_CanMBoxes_->MBOX25.MSGID.all = 0x0; - p_CanMBoxes_->MBOX25.MSGID.bit.STDMSGID = 0xAAA; + p_MailBox->MSGID.all = 0x0; + p_MailBox->MSGID.all = configData.msgID.all; - // Write to DLC field in Master Control reg - p_CanMBoxes_->MBOX25.MSGCTRL.bit.DLC = 8; - p_CanMBoxes_->MBOX25.MSGCTRL.bit.RTR = 0; + // Write to DLC and RTR field in control reg + p_MailBox->MSGCTRL.bit.DLC = configData.msgCtrlReg.bit.DLC; + p_MailBox->MSGCTRL.bit.RTR = configData.msgCtrlReg.bit.RTR; - // // Configure Mailbox under test as a Receive mailbox - // CanShadow_.CANMD.all = p_CanRegs_->CANMD.all; - CanShadow_.CANMD.bit.MD25 = 1; + CanShadow_.CANMD.all |= mboxControl; p_CanRegs_->CANMD.all = CanShadow_.CANMD.all; // Overwrite protection + // If "ON" make sure that an additional mailbox is configured to store ’overflow’ messages. // CanShadow_.CANOPC.all = p_CanRegs_->CANOPC.all; - // CanShadow_.CANOPC.bit.OPC1 = 1; // Should be one more mailbox to store 'overflow' messages + // CanShadow_.CANOPC.all |= mboxControl; // Should be one more mailbox to store 'overflow' messages // p_CanRegs_->CANOPC.all = CanShadow_.CANOPC.all; // Enable Mailbox CanShadow_.CANME.all = p_CanRegs_->CANME.all; - CanShadow_.CANME.bit.ME25 = 1; + CanShadow_.CANME.all |= mboxControl; p_CanRegs_->CANME.all = CanShadow_.CANME.all; - // Write to the mailbox RAM field - p_CanMBoxes_->MBOX25.MDL.all = 0x55555555; - p_CanMBoxes_->MBOX25.MDH.all = 0x55555555; + // Write to the mailbox RAM field // TODO doesn't work when rx. Check for RTR + // p_MailBox->MDL.all = 0x55555555; + // p_MailBox->MDH.all = 0x55555555; } } //canSpace diff --git a/main.cpp b/main.cpp index a2246d7..7559fce 100644 --- a/main.cpp +++ b/main.cpp @@ -17,8 +17,10 @@ interrupt void cpu_timer0_isr(void); canSpace::CAN canTest; Uint16 msgsSent = 0; Uint16 infCounter = 0; +volatile Uint16 testCounter = 0; +Uint32 testVar = 0; volatile bool startTX = false; -MBOX message; +canSpace::CANMessage message; void main() { @@ -78,24 +80,24 @@ void main() canTest.initGpio(canSpace::CANB); canTest.config(canSpace::CANB, 100); - canTest.configTxMBoxes(); - canTest.configRxMBoxes(); + // canTest.configTxMBoxes(); + canTest.configTxMBox(1, canSpace::ConfigMBox(false, 0xAAA, 0x0, false, false, 0xF)); + canTest.configRxMBoxes(25, canSpace::ConfigMBox(false, 0xAAA, 0x0, false, false, 0xF)); // InitECanGpio(); // InitECan(); CpuTimer0.RegsAddr->TCR.bit.TSS = 0; - - message.MSGCTRL.bit.DLC = 8; - message.MDL.byte.BYTE0 = 0x11; - message.MDL.byte.BYTE1 = 0x22; - message.MDL.byte.BYTE2 = 0x33; - message.MDL.byte.BYTE3 = 0x44; - message.MDH.byte.BYTE4 = 0xAA; - message.MDH.byte.BYTE5 = 0xBB; - message.MDH.byte.BYTE6 = 0xCC; - message.MDH.byte.BYTE7 = 0xDD; + message.msgctrl.bit.DLC = 8; + message.mdl.byte.BYTE0 = 0x11; + message.mdl.byte.BYTE1 = 0x22; + message.mdl.byte.BYTE2 = 0x33; + message.mdl.byte.BYTE3 = 0x44; + message.mdh.byte.BYTE4 = 0xAA; + message.mdh.byte.BYTE5 = 0xBB; + message.mdh.byte.BYTE6 = 0xCC; + message.mdh.byte.BYTE7 = 0xDD; idle_loop(); // @@ -113,7 +115,10 @@ void idle_loop() canTest.transmitMsg(1, message); msgsSent++; } - + if(canTest.isNewMessage()){ + testCounter++; + testVar = canTest.receiveMsg(25, message); + } }//end while //