Added ability to search by Channel PSM to the GetChannelData() function in the BluetoothHost demo.

Added new HCI states to properly initialize the bluetooth dongle and retrieve the local BDADDR.

Factored out Bluetooth state information into a new state structure for easy reference in the user application.

Added new StackInitialized() Bluetooth stack callback function.
pull/1469/head
Dean Camera 15 years ago
parent 8252b4febd
commit 5993e1efe7

@ -36,6 +36,14 @@
#include "BluetoothHost.h" #include "BluetoothHost.h"
/** Bluetooth configuration structure. This structure configures the bluetooth stack's user alterable settings. */
Bluetooth_Device_t Bluetooth_DeviceConfiguration =
{
Class: (DEVICE_CLASS_SERVICE_CAPTURING | DEVICE_CLASS_MAJOR_COMPUTER | DEVICE_CLASS_MINOR_COMPUTER_PALM),
PINCode: "0000",
Name: "LUFA Bluetooth Demo"
};
/** Main program entry point. This routine configures the hardware required by the application, then /** Main program entry point. This routine configures the hardware required by the application, then
* enters a loop to run the application tasks in sequence. * enters a loop to run the application tasks in sequence.
*/ */
@ -196,6 +204,16 @@ void Bluetooth_Host_Task(void)
} }
} }
/** Bluetooth stack callback event for when the Bluetooth stack has fully initialized using the attached
* Bluetooth dongle.
*/
void Bluetooth_StackInitialized(void)
{
printf_P(PSTR("Stack initialized with local address %02X:%02X:%02X:%02X:%02X:%02X.\r\n"),
Bluetooth_State.LocalBDADDR[5], Bluetooth_State.LocalBDADDR[4], Bluetooth_State.LocalBDADDR[3],
Bluetooth_State.LocalBDADDR[2], Bluetooth_State.LocalBDADDR[1], Bluetooth_State.LocalBDADDR[0]);
}
/** Bluetooth stack callback event for a Bluetooth connection request. When this callback fires, the /** Bluetooth stack callback event for a Bluetooth connection request. When this callback fires, the
* user application must indicate if the connection is to be allowed or rejected. * user application must indicate if the connection is to be allowed or rejected.
* *
@ -205,7 +223,7 @@ void Bluetooth_Host_Task(void)
*/ */
bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress) bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress)
{ {
printf_P(PSTR("Connection Request from Device %02X:%02X:%02X:%02X:%02X:%02X\r\n"), printf_P(PSTR("Connection Request from Device %02X:%02X:%02X:%02X:%02X:%02X.\r\n"),
RemoteAddress[5], RemoteAddress[4], RemoteAddress[3], RemoteAddress[2], RemoteAddress[5], RemoteAddress[4], RemoteAddress[3], RemoteAddress[2],
RemoteAddress[1], RemoteAddress[0]); RemoteAddress[1], RemoteAddress[0]);
@ -218,7 +236,7 @@ bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress)
*/ */
void Bluetooth_ConnectionComplete(void) void Bluetooth_ConnectionComplete(void)
{ {
printf_P(PSTR("Connection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X\r\n"), printf_P(PSTR("Connection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X.\r\n"),
Bluetooth_Connection.RemoteAddress[5], Bluetooth_Connection.RemoteAddress[4], Bluetooth_Connection.RemoteAddress[5], Bluetooth_Connection.RemoteAddress[4],
Bluetooth_Connection.RemoteAddress[3], Bluetooth_Connection.RemoteAddress[2], Bluetooth_Connection.RemoteAddress[3], Bluetooth_Connection.RemoteAddress[2],
Bluetooth_Connection.RemoteAddress[1], Bluetooth_Connection.RemoteAddress[0]); Bluetooth_Connection.RemoteAddress[1], Bluetooth_Connection.RemoteAddress[0]);
@ -231,7 +249,7 @@ void Bluetooth_ConnectionComplete(void)
*/ */
void Bluetooth_DisconnectionComplete(void) void Bluetooth_DisconnectionComplete(void)
{ {
printf_P(PSTR("Disconnection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X\r\n"), printf_P(PSTR("Disconnection Complete to Device %02X:%02X:%02X:%02X:%02X:%02X.\r\n"),
Bluetooth_Connection.RemoteAddress[5], Bluetooth_Connection.RemoteAddress[4], Bluetooth_Connection.RemoteAddress[5], Bluetooth_Connection.RemoteAddress[4],
Bluetooth_Connection.RemoteAddress[3], Bluetooth_Connection.RemoteAddress[2], Bluetooth_Connection.RemoteAddress[3], Bluetooth_Connection.RemoteAddress[2],
Bluetooth_Connection.RemoteAddress[1], Bluetooth_Connection.RemoteAddress[0]); Bluetooth_Connection.RemoteAddress[1], Bluetooth_Connection.RemoteAddress[0]);

@ -28,6 +28,12 @@
this software. this software.
*/ */
/*
TODO: Make SendPacket respect receiver's MTU
TODO: Make ReceivePacket stitch together MTU fragments (?)
TODO: Add channel opened/closed callbacks
*/
#define INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C #define INCLUDE_FROM_BLUETOOTH_ACLPACKETS_C
#include "BluetoothACLPackets.h" #include "BluetoothACLPackets.h"
@ -187,7 +193,8 @@ static void Bluetooth_ProcessIncommingACLPackets(void)
Pipe_ClearIN(); Pipe_ClearIN();
Pipe_Freeze(); Pipe_Freeze();
Bluetooth_PacketReceived(PacketData, DataHeader.PayloadLength, Bluetooth_GetChannelData(DataHeader.DestinationChannel, false)); Bluetooth_PacketReceived(PacketData, DataHeader.PayloadLength,
Bluetooth_GetChannelData(DataHeader.DestinationChannel, CHANNEL_SEARCH_LOCALNUMBER));
} }
} }
@ -362,7 +369,7 @@ static inline void Bluetooth_Signal_ConnectionReq(const BT_Signal_Header_t* cons
BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel); BT_ACL_DEBUG(2, "-- Source Channel: 0x%04X", ConnectionRequest.SourceChannel);
/* Try to retrieve the existing channel's information structure if it exists */ /* Try to retrieve the existing channel's information structure if it exists */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionRequest.SourceChannel, true); Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionRequest.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);
/* If an existing channel item with the correct remote channel number was not found, find a free channel entry */ /* If an existing channel item with the correct remote channel number was not found, find a free channel entry */
if (ChannelData == NULL) if (ChannelData == NULL)
@ -447,7 +454,7 @@ static inline void Bluetooth_Signal_ConnectionResp(const BT_Signal_Header_t* con
BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel); BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConnectionResponse.DestinationChannel);
/* Search for the referenced channel in the channel information list */ /* Search for the referenced channel in the channel information list */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionResponse.SourceChannel, false); Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConnectionResponse.SourceChannel, CHANNEL_SEARCH_LOCALNUMBER);
/* Only progress if the referenced channel data was found */ /* Only progress if the referenced channel data was found */
if (ChannelData != NULL) if (ChannelData != NULL)
@ -478,7 +485,7 @@ static inline void Bluetooth_Signal_ConfigurationReq(const BT_Signal_Header_t* c
Pipe_Freeze(); Pipe_Freeze();
/* Search for the referenced channel in the channel information list */ /* Search for the referenced channel in the channel information list */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, false); Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationRequest.DestinationChannel, CHANNEL_SEARCH_LOCALNUMBER);
BT_ACL_DEBUG(1, "<< L2CAP Configuration Request"); BT_ACL_DEBUG(1, "<< L2CAP Configuration Request");
BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel); BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", ConfigurationRequest.DestinationChannel);
@ -564,7 +571,7 @@ static inline void Bluetooth_Signal_ConfigurationResp(const BT_Signal_Header_t*
BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConfigurationResponse.Result); BT_ACL_DEBUG(2, "-- Result: 0x%02X", ConfigurationResponse.Result);
/* Search for the referenced channel in the channel information list */ /* Search for the referenced channel in the channel information list */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationResponse.SourceChannel, true); Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(ConfigurationResponse.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);
/* Only update the channel's state if it was found in the channel list */ /* Only update the channel's state if it was found in the channel list */
if (ChannelData != NULL) if (ChannelData != NULL)
@ -608,7 +615,7 @@ static inline void Bluetooth_Signal_DisconnectionReq(const BT_Signal_Header_t* c
Pipe_Freeze(); Pipe_Freeze();
/* Search for the referenced channel in the channel information list */ /* Search for the referenced channel in the channel information list */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, true); Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionRequest.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);
struct struct
{ {
@ -654,7 +661,7 @@ static inline void Bluetooth_Signal_DisconnectionResp(const BT_Signal_Header_t*
Pipe_Freeze(); Pipe_Freeze();
/* Search for the referenced channel in the channel information list */ /* Search for the referenced channel in the channel information list */
Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionResponse.SourceChannel, true); Bluetooth_Channel_t* ChannelData = Bluetooth_GetChannelData(DisconnectionResponse.SourceChannel, CHANNEL_SEARCH_REMOTENUMBER);
/* If the channel was found in the channel list, close it */ /* If the channel was found in the channel list, close it */
if (ChannelData != NULL) if (ChannelData != NULL)

@ -31,16 +31,9 @@
#define INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C #define INCLUDE_FROM_BLUETOOTHHCICOMMANDS_C
#include "BluetoothHCICommands.h" #include "BluetoothHCICommands.h"
/** Current processing state of the HCI portion of the Bluetooth stack. */
uint8_t Bluetooth_HCIProcessingState;
/** Next HCI state to enter once the last issued HCI command has completed. */
static uint8_t Bluetooth_HCINextState;
/** Temporary Bluetooth Device Address, for HCI responses which much include the detination address */ /** Temporary Bluetooth Device Address, for HCI responses which much include the detination address */
static uint8_t Bluetooth_TempDeviceAddress[6]; static uint8_t Bluetooth_TempDeviceAddress[6];
/** Bluetooth HCI processing task. This task should be called repeatedly the main Bluetooth /** Bluetooth HCI processing task. This task should be called repeatedly the main Bluetooth
* stack task to manage the HCI processing state. * stack task to manage the HCI processing state.
*/ */
@ -48,7 +41,7 @@ void Bluetooth_HCITask(void)
{ {
BT_HCICommand_Header_t HCICommandHeader; BT_HCICommand_Header_t HCICommandHeader;
switch (Bluetooth_HCIProcessingState) switch (Bluetooth_State.CurrentHCIState)
{ {
case Bluetooth_ProcessEvents: case Bluetooth_ProcessEvents:
Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE); Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE);
@ -74,7 +67,19 @@ void Bluetooth_HCITask(void)
{ {
case EVENT_COMMAND_COMPLETE: case EVENT_COMMAND_COMPLETE:
BT_HCI_DEBUG(1, "<< Command Complete"); BT_HCI_DEBUG(1, "<< Command Complete");
Bluetooth_HCIProcessingState = Bluetooth_HCINextState;
/* Check which operation was completed in case we need to process the even parameters */
switch (((BT_HCIEvent_CommandComplete_t*)&EventParams)->Opcode)
{
case (OGF_CTRLR_INFORMATIONAL | OCF_CTRLR_INFORMATIONAL_READBDADDR):
/* A READ BDADDR command completed, copy over the local device's BDADDR from the response */
memcpy(Bluetooth_State.LocalBDADDR,
&((BT_HCIEvent_CommandComplete_t*)&EventParams)->ReturnParams[1],
sizeof(Bluetooth_State.LocalBDADDR));
break;
}
Bluetooth_State.CurrentHCIState = Bluetooth_State.NextHCIState;
break; break;
case EVENT_COMMAND_STATUS: case EVENT_COMMAND_STATUS:
BT_HCI_DEBUG(1, "<< Command Status"); BT_HCI_DEBUG(1, "<< Command Status");
@ -82,7 +87,7 @@ void Bluetooth_HCITask(void)
/* If the execution of a command failed, reset the stack */ /* If the execution of a command failed, reset the stack */
if (((BT_HCIEvent_CommandStatus_t*)&EventParams)->Status) if (((BT_HCIEvent_CommandStatus_t*)&EventParams)->Status)
Bluetooth_HCIProcessingState = Bluetooth_Init; Bluetooth_State.CurrentHCIState = Bluetooth_Init;
break; break;
case EVENT_CONNECTION_REQUEST: case EVENT_CONNECTION_REQUEST:
BT_HCI_DEBUG(1, "<< Connection Request"); BT_HCI_DEBUG(1, "<< Connection Request");
@ -97,11 +102,11 @@ void Bluetooth_HCITask(void)
/* Only accept the connection if it is a ACL (data) connection, a device is not already connected /* Only accept the connection if it is a ACL (data) connection, a device is not already connected
and the user application has indicated that the connection should be allowed */ and the user application has indicated that the connection should be allowed */
Bluetooth_HCIProcessingState = (Bluetooth_Connection.IsConnected || !(IsACLConnection) || Bluetooth_State.CurrentHCIState = (Bluetooth_Connection.IsConnected || !(IsACLConnection) ||
!(Bluetooth_ConnectionRequest(Bluetooth_TempDeviceAddress))) ? !(Bluetooth_ConnectionRequest(Bluetooth_TempDeviceAddress))) ?
Bluetooth_Conn_RejectConnection : Bluetooth_Conn_AcceptConnection; Bluetooth_Conn_RejectConnection : Bluetooth_Conn_AcceptConnection;
BT_HCI_DEBUG(2, "-- Connection %S", (Bluetooth_HCIProcessingState == Bluetooth_Conn_RejectConnection) ? BT_HCI_DEBUG(2, "-- Connection %S", (Bluetooth_State.CurrentHCIState == Bluetooth_Conn_RejectConnection) ?
PSTR("REJECTED") : PSTR("ACCEPTED")); PSTR("REJECTED") : PSTR("ACCEPTED"));
break; break;
@ -113,7 +118,7 @@ void Bluetooth_HCITask(void)
&((BT_HCIEvent_PinCodeReq_t*)&EventParams)->RemoteAddress, &((BT_HCIEvent_PinCodeReq_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress)); sizeof(Bluetooth_TempDeviceAddress));
Bluetooth_HCIProcessingState = Bluetooth_Conn_SendPINCode; Bluetooth_State.CurrentHCIState = Bluetooth_Conn_SendPINCode;
break; break;
case EVENT_LINK_KEY_REQUEST: case EVENT_LINK_KEY_REQUEST:
BT_HCI_DEBUG(1, "<< Link Key Request"); BT_HCI_DEBUG(1, "<< Link Key Request");
@ -123,7 +128,7 @@ void Bluetooth_HCITask(void)
&((BT_HCIEvent_LinkKeyReq_t*)&EventParams)->RemoteAddress, &((BT_HCIEvent_LinkKeyReq_t*)&EventParams)->RemoteAddress,
sizeof(Bluetooth_TempDeviceAddress)); sizeof(Bluetooth_TempDeviceAddress));
Bluetooth_HCIProcessingState = Bluetooth_Conn_SendLinkKeyNAK; Bluetooth_State.CurrentHCIState = Bluetooth_Conn_SendLinkKeyNAK;
break; break;
case EVENT_CONNECTION_COMPLETE: case EVENT_CONNECTION_COMPLETE:
BT_HCI_DEBUG(1, "<< Connection Complete"); BT_HCI_DEBUG(1, "<< Connection Complete");
@ -148,7 +153,7 @@ void Bluetooth_HCITask(void)
Bluetooth_DisconnectionComplete(); Bluetooth_DisconnectionComplete();
Bluetooth_HCIProcessingState = Bluetooth_Init; Bluetooth_State.CurrentHCIState = Bluetooth_Init;
break; break;
} }
} }
@ -159,62 +164,94 @@ void Bluetooth_HCITask(void)
case Bluetooth_Init: case Bluetooth_Init:
BT_HCI_DEBUG(1, "# Init"); BT_HCI_DEBUG(1, "# Init");
Bluetooth_State.IsInitialized = false;
/* Reset the connection information structure to destroy any previous connection state */ /* Reset the connection information structure to destroy any previous connection state */
memset(&Bluetooth_Connection, 0x00, sizeof(Bluetooth_Connection)); memset(&Bluetooth_Connection, 0x00, sizeof(Bluetooth_Connection));
Bluetooth_HCIProcessingState = Bluetooth_Init_Reset; Bluetooth_State.CurrentHCIState = Bluetooth_Init_Reset;
break; break;
case Bluetooth_Init_Reset: case Bluetooth_Init_Reset:
BT_HCI_DEBUG(1, "# Reset"); BT_HCI_DEBUG(1, "# Reset");
HCICommandHeader = (BT_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_RESET}, OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_RESET),
ParameterLength: 0, ParameterLength: 0,
}; };
/* Send the command to reset the bluetooth dongle controller */ /* Send the command to reset the bluetooth dongle controller */
Bluetooth_SendHCICommand(&HCICommandHeader, NULL, 0); Bluetooth_SendHCICommand(&HCICommandHeader, NULL, 0);
Bluetooth_HCINextState = Bluetooth_Init_SetLocalName; Bluetooth_State.NextHCIState = Bluetooth_Init_ReadBufferSize;
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Init_ReadBufferSize:
BT_HCI_DEBUG(1, "# Read Buffer Size");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: (OGF_CTRLR_INFORMATIONAL | OCF_CTRLR_INFORMATIONAL_READBUFFERSIZE),
ParameterLength: 0,
};
/* Send the command to read the bluetooth buffer size (mandatory before device sends any data) */
Bluetooth_SendHCICommand(&HCICommandHeader, NULL, 0);
Bluetooth_State.NextHCIState = Bluetooth_Init_GetBDADDR;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Init_GetBDADDR:
BT_HCI_DEBUG(1, "# Get BDADDR");
HCICommandHeader = (BT_HCICommand_Header_t)
{
OpCode: (OGF_CTRLR_INFORMATIONAL | OCF_CTRLR_INFORMATIONAL_READBDADDR),
ParameterLength: 0,
};
/* Send the command to retrieve the BDADDR of the inserted bluetooth dongle */
Bluetooth_SendHCICommand(&HCICommandHeader, NULL, 0);
Bluetooth_State.NextHCIState = Bluetooth_Init_SetLocalName;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Init_SetLocalName: case Bluetooth_Init_SetLocalName:
BT_HCI_DEBUG(1, "# Set Local Name"); BT_HCI_DEBUG(1, "# Set Local Name");
HCICommandHeader = (BT_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME}, OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_LOCAL_NAME),
ParameterLength: 248, ParameterLength: 248,
}; };
/* Send the command to set the bluetooth dongle's name for other devices to see */ /* Send the command to set the bluetooth dongle's name for other devices to see */
Bluetooth_SendHCICommand(&HCICommandHeader, Bluetooth_DeviceConfiguration.Name, strlen(Bluetooth_DeviceConfiguration.Name)); Bluetooth_SendHCICommand(&HCICommandHeader, Bluetooth_DeviceConfiguration.Name, strlen(Bluetooth_DeviceConfiguration.Name));
Bluetooth_HCINextState = Bluetooth_Init_SetDeviceClass; Bluetooth_State.NextHCIState = Bluetooth_Init_SetDeviceClass;
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Init_SetDeviceClass: case Bluetooth_Init_SetDeviceClass:
BT_HCI_DEBUG(1, "# Set Device Class"); BT_HCI_DEBUG(1, "# Set Device Class");
HCICommandHeader = (BT_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE}, OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE),
ParameterLength: 3, ParameterLength: 3,
}; };
/* Send the command to set the class of the device for other devices to see */ /* Send the command to set the class of the device for other devices to see */
Bluetooth_SendHCICommand(&HCICommandHeader, &Bluetooth_DeviceConfiguration.Class, 3); Bluetooth_SendHCICommand(&HCICommandHeader, &Bluetooth_DeviceConfiguration.Class, 3);
Bluetooth_HCINextState = Bluetooth_Init_WriteScanEnable; Bluetooth_State.NextHCIState = Bluetooth_Init_WriteScanEnable;
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Init_WriteScanEnable: case Bluetooth_Init_WriteScanEnable:
BT_HCI_DEBUG(1, "# Write Scan Enable"); BT_HCI_DEBUG(1, "# Write Scan Enable");
HCICommandHeader = (BT_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_CTRLR_BASEBAND, OCF: OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE}, OpCode: (OGF_CTRLR_BASEBAND | OCF_CTRLR_BASEBAND_WRITE_SCAN_ENABLE),
ParameterLength: 1, ParameterLength: 1,
}; };
@ -223,15 +260,24 @@ void Bluetooth_HCITask(void)
/* Send the command to set the remote device scanning mode */ /* Send the command to set the remote device scanning mode */
Bluetooth_SendHCICommand(&HCICommandHeader, &Interval, 1); Bluetooth_SendHCICommand(&HCICommandHeader, &Interval, 1);
Bluetooth_HCINextState = Bluetooth_ProcessEvents; Bluetooth_State.NextHCIState = Bluetooth_Init_FinalizeInit;
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break;
case Bluetooth_Init_FinalizeInit:
Bluetooth_State.IsInitialized = true;
/* Fire the user application callback to indicate that the stack is now fully initialized */
Bluetooth_StackInitialized();
Bluetooth_State.NextHCIState = Bluetooth_ProcessEvents;
Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Conn_AcceptConnection: case Bluetooth_Conn_AcceptConnection:
BT_HCI_DEBUG(1, "# Accept Connection"); BT_HCI_DEBUG(1, "# Accept Connection");
HCICommandHeader = (BT_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST}, OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_ACCEPT_CONNECTION_REQUEST),
ParameterLength: sizeof(BT_HCICommand_AcceptConnectionReq_t), ParameterLength: sizeof(BT_HCICommand_AcceptConnectionReq_t),
}; };
@ -245,14 +291,14 @@ void Bluetooth_HCITask(void)
/* Send the command to accept the remote connection request */ /* Send the command to accept the remote connection request */
Bluetooth_SendHCICommand(&HCICommandHeader, &AcceptConnectionParams, sizeof(BT_HCICommand_AcceptConnectionReq_t)); Bluetooth_SendHCICommand(&HCICommandHeader, &AcceptConnectionParams, sizeof(BT_HCICommand_AcceptConnectionReq_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Conn_RejectConnection: case Bluetooth_Conn_RejectConnection:
BT_HCI_DEBUG(1, "# Reject Connection"); BT_HCI_DEBUG(1, "# Reject Connection");
HCICommandHeader = (BT_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST}, OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_REJECT_CONNECTION_REQUEST),
ParameterLength: sizeof(BT_HCICommand_RejectConnectionReq_t), ParameterLength: sizeof(BT_HCICommand_RejectConnectionReq_t),
}; };
@ -265,14 +311,14 @@ void Bluetooth_HCITask(void)
/* Send the command to reject the remote connection request */ /* Send the command to reject the remote connection request */
Bluetooth_SendHCICommand(&HCICommandHeader, &RejectConnectionParams, sizeof(BT_HCICommand_RejectConnectionReq_t)); Bluetooth_SendHCICommand(&HCICommandHeader, &RejectConnectionParams, sizeof(BT_HCICommand_RejectConnectionReq_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Conn_SendPINCode: case Bluetooth_Conn_SendPINCode:
BT_HCI_DEBUG(1, "# Send Pin Code"); BT_HCI_DEBUG(1, "# Send Pin Code");
HCICommandHeader = (BT_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY}, OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_PIN_CODE_REQUEST_REPLY),
ParameterLength: sizeof(BT_HCICommand_PinCodeResp_t), ParameterLength: sizeof(BT_HCICommand_PinCodeResp_t),
}; };
@ -286,14 +332,14 @@ void Bluetooth_HCITask(void)
/* Send the command to transmit the device's local PIN number for authentication */ /* Send the command to transmit the device's local PIN number for authentication */
Bluetooth_SendHCICommand(&HCICommandHeader, &PINCodeRequestParams, sizeof(BT_HCICommand_PinCodeResp_t)); Bluetooth_SendHCICommand(&HCICommandHeader, &PINCodeRequestParams, sizeof(BT_HCICommand_PinCodeResp_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break; break;
case Bluetooth_Conn_SendLinkKeyNAK: case Bluetooth_Conn_SendLinkKeyNAK:
BT_HCI_DEBUG(1, "# Send Link Key NAK"); BT_HCI_DEBUG(1, "# Send Link Key NAK");
HCICommandHeader = (BT_HCICommand_Header_t) HCICommandHeader = (BT_HCICommand_Header_t)
{ {
OpCode: {OGF: OGF_LINK_CONTROL, OCF: OCF_LINK_CONTROL_LINK_KEY_REQUEST_NEG_REPLY}, OpCode: (OGF_LINK_CONTROL | OCF_LINK_CONTROL_LINK_KEY_REQUEST_NEG_REPLY),
ParameterLength: sizeof(BT_HCICommand_LinkKeyNAKResp_t), ParameterLength: sizeof(BT_HCICommand_LinkKeyNAKResp_t),
}; };
@ -304,7 +350,7 @@ void Bluetooth_HCITask(void)
/* Send the command to transmit the link key NAK to the receiver */ /* Send the command to transmit the link key NAK to the receiver */
Bluetooth_SendHCICommand(&HCICommandHeader, &LinkKeyNAKParams, sizeof(BT_HCICommand_LinkKeyNAKResp_t)); Bluetooth_SendHCICommand(&HCICommandHeader, &LinkKeyNAKParams, sizeof(BT_HCICommand_LinkKeyNAKResp_t));
Bluetooth_HCIProcessingState = Bluetooth_ProcessEvents; Bluetooth_State.CurrentHCIState = Bluetooth_ProcessEvents;
break; break;
} }
} }

