Beispiel #1
0
static void set_error(uint8_t sra, SerialDriver *sdp) {
  flagsmask_t sts = 0;
  uint8_t dor = 0;
  uint8_t upe = 0;
  uint8_t fe = 0;

#if USE_AVR_USART0
  if (&SD1 == sdp) {
    dor = (1 << DOR0);
    upe = (1 << UPE0);
    fe = (1 << FE0);
  }
#endif

#if USE_AVR_USART1
  if (&SD2 == sdp) {
    dor = (1 << DOR1);
    upe = (1 << UPE1);
    fe = (1 << FE1);
  }
#endif

  if (sra & dor)
    sts |= SD_OVERRUN_ERROR;
  if (sra & upe)
    sts |= SD_PARITY_ERROR;
  if (sra & fe)
    sts |= SD_FRAMING_ERROR;
  chSysLockFromIsr();
  chnAddFlagsI(sdp, sts);
  chSysUnlockFromIsr();
}
Beispiel #2
0
static bool_t outint(SerialDriver *sdp) {

    if (sdp->com_data != INVALID_SOCKET) {
        int n;
        uint8_t data[1];

        /*
         * Input.
         */
        chSysLockFromIsr();
        n = sdRequestDataI(sdp);
        chSysUnlockFromIsr();
        if (n < 0)
            return FALSE;
        data[0] = (uint8_t)n;
        n = send(sdp->com_data, data, sizeof(data), 0);
        switch (n) {
        case 0:
            close(sdp->com_data);
            sdp->com_data = INVALID_SOCKET;
            chSysLockFromIsr();
            chnAddFlagsI(sdp, CHN_DISCONNECTED);
            chSysUnlockFromIsr();
            return FALSE;
        case INVALID_SOCKET:
            if (errno == EWOULDBLOCK)
                return FALSE;
            close(sdp->com_data);
            sdp->com_data = INVALID_SOCKET;
            return FALSE;
        }
        return TRUE;
    }
    return FALSE;
}
Beispiel #3
0
/**
 * @brief   Default data received callback.
 * @details The application must use this function as callback for the OUT
 *          data endpoint.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 * @param[in] ep        endpoint number
 */
void sduDataReceived(USBDriver *usbp, usbep_t ep) {
  size_t n, maxsize;
  SerialUSBDriver *sdup = usbp->out_params[ep - 1U];

  if (sdup == NULL) {
    return;
  }

  osalSysLockFromISR();
  chnAddFlagsI(sdup, CHN_INPUT_AVAILABLE);

  /* Writes to the input queue can only happen when there is enough space
     to hold at least one packet.*/
  maxsize = usbp->epc[ep]->out_maxsize;
  if ((n = iqGetEmptyI(&sdup->iqueue)) >= maxsize) {
    /* The endpoint cannot be busy, we are in the context of the callback,
       so a packet is in the buffer for sure.*/
    osalSysUnlockFromISR();

    n = (n / maxsize) * maxsize;
    usbPrepareQueuedReceive(usbp, ep, &sdup->iqueue, n);

    osalSysLockFromISR();
    (void) usbStartReceiveI(usbp, ep);
  }
  osalSysUnlockFromISR();
}
Beispiel #4
0
/**
 * @brief   USB device disconnection handler.
 * @note    If this function is not called from an ISR then an explicit call
 *          to @p osalOsRescheduleS() in necessary afterward.
 *
 * @param[in] uhdp      pointer to a @p USBHIDDriver object
 *
 * @iclass
 */
void hidDisconnectI(USBHIDDriver *uhdp) {

  /* Queues reset in order to signal the driver stop to the application.*/
  chnAddFlagsI(uhdp, CHN_DISCONNECTED);
  ibqResetI(&uhdp->ibqueue);
  obqResetI(&uhdp->obqueue);
}
Beispiel #5
0
static bool_t inint(SerialDriver *sdp) {

    if (sdp->com_data != INVALID_SOCKET) {
        int i;
        uint8_t data[32];

        /*
         * Input.
         */
        int n = recv(sdp->com_data, data, sizeof(data), 0);
        switch (n) {
        case 0:
            close(sdp->com_data);
            sdp->com_data = INVALID_SOCKET;
            chSysLockFromIsr();
            chnAddFlagsI(sdp, CHN_DISCONNECTED);
            chSysUnlockFromIsr();
            return FALSE;
        case INVALID_SOCKET:
            if (errno == EWOULDBLOCK)
                return FALSE;
            close(sdp->com_data);
            sdp->com_data = INVALID_SOCKET;
            return FALSE;
        }
        for (i = 0; i < n; i++) {
            chSysLockFromIsr();
            sdIncomingDataI(sdp, data[i]);
            chSysUnlockFromIsr();
        }
        return TRUE;
    }
    return FALSE;
}
Beispiel #6
0
/**
 * @brief   Default data received callback.
 * @details The application must use this function as callback for the OUT
 *          data endpoint.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 * @param[in] ep        OUT endpoint number
 */
