USB cihaz ve PC arasındaki tanışma muhabbeti

Başlatan ziyaretci, 23 Eylül 2016, 23:00:13

ziyaretci

 Merhabalar...

  Uzun zamandır 18f4550 dahilindeki USB donanımının PC ile haberleşme sırasındaki istekler, cevaplar vs. hakkında bilgi araştırıp deney yapıyorum. Bazen bu bilgileri anlamak evreni keşfederken bir yıldız bulmakla eşdeğer oluyor. "Her yönüyle USB" kitabı olsun, diğer Türkçe, İngilizce kaynaklar olsun araştırma yapıyor bazı kilit noktaları anlayıp rahat ederken bir sonraki kilit noktada yok oluyorum.

  İlgili protokol çok fazla detay içerdiğinden soru işaretleri arasında çırpınıyorum diyebilirim. Bugün teori ve pratiği bir arada götürmeye karar verdim ve test amaçlı bir devre kurup ilgili kayıtçılardan dahili pull-up dirençlerini, tam hız seçeneğini, donanım birimini aktif ettim. İlk aşamada bilgisayar ekranından bir cihaz bulundu balonunu görmek amacım. Fakat bağladığınız USB cihaz arızalı hatası alıyorum.

  Yine ilgili kaynaklardan USB cihazı bilgisayara bağladığımızda bizden ilk isteğinin "Aygıt tanımlayıcısı(Device descriptor)" olduğunu öğrendim ve 18f4550 datasheet'inde yer alan örnek buffer tanımlaması üzerinde ilgili tanımlamaları yerleştirdim.

#BYTE bLength = 0x500
#BYTE bDescriptorType = 0x501
#BYTE bcdUSB_1 = 0x502  // 2
#BYTE bcdUSB_2 = 0x503
#BYTE bDeviceClass = 0x504
#BYTE bDeviceSubClass = 0x505
#BYTE bDeviceProtocol = 0x506
#BYTE bMaxPacketSize = 0x507
#BYTE idVendor_1 = 0x508 // 2
#BYTE idVendor_2 = 0x509
#BYTE idProduct_1 = 0x50A //2
#BYTE idProduct_2 = 0x50B
#BYTE bcdDevice_1 = 0x50C // 2
#BYTE bcdDevice_2 = 0x50D 
#BYTE iManufacturer = 0x50E
#BYTE iProduct = 0x50F
#BYTE iSerialNumber = 0x510
#BYTE iNumConfigurations = 0x511

 
  Ve adreslere bilgileri yerleştirdim:
   bLength = 18;
bDescriptorType = 0x01;
bcdUSB_1 = 0b00000100;
bcdUSB_2 = 0b00000100;
bDeviceClass = 0x00;
bDeviceSubClass= 0x00;
bDeviceProtocol= 0x00;
bMaxPacketSize = 0x40;
idVendor_1 = 0x11;
idVendor_2 = 0x11;
idProduct_1 = 0x00;
idProduct_2 = 0x11;
bcdDevice_1 = 0b00000100;
bcdDevice_2 = 0b00000100;
iManufacturer =0x00;
iProduct=0x00;
iSerialNumber =0x00;
iNumConfigurations=0x07;

  Ardından dahili 3.3V regülatörünü aktif edip, tam hızı seçip, donanım birimini aktif ettim. Devre üzerinde Vusb ucuna 300nf kondansatör bağladım.
Bilgisayar arızalı cihaz uyarısı veriyor.

 
  Beni anlayan kişilerden cevap istiyorum.

Şu cevap veya benzeri cevapları yazmak isteyenler uğraşmasın:

  • Amerikayı yeniden keşfetmeye ne gerek var.
  • Hazır sürücü kullan boşa vakit harcama
  • USB sürücü mü yazacaksın?
  • Caydırma manası taşıyan her türlü cevap...

Öğrenmek istiyorum.

while(basari==false){
  Pes etmek yok. Her yönüyle USB kitabını tekrar okuyacağım. Ardından tekrar @ahmet Atar'ın(https://320volt.com/usb-hakkinda/5/) yayınladığı kaynağı okuyacağım, datasheet dosyalarını yeniden karıştıracağım.
}
Cihazı bilgisayara taktım;
-USB kayıtçıları üzerinde hangi ayarları yapmam gerekiyor?
-Bigisayarın(Host) istekleri cihaz üzerinde hangi tampona yazılıyor?
-Uç nota nasıl seçilir(bulamadım)?
-....
-...
-..
-.

  Çalıştırdığım kod:

 
#include <S:\PICC\Devices\18F4550.h>

