linux usb driver xbox360(2)

LED 제어하기

xbox 360 컨트롤러가 4개 LED를 가지고 있다. 총 4명 플레이어가 있을 경우 1 ~ 4까지 시계 방향으로 램프를 켜주게 된다. usb -> input 버튼 입력을 받아 들이기 전 간단해 보는 LED 제어를 해보기로 했다. 하..어렵다. 입력 받아들이는 것 보다 더 어려운 듯 하다.

cdev_led_register를 실행하면 /sys/class/led에 led 모듈이 등록된다.

pi@raspberrypi:/sys/class/leds $ dmesg | tail -20
[ 7044.723682] leds xpad_led: Setting an LED's brightness failed (-524)
[ 7044.723824] disconnected
[ 7344.482279] xpad is 56bd80be, xpad->udev is 7ea0c81d
[ 7344.482296] interface is 49be3431
[ 7344.482318] xbox360 1-1.1:1.0: interrupt in, out found. 2cedb0f6, 62b37858
[ 7344.482579] xbox360 1-1.1:1.0: usb xbox360 driver was registerd
[ 7344.482861] xpad is db7e959d, xpad->udev is 7ea0c81d
[ 7344.482875] interface is c0605ae3
[ 7344.482893] xbox360 1-1.1:1.1: interrupt in, out found. 6497d636, 4bf83f77
[ 7344.483394] xbox360 1-1.1:1.1: usb xbox360 driver was registerd
[ 7344.483545] usb 1-1.1: Led xpad_led renamed to xpad_led_1 due to name collision
[ 7344.483699] xpad is 2c597e01, xpad->udev is 7ea0c81d
[ 7344.483713] interface is dfef8df2
[ 7344.483730] xbox360 1-1.1:1.2: Could not find both interrupt-in and interrpt-out endpoints
[ 7344.483743] error -6
[ 7344.483824] xpad is 2c597e01, xpad->udev is 7ea0c81d
[ 7344.483837] interface is f1417f63
[ 7344.483852] xbox360 1-1.1:1.3: Could not find both interrupt-in and interrpt-out endpoints
[ 7344.483865] error -6
[ 7344.483985] usbcore: registered new interface driver xbox360


pi@raspberrypi:/sys/class/leds $ ls -tl
total 0
lrwxrwxrwx 1 root root 0 Jan  4 23:52 xpad_led -> ../../devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/leds/xpad_led
lrwxrwxrwx 1 root root 0 Jan  4 23:52 xpad_led_1 -> ../../devices/platform/scb/fd500000.pcie/pci0000

xbox 컨트롤러가 총 4개를 등록할 수 있는데, 인터럽트로 2개를 등록할 수 있다. 나머지 2개는 무엇인지 모르겠다. 암튼 xpad.c는 2번만 등록했다.

CDEV_LED로 등록을 하면 brightness_set 함수를 overload 할 수 있다. brightness_set -> xpad_led_set -> xpad_send_led_command으로 연결한다. xpad_send_led_command 안에서 LED 제어하는 패킷을 만들어 URB에 넣어 준다. urb->transfer_buffer_length를 잘 넣어줘야 URB 패킷을 전송한다.

인터럽트로 한번 등록하면 일정 주기로 계속 명령을 실행한다.

[  340.057841] xpad is c97d9e68, xpad->udev is decb56d0
[  340.057858] interface is d89e5572
[  340.057871] cur_altsetting is 2
[  340.057893] xbox360 1-1.1:1.0: interrupt in, out found. 00000000, 3b46194c
[  340.058231] xbox360 1-1.1:1.0: usb xbox360 driver was registerd
[  340.058253] dma output address 6ce62de4 with size 64, point to f2c4e403 was allocated
[  340.058266] actual address is 6ce62de4
[  340.058280] urb was allocated
[  340.058292] xpad->endpoint_out->bInterval is 8
[  340.058306] XPAD_OUT_LED_IDX: 2
[  340.058318] XPAD_NUM_OUT_PACKETS: 3
[  340.058440] xpad->led_command->data[0]:1,[1]:3,[2]:10, with 3 len
[  340.058463] xpad_send_led_command: completed
[  340.058828] usbcore: registered new interface driver xbox360
[  359.127170] usbcore: deregistering interface driver xbox360
[  359.127225] xpad address is c97d9e68, intf is d89e5572
[  359.129187] xpad->led_command->data[0]:1,[1]:3,[2]:0, with 3 len
[  359.129217] xbox360 1-1.1:1.0: xpad_send_led_command - usb_submit_urb failed with -ENOENT
[  359.131553] xpad led was unregistered
[  359.131575] dma output address 6ce62de4 with size 64 was freed
[  359.131590] disconnected

10번을 보내면 LED가 rotate 한다.

–추가–

  • interrupt 등록, usb_submit_urb 완료 함수(xpad_irq_outfn) 등록.
  • set_brightness로 led 밝기 조정 함수에 등록.
  • xpad->urb_active == true일 경우 명령에 맞는 패킷 만들어 전송.
  • xpad_irq_outfn 안ㅔ서 xpad->urb_active = false로 수정. xpad->urb_active가 없으면 일정 주기로 계속 실행됨.

참조 사이트.

코멘트

댓글 남기기

이 사이트는 Akismet을 사용하여 스팸을 줄입니다. 댓글 데이터가 어떻게 처리되는지 알아보세요.