STM32F4 Discovery Joystick sorunu

Başlatan metaltrrocker, 03 Mart 2014, 15:40:42

metaltrrocker

Arkadaşlar merhaba, yakın bir dostumun bir projesi (Flight Simulator Cockpit) olduğu için kullanıcı tanımlı bir joystick üretirsek buton atamalarını simulatör içerisinden ayarlayıp uçuşa başlarız diye düşündük.Dostum benden rica etti böyle birşey yapabilirmiyiz diye, ben de neden olmasın dedim ve kolları sıvadım.Stm32 discovery, hem adc hem de sayıca fazla bulunan pinler vasıtasıyla ihtiyacı fazlasıyla karşılar düşüncesiyle stm32 kullandım.
Discovery kiti bilgisayara joystick olarak tanıtma kısmını hallettim. Usb.org sitesindeki descriptor yazılımını kullanarak gerekli tanımlamaları yaptım.16 adet buton kullandım. Şimdilik adc ile joystick ekseni kullanımına girmedim.Kodlama kısmında halledemediğim şeyler var.
while(!HID_Write(&writebuff,8)); komutundan önce bilgiyi writebuff dizisine nasıl atamam lazım.Bit olarak atadım ama çalışmadı. Mikroc pic'den kodları çevirdim ve yazdım.Eksik birşeyler mutlaka vardır.Konu açmakta tereddüt ettim.Ancak internette veri tablosunun aşağıdaki gibi olduğunu buldum.
----------------------------------------------------------------------------------
 Byte  |   bit7  |  bit6   |   ....................................... |   bit0  |
----------------------------------------------------------------------------------
   0   |  btn8   |  btn7   |   ...................vs vs..............  |   btn1  |
   1   | btn16   |  btn15  |   ...................vs vs..............  |   btn9  |
----------------------------------------------------------------------------------


Usbdsc.c
const unsigned int USB_VENDOR_ID = 0x1234;
const unsigned int USB_PRODUCT_ID = 0x0007;
const char USB_SELF_POWER = 0x80;            // Self powered 0xC0,  0x80 bus powered
const char USB_MAX_POWER = 50;               // Bus power required in units of 2 mA
const char HID_INPUT_REPORT_BYTES = 64;
const char HID_OUTPUT_REPORT_BYTES = 64;
const char USB_TRANSFER_TYPE = 0x03;         //0x03 Interrupt
const char EP_IN_INTERVAL = 1;
const char EP_OUT_INTERVAL = 1;

const char USB_INTERRUPT = 1;
const char USB_HID_EP = 1;
const char USB_HID_RPT_SIZE = 26;

/* Device Descriptor */
const struct {
    char bLength;               // bLength         - Descriptor size in bytes (12h)
    char bDescriptorType;       // bDescriptorType - The constant DEVICE (01h)
    unsigned int bcdUSB;        // bcdUSB          - USB specification release number (BCD)
    char bDeviceClass;          // bDeviceClass    - Class Code
    char bDeviceSubClass;       // bDeviceSubClass - Subclass code
    char bDeviceProtocol;       // bDeviceProtocol - Protocol code
    char bMaxPacketSize0;       // bMaxPacketSize0 - Maximum packet size for endpoint 0
    unsigned int idVendor;      // idVendor        - Vendor ID
    unsigned int idProduct;     // idProduct       - Product ID
    unsigned int bcdDevice;     // bcdDevice       - Device release number (BCD)
    char iManufacturer;         // iManufacturer   - Index of string descriptor for the manufacturer
    char iProduct;              // iProduct        - Index of string descriptor for the product.
    char iSerialNumber;         // iSerialNumber   - Index of string descriptor for the serial number.
    char bNumConfigurations;    // bNumConfigurations - Number of possible configurations
} device_dsc = {
      0x12,                   // bLength
      0x01,                   // bDescriptorType
      0x0200,                 // bcdUSB
      0x00,                   // bDeviceClass
      0x00,                   // bDeviceSubClass
      0x00,                   // bDeviceProtocol
      8,                      // bMaxPacketSize0
      USB_VENDOR_ID,          // idVendor
      USB_PRODUCT_ID,         // idProduct
      0x0001,                 // bcdDevice
      0x01,                   // iManufacturer
      0x02,                   // iProduct
      0x00,                   // iSerialNumber
      0x01                    // bNumConfigurations
  };

