# Adding an MCP2515 CAN Controller Component to SimulIDE

This tutorial explains how to add a custom MCP2515 CAN controller component to SimulIDE.

The goal of this component is educational: it allows students to understand how a CAN controller works internally through SPI communication, MCP2515 registers, TX/RX buffers, interrupts, loopback mode, and a simplified virtual CAN bus.

## 1. Project Goal

The MCP2515 component adds a simulated CAN controller that can be used with Arduino or other microcontrollers in SimulIDE.

The component supports:

* SPI communication using CS, SCK, SI/MOSI and SO/MISO
* MCP2515 register emulation
* RESET, READ, WRITE and BIT MODIFY SPI commands
* READ STATUS and RX STATUS commands
* TX buffer and RX buffer handling
* INT output, active low
* Loopback mode
* Virtual communication between two MCP2515 components using a Bus ID
* CANH/CANL visual waveform output
* Standard 11-bit CAN frame generation
* Bit stuffing
* CRC-15 generation
* Simplified ACK handling

This is not yet a complete physical CAN bus simulator, but it is already useful for teaching SPI, CAN frames and the behavior of the MCP2515 controller.

## 2. Files to Add

Add the following two files to the SimulIDE source tree:

```text
SimulIDE-dev/src/components/micro/mcp2515.h
SimulIDE-dev/src/components/micro/mcp2515.cpp
```

These files contain the new `Mcp2515` component class.

The component provides the following pins:

```text
VCC
GND
CS
Rst
SI
SO
SCK
INT
CANH
CANL
```

Pin meaning:

```text
VCC   : logic supply, mainly visual in the current version
GND   : ground, mainly visual in the current version
CS    : SPI chip select, active low
Rst   : reset input, active low
SI    : SPI input, MOSI
SO    : SPI output, MISO
SCK   : SPI clock
INT   : interrupt output, active low
CANH  : visual CAN high signal
CANL  : visual CAN low signal
```

## 3. Registering the Component in SimulIDE

To make the component visible in the SimulIDE component list, modify:

```text
SimulIDE-dev/src/gui/componentlist/itemlibrary.cpp
```

Add the include:

```cpp
#include "mcp2515.h"
```

Then, inside `ItemLibrary::loadItems()`, add the MCP2515 component in the `Peripherals` section.

For example:

```cpp
addItem( new LibraryItem( QObject::tr("Peripherals"), "Micro", "perif.png","Peripherals", nullptr ) );
addItem( SerialPort::libraryItem() );
addItem( SerialTerm::libraryItem() );
addItem( TouchPad::libraryItem() );
addItem( KY023::libraryItem() );
addItem( KY040::libraryItem() );
addItem( DS1307::libraryItem() );
addItem( Esp01::libraryItem() );
addItem( Mcp2515::libraryItem() );
```

After recompiling SimulIDE, the component should appear in:

```text
Micro
└── Peripherals
    └── MCP2515 CAN
```

## 4. Important Note About the `.pro` File

If the SimulIDE `.pro` file already contains:

```pro
SOURCES = $$files( $$PWD/src/*.cpp, true )
HEADERS = $$files( $$PWD/src/*.h, true )
```

then you do not need to manually add:

```pro
src/components/micro/mcp2515.cpp
src/components/micro/mcp2515.h
```

These files are already included automatically.

Do not add them twice, otherwise you may get linker errors such as:

```text
multiple definition of `Mcp2515::stamp()`
multiple definition of `Mcp2515::paint(...)`
multiple definition of `Mcp2515::updateStep()`
```

## 5. Building SimulIDE

After adding the files and modifying `itemlibrary.cpp`, rebuild the project.

Recommended steps in Qt Creator:

```text
Build > Clean All
Build > Run qmake
Build > Rebuild All
```

Then run the generated executable, for example:

```text
build_XX/executables/SimulIDE_1.2.0-RC1/simulide.exe
```

Make sure you run the newly compiled executable, not an older installed version of SimulIDE.

## 6. Basic Wiring with Arduino

For a basic test with an Arduino Uno, use the following wiring:

```text
Arduino Uno      MCP2515
-----------      -------
5V               VCC
GND              GND
D10              CS
D13              SCK
D11              SI
D12              SO
5V               Rst
D2               INT
```

