5 #include "sw/device/lib/testing/usb_testutils.h" 
    8 #include "sw/device/lib/testing/test_framework/check.h" 
   12 #define MODULE_ID MAKE_MODULE_ID('u', 's', 't') 
   14 #define USBDEV_BASE_ADDR TOP_EARLGREY_USBDEV_BASE_ADDR 
   16 static dif_usbdev_t usbdev;
 
   25   CHECK(ctx && transfer && last);
 
   35   unsigned max_packet = USBDEV_MAX_PACKET_SIZE;
 
   36   if (transfer->
flags & kUsbTestutilsXfrMaxPacketSupplied) {
 
   37     max_packet = (unsigned)(transfer->
flags & kUsbTestutilsXfrMaxPacketMask);
 
   42   if (part_len > max_packet) {
 
   43     part_len = max_packet;
 
   45   size_t bytes_written = 0U;
 
   49                                          part_len, &bytes_written));
 
   52   uint32_t next_offset = transfer->
offset + bytes_written;
 
   54   if (bytes_written == max_packet) {
 
   55     if (next_offset < transfer->length ||
 
   56         (transfer->
flags & kUsbTestutilsXfrEmployZLP)) {
 
   60     CHECK(bytes_written < max_packet);
 
   63   transfer->
offset = next_offset;
 
   68 static bool usb_testutils_transfer_next_part(
 
   72       !usb_testutils_part_prepare(ctx, transfer, &transfer->
next_part,
 
   83   if ((transfer->
flags & kUsbTestutilsXfrDoubleBuffered) && !transfer->
last) {
 
   84     transfer->
next_valid = usb_testutils_part_prepare(
 
   95   TRY(dif_usbdev_irq_get_state(ctx->dev, &istate));
 
  104   if (istate & (1u << kDifUsbdevIrqPktSent)) {
 
  110       if (sentep & (1u << ep)) {
 
  117         usb_testutils_xfr_result_t res = kUsbTestutilsXfrResultOk;
 
  121             if (usb_testutils_transfer_next_part(ctx, (uint8_t)ep, transfer)) {
 
  124               res = kUsbTestutilsXfrResultFailed;
 
  134         if (done && ctx->
in[ep].tx_done_callback) {
 
  135           TRY(ctx->
in[ep].tx_done_callback(ctx->
in[ep].ep_ctx, res));
 
  137         sentep &= ~(1u << ep);
 
  146   if (istate & (1u << kDifUsbdevIrqPktReceived)) {
 
  161       if (ctx->
out[ep].rx_callback) {
 
  162         TRY(ctx->
out[ep].rx_callback(ctx->
out[ep].ep_ctx, packet_info, buffer));
 
  165         TRC_S(
"USB: unexpected RX ");
 
  171   if (istate & (1u << kDifUsbdevIrqLinkReset)) {
 
  172     TRC_S(
"USB: Bus reset");
 
  178       if (ctx->
in[ep].reset) {
 
  179         TRY(ctx->
in[ep].reset(ctx->
in[ep].ep_ctx));
 
  181       if (ctx->
out[ep].reset) {
 
  182         TRY(ctx->
out[ep].reset(ctx->
out[ep].ep_ctx));
 
  188   TRY(dif_usbdev_irq_acknowledge_state(ctx->dev, istate));
 
  191   if ((istate & (1u << kDifUsbdevIrqFrame))) {
 
  199     const dif_usbdev_irq_state_snapshot_t kIrqsLink =
 
  200         (1u << kDifUsbdevIrqPowered) | (1u << kDifUsbdevIrqDisconnected) |
 
  201         (1u << kDifUsbdevIrqHostLost) | (1u << kDifUsbdevIrqLinkReset) |
 
  202         (1u << kDifUsbdevIrqLinkSuspend) | (1u << kDifUsbdevIrqLinkResume) |
 
  203         (1u << kDifUsbdevIrqFrame);
 
  204     if (istate & kIrqsLink) {
 
  226       ~((1u << kDifUsbdevIrqLinkReset) | (1u << kDifUsbdevIrqPktReceived) |
 
  227         (1u << kDifUsbdevIrqPktSent) | (1u << kDifUsbdevIrqFrame) |
 
  228         (1u << kDifUsbdevIrqAvSetupEmpty) | (1u << kDifUsbdevIrqAvOutEmpty) |
 
  229         (1u << kDifUsbdevIrqRxFull) | (1u << kDifUsbdevIrqLinkOutErr) |
 
  230         (1u << kDifUsbdevIrqLinkInErr))) {
 
  238         ((1u << kDifUsbdevIrqRxFull) | (1u << kDifUsbdevIrqAvOverflow) |
 
  239          (1u << kDifUsbdevIrqLinkInErr) | (1u << kDifUsbdevIrqRxCrcErr) |
 
  240          (1u << kDifUsbdevIrqRxPidErr) | (1u << kDifUsbdevIrqRxBitstuffErr) |
 
  241          (1u << kDifUsbdevIrqLinkOutErr))) {
 
  242       LOG_INFO(
"USB: Unexpected interrupts: 0x%08x", istate);
 
  257     if (ctx->flushed == 0) {
 
  259         if (ctx->
in[ep].flush) {
 
  260           TRY(ctx->
in[ep].flush(ctx->
in[ep].ep_ctx));
 
  273                                               usb_testutils_link_handler_t link,
 
  287                                      const uint8_t *data, uint32_t length,
 
  288                                      usb_testutils_xfr_flags_t flags) {
 
  294     return OK_STATUS(
false);
 
  300   transfer->
length = length;
 
  301   transfer->
flags = flags;
 
  304   if (!usb_testutils_transfer_next_part(ctx, ep, transfer)) {
 
  307     return OK_STATUS(
false);
 
  311   return OK_STATUS(
true);
 
  314 status_t usb_testutils_in_endpoint_setup(
 
  316     void *ep_ctx, usb_testutils_tx_done_handler_t tx_done,
 
  317     usb_testutils_tx_flush_handler_t flush,
 
  318     usb_testutils_reset_handler_t reset) {
 
  320   ctx->
in[ep].ep_type = ep_type;
 
  321   ctx->
in[ep].ep_ctx = ep_ctx;
 
  322   ctx->
in[ep].tx_done_callback = tx_done;
 
  323   ctx->
in[ep].flush = flush;
 
  324   ctx->
in[ep].reset = reset;
 
  328       .direction = USBDEV_ENDPOINT_DIR_IN,
 
  335   if (ep_type == kUsbTransferTypeIsochronous) {
 
  345 status_t usb_testutils_out_endpoint_setup(
 
  347     usb_testutils_out_transfer_mode_t out_mode, 
void *ep_ctx,
 
  348     usb_testutils_rx_handler_t rx, usb_testutils_reset_handler_t reset) {
 
  350   ctx->
out[ep].ep_type = ep_type;
 
  351   ctx->
out[ep].ep_ctx = ep_ctx;
 
  352   ctx->
out[ep].rx_callback = rx;
 
  353   ctx->
out[ep].reset = reset;
 
  357       .direction = USBDEV_ENDPOINT_DIR_OUT,
 
  364   if (ep_type == kUsbTransferTypeIsochronous) {
 
  371   if (out_mode == kUsbdevOutDisabled) {
 
  377   if (out_mode == kUsbdevOutMessage) {
 
  388 status_t usb_testutils_endpoint_setup(
 
  390     usb_testutils_transfer_type_t out_type,
 
  391     usb_testutils_out_transfer_mode_t out_mode, 
void *ep_ctx,
 
  392     usb_testutils_tx_done_handler_t tx_done, usb_testutils_rx_handler_t rx,
 
  393     usb_testutils_tx_flush_handler_t flush,
 
  394     usb_testutils_reset_handler_t reset) {
 
  395   TRY(usb_testutils_in_endpoint_setup(ctx, ep, in_type, ep_ctx, tx_done, flush,
 
  400   return usb_testutils_out_endpoint_setup(ctx, ep, out_type, out_mode, ep_ctx,
 
  409       .direction = USBDEV_ENDPOINT_DIR_IN,
 
  414   ctx->
in[ep].tx_done_callback = NULL;
 
  415   ctx->
in[ep].flush = NULL;
 
  416   ctx->
in[ep].reset = NULL;
 
  426       .direction = USBDEV_ENDPOINT_DIR_OUT,
 
  437   ctx->
out[ep].rx_callback = NULL;
 
  438   ctx->
out[ep].reset = NULL;
 
  444   TRY(usb_testutils_in_endpoint_remove(ctx, ep));
 
  445   return usb_testutils_out_endpoint_remove(ctx, ep);
 
  449                             bool en_diff_rcvr, 
bool tx_use_d_se0) {
 
  450   TRY_CHECK(ctx != NULL);
 
  452   ctx->buffer_pool = &buffer_pool;
 
  475                 "USBDEV_NUM_ENDPOINTS must fit into uint8_t");
 
  477     TRY(usb_testutils_endpoint_setup(
 
  478         ctx, i, kUsbTransferTypeControl, kUsbTransferTypeControl,
 
  479         kUsbdevOutDisabled, NULL, NULL, NULL, NULL, NULL));
 
  483   TRY(dif_usbdev_irq_disable_all(ctx->dev, NULL));
 
  487   TRY(dif_usbdev_irq_acknowledge_all(ctx->dev));
 
  503                 "USBDEV_NUM_ENDPOINTS must fit into uint8_t");
 
  505                 "USBDEV_NUM_ENDPOINTS - 1 must not overflow");
 
  509     TRY(usb_testutils_endpoint_remove(ctx, ep));