void sduDataReceived(USBDriver *usbp, usbep_t ep) {
  uint8_t *buf;
  SerialUSBDriver *sdup = usbp->out_params[ep - 1U];

  if (sdup == NULL) {
    return;
  }

  osalSysLockFromISR();

  /* Signaling that data is available in the input queue.*/
  chnAddFlagsI(sdup, CHN_INPUT_AVAILABLE);

  /* Posting the filled buffer in the queue.*/
  ibqPostFullBufferI(&sdup->ibqueue,
                     usbGetReceiveTransactionSizeX(sdup->config->usbp,
                                                   sdup->config->bulk_out));

  /* The endpoint cannot be busy, we are in the context of the callback,
     so a packet is in the buffer for sure. Trying to get a free buffer
     for the next transaction.*/
  buf = ibqGetEmptyBufferI(&sdup->ibqueue);
  if (buf != NULL) {
    /* Buffer found, starting a new transaction.*/
    usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out,
                     buf, SERIAL_USB_BUFFERS_SIZE);
  }
  osalSysUnlockFromISR();
}
Beispiel #7
0
static bool connint(SerialDriver *sdp) {

  if (sdp->com_data == INVALID_SOCKET) {
    struct sockaddr addr;
    int addrlen = sizeof(addr);

    if ((sdp->com_data = accept(sdp->com_listen, &addr, &addrlen)) == INVALID_SOCKET)
      return false;

    if (ioctlsocket(sdp->com_data, FIONBIO, &nb) != 0) {
      printf("%s: Unable to setup non blocking mode on data socket\n", sdp->com_name);
      goto abort;
    }
    chSysLockFromISR();
    chnAddFlagsI(sdp, CHN_CONNECTED);
    chSysUnlockFromISR();
    return true;
  }
  return false;
abort:
  if (sdp->com_listen != INVALID_SOCKET)
    closesocket(sdp->com_listen);
  if (sdp->com_data != INVALID_SOCKET)
    closesocket(sdp->com_data);
  WSACleanup();
  exit(1);
}
Beispiel #8
0
/**
 * @brief   USB device disconnection handler.
 * @note    If this function is not called from an ISR then an explicit call
 *          to @p osalOsRescheduleS() in necessary afterward.
 *
 * @param[in] sdup      pointer to a @p SerialUSBDriver object
 *
 * @iclass
 */
void sduDisconnectI(SerialUSBDriver *sdup) {

  /* Queues reset in order to signal the driver stop to the application.*/
  chnAddFlagsI(sdup, CHN_DISCONNECTED);
  ibqResetI(&sdup->ibqueue);
  obqResetI(&sdup->obqueue);
}
Beispiel #9
0
static bool outint(SerialDriver *sdp) {

  if (sdp->com_data != INVALID_SOCKET) {
    int n;
    uint8_t data[1];

    /*
     * Input.
     */
    chSysLockFromISR();
    n = sdRequestDataI(sdp);
    chSysUnlockFromISR();
    if (n < 0)
      return false;
    data[0] = (uint8_t)n;
    n = send(sdp->com_data, (char *)data, sizeof(data), 0);
    switch (n) {
    case 0:
      closesocket(sdp->com_data);
      sdp->com_data = INVALID_SOCKET;
      chSysLockFromISR();
      chnAddFlagsI(sdp, CHN_DISCONNECTED);
      chSysUnlockFromISR();
      return false;
    case SOCKET_ERROR:
      if (WSAGetLastError() == WSAEWOULDBLOCK)
        return false;
      closesocket(sdp->com_data);
      sdp->com_data = INVALID_SOCKET;
      return false;
    }
    return true;
  }
  return false;
}
Beispiel #10
0
static bool inint(SerialDriver *sdp) {

  if (sdp->com_data != INVALID_SOCKET) {
    int i;
    uint8_t data[32];

    /*
     * Input.
     */
    int n = recv(sdp->com_data, (char *)data, sizeof(data), 0);
    switch (n) {
    case 0:
      closesocket(sdp->com_data);
      sdp->com_data = INVALID_SOCKET;
      chSysLockFromISR();
      chnAddFlagsI(sdp, CHN_DISCONNECTED);
      chSysUnlockFromISR();
      return false;
    case SOCKET_ERROR:
      if (WSAGetLastError() == WSAEWOULDBLOCK)
        return false;
      closesocket(sdp->com_data);
      sdp->com_data = INVALID_SOCKET;
      return false;
    }
    for (i = 0; i < n; i++) {
      chSysLockFromISR();
      sdIncomingDataI(sdp, data[i]);
      chSysUnlockFromISR();
    }
    return true;
  }
  return false;
}
Beispiel #11
0
/**
 * @brief   Common IRQ handler.
 *
 * @param[in] sdp       communication channel associated to the USART
 */