//#device ADC=10
#fuses HSPLL,USBDIV,PLL5,PUT,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOMCLR
/*
#fuses HSPLL,USBDIV,PLL5,CPUDIV1,NOPROTECT,NOWDT,PUT,NOCPD,NOSTVREN,NODEBUG,NOLVP,NOWRT,NOWRTD,NOIESO
#fuses NOFCMEN,NOPBADEN,NOWRTC,NOWRTB,NOEBTR,NOEBTRB,NOCPB,NOMCLR,NOLPT1OSC,NOXINST
#fuses VREGEN,NOICPRT
*/
#use delay(clock=48M)
#include <C:\Users\_Sist\Desktop\USB_\LCD420.C>
#include <C:\Users\_Sist\Desktop\USB_\karakterim.C>


#BYTE UCON  = 0xF6D  // USB CONTROL REGISTER
#BYTE UCFG  = 0xF6F  // USB CONFIGURATION REGISTER
#BYTE USTAT = 0xF6C  // USB STATUS REGISTER
#BYTE UEP0  = 0xF70  // USB ENDPOINT1
#BYTE UIR   = 0xF68  // USB INTERRUPT STATUS REGISTER
#BYTE UIE   = 0xF69  // USB INTERRUPT ENABLE REGISTER
#BYTE UEIR  = 0xF6A  // USB ERROR INTERRUPT STATUS REGISTER
#BYTE UEIE  = 0xF6B  // USB ERROR INTERRUPT ENABLE REGISTER

#BYTE BDSTAT = 0x400
#BYTE BD0CNT = 0x401
#BYTE BD0ADRL= 0x402
#BYTE BD0ADRH= 0x403


#BIT USBEN = UCON.3  // USB IS ACTIVETED
#BIT UPUEN = UCFG.4  // ON-CHIP PULL UP
#BIT FSEN  = UCFG.2  // FULL SPEED, SHOULD BE 48MHZ INPUT

#BIT EPINEN = UEP0.1
#BIT EPCONDIS = UEP0.3



////////////////////////AYGIT TANIMLAYICI ALANI 
#BYTE bLength = 0x500
#BYTE bDescriptorType = 0x501
#BYTE bcdUSB_1 = 0x502  // 2
#BYTE bcdUSB_2 = 0x503
#BYTE bDeviceClass = 0x504
#BYTE bDeviceSubClass = 0x505
#BYTE bDeviceProtocol = 0x506
#BYTE bMaxPacketSize = 0x507
#BYTE idVendor_1 = 0x508 // 2
#BYTE idVendor_2 = 0x509
#BYTE idProduct_1 = 0x50A //2
#BYTE idProduct_2 = 0x50B
#BYTE bcdDevice_1 = 0x50C // 2
#BYTE bcdDevice_2 = 0x50D 
#BYTE iManufacturer = 0x50E
#BYTE iProduct = 0x50F
#BYTE iSerialNumber = 0x510
#BYTE iNumConfigurations = 0x511







///////////////////////////////////////////////////////////////////////////////

VOID MAIN(){
LCD_INIT();
ozel_karakterler(); // Türkçe karakter dosyası
PRINTF(LCD_PUTC,"\fBU BİR TESTTİR.");
bLength = 18;
bDescriptorType = 0x01;
bcdUSB_1 = 0b00000100;
bcdUSB_2 = 0b00000100;
bDeviceClass = 0x00;
bDeviceSubClass= 0x00;
bDeviceProtocol= 0x00;
bMaxPacketSize = 0x40;
idVendor_1 = 0x11;
idVendor_2 = 0x11;
idProduct_1 = 0x00;
idProduct_2 = 0x11;
bcdDevice_1 = 0b00000100;
bcdDevice_2 = 0b00000100;
iManufacturer =0x00;
iProduct=0x00;
iSerialNumber =0x00;
iNumConfigurations=0x07;




DELAY_MS(1000);
OUTPUT_HIGH(PIN_D1);
DELAY_MS(1000); 
OUTPUT_LOW(PIN_D1);
DELAY_MS(1000);
 
BDSTAT = 0x01;
BD0CNT = 0x40;
BD0ADRL=0x00;
BD0ADRH=0x05;

EPCONDIS=1;
EPINEN=1;
FSEN=1;
UPUEN=1; 
USBEN=1;

FOR(;;){
OUTPUT_HIGH(PIN_D1);
DELAY_MS(500);
OUTPUT_LOW(PIN_D1);
DELAY_MS(500);

 }
}

 

Örnek tampon:


İlk istek:


Aygıt tanımlayıcısı:



t2

