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

323 lines
9.9 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "CAN.h"
#include "DSP2833x_ECan.h"
namespace can_space {
CAN::CAN(CAN_VARIANT canVariant) :
_canPort(canVariant),
_p_CanRegs(0),
_p_CanMBoxes(0),
_p_CanMotoRegs(0),
_p_CanMotsRegs(0)
{}
void CAN::initGpio(){
if(_canPort == CANA) InitECanaGpio();
else if (_canPort == CANB) InitECanbGpio();
}
void CAN::config(uint16_t baudrate, uint16_t flags){
if (_canPort == CANA){
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 1;
EDIS;
_p_CanRegs = &ECanaRegs;
_p_CanMBoxes = &ECanaMboxes;
_p_CanMotoRegs = &ECanaMOTORegs;
_p_CanMotsRegs = &ECanaMOTSRegs;
}
else if (_canPort == CANB){
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ECANBENCLK = 1;
EDIS;
_p_CanRegs = &ECanbRegs;
_p_CanMBoxes = &ECanbMboxes;
_p_CanMotoRegs = &ECanbMOTORegs;
_p_CanMotsRegs = &ECanbMOTSRegs;
}
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 );
// MSB - 0; LSB - 1
_CanShadow.CANMC.all = _p_CanRegs->CANMC.all;
if (flags & MSB_ENABLE){
_CanShadow.CANMC.bit.DBO = 0;
}
else
{ _CanShadow.CANMC.bit.DBO = 1; }
_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
_CanShadow.CANMC.all = _p_CanRegs->CANMC.all;
_CanShadow.CANMC.bit.ABO = 1;
_p_CanRegs->CANMC.all = _CanShadow.CANMC.all;
// 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_t boxNumber, const MsgID& configID, const MsgCtrlReg& configCtrlReg){
if (boxNumber > 31) return;
volatile MBOX* p_MailBox(0);
p_MailBox = &(_p_CanMBoxes->MBOX0) + boxNumber;
uint32_t 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;
// Config MBOX control reg
p_MailBox->MSGCTRL.all = configCtrlReg.all;
// Mailbox enable
_CanShadow.CANME.all = _p_CanRegs->CANME.all;
_CanShadow.CANME.all |= mboxControl;
_p_CanRegs->CANME.all = _CanShadow.CANME.all;
}
void CAN::configRxMBox(uint16_t boxNumber, const MsgID& configID, const MsgCtrlReg& configCtrlReg){
if (boxNumber > 31) return;
volatile MBOX* p_MailBox(0);
p_MailBox = &(_p_CanMBoxes->MBOX0) + boxNumber;
uint32_t mboxControl(0);
mboxControl = 1ul << boxNumber;
// 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_t flags){
EALLOW;
_p_CanRegs->CANGIM.all = flags;
EDIS;
}
void CAN::configMBoxIsr(uint16_t boxNumber){
if (boxNumber > 31) return;
uint32_t mboxControl(0);
mboxControl = 1ul << boxNumber;
EALLOW;
_p_CanRegs->CANMIL.all |= mboxControl;
_p_CanRegs->CANMIM.all |= mboxControl;
EDIS;
}
void CAN::enableTimeOutControl(uint16_t boxNumber){
if (boxNumber > 31) return;
uint32_t mboxControl(0);
mboxControl = _p_CanRegs->CANTOC.all;
mboxControl |= 1ul << boxNumber;
_p_CanRegs->CANTOC.all = mboxControl;
}
void CAN::disableTimeOutControl(uint16_t boxNumber){
if (boxNumber > 31) return;
uint32_t mboxControl(0);
mboxControl = _p_CanRegs->CANTOC.all;
mboxControl &= ~(1ul << boxNumber);
_p_CanRegs->CANTOC.all = mboxControl;
}
} //can_space