LCOV - code coverage report
Current view: top level - canbus - MCP2515Configurator.cpp (source / functions) Hit Total Coverage
Test: filtered.info Lines: 69 69 100.0 %
Date: 2025-07-25 11:48:17 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /*!
       2             :  * @file MCP2515Configurator.cpp
       3             :  * @brief Implementation of the MCP2515Configurator class.
       4             :  * @version 0.1
       5             :  * @date 2025-01-31
       6             :  * @author Félix LE BIHAN (@Fle-bihh)
       7             :  * @author Tiago Pereira (@t-pereira06)
       8             :  * @author Ricardo Melo (@reomelo)
       9             :  * @author Michel Batista (@MicchelFAB)
      10             :  *
      11             :  * @details This file contains the implementation of the MCP2515Configurator
      12             :  * class, which configures the MCP2515 CAN controller.
      13             :  *
      14             :  * @note This class is used to configure the MCP2515 CAN controller for
      15             :  * communication.
      16             :  *
      17             :  * @warning Ensure that the SPI controller is properly implemented.
      18             :  *
      19             :  * @see MCP2515Configurator.hpp for the class definition.
      20             :  *
      21             :  * @copyright Copyright (c) 2025
      22             :  *
      23             :  */
      24             : 
      25             : #include "MCP2515Configurator.hpp"
      26             : #include <chrono>
      27             : #include <thread>
      28             : 
      29             : /*!
      30             :  * @brief Construct a new MCP2515Configurator::MCP2515Configurator object
      31             :  * @param spiController The SPI controller to use for communication.
      32             :  * @details This constructor initializes the MCP2515Configurator object with the
      33             :  * specified SPI controller.
      34             :  */
      35          33 : MCP2515Configurator::MCP2515Configurator(ISPIController &spiController)
      36          33 :                 : spiController(spiController) {}
      37             : 
      38             : /*!
      39             :  * @brief clean up the resources used by the MCP2515Configurator.
      40             :  * @returns The chip in configuration mode.
      41             :  * @details This function cleans up the resources used putting the MCP2515 to
      42             :  * default configuration.
      43             :  */
      44           3 : bool MCP2515Configurator::resetChip() {
      45           3 :         sendCommand(RESET_CMD);
      46           3 :         std::this_thread::sleep_for(std::chrono::milliseconds(10));
      47           3 :         uint8_t status = readRegister(CANSTAT);
      48           3 :         return (status & 0xE0) == 0x80; // Verify configuration mode
      49             : }
      50             : 
      51             : /*!
      52             :  * @brief Configure the baud rate for the MCP2515.
      53             :  * @details This function sets the baud rate for the MCP2515.
      54             :  */
      55           2 : void MCP2515Configurator::configureBaudRate() {
      56           2 :         writeRegister(CNF1, 0x00); // Set BRP (Baud Rate Prescaler)
      57           2 :         writeRegister(CNF2, 0x90); // Set Propagation and Phase Segment 1
      58           2 :         writeRegister(CNF3, 0x02); // Set Phase Segment 2
      59           2 : }
      60             : 
      61             : /*!
      62             :  * @brief Configure the TX buffer for the MCP2515.
      63             :  * @details This function configures the TX buffer for the MCP2515.
      64             :  */
      65           2 : void MCP2515Configurator::configureTXBuffer() {
      66           2 :         writeRegister(TXB0CTRL, 0x00); // Clear TX buffer control register
      67           2 : }
      68             : 
      69             : /*!
      70             :  * @brief Configure the RX buffer for the MCP2515.
      71             :  * @details This function configures the RX buffer for the MCP2515.
      72             :  */
      73           2 : void MCP2515Configurator::configureRXBuffer() {
      74           2 :         writeRegister(RXB0CTRL,
      75             :                                                                 0x60); // Enable rollover and set RX mode to receive all
      76           2 : }
      77             : 
      78             : /*!
      79             :  * @brief Configure the filters and masks for the MCP2515.
      80             :  * @details This function configures the filters and masks for the MCP2515.
      81             :  */
      82           2 : void MCP2515Configurator::configureFiltersAndMasks() {
      83           2 :         writeRegister(0x00, 0xFF); // Set filter 0
      84           2 :         writeRegister(0x01, 0xFF); // Set mask 0
      85           2 : }
      86             : 
      87             : /*!
      88             :  * @brief Configure the interrupts for the MCP2515.
      89             :  * @details This function configures the interrupts for the MCP2515.
      90             :  */
      91           2 : void MCP2515Configurator::configureInterrupts() {
      92           2 :         writeRegister(CANINTE, 0x01); // Enable receive interrupt
      93           2 : }
      94             : 
      95             : /*!
      96             :  * @brief Set the mode for the MCP2515.
      97             :  * @param mode The mode to set.
      98             :  * @details This function sets the mode for the MCP2515.
      99             :  */
     100           2 : void MCP2515Configurator::setMode(uint8_t mode) {
     101           2 :         writeRegister(CANCTRL, mode);
     102           2 : }
     103             : 
     104             : /*!
     105             :  * @brief Verify the mode of the MCP2515.
     106             :  * @param expectedMode The expected mode.
     107             :  * @returns True if the mode is as expected, false otherwise.
     108             :  * @details This function verifies the mode of the MCP2515.
     109             :  */
     110           3 : bool MCP2515Configurator::verifyMode(uint8_t expectedMode) {
     111           3 :         uint8_t mode = readRegister(CANSTAT) & 0xE0;
     112           3 :         return mode == expectedMode;
     113             : }
     114             : 
     115             : /*!
     116             :  * @brief Write a value to a register.
     117             :  * @param address The address of the register.
     118             :  * @param value The value to write.
     119             :  * @details This function writes a value to a register.
     120             :  */
     121          29 : void MCP2515Configurator::writeRegister(uint8_t address, uint8_t value) {
     122          29 :         spiController.writeByte(address, value);
     123          29 : }
     124             : 
     125             : /*!
     126             :  * @brief Read a value from a register.
     127             :  * @param address The address of the register.
     128             :  * @returns The value read from the register.
     129             :  * @details This function reads a value from a register.
     130             :  */
     131          29 : uint8_t MCP2515Configurator::readRegister(uint8_t address) {
     132          29 :         return spiController.readByte(address);
     133             : }
     134             : 
     135             : /*!
     136             :  * @brief Send a command to the MCP2515.
     137             :  * @param command The command to send.
     138             :  * @returns The response from the MCP2515.
     139             :  * @details This function sends a command to the MCP2515
     140             :  */
     141           3 : void MCP2515Configurator::sendCommand(uint8_t command) {
     142           3 :         uint8_t tx[] = {command};
     143           3 :         spiController.spiTransfer(tx, nullptr, sizeof(tx));
     144           3 : }
     145             : 
     146             : /*!
     147             :  * @brief Read a CAN message from the MCP2515.
     148             :  * @param frameID The frame ID of the message.
     149             :  * @returns The data of the message.
     150             :  * @details This function reads a CAN message from the MCP2515.
     151             :  */
     152          12 : std::vector<uint8_t> MCP2515Configurator::readCANMessage(uint16_t &frameID) {
     153          12 :         std::vector<uint8_t> CAN_RX_Buf;
     154             : 
     155          12 :         if (readRegister(CANINTF) & 0x01) { // Check if data is available
     156           2 :                 uint8_t sidh = readRegister(RXB0SIDH);
     157           2 :                 uint8_t sidl = readRegister(RXB0SIDL);
     158           2 :                 frameID = (sidh << 3) | (sidl >> 5);
     159             : 
     160           2 :                 uint8_t len = readRegister(0x65); // Length of the data
     161           5 :                 for (uint8_t i = 0; i < len; ++i) {
     162           3 :                         CAN_RX_Buf.push_back(readRegister(0x66 + i));
     163             :                 }
     164             : 
     165           2 :                 writeRegister(CANINTF, 0x00); // Clear interrupt flag
     166             :         }
     167             : 
     168          11 :         return CAN_RX_Buf;
     169             : }
     170             : 
     171             : /*!
     172             :  * @brief Send a CAN message to the MCP2515.
     173             :  * @param frameID The frame ID of the message.
     174             :  * @param CAN_TX_Buf The data of the message.
     175             :  * @param length1 The length of the data.
     176             :  * @details This function sends a CAN message to the MCP2515.
     177             :  */
     178           1 : void MCP2515Configurator::sendCANMessage(uint16_t frameID, uint8_t *CAN_TX_Buf,
     179             :                                                                                                                                                                  uint8_t length1) {
     180           1 :         uint8_t tempdata = readRegister(CAN_RD_STATUS);
     181           1 :         writeRegister(TXB0SIDH, (frameID >> 3) & 0xFF);
     182           1 :         writeRegister(TXB0SIDL, (frameID & 0x07) << 5);
     183             : 
     184           1 :         writeRegister(TXB0EID8, 0);
     185           1 :         writeRegister(TXB0EID0, 0);
     186           1 :         writeRegister(TXB0DLC, length1);
     187           4 :         for (uint8_t j = 0; j < length1; ++j) {
     188           3 :                 writeRegister(TXB0D0 + j, CAN_TX_Buf[j]);
     189             :         }
     190             : 
     191           1 :         if (tempdata & 0x04) { // TXREQ
     192           1 :                 std::this_thread::sleep_for(
     193           1 :                                 std::chrono::milliseconds(10)); // sleep for 0.01 seconds
     194           1 :                 writeRegister(TXB0CTRL, 0);         // clean flag
     195             :                 while (true) {
     196           1 :                         if ((readRegister(CAN_RD_STATUS) & 0x04) != 1) {
     197           1 :                                 break;
     198             :                         }
     199             :                 }
     200             :         }
     201           1 :         uint8_t rtsCommand = CAN_RTS_TXB0;
     202           1 :         spiController.spiTransfer(&rtsCommand, nullptr, 1);
     203           1 : }

Generated by: LCOV version 1.14