root/wiimote/command.c @ 15d141cccd9a38fede6b80ab2d6b8f921991cf25

Revision 15d141cccd9a38fede6b80ab2d6b8f921991cf25, 5.8 KB (checked in by dsmith <dsmith@…>, 6 years ago)

Initial import

git-svn-id: http://abstrakraft.org/cwiid/svn/CWiid/trunk@3 918edb2d-ff29-0410-9de2-eb38e7f22bc7

  • Property mode set to 100644
Line 
1/* Copyright (C) 2007 L. Donnie Smith <wiimote@abstrakraft.org>
2 *
3 *  This program is free software; you can redistribute it and/or modify
4 *  it under the terms of the GNU General Public License as published by
5 *  the Free Software Foundation; either version 2 of the License, or
6 *  (at your option) any later version.
7 *
8 *  This program is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *  GNU General Public License for more details.
12 *
13 *  You should have received a copy of the GNU General Public License
14 *  along with this program; if not, write to the Free Software
15 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16 */
17
18#include <unistd.h>
19#include "wiimote_internal.h"
20
21/* IR Sensitivity Block */
22unsigned char ir_block1[] = CLIFF_IR_BLOCK_1;
23unsigned char ir_block2[] = CLIFF_IR_BLOCK_2;
24
25struct write_seq ir_enable10_seq[] = {
26        {WRITE_SEQ_RPT, RPT_IR_ENABLE1, (unsigned char *)"\x04", 1, 0},
27        {WRITE_SEQ_RPT, RPT_IR_ENABLE2, (unsigned char *)"\x04", 1, 0},
28        {WRITE_SEQ_MEM, 0xB00030, (unsigned char *)"\x08", 1,     WIIMOTE_RW_REG},
29        {WRITE_SEQ_MEM, 0xB00000, ir_block1, sizeof(ir_block1)-1, WIIMOTE_RW_REG},
30        {WRITE_SEQ_MEM, 0xB0001A, ir_block2, sizeof(ir_block2)-1, WIIMOTE_RW_REG},
31        {WRITE_SEQ_MEM, 0xB00033, (unsigned char *)"\x01", 1,     WIIMOTE_RW_REG}
32};
33
34struct write_seq ir_enable12_seq[] = {
35        {WRITE_SEQ_RPT, RPT_IR_ENABLE1, (unsigned char *)"\x04", 1, 0},
36        {WRITE_SEQ_RPT, RPT_IR_ENABLE2, (unsigned char *)"\x04", 1, 0},
37        {WRITE_SEQ_MEM, 0xB00030, (unsigned char *)"\x08", 1,     WIIMOTE_RW_REG},
38        {WRITE_SEQ_MEM, 0xB00000, ir_block1, sizeof(ir_block1)-1, WIIMOTE_RW_REG},
39        {WRITE_SEQ_MEM, 0xB0001A, ir_block2, sizeof(ir_block2)-1, WIIMOTE_RW_REG},
40        {WRITE_SEQ_MEM, 0xB00033, (unsigned char *)"\x03", 1,     WIIMOTE_RW_REG}
41};
42
43struct write_seq ir_disable_seq[] = {
44        {WRITE_SEQ_RPT, RPT_IR_ENABLE1, (unsigned char *)"\x00", 1, 0},
45        {WRITE_SEQ_RPT, RPT_IR_ENABLE2, (unsigned char *)"\x00", 1, 0}
46};
47
48int update_rpt_mode(struct wiimote *wiimote, int flags);
49
50#define CMD_BUF_LEN     21
51int wiimote_command(struct wiimote *wiimote, enum wiimote_command command,
52                    unsigned char flags) {
53        int ret = 0;
54        unsigned char buf[CMD_BUF_LEN];
55
56        switch (command) {
57        case WIIMOTE_CMD_STATUS:
58                buf[0] = 0;
59                if (send_report(wiimote, 0, RPT_STATUS_REQ, 1, buf)) {
60                        wiimote_err("Error requesting status");
61                        ret = -1;
62                }
63                break;
64        case WIIMOTE_CMD_LED:
65                wiimote->led_rumble_state = ((flags & 0x0F)<<4) |
66                                            (wiimote->led_rumble_state & 0x01);
67                buf[0]=wiimote->led_rumble_state;
68                if (send_report(wiimote, SEND_RPT_NO_RUMBLE, RPT_LED_RUMBLE, 1, buf)) {
69                        wiimote_err("Error setting LEDs");
70                        ret = -1;
71                }
72                break;
73        case WIIMOTE_CMD_RUMBLE:
74                wiimote->led_rumble_state = (wiimote->led_rumble_state & 0xFE) |
75                                            (flags ? 1 : 0);
76                buf[0]=wiimote->led_rumble_state;
77                if (send_report(wiimote, SEND_RPT_NO_RUMBLE, RPT_LED_RUMBLE, 1, buf)) {
78                        wiimote_err("Error setting rumble");
79                        ret = -1;
80                }
81                break;
82        case WIIMOTE_CMD_RPT_MODE:
83                update_rpt_mode(wiimote, flags);
84                break;
85        default:
86                wiimote_err("Unknown command");
87                ret = -1;
88                break;
89        }
90
91        return ret;
92}
93
94#define RPT_MODE_BUF_LEN 2
95int update_rpt_mode(struct wiimote *wiimote, int flags)
96{
97        unsigned char buf[RPT_MODE_BUF_LEN];
98        unsigned char rpt_mode;
99        struct write_seq *ir_enable_seq;
100        int seq_len;
101
102        /* Lock wiimote access */
103        if (pthread_mutex_lock(&wiimote->wiimote_mutex)) {
104                wiimote_err("Error locking rw_mutex");
105                return -1;
106        }
107
108        /* Use -1 to update the reporting mode without changing flags */
109        if (flags == -1) {
110                flags = wiimote->rpt_mode_flags;
111        }
112
113        if ((flags & WIIMOTE_RPT_EXT) &&
114          ((wiimote->extension == WIIMOTE_EXT_NUNCHUK) ||
115           (wiimote->extension == WIIMOTE_EXT_CLASSIC))) {
116                if ((flags & WIIMOTE_RPT_IR) &&
117                  (flags & WIIMOTE_RPT_ACC)) {
118                        rpt_mode = RPT_BTN_ACC_IR10_EXT6;
119                        ir_enable_seq = ir_enable10_seq;
120                        seq_len = SEQ_LEN(ir_enable10_seq);
121                }
122                else if (flags & WIIMOTE_RPT_IR) {
123                        rpt_mode = RPT_BTN_IR10_EXT9;
124                        ir_enable_seq = ir_enable10_seq;
125                        seq_len = SEQ_LEN(ir_enable10_seq);
126                }
127                else if (flags & WIIMOTE_RPT_ACC) {
128                        rpt_mode = RPT_BTN_ACC_EXT16;
129                }
130                else if (flags & WIIMOTE_RPT_BTN) {
131                        rpt_mode = RPT_BTN_EXT8;
132                }
133                else {
134                        rpt_mode = RPT_EXT21;
135                }       
136        }
137        else {
138                if (flags & WIIMOTE_RPT_IR) {
139                        rpt_mode = RPT_BTN_ACC_IR12;
140                        ir_enable_seq = ir_enable12_seq;
141                        seq_len = SEQ_LEN(ir_enable12_seq);
142                }
143                else if (flags & WIIMOTE_RPT_ACC) {
144                        rpt_mode = RPT_BTN_ACC;
145                }
146                else {
147                        rpt_mode = RPT_BTN;
148                }
149        }
150
151        /* Enable IR */
152        /* TODO: only do this when necessary (record old IR mode) */
153        if ((flags & WIIMOTE_RPT_IR)) {
154                if (exec_write_seq(wiimote, seq_len, ir_enable_seq)) {
155                        wiimote_err("Error on IR enable");
156                        if (pthread_mutex_unlock(&wiimote->wiimote_mutex)) {
157                                wiimote_err("Error unlocking wiimote_mutex: deadlock warning");
158                        }
159                        return -1;
160                }
161        }
162        /* Disable IR */
163        else if ((wiimote->rpt_mode_flags & WIIMOTE_RPT_IR) &
164          !(flags & WIIMOTE_RPT_IR)) {
165                if (exec_write_seq(wiimote, SEQ_LEN(ir_disable_seq),
166                                   ir_disable_seq)) {
167                        wiimote_err("Error on IR enable");
168                        if (pthread_mutex_unlock(&wiimote->wiimote_mutex)) {
169                                wiimote_err("Error unlocking wiimote_mutex: deadlock warning");
170                        }
171                        return -1;
172                }
173        }
174
175        /* Send SET_REPORT */
176        buf[0]=0;
177        buf[1]=rpt_mode;
178        if (send_report(wiimote, 0, RPT_RPT_MODE, RPT_MODE_BUF_LEN, buf)) {
179                wiimote_err("Error setting report state");
180                if (pthread_mutex_unlock(&wiimote->wiimote_mutex)) {
181                        wiimote_err("Error unlocking wiimote_mutex: deadlock warning");
182                }
183                return -1;
184        }
185
186        wiimote->rpt_mode_flags = flags;
187
188        /* Unlock wiimote_mutex */
189        if (pthread_mutex_unlock(&wiimote->wiimote_mutex)) {
190                wiimote_err("Error unlocking wiimote_mutex: deadlock warning");
191        }
192
193        return 0;
194}
195
Note: See TracBrowser for help on using the browser.