#pragma once #include "usb.h" static inline void USB_SetEPR(volatile uint16_t *EPR, uint16_t status) { // Caution: This function does a read-modify-write and is prone to // unexpected behaviour when there are transactions going one, because the // register contents might change during the funciton's execution. Thus, // only use this function in initialisation code! volatile uint16_t v = *EPR; status ^= v & (USB_EP0R_DTOG_RX | USB_EP0R_STAT_RX |\ USB_EP0R_DTOG_TX | USB_EP0R_STAT_TX); *EPR = status; } static inline void USB_SetEPRXStatus(volatile uint16_t *EPR, uint16_t status) { uint16_t v = *EPR; v ^= status & USB_EP0R_STAT_RX; v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_CTR_TX | USB_EP0R_EA | USB_EP0R_STAT_RX; *EPR = v; } static inline void USB_SetEPTXStatus(volatile uint16_t *EPR, uint16_t status) { uint16_t v = *EPR; v ^= status & USB_EP0R_STAT_TX; v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_CTR_TX | USB_EP0R_EA | USB_EP0R_STAT_TX; *EPR = v; } static inline void USB_SetEPType(volatile uint16_t *EPR, uint16_t type) { uint16_t v = *EPR; v &= USB_EP0R_CTR_RX | USB_EP0R_EP_KIND | USB_EP0R_CTR_TX | USB_EP0R_EA; v |= USB_EP0R_EP_TYPE & type; *EPR = v; } static inline void USB_SetEPAddress(volatile uint16_t *EPR, uint16_t address) { uint16_t v = *EPR; v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_CTR_TX; v |= USB_EP0R_EA & address; *EPR = v; } static inline void USB_SetEPKind(volatile uint16_t *EPR) { uint16_t v = *EPR; v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_CTR_TX | USB_EP0R_EA; v |= USB_EP0R_EP_KIND; *EPR = v; } static inline void USB_ClearEPKind(volatile uint16_t *EPR) { uint16_t v = *EPR; v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_CTR_TX | USB_EP0R_EA; *EPR = v; } static inline void USB_ClearEPCTRX(volatile uint16_t *EPR) { uint16_t v = *EPR; v &= USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_CTR_TX | USB_EP0R_EA; *EPR = v; } static inline void USB_ClearEPCTTX(volatile uint16_t *EPR) { uint16_t v = *EPR; v &= USB_EP0R_CTR_RX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_EA; *EPR = v; } static inline void USB_Delay(unsigned int delay) { SysTick->LOAD = delay; SysTick->VAL = 0; SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; while(!((SysTick->CTRL) & SysTick_CTRL_COUNTFLAG_Msk)); SysTick->CTRL = 0; } void USB_PMAToMemory(void *mem, uint16_t offset, size_t length); void USB_MemoryToPMA(uint16_t offset, const void *mem, size_t length);