USB HID Tanışma faslının bittiğini nasıl anlıyoruz

Başlatan z, 01 Temmuz 2012, 18:43:56

z

PCye bağlı USB HID cihazımız, PC den gelen sorguları cevaplıyor ve nihayetinde PC bağlanan cihazı her şeyiyle tanıyor ve artık bu donanımı yazılımlar kullanabilir hale geliyor.

Enumeration işlemi ardından HID descriptor de istendikten sonra USB tarafındaki yazılımım PC tarafında kullanıcı yazılımı varmı sorusuna cevap aramak için karşıya bir şeyler yolluyor ve cevap bekliyor. (Parola soruyor)

Fakat bu işlem eğer işletim sistemi hala USB cihazdan bir şeyler isteme aşamasına rastlarsa USB cihaz sorunlu tanınabiliyor ve device managerda bu HID cihazın başında sarı ünlem oluşmasına neden olabiliyor. Bu durum nadir de olsa oluyor.

Çözüm olarak zaman geçikmesi koymak hoşuma gitmiyor. Mesela PC HID descriptörü istedikten sonra 2 sn bekle ondan sonra karşıda yazılım varmı yokmu diye veri yolla şeklinde çözümü beğenmiyorum.

Sorum: USB tarafındaki yazılım, kendisinin işletim sistemi tarafından bir daha rahatsız edilmeyeceğini (sorgulanmayacağını) nasıl bilebilir.

Not: PC yazılımımla hem kontrol hem de interrupt transferi yapıyorum.
Acaba yanlışım burada mı? Kontrol transferi hiç kullanmamalımıyım?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

t2

Normal çalışan hid cihazlarda control ve interrupt transfer ikisi de mevcuttur. tanışma kısmı galiba control transfer ile oluyor.

carirt

bence interrupt transferi yeterli ack ile verinin doğru gidip gitmediği belli oluyor interrupt transferinde hangi mcu ve hangi yazılımı kullanıyorsunuz

ErsinErce

Device State "Configured" yapıldığında enumeration tamamlanmış oluyor hocam,
bu noktadan sonra veri aktarımına başlayabilirsiniz

z

Configured State

A logical thing to believe is that a USB device cannot be used until it is configured, that is, put into the configured state. As far as the device is concerned, the procedure to do this may be as trivial as writing something other than a "zero" to the device's configuration register. It is up to the host software to set the configuration to something that the device can actually use. As you'll see later, the device keeps a list of valid configurations from which the host can choose.

Setting a device to either its default configuration or one of the valid alternative configurations essentially causes the configuration of the device (and everything within the device) to revert to default values. This is important, because the host software must contain enough intelligence to "know" that it must reset whatever values it was using at the time it decided to change the state of the device.

mesaj birleştirme:: 02 Temmuz 2012, 01:50:47

Alıntı yapılan: carirt - 01 Temmuz 2012, 21:52:55
bence interrupt transferi yeterli ack ile verinin doğru gidip gitmediği belli oluyor interrupt transferinde hangi mcu ve hangi yazılımı kullanıyorsunuz

Islemci olarak TI-LM3S  serisini,  yazilim olarak da Delphi'de JEDI komponentini kullaniyorum.


mesaj birleştirme:: 03 Temmuz 2012, 03:05:00

SetConfiguration komutu ile tanışma faslının biteceğini umuyordum ama yanılmışım.

Device state configured durumu nasıl oluyor konusuna açıklık getirecek dokumanınız varmı?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ErsinErce


atioky_216

Biraz alakasız ancak bir şey sormak isterim;
Bu zamana kadar USB işlerde hep usb chip kullandım (FTDI, MCP, TI3410 vs..) onlarda sınıf olarak CDC yada (diğer sınıfı unuttum) oluyor. Onlarla denetleyici haberleştirmesi felan yaptım. Bu HID cihazlar ise içinde donanımsal USB modulu olan işlemci-denetleyiciler oluyor gördüğüm kadarı ile.

Merak ettiğim PC ye tanıtmak kolay oluyor mu? En basitinden bir sürü gerilim sınıfında çalışıyor işlemciler (3.3v ,5v ,2.7v (bunu net hatırlamıyorum))
Bu durumda PC tarafı usb 5V da çalısıyor, sorun olmuyor mu?. Yada Win7 de mesela baglar bağlamaz tanıyor mu yada driverini bulup kurunca tak- çıkar devamlı görüyor mu?
Gerçi USB protokolunu de hiç bilmiyorum, görse bile oturup onu anlamadan yapılmaz herhalde (UART değil sonuçta :D )