@ -47,9 +47,9 @@
#define BT_HCI_DEBUG(l, s, ...) do { if (HCI_DEBUG_LEVEL >= l) printf_P(PSTR("(HCI) " s "\r\n"), ##__VA_ARGS__); } while (0) #define BT_HCI_DEBUG(l, s, ...) do { if (HCI_DEBUG_LEVEL >= l) printf_P(PSTR("(HCI) " s "\r\n"), ##__VA_ARGS__); } while (0)
#define HCI_DEBUG_LEVEL 0 #define HCI_DEBUG_LEVEL 0
#define OGF_LINK_CONTROL 0x01 #define OGF_LINK_CONTROL (0x01 << 10)
#define OGF_CTRLR_BASEBAND 0x03 #define OGF_CTRLR_BASEBAND (0x03 << 10)
#define OGF_CTRLR_INFORMATIONAL 0x04 #define OGF_CTRLR_INFORMATIONAL (0x04 << 10)
#define OCF_LINK_CONTROL_INQUIRY 0x0001 #define OCF_LINK_CONTROL_INQUIRY 0x0001
#define OCF_LINK_CONTROL_INQUIRY_CANCEL 0x0002 #define OCF_LINK_CONTROL_INQUIRY_CANCEL 0x0002
@ -75,7 +75,8 @@
#define OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE 0x0024 #define OCF_CTRLR_BASEBAND_WRITE_CLASS_OF_DEVICE 0x0024
#define OCF_CTRLR_BASEBAND_WRITE_SIMPLE_PAIRING_MODE 0x0056 #define OCF_CTRLR_BASEBAND_WRITE_SIMPLE_PAIRING_MODE 0x0056
#define OCF_CTRLR_BASEBAND_WRITE_AUTHENTICATION_ENABLE 0x0020 #define OCF_CTRLR_BASEBAND_WRITE_AUTHENTICATION_ENABLE 0x0020
#define OGF_CTRLR_INFORMATIONAL_READBUFFERSIZE 0x0005 #define OCF_CTRLR_INFORMATIONAL_READBUFFERSIZE 0x0005
#define OCF_CTRLR_INFORMATIONAL_READBDADDR 0x0009
#define EVENT_COMMAND_STATUS 0x0F #define EVENT_COMMAND_STATUS 0x0F
#define EVENT_COMMAND_COMPLETE 0x0E #define EVENT_COMMAND_COMPLETE 0x0E
@ -92,12 +93,7 @@
/* Type Defines: */ /* Type Defines: */
typedef struct typedef struct
{ {
struct uint16_t OpCode;
{
int OCF : 10;
int OGF : 6;
} OpCode;
uint8_t ParameterLength; uint8_t ParameterLength;
uint8_t Parameters[]; uint8_t Parameters[];
} BT_HCICommand_Header_t; } BT_HCICommand_Header_t;
@ -112,17 +108,12 @@
{ {
uint8_t Status; uint8_t Status;
uint8_t Packets; uint8_t Packets;
uint16_t OpCode;
struct
{
int OCF : 10;
int OGF : 6;
} OpCode;
} BT_HCIEvent_CommandStatus_t; } BT_HCIEvent_CommandStatus_t;
typedef struct typedef struct
{ {
uint8_t HCLPacketsAllowable; uint8_t HCIPacketsAllowable;
uint16_t Opcode; uint16_t Opcode;
uint8_t ReturnParams[]; uint8_t ReturnParams[];
} BT_HCIEvent_CommandComplete_t; } BT_HCIEvent_CommandComplete_t;
@ -192,18 +183,18 @@
Bluetooth_ProcessEvents = 0, Bluetooth_ProcessEvents = 0,
Bluetooth_Init = 1, Bluetooth_Init = 1,
Bluetooth_Init_Reset = 2, Bluetooth_Init_Reset = 2,
Bluetooth_Init_SetLocalName = 3, Bluetooth_Init_ReadBufferSize = 3,
Bluetooth_Init_SetDeviceClass = 4, Bluetooth_Init_GetBDADDR = 4,
Bluetooth_Init_WriteScanEnable = 5, Bluetooth_Init_SetLocalName = 5,
Bluetooth_Conn_AcceptConnection = 6, Bluetooth_Init_SetDeviceClass = 6,
Bluetooth_Conn_RejectConnection = 7, Bluetooth_Init_WriteScanEnable = 7,
Bluetooth_Conn_SendPINCode = 8, Bluetooth_Init_FinalizeInit = 8,
Bluetooth_Conn_SendLinkKeyNAK = 9, Bluetooth_Conn_AcceptConnection = 9,
Bluetooth_Conn_RejectConnection = 10,
Bluetooth_Conn_SendPINCode = 11,
Bluetooth_Conn_SendLinkKeyNAK = 12,
}; };
/* External Variables: */
extern uint8_t Bluetooth_HCIProcessingState;
/* Function Prototypes: */ /* Function Prototypes: */
void Bluetooth_HCITask(void); void Bluetooth_HCITask(void);

