Разработка USB устройств
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Razuvaev 28 марта 2006 г. 22:09

Здравствуйте, позвольте обратиться к Вам с вопросом, касающимся разработки USB устройств.
Наш прибор передаёт и принимает от хоста данные по Универсальной Последовательной Шине, но
возникает некорректная ситуация при чтении данных непосредственно после записи их в
устройство. Прибор принимает данные от хоста и записывает их в буфер, из того же буфера
данные передаются хосту, т.о. информационный канал оказывается закольцованным. Мы
записываем данные в схему и ожидаем от неё в точности те же самые данные, но получаем не то.
прибор передаёт сначала содержимое буфера, существовавшее до момента записи, т.е. данные,
которые, по идее, должны были быть замещены новыми, а затем при повторных операциях чтения
мы всё-таки получаем то, что записали. Чтобы было понятнее привожу конкретный пример.
1) получаем от устройства 5 байт со значениями, соответственно 01, 02, 03, 04, 05
(сколько бы мы ни читали, получаем всё ту же последовательность, это правильно);
2) записываем в устройство 5 байт со значениями, соответственно 09, 18, 27, 36, 25
(сейчас начнётся непредвиденное);
3) получаем от устройства 5 байт со значениями, соответственно 01, 02, 03, 04, 05;
(вот он - предмет нашего вопроса);
4) получаем от устройства 5 байт со значениями, соответственно 09, 18, 27, 36, 25;
(сколько бы мы ни читали, получаем всё ту же последовательность, это правильно).
В общем, суть проблемы в том, что мы получаем неактуальные данные, на момент приёма
их уже не должно существовать.
Интересно, что, если сразу после включения прибора, данные записать, а потом прочитать,
то всё работает правильно. Из этого наблюдения вполне можно заключить, что неполадка
происходит при операции чтения. Непонятно, что мы сделали не так. Привожу технические
данные нашего проекта.

Мы используем интерфейсную микросхему PDIUSBD12 фирмы Philips и микроконтроллер AVR
ATmega16. Работаем с USB 1.0 в полноскоростном режиме. Тип передаваемых данных - массив.
Программное обеспечение: WinDriver v6.02 Jungo (c) 1998 - 2003 Win32, Build Date:
May 20 2003.
Программа для микроконтроллера разрабатывается в среде AVRCodeVision. Вот фрагмент кода:

void D12GetIRQ(void); //прерывание от PDIUSBD12
{
unsigned char Irq[2];

// delay_us(70);
D12CmdDataRead(D12_READ_INTERRUPT_REGISTER, Irq, 2);

if (Irq[0] & D12_INT_BUS_RESET) {
CtlTransferInProgress=PROGRESS_IDLE;
}
else
{
if (Irq[0] & D12_INT_EP_CONTROL_IN) ProcessControlInInterrupt();
if (Irq[0] & D12_INT_EP_CONTROL_OUT) ProcessControlOutInterrupt();
if (Irq[0] & D12_INT_EP1_IN) ProcessEndp1InInterrupt();
if (Irq[0] & D12_INT_EP_MAIN_OUT) ProcessMainOutInterrupt();

//Наша процедура прийма данных
if (Irq[0] & D12_INT_EP1_OUT) ProcessEndp1OutInterrupt();
//Наша процедура отправки данных
if (Irq[0] & D12_INT_EP_MAIN_IN) ProcessMainInInterrupt();
}
}

//Приёмник

void ProcessEndp1OUTInterrupt(void)
{
unsigned char *result;
D12CmdDataRead(D12_LAST_TRANS_POINT1_OUT, result, 1);

/*if (DeviceConfigured==1) {
bytenum=D12ReadEndpoint(D12_ENDPOINT_POINT1_OUT,x);

//x - массив из 4-х байт

};
*/
}

//Передатчик

void ProcessMainInInterrupt(void) {
unsigned char *result;
D12CmdDataRead(D12_LAST_TRANS_POINT2_IN, result, 1);


if (DeviceConfigured==1) {

D12WriteEndpoint(D12_ENDPOINT_POINT2_IN,x,5);

};

}

//Процедура для чтения данных из буфера схемы PDIUSBD12