z

MCU içinde USB donanımı varsa bu donanımın PC tarafından ne tip USB aygıt olarak görüneceği yazacağın yazılıma bağlı. (Özellikle de desciptor denilen tablo içeriklerine) Donanımı istediğin türde yapılandırabilirsin. Bunun için USB protokolünün gereklerini bilmen gerekiyor.

USB cihazı HID olarak tanıtmanın avantajı PC tarafında özel driver ihtiyacının olmaması.

CPU nun 3.3V oluşu, USB yi etkilemiyor.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

t2

Hocam yeri gelmişken hid konusundaki araştırmalarınıza istinaden birşey öğrenmek isterim:

Usbli piclerde yazılım sık sık  bazı register ları güncellemek, usb bağlantısını canlı tutmak zorundadır. Bu amaçla ya interrupt  kullanılır ya da döngü içerisinde  uygun bir yerden usbgüncelleme  rutini çağırılır.

Sizin kullandığınız çipperle, bu işin böyle olmadığı, usb durumunun kendiliğinden canlı kaldığı, registere yükle, kendi gitsin tarzında hid uygulama  yapabiliyor muyuz? Data bufferi yüksek olan, FTDI gibi ,kendiliğinden USB ile gönderim yapan  bir proje mümkün mü?

z

Bu zamana kadar hâla USB HID tanışma faslının bitip bitmediğini anlamanın yöntemini öğrenemedim.

Mevcut uygulamamda usb kartım (STM32F103) PC ye peryodik olarak data yolluyor. Ancak çip resetlendikten sonra ne zaman bu dataları yollamaya başlayacak sorusu hâla bir muamma.

Desriptorlerin istenmesini bekliyorum ama işe yaramıyor. Desriptörler isteniyor vs bir bakıyorsunuz bir daha isteniyor.

Şimdilik bu soruna bir çözüm buldum ama hiç hoşuma gitmiyor.

PC tarafındaki yazılım bana ait olduğu için bir paket yolluyorum. Bu ARM işlemcim paket bekliyor ve geldiyse garanti olsun diye de datalara bakıyor. Özel datayı gördüyse haa tamam artık PC'ye verileri gönderebilirim mantığını yürütüyor.

Bu işin profları bu sorunu nasıl çözmüşler?

Alıntı yapılan: t2 - 16 Temmuz 2012, 12:13:12

Usbli piclerde yazılım sık sık  bazı register ları güncellemek, usb bağlantısını canlı tutmak zorundadır. Bu amaçla ya interrupt  kullanılır ya da döngü içerisinde  uygun bir yerden usbgüncelleme  rutini çağırılır.

Sizin kullandığınız çipperle, bu işin böyle olmadığı, usb durumunun kendiliğinden canlı kaldığı, registere yükle, kendi gitsin tarzında hid uygulama  yapabiliyor muyuz? Data bufferi yüksek olan, FTDI gibi ,kendiliğinden USB ile gönderim yapan  bir proje mümkün mü?

PIC ile Usb çalışması yapmadım.  Kendi uygulamalarımda timer int ile USB registerlerinde bazı kritik flagları gözlüyorum. Ancak Int ile de kontrol etmek mümkün.

Yani hiç sorgulama yapmadan Usb int oluştuğunda USB unitesine ne var gene ne oldu demek mümkün.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ErsinErce

#10
Enumeration işlemi bittiğinde cihaz tanınmış ve driver'ı kurulmuş oluyor, hid, custom yapı farketmiyor, class'a bağlı değil yani diye tekrar edelim =)

detaylar;
http://www.google.com/search?q=usb+enumeration

acemi2010

#11
Merhaba
Hocam USB de iyi oldugumu soyleyemem; cok emin olmamakla birlikte goruslerim soyledir:
Cihaz ilk defa PCye takiiliyorsa; PC "yeni aygit algilandi" diye mesaj vererek en uygun driveri arar.Guvenilir eslesme buldugunda ise driveri yukleyerek iletisimine devam eder. Bu ara bu cihaztakildiginda her seferinde driver aranmasin diye cihaz bilgilerini OZELLIKLE PID ve VID yi INF uzantili dosyaya kaydeder.
Siz denemeleriniz sirasinda decriptorlerde degisiklik yapiyorsaniz (PIDyi ve VIDyi degistirmeden !) INF dosyasi icindeki kaydedilmis bazi datalar ile o an cihazdan alinan descriptor datalari arasinda conflict olusturabilir.
Benim kanaatim bu sadece denemelerinize has ve denemeler cercevesinde kalacak bir sorundur.
Cozum ise denemelr sirasinda descriptorlerde degisiklik yaptiginizda PIDyi ve VIDyi simdiye kadar kullanmadiginiz degerlerle degistirmek olabilir. Zira bu durumda PC yeni cihaz olarak algilayip uygun driver arama yoluna gidecektir.

