/*
LUFA Library
- Copyright (C) Dean Camera, 2014.
+ Copyright (C) Dean Camera, 2017.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
- Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+ Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
#include "AVRISPDescriptors.h"
-#if defined(RESET_TOGGLES_LIBUSB_COMPAT) || defined(__DOXYGEN__)
- /** Indicates if an external reset has occurred and the compatibility mode needs to be altered */
- static bool AVRISP_NeedCompatibilitySwitch ATTR_NO_INIT;
-
- /** Current AVRISP data IN endpoint address. */
- uint8_t AVRISP_CurrDataINEndpointAddress;
-
- /** Saved AVRISP data IN endpoint address in EEPROM. */
- uint8_t AVRISP_CurrDataINEndpointAddress_EEPROM EEMEM;
-#endif
-
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device.
*/
-AVRISP_USB_Descriptor_Configuration_t AVRISP_ConfigurationDescriptor =
+const AVRISP_USB_Descriptor_Configuration_t PROGMEM AVRISP_ConfigurationDescriptor =
{
.Config =
{
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-#if defined(RESET_TOGGLES_LIBUSB_COMPAT)
- .EndpointAddress = 0,
-#else
.EndpointAddress = AVRISP_DATA_IN_EPADDR,
-#endif
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = AVRISP_DATA_EPSIZE,
.PollingIntervalMS = 0x0A
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/
-const USB_Descriptor_String_t PROGMEM AVRISP_LanguageString =
-{
- .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
-
- .UnicodeString = {LANGUAGE_ID_ENG}
-};
+const USB_Descriptor_String_t PROGMEM AVRISP_LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG);
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
-const USB_Descriptor_String_t PROGMEM AVRISP_ManufacturerString =
-{
- .Header = {.Size = USB_STRING_LEN(5), .Type = DTYPE_String},
-
- .UnicodeString = L"ATMEL"
-};
+const USB_Descriptor_String_t PROGMEM AVRISP_ManufacturerString = USB_STRING_DESCRIPTOR(L"ATMEL");
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
-const USB_Descriptor_String_t PROGMEM AVRISP_ProductString =
-{
- .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
-
- .UnicodeString = L"AVRISP mkII"
-};
+const USB_Descriptor_String_t PROGMEM AVRISP_ProductString = USB_STRING_DESCRIPTOR(L"AVRISP mkII");
/** Serial number string. This is a Unicode string containing the device's unique serial number, expressed as a
* series of uppercase hexadecimal digits.
*/
-USB_Descriptor_String_t AVRISP_SerialString =
-{
- .Header = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String},
-
- .UnicodeString = L"000200012345\0" // Note: Real AVRISP-MKII has the embedded NUL byte, bug in firmware?
-};
+const USB_Descriptor_String_t PROGMEM AVRISP_SerialString = USB_STRING_DESCRIPTOR(L"000200012345\0"
+ // Note: Real AVRISP-MKII has the embedded NUL byte, bug in firmware?
+);
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given
* USB host.
*/
uint16_t AVRISP_GetDescriptor(const uint16_t wValue,
- const uint8_t wIndex,
- const void** const DescriptorAddress,
- uint8_t* DescriptorMemorySpace)
+ const uint16_t wIndex,
+ const void** const DescriptorAddress)
{
const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF);
const void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR;
- *DescriptorMemorySpace = MEMSPACE_FLASH;
-
switch (DescriptorType)
{
case DTYPE_Device:
Size = sizeof(USB_Descriptor_Device_t);
break;
case DTYPE_Configuration:
- *DescriptorMemorySpace = MEMSPACE_RAM;
- #if defined(RESET_TOGGLES_LIBUSB_COMPAT)
- /* Update the configuration descriptor with the current endpoint address */
- AVRISP_ConfigurationDescriptor.AVRISP_DataInEndpoint.EndpointAddress = AVRISP_CurrDataINEndpointAddress;
- #endif
-
Address = &AVRISP_ConfigurationDescriptor;
Size = sizeof(AVRISP_USB_Descriptor_Configuration_t);
break;
case AVRISP_STRING_ID_Serial:
Address = &AVRISP_SerialString;
Size = AVRISP_SerialString.Header.Size;
-
- /* Update serial number to have a different serial based on the current endpoint address */
- ((uint16_t*)&AVRISP_SerialString.UnicodeString)[6] = cpu_to_le16('0' + (AVRISP_DATA_IN_EPADDR & ENDPOINT_EPNUM_MASK));
-
- *DescriptorMemorySpace = MEMSPACE_RAM;
break;
}
*DescriptorAddress = Address;
return Size;
}
-
-#if defined(RESET_TOGGLES_LIBUSB_COMPAT) || defined(__DOXYGEN__)
-/** Checks the state of the system status register MCUSR and indicates via a flag if
- * the current AVRISP driver compatibility mode needs to be reset.
- *
- * When the \c RESET_TOGGLES_LIBUSB_COMPAT compile time option is enabled, pulling
- * the reset line of the AVR low will toggle between Jungo and libUSB compatibility
- * modes. Other forms of reset (such as power on or watchdog) will not force a mode
- * change.
- */
-void CheckExternalReset(void)
-{
- /* If an external reset occurred, we need to change compatibility mode */
- AVRISP_NeedCompatibilitySwitch = (MCUSR == (1 << EXTRF));
-
- MCUSR = 0;
-}
-
-/** Updates the device descriptors so that the correct compatibility mode is used
- * when the \c RESET_TOGGLES_LIBUSB_COMPAT compile time option is enabled. This
- * configures the programmer for either Jungo or libUSB driver compatibility. Each
- * time the AVR is reset via pulling the reset line low the compatibility mode will
- * be toggled. The current mode is stored in EEPROM and preserved through power
- * cycles of the AVR.
- */
-void UpdateCurrentCompatibilityMode(void)
-{
- /* Load the current IN endpoint address stored in EEPROM */
- AVRISP_CurrDataINEndpointAddress = eeprom_read_byte(&AVRISP_CurrDataINEndpointAddress_EEPROM);
-
- /* Check if we need to switch compatibility modes */
- if (AVRISP_NeedCompatibilitySwitch)
- {
- /* Toggle between compatibility modes */
- AVRISP_CurrDataINEndpointAddress = (AVRISP_CurrDataINEndpointAddress == AVRISP_DATA_IN_EPADDR_LIBUSB) ?
- AVRISP_DATA_IN_EPADDR_JUNGO : AVRISP_DATA_IN_EPADDR_LIBUSB;
-
- /* Save the new mode into EEPROM */
- eeprom_update_byte(&AVRISP_CurrDataINEndpointAddress_EEPROM, AVRISP_CurrDataINEndpointAddress);
- }
-
- LEDs_SetAllLEDs(LEDS_NO_LEDS);
-
- /* Validate IN endpoint address and indicate current mode via LED flashes */
- switch (AVRISP_CurrDataINEndpointAddress)
- {
- default:
- /* Default to Jungo compatibility mode if saved EEPROM is invalid */
- AVRISP_CurrDataINEndpointAddress = AVRISP_DATA_IN_EPADDR_JUNGO;
- case AVRISP_DATA_IN_EPADDR_JUNGO:
- /* Two flashes for Jungo compatibility mode */
- for (uint8_t i = 0; i < 4; i++)
- {
- LEDs_ToggleLEDs(LEDS_ALL_LEDS);
- Delay_MS(100);
- }
- break;
- case AVRISP_DATA_IN_EPADDR_LIBUSB:
- /* Five flashes for libUSB compatibility mode */
- for (uint8_t i = 0; i < 10; i++)
- {
- LEDs_ToggleLEDs(LEDS_ALL_LEDS);
- Delay_MS(100);
- }
- break;
- }
-
- Delay_MS(500);
-}
-#endif