// ---------------------------------------------------------------------------- // Configure the mailbox to send a CAN message. // Low level function called by sendMessage and by Tx Interrupt. static void sendMailbox(const xpcc::can::Message& message, uint32_t mailboxId) { CAN_TxMailBox_TypeDef* mailbox = &CAN2->sTxMailBox[mailboxId]; if (message.isExtended()) { mailbox->TIR = message.identifier << 3 | CAN_TI0R_IDE; } else { mailbox->TIR = message.identifier << 21; } if (message.isRemoteTransmitRequest()) { mailbox->TIR |= CAN_TI0R_RTR; } // Set up the DLC mailbox->TDTR = message.getLength(); // Set up the data field (copy the 8x8-bits into two 32-bit registers) const uint8_t * ATTRIBUTE_MAY_ALIAS data = message.data; mailbox->TDLR = reinterpret_cast<const uint32_t *>(data)[0]; mailbox->TDHR = reinterpret_cast<const uint32_t *>(data)[1]; // Request transmission mailbox->TIR |= CAN_TI0R_TXRQ; }
// ---------------------------------------------------------------------------- // Low level function to receive a message from mailbox. // Called by Rx Interrupt or by getMessage. static void readMailbox(xpcc::can::Message& message, uint32_t mailboxId) { CAN_FIFOMailBox_TypeDef* mailbox = &CAN2->sFIFOMailBox[mailboxId]; uint32_t rir = mailbox->RIR; if (rir & CAN_RI0R_IDE) { message.identifier = rir >> 3; message.setExtended(); }
/* Low level function: * Called by interrupt or by getMessage to receive a message */ static void readMessageObject(xpcc::can::Message & message, uint8_t messageObjectId) { // NXP's data structure for sending CAN messages CAN_MSG_OBJ msg_obj; // Which Message Object to receive msg_obj.msgobj = messageObjectId; // Read Message Object from CAN controller (*xpcc::lpc::Can::rom)->pCAND->can_receive(&msg_obj); // Is extended Identifier? if (msg_obj.mode_id & CAN_MSGOBJ_EXT) { message.setExtended(); // The lower 29 bits are the extended identifier message.identifier = msg_obj.mode_id & 0x1fffffff; } else { message.setExtended(false); // The lower 11 bits are the standard identifier message.identifier = msg_obj.mode_id & 0x7ff; } // Is RTR ? message.setRemoteTransmitRequest( (msg_obj.mode_id & CAN_MSGOBJ_RTR) ); // Get DLC message.length = msg_obj.dlc; // Copy Data // TODO Use memcpy or reinterpret_cast for (uint8_t ii = 0; ii < message.length; ++ii) { message.data[ii] = msg_obj.data[ii]; } }
/* Low level function: * Use a Message Object to send a message */ static void sendMessageObject(const xpcc::can::Message & message, uint8_t messageObjectId) { // NXP's data structure for sending CAN messages CAN_MSG_OBJ msg_obj; // Which Message Object to use, valid numbers are 0 to 31. // In this class 16 to 31 are used. msg_obj.msgobj = messageObjectId; // Mode and Identifier msg_obj.mode_id = message.identifier | CAN_MSGOBJ_STD; if (message.isExtended()) { msg_obj.mode_id |= CAN_MSGOBJ_EXT; } if (message.isRemoteTransmitRequest()) { msg_obj.mode_id |= CAN_MSGOBJ_RTR; } // Mask unused for transmission msg_obj.mask = 0x0; // Set up the DLC msg_obj.dlc = message.getLength(); // Copy the data. // TODO reinterpret_cast or memcpy for (uint8_t ii = 0; ii < msg_obj.dlc; ++ii) { msg_obj.data[ii] = message.data[ii]; } // Really send the message (*xpcc::lpc::Can::rom)->pCAND->can_transmit(&msg_obj); }
// ---------------------------------------------------------------------------- static void displayMessage(const xpcc::can::Message& message) { static uint32_t receiveCounter = 0; receiveCounter++; display.clear(); display.setFont(xpcc::font::Assertion); display << " CAN Demo"; display.drawLine(0, 13, 102, 13); display.setCursor(0, 16); display.setFont(xpcc::font::FixedWidth5x8); display.printf("id =%lx\n", message.getIdentifier()); if (message.isExtended()) { display << " extended"; } else { display << " standard"; } if (message.isRemoteTransmitRequest()) { display << ", rtr"; } display << xpcc::endl; display << "dlc =" << message.getLength() << xpcc::endl; if (!message.isRemoteTransmitRequest()) { display << "data="; uint8_t x = display.getCursor().getX(); for (uint32_t i = 0; i < message.getLength(); ++i) { if (i == 4) { // wrap around to the next line display << xpcc::endl; display.setCursorX(x); } display << xpcc::hex << message.data[i] << xpcc::ascii << ' '; } display << xpcc::endl; } display << "# received=" << receiveCounter; display.update(); }