/* Configuration 1 Descriptor */
const char configDescriptor1[]= {
    // Configuration Descriptor
    0x09,                   // bLength             - Descriptor size in bytes
    0x02,                   // bDescriptorType     - The constant CONFIGURATION (02h)
    0x29,0x00,              // wTotalLength        - The number of bytes in the configuration descriptor and all of its subordinate descriptors
    1,                      // bNumInterfaces      - Number of interfaces in the configuration
    1,                      // bConfigurationValue - Identifier for Set Configuration and Get Configuration requests
    0,                      // iConfiguration      - Index of string descriptor for the configuration
    USB_SELF_POWER,         // bmAttributes        - Self/bus power and remote wakeup settings
    USB_MAX_POWER,          // bMaxPower           - Bus power required in units of 2 mA

    // Interface Descriptor
    0x09,                   // bLength - Descriptor size in bytes (09h)
    0x04,                   // bDescriptorType - The constant Interface (04h)
    0,                      // bInterfaceNumber - Number identifying this interface
    0,                      // bAlternateSetting - A number that identifies a descriptor with alternate settings for this bInterfaceNumber.
    2,                      // bNumEndpoint - Number of endpoints supported not counting endpoint zero
    0x03,                   // bInterfaceClass - Class code
    0,                      // bInterfaceSubclass - Subclass code
    0,                      // bInterfaceProtocol - Protocol code
    0,                      // iInterface - Interface string index

    // HID Class-Specific Descriptor
    0x09,                   // bLength - Descriptor size in bytes.
    0x21,                   // bDescriptorType - This descriptor's type: 21h to indicate the HID class.
    0x01,0x01,              // bcdHID - HID specification release number (BCD).
    0x00,                   // bCountryCode - Numeric expression identifying the country for localized hardware (BCD) or 00h.
    1,                      // bNumDescriptors - Number of subordinate report and physical descriptors.
    0x22,                   // bDescriptorType - The type of a class-specific descriptor that follows
    USB_HID_RPT_SIZE,0x00,  // wDescriptorLength - Total length of the descriptor identified above.

    // Endpoint Descriptor
    0x07,                   // bLength - Descriptor size in bytes (07h)
    0x05,                   // bDescriptorType - The constant Endpoint (05h)
    USB_HID_EP | 0x80,      // bEndpointAddress - Endpoint number and direction
    USB_TRANSFER_TYPE,      // bmAttributes - Transfer type and supplementary information    
    0x40,0x00,              // wMaxPacketSize - Maximum packet size supported
    EP_IN_INTERVAL,         // bInterval - Service interval or NAK rate

    // Endpoint Descriptor
    0x07,                   // bLength - Descriptor size in bytes (07h)
    0x05,                   // bDescriptorType - The constant Endpoint (05h)
    USB_HID_EP,             // bEndpointAddress - Endpoint number and direction
    USB_TRANSFER_TYPE,      // bmAttributes - Transfer type and supplementary information
    0x40,0x00,              // wMaxPacketSize - Maximum packet size supported    
    EP_OUT_INTERVAL         // bInterval - Service interval or NAK rate
};

const struct {
  char report[];
}hid_rpt_desc =
  {
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x05, 0x09,                    //     USAGE_PAGE (Button)
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    0x29, 0x10,                    //     USAGE_MAXIMUM (Button 16)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x95, 0x10,                    //     REPORT_COUNT (16)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //     END_COLLECTION
    0xc0                           // END_COLLECTION
  };

//Language code string descriptor
const struct {
  char bLength;
  char bDscType;
  unsigned int string[1];
  } strd1 = {
      4,
      0x03,
      {0x0409}
    };


//Manufacturer string descriptor
const struct{
  char bLength;
  char bDscType;
  unsigned int string[12];
  }strd2={
    26,           //sizeof this descriptor string
    0x03,
    {'P','s','e','f','i','t',' ','G','a','m','e','z'}
  };

//Product string descriptor
const struct{
  char bLength;
  char bDscType;
  unsigned int string[12];
}strd3={
    26,          //sizeof this descriptor string
    0x03,
    {'P','s','e','f','i','t',' ','G','a','m','e','z'}
 };

//Array of configuration descriptors
const char* USB_config_dsc_ptr[1];

//Array of string descriptors
const char* USB_string_dsc_ptr[3];