@ -35,25 +35,23 @@
*/ */
Bluetooth_Connection_t Bluetooth_Connection = { IsConnected: false }; Bluetooth_Connection_t Bluetooth_Connection = { IsConnected: false };
/** Bluetooth configuration structure. This structure configures the bluetooth stack's user alterable settings. */ /** Bluetooth device state information structure. This structure contains details on the current Bluetooth stack
Bluetooth_Device_t Bluetooth_DeviceConfiguration = * state.
{ */
Class: (DEVICE_CLASS_SERVICE_CAPTURING | DEVICE_CLASS_MAJOR_COMPUTER | DEVICE_CLASS_MINOR_COMPUTER_PALM), Bluetooth_Stack_State_t Bluetooth_State = { IsInitialized: false };
PINCode: "0000",
Name: "LUFA Bluetooth Demo"
};
/** Bluetooth stack initialization function. This function must be called once to initialize the Bluetooth stack, /** Bluetooth stack initialization function. This function must be called once to initialize the Bluetooth stack,
* ready for connection to remote devices. * ready for connection to remote devices.
* *
* \note This function only begins the initialization process; the stack is initialized as the main Bluetooth stack * \note This function only begins the initialization process; the stack is initialized as the main Bluetooth stack
* management task is repeatedly called. The initialization process ends when the \ref Bluetooth_HCIProcessingState * management task is repeatedly called. The initialization process ends when the IsInitialized element of the
* global enters the Bluetooth_ProcessEvents state. * \ref Bluetooth_State structure becomes true and the \ref Bluetooth_StackInitialized() callback fires.
*/ */
void Bluetooth_Stack_Init(void) void Bluetooth_Stack_Init(void)
{ {
/* Reset the HCI state machine - this will eventually reset the adapter and stack when the Bluetooth stack task is called */ /* Reset the HCI state machine - this will eventually reset the adapter and stack when the Bluetooth stack task is called */
Bluetooth_HCIProcessingState = Bluetooth_Init; Bluetooth_State.CurrentHCIState = Bluetooth_Init;
Bluetooth_State.NextHCIState = Bluetooth_Init;
} }
/** Bluetooth stack management task. This task must be repeatedly called to maintain the Bluetooth stack and any connection /** Bluetooth stack management task. This task must be repeatedly called to maintain the Bluetooth stack and any connection
@ -67,22 +65,33 @@ void Bluetooth_Stack_USBTask(void)
/** Retrieves the channel information structure with the given local or remote channel number from the channel list. /** Retrieves the channel information structure with the given local or remote channel number from the channel list.
* *
* \param[in] ChannelNumber Channel number to search for in the channel list * \param[in] SearchValue Value to search for in the channel structure list
* \param[in] SearchByRemoteChannel Indicated whether to search for a channel information structure by the given remote channel * \param[in] SearchKey Key to search within the channel structure, a CHANNEL_SEARCH_* mask
* or local channel number
* *
* \return Pointer to the matching channel information structure in the channel table if found, NULL otherwise * \return Pointer to the matching channel information structure in the channel table if found, NULL otherwise
*/ */
Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t ChannelNumber, const bool SearchByRemoteChannel) Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t SearchValue, const uint8_t SearchKey)
{ {
for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++) for (uint8_t i = 0; i < BLUETOOTH_MAX_OPEN_CHANNELS; i++)
{ {
Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i]; Bluetooth_Channel_t* ChannelData = &Bluetooth_Connection.Channels[i];
/* Fetch the channel number that is to be matched against from the current channel information struct */ bool FoundMatch = false;
uint16_t SearchChannelNumber = (SearchByRemoteChannel) ? ChannelData->RemoteNumber : ChannelData->LocalNumber;
switch (SearchKey)
{
case CHANNEL_SEARCH_LOCALNUMBER:
FoundMatch = (SearchValue == ChannelData->LocalNumber);
break;
case CHANNEL_SEARCH_REMOTENUMBER:
FoundMatch = (SearchValue == ChannelData->RemoteNumber);
break;
case CHANNEL_SEARCH_PSM:
FoundMatch = (SearchValue == ChannelData->PSM);
break;
}
if (SearchChannelNumber == ChannelNumber) if (FoundMatch)
return ChannelData; return ChannelData;
} }

