Open
Description
I made a few optimizations to improve the performance of the interface for the MCP2515. There are a couple of commands to reduce the overhead of the SPI to increase the data throughput to and from the MCP2515; LOAD RX BUFFER, RTS, and READ RX BUFFER. I added it endPacket() even though it doesn't matter as much since it waits for the packet to complete sending before returning (there is still an improvement), the improvement in parsePacket() is nice.
int MCP2515Class::parsePacket()
{
int n;
uint8_t intf = readRegister(REG_CANINTF);
if (intf & FLAG_RXnIF(0))
{
n = 0;
}
else if (intf & FLAG_RXnIF(1))
{
n = 1;
}
else
{
_rxId = -1;
_rxRtr = false;
_rxLength = 0;
return 0;
}
uint8_t SIDH = readRegister(REG_RXBnSIDH(n));
uint8_t SIDL = readRegister(REG_RXBnSIDL(n));
uint32_t idA = ((SIDH << 3) & 0x07f8) | ((SIDL >> 5) & 0x07);
_rxId = idA;
_rxRtr = (SIDL & FLAG_SRR) ? true : false;
_rxDlc = readRegister(REG_RXBnDLC(n)) & 0x0f;
_rxIndex = 0;
if (_rxRtr)
{
_rxLength = 0;
}
else
{
_rxLength = _rxDlc;
SPI.beginTransaction(_spiSettings);
digitalWrite(_csPin, LOW);
SPI.transfer(0b10010010 | (n << 2)); //Set to stream RX data from Buffer n
for (uint8_t x = 0; x < _rxLength; x++)
_rxData[x] = SPI.transfer(0x00); //Stream data form RX buffer
digitalWrite(_csPin, HIGH); //unsetting CS pin will reset IRQ flag
SPI.endTransaction();
}
return _rxRtr ? true : _rxDlc;
}
int MCP2515Class::endPacket()
{
if (!CANControllerClass::endPacket())
{
return 0;
}
int n = 0;
writeRegister(REG_TXBnSIDH(n), _txId >> 3);
writeRegister(REG_TXBnSIDL(n), _txId << 5);
writeRegister(REG_TXBnEID8(n), 0x00);
writeRegister(REG_TXBnEID0(n), 0x00);
if (_txRtr)
{
writeRegister(REG_TXBnDLC(n), 0x40 | _txLength);
}
else
{
writeRegister(REG_TXBnDLC(n), _txLength); //set packet length
SPI.beginTransaction(_spiSettings);
digitalWrite(_csPin, LOW);
SPI.transfer(0b01000000 | (n * 2 + 1)); //set TX buffer for stream
for (uint8_t x = 0; x < _txLength; x++)
SPI.transfer(_txData[x]); //stream data to buffer
digitalWrite(_csPin, HIGH);
SPI.endTransaction();
}
SPI.beginTransaction(_spiSettings);
digitalWrite(_csPin, LOW);
SPI.transfer(0b10000000 | (1 << n)); //set RTS for TX Buffer n
digitalWrite(_csPin, HIGH);
SPI.endTransaction();
bool aborted = false;
while (readRegister(REG_TXBnCTRL(n)) & 0x08)
{
if (readRegister(REG_TXBnCTRL(n)) & 0x10)
{
// abort
aborted = true;
modifyRegister(REG_CANCTRL, 0x10, 0x10);
}
yield();
}
if (aborted) {
// clear abort command
modifyRegister(REG_CANCTRL, 0x10, 0x00);
}
modifyRegister(REG_CANINTF, FLAG_TXnIF(n), 0x00);
return (readRegister(REG_TXBnCTRL(n)) & 0x70) ? 0 : 1;
}
Metadata
Metadata
Assignees
Labels
No labels