Emandhal / MCP251XFD

MCP2517FD, MCP2518FD and MCP251863 driver
MIT License
28 stars 6 forks source link

Send optimization #16

Open mickeyl opened 2 months ago

mickeyl commented 2 months ago

Your driver works perfectly for me, but I wonder whether there's a chance to get more speed when sending or receiving packets. I stumbled over an optimization in https://github.com/pierremolinaro/acan2517/blob/master/src/ACAN2517.cpp where they are doing it like that:

void ACAN2517::appendInControllerTxFIFO (const CANMessage & inMessage) {
//--- Enter data to send to SPI into a 18-byte buffer (speed enhancement, thanks to thomasfla)
  uint8_t  buff [18] = {0} ;
//--- Enter command
  const uint16_t ramAddress = uint16_t (0x400 + readRegister32Assume_SPI_transaction (C1FIFOUA_REGISTER (TRANSMIT_FIFO_INDEX))) ;
  const uint16_t writeCommand = (ramAddress & 0x0FFF) | (0b0010 << 12) ;
  buff[0] = writeCommand >> 8 ;
  buff[1] = writeCommand & 0xFF ;
//--- Write identifier: if an extended frame is sent, identifier bits sould be reordered (see DS20005678B, page 27)
  uint32_t idf = inMessage.id ;
  if (inMessage.ext) {
    idf = ((inMessage.id >> 18) & 0x7FF) | ((inMessage.id & 0x3FFFF) << 11) ;
  }
  enterWordInBufferAtIndex (idf, buff, TRANSMIT_FIFO_INDEX) ;
//--- Write DLC, RTR, IDE bits
  uint32_t parameters = (inMessage.len > 8) ? 8 : inMessage.len ;
  if (inMessage.rtr) {
    parameters |= 1 << 5 ; // Set RTR bit
  }
  if (inMessage.ext) {
    parameters |= 1 << 4 ; // Set EXT bit
  }
  enterWordInBufferAtIndex (parameters, buff, 6) ;
//--- Enter frame data
  for (uint32_t i=0 ; i<8 ; i++) {
    buff [10 + i] = inMessage.data [i] ;
  }
//--- Send via SPI
  assertCS () ;
    mSPI.transfer (buff, 18) ;
  deassertCS () ;
//--- Increment FIFO, send message (see DS20005688B, page 48)
  const uint8_t d = (1 << 0) | (1 << 1) ; // Set UINC bit, TXREQ bit
  writeRegister8Assume_SPI_transaction (C1FIFOCON_REGISTER (TRANSMIT_FIFO_INDEX) + 1, d);
}

Apparantly they manage to prepare the buffers so that they have only one SPI transfer. The origin of this is in this comment here:

https://github.com/pierremolinaro/acan2517/issues/2#issuecomment-461525728

Do you think that's a worthwhile goal to pursue?

Emandhal commented 2 months ago

Hi,

You want this kind of optimization to be done directly in the MCP251XFD_ReceiveMessageFromFIFO() and MCP251XFD_TransmitMessageToFIFO()? If so, we will loose the READ and WRITE CRC/SAFE capability.

If this is what you want, I can put a #ifdef directive and set this kind of optimization but I don't think I will do a direct Arduino call. What do you think?