@ -51,6 +51,10 @@
#define CHANNEL_PSM_UPNP 0x0010 #define CHANNEL_PSM_UPNP 0x0010
#define CHANNEL_PSM_HIDP 0x0011 #define CHANNEL_PSM_HIDP 0x0011
#define CHANNEL_SEARCH_LOCALNUMBER 0
#define CHANNEL_SEARCH_REMOTENUMBER 1
#define CHANNEL_SEARCH_PSM 2
#define MAXIMUM_CHANNEL_MTU 255 #define MAXIMUM_CHANNEL_MTU 255
/* Enums: */ /* Enums: */
@ -116,6 +120,20 @@
char Name[]; /**< Name of the local bluetooth device, up to 248 characters. */ char Name[]; /**< Name of the local bluetooth device, up to 248 characters. */
} Bluetooth_Device_t; } Bluetooth_Device_t;
/** Bluetooth stack state information structure, for the containment of the Bluetooth stack state. The values in
* this structure are set by the Bluetooth stack internally, and should all be treated as read only by the user
* application.
*/
typedef struct
{
uint8_t CurrentHCIState; /**< Current HCI state machine state. */
uint8_t NextHCIState; /**< Next HCI state machine state to progress to once the currently issued command completes. */
bool IsInitialized; /**< Indicates if the Bluetooth stack is currently initialized and ready for connections
* to or from a remote Bluetooth device.
*/
uint8_t LocalBDADDR[6]; /**< Local bluetooth adapter's BDADDR, valid when the stack is fully initialized. */
} Bluetooth_Stack_State_t;
/* Includes: */ /* Includes: */
#include "BluetoothHCICommands.h" #include "BluetoothHCICommands.h"
#include "BluetoothACLPackets.h" #include "BluetoothACLPackets.h"
@ -124,12 +142,13 @@
void Bluetooth_Stack_Init(void); void Bluetooth_Stack_Init(void);
void Bluetooth_Stack_USBTask(void); void Bluetooth_Stack_USBTask(void);
void Bluetooth_StackInitialized(void);
bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress); bool Bluetooth_ConnectionRequest(const uint8_t* RemoteAddress);
void Bluetooth_ConnectionComplete(void); void Bluetooth_ConnectionComplete(void);
void Bluetooth_DisconnectionComplete(void); void Bluetooth_DisconnectionComplete(void);
bool Bluetooth_ChannelConnectionRequest(const uint16_t PSM); bool Bluetooth_ChannelConnectionRequest(const uint16_t PSM);
void Bluetooth_PacketReceived(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel); void Bluetooth_PacketReceived(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel);
Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t ChannelNumber, const bool SearchByRemoteChannel); Bluetooth_Channel_t* Bluetooth_GetChannelData(const uint16_t SearchValue, const uint8_t SearchKey);
Bluetooth_Channel_t* Bluetooth_OpenChannel(const uint16_t PSM); Bluetooth_Channel_t* Bluetooth_OpenChannel(const uint16_t PSM);
void Bluetooth_CloseChannel(Bluetooth_Channel_t* const Channel); void Bluetooth_CloseChannel(Bluetooth_Channel_t* const Channel);
uint8_t Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel); uint8_t Bluetooth_SendPacket(void* Data, uint16_t DataLen, Bluetooth_Channel_t* const Channel);
@ -137,5 +156,6 @@
/* External Variables: */ /* External Variables: */
extern Bluetooth_Device_t Bluetooth_DeviceConfiguration; extern Bluetooth_Device_t Bluetooth_DeviceConfiguration;
extern Bluetooth_Connection_t Bluetooth_Connection; extern Bluetooth_Connection_t Bluetooth_Connection;
extern Bluetooth_Stack_State_t Bluetooth_State;
#endif #endif

