Statistics
| Branch: | Tag: | Revision:

amiro-os / components / bluetooth / bluetooth-wiimote.cpp @ 8dbafe16

History | View | Annotate | Download (6.049 KB)

1 58fe0e0b Thomas Schöpping
#include <ch.hpp>
2
#include <hal.h>
3
4
#include <amiro/bluetooth/bluetooth-wiimote.hpp>
5
6
using namespace chibios_rt;
7
using namespace amiro;
8
9
/*
10
 * Class constructor
11
 */
12
BluetoothWiimote::BluetoothWiimote(BLUETOOTH *bluetooth, uint8_t rxtx) :
13
  BaseStaticThread<128>(), wiimoteConn(bluetooth, this, "WIIMOTE"),
14
  mailbox(mailboxBuffer, BLUETOOTH_WIIMOTE_MAILBOX_SIZE), accelerometer{0,0,0} {
15
  iwrap = &(bluetooth->iwrap);
16
  rx_tx = rxtx;
17
  linkId = 0xFF;
18
  stopflag = 0;
19
}
20
21
//----------------------------------------------------------------
22
23
msg_t BluetoothWiimote::main(void) {
24
  setName("BluetoothWiimote");
25
26
  while (!this->shouldTerminate()) {
27
    if (wiimoteReceive())
28
      this->requestTerminate();
29
  }
30
  return RDY_OK;
31
}
32
33
/*
34
 * Member functions
35
 */
