Microcontroller Communication Protocol
Microcontroller Communication Protocol (MCP) is used to send messages between different micro-controller on the robot.
All packets come in two formats: A bit array, optimized for size, and a C struct for ease of use. Functions are provided to easily switch between the two formats. Each type of packet comes with a unique header. The packet header, combined with the known packet lengths, allows sending multiple packets in a single transmission. Python bindings are provided to control the robots via python scripts. Python scripts are provided to automatically generate .c and .h files. No more manual bitshifting!
Folders & Files
There are 3 types of folders within MCP, namely to_board, from_board, and generator. The first two contain files that are received and sent from board respectively. This is done such that only necessary files are uploaded on the micro-controller with the help for platformio. As a consequence each packet can be found in at least two folders, which is not a problem as making changing should be done through the generator.
In the generator folder all definitions of boards and packets are hold, as well as the script to generate files from them. After making changes new files can be generated by running main.py
Besides the folders there are two more files. MCP_BaseTypes is a file that is also generated, and it holds helpful definitions about the packets, such as the ID that should be attached to the packet, minimum and maximum values of the packets. It also holds general definitions such as the ID of the boards and the masks and bit shifts information that is used for the ID. Lastly it contains some helper functions to retrieve for example the ID if the type of packet, and the receiving and sending board is given.
MCP_Driver.c/.h is a hand made file that has commonly used functions, such as initialization of the canfilter, methods to quickly handle incoming and outgoing packets, and useful stuff for the acknowledgements.
ack_numbers & free_to_send
ack_numbers and free_to_send are both arrays. As each board has an idea, the size of the array is the highest ID + 1. Lets say board XYZ has ID 15. From board ABC a message needs to send to board XYZ. First board ABC checks if free_to_send[15] is true. If not, the message cannot be send. Otherwise, the message is send with acknowledgement number ack_numbers[15]. Once the acknowledgement is received, ack_numbers[15] is increased by 1 (modulo 0xFF).
If no acknowledgement is sent this blocks the communication from board ABC to board XYZ temporarily. After 20ms the communication is unblocked. This way the loss of one message doesn't block the communication between two boards. In the current setup every board has 3 slots to receive packets from other boards. As between 2 boards only 1 packet could be active at any time, this does not create a problem at the time of writing this. WARNING: if more boards are to be attached and processing is not fast enough, communication could be blocked between to boards. Adding a more mailboxes or a system were packets are sent again if they are not acknowledged would be advised.
MCP_ARE_YOU_ALIVE & responses
These packets do not make actively use of acknowledgements, as it is the handshake that is sent during the initialization of the top-board. The responses do in a way acknowledge the MCP_ARE_YOU_ALIVE message.
These packets reset the free_to_send for the board the packet came from. For example the top-board sends MCP_ARE_YOU_ALIVE to the power board, than on the power-board the flag free_to_send is set to true for the top-board.