The reset pin is active low. If it is left floating or connected to ground, the MCP2515 will stay in reset. For a first test, connect `Rst` to `5V`.

## 7. Basic SPI Test

The first test should check that the MCP2515 responds to SPI commands.

Expected results:

```text
CANSTAT after RESET = 0x80
CANCTRL after RESET = 0x87
CNF1 = 0x03
CNF2 = 0x90
CNF3 = 0x02
CANCTRL loopback = 0x47
CANSTAT loopback = 0x40
```

This validates:

```text
SPI RESET
SPI READ
SPI WRITE
SPI BIT MODIFY
MISO/SO output
MCP2515 mode switching
```

## 8. Loopback Test

In loopback mode, a transmitted frame is copied from TXB0 to RXB0 inside the same MCP2515.

Example expected result:

```text
CANINTF after RTS = 0x05
READ STATUS after RTS = 0x09
RX STATUS after RTS = 0x40
RXB0D0 = 0xAB
RXB0D1 = 0xCD
INT pin after reception = 0
```

This means:

```text
TX0IF is set
RX0IF is set
RXB0 contains the transmitted data
INT is active low
```

## 9. Communication Between Two MCP2515 Components

The component includes a simplified virtual CAN bus using a property called `BusId`.

To connect two MCP2515 components together:

1. Place two Arduino boards.
2. Place two MCP2515 components.
3. Wire each Arduino to its own MCP2515 through SPI.
4. Set both MCP2515 components to the same Bus ID, for example:

```text
BusId = 1
```

5. Optionally connect CANH to CANH and CANL to CANL visually.

The actual virtual communication is based on the `BusId`.

Expected setup:

```text
Arduino 1 → MCP2515-1 → virtual CAN bus → MCP2515-2 → Arduino 2
```

## 10. CANH/CANL Oscilloscope Output

The component can generate a visible CAN-like waveform on CANH and CANL.

In the current educational version:

```text
Recessive bit = 1
CANH = 0
CANL = 1

Dominant bit = 0
CANH = 1
CANL = 0
```

This is not an exact analog CAN physical layer, but it is very useful for observing the frame structure on the SimulIDE oscilloscope.

Recommended oscilloscope wiring:

```text
CH1 → CANH
CH2 → CANL
GND → GND
```

Recommended oscilloscope settings:

```text
Time Div : 10 ms/div to 50 ms/div
Volt Div : 1 V/div
Trigger  : CH1 / rising edge
```

If the signal scrolls too quickly, slow down the Arduino transmission rate or increase the simulated CAN bit time in the component.

## 11. Educational CAN Frame Generation

The component can generate a standard 11-bit CAN data frame.

The generated frame includes:

```text
SOF
11-bit identifier
RTR
IDE
r0
DLC
DATA
CRC-15
CRC delimiter
ACK slot
ACK delimiter
EOF
Intermission
```

Bit stuffing is applied from SOF to the end of the CRC field.

The ACK behavior is simplified:

* if another MCP2515 on the same BusId is in normal mode, the ACK slot is forced dominant;
* if no receiver is available, an error flag can be set in the transmitter.

## 12. Suggested Example Files

It is useful to provide the following Arduino examples with the component:

```text
mcp2515_loopback_test.ino
arduino1_mcp2515_transmitter.ino
arduino2_mcp2515_receiver.ino
```

The loopback example validates a single MCP2515.

The transmitter and receiver examples validate communication between two MCP2515 components.

## 13. Current Limitations

This implementation is educational and simplified.

Current limitations:

```text
No full physical CAN layer
No full multi-node arbitration yet
No complete error frame handling
No full MCP2515 acceptance filters and masks
No extended 29-bit identifier support yet
No TEC/REC error counters
No bus-off state
```

Possible future improvements:

```text
real arbitration between multiple transmitters
more accurate ACK handling
extended CAN frames
acceptance masks and filters
error frames
automatic retransmission
bus-off and error counter management
more realistic CANH/CANL analog levels
```

## 14. Conclusion

This MCP2515 component makes it possible to simulate and teach the relationship between:

```text
Arduino SPI communication
MCP2515 internal registers
CAN TX/RX buffers
interrupt handling
CAN frame generation
CANH/CANL waveform observation
```

It can be used as a teaching tool for embedded systems, SPI communication, and CAN bus fundamentals.
