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

 
 
> Рабочий пример работы SL811 в режиме host'a
Hexxx
сообщение Apr 10 2007, 15:14
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 49
Регистрация: 29-03-06
Пользователь №: 15 592



Тема поднималась милион раз, но никто так и не удосужился запостить пример. Значит буду первым:
Код
#define MASTER_MODE             0x80

void SL811_Init(void)
{    
    SL811Write(cDATASet, 0xe0); //SOF Timeout Value
    SL811Write(cSOFcnt, 0x2e | MASTER_MODE);
    SL811Write(CtrlReg, 0x5);            
    SL811Write(EP0Status, PID_SOF);
    SL811Write(EP0Counter, 0);              //Set Endpoint Zero
    SL811Write(EP0Control, 0x01);            //Start the SOF
    SL811Write(IntEna, INSERT_REMOVE);      //USB-A, Insert/Remove, USB_Resume.
    SL811Write(IntStatus, INT_CLEAR);    //Clear Interrupt enable status
    
}

#define NO_ERROR 0
#define ERROR_TIMEOUT 1
#define ERROR_STALL 2
#define ERROR_OVERFLOW 3
#define ERROR_EP0_ERROR 4
#define ERROR_UNKNOWN 5


int SendData(void * pData, int DataSize)
{
  unsigned char result, intr, remainder,timeout;
  SL811BufWrite(EP0_Buf,pData,DataSize);

  SL811Write(EP0Status,(PID_SETUP | 0));  // PID + EP address
  SL811Write(EP0Counter,0);               // USB address
  SL811Write(EP0Address,EP0_Buf);         // buffer address, start with "data0"
  SL811Write(EP0XferLen,DataSize);        // data transfer length
  SL811Write(IntStatus,INT_CLEAR);        // clear interrupt status
  SL811Write(EP0Control,DATA0_WR);  

  timeout=10;
  while(1)
  {
    do
    {                                      
      intr = SL811Read(IntStatus);          // wait for interrupt to be done
      if((intr & USB_RESET) || (intr & INSERT_REMOVE))  //leave if device is removed
        return 1;                  
              
    } while (!(intr & USB_A_DONE)); // interrupt done !!!
  
    SL811Write(IntStatus,INT_CLEAR);         // clear interrupt status
    result = SL811Read(EP0Status);           // read EP0status register
    remainder = SL811Read(EP0Counter);       // remainder value in last pkt xfer
  
    if (result & EP0_ACK)
      return 0;  
    
    if (result & EP0_NAK)                  // NAK Detected
    {                            
        SL811Write(IntStatus,INT_CLEAR);        // clear interrupt status, need to
        SL811Write(EP0Control,DATA0_WR);            // re-arm and request for last cmd, IN token
        result = 0;                                     // respond to NAK status only
    }
    
    if (result & EP0_TIMEOUT)                // TIMEOUT Detected
    {                            
        if(timeout)
        {  
            timeout--;
        }
        else
          return ERROR_TIMEOUT;                    // exit on the timeout detected  
        
        SL811Write(IntStatus,INT_CLEAR);        // clear interrupt status, need to
        SL811Write(EP0Control,DATA0_WR);            // re-arm and request for last cmd again
    }
    
    if (result & EP0_STALL)                  // STALL detected
      return ERROR_STALL;                    // for unsupported request.
    
    if (result & EP0_OVERFLOW)                // OVERFLOW detected
      return ERROR_OVERFLOW;  
    
    if (result & EP0_ERROR)                  // ERROR detected
      return ERROR_EP0_ERROR;
  }
  
  
  return ERROR_UNKNOWN;
}

