/*----------------------------------------------------------------------------*/ 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; }
/*----------------------------------------------------------------------------*/ 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); }
/*----------------------------------------------------------------------------*/ 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); }