Example #1
0
/*----------------------------------------------------------------------------*/
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);
}
Example #2
0
File: can.c Project: stxent/halm
/*----------------------------------------------------------------------------*/
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;
}