Все прочитали, вроде даже поняли, взяли паяльник - а нифига не получается? Скорее сюда! Поможем. Чем можем...
Ответить

1986ВЕ1 и запрос USB SET_ADDRESS

Ср май 24, 2017 11:44:18

Работаю с контроллером 1986ВЕ1QI и USB.
Не могу понять, должен ли что-то device программно отвечать на запрос хоста SET_ADDRESS (0x00, 0x05, ...)? Или это должно поддерживаться на аппаратном уровне?
Инициализация устройства застревает именно на этом этапе, т.е. первую отсылку дескриптора (запрос 0х80, 0х06, ...) оно вроде как проходит.
Использую лишь некоторые части кода библиотеки, т.к. целиком она тащит за собой кучу всего. По этой причине инициализацию пишу поэтапно, и вот на адресе застрял.
Я знаю, что адрес фактически должен меняться только после ответа на GET_STATUS, но что делать на этапе SET_ADDRESS, чтобы оно дальше пошло?

Подскажите, пожалуйста, пол-дня над этой строчкой думаю.

Спойлерvoid USB_IRQHandler (void) {

if (MDR_USB->SIS & RESET_EV) //ñáðîñ USB
{

MDR_USB->SIS=0x1F; //Clear Interrupt Status
MDR_USB->SIM=RESET_IE | TDONE_IE | (USB_SOF_EVENT ? SOF_IE : 0); //Enable interrupts
//Setup Control Endpoint 0
MDR_USB->USB_SEP_FIFO[0].RXFC=1; //Clear RX FIFO EndPoint 0
MDR_USB->USB_SEP_FIFO[0].TXFDC=1; //Clear TX FIFO EndPoint 0
MDR_USB->USB_SEP[0].CTRL=EP_EN | EP_RDY; //Enable Endpoint 0, go to endpoint redy state

//Çàäàåì àäðåñ óñòðîéñòâà (ïåðâîíà÷àëüíî 0 - äëÿ ïîñëåäóþùåãî íàçíà÷åíèÿ)
USB_SetSA(0x00); //Ñáðîñ àäðåñà äëÿ îòâåòà íà øèðîêîâåùàòåëüíûå ïàêåòû

MDR_USB->SIS |=RESET_EV; //î÷èñòêà ôëàãà ñáðîñà
}

if (MDR_USB->SIS & TDONE_EV) //ïðîøëà òðàíçàêöèÿ
{
int num;
MDR_USB->SIS |=TDONE_EV; //î÷èñòêà ôëàãà çàâåðøåíèÿ òðàíçàêöèè
for (num=0; num<USB_EP_NUM; num++) //Ïðîâåðêà äàííûõ â êîíå÷íûõ òî÷êàõ
{
if ((MDR_USB->USB_SEP[num].CTRL &EP_EN)&&(!(MDR_USB->USB_SEP[num].CTRL &EP_RDY)))
//Ïî çàâåðøåíèè òðàíçàêöèè òî÷êà áóäåò íå ãîòîâà
break;
}

while (MDR_USB->USB_SEP[num].STS &0x0F) //îáðàáîòêà îøèáîê
{
//if error ocured
if (MDR_USB->USB_SEP[num].STS &RXO_ERR)
{
//USB_Error_Event(1);
MDR_USB->USB_SEP[num].STS &= ~RXO_ERR;
}
else
{
//USB_Error_Event(0);
MDR_USB->USB_SEP[num].STS &= ~0x0F;
}
}

int val=MDR_USB->USB_SEP[num].TS; //Ïðîâåðêà òèïà òðàíçàêöèè
Endpoint(val);
}

}

void Endpoint(int t_type) {
switch (t_type) {

case SETUP: //Óñòàíîâî÷íàÿ òðàíçàêöèÿ
USB_ReadEP (0, InData);
break;

case RESAVE: //Õîñò ïåðåäàåò äàííûå
USB_ReadEP (0, InData);
break;

case TRANSMIT: //Õîñò îæèäàåò äàííûå
USB_ReadEP (0, InData);
if (InData[0]==0x80 && InData[1]==0x06) //Îòïðàâêà äåñêðèïòîðà
USB_WriteEP(0, DESC1, 64);
if (InData[0]==0x00 && InData[1]==0x05) //Ïîëó÷åíèå àäðåñà
{
DEV_adr = InData[2];
MDR_USB->USB_SEP_FIFO[0].RXFC=1; //Î÷èñòêà ïðèåìíîãî áóôåðà è ãîòîâíîñòü
MDR_USB->USB_SEP[0].CTRL |= EP_RDY;
}
if (InData[0]==0x80 && InData[1]==0x00) //Îòïðàâêà ñòàòóñà è íàçíà÷åíèå àäðåñà óñòðîéñòâà
{
USB_WriteEP(0, STATUS, 2);
USB_SetSA(DEV_adr);
}
break;

default: break;

}


}

Re: 1986ВЕ1 и запрос USB SET_ADDRESS

Пт май 26, 2017 13:16:37

Разобрался. Почему-то в литературе не пишут, что STATUS-фаза установки адреса и запрос GET_STATUS - совсем разные вещи. Хоть назвали бы по-разному...
Прикол в том, что SET_ADDRESS - это по факту два пакета.
Один приходит с токеном SETUP, и на него нужно ответить пакетом с нулевой длиной (или просто разрешить работу оконечной точки).
Второй пакет приходит с токеном IN, как раз на него нужно ответить двумя байтами статуса, и именно после него сменить адрес на назначенный хостом.

Надеюсь, кому-то это поможет.
Ответить