@ -39,7 +39,7 @@ const ServiceAttributeTable_t SDP_Attribute_Table[] PROGMEM =
{.AttributeID = SDP_ATTRIBUTE_NAME , .AttributeData = &SDP_Attribute_Name}, {.AttributeID = SDP_ATTRIBUTE_NAME , .AttributeData = &SDP_Attribute_Name},
{.AttributeID = SDP_ATTRIBUTE_DESCRIPTION , .AttributeData = &SDP_Attribute_Description}, {.AttributeID = SDP_ATTRIBUTE_DESCRIPTION , .AttributeData = &SDP_Attribute_Description},
{.AttributeID = SDP_ATTRIBUTE_AVAILABILITY, .AttributeData = &SDP_Attribute_Availability}, {.AttributeID = SDP_ATTRIBUTE_AVAILABILITY, .AttributeData = &SDP_Attribute_Availability},
{.AttributeData = NULL} SERVICE_ATTRIBUTE_TABLE_TERMINATOR
}; };
SERVICE_ATTRIBUTE_TEXT(RFCOMM_Attribute_Name, "RFCOMM"); SERVICE_ATTRIBUTE_TEXT(RFCOMM_Attribute_Name, "RFCOMM");
@ -50,7 +50,7 @@ const ServiceAttributeTable_t RFCOMM_Attribute_Table[] PROGMEM =
{.AttributeID = SDP_ATTRIBUTE_NAME , .AttributeData = &RFCOMM_Attribute_Name}, {.AttributeID = SDP_ATTRIBUTE_NAME , .AttributeData = &RFCOMM_Attribute_Name},
{.AttributeID = SDP_ATTRIBUTE_DESCRIPTION , .AttributeData = &RFCOMM_Attribute_Description}, {.AttributeID = SDP_ATTRIBUTE_DESCRIPTION , .AttributeData = &RFCOMM_Attribute_Description},
{.AttributeID = SDP_ATTRIBUTE_AVAILABILITY, .AttributeData = &RFCOMM_Attribute_Availability}, {.AttributeID = SDP_ATTRIBUTE_AVAILABILITY, .AttributeData = &RFCOMM_Attribute_Availability},
{.AttributeData = NULL} SERVICE_ATTRIBUTE_TABLE_TERMINATOR
}; };
const ServiceTable_t SDP_Services_Table[] = const ServiceTable_t SDP_Services_Table[] =

