реклама на сайте
подробности

 
 
> помогите понять usb enumeration, в lpc2368
PriBoris
сообщение Oct 13 2009, 17:29
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 167
Регистрация: 7-10-05
Из: Санкт-Петербург
Пользователь №: 9 352



3 дня бьюсь, не могу ничего понять
физику usb я знаю, раньше успешно сделал функцию на tms5509a
но не могу понять что от меня хочет lpc2368
(среда crossworks)

почему-то весь процесс затыкается после установки адреса (SET_ADDRESS)

(1) я принял SETUP c get descriptor (DEVICE_DESCRIPTOR)
(2) отослал IN c 18 байтами дескриптора
(3) получил пустой OUT
(4) принял SETUP с set address
(5) отослал пустой IN
(6) в прерывании по успешной высылке IN устанавливаю адрес
UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,UsbDeviceAddress+(1<<7));
и на этом все заканчивается
точнее при некоторых условиях через десяток секунд ПК опять спрашивает DEVICE_DESCRIPTOR, но процесс дальше не идет

куда копать не понимаю
событие reset не приходит
по идее у меня какая-то чехарда или недоделка в stall/unstall, но перепробовав кучу вариантов не смог найти работоспособного

посмотрите пожалуйста код
может что-то не так делаю

ниже конспективно код с комментариями
пока обрабочиков прерываний нет, только поллинг

В StartUsb инициализация :
Код
void StartUsb(void)
{
  rUSBClkCtrl=(1<<1)|(1<<4);
  while(1) if ((rUSBClkSt)==((1<<1)|(1<<4))) break;

  rUSBReEp = 0;

  rUSBReEp |= (1<<0); // realize EP0
  rUSBEpInd = 0; // control OUT
  rUSBMaxPSize = 64;
  while(1) if (((rUSBDevIntSt)&(1<<8))==(1<<8)) break;
  rUSBDevIntClr = (1<<8); // EP_RLZED

  rUSBReEp |= (1<<1); // realize EP1
  rUSBEpInd = 1; // control IN
  rUSBMaxPSize = 64;
  while(1) if (((rUSBDevIntSt)&(1<<8))==(1<<8)) break;
  rUSBDevIntClr = (1<<8); // EP_RLZED

  rUSBEpIntPri = 0x00000000;
  rUSBDevIntEn =  (1<<USBDEVINT_TxENDPKT)|
                  (1<<USBDEVINT_RxENDPKT)|
                  (1<<USBDEVINT_DEV_STAT)|
                  (1<<USBDEVINT_EP_SLOW)|
                  (1<<USBDEVINT_ERR_INT);
  rUSBDevIntClr = 0xFFFFFFFF;
  rUSBEpIntEn = (1<<0)|(1<<1);
  rUSBEpIntClr = 0xFFFFFFFF;

  UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,0+0x80);
  UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,0+0x80);

  w0 = UsbReadCommandWord(USB_SIE_COMMAND_ReadTestRegister);
  if (w0 != 0xa50f) while(1);
}


В основном теле опрашиваются события, ошибки, прерывания от точек:
Код
     // check error interrupt
      if ( (UsbDevIntStatus&(1<<USBDEVINT_ERR_INT)) != 0 )
      {
        UsbErrorCode = UsbReadCommandByte( USB_SIE_COMMAND_GetErrorCode );
        UsbErrorStatus = UsbReadCommandByte( USB_SIE_COMMAND_ReadErrorStatus );
        UsbErrorCounter++;
        rUSBDevIntClr = (1<<USBDEVINT_ERR_INT); // ERR_INT
      }
      // check status change event
      if ( (UsbDevIntStatus&(1<<USBDEVINT_DEV_STAT)) != 0 )
      {
        UsbDeviceStatus = UsbReadCommandByte( USB_SIE_COMMAND_GetDeviceStatus );
        if ((UsbDeviceStatus&(1<<3))!=0)
          if ((UsbDeviceStatus&(1<<2))!=0) {/**/};
        if ((UsbDeviceStatus&(1<<4))!=0) { /**/};
        rUSBDevIntClr = (1<<USBDEVINT_DEV_STAT);
      }
      // endpoint interrupt
      if ( (UsbDevIntStatus&(1<<USBDEVINT_EP_SLOW)) != 0 )
      {
        UsbEpIntStatus = rUSBEpIntSt;
        if ( (UsbEpIntStatus&(1<<0))!=0 ) UsbType1ProcessEp0Rx();
        if ( (UsbEpIntStatus&(1<<1))!=0 ) UsbType1ProcessEp0Tx();
        rUSBDevIntClr = (1<<USBDEVINT_EP_SLOW);
      }


