c - STM32 USB OTG HOST Library hangs trying to create file with FatFs -
i trying create file fatfs on usb flash, f_open
call trying read boot sector first time file system mount hangs on function.
dresult disk_read ( byte drv, /* physical drive number (0) */ byte *buff, /* pointer data buffer 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)) { { 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 ); // loop wich create hanging state } if(status == usbh_msc_ok) return res_ok; return res_error; }
the main problem loop wich creates hanging state
while(status == usbh_msc_busy );
so not know avoid this. using debuger discover state caused parameter cmdstatemachine
of structure usbh_msc_botxferparam
, type usbh_botxfer_typedef
equal cmd_uninitialized_state
wich actualy cause miss of switch statement of usbh_msc_read10
function.
/** * @brief usbh_msc_read10 * issue read command device. once response received, * updates status upper layer * @param databuffer : databuffer contain data read * @param address : address data read * @param nbofbytes : nbofbytes read * @retval status */ uint8_t usbh_msc_read10(usb_otg_core_handle *pdev, uint8_t *databuffer, uint32_t address, uint32_t nbofbytes) { uint8_t index; static usbh_msc_status_typedef status = usbh_msc_busy; uint16_t nbofpages; status = usbh_msc_busy; if(hcd_isdeviceconnected(pdev)) { switch(usbh_msc_botxferparam.cmdstatemachine) { case cmd_send_state: /*prepare cbw , relevent field*/ usbh_msc_cbwdata.field.cbwtransferlength = nbofbytes; usbh_msc_cbwdata.field.cbwflags = usb_ep_dir_in; usbh_msc_cbwdata.field.cbwlength = cbw_length; usbh_msc_botxferparam.prxtxbuff = databuffer; for(index = cbw_cb_length; index != 0; index--) { usbh_msc_cbwdata.field.cbwcb[index] = 0x00; } usbh_msc_cbwdata.field.cbwcb[0] = opcode_read10; /*logical block address*/ usbh_msc_cbwdata.field.cbwcb[2] = (((uint8_t*)&address)[3]); usbh_msc_cbwdata.field.cbwcb[3] = (((uint8_t*)&address)[2]); usbh_msc_cbwdata.field.cbwcb[4] = (((uint8_t*)&address)[1]); usbh_msc_cbwdata.field.cbwcb[5] = (((uint8_t*)&address)[0]); /*usbh_msc_page_length = 512*/ nbofpages = nbofbytes/ usbh_msc_page_length; /*tranfer length */ usbh_msc_cbwdata.field.cbwcb[7] = (((uint8_t *)&nbofpages)[1]) ; usbh_msc_cbwdata.field.cbwcb[8] = (((uint8_t *)&nbofpages)[0]) ; usbh_msc_botxferparam.botstate = usbh_msc_send_cbw; /* start transfer, let state machine magage other transactions */ usbh_msc_botxferparam.mscstate = usbh_msc_bot_usb_transfers; usbh_msc_botxferparam.botxferstatus = usbh_msc_busy; usbh_msc_botxferparam.cmdstatemachine = cmd_wait_status; status = usbh_msc_busy; break; case cmd_wait_status: if((usbh_msc_botxferparam.botxferstatus == usbh_msc_ok) && \ (hcd_isdeviceconnected(pdev))) { /* commands sent , response received */ usbh_msc_botxferparam.cmdstatemachine = cmd_send_state; status = usbh_msc_ok; } else if (( usbh_msc_botxferparam.botxferstatus == usbh_msc_fail ) && \ (hcd_isdeviceconnected(pdev))) { /* failure mode */ usbh_msc_botxferparam.cmdstatemachine = cmd_send_state; } else if ( usbh_msc_botxferparam.botxferstatus == usbh_msc_phase_error ) { /* failure mode */ usbh_msc_botxferparam.cmdstatemachine = cmd_send_state; status = usbh_msc_phase_error; } else { /* wait commands completed */ /* no change in state machine */ } break; default: break; } } return status; }
here usbh_botxfer_typedef
type declaration;
typedef struct _botxfer { uint8_t mscstate; uint8_t mscstatebkp; uint8_t mscstatecurrent; uint8_t cmdstatemachine; uint8_t botstate; uint8_t botstatebkp; uint8_t* prxtxbuff; uint16_t datalength; uint8_t botxfererrorcount; uint8_t botxferstatus; } usbh_botxfer_typedef;
during debug discover fields of 0x00.
here fatfs calls
int main(void) { fatfs fat; fil file; fresult fr; rcc->ahb1enr |= rcc_ahb1enr_gpioden; /* enable swo output */ dbgmcu->cr = 0x00000020; gpiod->moder=0x55000000; gpiod->otyper = 0x00000000; gpiod->ospeedr = 0x00000001; while(1) { if (!usb_msc_isinitialized()) { usb_msc_initialize(); } if (usb_msc_isconnected()) { gpiod->odr = (1 << 15); disk_initialize(0); fr = f_mount(0, &fat); if(fr == fr_ok) { fr = f_open(&file,"0:dp_lab8.pdf",(fa_create_always | fa_write)); if (fr == fr_ok) { f_close(&file); } f_mount(0, null); } } else { gpiod->odr = (1 << 14); } usb_msc_main(); } }
usb_msc_isconnected
function is:
int usb_msc_isconnected(void) { if (g_usb_msc_hoststatus == usb_dev_not_supported) { usb_msc_uninitialize(); } return !(g_usb_msc_hoststatus == usb_dev_detached || g_usb_msc_hoststatus == usb_host_no_init || g_usb_msc_hoststatus == usb_dev_not_supported); }
and device states are:
typedef enum { usb_host_no_init = 0, /* usb interface not initialized */ usb_dev_detached, /* no device connected */ usb_speed_error, /* unsupported usb speed */ usb_dev_not_supported, /* unsupported device */ usb_dev_write_protect, /* device write protected */ usb_over_current, /* overcurrent detected */ usb_dev_connected /* device connected , ready */ } usb_hoststatus;
the value of g_usb_msc_hoststatus
received standard usb host user callbacks.
i think bug in st host library. i've hunted down, usb host unable pass enumeration stage. after fix stack ok.
there union _usb_setup
in usbh_def.h file in "stm32cube/repository/stm32cube_fw_f7_v1.13.0/middlewares/st/stm32_usb_host_library/core/inc" (any chip, not f7, version, not v1.13.0). has uint16_t bmrequesttype and uint16_t brequest. these 2 fileds must uint8_t of usb specs. fixing issue made usb host go needed. enumeration stage passes ok, , other stages well.
Comments
Post a Comment