12 #include "usbdev_regs.h"
19 "Mismatch in number of endpoints");
24 #define USBDEV_BUFFER_ENTRY_SIZE_BYTES USBDEV_MAX_PACKET_SIZE
29 #define BUFFER_POOL_FULL (USBDEV_NUM_BUFFERS - 1)
30 #define BUFFER_POOL_EMPTY -1
36 uint32_t config_in_reg_offset;
46 #define ENDPOINT_HW_INFO_ENTRY(N) \
47 [N] = {.config_in_reg_offset = USBDEV_CONFIGIN_##N##_REG_OFFSET, \
48 .bit_index = USBDEV_IN_SENT_SENT_##N##_BIT}
51 ENDPOINT_HW_INFO_ENTRY(0), ENDPOINT_HW_INFO_ENTRY(1),
52 ENDPOINT_HW_INFO_ENTRY(2), ENDPOINT_HW_INFO_ENTRY(3),
53 ENDPOINT_HW_INFO_ENTRY(4), ENDPOINT_HW_INFO_ENTRY(5),
54 ENDPOINT_HW_INFO_ENTRY(6), ENDPOINT_HW_INFO_ENTRY(7),
55 ENDPOINT_HW_INFO_ENTRY(8), ENDPOINT_HW_INFO_ENTRY(9),
56 ENDPOINT_HW_INFO_ENTRY(10), ENDPOINT_HW_INFO_ENTRY(11),
59 #undef ENDPOINT_HW_INFO_ENTRY
75 return pool->top == BUFFER_POOL_FULL;
86 return pool->top == BUFFER_POOL_EMPTY;
98 static bool buffer_pool_is_valid_buffer_id(uint8_t buffer_id) {
99 return buffer_id < USBDEV_NUM_BUFFERS;
111 if (buffer_pool_is_full(pool) || !buffer_pool_is_valid_buffer_id(buffer_id)) {
116 pool->buffers[pool->top] = buffer_id;
130 uint8_t *buffer_id) {
131 if (buffer_pool_is_empty(pool) || buffer_id == NULL) {
135 *buffer_id = pool->buffers[pool->top];
156 for (uint8_t i = 0; i < USBDEV_NUM_BUFFERS; ++i) {
157 if (!buffer_pool_add(pool, i)) {
173 static bool is_valid_endpoint(uint8_t endpoint_number) {
186 if (usbdev == NULL || !is_valid_endpoint(endpoint) ||
192 mmio_region_read32(usbdev->
base_addr, (ptrdiff_t)reg_offset);
195 mmio_region_write32(usbdev->
base_addr, (ptrdiff_t)reg_offset, reg_val);
204 static uint32_t get_buffer_addr(uint8_t buffer_id,
size_t offset) {
205 return USBDEV_BUFFER_REG_OFFSET +
206 (buffer_id * USBDEV_BUFFER_ENTRY_SIZE_BYTES) + offset;
216 if (usbdev == NULL || buffer_pool == NULL) {
221 if (!buffer_pool_init(buffer_pool)) {
235 uint32_t phy_config_val = 0;
237 phy_config_val, USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT,
249 phy_config_val, USBDEV_PHY_CONFIG_USB_REF_DISABLE_BIT,
253 mmio_region_write32(usbdev->
base_addr, USBDEV_PHY_CONFIG_REG_OFFSET,
261 if (usbdev == NULL || buffer_pool == NULL) {
266 while (!buffer_pool_is_empty(buffer_pool)) {
268 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
270 uint32_t av_setup_depth =
272 if (av_setup_depth >= 2) {
281 if (!buffer_pool_remove(buffer_pool, &buffer_id)) {
284 if (av_setup_depth >= 2) {
288 mmio_region_write32(usbdev->
base_addr, USBDEV_AVOUTBUFFER_REG_OFFSET,
293 0, USBDEV_AVSETUPBUFFER_BUFFER_FIELD, buffer_id);
294 mmio_region_write32(usbdev->
base_addr, USBDEV_AVSETUPBUFFER_REG_OFFSET,
305 return endpoint_functionality_enable(usbdev, USBDEV_RXENABLE_SETUP_REG_OFFSET,
306 endpoint, new_state);
312 return endpoint_functionality_enable(usbdev, USBDEV_RXENABLE_OUT_REG_OFFSET,
313 endpoint, new_state);
319 return endpoint_functionality_enable(usbdev, USBDEV_SET_NAK_OUT_REG_OFFSET,
320 endpoint, new_state);
326 if (endpoint.
direction == USBDEV_ENDPOINT_DIR_IN) {
327 return endpoint_functionality_enable(usbdev, USBDEV_IN_STALL_REG_OFFSET,
328 endpoint.
number, new_state);
330 return endpoint_functionality_enable(usbdev, USBDEV_OUT_STALL_REG_OFFSET,
331 endpoint.
number, new_state);
338 if (usbdev == NULL || state == NULL || !is_valid_endpoint(endpoint.
number)) {
342 ptrdiff_t reg_offset = endpoint.
direction == USBDEV_ENDPOINT_DIR_IN
343 ? USBDEV_IN_STALL_REG_OFFSET
344 : USBDEV_OUT_STALL_REG_OFFSET;
345 uint32_t reg_val = mmio_region_read32(usbdev->
base_addr, reg_offset);
355 if (endpoint.
direction == USBDEV_ENDPOINT_DIR_IN) {
356 return endpoint_functionality_enable(usbdev, USBDEV_IN_ISO_REG_OFFSET,
357 endpoint.
number, new_state);
359 return endpoint_functionality_enable(usbdev, USBDEV_OUT_ISO_REG_OFFSET,
360 endpoint.
number, new_state);
367 if (endpoint.
direction == USBDEV_ENDPOINT_DIR_IN) {
368 return endpoint_functionality_enable(usbdev, USBDEV_EP_IN_ENABLE_REG_OFFSET,
369 endpoint.
number, new_state);
371 return endpoint_functionality_enable(
372 usbdev, USBDEV_EP_OUT_ENABLE_REG_OFFSET, endpoint.
number, new_state);
384 mmio_region_read32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET);
387 mmio_region_write32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET, reg_val);
395 if (usbdev == NULL || info == NULL || buffer == NULL) {
400 uint32_t fifo_status =
401 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
407 const uint32_t fifo_entry =
408 mmio_region_read32(usbdev->
base_addr, USBDEV_RXFIFO_REG_OFFSET);
420 USBDEV_RXFIFO_BUFFER_FIELD),
422 .remaining_bytes = info->
length,
432 if (usbdev == NULL || buffer_pool == NULL || buffer == NULL) {
436 if (buffer_pool_is_empty(buffer_pool)) {
441 if (!buffer_pool_remove(buffer_pool, &buffer_id)) {
448 .remaining_bytes = USBDEV_BUFFER_ENTRY_SIZE_BYTES,
458 if (usbdev == NULL || buffer_pool == NULL || buffer == NULL) {
462 switch (buffer->
type) {
466 if (!buffer_pool_add(buffer_pool, buffer->
id)) {
480 size_t dst_len,
size_t *bytes_written) {
481 if (usbdev == NULL || buffer_pool == NULL || buffer == NULL ||
488 if (bytes_to_copy > dst_len) {
489 bytes_to_copy = dst_len;
492 const uint32_t buffer_addr = get_buffer_addr(buffer->
id, buffer->
offset);
496 buffer->
offset += bytes_to_copy;
499 if (bytes_written != NULL) {
500 *bytes_written = bytes_to_copy;
509 if (!buffer_pool_add(buffer_pool, buffer->
id)) {
520 const uint8_t *src,
size_t src_len,
521 size_t *bytes_written) {
522 if (usbdev == NULL || buffer == NULL ||
529 if (bytes_to_copy > src_len) {
530 bytes_to_copy = src_len;
534 uint32_t buffer_addr = get_buffer_addr(buffer->
id, buffer->
offset);
538 buffer->
offset += bytes_to_copy;
542 *bytes_written = bytes_to_copy;
554 if (usbdev == NULL || !is_valid_endpoint(endpoint) || buffer == NULL ||
560 const uint32_t config_in_reg_offset =
561 kEndpointHwInfos[endpoint].config_in_reg_offset;
567 uint32_t config_in_val = 0;
569 config_in_val, USBDEV_CONFIGIN_0_BUFFER_0_FIELD, buffer->
id);
571 config_in_val, USBDEV_CONFIGIN_0_SIZE_0_FIELD, buffer->
offset);
572 mmio_region_write32(usbdev->
base_addr, (ptrdiff_t)config_in_reg_offset,
578 mmio_region_write32(usbdev->
base_addr, (ptrdiff_t)config_in_reg_offset,
590 if (usbdev == NULL || sent == NULL) {
593 *sent = (uint16_t)mmio_region_read32(usbdev->
base_addr,
594 USBDEV_IN_SENT_REG_OFFSET);
601 if (usbdev == NULL || buffer_pool == NULL || !is_valid_endpoint(endpoint)) {
605 uint32_t config_in_reg_offset =
606 kEndpointHwInfos[endpoint].config_in_reg_offset;
607 uint32_t config_in_reg_val =
608 mmio_region_read32(usbdev->
base_addr, (ptrdiff_t)config_in_reg_offset);
610 config_in_reg_val, USBDEV_CONFIGIN_0_BUFFER_0_FIELD);
612 mmio_region_write32(usbdev->
base_addr, (ptrdiff_t)config_in_reg_offset,
613 1u << USBDEV_CONFIGIN_0_PEND_0_BIT);
615 mmio_region_write32(usbdev->
base_addr, USBDEV_IN_SENT_REG_OFFSET,
618 if (!buffer_pool_add(buffer_pool, buffer)) {
627 if (usbdev == NULL ||
status == NULL || !is_valid_endpoint(endpoint)) {
632 uint32_t config_in_reg_offset =
633 kEndpointHwInfos[endpoint].config_in_reg_offset;
634 uint8_t endpoint_bit_index = kEndpointHwInfos[endpoint].bit_index;
637 uint32_t config_in_val =
638 mmio_region_read32(usbdev->
base_addr, (ptrdiff_t)config_in_reg_offset);
645 USBDEV_IN_SENT_REG_OFFSET),
646 endpoint_bit_index)) {
661 if (usbdev == NULL) {
666 mmio_region_read32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET);
669 mmio_region_write32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET, reg_val);
675 if (usbdev == NULL || addr == NULL) {
680 mmio_region_read32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET);
683 USBDEV_USBCTRL_DEVICE_ADDRESS_FIELD);
690 if (usbdev == NULL || toggles == NULL) {
695 mmio_region_read32(usbdev->
base_addr, USBDEV_OUT_DATA_TOGGLE_REG_OFFSET);
697 *toggles = (uint16_t)reg_val;
704 if (usbdev == NULL || toggles == NULL) {
709 mmio_region_read32(usbdev->
base_addr, USBDEV_IN_DATA_TOGGLE_REG_OFFSET);
711 *toggles = (uint16_t)reg_val;
717 uint16_t mask, uint16_t state) {
718 if (usbdev == NULL) {
723 mmio_region_write32(usbdev->
base_addr, USBDEV_OUT_DATA_TOGGLE_REG_OFFSET,
724 ((uint32_t)mask << 16) | state);
730 uint16_t mask, uint16_t state) {
731 if (usbdev == NULL) {
736 mmio_region_write32(usbdev->
base_addr, USBDEV_IN_DATA_TOGGLE_REG_OFFSET,
737 ((uint32_t)mask << 16) | state);
744 if (usbdev == NULL) {
748 uint32_t reg_val = (uint32_t)1u << (endpoint + 16u);
749 mmio_region_write32(usbdev->
base_addr, USBDEV_OUT_DATA_TOGGLE_REG_OFFSET,
751 mmio_region_write32(usbdev->
base_addr, USBDEV_IN_DATA_TOGGLE_REG_OFFSET,
758 uint16_t *frame_index) {
759 if (usbdev == NULL || frame_index == NULL) {
764 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
774 if (usbdev == NULL || host_lost == NULL) {
780 USBDEV_USBSTAT_HOST_LOST_BIT);
787 if (usbdev == NULL || link_state == NULL) {
792 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
796 case USBDEV_USBSTAT_LINK_STATE_VALUE_DISCONNECTED:
797 *link_state = kDifUsbdevLinkStateDisconnected;
799 case USBDEV_USBSTAT_LINK_STATE_VALUE_POWERED:
800 *link_state = kDifUsbdevLinkStatePowered;
802 case USBDEV_USBSTAT_LINK_STATE_VALUE_POWERED_SUSPENDED:
803 *link_state = kDifUsbdevLinkStatePoweredSuspended;
805 case USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE:
806 *link_state = kDifUsbdevLinkStateActive;
808 case USBDEV_USBSTAT_LINK_STATE_VALUE_SUSPENDED:
809 *link_state = kDifUsbdevLinkStateSuspended;
811 case USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE_NOSOF:
812 *link_state = kDifUsbdevLinkStateActiveNoSof;
814 case USBDEV_USBSTAT_LINK_STATE_VALUE_RESUMING:
815 *link_state = kDifUsbdevLinkStateResuming;
826 if (usbdev == NULL || sense == NULL) {
831 USBDEV_USBSTAT_SENSE_BIT);
837 const dif_usbdev_t *usbdev, uint8_t *setup_depth, uint8_t *out_depth) {
838 if (usbdev == NULL || setup_depth == NULL || out_depth == NULL) {
843 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
846 reg_val, USBDEV_USBSTAT_AV_SETUP_DEPTH_FIELD);
849 reg_val, USBDEV_USBSTAT_AV_OUT_DEPTH_FIELD);
855 const dif_usbdev_t *usbdev,
bool *setup_is_full,
bool *out_is_full) {
856 if (usbdev == NULL || setup_is_full == NULL || out_is_full == NULL) {
861 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
871 if (usbdev == NULL || depth == NULL) {
876 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
886 if (usbdev == NULL || is_empty == NULL) {
891 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
904 mmio_region_read32(usbdev->
base_addr, USBDEV_PHY_CONFIG_REG_OFFSET);
906 reg_val, USBDEV_PHY_CONFIG_TX_OSC_TEST_MODE_BIT, set_tx_osc_mode);
907 mmio_region_write32(usbdev->
base_addr, USBDEV_PHY_CONFIG_REG_OFFSET, reg_val);
923 mmio_region_write32(usbdev->
base_addr, USBDEV_WAKE_CONTROL_REG_OFFSET,
930 if (usbdev == NULL ||
status == NULL) {
934 mmio_region_read32(usbdev->
base_addr, USBDEV_WAKE_EVENTS_REG_OFFSET);
945 if (usbdev == NULL) {
949 mmio_region_read32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET);
952 mmio_region_write32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET, reg_val);
958 if (usbdev == NULL ||
status == NULL) {
962 mmio_region_read32(usbdev->
base_addr, USBDEV_PHY_PINS_SENSE_REG_OFFSET);
1012 mmio_region_write32(usbdev->
base_addr, USBDEV_PHY_PINS_DRIVE_REG_OFFSET,
1018 const uint8_t *src,
size_t src_len) {
1020 src_len > USBDEV_BUFFER_ENTRY_SIZE_BYTES) {
1025 ptrdiff_t buffer_offset = (ptrdiff_t)get_buffer_addr(
id, 0U);
1026 const uint32_t *restrict ews = (uint32_t *)(src + (src_len & ~15u));
1027 const uint32_t *restrict ws = (uint32_t *)src;
1034 mmio_region_write32(usbdev->
base_addr, buffer_offset, ws[0]);
1035 mmio_region_write32(usbdev->
base_addr, buffer_offset + 4, ws[1]);
1036 mmio_region_write32(usbdev->
base_addr, buffer_offset + 8, ws[2]);
1037 mmio_region_write32(usbdev->
base_addr, buffer_offset + 12, ws[3]);
1038 buffer_offset += 16;
1045 ews = ws + (src_len >> 2);
1047 mmio_region_write32(usbdev->
base_addr, buffer_offset, *ws++);
1053 const uint8_t *restrict bs = (uint8_t *)ws;
1056 d |= ((uint32_t)bs[1] << 8);
1058 d |= ((uint32_t)bs[2] << 16);
1064 mmio_region_write32(usbdev->
base_addr, buffer_offset, d);
1072 uint8_t *dst,
size_t dst_len) {
1074 dst_len > USBDEV_BUFFER_ENTRY_SIZE_BYTES) {
1079 ptrdiff_t buffer_offset = (ptrdiff_t)get_buffer_addr(
id, 0U);
1080 const uint32_t *restrict ewd = (uint32_t *)(dst + (dst_len & ~15u));
1081 uint32_t *restrict wd = (uint32_t *)dst;
1088 wd[0] = mmio_region_read32(usbdev->
base_addr, buffer_offset);
1089 wd[1] = mmio_region_read32(usbdev->
base_addr, buffer_offset + 4);
1090 wd[2] = mmio_region_read32(usbdev->
base_addr, buffer_offset + 8);
1091 wd[3] = mmio_region_read32(usbdev->
base_addr, buffer_offset + 12);
1092 buffer_offset += 16;
1099 ewd = wd + (dst_len >> 2);
1101 *wd++ = mmio_region_read32(usbdev->
base_addr, buffer_offset);
1108 uint8_t *restrict bd = (uint8_t *)wd;
1109 uint32_t d = mmio_region_read32(usbdev->
base_addr, buffer_offset);
1112 bd[1] = (uint8_t)(d >> 8);
1114 bd[2] = (uint8_t)(d >> 16);