mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Some minor changes
This commit is contained in:
parent
a70deaf5cc
commit
1ff0135b31
6 changed files with 111 additions and 95 deletions
22
BTD.cpp
22
BTD.cpp
|
@ -295,7 +295,7 @@ void BTD::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) {
|
|||
uint8_t BTD::Release() {
|
||||
for (uint8_t i=0; i<BTD_NUMDEVICES; i++)
|
||||
if (btService[i])
|
||||
btService[i]->Release(); // Reset both the L2CAP Channel and the HCI Connection
|
||||
btService[i]->Reset(); // Reset both the L2CAP Channel and the HCI Connection
|
||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
bPollEnable = false;
|
||||
|
@ -560,13 +560,16 @@ void BTD::HCI_task() {
|
|||
Notify(PSTR("\r\nScan Disabled"));
|
||||
#endif
|
||||
hci_event_flag = 0;
|
||||
hci_state = HCI_DONE_STATE;
|
||||
hci_state = HCI_DONE_STATE;
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_DONE_STATE:
|
||||
hci_state = HCI_SCANNING_STATE;
|
||||
connectionClaimed = false;
|
||||
hci_counter++;
|
||||
if (hci_counter > 100) { // Wait until we have looped 100 times to make sure that the L2CAP connection has been started
|
||||
hci_state = HCI_SCANNING_STATE;
|
||||
l2capConnectionClaimed = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_DISCONNECT_STATE:
|
||||
|
@ -591,8 +594,8 @@ void BTD::HCI_task() {
|
|||
}
|
||||
|
||||
void BTD::ACL_event_task() {
|
||||
uint16_t MAX_BUFFER_SIZE = BULK_MAXPKTSIZE;
|
||||
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_DATAIN_PIPE ].epAddr, &MAX_BUFFER_SIZE, l2capinbuf); // input on endpoint 2
|
||||
uint16_t MAX_BUFFER_SIZE = BULK_MAXPKTSIZE;
|
||||
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_DATAIN_PIPE ].epAddr, &MAX_BUFFER_SIZE, l2capinbuf); // input on endpoint 2
|
||||
if(!rcode) { // Check for errors
|
||||
for (uint8_t i=0; i<BTD_NUMDEVICES; i++)
|
||||
if (btService[i])
|
||||
|
@ -605,7 +608,7 @@ void BTD::ACL_event_task() {
|
|||
}
|
||||
for (uint8_t i=0; i<BTD_NUMDEVICES; i++)
|
||||
if (btService[i])
|
||||
btService[i]->Poll();
|
||||
btService[i]->Run();
|
||||
}
|
||||
|
||||
/************************************************************/
|
||||
|
@ -792,15 +795,16 @@ void BTD::L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t
|
|||
|
||||
uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf);
|
||||
if(rcode) {
|
||||
delay(100); // This small delay prevents it from overflowing if it fails
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nError sending L2CAP message: 0x"));
|
||||
Notify(PSTR("\r\nError sending L2CAP message: 0x"));
|
||||
PrintHex<uint8_t>(rcode);
|
||||
Notify(PSTR(" - Channel ID: "));
|
||||
Serial.print(channelHigh);
|
||||
Notify(PSTR(" "));
|
||||
Serial.print(channelLow);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
void BTD::l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid, uint8_t result) {
|
||||
l2capoutbuf[0] = L2CAP_CMD_CONNECTION_RESPONSE; // Code
|
||||
|
|
8
BTD.h
8
BTD.h
|
@ -115,8 +115,8 @@
|
|||
class BluetoothService { // All services should include this class
|
||||
public:
|
||||
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services
|
||||
virtual void Poll(); // Used to run the different state machines
|
||||
virtual void Release(); // Used to reset the services
|
||||
virtual void Run(); // Used to run the different state machines
|
||||
virtual void Reset(); // Used to reset the services
|
||||
virtual void disconnect(); // Used to disconnect both the L2CAP Channel and the HCI Connection
|
||||
};
|
||||
|
||||
|
@ -152,8 +152,8 @@ public:
|
|||
return 1; // ErrorregisterServiceClass
|
||||
};
|
||||
|
||||
void claimConnection() { connectionClaimed = true; }; // This is used by the service to know when to store the device information
|
||||
bool connectionClaimed;
|
||||
void claimConnection() { l2capConnectionClaimed = true; }; // This is used by the service to know when to store the device information
|
||||
bool l2capConnectionClaimed;
|
||||
|
||||
const char* btdName; // These are set by the SPP library
|
||||
const char* btdPin;
|
||||
|
|
135
PS3BT.cpp
135
PS3BT.cpp
|
@ -58,7 +58,7 @@ pBtd(p) // pointer to USB class instance - mandatory
|
|||
interrupt_dcid[0] = 0x41;//0x0041
|
||||
interrupt_dcid[1] = 0x00;
|
||||
|
||||
Release();
|
||||
Reset();
|
||||
}
|
||||
bool PS3BT::getButton(Button b) {
|
||||
if (l2capinbuf == NULL)
|
||||
|
@ -209,7 +209,7 @@ String PS3BT::getStatusString() {
|
|||
return statusOutput;
|
||||
}
|
||||
}
|
||||
void PS3BT::Release() {
|
||||
void PS3BT::Reset() {
|
||||
PS3Connected = false;
|
||||
PS3MoveConnected = false;
|
||||
PS3NavigationConnected = false;
|
||||
|
@ -233,11 +233,9 @@ void PS3BT::disconnect() { //Use this void to disconnect any of the controllers
|
|||
}
|
||||
|
||||
void PS3BT::ACLData(uint8_t* ACLData) {
|
||||
for(uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
|
||||
l2capinbuf[i] = ACLData[i];
|
||||
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||
if(((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) || ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM)) {
|
||||
if(!pBtd->connectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected) {
|
||||
if(!pBtd->l2capConnectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected) {
|
||||
if (ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||
if(((ACLData[12] | (ACLData[13] << 8)) == HID_CTRL_PSM) || ((ACLData[12] | (ACLData[13] << 8)) == HID_INTR_PSM)) {
|
||||
pBtd->claimConnection(); // Claim that the incoming connection belongs to this service
|
||||
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||
for(uint8_t i = 0; i < 30; i++)
|
||||
|
@ -252,7 +250,9 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000))) { //acl_handle_ok
|
||||
if (((ACLData[0] | (ACLData[1] << 8)) == (hci_handle | 0x2000))) { //acl_handle_ok
|
||||
for(uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
|
||||
l2capinbuf[i] = ACLData[i];
|
||||
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U
|
||||
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||
#ifdef DEBUG
|
||||
|
@ -401,9 +401,10 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
L2CAP_task();
|
||||
}
|
||||
}
|
||||
void PS3BT::Poll() {
|
||||
void PS3BT::L2CAP_task() {
|
||||
switch (l2cap_state) {
|
||||
case L2CAP_EV_WAIT:
|
||||
if (l2cap_connection_request_control_flag) {
|
||||
|
@ -424,7 +425,7 @@ void PS3BT::Poll() {
|
|||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nHID Control Configuration Request"));
|
||||
#endif
|
||||
pBtd->l2cap_config_response(hci_handle,identifier, control_scid);
|
||||
pBtd->l2cap_config_response(hci_handle,identifier, control_scid);
|
||||
l2cap_state = L2CAP_EV_CONTROL_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
@ -442,12 +443,12 @@ void PS3BT::Poll() {
|
|||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"));
|
||||
#endif
|
||||
pBtd->l2cap_connection_response(hci_handle,identifier, interrupt_dcid, interrupt_scid, PENDING);
|
||||
pBtd->l2cap_connection_response(hci_handle,identifier, interrupt_dcid, interrupt_scid, PENDING);
|
||||
delay(1);
|
||||
pBtd->l2cap_connection_response(hci_handle,identifier, interrupt_dcid, interrupt_scid, SUCCESSFUL);
|
||||
pBtd->l2cap_connection_response(hci_handle,identifier, interrupt_dcid, interrupt_scid, SUCCESSFUL);
|
||||
identifier++;
|
||||
delay(1);
|
||||
pBtd->l2cap_config_request(hci_handle,identifier, interrupt_scid);
|
||||
pBtd->l2cap_config_request(hci_handle,identifier, interrupt_scid);
|
||||
|
||||
l2cap_state = L2CAP_EV_INTERRUPT_REQUEST;
|
||||
}
|
||||
|
@ -465,8 +466,8 @@ void PS3BT::Poll() {
|
|||
if (l2cap_config_success_interrupt_flag) {
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nHID Interrupt Successfully Configured"));
|
||||
#endif
|
||||
if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
||||
#endif
|
||||
if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
||||
for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed
|
||||
l2capinbuf[i] = 0;
|
||||
ButtonState = 0;
|
||||
|
@ -478,55 +479,8 @@ void PS3BT::Poll() {
|
|||
timer = millis();
|
||||
}
|
||||
break;
|
||||
case L2CAP_EV_HID_ENABLE_SIXAXIS:
|
||||
if(millis() - timer > 1000) { // loop 1 second before sending the command
|
||||
for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed
|
||||
l2capinbuf[i] = 0;
|
||||
ButtonState = 0;
|
||||
OldButtonState = 0;
|
||||
|
||||
enable_sixaxis();
|
||||
for (uint8_t i = 15; i < 19; i++)
|
||||
l2capinbuf[i] = 0x7F; // Set the analog joystick values to center position
|
||||
l2cap_state = L2CAP_EV_HID_PS3_LED;
|
||||
timer = millis();
|
||||
}
|
||||
break;
|
||||
|
||||
case L2CAP_EV_HID_PS3_LED:
|
||||
if(millis() - timer > 1000) { // loop 1 second before sending the command
|
||||
if (remote_name[0] == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P')
|
||||
setLedOn(LED1);
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"));
|
||||
#endif
|
||||
PS3Connected = true;
|
||||
} else if (remote_name[0] == 'N') { // First letter in Navigation Controller ('N')
|
||||
setLedOn(LED1); // This just turns LED constantly on, on the Navigation controller
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nNavigation Controller Enabled\r\n"));
|
||||
#endif
|
||||
PS3NavigationConnected = true;
|
||||
} else if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
||||
moveSetBulb(Red);
|
||||
timerBulbRumble = millis();
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nMotion Controller Enabled\r\n"));
|
||||
#endif
|
||||
PS3MoveConnected = true;
|
||||
}
|
||||
l2cap_state = L2CAP_EV_DONE;
|
||||
}
|
||||
break;
|
||||
|
||||
case L2CAP_EV_DONE:
|
||||
if (PS3MoveConnected) { //The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
|
||||
if (millis() - timerBulbRumble > 4000) { //Send at least every 4th second
|
||||
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);//The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
||||
timerBulbRumble = millis();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* These states are handled in Run() */
|
||||
|
||||
case L2CAP_EV_INTERRUPT_DISCONNECT:
|
||||
if (l2cap_disconnect_response_interrupt_flag) {
|
||||
|
@ -549,6 +503,59 @@ void PS3BT::Poll() {
|
|||
l2cap_state = L2CAP_EV_WAIT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
void PS3BT::Run() {
|
||||
switch (l2cap_state) {
|
||||
case L2CAP_EV_HID_ENABLE_SIXAXIS:
|
||||
if(millis() - timer > 1000) { // loop 1 second before sending the command
|
||||
for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed
|
||||
l2capinbuf[i] = 0;
|
||||
ButtonState = 0;
|
||||
OldButtonState = 0;
|
||||
|
||||
enable_sixaxis();
|
||||
for (uint8_t i = 15; i < 19; i++)
|
||||
l2capinbuf[i] = 0x7F; // Set the analog joystick values to center position
|
||||
l2cap_state = L2CAP_EV_HID_PS3_LED;
|
||||
timer = millis();
|
||||
}
|
||||
break;
|
||||
|
||||
case L2CAP_EV_HID_PS3_LED:
|
||||
if(millis() - timer > 1000) { // loop 1 second before sending the command
|
||||
if (remote_name[0] == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P')
|
||||
setLedOn(LED1);
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"));
|
||||
#endif
|
||||
PS3Connected = true;
|
||||
} else if (remote_name[0] == 'N') { // First letter in Navigation Controller ('N')
|
||||
setLedOn(LED1); // This just turns LED constantly on, on the Navigation controller
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nNavigation Controller Enabled\r\n"));
|
||||
#endif
|
||||
PS3NavigationConnected = true;
|
||||
} else if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
||||
moveSetBulb(Red);
|
||||
timerBulbRumble = millis();
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nMotion Controller Enabled\r\n"));
|
||||
#endif
|
||||
PS3MoveConnected = true;
|
||||
}
|
||||
l2cap_state = L2CAP_EV_DONE;
|
||||
}
|
||||
break;
|
||||
|
||||
case L2CAP_EV_DONE:
|
||||
if (PS3MoveConnected) { //The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
|
||||
if (millis() - timerBulbRumble > 4000) { //Send at least every 4th second
|
||||
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);//The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
||||
timerBulbRumble = millis();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
6
PS3BT.h
6
PS3BT.h
|
@ -219,8 +219,8 @@ public:
|
|||
|
||||
// BluetoothService implementation
|
||||
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services
|
||||
virtual void Poll(); // Used to run the state maschine
|
||||
virtual void Release(); // Use this to reset the service
|
||||
virtual void Run(); // Used to run part of the state maschine
|
||||
virtual void Reset(); // Use this to reset the service
|
||||
virtual void disconnect(); // Use this void to disconnect any of the controllers
|
||||
|
||||
/* PS3 Controller Commands */
|
||||
|
@ -258,6 +258,8 @@ private:
|
|||
/* mandatory members */
|
||||
BTD *pBtd;
|
||||
|
||||
void L2CAP_task(); // L2CAP state machine
|
||||
|
||||
/* Variables filled from HCI event management */
|
||||
int16_t hci_handle;
|
||||
uint8_t remote_name[30]; // first 30 chars of remote name
|
||||
|
|
30
SPP.cpp
30
SPP.cpp
|
@ -50,17 +50,16 @@ pBtd(p) // Pointer to BTD class instance - mandatory
|
|||
|
||||
pBtd->btdName = name;
|
||||
pBtd->btdPin = pin;
|
||||
l2cap_sdp_state = L2CAP_SDP_WAIT;
|
||||
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
|
||||
l2cap_event_flag = 0;
|
||||
|
||||
/* Set device cid for the SDP and RFCOMM channelse */
|
||||
sdp_dcid[0] = 0x50; // 0x0050
|
||||
sdp_dcid[1] = 0x00;
|
||||
rfcomm_dcid[0] = 0x51; // 0x0051
|
||||
rfcomm_dcid[1] = 0x00;
|
||||
|
||||
Reset();
|
||||
}
|
||||
void SPP::Release() {
|
||||
void SPP::Reset() {
|
||||
connected = false;
|
||||
RFCOMMConnected = false;
|
||||
SDPConnected = false;
|
||||
|
@ -78,16 +77,18 @@ void SPP::disconnect(){
|
|||
l2cap_event_flag = 0; // Reset flags
|
||||
l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE;
|
||||
}
|
||||
void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||
if(((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM) || ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM)) {
|
||||
if(!pBtd->connectionClaimed && !connected && !RFCOMMConnected && !SDPConnected) {
|
||||
void SPP::ACLData(uint8_t* ACLData) {
|
||||
if(!pBtd->l2capConnectionClaimed && !connected && !RFCOMMConnected && !SDPConnected) {
|
||||
if (ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||
if(((ACLData[12] | (ACLData[13] << 8)) == SDP_PSM) || ((ACLData[12] | (ACLData[13] << 8)) == RFCOMM_PSM)) {
|
||||
pBtd->claimConnection(); // Claim that the incoming connection belongs to this service
|
||||
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||
}
|
||||
}
|
||||
}
|
||||
if (((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000))) { // acl_handle_ok
|
||||
if (((ACLData[0] | (ACLData[1] << 8)) == (hci_handle | 0x2000))) { // acl_handle_ok
|
||||
for(uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
|
||||
l2capinbuf[i] = ACLData[i];
|
||||
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U
|
||||
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||
#ifdef DEBUG
|
||||
|
@ -362,9 +363,11 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
|||
PrintHex<uint8_t>(l2capinbuf[6]);
|
||||
#endif
|
||||
}
|
||||
SDP_task();
|
||||
RFCOMM_task();
|
||||
}
|
||||
}
|
||||
void SPP::Poll() {
|
||||
void SPP::Run() {
|
||||
if(waitForLastCommand && (millis() - timer) > 100) { // We will only wait 100ms and see if the UIH Remote Port Negotiation Command is send, as some deviced don't send it
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"));
|
||||
|
@ -372,9 +375,7 @@ void SPP::Poll() {
|
|||
creditSent = false;
|
||||
waitForLastCommand = false;
|
||||
connected = true; // The RFCOMM channel is now established
|
||||
}
|
||||
SDP_task();
|
||||
RFCOMM_task();
|
||||
}
|
||||
}
|
||||
void SPP::SDP_task() {
|
||||
switch (l2cap_sdp_state)
|
||||
|
@ -773,7 +774,8 @@ void SPP::println(const __FlashStringHelper *ifsh) {
|
|||
print(buf,size+2);
|
||||
}
|
||||
void SPP::println(void) {
|
||||
print("\r\n");
|
||||
uint8_t buf[2] = {'\r','\n'};
|
||||
print(buf,2);
|
||||
}
|
||||
|
||||
/* These must be used to print numbers */
|
||||
|
|
5
SPP.h
5
SPP.h
|
@ -99,8 +99,8 @@ public:
|
|||
|
||||
// BluetoothService implementation
|
||||
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services
|
||||
virtual void Poll(); // Used to run SDP_task() and RFCOMM_task()
|
||||
virtual void Release(); // Use this to reset the service
|
||||
virtual void Run(); // Used to establish the connection automatically
|
||||
virtual void Reset(); // Use this to reset the service
|
||||
virtual void disconnect(); // Used this void to disconnect the virtual serial port
|
||||
|
||||
bool connected;// Variable used to indicate if the connection is established
|
||||
|
@ -141,6 +141,7 @@ private:
|
|||
uint16_t l2cap_event_flag; // l2cap flags of received bluetooth events
|
||||
|
||||
uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
|
||||
uint8_t l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap in data
|
||||
uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
|
||||
|
||||
/* L2CAP Channels */
|
||||
|
|
Loading…
Reference in a new issue