static void bmk9_execute(void) { uint32_t n; static uint8_t ib[16]; static InputQueue iq; chIQInit(&iq, ib, sizeof(ib), NULL); n = 0; test_wait_tick(); test_start_timer(1000); do { chIQPutI(&iq, 0); chIQPutI(&iq, 1); chIQPutI(&iq, 2); chIQPutI(&iq, 3); (void)chIQGet(&iq); (void)chIQGet(&iq); (void)chIQGet(&iq); (void)chIQGet(&iq); n++; #if defined(SIMULATOR) ChkIntSources(); #endif } while (!test_timer_done); test_print("--- Score : "); test_printn(n * 4); test_println(" bytes/S"); }
static void queues1_execute(void) { unsigned i; size_t n; /* Initial empty state */ test_assert_lock(1, chIQIsEmptyI(&iq), "not empty"); /* Queue filling */ chSysLock(); for (i = 0; i < TEST_QUEUES_SIZE; i++) chIQPutI(&iq, 'A' + i); chSysUnlock(); test_assert_lock(2, chIQIsFullI(&iq), "still has space"); test_assert_lock(3, chIQPutI(&iq, 0) == Q_FULL, "failed to report Q_FULL"); /* Queue emptying */ for (i = 0; i < TEST_QUEUES_SIZE; i++) test_emit_token(chIQGet(&iq)); test_assert_lock(4, chIQIsEmptyI(&iq), "still full"); test_assert_sequence(5, "ABCD"); /* Queue filling again */ chSysLock(); for (i = 0; i < TEST_QUEUES_SIZE; i++) chIQPutI(&iq, 'A' + i); chSysUnlock(); /* Reading the whole thing */ n = chIQReadTimeout(&iq, wa[1], TEST_QUEUES_SIZE * 2, TIME_IMMEDIATE); test_assert(6, n == TEST_QUEUES_SIZE, "wrong returned size"); test_assert_lock(7, chIQIsEmptyI(&iq), "still full"); /* Queue filling again */ chSysLock(); for (i = 0; i < TEST_QUEUES_SIZE; i++) chIQPutI(&iq, 'A' + i); chSysUnlock(); /* Partial reads */ n = chIQReadTimeout(&iq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); test_assert(8, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); n = chIQReadTimeout(&iq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); test_assert(9, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); test_assert_lock(10, chIQIsEmptyI(&iq), "still full"); /* Testing reset */ chSysLock(); chIQPutI(&iq, 0); chIQResetI(&iq); chSysUnlock(); test_assert_lock(11, chIQGetFullI(&iq) == 0, "still full"); threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread1, NULL); test_assert_lock(12, chIQGetFullI(&iq) == 0, "not empty"); test_wait_threads(); /* Timeout */ test_assert(13, chIQGetTimeout(&iq, 10) == Q_TIMEOUT, "wrong timeout return"); }
void USART2_IRQHandler(void) { uint16_t sr = huart2.Instance->SR; while (sr & (USART_SR_RXNE | USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)) { uint8_t b; /* Error condition detection.*/ if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)) { printf("uart error 0x%x!\r\n", sr); } b = huart2.Instance->DR; if (sr & USART_SR_RXNE) { if (Q_OK != chIQPutI(&g_iqp, b)) { printf("enqueue failed.\r\n"); } } sr = huart2.Instance->SR; } //CommUartIrqHandler(&huart2); }
/** * @brief Common IRQ handler. * @note Tries hard to clear all the pending interrupt sources, we don't * want to go through the whole ISR and have another interrupt soon * after. * * @param[in] u pointer to an UART I/O block * @param[in] sdp communication channel associated to the UART */ static void serve_interrupt(SerialDriver *sdp) { UART_TypeDef *u = sdp->uart; uint8_t s1 = u->S1; if (s1 & UARTx_S1_RDRF) { osalSysLockFromISR(); if (chIQIsEmptyI(&sdp->iqueue)) chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE); if (chIQPutI(&sdp->iqueue, u->D) < Q_OK) chnAddFlagsI(sdp, SD_OVERRUN_ERROR); osalSysUnlockFromISR(); } if (s1 & UARTx_S1_TDRE) { msg_t b; osalSysLockFromISR(); b = chOQGetI(&sdp->oqueue); osalSysUnlockFromISR(); if (b < Q_OK) { osalSysLockFromISR(); chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); osalSysUnlockFromISR(); u->C2 &= ~UARTx_C2_TIE; } else { u->D = b; } } }
/** * @brief Handles incoming data. * @details This function must be called from the input interrupt service * routine in order to enqueue incoming data and generate the * related events. * @note The incoming data event is only generated when the input queue * becomes non-empty. * @note In order to gain some performance it is suggested to not use * this function directly but copy this code directly into the * interrupt service routine. * * @param[in] sdp pointer to a @p SerialDriver structure * @param[in] b the byte to be written in the driver's Input Queue * * @iclass */ void sdIncomingDataI(SerialDriver *sdp, uint8_t b) { chDbgCheckClassI(); chDbgCheck(sdp != NULL, "sdIncomingDataI"); if (chIQIsEmptyI(&sdp->iqueue)) chIOAddFlagsI(sdp, IO_INPUT_AVAILABLE); if (chIQPutI(&sdp->iqueue, b) < Q_OK) chIOAddFlagsI(sdp, SD_OVERRUN_ERROR); }
void CommUartRxIrqProcess(UART_HandleTypeDef *huart) { uint8_t b; g_dbgUartRxCnt++; b = huart->Instance->DR & 0xff; if (Q_OK != chIQPutI(&g_iqp, b)) { printf("enqueue failed.\r\n"); } return; }
/** * @brief Common IRQ handler. * @note Tries hard to clear all the pending interrupt sources, we dont want * to go through the whole ISR and have another interrupt soon after. * * @param[in] sdp communication channel associated to the UART */ static void serve_interrupt(SerialDriver *sdp) { UART *u = sdp->uart; while (TRUE) { switch (u->UART_IIR & IIR_SRC_MASK) { case IIR_SRC_NONE: return; case IIR_SRC_ERROR: set_error(sdp, u->UART_LSR); break; case IIR_SRC_TIMEOUT: case IIR_SRC_RX: chSysLockFromIsr(); if (chIQIsEmptyI(&sdp->iqueue)) chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE); chSysUnlockFromIsr(); while (u->UART_LSR & LSR_RBR_FULL) { chSysLockFromIsr(); if (chIQPutI(&sdp->iqueue, u->UART_RBR) < Q_OK) chnAddFlagsI(sdp, SD_OVERRUN_ERROR); chSysUnlockFromIsr(); } break; case IIR_SRC_TX: { int i = LPC214x_UART_FIFO_PRELOAD; do { msg_t b; chSysLockFromIsr(); b = chOQGetI(&sdp->oqueue); chSysUnlockFromIsr(); if (b < Q_OK) { u->UART_IER &= ~IER_THRE; chSysLockFromIsr(); chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); chSysUnlockFromIsr(); break; } u->UART_THR = b; } while (--i); } break; default: (void) u->UART_THR; (void) u->UART_RBR; } } }
/** * @brief Common IRQ handler. * @note Tries hard to clear all the pending interrupt sources, we don't * want to go through the whole ISR and have another interrupt soon * after. * * @param[in] u pointer to an UART I/O block * @param[in] sdp communication channel associated to the UART */ static void serve_interrupt(SerialDriver *sdp) { LPC_UART_TypeDef *u = sdp->uart; while (TRUE) { switch (u->IIR & IIR_SRC_MASK) { case IIR_SRC_NONE: return; case IIR_SRC_ERROR: set_error(sdp, u->LSR); break; case IIR_SRC_TIMEOUT: case IIR_SRC_RX: chSysLockFromIsr(); if (chIQIsEmpty(&sdp->iqueue)) chEvtBroadcastI(&sdp->ievent); chSysUnlockFromIsr(); while (u->LSR & LSR_RBR_FULL) { chSysLockFromIsr(); if (chIQPutI(&sdp->iqueue, u->RBR) < Q_OK) sdAddFlagsI(sdp, SD_OVERRUN_ERROR); chSysUnlockFromIsr(); } break; case IIR_SRC_TX: { int i = LPC13xx_UART_FIFO_PRELOAD; do { msg_t b; chSysLockFromIsr(); b = chOQGetI(&sdp->oqueue); chSysUnlockFromIsr(); if (b < Q_OK) { u->IER &= ~IER_THRE; chSysLockFromIsr(); chEvtBroadcastI(&sdp->oevent); chSysUnlockFromIsr(); break; } u->THR = b; } while (--i); } break; default: (void) u->THR; (void) u->RBR; } } }
/** * @brief Common IRQ handler. * @note Tries hard to clear all the pending interrupt sources, we don't * want to go through the whole ISR and have another interrupt soon * after. * * @param[in] u pointer to an UART I/O block * @param[in] sdp communication channel associated to the UART */ static void serve_interrupt(SerialDriver *sdp) { LPC_USART_TypeDef *u = sdp->uart; while (u->INTSTAT) { if (u->INTSTAT & STAT_RXRDY) { chSysLockFromIsr(); if (chIQIsEmptyI(&sdp->iqueue)) chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE); if (chIQPutI(&sdp->iqueue, u->RXDATA) < Q_OK) chnAddFlagsI(sdp, SD_OVERRUN_ERROR); chSysUnlockFromIsr(); } if (u->INTSTAT & STAT_TXRDY) { msg_t b; chSysLockFromIsr(); b = chOQGetI(&sdp->oqueue); chSysUnlockFromIsr(); if (b < Q_OK) { u->INTENCLR = STAT_TXRDY; chSysLockFromIsr(); chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); chSysUnlockFromIsr(); break; } else { u->TXDATA = b; } } if (u->INTSTAT & (STAT_OVERRUN | STAT_DELTARXBRK | STAT_FRAMERR | STAT_PARITYERR) ) { IOREG32 stat = u->STAT; set_error(sdp, stat); u->STAT = stat; } } }
msg_t InQueue::putI(uint8_t b) { return chIQPutI(&iq, b); }