Посылка данных от USB Mass Storage Device

Тема в разделе "WASM.ELECTRONICS", создана пользователем Lecko, 19 окт 2011.

  1. Lecko

    Lecko Андрей

    Публикаций:
    0
    Регистрация:
    20 дек 2010
    Сообщения:
    60
    Всем привет!

    Имеется устройство на базе МК LPC2478, которое при подключении к компьютеру определяется как Mass Storage Device. Имеется код, который по специальной команде (отличающейся от стандартной команды чтения) должен послать 512 байт из массива. Вот код

    Код (Text):
    1. BYTE * buffer=(BYTE * )malloc(sizeof(BYTE)*512);
    2. DWORD res;
    3. BYTE i=0,j=0;  
    4. CSW.dDataResidue = 512;            
    5. BulkStage=MSC_BS_DATA_IN;
    6. fill(0,buffer,135,1);//заполняем массив
    7. while(CSW.dDataResidue>0)
    8. {
    9.     delayMs(0,1);
    10.     USB_WriteEP(MSC_EP_IN, (BYTE*)&mci_buffer[i*64],64);                   
    11.     CSW.dDataResidue-=64;
    12.     i++;
    13. }
    14. BulkStage = MSC_BS_DATA_IN_LAST;
    15. CSW.bStatus = CSW_CMD_PASSED;              
    16. free(mci_buffer);
    В таком виде код работает. Однако если удалить строчку
    Код (Text):
    1. delayMs(0,1);
    , то передача не проходит. Насколько я понимаю, для отработки функции USB_WriteEP требуется какое-то время.

    Код функции USB_WriteEP взят из стандартной библиотеки Keil
    Код (Text):
    1. DWORD USB_WriteEP (DWORD EPNum, BYTE *pData, DWORD cnt) {
    2.   DWORD n;
    3.  
    4.   USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
    5.  
    6.   TX_PLENGTH = cnt;
    7.  
    8.   for (n = 0; n < (cnt + 3) / 4; n++) {
    9.     TX_DATA = *((__packed DWORD *)pData);
    10.     pData += 4;
    11.   }
    12.   USB_CTRL = 0;
    13.  
    14.   WrCmd(CMD_SEL_EP(EPAdr(EPNum)));
    15.   WrCmd(CMD_VALID_BUF);
    16.   return (cnt);
    17. }
    Вопрос: можно ли как-то отследить состояние выполнения записи на endpoint (например, через какой-нибудь регистр) и в этом ли вообще дело? Или, выражаясь по-другому, как избавиться от функции задержки?
     
  2. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Lecko
    Для начало надо понимать подсистему USB. Кто инициирует запрос на получения данных? ага тотоже ... Когда функта отработает os_evt_wait_or(USB_EVT_IN, 0xFFFF); Тогда вы можете смело и красиво посылать данные ... Конечно извените но ваш код это убитый высер. (( сорри ахахахаха. Так как если хост подвиснит команды перестанут опять таки отправлятся.
     
  3. Lecko

    Lecko Андрей

    Публикаций:
    0
    Регистрация:
    20 дек 2010
    Сообщения:
    60
    1) данный код вызывается по соответствующему прерыванию, просто в листинге я этого не привел.
    2) как я уже писал выше, при установки задержки в 1 мс на каждый пакет код работает. Вопрос заключался в том, зачем эта задержка нужна и как от нее избавиться
     
  4. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Прерывание какое? вам нужно события прочекать что хост готов получать данные... Хотя конечно время отправки тоже какое то есть , но должно входить в write.

    Вот тут можно покопать:
    http://developerarm7.googlecode.com/svn-history/r2/trunk/NXP/Project/USB_UVC_LPC/
    http://read.pudn.com/downloads135/ebook/574089/USBHIDkeyboard20080805/USBHID/usbuser.c__.htm
     
  5. Lecko

    Lecko Андрей

    Публикаций:
    0
    Регистрация:
    20 дек 2010
    Сообщения:
    60
    спасибо, заработало! Главная идея в том, что перед отправкой очередной порции байт нужно проверять, закончилась ли отправка предыдущей и готов ли хост к приему - соответствующие байты в регистре RX_DATA