Доброго времени суток!
Помогите решить проблему, я использую для LPC17xx USBHostLite, всё работает, но вот непонятно, почему скорость записи на USB флешку вариируется от 200 до 350 кБайт/сек, хотя комп пишет на неё со скоростью 3 МБайта/сек.
Для контроля работы хоста дёргаю отдельной ножкой контроллера, и смотрю осциллографом. Наблюдается следующая картина:
где-то после 7-10 пакетов (передача буферов по 4096 байт происходит по 8 мс) идёт очень длинное ожидание - около 120 мс. Т.е. ~7-мь пакетов без существенной задержки, потом задержка ~120 мс, и так далее.
Вот код где я смотрю задержки на осциллографе:
в функции Host_ProcessTD перед ожиданием ответа от флехи Host_WDHWait() дёргаю ножкой проца, и в функции MS_BulkSend на втором вызове функции Host_ProcessTD иногда происходит задержка ~100 мс. Как увеличить скорость и откуда такие задержки?
rt_int32_t MS_BulkSend ( rt_uint32_t block_number,
volatile rt_uint8_t *user_buffer,
rt_uint16_t num_blocks)
{
rt_int32_t rc;
Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_OUT, SCSI_CMD_WRITE_10, 10);
rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
if (rc == OK) {
Host_DelayMS(20);
rc = Host_ProcessTD(EDBulkOut, TD_OUT, user_buffer, MS_BlkSize * num_blocks);
if (rc == OK) {
rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
if (rc == OK) {
if (TDBuffer[12] != 0) {
rc = ERR_MS_CMD_FAILED;
}
}
}
}
return (rc);
}
rt_int32_t Host_ProcessTD (volatile HCED *ed,
volatile rt_uint32_t token,
volatile rt_uint8_t *buffer,
rt_uint32_t buffer_len)
{
volatile rt_uint32_t td_toggle;
if (ed == EDCtrl) {
if (token == TD_SETUP) {
td_toggle = TD_TOGGLE_0;
} else {
td_toggle = TD_TOGGLE_1;
}
} else {
td_toggle = 0;
}
TDHead->Control = (TD_ROUNDING |
token |
TD_DELAY_INT(0) |
td_toggle |
TD_CC);
TDTail->Control = 0;
TDHead->CurrBufPtr = (rt_uint32_t) buffer;
TDTail->CurrBufPtr = 0;
TDHead->Next = (rt_uint32_t) TDTail;
TDTail->Next = 0;
TDHead->BufEnd = (rt_uint32_t)(buffer + (buffer_len - 1));
TDTail->BufEnd = 0;
ed->HeadTd = (rt_uint32_t)TDHead | ((ed->HeadTd) & 0x00000002);
ed->TailTd = (rt_uint32_t)TDTail;
ed->Next = 0;
if (ed == EDCtrl) {
LPC_USB->HcControlHeadED = (rt_uint32_t)ed;
LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF;
LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_CLE;
} else {
LPC_USB->HcBulkHeadED = (rt_uint32_t)ed;
LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE;
}
if (DebugValue) LPC_GPIO0->FIOSET = 1<<11;
else LPC_GPIO0->FIOCLR = 1<<11;
DebugValue = !DebugValue;
Host_WDHWait();
// if (!(TDHead->Control & 0xF0000000)) {
if (!HOST_TDControlStatus) {
return (OK);
} else {
return (ERR_TD_FAIL);
}
}