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