USB Complete kitabinin 9uncu bolumunu incelemekte fayda goruyorum. Bu konuya detayli egilmis Jan amca (ya da teyze)

Saygilarimla
Timucin

EDIT : yanlis anlasilmasin unlem isaretinin bir nedenini aciklamaya calistim

z

Sorum yanlış anlaşılmış olabilir düşüncesiyle problemimi yeniden izah edeyim.

USB bir klavye tasarladığınızı varsayın. Bu klavyenin görevi PC'ye sürekli olarak A harfi yollamak olsun.

Klavyeyi daha doğrusu USB donanımlı işlemcimize enerji verir vermez A yollama rutini devreye girmemelidir.

Öcelikle enumeration işleminin bitmesi gerekir.

Enumeration işlemi biter bitmez artık A harfini peş peşe yollayabiliriz.

Enumeration işleminde PC usbli işlemcimize ha bire istekte bulunuyor. Bana şunu yolla, bana bunu yolla .....

İşlemci de be istekleri cevaplıyor. Ben enumeration ne zaman bitiyor anlayamıyorum. Çünkü control transferi ile istenen bilgiler bitti artık interrupt transferine başlayabilirsin gibi bir muhabbet yok.

Bu soruna çözüm bulamadığım için kendimce yöntem geliştirdim. PC tarafındaki yazılımım enumeration işleminin bitip bitmediğini anlayabiliyor ve bittiğinde karta tamam artık A larını yollayabilirsin şeklinde bilgi gönderiyor. Halbuki buna gerek kalmadan usb işlemcimin buna kendisinin karar verebilmesi lazım.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

t2

PICde USB isteklerinin cevaplandığı bir fonksiyon oluyor. periyodik olarak veya arasıra bunu çağırmak gerekiyor. Zaman aşımı da var. eğer belli süre içinde bu fonksiyon çağırılmaz ise USB bağlantı kesildi demektir.

Bu fonksiyonun detaylarına  baktığımızda, pcden gelen sorguya göre bazı cevaplar iletildiği anlaşılıyor.

veri gönderme işlemi ise ayrı bir şey. eğer yukarıdaki fonksiyonda bir sıkıntı varsa o zaman veri gönderilemiyor. önce sorulan soruya cevap verilmesi gerek. iletişim garanti olsun diye datayı göndermeden önce bu periyodik fonksiyonu yeniden çağırıyoruz. zaten cevaplanacak soru yoksa datayı gönderme işine geçiyoruz.
        USBDeviceTasks(); // Interrupt or polling method.  If using polling, must call
                          // this function periodically.  This function will take care
                          // of processing and responding to SETUP transactions 
                          // (such as during the enumeration process when you first
                          // plug in).  USB hosts require that USB devices should accept
                          // and process SETUP packets in a timely fashion.  Therefore,
                          // when using polling, this function should be called 
                          // regularly (such as once every 1.8ms or faster** [see 
                          // inline code comments in usb_device.c for explanation when
                          // "or faster" applies])  In most cases, the USBDeviceTasks() 
                          // function does not take very long to execute (ex: <100 
                          // instruction cycles) before it returns.


başka bir yerde de şunu yazmış:
BOOL USER_USB_CALLBACK_EVENT_HANDLER(int event, void *pdata, WORD size)
{
    switch( event )
    {
        case EVENT_TRANSFER:
            //Add application specific callback task or callback function here if desired.
            break;
        case EVENT_SOF:
            USBCB_SOF_Handler();
            break;
        case EVENT_SUSPEND:
            USBCBSuspend();
            break;
        case EVENT_RESUME:
            USBCBWakeFromSuspend();
            break;
        case EVENT_CONFIGURED: 
            USBCBInitEP();
            break;
        case EVENT_SET_DESCRIPTOR:
            USBCBStdSetDscHandler();
            break;
        case EVENT_EP0_REQUEST:
            USBCBCheckOtherReq();
            break;
        case EVENT_BUS_ERROR:
            USBCBErrorHandler();
            break;
        case EVENT_TRANSFER_TERMINATED:
            //Add application specific callback task or callback function here if desired.
            //The EVENT_TRANSFER_TERMINATED event occurs when the host performs a CLEAR
            //FEATURE (endpoint halt) request on an application endpoint which was 
            //previously armed (UOWN was = 1).  Here would be a good place to:
            //1.  Determine which endpoint the transaction that just got terminated was 
            //      on, by checking the handle value in the *pdata.
            //2.  Re-arm the endpoint if desired (typically would be the case for OUT 
            //      endpoints).
            break;
        default:
            break;
    }      
    return TRUE; 
}

