Add RX and TX methods. Change config methods

Must be tested without test mode
feature/baseCAN
Oleg 2 months ago
parent 82df69c385
commit 4446eb970a

@ -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<bool>(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

@ -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_;

@ -1,10 +1,11 @@
#include "CAN.h"
#include "DSP2833x_ECan.h"
#include <cstddef>
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

@ -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
//

Loading…
Cancel
Save