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