aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA/Drivers/USB
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-06-20 11:43:26 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-06-20 11:43:26 +0000
commit00d0883507efdc17688abafa75e81bf62f83d777 (patch)
treeefdf229555604f3c092557ac7ce638cf838dbdb2 /LUFA/Drivers/USB
parent35bdada24b49c4dd1900a78a1595077b99814cf9 (diff)
downloadlufa-00d0883507efdc17688abafa75e81bf62f83d777.tar.gz
lufa-00d0883507efdc17688abafa75e81bf62f83d777.tar.bz2
lufa-00d0883507efdc17688abafa75e81bf62f83d777.zip
Added USE_INTERNAL_SERIAL compile time option to automatically read out the internal unique serial number as the device's serial number descriptor on supported AVR models.
Diffstat (limited to 'LUFA/Drivers/USB')
-rw-r--r--LUFA/Drivers/USB/Class/Device/CDC.c6
-rw-r--r--LUFA/Drivers/USB/Class/Device/CDC.h24
-rw-r--r--LUFA/Drivers/USB/Class/Host/CDC.c28
-rw-r--r--LUFA/Drivers/USB/Class/Host/CDC.h24
-rw-r--r--LUFA/Drivers/USB/HighLevel/StdDescriptors.h8
-rw-r--r--LUFA/Drivers/USB/LowLevel/DevChapter9.c32
-rw-r--r--LUFA/Drivers/USB/LowLevel/DevChapter9.h12
7 files changed, 106 insertions, 28 deletions
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.c b/LUFA/Drivers/USB/Class/Device/CDC.c
index cc8161e0b..fc6ea93fb 100644
--- a/LUFA/Drivers/USB/Class/Device/CDC.c
+++ b/LUFA/Drivers/USB/Class/Device/CDC.c
@@ -74,7 +74,7 @@ void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_Device_t* CDCInterfaceInf
{
Endpoint_ClearSETUP();
- CDCInterfaceInfo->State.ControlLineState = USB_ControlRequest.wValue;
+ CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue;
EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
@@ -178,7 +178,7 @@ uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
return DataByte;
}
-void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, uint16_t LineStateMask)
+void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
{
if (!(USB_IsConnected))
return;
@@ -195,7 +195,7 @@ void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* CDCInterf
};
Endpoint_Write_Stream_LE(&Notification, sizeof(Notification), NO_STREAM_CALLBACK);
- Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask), NO_STREAM_CALLBACK);
+ Endpoint_Write_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost, sizeof(uint8_t), NO_STREAM_CALLBACK);
Endpoint_ClearIN();
}
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.h b/LUFA/Drivers/USB/Class/Device/CDC.h
index 13fa8d3b7..bcf8ff7b9 100644
--- a/LUFA/Drivers/USB/Class/Device/CDC.h
+++ b/LUFA/Drivers/USB/Class/Device/CDC.h
@@ -71,7 +71,15 @@
/** Current State information structure for \ref USB_ClassInfo_CDC_Device_t CDC device interface structures. */
typedef struct
{
- uint8_t ControlLineState; /**< Current control line states, as set by the host */
+ struct
+ {
+ uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
+ * masks.
+ */
+ uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
+ * masks.
+ */
+ } ControlLineStates;
struct
{
@@ -143,8 +151,8 @@
/** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a
* control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the
* user program by declaring a handler function with the same name and parameters listed here. The new control line states
- * are available in the ControlLineState value inside the CDC interface structure passed as a parameter, set as a mask of
- * CDC_CONTROL_LINE_OUT_* masks.
+ * are available in the ControlLineStates.HostToDevice value inside the CDC interface structure passed as a parameter, set as
+ * a mask of CDC_CONTROL_LINE_OUT_* masks.
*
* \param CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
*/
@@ -185,14 +193,14 @@
*/
uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo);
- /** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial control
- * lines (DCD, DSR, etc.) have changed states, or to give BREAK notfications to the host. Line states persist until they are
- * cleared via a second notification.
+ /** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial
+ * control lines (DCD, DSR, etc.) have changed states, or to give BREAK notfications to the host. Line states persist
+ * until they are cleared via a second notification. This should be called each time the CDC class driver's
+ * ControlLineStates.DeviceToHost value is updated to push the new states to the USB host.
*
* \param CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
- * \param LineStateMask Mask of CDC_CONTROL_LINE_IN_* masks giving the current control line states
*/
- void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo, uint16_t LineStateMask);
+ void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
diff --git a/LUFA/Drivers/USB/Class/Host/CDC.c b/LUFA/Drivers/USB/Class/Host/CDC.c
index aef5b3539..2d5ec0fb2 100644
--- a/LUFA/Drivers/USB/Class/Host/CDC.c
+++ b/LUFA/Drivers/USB/Class/Host/CDC.c
@@ -71,7 +71,6 @@ static uint8_t CDC_Host_ProcessConfigDescriptor(USB_ClassInfo_CDC_Host_t* CDCInt
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
{
- /* Descriptor not found, error out */
return CDC_ENUMERROR_NoCDCInterfaceFound;
}
}
@@ -149,10 +148,12 @@ static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
- /* Check the CDC descriptor class, subclass and protocol, break out if correct control interface found */
- if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class == CDC_CONTROL_CLASS) &&
- (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == CDC_CONTROL_SUBCLASS) &&
- (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == CDC_CONTROL_PROTOCOL))
+ USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
+ USB_Descriptor_Interface_t);
+
+ if ((CurrentInterface->Class == CDC_CONTROL_CLASS) &&
+ (CurrentInterface->SubClass == CDC_CONTROL_SUBCLASS) &&
+ (CurrentInterface->Protocol == CDC_CONTROL_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
@@ -165,10 +166,12 @@ static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* CurrentDescriptor)
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Interface)
{
- /* Check the CDC descriptor class, subclass and protocol, break out if correct data interface found */
- if ((DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Class == CDC_DATA_CLASS) &&
- (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).SubClass == CDC_DATA_SUBCLASS) &&
- (DESCRIPTOR_CAST(CurrentDescriptor, USB_Descriptor_Interface_t).Protocol == CDC_DATA_PROTOCOL))
+ USB_Descriptor_Interface_t* CurrentInterface = DESCRIPTOR_PCAST(CurrentDescriptor,
+ USB_Descriptor_Interface_t);
+
+ if ((CurrentInterface->Class == CDC_DATA_CLASS) &&
+ (CurrentInterface->SubClass == CDC_DATA_SUBCLASS) &&
+ (CurrentInterface->Protocol == CDC_DATA_PROTOCOL))
{
return DESCRIPTOR_SEARCH_Found;
}
@@ -181,8 +184,10 @@ static uint8_t DComp_CDC_Host_NextInterfaceCDCDataEndpoint(void* CurrentDescript
{
if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint)
{
- uint8_t EndpointType = (DESCRIPTOR_CAST(CurrentDescriptor,
- USB_Descriptor_Endpoint_t).Attributes & EP_TYPE_MASK);
+ USB_Descriptor_Endpoint_t* CurrentEndpoint = DESCRIPTOR_PCAST(CurrentDescriptor,
+ USB_Descriptor_Endpoint_t)
+
+ uint8_t EndpointType = (CurrentEndpoint->Attributes & EP_TYPE_MASK);
if ((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT))
return DESCRIPTOR_SEARCH_Found;
@@ -215,7 +220,6 @@ void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
USB_HostState = HOST_STATE_Configured;
break;
case HOST_STATE_Configured:
-
USB_HostState = HOST_STATE_Ready;
break;
}
diff --git a/LUFA/Drivers/USB/Class/Host/CDC.h b/LUFA/Drivers/USB/Class/Host/CDC.h
index 859c41d57..4054cf117 100644
--- a/LUFA/Drivers/USB/Class/Host/CDC.h
+++ b/LUFA/Drivers/USB/Class/Host/CDC.h
@@ -68,8 +68,16 @@
uint16_t DataOUTPipeSize; /**< Size in bytes of the CDC interface's OUT data pipe */
uint16_t NotificationPipeSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
- uint8_t ControlLineState; /**< Current control line states */
-
+ struct
+ {
+ uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
+ * masks.
+ */
+ uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
+ * masks.
+ */
+ } ControlLineStates;
+
struct
{
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
@@ -80,7 +88,7 @@
* CDCDevice_LineCodingParity_t enum
*/
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
- } LineEncoding;
+ } LineEncoding;
} USB_ClassInfo_CDC_Host_State_t;
/** Class state structure. An instance of this structure should be made within the user application,
@@ -138,6 +146,16 @@
static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* CurrentDescriptor);
static uint8_t DComp_CDC_Host_NextInterfaceCDCDataEndpoint(void* CurrentDescriptor);
#endif
+
+ void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
+
+ uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
+ uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
+
+ void CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, char* Data, uint16_t Length);
+ void CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, uint8_t Data);
+ uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
+ uint8_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
#endif
diff --git a/LUFA/Drivers/USB/HighLevel/StdDescriptors.h b/LUFA/Drivers/USB/HighLevel/StdDescriptors.h
index 7a0ca52b3..2ce75b2d9 100644
--- a/LUFA/Drivers/USB/HighLevel/StdDescriptors.h
+++ b/LUFA/Drivers/USB/HighLevel/StdDescriptors.h
@@ -244,7 +244,13 @@
*/
uint8_t SerialNumStrIndex; /**< String index for the product's globally unique hexadecimal
* serial number, in uppercase Unicode ASCII.
- *
+ *
+ * \note On some AVR models, there is an embedded serial number
+ * in the chip which can be used for the device serial number.
+ * To use this serial number, define USE_INTERNAL_SERIAL to a
+ * unique string index number in the project makefile and set
+ * this value to USE_INTERNAL_SERIAL.
+ *
* \see ManufacturerStrIndex structure entry.
*/
diff --git a/LUFA/Drivers/USB/LowLevel/DevChapter9.c b/LUFA/Drivers/USB/LowLevel/DevChapter9.c
index 829bd13e8..9acf30099 100644
--- a/LUFA/Drivers/USB/LowLevel/DevChapter9.c
+++ b/LUFA/Drivers/USB/LowLevel/DevChapter9.c
@@ -179,6 +179,36 @@ static void USB_Device_GetDescriptor(void)
void* DescriptorPointer;
uint16_t DescriptorSize;
+ #if defined(USE_INTERNAL_SERIAL)
+ if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
+ {
+ uint8_t SignatureDescriptor[2 + (sizeof(int16_t) * 20)];
+
+ SignatureDescriptor[0] = sizeof(SignatureDescriptor);
+ SignatureDescriptor[1] = DTYPE_String;
+
+ uint16_t* SigUnicodeChars = (uint16_t*)&SignatureDescriptor[2];
+
+ for (uint8_t SerialByteNum = 0; SerialByteNum < 10; SerialByteNum++)
+ {
+ char ConvSigString[3];
+
+ itoa(boot_signature_byte_get(0x0E + SerialByteNum), ConvSigString, 16);
+
+ SigUnicodeChars[0] = toupper(ConvSigString[0]);
+ SigUnicodeChars[1] = toupper(ConvSigString[1]);
+
+ SigUnicodeChars += 2;
+ }
+
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Control_Stream_LE(SignatureDescriptor, sizeof(SignatureDescriptor));
+ Endpoint_ClearOUT();
+
+ return;
+ }
+ #endif
+
if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
&DescriptorPointer)) == NO_DESCRIPTOR)
{
@@ -186,7 +216,7 @@ static void USB_Device_GetDescriptor(void)
}
Endpoint_ClearSETUP();
-
+
#if defined(USE_RAM_DESCRIPTORS)
Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
#else
diff --git a/LUFA/Drivers/USB/LowLevel/DevChapter9.h b/LUFA/Drivers/USB/LowLevel/DevChapter9.h
index 68cb2c448..65fa0418c 100644
--- a/LUFA/Drivers/USB/LowLevel/DevChapter9.h
+++ b/LUFA/Drivers/USB/LowLevel/DevChapter9.h
@@ -35,6 +35,9 @@
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
+ #include <avr/boot.h>
+ #include <stdlib.h>
+ #include <ctype.h>
#include "../HighLevel/StdDescriptors.h"
#include "../HighLevel/Events.h"
@@ -42,6 +45,15 @@
#include "../HighLevel/USBTask.h"
#include "LowLevel.h"
+ /* Preprocessor Checks: */
+ #if defined(USE_INTERNAL_SERIAL) && !(defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
+ #error USE_INTERNAL_SERIAL invalid, the selected AVR model does not contain unique serial bytes.
+ #endif
+
+ #if defined(USE_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL <= 1)
+ #error USE_INTERNAL_SERIAL must be defined to the string descriptor index chosen for the serial number descriptor.
+ #endif
+
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {