Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: вопрос по USB
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Понедельник
проинициализировал UDP, запускаю программу, втыкаю шнур USB, пока работаю не по прерываниям, в вайле проверяю флаг RXSETUP, после его установки считываю RXBYTECNT байт (8) из ФИФО, вот они
0x80
0x06
0x00
0x01
0x00
0x00
0x40
0x00
считаю полученный фрейм запросом хоста дескриптора устройства, т.к. размер дескриптора больше макс. размера буфера для нулевой конечной точки, разбиваю дескриптор на 3 части (8 8 2 байта) , записываю первые 8 байт в ФИФО, устанавливаю флаг TXPKTRDY, сбрасываю TXCOMP, жду пока TXPKTRDY == 0, отправляю в ФИФО след. 8 байт, потом оставшиеся 2 байта , вот мой дескриптор :
//! \brief Device descriptor
#define USB_DEVICE_DESCRIPTOR 0x01
//! \brief Interface power descriptor
#define USB_ENDPOINT0_MAXPACKETSIZE 8
//! idVendor - ATMEL Vendor ID
#define USB_VENDOR_ATMEL 0x03EB
//! bcdUSB field - USB 2.0 specification code
#define USB2_00 0x0200
#define USB1_10 0x0110
static const S_usb_device_descriptor sDeviceDescriptor = {

sizeof(S_usb_device_descriptor), // Size of this descriptor in bytes
USB_DEVICE_DESCRIPTOR, // DEVICE Descriptor Type
USB1_10, // USB Specification 2.0
0x00, // Class is specified in the interface descriptor.
0x00, // Subclass is specified in the interface descriptor.
0x00, // Protocol is specified in the interface descriptor.
USB_ENDPOINT0_MAXPACKETSIZE, // Maximum packet size for endpoint zero
USB_VENDOR_ATMEL, // Vendor ID "ATMEL"
0x1234, // Product ID
0x0001, // Device release number
0x01, // Index 1: manufacturer string
0x02, // Index 2: product string
0x03, // Index 3: serial number string
0x01 // One possible configurations
};
система пишет, что обнаружено неизвестное устройство, в диспетчере DEVid = 0000 VENDORid=0000?
винды повторяют посылку запроса дескриптора еще 3 раза, т.е. принимаются пакеты правильно, проблема с отправкой. Намекните, чего я не так делаю ? Спасибо
aaarrr
Цитата(Понедельник @ Oct 3 2007, 15:25) *
записываю первые 8 байт в ФИФО, устанавливаю флаг TXPKTRDY, сбрасываю TXCOMP, жду пока TXPKTRDY == 0, отправляю в ФИФО след. 8 байт, потом оставшиеся 2 байта

По-моему, логика при обработке запроса получается такая:
1. Установить DIR и сбросить RXSETUP
2. Записать 8 байт пакета
3. УстановитьTXPKTRDY
4. Дождаться TXCOMP
5. Записать следующую порцию данных
6. Установить DIR и TXPKTRDY и сбросить TXCOMP
П.п. 4-6 повторяются для оставшихся данных.
Понедельник
Цитата(aaarrr @ Oct 3 2007, 15:52) *
По-моему, логика при обработке запроса получается такая:
1. Установить DIR и сбросить RXSETUP
2. Записать 8 байт пакета
3. УстановитьTXPKTRDY
4. Дождаться TXCOMP
5. Записать следующую порцию данных
6. Установить DIR и TXPKTRDY и сбросить TXCOMP
П.п. 4-6 повторяются для оставшихся данных.

переписал, как вы советовали, теперь зависает на проверке TXCOMP перед отправкой последних 2 байт
aaarrr
Странно: последовательность проверил, все работает нормально.
Выложите код, попробуем разобраться.
Да, и выложите дескриптор в удобочитаемом виде, что такое S_usb_device_descriptor для меня, например, осталось загадкой.
KAlex
Цитата(Понедельник @ Oct 3 2007, 16:38) *
переписал, как вы советовали, теперь зависает на проверке TXCOMP перед отправкой последних 2 байт

Вот кусок, у меня работает.
//*----------------------------------------------------------------------------
//* \fn AT91F_USB_SendData
//* \brief Send Data through the control endpoint
//*----------------------------------------------------------------------------
__arm static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, u_int length){
u_int cpt = 0;
AT91_REG csr;
do { cpt = MIN(length, 8);
length -= cpt;
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXPKTRDY)
if ( pUdp->UDP_ISR & AT91C_UDP_RXSUSP ) return;
while (cpt--) pUdp->UDP_FDR[0] = *pData++;
if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
}
pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
do {
csr = pUdp->UDP_CSR[0];
// Data IN stage has been stopped by a status OUT
if (csr & AT91C_UDP_RX_DATA_BK0) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
return;
}
} while ( !(csr & AT91C_UDP_TXCOMP) );
} while (length);
if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
}
}
Понедельник
Цитата(aaarrr @ Oct 3 2007, 16:56) *
Странно: последовательность проверил, все работает нормально.
Выложите код, попробуем разобраться.
Да, и выложите дескриптор в удобочитаемом виде, что такое S_usb_device_descriptor для меня, например, осталось загадкой.

typedef struct {

unsigned char bLength; //!< Size of this descriptor in bytes
unsigned char bDescriptorType; //!< DEVICE descriptor type
unsigned short bscUSB; //!< USB specification release number
unsigned char bDeviceClass; //!< Class code
unsigned char bDeviceSubClass; //!< Subclass code
unsigned char bDeviceProtocol; //!< Protocol code
unsigned char bMaxPacketSize0; //!< Control endpoint 0 max. packet size
unsigned short idVendor; //!< Vendor ID
unsigned short idProduct; //!< Product ID
unsigned short bcdDevice; //!< Device release number
unsigned char iManufacturer; //!< Index of manu. string descriptor
unsigned char iProduct; //!< Index of prod. string descriptor
unsigned char iSerialNumber; //!< Index of S.N. string descriptor
unsigned char bNumConfigurations; //!< Number of possible configurations

} S_usb_device_descriptor;

char* point;
point = &sDeviceDescriptor;
while(1)
{
value++;
// *AT91C_UDP_CSR |= 0x8000;
while(!(*AT91C_UDP_CSR & 0x4));
len = ((*AT91C_UDP_CSR) >> 16) & 0xFFFF;
for (i = 0; i < len; i++)
{
buf[value][i] = *AT91C_UDP_FDR;
}

*AT91C_UDP_CSR |= 0x80; //set DIR
Delay(10);
*AT91C_UDP_CSR &= 0xFFFFFFFB; //clear RXSETUP
////////////////////////////////////
for(i = 0; i < 8; i++)
{
*AT91C_UDP_FDR = *(point++);// write data to fifo
}
*AT91C_UDP_CSR |= 0x80; //set DIR
*AT91C_UDP_CSR |= 0x10; //set TXPKTRDY

////////////////////////////////////////////////////////////////
while(!(*AT91C_UDP_CSR & 0x1));// wait finish send
*AT91C_UDP_CSR &= 0xFFFFFFFE;//clear TXCOMP
Delay(10);
for(i = 0; i < 8; i++)
{
*AT91C_UDP_FDR = *(point++);// write data to fifo
}
*AT91C_UDP_CSR |= 0x80; //set DIR
Delay(10);
*AT91C_UDP_CSR |= 0x10;//set TXPKTRDY
//*AT91C_UDP_CSR &= 0xFFFFFFFE;//clear TXCOMP
//////////////////////////////
while(!(*AT91C_UDP_CSR & 0x1));// wait finish send
*AT91C_UDP_CSR &= 0xFFFFFFFE;
Delay(10);
for(i = 0; i < 2; i++)
{
*AT91C_UDP_FDR = *(point++);
}
*AT91C_UDP_CSR |= 0x80; //set DIR
Delay(10);
*AT91C_UDP_CSR |= 0x10; //set TXPKTRDY

while(!(*AT91C_UDP_CSR & 0x1));// wait finish send
*AT91C_UDP_CSR &= 0xFFFFFFFE;
}

извините, код пока в таком виде , красоту не наводил, ибо не арбайтен
aaarrr
TXCOMP нужно снимать после установки TXPKTRDY. Обращайте внимание на сноски Warning в DS.
Понедельник
Цитата(aaarrr @ Oct 3 2007, 18:15) *
TXCOMP нужно снимать после установки TXPKTRDY. Обращайте внимание на сноски Warning в DS.


