Esempio n. 1
0
/*----------------------------------------------------------------------------*/
int main(void)
{
  setupClock();

  const struct Pin led = pinInit(LED_PIN);
  pinOutput(led, true);

  struct GpTimerPwmUnit * const pwmUnit = init(GpTimerPwmUnit, &pwmUnitConfig);
  assert(pwmUnit);
  struct Pwm * const pwmOutput = gpTimerPwmCreate(pwmUnit, OUTPUT_PIN);
  assert(pwmOutput);
  pwmSetDuration(pwmOutput, pwmGetResolution(pwmOutput) / 2);

  struct Timer * const counter = init(GpTimerCounter, &counterConfig);
  assert(counter);

  struct Timer * const timer = init(GpTimer, &timerConfig);
  assert(timer);
  timerSetOverflow(timer, 1000);

  bool event = false;
  timerSetCallback(timer, onTimerOverflow, &event);

  timerEnable(counter);
  pwmEnable(pwmOutput);
  timerEnable(timer);

  while (1)
  {
    while (!event)
      barrier();
    event = false;

    const uint32_t period = timerGetValue(counter);
    timerSetValue(counter, 0);

    if (period >= 999 && period <= 1001)
      pinReset(led);
    else
      pinSet(led);
  }

  return 0;
}
Esempio n. 2
0
/*----------------------------------------------------------------------------*/
static void interruptHandler(void *object)
{
  struct Can * const interface = object;
  LPC_CAN_Type * const reg = interface->base.reg;
  bool event = false;

  while (reg->SR & SR_RBS)
  {
    if (!queueEmpty(&interface->pool))
    {
      const uint32_t timestamp = interface->timer ?
          timerGetValue(interface->timer) : 0;

      const uint32_t data[2] = {reg->RDA, reg->RDB};
      const uint32_t information = reg->RFS;
      struct CanStandardMessage *message;

      queuePop(&interface->pool, &message);

      message->timestamp = timestamp;
      message->id = reg->RID;
      message->length = RFS_DLC_VALUE(information);
      message->flags = 0;
      if (information & RFS_FF)
        message->flags |= CAN_EXT_ID;
      if (information & RFS_RTR)
        message->flags |= CAN_RTR;
      memcpy(message->data, data, sizeof(data));

      queuePush(&interface->rxQueue, &message);
      event = true;
    }

    /* Release receive buffer */
    reg->CMR = CMR_RRB;
  }

  uint32_t status = reg->SR;

  if (status & SR_TBS_MASK)
  {
    /* Disable interrupts for completed transmit buffers */
    uint32_t enabledInterrupts = reg->IER;

    if (status & SR_TBS(0))
      enabledInterrupts &= ~IER_TIE1;
    if (status & SR_TBS(1))
      enabledInterrupts &= ~IER_TIE2;
    if (status & SR_TBS(2))
      enabledInterrupts &= ~IER_TIE3;

    reg->IER = enabledInterrupts;

    while (!queueEmpty(&interface->txQueue) && (status & SR_TBS_MASK))
    {
      const struct CanMessage *message;

      queuePop(&interface->txQueue, &message);
      status = sendMessage(interface, message, status);
    }
  }

  if (status & SR_BS)
  {
    /*
     * The controller is forced into a bus-off state, RM bit should be cleared
     * to continue normal operation.
     */
    reg->MOD &= ~MOD_RM;
  }

  if (interface->callback && event)
    interface->callback(interface->callbackArgument);
}
Esempio n. 3
0
File: can.c Progetto: stxent/halm
/*----------------------------------------------------------------------------*/
static void interruptHandler(void *object)
{
  struct Can * const interface = object;
  LPC_CAN_Type * const reg = interface->base.reg;
  const uint32_t icr = reg->ICR;
  bool event = false;

  if (icr & ICR_RI)
  {
    while (reg->SR & SR_RBS)
    {
      const uint32_t timestamp = interface->timer ?
          timerGetValue(interface->timer) : 0;

      if (!pointerQueueFull(&interface->rxQueue))
      {
        struct CanMessage * const message = pointerArrayBack(&interface->pool);
        pointerArrayPopBack(&interface->pool);

        readMessage(interface, message);
        message->timestamp = timestamp;
        pointerQueuePushBack(&interface->rxQueue, message);
        event = true;
      }

      /* Release receive buffer */
      reg->CMR = CMR_RRB | CMR_CDO;
    }
  }

  const uint32_t sr = reg->SR;

  if ((icr & (ICR_EPI | ICR_TI_MASK)) && !(sr & SR_BS))
  {
    uint32_t status = sr & SR_TBS_MASK;

    /*
     * Enqueue new messages when:
     *   - no sequence restart occurred.
     *   - when sequence restart occurred and hardware queue was drained.
     */
    if (interface->sequence || status == SR_TBS_MASK)
    {
      while (!pointerQueueEmpty(&interface->txQueue) && status)
      {
        struct CanMessage * const message =
            pointerQueueFront(&interface->txQueue);
        pointerQueuePopFront(&interface->txQueue);

        sendMessage(interface, message, &status);
        pointerArrayPushBack(&interface->pool, message);

        /* Check whether sequence restart occurred or not */
        if (!interface->sequence)
          break;
      }
    }
  }

  if ((icr & ICR_BEI) && (sr & SR_BS))
  {
    /*
     * The controller is forced into a bus-off state, RM bit should be cleared
     * to continue normal operation.
     */
    reg->MOD &= ~MOD_RM;
  }

  if (interface->callback && event)
    interface->callback(interface->callbackArgument);
}