static void serve_interrupt(SerialDriver *sdp) {
  USART_TypeDef *u = sdp->usart;
  uint16_t cr1 = u->CR1;
  uint16_t sr = u->SR;

  /* Special case, LIN break detection.*/
  if (sr & USART_SR_LBD) {
    osalSysLockFromISR();
    chnAddFlagsI(sdp, SD_BREAK_DETECTED);
    osalSysUnlockFromISR();
    u->SR = ~USART_SR_LBD;
  }

  /* Data available.*/
  osalSysLockFromISR();
  while (sr & USART_SR_RXNE) {
    /* Error condition detection.*/
    if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE  | USART_SR_PE))
      set_error(sdp, sr);
    sdIncomingDataI(sdp, u->DR);
    sr = u->SR;
  }
  osalSysUnlockFromISR();

  /* Transmission buffer empty.*/
  if ((cr1 & USART_CR1_TXEIE) && (sr & USART_SR_TXE)) {
    msg_t b;
    osalSysLockFromISR();
    b = oqGetI(&sdp->oqueue);
    if (b < Q_OK) {
      chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
      u->CR1 = (cr1 & ~USART_CR1_TXEIE) | USART_CR1_TCIE;
    }
    else
      u->DR = b;
    osalSysUnlockFromISR();
  }

  /* Physical transmission end.*/
  if (sr & USART_SR_TC) {
    osalSysLockFromISR();
    chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
    osalSysUnlockFromISR();
    u->CR1 = cr1 & ~(USART_CR1_TXEIE | USART_CR1_TCIE);
    u->SR = ~USART_SR_TC;
  }
}
Beispiel #12
0
/**
 * @brief   USB device configured handler.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 *
 * @iclass
 */
void sduConfigureHookI(USBDriver *usbp) {
  SerialUSBDriver *sdup = usbp->param;

  sdup->flags = CHN_NO_ERROR;
  chIQResetI(&sdup->iqueue);
  chOQResetI(&sdup->oqueue);
  chnAddFlagsI(sdup, CHN_CONNECTED);
}
Beispiel #13
0
/**
 * @brief   Common IRQ handler.
 *
 * @param[in] sdp       communication channel associated to the USART
 */