int GetReply(void * pData, int DataSize)
{
  unsigned char result, intr, remainder,timeout;
  
  SL811Write(EP0Status,(PID_IN | 0));  // PID + EP address
  SL811Write(EP0Counter,0);               // USB address
  SL811Write(EP0Address,EP0_Buf);         // buffer address, start with "data0"
  SL811Write(EP0XferLen,DataSize);        // data transfer length
  SL811Write(IntStatus,INT_CLEAR);        // clear interrupt status
  SL811Write(EP0Control,DATA0_RD);  
  
  timeout=10;
  while(1)
  {
    do
    {                                      
      intr = SL811Read(IntStatus);          // wait for interrupt to be done
      if((intr & USB_RESET) || (intr & INSERT_REMOVE))  //leave if device is removed
        return 1;                  
              
    } while (!(intr & USB_A_DONE)); // interrupt done !!!
  
    SL811Write(IntStatus,INT_CLEAR);         // clear interrupt status
    result = SL811Read(EP0Status);           // read EP0status register
    remainder = SL811Read(EP0Counter);       // remainder value in last pkt xfer
  
    if (result & EP0_ACK)
    {
      if(remainder!=DataSize)              
      {
        SL811BufRead(EP0_Buf, pData, DataSize);
        return 0;
      }
    }
    
    if (result & EP0_NAK)                  // NAK Detected
    {                            
        SL811Write(IntStatus,INT_CLEAR);        // clear interrupt status, need to
        SL811Write(EP0Control,DATA0_WR);            // re-arm and request for last cmd, IN token
        result = 0;                                     // respond to NAK status only
    }
    
    if (result & EP0_TIMEOUT)                // TIMEOUT Detected
    {                            
        if(timeout)
        {  
            timeout--;
        }
        else
          return ERROR_TIMEOUT;                    // exit on the timeout detected  
        
        SL811Write(IntStatus,INT_CLEAR);        // clear interrupt status, need to
        SL811Write(EP0Control,DATA0_WR);            // re-arm and request for last cmd again
    }
    
    if (result & EP0_STALL)                  // STALL detected
      return ERROR_STALL;                    // for unsupported request.
    
    if (result & EP0_OVERFLOW)                // OVERFLOW detected
      return ERROR_OVERFLOW;  
    
    if (result & EP0_ERROR)                  // ERROR detected
      return ERROR_EP0_ERROR;
  }
  
  return ERROR_UNKNOWN;
}

unsigned char Buffer[0x64];
void testSL811(void)
{
  int error;
  SetupPKG pkg;
  pkg.bmRequest=0x80;
  pkg.bRequest=0x06;
  pkg.wValue=0x200;
  pkg.wIndex=0x00;
  pkg.wLength=0xFF00;
  
  SL811ClockInit();
  SL811_Init();
  
  error=SendData(&pkg,sizeof(pkg));
  if (!error)
  {
    error=GetReply(Buffer,0x9);  
  }

}


Код не идеальный, надо доделывать функцию чтения. Он инитит хост в режиме low-speed и позволяет вам послать SETUP пакет GET_DESCRIPTOR и вычитать 9-байтов ответа от Slave устройства. Все нехватающие функции и define есть в cy3662/EZ811 development kit'e. Его можно взять вот тут
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Hexxx
сообщение Apr 19 2007, 14:59
Сообщение #2


Участник
*

Группа: Свой
Сообщений: 49
Регистрация: 29-03-06
Пользователь №: 15 592



И все таки он глючит на чтении. Люди помогите, уже 2 недели бьюсь не могу понять как должно работать чтение. help.gif

Как я делаю:
Инициализирую SL811 в режим Full Speed:
Код
SL811Write(cSOFcnt,0xAE);       // Set up host & full speed direct and SOF cnt
SL811Write(cDATASet,0xE0);      // SOF Counter Low = 0xE0; 1ms interval
SL811Write(CtrlReg,0x05);       // Setup 48MHz and SOF enable

SL811Write(EP0Status,0x50);           // Setup SOF Token, EP0
SL811Write(EP0Counter,0x00);        // reset to zero count
SL811Write(EP0Control,0x01);           // start generate SOF or EOP

SL811Write(IntStatus,INT_CLEAR);


Шлю запрос на получение дескриптора конфигурации:
Код
SL811BufWrite(EP0_Buf,pData,DataSize);
SL811Write(EP0Status,(PID_SETUP | 0));
SL811Write(EP0Counter,0);               // USB address
SL811Write(EP0Address,EP0_Buf);         // buffer address, start with "data0"
SL811Write(EP0XferLen,DataSize);        // data transfer length
SL811Write(IntStatus,INT_CLEAR);        // clear interrupt status
SL811Write(EP0Control,sDATA0_WR);