Обработчик OUT ep0:
Код
void UsbType1ProcessEp0Rx(void)
{
      UsbCounterEp0Rx++;

      rUSBCtrl = (1<<0)|(0<<2); // RD_EN, LOG_ENDPOINT=0
      UsbRxPacketLength = UsbReadRxPacketLength();
      UsbReadPacket((WORD)UsbRxPacketLength);
      rUSBDevIntClr = (1<<USBDEVINT_RxENDPKT); // RxENDPKT
      rUSBCtrl = 0;
      UsbClearBufferResult = UsbReadCommandByte(USB_SIE_COMMAND_ClearBuffer);
      UsbSelectEndpoint0 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint0);
      rUSBEpIntClr = (1<<0);

          if ( (UsbSelectEndpoint0&(1<<2)) != 0 ) // setup packet
          {
            UsbCounterEp0Setup++;
            UsbSetupMaxLength = *(WORD*)(&(UsbRxPacket[6]));
            switch(*(WORD*)(&(UsbRxPacket[0])) & 0xFF80)
            {
              //-------------------------------------------------------------
              case 0x0680: // get descriptor
                switch(*(WORD*)(&(UsbRxPacket[2])) & 0xFF00)
                {
                  //-------------------------------------------------------------
                  case USB_DEVICE_DESCRIPTOR_TYPE:
                    UsbCounterEp0Setup1++;
                    rUSBCtrl = (1<<1)|(0<<2);
                    UsbSendPacket(_UsbType1DeviceDescriptor,18);
                    rUSBCtrl = 0;
                    UsbWriteCommand(USB_SIE_COMMAND_SelectEndpoint1);
                    UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
                    rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
                    break;
                  //-------------------------------------------------------------
                  case USB_CONFIGURATION_DESCRIPTOR_TYPE:
                    rUSBCtrl = (1<<1)|(0<<2);
                    if (UsbSetupMaxLength>=32)
                      UsbSendPacket(_UsbType1ConfigurationDescriptor,32);
                    else
                      UsbSendPacket(_UsbType1ConfigurationDescriptor,UsbSetupMaxLength);
                    rUSBCtrl = 0;
                    UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
                    UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
                    rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
                    break;
                  //-------------------------------------------------------------
                  case USB_STRING_DESCRIPTOR_TYPE:
                    switch(*(WORD*)(&(UsbRxPacket[2])) & 0x00FF)
                    {
                      case 0:
                        rUSBCtrl = (1<<1)|(0<<2);
                        UsbSendPacket(_UsbLanguage,4);
                        rUSBCtrl = 0;
                        UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
                        UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
                        rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
                        break;
                      case 1:
                        rUSBCtrl = (1<<1)|(0<<2);
                        UsbSendPacket(_UsbStringManufacturer,50);
                        rUSBCtrl = 0;
                        UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
                        UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
                        rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
                        break;
                      case 2:
                        rUSBCtrl = (1<<1)|(0<<2);
                        UsbSendPacket(_UsbStringProduct,50);
                        rUSBCtrl = 0;
                        UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
                        UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
                        rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
                        break;
                      default:
                        UsbStallEp0Rx();
                        UsbStallEp0Tx();
                        break;
                    }
                    break;
                  //-------------------------------------------------------------
                  default:
                    UsbStallEp0Rx();
                    UsbStallEp0Tx();
                    break;
                  //-------------------------------------------------------------
                }
                break;
              //-------------------------------------------------------------
              case 0x0500: // set address
                UsbCounterEp0Setup2++;
//                UsbUnstallEp0Rx();
                UsbUnstallEp0Tx();
                UsbDeviceAddress = 0x7F & (*(WORD*)(&(UsbRxPacket[2])));
                rUSBCtrl = (1<<1)|(0<<2);
                rUSBTxPLen = 0;
                rUSBCtrl = 0;
                rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
                UsbWriteCommand(USB_SIE_COMMAND_SelectEndpoint1);
                UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
                break;
              //-------------------------------------------------------------
              case 0x0900: // set configuration
                UsbUnstallEp0Tx();
                rUSBCtrl = (1<<1)|(0<<2);
                rUSBTxPLen = 0;
                rUSBCtrl = 0;
                UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
                UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
                rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
                UsbConfigured = 1;
                break;
              //-------------------------------------------------------------
              default:
                UsbStallEp0Rx();
                UsbStallEp0Tx();
                break;
              //-------------------------------------------------------------
            }          
          }
          else // data OUT packet
          {
            UsbCounterEp0Data++;
          }

}


Обработчик IN ep0:
Код
void UsbType1ProcessEp0Tx(void)
{
          UsbCounterEp0Tx++;
          rUSBEpIntClr = (1<<1);
          if (UsbDeviceAddress!=0)
          {
            UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,UsbDeviceAddress+(1<<7));
            UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,UsbDeviceAddress+(1<<7));
            UsbDeviceAddress = 0;
          }
          if (UsbConfigured!=0)
          {
            while(1);
            UsbConfigured=0;
            UsbStatus = USB_STATUS_TYPE1_CONFIGURED;

            UsbWriteCommandByte(USB_SIE_COMMAND_ConfigureDevice,1);
/*... */
          }
}


На всякий случай вспомогательные вещи:
Код
void UsbStallEp0Rx(void){
  UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint0,1);}
void UsbUnstallEp0Rx(void){
  UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint0,0);}
void UsbStallEp0Tx(void){
  UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint1,1);}
void UsbUnstallEp0Tx(void){
  UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint1,0);}


BYTE __attribute__ ((aligned (4))) _UsbType1DeviceDescriptor[18] = {
            0x12,                //;BYTE bLength : 8;
            0x01,                //;BYTE bDescriptorType : 8;
            0x00,0x02,            //;WORD bcdUSB : 16;
            0x00,                //;BYTE bDeviceClass : 8;
            0x00,                //;BYTE bDeviceSubclass : 8;
            0x00,                //;BYTE bDeviceProtocol : 8;
            64,                    //;BYTE bMaxPacketSize : 8;
            0x34,0x12,            //;WORD idVendor : 16;
            0x78,0x56,            //;WORD idProduct : 16;
            0x00,0x00,            //;WORD bcdDevice : 16;
            1,                    //;BYTE iManufacturer : 8;
            2,                    //;BYTE iProduct : 8;
            0,                    //;BYTE iSerialNumber : 8;
            1,                    //;BYTE iNumConfigurations : 8;
};
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 6th July 2025 - 21:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01408 секунд с 7
ELECTRONIX ©2004-2016