/*----------------------------------------------------------------------------*/ static uint32_t sendMessage(struct Can *interface, const struct CanMessage *message, uint32_t status) { assert(message->length <= 8); LPC_CAN_Type * const reg = interface->base.reg; unsigned int index; uint32_t mask; if (status & SR_TBS(0)) { index = 0; mask = IER_TIE1; } else if (status & SR_TBS(1)) { index = 1; mask = IER_TIE2; } else { index = 2; mask = IER_TIE3; } uint32_t data[2] = {0}; uint32_t command = CMR_TR | CMR_STB(index); uint32_t information = TFI_DLC(message->length); if ((message->flags & CAN_SELF_RX) || interface->mode == MODE_LOOPBACK) command |= CMR_SRR; if (message->flags & CAN_EXT_ID) { assert(message->id < 1UL << 29); information |= TFI_FF; } else assert(message->id < 1UL << 11); if (message->flags & CAN_RTR) { assert(message->length == 0); information |= TFI_RTR; } memcpy(data, message->data, message->length); reg->TX[index].TFI = information; reg->TX[index].TID = message->id; reg->TX[index].TDA = data[0]; reg->TX[index].TDB = data[1]; reg->IER |= mask; reg->CMR = command; return status & ~SR_TBS(index); }
/*----------------------------------------------------------------------------*/ static void sendMessage(struct Can *interface, const struct CanMessage *message, uint32_t *status) { assert(message->length <= 8); uint32_t command = interface->mode != MODE_LOOPBACK ? CMR_TR : CMR_SRR; uint32_t information = TFI_DLC(message->length); if (message->flags & CAN_EXT_ID) { assert(message->id < (1UL << 29)); information |= TFI_FF; } else { assert(message->id < (1UL << 11)); } LPC_CAN_Type * const reg = interface->base.reg; const unsigned int position = countLeadingZeros32(reverseBits32(*status)); const unsigned int index = SR_TBS_VALUE_TO_CHANNEL(position); if (!(message->flags & CAN_RTR)) { uint32_t data[2]; memcpy(data, message->data, sizeof(data)); reg->TX[index].TDA = data[0]; reg->TX[index].TDB = data[1]; } else { information |= TFI_RTR; } reg->TX[index].TFI = information | TFI_PRIO(interface->sequence); reg->TX[index].TID = message->id; reg->CMR = command | CMR_STB(index); *status &= ~BIT(position); ++interface->sequence; }