Дальше жду пока закончится отправка и читаю статус:

Код
do
{                                      
  intr = SL811Read(IntStatus);          // wait for interrupt to be done
  if((intr & USB_RESET) || (intr & INSERT_REMOVE))  //leave if device is removed
     return ERROR_DISCONNECT;                  
            
} while (!(intr & USB_A_DONE)); // interrupt done !!!
  
SL811Write(IntStatus,INT_CLEAR);         // clear interrupt status
status = SL811Read(EP0Status);           // read EP0status register


Возращается (status & EP0_ACK)==EP0_ACK. Т.е. с отправкой все ok.

Далее читаю ответ. Я в снифере на компе поглядел, что должно прийти 0x43 байта. Размер EP0_Buf= 0x40 байт. Поэтому пытаюсь читать 0x40 байт:
Код
SL811Write(EP0Status, (PID_IN | 0));  // PID + EP address
SL811Write(EP0Counter, 0);               // USB address
SL811Write(EP0Address, EP0_Buf);         // buffer address, start with "data0"

if (ReqProc.BufferSize > 0x40)
  SL811Write(EP0XferLen, 0x40);
else
  SL811Write(EP0XferLen,BufferSize);        // data transfer length
  
SL811Write(IntStatus, INT_CLEAR);        // clear interrupt status
SL811Write(EP0Control, sDATA0_RD);


Снова жду результата:

Код
do
{                                      
  intr = SL811Read(IntStatus);          // wait for interrupt to be done
  if((intr & USB_RESET) || (intr & INSERT_REMOVE))  //leave if device is removed
     return ERROR_DISCONNECT;                  
            
} while (!(intr & USB_A_DONE)); // interrupt done !!!
  
SL811Write(IntStatus,INT_CLEAR);         // clear interrupt status
status = SL811Read(EP0Status);           // read EP0status register


Опять возращается (status & EP0_ACK)==EP0_ACK. Т.е. вроде как прочитало.

Читаю сколько там осталось дочитать:
Код
remainder = SL811Read(EP0Counter);


remainder = 0x30, получается что недочитано 0x30 байт! Что делать дальше? Как их дочитать? Почему оно их недочитало? В примере из EZ811 DK они вообще такие пакеты скипают.

Пробовал ради интереса прочитать то что лежит в EP0_Buf. Там лежит 0x10 байт, правильных, таких же как я видел в снифере на компе, а дальше мусор.

Еще в примере из EZ811 DK они зачем-то переключают буферы когда читают большой кусок, зачем?
И последнее, что такое payload? Как его определяют?
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Hexxx   Рабочий пример работы SL811 в режиме host'a   Apr 10 2007, 15:14
- - Hexxx   Я понял как заставить работать пример из EZ811 DK...   Apr 18 2007, 17:28
- - Hexxx   Так странно, куча людей. У многих уже проблемы с в...   Apr 20 2007, 11:51
- - Hexxx   Отвечает Александр Друзь! Payload - это масим...   Apr 23 2007, 12:40
- - Hexxx   Эпопея продолжается. Bulk-transfer не пашет. Отпра...   May 3 2007, 13:07
|- - misyachniy   Не знаю что и посоветовать. У меня был затык в том...   May 3 2007, 16:06
- - Hexxx   А меня опять оказался баг с переключением DATA0/DA...   May 4 2007, 12:08
- - Hexxx   Начал пробовать подключать разные устройства. Кто-...   May 7 2007, 08:32
- - Hexxx   А вообще когда проставляется TIMEOUT?   May 7 2007, 13:49
- - Hexxx   ап   May 8 2007, 13:41
|- - Ailinor   Я решил так: int Read(unsigned char *buff) { ...   May 10 2007, 15:18
- - Hexxx   Я тут тоже по этому вопросу мучаю разных людей. Од...   May 11 2007, 13:17
- - Hexxx   Кое-что еще выяснилось на счет таймаутов. Если де...   May 17 2007, 05:05
- - Hexxx   А фишка оказалась была в том, что я не делал SetAd...   Jun 18 2007, 12:58


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

 


RSS Текстовая версия Сейчас: 20th August 2025 - 09:54
Рейтинг@Mail.ru


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