36
msg_t BluetoothWiimote::wiimoteReceive() {
37
  BluetoothDescriptor* recv_descriptor = NULL;
38
  uint8_t *buffer;
39
  size_t length;
40
  msg_t msg;
41
42
  static uint8_t button_up;
43
  static uint8_t button_down;
44
  static uint8_t button_right;
45
  static uint8_t button_left;
46
  static uint8_t button_plus;
47
  static uint8_t button_home;
48
  static uint8_t button_minus;
49
  static uint8_t button_A;
50
  static uint8_t button_B;
51
  static uint8_t button_1;
52
  static uint8_t button_2;
53
54
  msg = mailbox.fetch((msg_t*) &recv_descriptor, TIME_INFINITE);
55
  if ((msg == RDY_RESET) || stopflag)
56
    return RDY_RESET;
57
58
  buffer = recv_descriptor->bluetoothDescriptorGetPayload();
59
  length = recv_descriptor->bluetoothDescriptorGetPayloadLength();
60
61
  if (buffer[0] == 0xA1 && buffer[1] == 0x31) {
62
    accelerometer.x_axis = (buffer[4] << 2) + ((buffer[2] & 0x60) >> 5) - 0x1EC;
63
    accelerometer.y_axis = (buffer[5] << 2) + ((buffer[3] & 0x20) >> 4) - 0x1EA;
64
    accelerometer.z_axis = (buffer[6] << 2) + ((buffer[3] & 0x40) >> 5) - 0x1EE;
65
66
    if (buffer[3] & 0x80) {             // Press home to return button reporting
67
      bluetoothWiimoteDataBtn();
68
      accelerometer.x_axis = 0;
69
      accelerometer.y_axis = 0;
70
      accelerometer.z_axis = 0;
71
    }
72
73
  } else if (buffer[0] == 0xA1 && buffer[1] == 0x30) {
74
    button_up    = (buffer[2] & 0x08) >> 3;
75
    button_down  = (buffer[2] & 0x04) >> 2;
76
    button_right = (buffer[2] & 0x02) >> 1;
77
    button_left  = (buffer[2] & 0x01) >> 0;
78
    button_plus  = (buffer[2] & 0x10) >> 4;
79
    button_home  = (buffer[3] & 0x80) >> 7;
80
    button_minus = (buffer[3] & 0x10) >> 4;
81
    button_A     = (buffer[3] & 0x08) >> 3;
82
    button_B     = (buffer[3] & 0x04) >> 2;
83
    button_1     = (buffer[3] & 0x02) >> 1;
84
    button_2     = (buffer[3] & 0x01) >> 0;
85
86
    if (button_up)
87
      chSequentialStreamPut((BaseSequentialStream*) &SD1, 'U');
88
89
    if (button_down)
90
      chSequentialStreamPut((BaseSequentialStream*) &SD1, 'D');
91
92
    if (button_right)
93
      chSequentialStreamPut((BaseSequentialStream*) &SD1, 'R');
94
95
    if (button_left)
96
      chSequentialStreamPut((BaseSequentialStream*) &SD1, 'L');
97
98
    if (button_plus)
99
      chSequentialStreamPut((BaseSequentialStream*) &SD1, '+');
100
101
    if (button_home)
102
      chSequentialStreamPut((BaseSequentialStream*) &SD1, 'H');
103
104
    if (button_minus)
105
      chSequentialStreamPut((BaseSequentialStream*) &SD1, '-');
106
107
    if (button_A)
108
      chSequentialStreamPut((BaseSequentialStream*) &SD1, 'A');
109
110
    if (button_B)
111
      chSequentialStreamPut((BaseSequentialStream*) &SD1, 'B');
112
113
    if (button_1)
114
      chSequentialStreamPut((BaseSequentialStream*) &SD1, '1');
115
116
    if (button_2)
117
      chSequentialStreamPut((BaseSequentialStream*) &SD1, '2');
118
119
    if (button_minus && button_plus)   // Press minus and plue to return accelerometer reporting
120
      bluetoothWiimoteDataBtnAcc();
121
  } else {
122
    chSequentialStreamWrite((BaseSequentialStream*) &SD1, buffer, length);
123
  }
124
125
  msg = iwrap->transport.bluetoothTransportGetStorageMailbox()->post((msg_t) recv_descriptor, TIME_INFINITE);
126
  if ((msg == RDY_RESET) || stopflag)
127
    return RDY_RESET;
128
129
  return RDY_OK;
130
}
131
132
msg_t BluetoothWiimote::wiimoteTransmit(const uint8_t* wiimotecmd, size_t length) {
133
  msg_t msg;
134
135
  if ((rx_tx & 0x01) && (linkId != 0xFF) && (!stopflag))
136
    msg = iwrap->iwrapTransmit(linkId, wiimotecmd, length);
137
  else
138
    msg = RDY_RESET;
139
140
  return msg;
141
}
142
143
void BluetoothWiimote::bluetoothWiimoteStart(uint8_t linkid) {
144
  linkId = linkid;
145
  iwrap->transport.bluetoothTransportSetReceiveMailbox(linkId, &this->mailbox);
146
147
  if ((rx_tx & 0x02)) {   // && (!stopflag)
148
    this->start(NORMALPRIO);
149
  }
150
  stopflag = 0;
151
}
152
153
void BluetoothWiimote::bluetoothWiimoteStop() {
154
  linkId = 0xFF;
155
  stopflag = 1;
156
  mailbox.post(RDY_RESET, TIME_INFINITE);        // TIME_IMMEDIATE TIME_INFINITE
157
}
158
159
bool BluetoothWiimote::bluetoothWiimoteIsConnected() {
160
  if (linkId == 0xFF)
161
    return false;
162
163
  return true;
164
}
165
166
void BluetoothWiimote::bluetoothWiimoteListen(const char *addr) {
167
  wiimoteConn.bluetoothConnectorListen(addr);
168
}
169
170
void BluetoothWiimote::bluetoothWiimoteConnect(const char *addr) {
171
  wiimoteConn.bluetoothConnectorConnect(addr);
172
}
173
174
void BluetoothWiimote::bluetoothWiimoteDisconnect(const char *addr) {
175
  wiimoteConn.bluetoothConnectorDisconnect(addr);
176
}
177
178
BluetoothWiimote::Accelerometer * BluetoothWiimote::getAccelerometer() {
179
  return &accelerometer;
180
}
181
182
/*
183
 * @brief :  On-off LEDs and Motor of Wiimote.
184
 *
185
 * @param[in] ledid_flag     On-off flag of LEDs 1,2,3,4
186
 *                           (LED1: 0x10, LED2: 0x20, LED3: 0x40, LED4: 0x80)
187
 * @param[in] vibrate_flag   On-off flag of Vibration Motor (On: 1, off: 0)
188
 */
189
void BluetoothWiimote::bluetoothWiimoteLedVibrate(uint8_t ledid_flag, uint8_t vibrate_flag) {
190
  const uint8_t data[] = {0xA2, 0x11, (uint8_t) (ledid_flag | vibrate_flag)};
191
  wiimoteTransmit(data, 3);
192
}
193
194
/*
195
 * @brief :  Show status information of Wiimote.
196
 */
197
void BluetoothWiimote::bluetoothWiimoteStatusInfo() {
198
  const uint8_t data[] = {0xA2, 0x15, 0x00};
199
  wiimoteTransmit(data, 3);
200
}
201
202
/*
203
 * @brief :  Send button status (change event) of Wiimote.
204
 */
205
void BluetoothWiimote::bluetoothWiimoteDataBtn() {
206
  const uint8_t data[] = {0xA2, 0x12, 0x00, 0x30};
207
  wiimoteTransmit(data, 4);
208
}
209
210
/*
211
 * @brief :  Send button & accelerometer status (change event) of Wiimote.
212
 */
213
void BluetoothWiimote::bluetoothWiimoteDataBtnAcc() {
214
  const uint8_t data[] = {0xA2, 0x12, 0x00, 0x31};
215
  wiimoteTransmit(data, 4);
216
}