static void serve_interrupt(SerialDriver *sdp) {
  USART_TypeDef *u = sdp->usart;
  uint32_t cr1 = u->CR1;
  uint32_t isr;

  /* Reading and clearing status.*/
  isr = u->ISR;
  u->ICR = isr;

  /* Error condition detection.*/
  if (isr & (USART_ISR_ORE | USART_ISR_NE | USART_ISR_FE  | USART_ISR_PE))
    set_error(sdp, isr);
  /* Special case, LIN break detection.*/
  if (isr & USART_ISR_LBD) {
    chSysLockFromIsr();
    chnAddFlagsI(sdp, SD_BREAK_DETECTED);
    chSysUnlockFromIsr();
  }
  /* Data available.*/
  if (isr & USART_ISR_RXNE) {
    chSysLockFromIsr();
    sdIncomingDataI(sdp, (uint8_t)u->RDR);
    chSysUnlockFromIsr();
  }
  /* Transmission buffer empty.*/
  if ((cr1 & USART_CR1_TXEIE) && (isr & USART_ISR_TXE)) {
    msg_t b;
    chSysLockFromIsr();
    b = chOQGetI(&sdp->oqueue);
    if (b < Q_OK) {
      chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
      u->CR1 = (cr1 & ~USART_CR1_TXEIE) | USART_CR1_TCIE;
    }
    else
      u->TDR = b;
    chSysUnlockFromIsr();
  }
  /* Physical transmission end.*/
  if (isr & USART_ISR_TC) {
    chSysLockFromIsr();
    chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
    chSysUnlockFromIsr();
    u->CR1 = cr1 & ~USART_CR1_TCIE;
  }
}
/**
 * @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 serial_serve_interrupt(SerialDriver *sdp) 
{
  uint32_t u = sdp->uart;
  uint16_t mis = HWREG(u + UART_O_MIS);
  
  HWREG(u + UART_O_ICR) = mis;		/* clear interrupts */

  if (mis & (UART_MIS_FEMIS | UART_MIS_PEMIS | UART_MIS_BEMIS | UART_MIS_OEMIS)) {
    set_error(sdp, mis);
  }

  if ((mis & UART_MIS_RXMIS) || (mis &  UART_MIS_RTMIS)) {
    osalSysLockFromISR();
    if (iqIsEmptyI(&sdp->iqueue)) {
      chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE);
    }
    osalSysUnlockFromISR();
    while ((HWREG(u + UART_O_FR) & UART_FR_RXFE) == 0) {
      osalSysLockFromISR();
      if (iqPutI(&sdp->iqueue, HWREG(u + UART_O_DR)) < Q_OK) {
        chnAddFlagsI(sdp, SD_QUEUE_FULL_ERROR);
      }
      osalSysUnlockFromISR();
    }
  }

  if (mis & UART_MIS_TXMIS) {
    while ((HWREG(u + UART_O_FR) & UART_FR_TXFF) == 0) {
      msg_t b;
      osalSysLockFromISR();
      b = oqGetI(&sdp->oqueue);
      osalSysUnlockFromISR();
      if (b < Q_OK) {
        HWREG(u + UART_O_IM) &= ~UART_IM_TXIM;
        osalSysLockFromISR();
        chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
        osalSysUnlockFromISR();
        break;
      }
      HWREG(u + UART_O_DR) = b;
    }
  }

  /* TODO: Physical transmission end. */
}
Beispiel #15
0
/**
 * @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 serial_serve_interrupt(SerialDriver *sdp) 
{
  UART_TypeDef *u = sdp->uart;
  uint16_t mis = u->MIS;
  
  u->ICR = mis;		/* clear interrupts */

  if (mis & (TIVA_MIS_FEMIS | TIVA_MIS_PEMIS | TIVA_MIS_BEMIS | TIVA_MIS_OEMIS)) {
    set_error(sdp, mis);
  }

  if ((mis & TIVA_MIS_RXMIS) || (mis &  TIVA_MIS_RTMIS)) {
    osalSysLockFromISR();
    if (iqIsEmptyI(&sdp->iqueue)) {
      chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE);
    }
    osalSysUnlockFromISR();
    while ((u->FR & TIVA_FR_RXFE) == 0) {
      osalSysLockFromISR();
      if (iqPutI(&sdp->iqueue, u->DR) < Q_OK) {
        chnAddFlagsI(sdp, SD_OVERRUN_ERROR);
      }
      osalSysUnlockFromISR();
    }
  }

  if (mis & TIVA_MIS_TXMIS) {
    while ((u->FR & TIVA_FR_TXFF) == 0) {
      msg_t b;
      osalSysLockFromISR();
      b = oqGetI(&sdp->oqueue);
      osalSysUnlockFromISR();
      if (b < Q_OK) {
        u->IM &= ~TIVA_IM_TXIM;
        osalSysLockFromISR();
        chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
        osalSysUnlockFromISR();
        break;
      }
      u->DR = b;
    }
  }
}
/**
 * @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;
    }

  }
}
Beispiel #17
0
/**
 * @brief   Handles outgoing data.
 * @details Must be called from the output interrupt service routine in order
 *          to get the next byte to be transmitted.
 * @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
 * @return              The byte value read from the driver's output queue.
 * @retval Q_EMPTY      if the queue is empty (the lower driver usually
 *                      disables the interrupt source when this happens).
 *
 * @iclass
 */