#1
Alıntı Yap-Uç nota nasıl seçilir(bulamadım).


Buradan :
HID_EP | _EP_IN,            //EndpointAddress


....

#define HID_EP   1

#define _EP_IN      0x80



ziyaretci

Alıntı yapılan: t2 - 23 Eylül 2016, 23:23:17

Buradan :
HID_EP | _EP_IN,            //EndpointAddress


....

#define HID_EP   1

#define _EP_IN      0x80




Hocam cevabınız için teşekkür ederim. Fakat ben aslıda 18f4550 datasheet'inde endpoint seçme kayıtçısını bulamadım.

1--Uç nokta seçme işlemi HOST cihazın bizi tanımak istediği ilk bilgiler(descriptor[device, string vs.]) ile mi seçiliyor acaba?
2--HOST bizden ilk isteği olan "Aygıt tanımlayıcı istek(device descriptor)" bu istek hangi PID numarası ile hangi tampona yerleştiriliyor?
3--Datasheet'in paylaştığı örnek tampona mı bu tanımlamalar yerleştiriliyor?
4--Aygıt tanımlayıcısının BDSTAT istek bilgisi 0x01 'miş, yani ben;
-> 400h adresine 0x01
-> 401h adresine maksimum hızda maksimum paket boyutu 64 yani 0x40
-> 402h ve 403h adresine bu tanımlayıcı bilgilerinin detaylarını barındıracak bilgilerin yüklendiği adres başlangıcını mı yükleyip donanım birimini aktif yapacağım?

Yaptığım son deneylerde;

-Dahili 3.3V regülatörünü aktif yaptım.
-Tam hız seçimini aktifleştirdim.
-PING-PONG tamponlarını tüm endpointler için aktif ettim.
-Ve USBEN yani donanım birimini atağa geçirdim. Usb bağlanır bağlanmaz.
 
  Sonuç: Dahili regülatörü aktif ettiğimde sadece bilgisayar algılama sesi veriyor, ardından "sürücü hatası veya arızalı cihaz" uyarısı veriyor.

Fakat USTAT kaydedicisinde herhangi bir değişim gözlemleyemedim. Ek olarak;
UIR kaydedicisi(USB INTERRUPT STATUS) 'inde aşağıdaki bilgileri okudum.

>>SOFIF(TRUE)[BIT6]: SIE tarafından bir start-of-frame token alınır.
>>STALLIF(FALSE)[BIT5]: Bir stall el sıkışması gönderilemedi.
>>IDLEIF(TRUE)[BIT4]:Boşta(idle) algılama kesme biti yani "Boşta durum algılandı!"
>>TRNIF(FALSE)[BIT3]:Beklenen işlem tamamlanmadı veya beklenen işlem yok.
>>ACTVIF(TRUE)[BIT2]: Hat aktivitesi algılama kesme biti yani D+/D- hatları aktif olarak tespit edildi.
>>UERRIF(FALSE)[BIT1]: USB hata durumu kesme biti yani "Maskesiz bir hata durumu oluşmadı. "
>>URSTIF(TRUE)[BIT0]: Usb reset kesme biti, yani "Geçerli bir USB Reset durumu oluştu; 00h UADDR kaydedicisine yüklendi."

  Şuanda bir iğne olarak samanlığın hangi noktasındayım bilmiyorum. Var mı bir tespitiniz? Teşekkürler.





t2

#3
Sizin umduğunuz gibi işlemiyor olabilir.
Yaptıklarınız nasıl denk gelecek de çalışacak? 

Çalışan yüzlerce örnek var.  Bir tanesini deneyin.  Devre çalışsın

Kodu sonra anlamaya çalışın. En kolayı bu.
http://picforum.ric323.com/viewtopic.php?f=46&t=103#p697

Ayar Descriptor,  ne gerekirse hafızada bir yerlere yüklenir. Host tarafından sorgu gelirse buradan okunur.  Başlangıç ayarları, 
Main içerisindeki  USBinit gibi bir fonksiyon ile olur. Nasıl yapilir? Kod içinden anlaşılabilir. 

Okan AKÇA

Genelde firmalar hazır çevirici entegreler kullaniyorlar. Degilse işin içinden cikilmaz hal aliyor.

ziyaretci

Alıntı yapılan: Okan AKÇA - 25 Eylül 2016, 11:48:29
Genelde firmalar hazır çevirici entegreler kullaniyorlar. değilse işin içinden cikilmaz hal aliyor.

  Bu entegreler usb - rs232 üzerine mi? Varsa isim verebilir misiniz?

t2

#6
Mesaj iptal

ahmetbudak