@ -78,6 +78,7 @@
{.Header = (type | 5), .Size = size, .Data = __VA_ARGS__} {.Header = (type | 5), .Size = size, .Data = __VA_ARGS__}
#define SERVICE_ATTRIBUTE_32BIT_LEN(name, type, size, ...) const ServiceAttributeData32Bit_t name PROGMEM = \ #define SERVICE_ATTRIBUTE_32BIT_LEN(name, type, size, ...) const ServiceAttributeData32Bit_t name PROGMEM = \
{.Header = (type | 5), .Size = size, .Data = __VA_ARGS__} {.Header = (type | 5), .Size = size, .Data = __VA_ARGS__}
#define SERVICE_ATTRIBUTE_TABLE_TERMINATOR {.AttributeData = NULL}
/* Type Defines: */ /* Type Defines: */
typedef struct typedef struct

@ -12,7 +12,7 @@
* - Added incomplete MIDIToneGenerator project * - Added incomplete MIDIToneGenerator project
* - Added new Relay Controller Board project (thanks to OBinou) * - Added new Relay Controller Board project (thanks to OBinou)
* - Added board hardware driver support for the Teensy, USBTINY MKII, Benito and JM-DB-U2 lines of third party USB AVR boards * - Added board hardware driver support for the Teensy, USBTINY MKII, Benito and JM-DB-U2 lines of third party USB AVR boards
* - Added new ATTR_NO_INIT variable attribute * - Added new ATTR_NO_INIT variable attribute for global variables that should not be automatically cleared on startup
* *
* <b>Changed:</b> * <b>Changed:</b>
* - AVRISP programmer project now has a more robust timeout system, allowing for an increase of the software USART speed * - AVRISP programmer project now has a more robust timeout system, allowing for an increase of the software USART speed

