diff options
author | Diego Ismirlian <dismirlian (at) google's mail.com> | 2017-06-05 10:18:45 -0300 |
---|---|---|
committer | Diego Ismirlian <dismirlian (at) google's mail.com> | 2017-06-05 10:18:45 -0300 |
commit | 5ecaf7722b5f1f9d0c41213fc5c129b451302f99 (patch) | |
tree | 4a4e2b746d6db725e3aacf8ff87e1a3a88e3dd4e /os | |
parent | eec17ec12e23b7f647d37a8d70df4df34632f8c1 (diff) | |
download | ChibiOS-Contrib-5ecaf7722b5f1f9d0c41213fc5c129b451302f99.tar.gz ChibiOS-Contrib-5ecaf7722b5f1f9d0c41213fc5c129b451302f99.tar.bz2 ChibiOS-Contrib-5ecaf7722b5f1f9d0c41213fc5c129b451302f99.zip |
USB Host fixes
- Cleaned up alignment macros for GCC & IAR
- Corrected EP halt and Clear halt behaviours
- Initialization of class drivers by USB Host main driver
- Minor cosmetic fixes
- Updated USB_HOST testhal app
Diffstat (limited to 'os')
-rw-r--r-- | os/hal/include/hal_usbh.h | 26 | ||||
-rw-r--r-- | os/hal/include/usbh/debug.h | 2 | ||||
-rw-r--r-- | os/hal/include/usbh/defs.h | 20 | ||||
-rw-r--r-- | os/hal/include/usbh/dev/ftdi.h | 12 | ||||
-rw-r--r-- | os/hal/include/usbh/dev/hub.h | 11 | ||||
-rw-r--r-- | os/hal/include/usbh/dev/msd.h | 7 | ||||
-rw-r--r-- | os/hal/include/usbh/list.h | 5 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c | 99 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h | 13 | ||||
-rw-r--r-- | os/hal/src/hal_usbh.c | 66 | ||||
-rw-r--r-- | os/hal/src/usbh/hal_usbh_debug.c | 9 | ||||
-rw-r--r-- | os/hal/src/usbh/hal_usbh_desciter.c | 24 | ||||
-rw-r--r-- | os/hal/src/usbh/hal_usbh_ftdi.c | 18 | ||||
-rw-r--r-- | os/hal/src/usbh/hal_usbh_hub.c | 15 | ||||
-rw-r--r-- | os/hal/src/usbh/hal_usbh_msd.c | 31 | ||||
-rw-r--r-- | os/various/fatfs_bindings/fatfs.mk | 7 | ||||
-rw-r--r-- | os/various/fatfs_bindings/fatfs_diskio.c | 320 |
17 files changed, 570 insertions, 115 deletions
diff --git a/os/hal/include/hal_usbh.h b/os/hal/include/hal_usbh.h index 63be93e..5dcd01a 100644 --- a/os/hal/include/hal_usbh.h +++ b/os/hal/include/hal_usbh.h @@ -20,6 +20,9 @@ #include "hal.h" +#ifndef HAL_USE_USBH +#define HAL_USE_USBH FALSE +#endif #ifndef HAL_USBH_USE_FTDI #define HAL_USBH_USE_FTDI FALSE @@ -37,6 +40,8 @@ #define HAL_USBH_USE_UVC FALSE #endif +#define HAL_USBH_USE_IAD HAL_USBH_USE_UVC + #if (HAL_USE_USBH == TRUE) || defined(__DOXYGEN__) #include "osal.h" @@ -104,13 +109,11 @@ enum usbh_urbstatus { USBH_URBSTATUS_UNINITIALIZED = 0, USBH_URBSTATUS_INITIALIZED, USBH_URBSTATUS_PENDING, -// USBH_URBSTATUS_QUEUED, USBH_URBSTATUS_ERROR, USBH_URBSTATUS_TIMEOUT, USBH_URBSTATUS_CANCELLED, USBH_URBSTATUS_STALL, USBH_URBSTATUS_DISCONNECTED, -// USBH_URBSTATUS_EPCLOSED, USBH_URBSTATUS_OK, }; @@ -145,7 +148,8 @@ typedef void (*usbh_completion_cb)(usbh_urb_t *); /* include the low level driver; the required definitions are above */ #include "hal_usbh_lld.h" -#define USBH_DEFINE_BUFFER(type, name) USBH_LLD_DEFINE_BUFFER(type, name) +#define USBH_DEFINE_BUFFER(var) USBH_LLD_DEFINE_BUFFER(var) +#define USBH_DECLARE_STRUCT_MEMBER(member) USBH_LLD_DECLARE_STRUCT_MEMBER(member) struct usbh_urb { usbh_ep_t *ep; @@ -198,9 +202,8 @@ struct usbh_device { usbh_devstatus_t status; usbh_devspeed_t speed; - USBH_DEFINE_BUFFER(usbh_device_descriptor_t, devDesc); - unsigned char align_bytes[2]; - USBH_DEFINE_BUFFER(usbh_config_descriptor_t, basicConfigDesc); + USBH_DECLARE_STRUCT_MEMBER(usbh_device_descriptor_t devDesc); + USBH_DECLARE_STRUCT_MEMBER(usbh_config_descriptor_t basicConfigDesc); uint8_t *fullConfigurationDescriptor; uint8_t keepFullCfgDesc; @@ -362,10 +365,13 @@ extern "C" { usbhEPCloseS(ep); osalSysUnlock(); } - static inline void usbhEPResetI(usbh_ep_t *ep) { - osalDbgCheckClassI(); - osalDbgCheck(ep != NULL); - usbh_lld_epreset(ep); + bool usbhEPResetS(usbh_ep_t *ep); + static inline bool usbhEPReset(usbh_ep_t *ep) { + bool ret; + osalSysLock(); + ret = usbhEPResetS(ep); + osalSysUnlock(); + return ret; } static inline bool usbhEPIsPeriodic(usbh_ep_t *ep) { osalDbgCheck(ep != NULL); diff --git a/os/hal/include/usbh/debug.h b/os/hal/include/usbh/debug.h index 5120121..df077aa 100644 --- a/os/hal/include/usbh/debug.h +++ b/os/hal/include/usbh/debug.h @@ -23,8 +23,6 @@ #if HAL_USE_USBH
-//TODO: Debug is only for USBHD1, make it generic.
-
#if USBH_DEBUG_ENABLE
void usbDbgPrintf(const char *fmt, ...);
void usbDbgPuts(const char *s);
diff --git a/os/hal/include/usbh/defs.h b/os/hal/include/usbh/defs.h index c3d8a9a..58b1de2 100644 --- a/os/hal/include/usbh/defs.h +++ b/os/hal/include/usbh/defs.h @@ -25,12 +25,12 @@ #include "osal.h"
#ifdef __IAR_SYSTEMS_ICC__
-#define PACKED_STRUCT typedef PACKED_VAR struct
+#define PACKED_STRUCT PACKED_VAR struct
#else
-#define PACKED_STRUCT typedef struct PACKED_VAR
+#define PACKED_STRUCT struct PACKED_VAR
#endif
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
@@ -49,7 +49,7 @@ PACKED_STRUCT { #define USBH_DT_DEVICE 0x01
#define USBH_DT_DEVICE_SIZE 18
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
@@ -62,7 +62,7 @@ PACKED_STRUCT { #define USBH_DT_CONFIG 0x02
#define USBH_DT_CONFIG_SIZE 9
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wData[1];
@@ -70,7 +70,7 @@ PACKED_STRUCT { #define USBH_DT_STRING 0x03
#define USBH_DT_STRING_SIZE 2
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
@@ -84,7 +84,7 @@ PACKED_STRUCT { #define USBH_DT_INTERFACE 0x04
#define USBH_DT_INTERFACE_SIZE 9
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
@@ -95,7 +95,7 @@ PACKED_STRUCT { #define USBH_DT_ENDPOINT 0x05
#define USBH_DT_ENDPOINT_SIZE 7
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bFirstInterface;
@@ -108,7 +108,7 @@ PACKED_STRUCT { #define USBH_DT_INTERFACE_ASSOCIATION 0x0b
#define USBH_DT_INTERFACE_ASSOCIATION_SIZE 8
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bDescLength;
uint8_t bDescriptorType;
uint8_t bNbrPorts;
@@ -120,7 +120,7 @@ PACKED_STRUCT { #define USBH_DT_HUB 0x29
#define USBH_DT_HUB_SIZE (7 + 4)
-PACKED_STRUCT {
+typedef PACKED_STRUCT {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
diff --git a/os/hal/include/usbh/dev/ftdi.h b/os/hal/include/usbh/dev/ftdi.h index ad6b4cd..27a6f12 100644 --- a/os/hal/include/usbh/dev/ftdi.h +++ b/os/hal/include/usbh/dev/ftdi.h @@ -96,7 +96,7 @@ struct USBHFTDIPortDriver { usbh_urb_t iq_urb;
threads_queue_t iq_waiting;
uint32_t iq_counter;
- USBH_DEFINE_BUFFER(uint8_t, iq_buff[64]);
+ USBH_DECLARE_STRUCT_MEMBER(uint8_t iq_buff[64]);
uint8_t *iq_ptr;
@@ -104,7 +104,7 @@ struct USBHFTDIPortDriver { usbh_urb_t oq_urb;
threads_queue_t oq_waiting;
uint32_t oq_counter;
- USBH_DEFINE_BUFFER(uint8_t, oq_buff[64]);
+ USBH_DECLARE_STRUCT_MEMBER(uint8_t oq_buff[64]);
uint8_t *oq_ptr;
virtual_timer_t vt;
@@ -113,7 +113,7 @@ struct USBHFTDIPortDriver { USBHFTDIPortDriver *next;
};
-typedef struct USBHFTDIDriver {
+struct USBHFTDIDriver {
/* inherited from abstract class driver */
_usbh_base_classdriver_data
@@ -121,11 +121,12 @@ typedef struct USBHFTDIDriver { USBHFTDIPortDriver *ports;
mutex_t mtx;
-} USBHFTDIDriver;
+};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
+#define usbhftdipGetState(ftdipp) ((ftdipp)->state)
/*===========================================================================*/
@@ -144,6 +145,9 @@ extern "C" { void usbhftdipObjectInit(USBHFTDIPortDriver *ftdipp);
void usbhftdipStart(USBHFTDIPortDriver *ftdipp, const USBHFTDIPortConfig *config);
void usbhftdipStop(USBHFTDIPortDriver *ftdipp);
+
+ /* global initializer */
+ void usbhftdiInit(void);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/include/usbh/dev/hub.h b/os/hal/include/usbh/dev/hub.h index 07e88e6..a3becbc 100644 --- a/os/hal/include/usbh/dev/hub.h +++ b/os/hal/include/usbh/dev/hub.h @@ -23,7 +23,7 @@ #if HAL_USE_USBH
#if HAL_USBH_USE_HUB
-typedef struct USBHHubDriver {
+struct USBHHubDriver {
/* inherited from abstract class driver */
_usbh_base_classdriver_data
@@ -32,19 +32,19 @@ typedef struct USBHHubDriver { usbh_ep_t epint;
usbh_urb_t urb;
- USBH_DEFINE_BUFFER(uint8_t, scbuff[4]);
+ USBH_DECLARE_STRUCT_MEMBER(uint8_t scbuff[4]);
volatile uint32_t statuschange;
uint16_t status;
uint16_t c_status;
usbh_port_t *ports;
- USBH_DEFINE_BUFFER(usbh_hub_descriptor_t, hubDesc);
+ USBH_DECLARE_STRUCT_MEMBER(usbh_hub_descriptor_t hubDesc);
/* Low level part */
_usbh_hub_ll_data
-} USBHHubDriver;
+};
extern USBHHubDriver USBHHUBD[HAL_USBHHUB_MAX_INSTANCES];
@@ -89,6 +89,9 @@ static inline usbh_urbstatus_t usbhhubSetFeaturePort(usbh_port_t *port, uint8_t }
void usbhhubObjectInit(USBHHubDriver *hubdp);
+
+void usbhhubInit(void);
+
#else
static inline usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host,
diff --git a/os/hal/include/usbh/dev/msd.h b/os/hal/include/usbh/dev/msd.h index d164618..88e8a5e 100644 --- a/os/hal/include/usbh/dev/msd.h +++ b/os/hal/include/usbh/dev/msd.h @@ -65,7 +65,7 @@ struct USBHMassStorageLUNDriver { USBHMassStorageLUNDriver *next;
};
-typedef struct USBHMassStorageDriver {
+struct USBHMassStorageDriver {
/* inherited from abstract class driver */
_usbh_base_classdriver_data
@@ -81,7 +81,7 @@ typedef struct USBHMassStorageDriver { uint32_t tag;
USBHMassStorageLUNDriver *luns;
-} USBHMassStorageDriver;
+};
/*===========================================================================*/
@@ -116,6 +116,9 @@ extern "C" { bool usbhmsdLUNGetInfo(USBHMassStorageLUNDriver *lunp, BlockDeviceInfo *bdip);
bool usbhmsdLUNIsInserted(USBHMassStorageLUNDriver *lunp);
bool usbhmsdLUNIsProtected(USBHMassStorageLUNDriver *lunp);
+
+ /* global initializer */
+ void usbhmsdInit(void);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/include/usbh/list.h b/os/hal/include/usbh/list.h index 4eceacd..317e51b 100644 --- a/os/hal/include/usbh/list.h +++ b/os/hal/include/usbh/list.h @@ -7,11 +7,8 @@ #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
-#define container_of(ptr, type, member) ((type *)(void *)((char *)(ptr) - offsetof(type, member)))
#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof(((type *)0)->member) * __mptr = (ptr); \
- (type *)((char *)__mptr - offsetof(type, member)); })
+#define container_of(ptr, type, member) ((type *)(void *)((char *)(ptr) - offsetof(type, member)))
#endif
/*
diff --git a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c index 8947490..21cf967 100644 --- a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c +++ b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c @@ -21,6 +21,53 @@ #include "usbh/internal.h" #include <string.h> +#if STM32_USBH_USE_OTG1 +#if !defined(STM32_OTG1_CHANNELS_NUMBER) +#error "STM32_OTG1_CHANNELS_NUMBER must be defined" +#endif +#if !defined(STM32_OTG1_RXFIFO_SIZE) +#define STM32_OTG1_RXFIFO_SIZE 1024 +#endif +#if !defined(STM32_OTG1_PTXFIFO_SIZE) +#define STM32_OTG1_PTXFIFO_SIZE 128 +#endif +#if !defined(STM32_OTG1_NPTXFIFO_SIZE) +#define STM32_OTG1_NPTXFIFO_SIZE 128 +#endif +#if (STM32_OTG1_RXFIFO_SIZE + STM32_OTG1_PTXFIFO_SIZE + STM32_OTG1_NPTXFIFO_SIZE) > (STM32_OTG1_FIFO_MEM_SIZE * 4) +#error "Not enough memory in OTG1 implementation" +#elif (STM32_OTG1_RXFIFO_SIZE + STM32_OTG1_PTXFIFO_SIZE + STM32_OTG1_NPTXFIFO_SIZE) < (STM32_OTG1_FIFO_MEM_SIZE * 4) +#warning "Spare memory in OTG1; could enlarge RX, PTX or NPTX FIFO sizes" +#endif +#if (STM32_OTG1_RXFIFO_SIZE % 4) || (STM32_OTG1_PTXFIFO_SIZE % 4) || (STM32_OTG1_NPTXFIFO_SIZE % 4) +#error "FIFO sizes must be a multiple of 32-bit words" +#endif +#endif + +#if STM32_USBH_USE_OTG2 +#if !defined(STM32_OTG2_CHANNELS_NUMBER) +#error "STM32_OTG2_CHANNELS_NUMBER must be defined" +#endif +#if !defined(STM32_OTG2_RXFIFO_SIZE) +#define STM32_OTG2_RXFIFO_SIZE 2048 +#endif +#if !defined(STM32_OTG2_PTXFIFO_SIZE) +#define STM32_OTG2_PTXFIFO_SIZE 1024 +#endif +#if !defined(STM32_OTG2_NPTXFIFO_SIZE) +#define STM32_OTG2_NPTXFIFO_SIZE 1024 +#endif +#if (STM32_OTG2_RXFIFO_SIZE + STM32_OTG2_PTXFIFO_SIZE + STM32_OTG2_NPTXFIFO_SIZE) > (STM32_OTG2_FIFO_MEM_SIZE * 4) +#error "Not enough memory in OTG2 implementation" +#elif (STM32_OTG2_RXFIFO_SIZE + STM32_OTG2_PTXFIFO_SIZE + STM32_OTG2_NPTXFIFO_SIZE) < (STM32_OTG2_FIFO_MEM_SIZE * 4) +#warning "Spare memory in OTG2; could enlarge RX, PTX or NPTX FIFO sizes" +#endif +#if (STM32_OTG2_RXFIFO_SIZE % 4) || (STM32_OTG2_PTXFIFO_SIZE % 4) || (STM32_OTG2_NPTXFIFO_SIZE % 4) +#error "FIFO sizes must be a multiple of 32-bit words" +#endif +#endif + + #if USBH_LLD_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) #define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) @@ -492,7 +539,7 @@ static uint32_t _write_packet(struct list_head *list, uint32_t space_available) void usbh_lld_ep_object_init(usbh_ep_t *ep) { /* CTRL(IN) CTRL(OUT) INT(IN) INT(OUT) BULK(IN) BULK(OUT) ISO(IN) ISO(OUT) - * STALL si sólo DAT/STAT si si si si no no ep->type != ISO && (ep->type != CTRL || ctrlphase != SETUP) + * STALL si solo DAT/STAT si si si si no no ep->type != ISO && (ep->type != CTRL || ctrlphase != SETUP) * ACK si si si si si si no no ep->type != ISO * NAK si si si si si si no no ep->type != ISO * BBERR si no si no si no si no ep->in @@ -563,6 +610,11 @@ void usbh_lld_ep_close(usbh_ep_t *ep) { osalOsRescheduleS(); } +bool usbh_lld_ep_reset(usbh_ep_t *ep) { + ep->dt_mask = HCTSIZ_DPID_DATA0; + return TRUE; +} + void usbh_lld_urb_submit(usbh_urb_t *urb) { usbh_ep_t *const ep = urb->ep; @@ -596,17 +648,20 @@ bool usbh_lld_urb_abort(usbh_urb_t *urb, usbh_urbstatus_t status) { if (hcm->halt_reason == USBH_LLD_HALTREASON_NONE) { /* The channel is not being halted */ + uinfof("\t%s: usbh_lld_urb_abort: channel is not being halted", hcm->ep->name); urb->status = status; _halt_channel(ep->device->host, hcm, USBH_LLD_HALTREASON_ABORT); } else { /* The channel is being halted, so we can't re-halt it. The CHH interrupt will * be in charge of completing the transfer, but the URB will not have the specified status. */ + uinfof("\t%s: usbh_lld_urb_abort: channel is being halted", hcm->ep->name); } return FALSE; } /* This URB is active, we can cancel it now */ + uinfof("\t%s: usbh_lld_urb_abort: URB is not active", hcm->ep->name); _transfer_completedI(ep, urb, status); return TRUE; @@ -855,8 +910,12 @@ static inline void _chh_int(USBHDriver *host, stm32_hc_management_t *hcm, stm32_ break; case USBH_LLD_HALTREASON_STALL: - if ((ep->type == USBH_EPTYPE_CTRL) && (ep->xfer.u.ctrl_phase == USBH_LLD_CTRLPHASE_SETUP)) { - uerrf("\t%s: Faulty device: STALLed SETUP phase", ep->name); + if (ep->type == USBH_EPTYPE_CTRL) { + if (ep->xfer.u.ctrl_phase == USBH_LLD_CTRLPHASE_SETUP) { + uerrf("\t%s: Faulty device: STALLed SETUP phase", ep->name); + } + } else { + ep->status = USBH_EPSTATUS_HALTED; } _transfer_completed(ep, urb, USBH_URBSTATUS_STALL); break; @@ -926,10 +985,15 @@ static inline void _hcint_int(USBHDriver *host) { haint = host->otg->HAINT; haint &= host->otg->HAINTMSK; +#if USBH_LLD_DEBUG_ENABLE_ERRORS if (!haint) { - uerrf("HAINT=%08x, HAINTMSK=%08x", host->otg->HAINT, host->otg->HAINTMSK); + uint32_t a, b; + a = host->otg->HAINT; + b = host->otg->HAINTMSK; + uerrf("HAINT=%08x, HAINTMSK=%08x", a, b); return; } +#endif #if 1 //channel lookup loop uint8_t i; @@ -1186,11 +1250,17 @@ static void usb_lld_serve_interrupt(USBHDriver *host) { } gintsts &= otg->GINTMSK; +#if USBH_DEBUG_ENABLE_WARNINGS if (!gintsts) { - uwarnf("GINTSTS=%08x, GINTMSK=%08x", otg->GINTSTS, otg->GINTMSK); + uint32_t a, b; + a = otg->GINTSTS; + b = otg->GINTMSK; + uwarnf("GINTSTS=%08x, GINTMSK=%08x", a, b); return; } -// otg->GINTMSK &= ~(GINTMSK_NPTXFEM | GINTMSK_PTXFEM); +#endif + + // otg->GINTMSK &= ~(GINTMSK_NPTXFEM | GINTMSK_PTXFEM); otg->GINTSTS = gintsts; if (gintsts & GINTSTS_SOF) @@ -1437,6 +1507,7 @@ static void _usbh_start(USBHDriver *usbh) { } #endif #endif +#undef HNPTXFSIZ otg_txfifo_flush(usbh, 0x10); otg_rxfifo_flush(usbh); @@ -1478,18 +1549,18 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy break; case ClearPortFeature: - chDbgAssert(windex == 1, "invalid windex"); + osalDbgAssert(windex == 1, "invalid windex"); osalSysLock(); switch (wvalue) { case USBH_PORT_FEAT_ENABLE: case USBH_PORT_FEAT_SUSPEND: case USBH_PORT_FEAT_POWER: - chDbgAssert(0, "unimplemented"); /* TODO */ + osalDbgAssert(0, "unimplemented"); /* TODO */ break; case USBH_PORT_FEAT_INDICATOR: - chDbgAssert(0, "unsupported"); + osalDbgAssert(0, "unsupported"); break; case USBH_PORT_FEAT_C_CONNECTION: @@ -1541,7 +1612,7 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy break; case GetPortStatus: - chDbgAssert(windex == 1, "invalid windex"); + osalDbgAssert(windex == 1, "invalid windex"); osalDbgCheck(wlength >= 4); osalSysLock(); *(uint32_t *)buf = usbh->rootport.lld_status | (usbh->rootport.lld_c_status << 16); @@ -1550,17 +1621,17 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy break; case SetHubFeature: - chDbgAssert(0, "unsupported"); + osalDbgAssert(0, "unsupported"); break; case SetPortFeature: - chDbgAssert(windex == 1, "invalid windex"); + osalDbgAssert(windex == 1, "invalid windex"); switch (wvalue) { case USBH_PORT_FEAT_TEST: case USBH_PORT_FEAT_SUSPEND: case USBH_PORT_FEAT_POWER: - chDbgAssert(0, "unimplemented"); /* TODO */ + osalDbgAssert(0, "unimplemented"); /* TODO */ break; case USBH_PORT_FEAT_RESET: { @@ -1580,7 +1651,7 @@ usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestTy } break; case USBH_PORT_FEAT_INDICATOR: - chDbgAssert(0, "unsupported"); + osalDbgAssert(0, "unsupported"); break; default: diff --git a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h index 15413b4..4552c2d 100644 --- a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h +++ b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.h @@ -127,25 +127,26 @@ typedef struct stm32_hc_management { "use USBH_DEFINE_BUFFER() to declare the IO buffers"); \ } while (0) - - void usbh_lld_init(void); void usbh_lld_start(USBHDriver *usbh); void usbh_lld_ep_object_init(usbh_ep_t *ep); void usbh_lld_ep_open(usbh_ep_t *ep); void usbh_lld_ep_close(usbh_ep_t *ep); +bool usbh_lld_ep_reset(usbh_ep_t *ep); void usbh_lld_urb_submit(usbh_urb_t *urb); bool usbh_lld_urb_abort(usbh_urb_t *urb, usbh_urbstatus_t status); usbh_urbstatus_t usbh_lld_root_hub_request(USBHDriver *usbh, uint8_t bmRequestType, uint8_t bRequest, uint16_t wvalue, uint16_t windex, uint16_t wlength, uint8_t *buf); uint8_t usbh_lld_roothub_get_statuschange_bitmap(USBHDriver *usbh); -#define usbh_lld_epreset(ep) do {(ep)->dt_mask = HCTSIZ_DPID_DATA0;} while (0); - #ifdef __IAR_SYSTEMS_ICC__ -#define USBH_LLD_DEFINE_BUFFER(type, name) type name +#define USBH_LLD_DEFINE_BUFFER(var) _Pragma("data_alignment=4") var +#define USBH_LLD_DECLARE_STRUCT_MEMBER_H1(x, y) x ## y +#define USBH_LLD_DECLARE_STRUCT_MEMBER_H2(x, y) USBH_LLD_DECLARE_STRUCT_MEMBER_H1(x, y) +#define USBH_LLD_DECLARE_STRUCT_MEMBER(member) unsigned int USBH_LLD_DECLARE_STRUCT_MEMBER_H2(dummy_align_, __COUNTER__); member #else -#define USBH_LLD_DEFINE_BUFFER(type, name) type name __attribute__((aligned(4))) +#define USBH_LLD_DEFINE_BUFFER(var) var __attribute__((aligned(4))) +#define USBH_LLD_DECLARE_STRUCT_MEMBER(member) member __attribute__((aligned(4))) #endif #endif diff --git a/os/hal/src/hal_usbh.c b/os/hal/src/hal_usbh.c index befe17f..0d0bf06 100644 --- a/os/hal/src/hal_usbh.c +++ b/os/hal/src/hal_usbh.c @@ -19,10 +19,14 @@ #if HAL_USE_USBH -#include "usbh/dev/hub.h" #include "usbh/internal.h" #include <string.h> +//devices +#include "usbh/dev/hub.h" +#include "usbh/dev/ftdi.h" +#include "usbh/dev/msd.h" + #if USBH_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) #define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) @@ -107,11 +111,14 @@ void usbhObjectInit(USBHDriver *usbh) { } void usbhInit(void) { +#if HAL_USBH_USE_FTDI + usbhftdiInit(); +#endif +#if HAL_USBH_USE_MSD + usbhmsdInit(); +#endif #if HAL_USBH_USE_HUB - uint8_t i; - for (i = 0; i < HAL_USBHHUB_MAX_INSTANCES; i++) { - usbhhubObjectInit(&USBHHUBD[i]); - } + usbhhubInit(); #endif usbh_lld_init(); } @@ -128,7 +135,6 @@ void usbhStart(USBHDriver *usbh) { osalSysUnlock(); } - void usbhStop(USBHDriver *usbh) { //TODO: implement (void)usbh; @@ -181,6 +187,22 @@ static void _ep0_object_init(usbh_device_t *dev, uint16_t wMaxPacketSize) { usbhEPSetName(&dev->ctrl, "DEV[CTRL]"); } +bool usbhEPResetS(usbh_ep_t *ep) { + osalDbgCheckClassS(); + osalDbgCheck(ep != NULL); + osalDbgAssert((ep->status == USBH_EPSTATUS_OPEN) || (ep->status == USBH_EPSTATUS_HALTED), "invalid state"); + osalDbgAssert(ep->type != USBH_EPTYPE_CTRL, "don't need to reset control endpoint"); + + usbh_urbstatus_t ret = usbhControlRequest(ep->device, + USBH_STANDARDOUT(USBH_REQTYPE_ENDPOINT, USBH_REQ_CLEAR_FEATURE, 0, ep->address | (ep->in ? 0x80 : 0x00)), + 0, 0); + + /* TODO: GET_STATUS to see if endpoint is still halted */ + if ((ret == USBH_URBSTATUS_OK) && usbh_lld_ep_reset(ep)) { + return HAL_SUCCESS; + } + return HAL_FAILED; +} /*===========================================================================*/ /* URB API. */ @@ -258,7 +280,6 @@ bool _usbh_urb_abortI(usbh_urb_t *urb, usbh_urbstatus_t status) { _usbh_urb_completeI(urb, status); return TRUE; -// case USBH_URBSTATUS_QUEUED: case USBH_URBSTATUS_PENDING: return usbh_lld_urb_abort(urb, status); } @@ -271,11 +292,18 @@ void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status) { if (_usbh_urb_abortI(urb, status) == FALSE) { uwarn("URB wasn't aborted immediately, suspend"); osalThreadSuspendS(&urb->abortingThread); - urb->abortingThread = 0; - } else { + osalDbgAssert(urb->abortingThread == 0, "maybe we should uncomment the line below"); + //urb->abortingThread = 0; + } +#if !(USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_WARNINGS) + else { osalOsRescheduleS(); } +#else uwarn("URB aborted"); + osalOsRescheduleS(); /* debug printing functions call I-class functions inside + which may cause a priority violation without this call */ +#endif } bool usbhURBCancelI(usbh_urb_t *urb) { @@ -295,9 +323,9 @@ msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout) { switch (urb->status) { case USBH_URBSTATUS_INITIALIZED: case USBH_URBSTATUS_PENDING: -// case USBH_URBSTATUS_QUEUED: ret = osalThreadSuspendTimeoutS(&urb->waitingThread, timeout); - urb->waitingThread = 0; + osalDbgAssert(urb->waitingThread == 0, "maybe we should uncomment the line below"); + //urb->waitingThread = 0; break; case USBH_URBSTATUS_OK: @@ -408,7 +436,7 @@ usbh_urbstatus_t usbhControlRequest(usbh_device_t *dev, uint16_t wLength, uint8_t *buff) { - const USBH_DEFINE_BUFFER(usbh_control_request_t, req) = { + USBH_DEFINE_BUFFER(const usbh_control_request_t req) = { bmRequestType, bRequest, wValue, @@ -511,7 +539,7 @@ bool usbhStdReqGetInterface(usbh_device_t *dev, uint8_t bInterfaceNumber, uint8_t *bAlternateSetting) { - USBH_DEFINE_BUFFER(uint8_t, alt); + USBH_DEFINE_BUFFER(uint8_t alt); usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GET_INTERFACE(bInterfaceNumber), 1, &alt); if (ret != USBH_URBSTATUS_OK) @@ -720,7 +748,7 @@ static bool _device_enumerate(usbh_device_t *dev) { #if USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_INFO void usbhDevicePrintInfo(usbh_device_t *dev) { - USBH_DEFINE_BUFFER(char, str[64]); + USBH_DEFINE_BUFFER(char str[64]); usbh_device_descriptor_t *const desc = &dev->devDesc; uinfo("----- Device info -----"); @@ -934,7 +962,7 @@ static void _port_connected(usbh_port_t *port) { uint8_t i; uint8_t retries; usbh_devspeed_t speed; - USBH_DEFINE_BUFFER(usbh_string_descriptor_t, strdesc); + USBH_DEFINE_BUFFER(usbh_string_descriptor_t strdesc); uinfof("Port %d connected, wait debounce...", port->number); @@ -1313,9 +1341,11 @@ static bool _classdriver_load(usbh_device_t *dev, uint8_t class, success: /* Link this driver to the device */ - drv->next = dev->drivers; - dev->drivers = drv; - drv->dev = dev; + if (!drv->dev) { + drv->next = dev->drivers; + dev->drivers = drv; + drv->dev = dev; + } return HAL_SUCCESS; } diff --git a/os/hal/src/usbh/hal_usbh_debug.c b/os/hal/src/usbh/hal_usbh_debug.c index 51ca166..497aa39 100644 --- a/os/hal/src/usbh/hal_usbh_debug.c +++ b/os/hal/src/usbh/hal_usbh_debug.c @@ -17,15 +17,13 @@ #include "hal.h" -#if HAL_USE_USBH +#if HAL_USE_USBH && USBH_DEBUG_ENABLE #include "ch.h" #include "usbh/debug.h" #include <stdarg.h> #include "chprintf.h" -#if USBH_DEBUG_ENABLE - #define MAX_FILLER 11 #define FLOAT_PRECISION 9 #define MPRINTF_USE_FLOAT 0 @@ -472,8 +470,8 @@ void usbDbgSystemHalted(void) { } } -static void usb_debug_thread(void *p) { - USBHDriver *host = (USBHDriver *)p; +static void usb_debug_thread(void *arg) { + USBHDriver *host = (USBHDriver *)arg; uint8_t state = 0; chRegSetThreadName("USBH_DBG"); @@ -531,6 +529,5 @@ void usbDbgInit(USBHDriver *host) { iqObjectInit(&USBH_DEBUG_USBHD.iq, USBH_DEBUG_USBHD.dbg_buff, sizeof(USBH_DEBUG_USBHD.dbg_buff), 0, 0); chThdCreateStatic(USBH_DEBUG_USBHD.waDebug, sizeof(USBH_DEBUG_USBHD.waDebug), NORMALPRIO, usb_debug_thread, &USBH_DEBUG_USBHD); } -#endif #endif diff --git a/os/hal/src/usbh/hal_usbh_desciter.c b/os/hal/src/usbh/hal_usbh_desciter.c index 63137d4..48d9d87 100644 --- a/os/hal/src/usbh/hal_usbh_desciter.c +++ b/os/hal/src/usbh/hal_usbh_desciter.c @@ -134,22 +134,18 @@ void cs_iter_next(generic_iterator_t *ics) { if ((curr[0] < 2) || (rem < 2) || (rem < curr[0])) return; - //for (;;) { - rem -= curr[0]; - curr += curr[0]; + rem -= curr[0]; + curr += curr[0]; - if ((curr[0] < 2) || (rem < 2) || (rem < curr[0])) - return; - - if ((curr[1] == USBH_DT_INTERFACE_ASSOCIATION) - || (curr[1] == USBH_DT_INTERFACE) - || (curr[1] == USBH_DT_CONFIG) - || (curr[1] == USBH_DT_ENDPOINT)) { - return; - } + if ((curr[0] < 2) || (rem < 2) || (rem < curr[0])) + return; - // break; - //} + if ((curr[1] == USBH_DT_INTERFACE_ASSOCIATION) + || (curr[1] == USBH_DT_INTERFACE) + || (curr[1] == USBH_DT_CONFIG) + || (curr[1] == USBH_DT_ENDPOINT)) { + return; + } ics->valid = 1; ics->rem = rem; diff --git a/os/hal/src/usbh/hal_usbh_ftdi.c b/os/hal/src/usbh/hal_usbh_ftdi.c index 4bd7296..12ed0f9 100644 --- a/os/hal/src/usbh/hal_usbh_ftdi.c +++ b/os/hal/src/usbh/hal_usbh_ftdi.c @@ -16,7 +16,6 @@ */ #include "hal.h" -#include "hal_usbh.h" #if HAL_USBH_USE_FTDI @@ -114,8 +113,7 @@ static usbh_baseclassdriver_t *_ftdi_load(usbh_device_t *dev, const uint8_t *des if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_INTERFACE)) return NULL; - const usbh_interface_descriptor_t * const ifdesc = (const usbh_interface_descriptor_t * const)descriptor; - if (ifdesc->bInterfaceNumber != 0) { + if (((const usbh_interface_descriptor_t *)descriptor)->bInterfaceNumber != 0) { uwarn("FTDI: Will allocate driver along with IF #0"); } @@ -324,7 +322,7 @@ static usbh_urbstatus_t _ftdi_port_control(USBHFTDIPortDriver *ftdipp, osalDbgCheck(bRequest < sizeof_array(bmRequestType)); osalDbgCheck(bRequest != 1); - const USBH_DEFINE_BUFFER(usbh_control_request_t, req) = { + USBH_DEFINE_BUFFER(const usbh_control_request_t req) = { bmRequestType[bRequest], bRequest, wValue, @@ -387,7 +385,7 @@ static usbh_urbstatus_t _set_baudrate(USBHFTDIPortDriver *ftdipp, uint32_t baudr if (ftdipp->ftdip->dev->basicConfigDesc.bNumInterfaces > 1) wIndex = (wIndex << 8) | (ftdipp->ifnum + 1); - const USBH_DEFINE_BUFFER(usbh_control_request_t, req) = { + USBH_DEFINE_BUFFER(const usbh_control_request_t req) = { USBH_REQTYPE_VENDOR | USBH_REQTYPE_OUT | USBH_REQTYPE_DEVICE, FTDI_COMMAND_SETBAUD, wValue, @@ -714,4 +712,14 @@ void usbhftdipObjectInit(USBHFTDIPortDriver *ftdipp) { ftdipp->state = USBHFTDIP_STATE_STOP; } +void usbhftdiInit(void) { + uint8_t i; + for (i = 0; i < HAL_USBHFTDI_MAX_INSTANCES; i++) { + usbhftdiObjectInit(&USBHFTDID[i]); + } + for (i = 0; i < HAL_USBHFTDI_MAX_PORTS; i++) { + usbhftdipObjectInit(&FTDIPD[i]); + } +} + #endif diff --git a/os/hal/src/usbh/hal_usbh_hub.c b/os/hal/src/usbh/hal_usbh_hub.c index 56257b2..15c3534 100644 --- a/os/hal/src/usbh/hal_usbh_hub.c +++ b/os/hal/src/usbh/hal_usbh_hub.c @@ -15,10 +15,7 @@ limitations under the License. */ -#include <string.h> #include "hal.h" -#include "hal_usbh.h" -#include "usbh/internal.h" #if HAL_USBH_USE_HUB @@ -28,6 +25,7 @@ #include <string.h> #include "usbh/dev/hub.h" +#include "usbh/internal.h" #if USBHHUB_DEBUG_ENABLE_TRACE #define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) @@ -63,7 +61,7 @@ USBHHubDriver USBHHUBD[HAL_USBHHUB_MAX_INSTANCES]; -usbh_port_t USBHPorts[HAL_USBHHUB_MAX_PORTS]; +static usbh_port_t USBHPorts[HAL_USBHHUB_MAX_PORTS]; static usbh_baseclassdriver_t *hub_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); static void hub_unload(usbh_baseclassdriver_t *drv); @@ -290,9 +288,18 @@ void usbhhubObjectInit(USBHHubDriver *hubdp) { memset(hubdp, 0, sizeof(*hubdp)); hubdp->info = &usbhhubClassDriverInfo; } + +void usbhhubInit(void) { + uint8_t i; + for (i = 0; i < HAL_USBHHUB_MAX_INSTANCES; i++) { + usbhhubObjectInit(&USBHHUBD[i]); + } +} + #else #if HAL_USE_USBH +#include <string.h> void _usbhub_port_object_init(usbh_port_t *port, USBHDriver *usbh, uint8_t number) { memset(port, 0, sizeof(*port)); port->number = number; diff --git a/os/hal/src/usbh/hal_usbh_msd.c b/os/hal/src/usbh/hal_usbh_msd.c index 7a4f826..0f02e03 100644 --- a/os/hal/src/usbh/hal_usbh_msd.c +++ b/os/hal/src/usbh/hal_usbh_msd.c @@ -16,7 +16,6 @@ */ #include "hal.h" -#include "hal_usbh.h" #if HAL_USBH_USE_MSD @@ -91,8 +90,8 @@ const usbh_classdriverinfo_t usbhmsdClassDriverInfo = { static usbh_baseclassdriver_t *_msd_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) { int i; USBHMassStorageDriver *msdp; - uint8_t luns; // should declare it here to eliminate 'control bypass initialization' warning - usbh_urbstatus_t stat; // should declare it here to eliminate 'control bypass initialization' warning + uint8_t luns; + usbh_urbstatus_t stat; if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_INTERFACE)) return NULL; @@ -157,7 +156,7 @@ alloc_ok: /* read the number of LUNs */ uinfo("Reading Max LUN:"); - USBH_DEFINE_BUFFER(uint8_t, buff[4]); + USBH_DEFINE_BUFFER(uint8_t buff[4]); stat = usbhControlRequest(dev, USBH_CLASSIN(USBH_REQTYPE_INTERFACE, MSD_GET_MAX_LUN, 0, msdp->ifnum), 1, buff); @@ -240,7 +239,7 @@ static void _msd_unload(usbh_baseclassdriver_t *drv) { /* USB Bulk Only Transport SCSI Command block wrapper */ -PACKED_STRUCT { +typedef PACKED_STRUCT { uint32_t dCBWSignature; uint32_t dCBWTag; uint32_t dCBWDataTransferLength; @@ -253,9 +252,8 @@ PACKED_STRUCT { #define MSD_CBWFLAGS_D2H 0x80 #define MSD_CBWFLAGS_H2D 0x00 - /* USB Bulk Only Transport SCSI Command status wrapper */ -PACKED_STRUCT { +typedef PACKED_STRUCT { uint32_t dCSWSignature; uint32_t dCSWTag; uint32_t dCSWDataResidue; @@ -299,7 +297,7 @@ typedef struct { /* Request sense */ #define SCSI_CMD_REQUEST_SENSE 0x03 -PACKED_STRUCT { +typedef PACKED_STRUCT { uint8_t byte[18]; } scsi_sense_response_t; @@ -333,7 +331,7 @@ PACKED_STRUCT { /* Inquiry */ #define SCSI_CMD_INQUIRY 0x12 -PACKED_STRUCT { +typedef PACKED_STRUCT { uint8_t peripheral; uint8_t removable; uint8_t version; @@ -349,14 +347,14 @@ PACKED_STRUCT { /* Read Capacity 10 */ #define SCSI_CMD_READ_CAPACITY_10 0x25 -PACKED_STRUCT { +typedef PACKED_STRUCT { uint32_t last_block_addr; uint32_t block_size; } scsi_readcapacity10_response_t; /* Start/Stop Unit */ #define SCSI_CMD_START_STOP_UNIT 0x1B -PACKED_STRUCT { +typedef PACKED_STRUCT { uint8_t op_code; uint8_t lun_immed; uint8_t res1; @@ -682,7 +680,7 @@ bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) { USBH_DEFINE_BUFFER(union { scsi_inquiry_response_t inq; - scsi_readcapacity10_response_t cap; }, u); + scsi_readcapacity10_response_t cap; } u); uinfo("INQUIRY..."); res = scsi_inquiry(lunp, &u.inq); @@ -936,4 +934,13 @@ void usbhmsdObjectInit(USBHMassStorageDriver *msdp) { osalMutexObjectInit(&msdp->mtx); } +void usbhmsdInit(void) { + uint8_t i; + for (i = 0; i < HAL_USBHMSD_MAX_INSTANCES; i++) { + usbhmsdObjectInit(&USBHMSD[i]); + } + for (i = 0; i < HAL_USBHMSD_MAX_LUNS; i++) { + usbhmsdLUNObjectInit(&MSBLKD[i]); + } +} #endif diff --git a/os/various/fatfs_bindings/fatfs.mk b/os/various/fatfs_bindings/fatfs.mk new file mode 100644 index 0000000..238037e --- /dev/null +++ b/os/various/fatfs_bindings/fatfs.mk @@ -0,0 +1,7 @@ +# FATFS files. +FATFSSRC = ${CHIBIOS_CONTRIB}/os/various/fatfs_bindings/fatfs_diskio.c \ + ${CHIBIOS}/os/various/fatfs_bindings/fatfs_syscall.c \ + ${CHIBIOS}/ext/fatfs/src/ff.c \ + ${CHIBIOS}/ext/fatfs/src/option/unicode.c + +FATFSINC = ${CHIBIOS}/ext/fatfs/src diff --git a/os/various/fatfs_bindings/fatfs_diskio.c b/os/various/fatfs_bindings/fatfs_diskio.c new file mode 100644 index 0000000..6949310 --- /dev/null +++ b/os/various/fatfs_bindings/fatfs_diskio.c @@ -0,0 +1,320 @@ +/*-----------------------------------------------------------------------*/ +/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */ +/*-----------------------------------------------------------------------*/ +/* This is a stub disk I/O module that acts as front end of the existing */ +/* disk I/O modules and attach it to FatFs module with common interface. */ +/*-----------------------------------------------------------------------*/ + +#include "hal.h" +#include "ffconf.h" +#include "diskio.h" +#include "usbh/dev/msd.h" + +#if HAL_USE_MMC_SPI && HAL_USE_SDC +#error "cannot specify both MMC_SPI and SDC drivers" +#endif + +#if HAL_USE_MMC_SPI +extern MMCDriver MMCD1; +#elif HAL_USE_SDC +extern SDCDriver SDCD1; +#elif HAL_USBH_USE_MSD + +#else +#error "MMC_SPI, SDC or USBH_MSD driver must be specified" +#endif + +/*-----------------------------------------------------------------------*/ +/* Correspondence between physical drive number and physical drive. */ +#if HAL_USE_MMC_SPI +#define MMC 0 +#endif + +#if HAL_USE_SDC +#define SDC 0 +#endif + +#if HAL_USBH_USE_MSD +#if defined(MMC) || defined(SDC) +#define MSDLUN0 1 +#else +#define MSDLUN0 0 +#endif +#endif + +/*-----------------------------------------------------------------------*/ +/* Inidialize a Drive */ + +DSTATUS disk_initialize ( + BYTE pdrv /* Physical drive nmuber (0..) */ +) +{ + DSTATUS stat; + + switch (pdrv) { +#if HAL_USE_MMC_SPI + case MMC: + stat = 0; + /* It is initialized externally, just reads the status.*/ + if (blkGetDriverState(&MMCD1) != BLK_READY) + stat |= STA_NOINIT; + if (mmcIsWriteProtected(&MMCD1)) + stat |= STA_PROTECT; + return stat; +#elif HAL_USE_SDC + case SDC: + stat = 0; + /* It is initialized externally, just reads the status.*/ + if (blkGetDriverState(&SDCD1) != BLK_READY) + stat |= STA_NOINIT; + if (sdcIsWriteProtected(&SDCD1)) + stat |= STA_PROTECT; + return stat; +#endif +#if HAL_USBH_USE_MSD + case MSDLUN0: + stat = 0; + /* It is initialized externally, just reads the status.*/ + if (blkGetDriverState(&MSBLKD[0]) != BLK_READY) + stat |= STA_NOINIT; + return stat; +#endif + } + return STA_NOINIT; +} + + + +/*-----------------------------------------------------------------------*/ +/* Return Disk Status */ + +DSTATUS disk_status ( + BYTE pdrv /* Physical drive nmuber (0..) */ +) +{ + DSTATUS stat; + + switch (pdrv) { +#if HAL_USE_MMC_SPI + case MMC: + stat = 0; + /* It is initialized externally, just reads the status.*/ + if (blkGetDriverState(&MMCD1) != BLK_READY) + stat |= STA_NOINIT; + if (mmcIsWriteProtected(&MMCD1)) + stat |= STA_PROTECT; + return stat; +#elif HAL_USE_SDC + case SDC: + stat = 0; + /* It is initialized externally, just reads the status.*/ + if (blkGetDriverState(&SDCD1) != BLK_READY) + stat |= STA_NOINIT; + if (sdcIsWriteProtected(&SDCD1)) + stat |= STA_PROTECT; + return stat; +#endif +#if HAL_USBH_USE_MSD + case MSDLUN0: + stat = 0; + /* It is initialized externally, just reads the status.*/ + if (blkGetDriverState(&MSBLKD[0]) != BLK_READY) + stat |= STA_NOINIT; + return stat; +#endif + } + return STA_NOINIT; +} + + + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ + +DRESULT disk_read ( + BYTE pdrv, /* Physical drive nmuber (0..) */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Sector address (LBA) */ + UINT count /* Number of sectors to read (1..255) */ +) +{ + switch (pdrv) { +#if HAL_USE_MMC_SPI + case MMC: + if (blkGetDriverState(&MMCD1) != BLK_READY) + return RES_NOTRDY; + if (mmcStartSequentialRead(&MMCD1, sector)) + return RES_ERROR; + while (count > 0) { + if (mmcSequentialRead(&MMCD1, buff)) + return RES_ERROR; + buff += MMCSD_BLOCK_SIZE; + count--; + } + if (mmcStopSequentialRead(&MMCD1)) + return RES_ERROR; + return RES_OK; +#elif HAL_USE_SDC + case SDC: + if (blkGetDriverState(&SDCD1) != BLK_READY) + return RES_NOTRDY; + if (sdcRead(&SDCD1, sector, buff, count)) + return RES_ERROR; + return RES_OK; +#endif +#if HAL_USBH_USE_MSD + case MSDLUN0: + /* It is initialized externally, just reads the status.*/ + if (blkGetDriverState(&MSBLKD[0]) != BLK_READY) + return RES_NOTRDY; + if (usbhmsdLUNRead(&MSBLKD[0], sector, buff, count)) + return RES_ERROR; + return RES_OK; +#endif + } + return RES_PARERR; +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ + +#if _USE_WRITE +DRESULT disk_write ( + BYTE pdrv, /* Physical drive nmuber (0..) */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Sector address (LBA) */ + UINT count /* Number of sectors to write (1..255) */ +) +{ + switch (pdrv) { +#if HAL_USE_MMC_SPI + case MMC: + if (blkGetDriverState(&MMCD1) != BLK_READY) + return RES_NOTRDY; + if (mmcIsWriteProtected(&MMCD1)) + return RES_WRPRT; + if (mmcStartSequentialWrite(&MMCD1, sector)) + return RES_ERROR; + while (count > 0) { + if (mmcSequentialWrite(&MMCD1, buff)) + return RES_ERROR; + buff += MMCSD_BLOCK_SIZE; + count--; + } + if (mmcStopSequentialWrite(&MMCD1)) + return RES_ERROR; + return RES_OK; +#elif HAL_USE_SDC + case SDC: + if (blkGetDriverState(&SDCD1) != BLK_READY) + return RES_NOTRDY; + if (sdcWrite(&SDCD1, sector, buff, count)) + return RES_ERROR; + return RES_OK; +#endif +#if HAL_USBH_USE_MSD + case MSDLUN0: + /* It is initialized externally, just reads the status.*/ + if (blkGetDriverState(&MSBLKD[0]) != BLK_READY) + return RES_NOTRDY; + if (usbhmsdLUNWrite(&MSBLKD[0], sector, buff, count)) + return RES_ERROR; + return RES_OK; +#endif + } + return RES_PARERR; +} +#endif /* _USE_WRITE */ + + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ + +#if _USE_IOCTL +DRESULT disk_ioctl ( + BYTE pdrv, /* Physical drive nmuber (0..) */ + BYTE cmd, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + switch (pdrv) { +#if HAL_USE_MMC_SPI + case MMC: + switch (cmd) { + case CTRL_SYNC: + return RES_OK; + case GET_SECTOR_SIZE: + *((WORD *)buff) = MMCSD_BLOCK_SIZE; + return RES_OK; +#if _USE_ERASE + case CTRL_ERASE_SECTOR: + mmcErase(&MMCD1, *((DWORD *)buff), *((DWORD *)buff + 1)); + return RES_OK; +#endif + default: + return RES_PARERR; + } +#elif HAL_USE_SDC + case SDC: + switch (cmd) { + case CTRL_SYNC: + return RES_OK; + case GET_SECTOR_COUNT: + *((DWORD *)buff) = mmcsdGetCardCapacity(&SDCD1); + return RES_OK; + case GET_SECTOR_SIZE: + *((WORD *)buff) = MMCSD_BLOCK_SIZE; + return RES_OK; + case GET_BLOCK_SIZE: + *((DWORD *)buff) = 256; /* 512b blocks in one erase block */ + return RES_OK; +#if _USE_ERASE + case CTRL_ERASE_SECTOR: + sdcErase(&SDCD1, *((DWORD *)buff), *((DWORD *)buff + 1)); + return RES_OK; +#endif + default: + return RES_PARERR; + } +#endif +#if HAL_USBH_USE_MSD + case MSDLUN0: + switch (cmd) { + case CTRL_SYNC: + return RES_OK; + case GET_SECTOR_COUNT: + *((DWORD *)buff) = MSBLKD[0].info.blk_num; + return RES_OK; + case GET_SECTOR_SIZE: + *((WORD *)buff) = MSBLKD[0].info.blk_size; + return RES_OK; +#if _USE_ERASE +#error "unimplemented yet!" +// case CTRL_ERASE_SECTOR: +// .... +// return RES_OK; +#endif + default: + return RES_PARERR; + } +#endif + } + return RES_PARERR; +} +#endif /* _USE_IOCTL */ + +DWORD get_fattime(void) { +#if HAL_USE_RTC + RTCDateTime timespec; + + rtcGetTime(&RTCD1, ×pec); + return rtcConvertDateTimeToFAT(×pec); +#else + return ((uint32_t)0 | (1 << 16)) | (1 << 21); /* wrong but valid time */ +#endif +} + + |