unsigned char D12ReadEndpoint(unsigned char Endpoint, unsigned char *Buffer)
{
unsigned char header[2];
unsigned char BufferStatus = 0;
/* Check if Buffer is Full */
// do
// {
D12CmdDataRead(Endpoint, &BufferStatus, 1);
// } while ((BufferStatus & 0x01)!=1);
if (BufferStatus & 0x01)
{
/* Read dummy header - D12 buffer pointer is incremented on each read */
/* and is only reset by a Select Endpoint Command */
D12CmdDataRead(D12_READ_BUFFER, header, 2);
if(header[1]) D12DataRead(Buffer, header[1]);
/* Allow new packets to be accepted */
D12CmdWrite(D12_CLEAR_BUFFER);
}
return header[1];
}

//Процедура для записи данных в буфер схемы PDIUSBD12

void D12WriteEndpoint(unsigned char Endpoint, unsigned char *Buffer, unsigned char Bytes)
{
unsigned char header[2];
unsigned char BufferStatus = 0;
// do
// {
// D12CmdDataRead(Endpoint,&BufferStatus,1);
// } while (BufferStatus & 0x01);

header[0] = 0x00;
header[1] = Bytes;
/* Select Endpoint */
D12CmdDataRead(Endpoint, &BufferStatus, 1);

if ((BufferStatus & 0x01)==0)
{

/* Write Header */
D12CmdDataWrite(D12_WRITE_BUFFER, header, 2);
/* Write Packet */
if (Bytes) D12DataWrite(Buffer, Bytes);
/* Validate Buffer */
D12CmdWrite(D12_VALIDATE_BUFFER);

}

}


Для отладки мы воспользовались программой SnoopyPro, которая проследила трафик и выдала
следующий LOG-файл:






GET_DESCRIPTOR_FROM_DEVICE

0

-1





CONTROL_TRANSFER

0

-1

1



32

0902200001010080320904000002ffff02000705010241000107058202410001







SELECT_CONFIGURATION

0

-1





SELECT_CONFIGURATION

63

-1





GET_DESCRIPTOR_FROM_DEVICE

63

-1





CONTROL_TRANSFER

63

-1

1



18

120110010000001071046606000001000001







SELECT_INTERFACE

63

-1





SELECT_INTERFACE

125

-1





SELECT_INTERFACE

125

-1





SELECT_INTERFACE

188

-1





BULK_OR_INTERRUPT_TRANSFER

84203

-1

1



5

0b16212c37







BULK_OR_INTERRUPT_TRANSFER

84203

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

87985

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

87985

-1

1



5

0b16212c37







BULK_OR_INTERRUPT_TRANSFER

92266

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

92266

-1

1



5

0b16212c37







BULK_OR_INTERRUPT_TRANSFER

125813

-1

1



5

131d27313b







BULK_OR_INTERRUPT_TRANSFER

125813

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

130188

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

130188

-1

1



5

0b16212c37







BULK_OR_INTERRUPT_TRANSFER

133391

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

133391

-1

1



5

131d27313b







BULK_OR_INTERRUPT_TRANSFER

136719

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

136719

-1

1



5

131d27313b







BULK_OR_INTERRUPT_TRANSFER

158031

-1

1



5

121c26303a







BULK_OR_INTERRUPT_TRANSFER

158031

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

173172

-1

1



5

111b252f39







BULK_OR_INTERRUPT_TRANSFER

173172

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

175985

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

175985

-1

1



5

131d27313b







BULK_OR_INTERRUPT_TRANSFER

178735

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

178735

-1

1



5

111b252f39







BULK_OR_INTERRUPT_TRANSFER

180047

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

180047

-1

1



5

111b252f39







BULK_OR_INTERRUPT_TRANSFER

186125

-1

1



5









BULK_OR_INTERRUPT_TRANSFER

186125

-1

1



5

111b252f39



Вот так. Вроде бы и не очень сложно, но работает не так, как хотелось бы. Подскажите, в
чём тут дело. Как добиться нормальной работы устройства?

28.03.06 C уважением Разуваев Юрий Юрьевич

E-mail: RazuvaevYY@mail.ru

Составить ответ  |||  Конференция  |||  Архив

Ответы



Rambler's Top100 Рейтинг@Mail.ru
Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание

E-mail: info@telesys.ru