예제 #1
0
/**
 * @brief   Deactivates the CAN peripheral.
 *
 * @param[in] canp      pointer to the @p CANDriver object
 *
 * @api
 */
void canStop(CANDriver *canp) {

  osalDbgCheck(canp != NULL);

  osalSysLock();
  osalDbgAssert((canp->state == CAN_STOP) || (canp->state == CAN_READY),
                "invalid state");
  can_lld_stop(canp);
  canp->state  = CAN_STOP;
  osalThreadDequeueAllI(&canp->rxqueue, MSG_RESET);
  osalThreadDequeueAllI(&canp->txqueue, MSG_RESET);
  osalOsRescheduleS();
  osalSysUnlock();
}
예제 #2
0
파일: usb_lld.c 프로젝트: szym4n/ChibiOS
static void usb_fifo_read(USBDriver *usbp, usbep_t ep, size_t n) {
  const USBEndpointConfig *epcp = usbp->epc[ep];
  USBOutEndpointState *osp = epcp->out_state;
  syssts_t sts;
  if (n > epcp->out_maxsize)
    n = epcp->out_maxsize;

  /* Must lock for entire operation to ensure nothing changes the ENUM value */
  sts = osalSysGetStatusAndLockX();
  UENUM = ep & 0xf;
  if (osp->rxqueued) {
    input_queue_t *inq = osp->mode.queue.rxqueue;
    uint8_t i;
    for (i = 0; i < n; ++i) {
      uint8_t b = UEDATX;
      *inq->q_wrptr++ = b;
      if (inq->q_wrptr >= inq->q_top) {
        inq->q_wrptr = inq->q_buffer;
      }
    }
    /* Update queue state */
    inq->q_counter += n;
    osalThreadDequeueAllI(&inq->q_waiting, Q_OK);
  } else {
    uint8_t i;
    for (i = 0; i < n; ++i) {
      osp->mode.linear.rxbuf[i] = UEDATX;
    }
    osp->mode.linear.rxbuf += n;
  }
  osalSysRestoreStatusX(sts);
}
예제 #3
0
파일: usb_lld.c 프로젝트: szym4n/ChibiOS
static void usb_fifo_write(USBDriver *usbp, usbep_t ep, size_t n) {
  const USBEndpointConfig *epcp = usbp->epc[ep];
  USBInEndpointState *isp = epcp->in_state;
  syssts_t sts;
  if (n > epcp->in_maxsize)
    n = epcp->in_maxsize;

  /* Must lock for entire operation to ensure nothing changes the ENUM value */
  sts = osalSysGetStatusAndLockX();
  UENUM = ep & 0xf;
  if (isp->txqueued) {
    output_queue_t *outq = isp->mode.queue.txqueue;
    uint8_t i;  /* TODO not enough for a 256b endpoint! */
    for (i = 0; i < n; ++i) {
      uint8_t b = *outq->q_rdptr++;
      UEDATX = b;
      if (outq->q_rdptr >= outq->q_top) {
        outq->q_rdptr = outq->q_buffer;
      }
    }
    /* Update queue state */
    outq->q_counter += n;
    osalThreadDequeueAllI(&outq->q_waiting, Q_OK);
  } else {
    uint8_t i;  /* TODO not enough for a 256b endpoint! */
    for (i = 0; i < n; ++i) {
      UEDATX = isp->mode.linear.txbuf[i];
    }
    isp->mode.linear.txbuf += n;
  }
  isp->last_tx_size = n;
  osalSysRestoreStatusX(sts);
}
예제 #4
0
파일: usb_lld.c 프로젝트: woodyh/ChibiOS
/**
 * @brief   Writes to a dedicated packet buffer.
 *
 * @param[in] udp       pointer to a @p stm32_usb_descriptor_t
 * @param[in] buf       buffer where to fetch the packet data
 * @param[in] n         maximum number of bytes to copy. This value must
 *                      not exceed the maximum packet size for this endpoint.
 *
 * @notapi
 */