@ -17,8 +17,10 @@
* It supports a large number of USB AVR models and boards (see \ref Page_DeviceSupport). It is designed to provide an easy to use, * It supports a large number of USB AVR models and boards (see \ref Page_DeviceSupport). It is designed to provide an easy to use,
* feature rich framework for the development of USB peripherals and hosts. * feature rich framework for the development of USB peripherals and hosts.
* *
* LUFA focuses on the microcontroller side of USB development only; it includes no host USB driver development facilities. While * LUFA focuses on the microcontroller side of USB development only; it includes no PC host USB driver development facilities - other projects
* custom USB devices can be made with LUFA, the included demos all use the inbuilt OS drivers for each USB class for simplicity. * such as the Windows Driver Development Kit, Windows USB Device Mode Framework and libusb may be of interest for developing custom OS drivers.
* While custom USB devices can be made with LUFA using such tools, the included demos all use the inbuilt OS drivers for each USB class for
* simplicity.
* *
* The library is currently in a stable release, suitable for download and incorporation into user projects for * The library is currently in a stable release, suitable for download and incorporation into user projects for
* both host and device modes. For information about the project progression, see the blog link at \ref Page_Resources. * both host and device modes. For information about the project progression, see the blog link at \ref Page_Resources.

@ -76,7 +76,7 @@ static ParameterItem_t ParameterTable[] =
{ .ParamID = PARAM_STATUS_TGT_CONN, { .ParamID = PARAM_STATUS_TGT_CONN,
.ParamPrivileges = PARAM_PRIV_READ, .ParamPrivileges = PARAM_PRIV_READ,
.ParamValue = 0x00 }, .ParamValue = STATUS_ISP_READY },
{ .ParamID = PARAM_DISCHARGEDELAY, { .ParamID = PARAM_DISCHARGEDELAY,
.ParamPrivileges = PARAM_PRIV_WRITE, .ParamPrivileges = PARAM_PRIV_WRITE,

Loading…
Cancel
Save