|
Здравствуйте, позвольте обратиться к Вам с вопросом, касающимся разработки 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-файл:
Вот так. Вроде бы и не очень сложно, но работает не так, как хотелось бы. Подскажите, в
чём тут дело. Как добиться нормальной работы устройства?
28.03.06 C уважением Разуваев Юрий Юрьевич
E-mail: RazuvaevYY@mail.ru
E-mail: info@telesys.ru