static void usb_packet_write_from_queue(stm32_usb_descriptor_t *udp,
                                        output_queue_t *oqp, size_t n) {
  size_t nhw;
  syssts_t sts;
  stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->TXADDR0);

  nhw = n / 2;
  while (nhw > 0) {
    stm32_usb_pma_t w;

    w  = (stm32_usb_pma_t)*oqp->q_rdptr++;
    if (oqp->q_rdptr >= oqp->q_top)
      oqp->q_rdptr = oqp->q_buffer;
    w |= (stm32_usb_pma_t)*oqp->q_rdptr++ << 8;
    if (oqp->q_rdptr >= oqp->q_top)
      oqp->q_rdptr = oqp->q_buffer;
    *pmap++ = w;
    nhw--;
  }

  /* Last byte for odd numbers.*/
  if ((n & 1) != 0) {
    *pmap = (stm32_usb_pma_t)*oqp->q_rdptr++;
    if (oqp->q_rdptr >= oqp->q_top)
      oqp->q_rdptr = oqp->q_buffer;
  }

  /* Updating queue.*/
  sts = osalSysGetStatusAndLockX();

  oqp->q_counter += n;
  osalThreadDequeueAllI(&oqp->q_waiting, Q_OK);

  osalSysRestoreStatusX(sts);
}
예제 #5
0
파일: usb_lld.c 프로젝트: woodyh/ChibiOS
/**
 * @brief   Reads from a dedicated packet buffer.
 *
 * @param[in] udp       pointer to a @p stm32_usb_descriptor_t
 * @param[in] iqp       pointer to an @p input_queue_t object
 * @param[in] n         maximum number of bytes to copy. This value must
 *                      not exceed the maximum packet size for this endpoint.
 *
 * @notapi
 */
static void usb_packet_read_to_queue(stm32_usb_descriptor_t *udp,
                                     input_queue_t *iqp, size_t n) {
  size_t nhw;
  stm32_usb_pma_t *pmap= USB_ADDR2PTR(udp->RXADDR0);

  nhw = n / 2;
  while (nhw > 0) {
    stm32_usb_pma_t w;

    w = *pmap++;
    *iqp->q_wrptr++ = (uint8_t)w;
    if (iqp->q_wrptr >= iqp->q_top)
      iqp->q_wrptr = iqp->q_buffer;
    *iqp->q_wrptr++ = (uint8_t)(w >> 8);
    if (iqp->q_wrptr >= iqp->q_top)
      iqp->q_wrptr = iqp->q_buffer;
    nhw--;
  }
  /* Last byte for odd numbers.*/
  if ((n & 1) != 0) {
    *iqp->q_wrptr++ = (uint8_t)*pmap;
    if (iqp->q_wrptr >= iqp->q_top)
      iqp->q_wrptr = iqp->q_buffer;
  }

  /* Updating queue.*/
  osalSysLockFromISR();

  iqp->q_counter += n;
  osalThreadDequeueAllI(&iqp->q_waiting, Q_OK);

  osalSysUnlockFromISR();
}
예제 #6
0
/**
 * @brief   Writes to a TX FIFO fetching data from a queue.
 *
 * @param[in] fifop     pointer to the FIFO register
 * @param[in] oqp       pointer to an @p output_queue_t object
 * @param[in] n         maximum number of bytes to copy
 *
 * @notapi
 */
static void otg_fifo_write_from_queue(volatile uint32_t *fifop,
                                      output_queue_t *oqp,
                                      size_t n) {
  uint32_t w;
  size_t i;

  /* Pushing all complete words.*/
  i = 0;
  w = 0;
  while (i < n) {
    w |= (uint32_t)*oqp->q_rdptr << ((i & 3) * 8);
    oqp->q_rdptr++;
    if (oqp->q_rdptr >= oqp->q_top) {
      oqp->q_rdptr = oqp->q_buffer;
    }
    i++;
    if ((i & 3) == 0) {
      *fifop = w;
      w = 0;
    }
  }

  /* Remaining bytes.*/
  if ((i & 3) != 0) {
    *fifop = w;
  }

  /* Updating queue.*/
  osalSysLock();
  oqp->q_counter += n;
  osalThreadDequeueAllI(&oqp->q_waiting, Q_OK);
  osalOsRescheduleS();
  osalSysUnlock();
}
예제 #7
0
/**
 * @brief   Resets an input queue.
 * @details All the data in the input queue is erased and lost, any waiting
 *          thread is resumed with status @p Q_RESET.
 * @note    A reset operation can be used by a low level driver in order to
 *          obtain immediate attention from the high level layers.
 *
 * @param[in] iqp       pointer to an @p input_queue_t structure
 *
 * @iclass
 */
void iqResetI(input_queue_t *iqp) {

  osalDbgCheckClassI();

  iqp->q_rdptr = iqp->q_buffer;
  iqp->q_wrptr = iqp->q_buffer;
  iqp->q_counter = 0;
  osalThreadDequeueAllI(&iqp->q_waiting, Q_RESET);
}
예제 #8
0
/**
 * @brief   Resets an output queue.
 * @details All the data in the output queue is erased and lost, any waiting
 *          thread is resumed with status @p Q_RESET.
 * @note    A reset operation can be used by a low level driver in order to
 *          obtain immediate attention from the high level layers.
 *
 * @param[in] oqp       pointer to an @p output_queue_t structure
 *
 * @iclass
 */