void USB_Init_Desc(){
  USB_config_dsc_ptr[0] = &configDescriptor1;
  USB_string_dsc_ptr[0] = (const char*)&strd1;
  USB_string_dsc_ptr[1] = (const char*)&strd2;
  USB_string_dsc_ptr[2] = (const char*)&strd3;
}


Usbhid1.c
void main(void)
{
        GPIO_Digital_Input(&GPIOA_IDR, _GPIO_PINMASK_ALL);         // Set PA0 as digital input
        GPIO_Digital_Output(&GPIOD_ODR, _GPIO_PINMASK_ALL);      // Set PORTD as digital output
        HID_Enable(&readbuff,&writebuff);

        while(1)
        {
                //USB 
                while(!HID_Write(&writebuff,16));
        }
        HID_Disable();
}

void USB1Interrupt(void) iv IVT_INT_OTG_FS{
  USB_Interrupt_Proc();
}

metaltrrocker

Projenin 4 butona indirgenmiş halini yükledim, hala algoritmayı kuramadım. --» http://www.mediafire.com/download/uygb5k5ba1br3da/yeni2.rar

metaltrrocker

Sorunu şimdilik çözdüm en azından veriyi okuyabiliyorum artık.
while(!HID_Write(&writebuff,16));

kısmını
writebuff[0]=0x01;
while(!HID_Write(&writebuff,1));

olarak değiştirinece 1 nolu buton çalıştı.asıl bilmediğim şey tablodaki byte ların writebuff dizisindeki elemanlara denk geldiğiydi.Ben writebuff serisinin elemanlarını tek tek bit olarak düşünmüştüm.
yarın 16 adet buton ile deneyeceğim.Adım adım gidecem.Umarım aksilik olmaz.

metaltrrocker

#3
32 Buton olarak çalışan versiyonunu buraya ekliyorum. İlerde ya da mevcut zaman dilimi içerisinde denemek isteyenler olabilir. Descriptor tanımlamalarında 64 adet tuşa izin verildiği halde 32 tanesini kullanabildim. İnternette araştırdığım kadarıyla 32 buton sınırlandırması var. Yanlışım varsa üstadlar düzeltsinler ben de tam emin olamadım. Yabancı kaynaklarda bu şekilde yazıyordu.Bir sonraki adımım, adc leri kullanarak analog çıbıklar eklemek.
Dosya linki --> yeni3(32_buton_çalışıyor).rar
Usb HID ile ilgili güzel bir döküman --> https://www.mediafire.com/?7wn61yslkavkxw2

metaltrrocker

Analog çıbıkları da ekleyip bu projeyi tamamladım.Bilgisayar tarafında Gamepad olarak görünüyor. Projede 32 adet buton, x/y/z eksenleri, x/y/z dönmeleri, throttle(valf)  bulunmaktadır. İşine yarayan olursa buradan dosyalara ulaşıp kurcalayabilir.
Proje linki --> https://www.mediafire.com/?233f65mbxbvb5j2

iqsuz

hocam kodları inceledim fakat kafama takılan bir soru var.

usb_dsc'nin içindekileri sen mi yazdın yoksa mikroc'un içindeki tool'dan mı yaptın?

eğer sen yazdıysan mantığı nedir?

metaltrrocker

http://www.usb.org/developers/hidpage/
sayfanın altındaki HID Descriptor Tool' u kullanarak yazdım. İnternetten joystick icin tanımlı descriptor örneklerine bakarak ve kendi ihtiyaclarıma göre düzenleyerek oluşturdum. İlk mesajlarda butonlardan biraz bahsettim.
usbdsc.c içerisindeki struct larla oynayarak ve string boyutunu ayarlayarak HID ismini değiştirdim. 1-2 başarısız deneme sonrasında çalıştırmayı başardım. Benimki biraz deneme yanılma oldu.
Yukarıda verdiğim linkte detaylı anlatımlar mevcut ingilizcen iyi ise onları da kullanabilirsin.

sequence

Merhaba,

Flight simulator de kullanmak üzere ben de 32 butonlu joystick devresi ile ilgili bilgi arıyordum fakat bir türlü bulamadım. Bu devre ile ilgili şema, devre elemanları ve pic programı gibi bilgileri paylaşabilir misiniz? Gerçekten uzun zamandır aradığım ama sonuca ulaşamadığım bir konu bu.