msg_t sdRequestDataI(SerialDriver *sdp) {
  msg_t  b;

  chDbgCheckClassI();
  chDbgCheck(sdp != NULL, "sdRequestDataI");

  b = chOQGetI(&sdp->oqueue);
  if (b < Q_OK)
    chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
  return b;
}
Beispiel #18
0
/**
 * @brief   Handles outgoing data.
 * @details Must be called from the output interrupt service routine in order
 *          to get the next byte to be transmitted.
 * @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
 * @return              The byte value read from the driver's output queue.
 * @retval MSG_TIMEOUT  if the queue is empty (the lower driver usually
 *                      disables the interrupt source when this happens).
 *
 * @iclass
 */
msg_t sdRequestDataI(SerialDriver *sdp) {
  msg_t  b;

  osalDbgCheckClassI();
  osalDbgCheck(sdp != NULL);

  b = oqGetI(&sdp->oqueue);
  if (b < MSG_OK)
    chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
  return b;
}
Beispiel #19
0
/**
 * @brief   Common TXI IRQ handler.
 *
 * @param[in] sdp       pointer to a @p SerialDriver object
 */
static void spc5xx_serve_txi_interrupt(SerialDriver *sdp) {
  msg_t b;

  sdp->linflexp->UARTSR.R = SPC5_UARTSR_DTF;
  b = chOQGetI(&sdp->oqueue);
  if (b < Q_OK) {
    chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
    sdp->linflexp->UARTCR.B.TXEN = 0;
  }
  else
    sdp->linflexp->BDRL.B.DATA0 = b;
}
Beispiel #20
0
/**
 * @brief   USB device configured handler.
 *
 * @param[in] bdup      pointer to a @p BulkUSBDriver object
 *
 * @iclass
 */
void bduConfigureHookI(BulkUSBDriver *bdup) {
  USBDriver *usbp = bdup->config->usbp;

  chIQResetI(&bdup->iqueue);
  chOQResetI(&bdup->oqueue);
  chnAddFlagsI(bdup, CHN_CONNECTED);

  /* Starts the first OUT transaction immediately.*/
  usbPrepareQueuedReceive(usbp, bdup->config->bulk_out, &bdup->iqueue,
                          usbp->epc[bdup->config->bulk_out]->out_maxsize);
  usbStartReceiveI(usbp, bdup->config->bulk_out);
}
/**
 * @brief   USB device configured handler.
 *
 * @param[in] sdup      pointer to a @p SerialUSBDriver object
 *
 * @iclass
 */
void sduConfigureHookI(SerialUSBDriver *sdup) {
  USBDriver *usbp = sdup->config->usbp;

  iqResetI(&sdup->iqueue);
  oqResetI(&sdup->oqueue);
  chnAddFlagsI(sdup, CHN_CONNECTED);

  /* Starts the first OUT transaction immediately.*/
  usbPrepareQueuedReceive(usbp, sdup->config->bulk_out, &sdup->iqueue,
                          usbp->epc[sdup->config->bulk_out]->out_maxsize);
  (void) usbStartReceiveI(usbp, sdup->config->bulk_out);
}
Beispiel #22
0
/**
 * @brief   Attempts a TX preload
 */
static void preload(SerialDriver *sdp) {
  UART_TypeDef *u = sdp->uart;

  if (u->S1 & UARTx_S1_TDRE) {
    msg_t b = chOQGetI(&sdp->oqueue);
    if (b < Q_OK) {
      chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
      return;
    }
    u->D = b;
    u->C2 |= UARTx_C2_TIE;
  }
}
/**
 * @brief     Error handling routine.
 *
 * @param[in] sra     USCI status register containing errors
 * @param[in] sdp     pointer to a @p SerialDriver object
 */
static void set_error(uint16_t sra, SerialDriver * sdp) {
  eventflags_t sts = 0;

  if (sra & UCOE)
    sts |= SD_OVERRUN_ERROR;
  if (sra & UCPE)
    sts |= SD_PARITY_ERROR;
  if (sra & UCFE)
    sts |= SD_FRAMING_ERROR;
  osalSysLockFromISR();
  chnAddFlagsI(sdp, sts);
  osalSysUnlockFromISR();
}
/**
 * @brief   Attempts a TX preload.
 */
