M480 BSP  V3.05.001
The Board Support Package for M480 Series
msc_xfer.c
Go to the documentation of this file.
1 /**************************************************************************/
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include "NuMicro.h"
15 #include "diskio.h" // FATFS header
16 #include "usb.h"
17 #include "msc.h"
18 
19 
20 static int __tag = 0x10e24388;
21 
22 
23 static void bulk_xfer_done(UTR_T *utr)
24 {
25  // msc_debug_msg("BULK XFER done - %d\n", utr->status);
26 }
27 
28 int msc_bulk_transfer(MSC_T *msc, EP_INFO_T *ep, uint8_t *data_buff, int data_len, int timeout_ticks)
29 {
30  UTR_T *utr;
31  uint32_t t0;
32  int ret;
33 
34  utr = alloc_utr(msc->iface->udev);
35  if (!utr)
36  return USBH_ERR_MEMORY_OUT;
37 
38  utr->ep = ep;
39  utr->buff = data_buff;
40  utr->data_len = data_len;
41  utr->xfer_len = 0;
42  utr->func = bulk_xfer_done;
43  utr->bIsTransferDone = 0;
44 
45  ret = usbh_bulk_xfer(utr);
46  if (ret < 0)
47  return ret;
48 
49  t0 = get_ticks();
50  while (utr->bIsTransferDone == 0)
51  {
52  if (get_ticks() - t0 > timeout_ticks)
53  {
54  usbh_quit_utr(utr);
55  free_utr(utr);
56  return USBH_ERR_TIMEOUT;
57  }
58  }
59  ret = utr->status;
60  free_utr(utr);
61  msc_debug_msg(" <BULK> status: %d, xfer_len: %d\n", utr->status, utr->xfer_len);
62 
63  return ret;
64 }
65 
66 
67 static int do_scsi_command(MSC_T *msc, uint8_t *buff, uint32_t data_len, int bIsDataIn, int timeout_ticks)
68 {
69  int ret;
70  struct bulk_cb_wrap *cmd_blk = &msc->cmd_blk; /* MSC Bulk-only command block */
71  struct bulk_cs_wrap *cmd_status = &msc->cmd_status;; /* MSC Bulk-only command status */
72 
73  cmd_blk->Signature = MSC_CB_SIGN;
74  cmd_blk->Tag = __tag++;
75  cmd_blk->DataTransferLength = data_len;
76  cmd_blk->Lun = msc->lun;
77 
78  ret = msc_bulk_transfer(msc, msc->ep_bulk_out, (uint8_t *)cmd_blk, 31, timeout_ticks);
79  if (ret < 0)
80  return ret;
81 
82  msc_debug_msg(" [XFER] MSC CMD OK.\n");
83 
84  if (data_len > 0)
85  {
86  if (bIsDataIn)
87  ret = msc_bulk_transfer(msc, msc->ep_bulk_in, buff, data_len, 500);
88  else
89  ret = msc_bulk_transfer(msc, msc->ep_bulk_out, buff, data_len, 500);
90  if (ret < 0)
91  return ret;
92  msc_debug_msg(" [XFER] MSC DATA OK.\n");
93  }
94 
95  ret = msc_bulk_transfer(msc, msc->ep_bulk_in, (uint8_t *)cmd_status, 13, timeout_ticks);
96  if (ret < 0)
97  return ret;
98 
99  msc_debug_msg(" [XFER] MSC STATUS OK.\n");
100 
101  if (cmd_status->Status != 0)
102  {
103  msc_debug_msg(" !! CSW status error.\n");
104  return UMAS_ERR_CMD_STATUS;
105  }
106  msc_debug_msg(" [CSW] status OK.\n");
107 
108  msc_debug_msg("SCSI command 0x%0x done.\n", cmd_blk->CDB[0]);
109  return 0;
110 }
111 
112 
113 int run_scsi_command(MSC_T *msc, uint8_t *buff, uint32_t data_len, int bIsDataIn, int timeout_ticks)
114 {
115  return do_scsi_command(msc, buff, data_len, bIsDataIn, timeout_ticks);
116 }
117 
118 /*** (C) COPYRIGHT 2017 Nuvoton Technology Corp. ***/
119 
120 
#define USBH_ERR_TIMEOUT
Definition: usbh_lib.h:46
static void bulk_xfer_done(UTR_T *utr)
Definition: msc_xfer.c:23
NuMicro peripheral access layer header file.
M480 MCU USB Host mass storage class header.
uint32_t get_ticks(void)
A function return current tick count.
int msc_bulk_transfer(MSC_T *msc, EP_INFO_T *ep, uint8_t *data_buff, int data_len, int timeout_ticks)
Definition: msc_xfer.c:28
static int __tag
Definition: msc_xfer.c:20
#define USBH_ERR_MEMORY_OUT
Definition: usbh_lib.h:32
static int do_scsi_command(MSC_T *msc, uint8_t *buff, uint32_t data_len, int bIsDataIn, int timeout_ticks)
Definition: msc_xfer.c:67
#define UMAS_ERR_CMD_STATUS
Definition: usbh_lib.h:81
int run_scsi_command(MSC_T *msc, uint8_t *buff, uint32_t data_len, int bIsDataIn, int timeout_ticks)
Definition: msc_xfer.c:113
USB Host library header file.