State Diagrams for the NEDMO/Controller:
The ControllerFSM, as depicted in the state diagram below, handles all user inputs and the UART related reception and transmission. The controller, referred to as the NEDMO, is comprised of a Fuelcon, responsible for communicating with the boat using class-defined communication protocol, and a Navcon, responsible for taking in inputs from three buttons, two joysticks, and an encoder recording large scale swinging motion. The handlings of the UART receiving and transmitting, the input capture system for the swing detection, and the check for the continuity of the large-scale motion are through interrupts. More details can be found in ControllerFSM.c.
A detailed explanation of UART receiving and transmitting processes is provided below:
Transmitting Process:
Depending on the current state of the FSM and the button inputs received, the controller can transmit one of three message types: ControlFrame, PairingFrame, or RefuelFrame. Whether to send RefuelFrame or ControlFrame depends on if there has been unsent refuel events stored when the 200ms timer sets off. These message frames are stored as static uint8_t arrays. During transmission, the software calculates a checksum by summing all bytes from API_IDENTIFIER_Index to the second-to-last byte of the array, then subtracting this 8-bit sum from 0xFF. This checksum is loaded into the SUM byte. The first byte of the message is then loaded into the U2TXREG register, and the UART2 TX interrupt is locally enabled. The index for the next byte to send (ByteInd) is set to 1. With UTXISEL set to 0b01, when all TX buffers are empty, the U2TXIF interrupt flag is set, and the byte corresponding to the ByteInd is loaded into the U2TXREG. When the ByteInd equals the length of the message, it indicates that all bytes have been loaded and transmitted. The UART2 TX interrupt is then locally disabled.
Receiving Process:
The interrupt is triggered whenever any bytes arrive withURXISEL set to 0b00. Upon receiving data, the first check is whether the byte matches the delimiter defined in the communication protocol. If it matches, the ActualMsgFlag control variable is set; if not, all receiving-related variables are cleared, and the system awaits the next valid frame. Whenever the U2 RXIF interrupt flag is set, indicating data in the buffer, the byte is read into ReceivedFrame[RxByteInd], and RxByteInd is incremented. When RxByteInd reaches 2, indicating the byte that stores the message length, MSG_LEN is updated to reflect the expected full frame length. This increment continues until RxByteInd is one less than MSG_LEN, indicating the end byte of the receiving frame when the RxByteInd is reset back to 0 and the ActualMsgFlag is cleared. Depending on the value at MSG_ID_Index in the ReceivedFrame, the system either acknowledges pairing with an ES_PAIRED_ACK or indicates the reception of fuel status from the 0ILUS with an ES_ValidStatusReceived.