esensoy

CCS in ya da Microchip in örnek bir usb hid kodu incelenip nerede "Enumarated" bayrağını yaktığına bakılabilir,
CCS için ex_usb_hid.c örnek dosyası içinde boyle bir kod var;
new_enumerated=usb_enumerated();
if (new_enumerated && !last_enumerated)
      uart_printf("\r\n\nUSB enumerated by PC/HOST");

usb_enumarated() ise;
int1 usb_enumerated(void)
{
   return(USB_stack_status.curr_config);
}
şeklinde tanımlanmış,

USB_stack_status.curr_config in eşitliğin solunda bulunduğu ve sıfırdan farklı bir değer alabileceği tek yer de usb.c dosyası içinde ki bu fonksiyonda bulunan en son case,
/**************************************************************
/* usb_isr_tkn_setup_StandardDevice()
/*
/* Input: usb_ep0_rx_buffer[1] == bRequest
/*
/* Summary: bmRequestType told us it was a Standard Device request.
/*          bRequest says which request.  Only certain requests are valid,
/*          if a non-valid request was made then return with an Wrong-Statue (IDLE)
/*
/* Part of usb_isr_tok_setup_dne()
/***************************************************************/
void usb_isr_tkn_setup_StandardDevice(void) {
   switch(usb_ep0_rx_buffer[1]) {

      case USB_STANDARD_REQUEST_GET_STATUS:  //0
            debug_usb(debug_putc,"GS");
            usb_ep0_tx_buffer[0]=USB_stack_status.status_device;
            usb_ep0_tx_buffer[1]=0;
            usb_request_send_response(2);
            break;

      case USB_STANDARD_REQUEST_CLEAR_FEATURE:  //1
            if (usb_ep0_rx_buffer[2] == 1) {
               debug_usb(debug_putc,"CF");
               USB_stack_status.status_device &= 1;
               usb_put_0len_0();
            }
            else
               usb_request_stall();
            break;

      case USB_STANDARD_REQUEST_SET_FEATURE: //3
            if (usb_ep0_rx_buffer[2] == 1) {
               debug_usb(debug_putc,"SF");
               USB_stack_status.status_device |= 2;
               usb_put_0len_0();
            }
            else
               usb_request_stall();
            break;

      case USB_STANDARD_REQUEST_SET_ADDRESS: //5
            debug_usb(debug_putc,"SA");
            USB_stack_status.dev_req=SET_ADDRESS; //currently processing set_address request
            USB_address_pending=usb_ep0_rx_buffer[2];
            #ifdef __USBN__   //NATIONAL part handles this differently than pic16c7x5
            USB_stack_status.dev_req=NONE; //currently processing set_address request
            usb_set_address(USB_address_pending);
            USB_stack_status.curr_config=0;   // make sure current configuration is 0
            #endif
            usb_put_0len_0();
            break;

      case USB_STANDARD_REQUEST_GET_DESCRIPTOR: //6
            debug_usb(debug_putc,"GD");
            usb_Get_Descriptor();
            break;

      case USB_STANDARD_REQUEST_GET_CONFIGURATION: //8
            debug_usb(debug_putc,"GC");
            usb_ep0_tx_buffer[0]=USB_stack_status.curr_config;
            usb_request_send_response(1);
            break;

      case USB_STANDARD_REQUEST_SET_CONFIGURATION: //9
            if (usb_ep0_rx_buffer[2] <= USB_NUM_CONFIGURATIONS) {
               USB_stack_status.curr_config=usb_ep0_rx_buffer[2];
               usb_set_configured(usb_ep0_rx_buffer[2]);
               debug_usb(debug_putc,"SC%U", USB_stack_status.curr_config);               
               usb_put_0len_0();
            }
            break;

      default:
            usb_request_stall();
            break;
   }
}


yani device durumunu host belirliyor ve bunu da device a usb_ep0_rx_buffer[1] ile bildiriyor gibi görülüyor,
En tehlikeli an "zafer" anıdır.