You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CCS-COMM_BOARD/Protocol/CANConfig.cpp

288 lines
9.1 KiB
C++

#include "CAN.h"
namespace canSpace {
CAN::CAN(CAN_VARIANT canVariant) :
canPort(canVariant)
{}
void CAN::initGpio(){
if(canPort == CANA) InitECanaGpio();
else if (canPort == CANB) InitECanbGpio();
}
void CAN::config(Uint16 baudrate, Uint16 flags){
if (canPort == CANA){
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 1;
EDIS;
p_CanRegs_ = &ECanaRegs;
p_CanMBoxes_ = &ECanaMboxes;
}
else if (canPort == CANB){
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ECANBENCLK = 1;
EDIS;
p_CanRegs_ = &ECanbRegs;
p_CanMBoxes_ = &ECanbMboxes;
}
else { return; }
// Create a shadow register structure for the CAN control registers. This // TODO add this into description
// is needed, since only 32-bit access is allowed to these registers.
// 16-bit access to these registers could potentially corrupt the register
// contents or return false data. This is especially true while writing
// to/reading from a bit (or group of bits) among bits 16 - 31
EALLOW;
// 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;
CanShadow_.CANRIOC.all = p_CanRegs_->CANRIOC.all;
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
// initialized to zero
p_CanMBoxes_->MBOX0.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX1.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX2.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX3.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX4.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX5.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX6.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX7.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX8.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX9.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX10.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX11.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX12.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX13.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX14.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX15.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX16.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX17.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX18.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX19.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX20.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX21.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX22.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX23.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX24.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX25.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX26.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX27.MSGCTRL.all = 0x00000000;
p_CanMBoxes_->MBOX28.MSGCTRL.all = 0x00000000;
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;
p_CanRegs_->CANRMP.all = 0xFFFFFFFF;
p_CanRegs_->CANGIF0.all = 0xFFFFFFFF;
p_CanRegs_->CANGIF1.all = 0xFFFFFFFF;
// Configure bit timing parameters for eCANA
CanShadow_.CANMC.all = p_CanRegs_->CANMC.all;
CanShadow_.CANMC.bit.CCR = 1 ;
p_CanRegs_->CANMC.all = CanShadow_.CANMC.all;
do { CanShadow_.CANES.all = p_CanRegs_->CANES.all; }
while(CanShadow_.CANES.bit.CCE != 1 );
// LSB - 0; MSB - 1
CanShadow_.CANMC.all = p_CanRegs_->CANMC.all;
if (flags & MSB_ENABLE){
CanShadow_.CANMC.bit.DBO = 1;
}
else
{ CanShadow_.CANMC.bit.DBO = 0; }
p_CanRegs_->CANMC.all = CanShadow_.CANMC.all;
CanShadow_.CANBTC.all = 0;
// 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:
CanShadow_.CANBTC.bit.BRPREG = 4;
CanShadow_.CANBTC.bit.TSEG2REG = 3;
CanShadow_.CANBTC.bit.TSEG1REG = 9;
break;
case 500:
CanShadow_.CANBTC.bit.BRPREG = 9;
CanShadow_.CANBTC.bit.TSEG2REG = 3;
CanShadow_.CANBTC.bit.TSEG1REG = 9;
break;
case 250:
CanShadow_.CANBTC.bit.BRPREG = 19;
CanShadow_.CANBTC.bit.TSEG2REG = 3;
CanShadow_.CANBTC.bit.TSEG1REG = 9;
break;
case 100:
CanShadow_.CANBTC.bit.BRPREG = 49;
CanShadow_.CANBTC.bit.TSEG2REG = 3;
CanShadow_.CANBTC.bit.TSEG1REG = 9;
break;
default: return;
}
CanShadow_.CANBTC.bit.SAM = 1;
p_CanRegs_->CANBTC.all = CanShadow_.CANBTC.all;
CanShadow_.CANMC.all = p_CanRegs_->CANMC.all;
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;
// Disable all interrupts
p_CanRegs_->CANGIM.all = 0;
p_CanRegs_->CANMIM.all = 0;
//
// Debug feature
// Configure the eCAN for self test mode.
CanShadow_.CANMC.all = p_CanRegs_->CANMC.all;
if (flags & STM_ENABLE){
CanShadow_.CANMC.bit.STM = 1;
}
else
{ CanShadow_.CANMC.bit.STM = 0; }
p_CanRegs_->CANMC.all = CanShadow_.CANMC.all;
EDIS;
}
void CAN::configTxMBox(Uint16 boxNumber, const MsgID& configID, const MsgCtrlReg& configCtrlReg){
if (boxNumber > 31) return;
volatile MBOX* p_MailBox(0);
p_MailBox = &(p_CanMBoxes_->MBOX0) + boxNumber;
Uint32 mboxControl(0);
mboxControl = 1ul << boxNumber;
// Reset transmittion
if (CanShadow_.CANTRS.all &= mboxControl)
{
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 = configID.all;
// Mailbox direction - transmit
CanShadow_.CANMD.all = p_CanRegs_->CANMD.all;
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 = configCtrlReg.bit.RTR;
p_MailBox->MSGCTRL.bit.TPL = configCtrlReg.bit.TPL;
// Mailbox enable
CanShadow_.CANME.all = p_CanRegs_->CANME.all;
CanShadow_.CANME.all |= mboxControl;
p_CanRegs_->CANME.all = CanShadow_.CANME.all;
}
2 months ago
void CAN::configRxMBox(Uint16 boxNumber, const MsgID& configID, const MsgCtrlReg& configCtrlReg){
if (boxNumber > 31) return;
volatile MBOX* p_MailBox(0);
p_MailBox = &(p_CanMBoxes_->MBOX0) + boxNumber;
Uint32 mboxControl(0);
mboxControl = 1ul << boxNumber;
2 months ago
// 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 = 0x0;
p_MailBox->MSGID.all = configID.all;
// Write to DLC and RTR field in control reg
p_MailBox->MSGCTRL.bit.DLC = configCtrlReg.bit.DLC;
p_MailBox->MSGCTRL.bit.RTR = configCtrlReg.bit.RTR;
// Configure Mailbox under test as a Receive mailbox
CanShadow_.CANMD.all = p_CanRegs_->CANMD.all;
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.
if(configCtrlReg.bit.OPC){
CanShadow_.CANOPC.all = p_CanRegs_->CANOPC.all;
CanShadow_.CANOPC.all |= mboxControl;
p_CanRegs_->CANOPC.all = CanShadow_.CANOPC.all;
}
// Enable Mailbox
CanShadow_.CANME.all = p_CanRegs_->CANME.all;
CanShadow_.CANME.all |= mboxControl;
p_CanRegs_->CANME.all = CanShadow_.CANME.all;
}
void CAN::configSystemIsr(Uint32 flags){
EALLOW;
p_CanRegs_->CANGIM.all = flags;
EDIS;
}
void CAN::configMBoxIsr(Uint16 boxNumber){
if (boxNumber > 31) return;
Uint32 mboxControl(0);
mboxControl = 1ul << boxNumber;
EALLOW;
p_CanRegs_->CANMIL.all |= mboxControl;
p_CanRegs_->CANMIM.all |= mboxControl;
EDIS;
}
} //canSpace