11 #include "usbdev_regs.h"
18 "Mismatch in number of endpoints");
23 #define USBDEV_BUFFER_ENTRY_SIZE_BYTES USBDEV_MAX_PACKET_SIZE
28 #define BUFFER_POOL_FULL (USBDEV_NUM_BUFFERS - 1)
29 #define BUFFER_POOL_EMPTY -1
35 uint32_t config_in_reg_offset;
45 #define ENDPOINT_HW_INFO_ENTRY(N) \
46 [N] = {.config_in_reg_offset = USBDEV_CONFIGIN_##N##_REG_OFFSET, \
47 .bit_index = USBDEV_IN_SENT_SENT_##N##_BIT}
50 ENDPOINT_HW_INFO_ENTRY(0), ENDPOINT_HW_INFO_ENTRY(1),
51 ENDPOINT_HW_INFO_ENTRY(2), ENDPOINT_HW_INFO_ENTRY(3),
52 ENDPOINT_HW_INFO_ENTRY(4), ENDPOINT_HW_INFO_ENTRY(5),
53 ENDPOINT_HW_INFO_ENTRY(6), ENDPOINT_HW_INFO_ENTRY(7),
54 ENDPOINT_HW_INFO_ENTRY(8), ENDPOINT_HW_INFO_ENTRY(9),
55 ENDPOINT_HW_INFO_ENTRY(10), ENDPOINT_HW_INFO_ENTRY(11),
58 #undef ENDPOINT_HW_INFO_ENTRY
74 return pool->top == BUFFER_POOL_FULL;
85 return pool->top == BUFFER_POOL_EMPTY;
97 static bool buffer_pool_is_valid_buffer_id(uint8_t buffer_id) {
98 return buffer_id < USBDEV_NUM_BUFFERS;
110 if (buffer_pool_is_full(pool) || !buffer_pool_is_valid_buffer_id(buffer_id)) {
115 pool->buffers[pool->top] = buffer_id;
129 uint8_t *buffer_id) {
130 if (buffer_pool_is_empty(pool) || buffer_id == NULL) {
134 *buffer_id = pool->buffers[pool->top];
155 for (uint8_t i = 0; i < USBDEV_NUM_BUFFERS; ++i) {
156 if (!buffer_pool_add(pool, i)) {
172 static bool is_valid_endpoint(uint8_t endpoint_number) {
185 if (usbdev == NULL || !is_valid_endpoint(endpoint) ||
191 mmio_region_read32(usbdev->
base_addr, (ptrdiff_t)reg_offset);
194 mmio_region_write32(usbdev->
base_addr, (ptrdiff_t)reg_offset, reg_val);
203 static uint32_t get_buffer_addr(uint8_t buffer_id,
size_t offset) {
204 return USBDEV_BUFFER_REG_OFFSET +
205 (buffer_id * USBDEV_BUFFER_ENTRY_SIZE_BYTES) + offset;
215 if (usbdev == NULL || buffer_pool == NULL) {
220 if (!buffer_pool_init(buffer_pool)) {
234 uint32_t phy_config_val = 0;
236 phy_config_val, USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT,
248 phy_config_val, USBDEV_PHY_CONFIG_USB_REF_DISABLE_BIT,
252 mmio_region_write32(usbdev->
base_addr, USBDEV_PHY_CONFIG_REG_OFFSET,
260 if (usbdev == NULL || buffer_pool == NULL) {
265 while (!buffer_pool_is_empty(buffer_pool)) {
267 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
269 uint32_t av_setup_depth =
271 if (av_setup_depth >= 2) {
280 if (!buffer_pool_remove(buffer_pool, &buffer_id)) {
283 if (av_setup_depth >= 2) {
287 mmio_region_write32(usbdev->
base_addr, USBDEV_AVOUTBUFFER_REG_OFFSET,
292 0, USBDEV_AVSETUPBUFFER_BUFFER_FIELD, buffer_id);
293 mmio_region_write32(usbdev->
base_addr, USBDEV_AVSETUPBUFFER_REG_OFFSET,
304 return endpoint_functionality_enable(usbdev, USBDEV_RXENABLE_SETUP_REG_OFFSET,
305 endpoint, new_state);
311 return endpoint_functionality_enable(usbdev, USBDEV_RXENABLE_OUT_REG_OFFSET,
312 endpoint, new_state);
318 return endpoint_functionality_enable(usbdev, USBDEV_SET_NAK_OUT_REG_OFFSET,
319 endpoint, new_state);
325 if (endpoint.
direction == USBDEV_ENDPOINT_DIR_IN) {
326 return endpoint_functionality_enable(usbdev, USBDEV_IN_STALL_REG_OFFSET,
327 endpoint.
number, new_state);
329 return endpoint_functionality_enable(usbdev, USBDEV_OUT_STALL_REG_OFFSET,
330 endpoint.
number, new_state);
337 if (usbdev == NULL || state == NULL || !is_valid_endpoint(endpoint.
number)) {
341 ptrdiff_t reg_offset = endpoint.
direction == USBDEV_ENDPOINT_DIR_IN
342 ? USBDEV_IN_STALL_REG_OFFSET
343 : USBDEV_OUT_STALL_REG_OFFSET;
344 uint32_t reg_val = mmio_region_read32(usbdev->
base_addr, reg_offset);
354 if (endpoint.
direction == USBDEV_ENDPOINT_DIR_IN) {
355 return endpoint_functionality_enable(usbdev, USBDEV_IN_ISO_REG_OFFSET,
356 endpoint.
number, new_state);
358 return endpoint_functionality_enable(usbdev, USBDEV_OUT_ISO_REG_OFFSET,
359 endpoint.
number, new_state);
366 if (endpoint.
direction == USBDEV_ENDPOINT_DIR_IN) {
367 return endpoint_functionality_enable(usbdev, USBDEV_EP_IN_ENABLE_REG_OFFSET,
368 endpoint.
number, new_state);
370 return endpoint_functionality_enable(
371 usbdev, USBDEV_EP_OUT_ENABLE_REG_OFFSET, endpoint.
number, new_state);
383 mmio_region_read32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET);
386 mmio_region_write32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET, reg_val);
394 if (usbdev == NULL || info == NULL || buffer == NULL) {
399 uint32_t fifo_status =
400 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
406 const uint32_t fifo_entry =
407 mmio_region_read32(usbdev->
base_addr, USBDEV_RXFIFO_REG_OFFSET);
419 USBDEV_RXFIFO_BUFFER_FIELD),
421 .remaining_bytes = info->
length,
431 if (usbdev == NULL || buffer_pool == NULL || buffer == NULL) {
435 if (buffer_pool_is_empty(buffer_pool)) {
440 if (!buffer_pool_remove(buffer_pool, &buffer_id)) {
447 .remaining_bytes = USBDEV_BUFFER_ENTRY_SIZE_BYTES,
457 if (usbdev == NULL || buffer_pool == NULL || buffer == NULL) {
461 switch (buffer->
type) {
465 if (!buffer_pool_add(buffer_pool, buffer->
id)) {
479 size_t dst_len,
size_t *bytes_written) {
480 if (usbdev == NULL || buffer_pool == NULL || buffer == NULL ||
487 if (bytes_to_copy > dst_len) {
488 bytes_to_copy = dst_len;
491 const uint32_t buffer_addr = get_buffer_addr(buffer->
id, buffer->
offset);
495 buffer->
offset += bytes_to_copy;
498 if (bytes_written != NULL) {
499 *bytes_written = bytes_to_copy;
508 if (!buffer_pool_add(buffer_pool, buffer->
id)) {
519 const uint8_t *src,
size_t src_len,
520 size_t *bytes_written) {
521 if (usbdev == NULL || buffer == NULL ||
528 if (bytes_to_copy > src_len) {
529 bytes_to_copy = src_len;
533 uint32_t buffer_addr = get_buffer_addr(buffer->
id, buffer->
offset);
537 buffer->
offset += bytes_to_copy;
541 *bytes_written = bytes_to_copy;
553 if (usbdev == NULL || !is_valid_endpoint(endpoint) || buffer == NULL ||
559 const uint32_t config_in_reg_offset =
560 kEndpointHwInfos[endpoint].config_in_reg_offset;
566 uint32_t config_in_val = 0;
568 config_in_val, USBDEV_CONFIGIN_0_BUFFER_0_FIELD, buffer->
id);
570 config_in_val, USBDEV_CONFIGIN_0_SIZE_0_FIELD, buffer->
offset);
571 mmio_region_write32(usbdev->
base_addr, (ptrdiff_t)config_in_reg_offset,
577 mmio_region_write32(usbdev->
base_addr, (ptrdiff_t)config_in_reg_offset,
589 if (usbdev == NULL || sent == NULL) {
592 *sent = (uint16_t)mmio_region_read32(usbdev->
base_addr,
593 USBDEV_IN_SENT_REG_OFFSET);
600 if (usbdev == NULL || buffer_pool == NULL || !is_valid_endpoint(endpoint)) {
604 uint32_t config_in_reg_offset =
605 kEndpointHwInfos[endpoint].config_in_reg_offset;
606 uint32_t config_in_reg_val =
607 mmio_region_read32(usbdev->
base_addr, (ptrdiff_t)config_in_reg_offset);
609 config_in_reg_val, USBDEV_CONFIGIN_0_BUFFER_0_FIELD);
611 mmio_region_write32(usbdev->
base_addr, (ptrdiff_t)config_in_reg_offset,
612 1u << USBDEV_CONFIGIN_0_PEND_0_BIT);
614 mmio_region_write32(usbdev->
base_addr, USBDEV_IN_SENT_REG_OFFSET,
617 if (!buffer_pool_add(buffer_pool, buffer)) {
626 if (usbdev == NULL ||
status == NULL || !is_valid_endpoint(endpoint)) {
631 uint32_t config_in_reg_offset =
632 kEndpointHwInfos[endpoint].config_in_reg_offset;
633 uint8_t endpoint_bit_index = kEndpointHwInfos[endpoint].bit_index;
636 uint32_t config_in_val =
637 mmio_region_read32(usbdev->
base_addr, (ptrdiff_t)config_in_reg_offset);
644 USBDEV_IN_SENT_REG_OFFSET),
645 endpoint_bit_index)) {
660 if (usbdev == NULL) {
665 mmio_region_read32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET);
668 mmio_region_write32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET, reg_val);
674 if (usbdev == NULL || addr == NULL) {
679 mmio_region_read32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET);
682 USBDEV_USBCTRL_DEVICE_ADDRESS_FIELD);
689 if (usbdev == NULL || toggles == NULL) {
694 mmio_region_read32(usbdev->
base_addr, USBDEV_OUT_DATA_TOGGLE_REG_OFFSET);
696 *toggles = (uint16_t)reg_val;
703 if (usbdev == NULL || toggles == NULL) {
708 mmio_region_read32(usbdev->
base_addr, USBDEV_IN_DATA_TOGGLE_REG_OFFSET);
710 *toggles = (uint16_t)reg_val;
716 uint16_t mask, uint16_t state) {
717 if (usbdev == NULL) {
722 mmio_region_write32(usbdev->
base_addr, USBDEV_OUT_DATA_TOGGLE_REG_OFFSET,
723 ((uint32_t)mask << 16) | state);
729 uint16_t mask, uint16_t state) {
730 if (usbdev == NULL) {
735 mmio_region_write32(usbdev->
base_addr, USBDEV_IN_DATA_TOGGLE_REG_OFFSET,
736 ((uint32_t)mask << 16) | state);
743 if (usbdev == NULL) {
747 uint32_t reg_val = (uint32_t)1u << (endpoint + 16u);
748 mmio_region_write32(usbdev->
base_addr, USBDEV_OUT_DATA_TOGGLE_REG_OFFSET,
750 mmio_region_write32(usbdev->
base_addr, USBDEV_IN_DATA_TOGGLE_REG_OFFSET,
757 uint16_t *frame_index) {
758 if (usbdev == NULL || frame_index == NULL) {
763 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
773 if (usbdev == NULL || host_lost == NULL) {
779 USBDEV_USBSTAT_HOST_LOST_BIT);
786 if (usbdev == NULL || link_state == NULL) {
791 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
795 case USBDEV_USBSTAT_LINK_STATE_VALUE_DISCONNECTED:
796 *link_state = kDifUsbdevLinkStateDisconnected;
798 case USBDEV_USBSTAT_LINK_STATE_VALUE_POWERED:
799 *link_state = kDifUsbdevLinkStatePowered;
801 case USBDEV_USBSTAT_LINK_STATE_VALUE_POWERED_SUSPENDED:
802 *link_state = kDifUsbdevLinkStatePoweredSuspended;
804 case USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE:
805 *link_state = kDifUsbdevLinkStateActive;
807 case USBDEV_USBSTAT_LINK_STATE_VALUE_SUSPENDED:
808 *link_state = kDifUsbdevLinkStateSuspended;
810 case USBDEV_USBSTAT_LINK_STATE_VALUE_ACTIVE_NOSOF:
811 *link_state = kDifUsbdevLinkStateActiveNoSof;
813 case USBDEV_USBSTAT_LINK_STATE_VALUE_RESUMING:
814 *link_state = kDifUsbdevLinkStateResuming;
825 if (usbdev == NULL || sense == NULL) {
830 USBDEV_USBSTAT_SENSE_BIT);
836 const dif_usbdev_t *usbdev, uint8_t *setup_depth, uint8_t *out_depth) {
837 if (usbdev == NULL || setup_depth == NULL || out_depth == NULL) {
842 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
845 reg_val, USBDEV_USBSTAT_AV_SETUP_DEPTH_FIELD);
848 reg_val, USBDEV_USBSTAT_AV_OUT_DEPTH_FIELD);
854 const dif_usbdev_t *usbdev,
bool *setup_is_full,
bool *out_is_full) {
855 if (usbdev == NULL || setup_is_full == NULL || out_is_full == NULL) {
860 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
870 if (usbdev == NULL || depth == NULL) {
875 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
885 if (usbdev == NULL || is_empty == NULL) {
890 mmio_region_read32(usbdev->
base_addr, USBDEV_USBSTAT_REG_OFFSET);
903 mmio_region_read32(usbdev->
base_addr, USBDEV_PHY_CONFIG_REG_OFFSET);
905 reg_val, USBDEV_PHY_CONFIG_TX_OSC_TEST_MODE_BIT, set_tx_osc_mode);
906 mmio_region_write32(usbdev->
base_addr, USBDEV_PHY_CONFIG_REG_OFFSET, reg_val);
922 mmio_region_write32(usbdev->
base_addr, USBDEV_WAKE_CONTROL_REG_OFFSET,
929 if (usbdev == NULL ||
status == NULL) {
933 mmio_region_read32(usbdev->
base_addr, USBDEV_WAKE_EVENTS_REG_OFFSET);
944 if (usbdev == NULL) {
948 mmio_region_read32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET);
951 mmio_region_write32(usbdev->
base_addr, USBDEV_USBCTRL_REG_OFFSET, reg_val);
957 if (usbdev == NULL ||
status == NULL) {
961 mmio_region_read32(usbdev->
base_addr, USBDEV_PHY_PINS_SENSE_REG_OFFSET);
1011 mmio_region_write32(usbdev->
base_addr, USBDEV_PHY_PINS_DRIVE_REG_OFFSET,