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가 없으면 일정 주기로 계속 실행됨.
참조 사이트.