я пробовал и так и эдак, для синхронизации после каждой установки\снятия флага проверял содержимое регистра, никак не работает, отправляет вторую порцию и вистнет на
while(!(*AT91C_UDP_CSR & 0x1));// wait finish send
как будто система не отвечает на 2-ю посылку

блин, и не посмотреть обмен, с эзернетом проще
Понедельник
Цитата(aaarrr @ Oct 3 2007, 18:15) *
TXCOMP нужно снимать после установки TXPKTRDY. Обращайте внимание на сноски Warning в DS.


вот, переписал как советовали, прогоните у себя ,пожалуйста

while(1)
{
value++;
*AT91C_UDP_CSR |= 0x8000;
while(!(*AT91C_UDP_CSR & 0x4));
len = ((*AT91C_UDP_CSR) >> 16) & 0xFFFF;
for (i = 0; i < len; i++)
{
buf[value][i] = *AT91C_UDP_FDR;
}
/***************************************************************/

/***************************************************************/
*AT91C_UDP_CSR |= 0x80; //set DIR
while(!(*AT91C_UDP_CSR & 0x80));// wait
*AT91C_UDP_CSR &= 0xFFFFFFFB; //clear RXSETUP
while((*AT91C_UDP_CSR & 0x04));// wait
////////////////////////////////////
for(i = 0; i < 8; i++)
{
*AT91C_UDP_FDR = *(point++);
}

*AT91C_UDP_CSR |= 0x10; //set TXPKTRDY
while(!(*AT91C_UDP_CSR & 0x10));// wait
*AT91C_UDP_CSR &= 0xFFFFFFFE;//clear TXCOMP
while((*AT91C_UDP_CSR & 0x04));// wait
//////////////////////////////
while(!(*AT91C_UDP_CSR & 0x1));//// *AT91C_UDP_CSR &= 0xFFFFFFFE;
for(i = 0; i < 8; i++)
{
*AT91C_UDP_FDR = *(point++);
}
*AT91C_UDP_CSR |= 0x80; //set DIR
while(!(*AT91C_UDP_CSR & 0x80));// wait
*AT91C_UDP_CSR |= 0x10;//set TXPKTRDY
while(!(*AT91C_UDP_CSR & 0x10));// wait
*AT91C_UDP_CSR &= 0xFFFFFFFE;//clear TXCOMP
while((*AT91C_UDP_CSR & 0x04));// wait
//////////////////////////////
while(!(*AT91C_UDP_CSR & 0x1));// wait finish send <---------- вот здесь зависает !!!!!
for(i = 0; i < 2; i++)
{
*AT91C_UDP_FDR = *(point++);
}
*AT91C_UDP_CSR |= 0x80; //set DIR
while(!(*AT91C_UDP_CSR & 0x80));// wait
*AT91C_UDP_CSR |= 0x10;//set TXPKTRDY
while(!(*AT91C_UDP_CSR & 0x10));// wait
*AT91C_UDP_CSR &= 0xFFFFFFFE;//clear TXCOMP
while((*AT91C_UDP_CSR & 0x04));// wait
while(!(*AT91C_UDP_CSR & 0x1));// wait finish send
*AT91C_UDP_CSR &= 0xFFFFFFFE;
}
aaarrr
Цитата(Понедельник @ Oct 3 2007, 20:19) *
вот, переписал как советовали, прогоните у себя ,пожалуйста

Я бы проверил, не будь код столь откровенно ужасен. Я понимаю, что тестовый проект и т.п., но так писать нельзя.
Работать лучше сразу по прерываниям, обрабатывать ENDBUSRES нужно обязательно - по нему сбрасываются все CSR'ы.

Конструкции типа:
Код
*AT91C_UDP_CSR |= 0x80;      //set DIR
while(!(*AT91C_UDP_CSR & 0x80));// wait

лучше заменить на:
Код
while(!(*AT91C_UDP_CSR & 0x80))
    *AT91C_UDP_CSR |= 0x80;      //set DIR


Возьмите за основу хотя бы usb framework от Atmel - он кривой, конечно, но немного работает.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.