예제 #1
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);
}
예제 #2
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);
}
예제 #3
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);
}
예제 #4
0
파일: usb_lld.c 프로젝트: szym4n/ChibiOS
/**
 * @brief   Brings an OUT endpoint in the active state.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 * @param[in] ep        endpoint number
 *
 * @notapi
 */
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
  syssts_t sts;
  (void)usbp;

  /* Select this endpoint number for subsequent commands */
  /* Must lock for entire operation to ensure nothing changes the ENUM value */
  sts = osalSysGetStatusAndLockX();
  UENUM = ep & 0xf;

  UECONX |= (1 << STALLRQC);
  osalSysRestoreStatusX(sts);
}
예제 #5
0
파일: rtc_lld.c 프로젝트: Babody/ChibiOS
/**
 * @brief   Set alarm time.
 *
 * @note    Default value after BKP domain reset is 0xFFFFFFFF
 * @note    The function can be called from any context.
 *
 * @param[in] rtcp      pointer to RTC driver structure
 * @param[in] alarm     alarm identifier
 * @param[in] alarmspec pointer to a @p RTCAlarm structure
 *
 * @notapi
 */
void rtc_lld_set_alarm(RTCDriver *rtcp,
                       rtcalarm_t alarm_number,
                       const RTCAlarm *alarmspec) {
  syssts_t sts;
  (void)alarm_number;

  /* Entering a reentrant critical zone.*/
  sts = osalSysGetStatusAndLockX();

  rtc_acquire_access();
  if (alarmspec != NULL) {
    rtcp->rtc->ALRH = (uint16_t)(alarmspec->tv_sec >> 16);
    rtcp->rtc->ALRL = (uint16_t)(alarmspec->tv_sec & 0xFFFF);
  }
예제 #6
0
파일: rtc_lld.c 프로젝트: Babody/ChibiOS
/**
 * @brief   Load value of RTCCLK to prescaler registers.
 * @note    The pre-scaler must not be set on every reset as RTC clock
 *          counts are lost when it is set.
 * @note    This function designed to be called from
 *          hal_lld_backup_domain_init(). Because there is only place
 *          where possible to detect BKP domain reset event reliably.
 *
 * @notapi
 */
void rtc_lld_set_prescaler(void) {
  syssts_t sts;

  /* Entering a reentrant critical zone.*/
  sts = osalSysGetStatusAndLockX();

  rtc_acquire_access();
  RTC->PRLH = (uint16_t)((STM32_RTCCLK - 1) >> 16) & 0x000F;
  RTC->PRLL = (uint16_t)(((STM32_RTCCLK - 1))      & 0xFFFF);
  rtc_release_access();

  /* Leaving a reentrant critical zone.*/
  osalSysRestoreStatusX(sts);
}
예제 #7
0
파일: usb_lld.c 프로젝트: szym4n/ChibiOS
/**
 * @brief   Starts a transmit operation on an IN endpoint.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 * @param[in] ep        endpoint number
 *
 * @notapi
 */
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
  syssts_t sts;
  (void)usbp;

  /* Select this endpoint number for subsequent commands */
  /* Must lock for entire operation to ensure nothing changes the ENUM value */
  sts = osalSysGetStatusAndLockX();
  UENUM = ep & 0xf;

  /* Clear FIFOCON to send the data in the FIFO and switch bank */
  UEINTX &= ~((1 << TXINI) | (1 << FIFOCON));

  /* Enable the TX complete interrupt */
  UEIENX |= (1 << TXINE);
  osalSysRestoreStatusX(sts);
}
예제 #8
0
int64_t TimeKeeper::utc(void) {
  int64_t ret;
  uint32_t cnt1, cnt2;
  syssts_t sts;

  sts  = osalSysGetStatusAndLockX();
  cnt1 = RTC_GPTD.tim->CNT;
  ret  = unix_usec;
  cnt2 = RTC_GPTD.tim->CNT;
  osalSysRestoreStatusX(sts);

  if (cnt2 >= cnt1)
    return ret + cnt1;
  else
    return ret + cnt1 + RTC_TIMER_STEP + timer_skew;
}