void oqResetI(output_queue_t *oqp) {

  osalDbgCheckClassI();

  oqp->q_rdptr = oqp->q_buffer;
  oqp->q_wrptr = oqp->q_buffer;
  oqp->q_counter = qSizeX(oqp);
  osalThreadDequeueAllI(&oqp->q_waiting, Q_RESET);
}
예제 #9
0
파일: can.c 프로젝트: SVentas/SmartMDC
/**
 * @brief   Deactivates the CAN peripheral.
 *
 * @param[in] canp      pointer to the @p CANDriver object
 *
 * @api
 */
void canStop(CANDriver *canp) {

  osalDbgCheck(canp != NULL);

  osalSysLock();
  osalDbgAssert((canp->state == CAN_STOP) || (canp->state == CAN_READY),
                "invalid state");

  /* The low level driver is stopped.*/
  can_lld_stop(canp);
  canp->state  = CAN_STOP;

  /* Threads waiting on CAN APIs are notified that the driver has been
     stopped in order to not have stuck threads.*/
  osalThreadDequeueAllI(&canp->rxqueue, MSG_RESET);
  osalThreadDequeueAllI(&canp->txqueue, MSG_RESET);
  osalOsRescheduleS();
  osalSysUnlock();
}
예제 #10
0
/**
 * @brief   Writes to a TX FIFO fetching data from a queue.
 *
 * @param[in] fifop     pointer to the FIFO register
 * @param[in] oqp       pointer to an @p output_queue_t object
 * @param[in] n         maximum number of bytes to copy
 *
 * @notapi
 */
static void otg_fifo_write_from_queue(volatile uint32_t *fifop,
                                      output_queue_t *oqp,
                                      size_t n) {
  size_t ntogo;

  ntogo = n;
  while (ntogo > 0) {
    uint32_t w, i;
    size_t nw = ntogo / 4;

    if (nw > 0) {
      size_t streak;
      uint32_t nw2end = (oqp->q_top - oqp->q_rdptr) / 4;

      ntogo -= (streak = nw <= nw2end ? nw : nw2end) * 4;
      oqp->q_rdptr = otg_do_push(fifop, oqp->q_rdptr, streak);
      if (oqp->q_rdptr >= oqp->q_top) {
        oqp->q_rdptr = oqp->q_buffer;
        continue;
      }
    }

    /* If this condition is not satisfied then there is a word lying across
       queue circular buffer boundary or there are some remaining bytes.*/
    if (ntogo <= 0)
      break;

    /* One byte at time.*/
    w = 0;
    i = 0;
    while ((ntogo > 0) && (i < 4)) {
      w |= (uint32_t)*oqp->q_rdptr++ << (i * 8);
      if (oqp->q_rdptr >= oqp->q_top)
        oqp->q_rdptr = oqp->q_buffer;
      ntogo--;
      i++;
    }
    *fifop = w;
  }

  /* Updating queue.*/
  osalSysLock();
  oqp->q_counter += n;
  osalThreadDequeueAllI(&oqp->q_waiting, Q_OK);
  osalOsRescheduleS();
  osalSysUnlock();
}
예제 #11
0
/**
 * @brief   Reads a packet from the RXFIFO.
 *
 * @param[in] fifop     pointer to the FIFO register
 * @param[in] iqp       pointer to an @p input_queue_t object
 * @param[in] n         number of bytes to pull from the FIFO
 *
 * @notapi
 */
static void otg_fifo_read_to_queue(volatile uint32_t *fifop,
                                   input_queue_t *iqp,
                                   size_t n) {
  size_t ntogo;

  ntogo = n;
  while (ntogo > 0) {
    uint32_t w, i;
    size_t nw = ntogo / 4;

    if (nw > 0) {
      size_t streak;
      uint32_t nw2end = (iqp->q_wrptr - iqp->q_wrptr) / 4;

      ntogo -= (streak = nw <= nw2end ? nw : nw2end) * 4;
      iqp->q_wrptr = otg_do_pop(fifop, iqp->q_wrptr, streak);
      if (iqp->q_wrptr >= iqp->q_top) {
        iqp->q_wrptr = iqp->q_buffer;
        continue;
      }
    }

    /* If this condition is not satisfied then there is a word lying across
       queue circular buffer boundary or there are some remaining bytes.*/
    if (ntogo <= 0)
      break;

    /* One byte at time.*/
    w = *fifop;
    i = 0;
    while ((ntogo > 0) && (i < 4)) {
      *iqp->q_wrptr++ = (uint8_t)(w >> (i * 8));
      if (iqp->q_wrptr >= iqp->q_top)
        iqp->q_wrptr = iqp->q_buffer;
      ntogo--;
      i++;
    }
  }

  /* Updating queue.*/
  osalSysLock();
  iqp->q_counter += n;
  osalThreadDequeueAllI(&iqp->q_waiting, Q_OK);
  osalOsRescheduleS();
  osalSysUnlock();
}