2014-07-21 11:25 AM
Hello,
I'm currently working with an STM32F215 mcu and I'm attempting to write a test program with the USB-Host-Device Library V.2.1.0. The goal of this test project is to program the STM32F215 as a host controller, and when an MSC USB Device is connected, download the contents and transmit over UART. Inside usbh_usr.c I have written the following code:
int
USBH_USR_MSC_Application(
void
)
{
switch
(msc_state)
{
case
MSC_INIT:
{
printf
(
''Starting download...\r\n''
);
msc_state = MSC_READ;
}
break
;
case
MSC_IDLE:
{
}
break
;
case
MSC_READ:
{
uint32_t sectors_read = 0;
uint8_t buffer[64];
/* Download every available sector */
if
(sectors_read < USBH_MSC_Param.MSCapacity)
{
/* Check if there's enough room in uart buffer */
if
(dl_uart_count() < (BUFFER_SIZE - 64))
{
uint8_t status = USBH_MSC_OK;
/* Queue read command */
status = USBH_MSC_Read10(&USB_OTG_Core,
buffer,
sectors_read,
64);
if
(status == USBH_MSC_OK)
{
printf
(
''Downloaded sector %lu of %lu\r\n''
, sectors_read, USBH_MSC_Param.MSCapacity);
/* Write data to usart */
dl_uart_write(buffer, 64);
/* Set next sector to be read */
sectors_read++;
}
else
if
(status == USBH_MSC_FAIL || status == USBH_MSC_PHASE_ERROR)
{
msc_state = MSC_ERROR;
}
}
}
else
{
printf
(
''Download complete\r\n''
);
msc_state = MSC_IDLE;
}
}
break
;
case
MSC_WRITE:
break
;
case
MSC_ERROR:
printf
(
''Error detected\r\n''
);
msc_state = MSC_IDLE;
break
;
default
:
break
;
}
return
(0);
}
The trouble is, the download never starts, and USBH_MSC_Read10 repeatedly returns USBH_MSC_BUSY. Based on my debugger, it seems like the parameter USBH_MSC_BOTXferParam.CmdStateMachine is constantly stuck at CMD_WAIT_STATUS. I've been reading the documentation as well as digging into the usb 2.0 specification document, but neither seem to be helping much. Is there a delay I need to put in after I queue up the read command? Or an additional command? I've checked the examples and they don't seem to help much either.
Additionally, the code's comments/documentation has been confusing, so I'm not totally sure what the parameters of USBH_MSC_Read10 should be. The first two are self-explanatory, but afterward, is the address the actual address, and is it in terms of bytes or sectors? Also, how can USBH_MSC_Read10 support values larger than wMaxPacketSize if it's using bulk transfers?
#usbhost #stm32 #stm32f3
2014-07-21 12:04 PM
Sectors, are without doubt, not 64 bytes.
You should probably review a SCSI/MMC specification to understand the command structures.2014-07-21 12:23 PM
Yes, I'm well aware that sectors are not 64 bytes. The size of the sectors reported back in the endpoint descriptors is 512 which seems pretty typical. The 64 bytes was a leftover debugging attempt, as I was wondering if requesting a number of bytes greater than the maximum packet size was causing the hang-up.
I don't believe my original question of why the state machine was hanging on CMD_MSC_BUSY was answered though?2014-07-21 01:00 PM
Try to reduce the HCLK frequency 2 or 4 times (increase AHB prescaler in clock configuration).
2014-07-21 01:13 PM
I don't believe my original question of why the state machine was hanging on CMD_MSC_BUSY was answered though?
Indeed, I really don't want to be dragged into your dev work. I'm pretty sure the MSC device doesn't understand the foreshortened transfer, and the stack might not be the best place to situate it. But as I understand it, the routine is supposed to return BUSY while you pump the data transfer, as USBH_MSC_Read10() isn't a blocking call. You might want to review how it's used in a working example. STM32F4-Discovery_FW_V1.1.0\Libraries\STM32_USB_HOST_Library\Class\MSC\src\usbh_msc_fatfs.c/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE drv, /* Physical drive number (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
BYTE status = USBH_MSC_OK;
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if(HCD_IsDeviceConnected(&USB_OTG_Core))
{
do
{
status = USBH_MSC_Read10(&USB_OTG_Core, buff, sector, 512*count);
USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);
if(!HCD_IsDeviceConnected(&USB_OTG_Core))
{
return RES_ERROR;
}
}
while(status == USBH_MSC_BUSY );
}
if(status == USBH_MSC_OK)
return RES_OK;
return RES_ERROR;
}