static void preload(SerialDriver *sdp) {
  LPC_USART_TypeDef *u = sdp->uart;

  if (u->STAT & STAT_TXIDLE) {
    msg_t b = chOQGetI(&sdp->oqueue);
    if (b < Q_OK) {
      chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
      return;
    }
    u->TXDATA = b;
  }
  u->INTENSET = STAT_TXRDY;
}
Beispiel #25
0
/**
 * @brief   Error handling routine.
 *
 * @param[in] sdp       pointer to a @p SerialDriver object
 * @param[in] sr        USART SR register value
 */
static void set_error(SerialDriver *sdp, uint16_t sr) {
  eventflags_t sts = 0;

  if (sr & USART_SR_ORE)
    sts |= SD_OVERRUN_ERROR;
  if (sr & USART_SR_PE)
    sts |= SD_PARITY_ERROR;
  if (sr & USART_SR_FE)
    sts |= SD_FRAMING_ERROR;
  if (sr & USART_SR_NE)
    sts |= SD_NOISE_ERROR;
  chnAddFlagsI(sdp, sts);
}
Beispiel #26
0
/**
 * @brief
 */
static void fifo_load(SerialDriver *sdp)
{
  UART_TypeDef *u = sdp->uart;

  while ((u->FR & TIVA_FR_TXFF) == 0) {
    msg_t b = oqGetI(&sdp->oqueue);
    if (b < Q_OK) {
      chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
      return;
    }
    u->DR = b;
  }
  u->IM |= TIVA_IM_TXIM;   /* transmit interrupt enable */
}
Beispiel #27
0
/**
 * @brief   Error handling routine.
 *
 * @param[in] sdp       communication channel associated to the UART
 * @param[in] err       UART LSR register value
 */
static void set_error(SerialDriver *sdp, IOREG32 err) {
  flagsmask_t sts = 0;

  if (err & LSR_OVERRUN)
    sts |= SD_OVERRUN_ERROR;
  if (err & LSR_PARITY)
    sts |= SD_PARITY_ERROR;
  if (err & LSR_FRAMING)
    sts |= SD_FRAMING_ERROR;
  if (err & LSR_BREAK)
    sts |= SD_BREAK_DETECTED;
  chSysLockFromIsr();
  chnAddFlagsI(sdp, sts);
  chSysUnlockFromIsr();
}
/**
 * @brief   Error handling routine.
 *
 * @param[in] sdp       pointer to a @p SerialDriver object
 * @param[in] sr        USART SR register value
 */
static void set_error(SerialDriver *sdp, uint16_t sr) {
  flagsmask_t sts = 0;

  if (sr & USART_SR_ORE)
    sts |= SD_OVERRUN_ERROR;
  if (sr & USART_SR_PE)
    sts |= SD_PARITY_ERROR;
  if (sr & USART_SR_FE)
    sts |= SD_FRAMING_ERROR;
  if (sr & USART_SR_NE)
    sts |= SD_NOISE_ERROR;
  chSysLockFromIsr();
  chnAddFlagsI(sdp, sts);
  chSysUnlockFromIsr();
}
/**
 * @brief   Fill the hardware FIFO of a UART.
 */
static void fifo_load(SerialDriver *sdp)
{
  uint32_t u = sdp->uart;

  while ((HWREG(u + UART_O_FR) & UART_FR_TXFF) == 0) {
    msg_t b = oqGetI(&sdp->oqueue);
    if (b < Q_OK) {
      chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
      return;
    }
    HWREG(u + UART_O_DR) = b;
  }

  HWREG(u + UART_O_IM) |= UART_IM_TXIM;   /* transmit interrupt enable */
}
Beispiel #30
0
/**
 * @brief   Error handling routine.
 *
 * @param[in] err       USART CSR register value
 * @param[in] sdp       communication channel associated to the USART
 */
static void set_error(SerialDriver *sdp, AT91_REG csr) {
  flagsmask_t sts = 0;

  if (csr & AT91C_US_OVRE)
    sts |= SD_OVERRUN_ERROR;
  if (csr & AT91C_US_PARE)
    sts |= SD_PARITY_ERROR;
  if (csr & AT91C_US_FRAME)
    sts |= SD_FRAMING_ERROR;
  if (csr & AT91C_US_RXBRK)
    sts |= SD_BREAK_DETECTED;
  chSysLockFromIsr();
  chnAddFlagsI(sdp, sts);
  chSysUnlockFromIsr();
}