The incomplete StandaloneProgrammer project now uses Host and Device Mass storage classes, so that program data can either be loaded onto the device's Dataflash storage, or read off an attached USB memory stick.

The USB target family and allowable USB mode tokens are now public and documented (USB_CAN_BE_*, USB_SERIES_*_AVR).

The SCSI_Request_Sense_Response_t and SCSI_Inquiry_Response_t type defines are now part of the Mass Storage Class driver common defines, rather than being defined in the Host mode Class driver section only.

The USB_MODE_HOST token is now defined even when host mode is not available.

Added missing CDC_Host_CreateBlockingStream() function code to the CDC Host Class driver.
pull/1469/head
Dean Camera 15 years ago
parent 6e867f7d9b
commit aaa0bed556

@ -72,67 +72,6 @@
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */ /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
#define DEVICE_TYPE_CDROM 0x05 #define DEVICE_TYPE_CDROM 0x05
/* Type Defines: */
/** Type define for a SCSI response structure to a SCSI INQUIRY command. For details of the
* structure contents, refer to the SCSI specifications.
*/
typedef struct
{
unsigned char DeviceType : 5;
unsigned char PeripheralQualifier : 3;
unsigned char _RESERVED1 : 7;
unsigned char Removable : 1;
uint8_t Version;
unsigned char ResponseDataFormat : 4;
unsigned char _RESERVED2 : 1;
unsigned char NormACA : 1;
unsigned char TrmTsk : 1;
unsigned char AERC : 1;
uint8_t AdditionalLength;
uint8_t _RESERVED3[2];
unsigned char SoftReset : 1;
unsigned char CmdQue : 1;
unsigned char _RESERVED4 : 1;
unsigned char Linked : 1;
unsigned char Sync : 1;
unsigned char WideBus16Bit : 1;
unsigned char WideBus32Bit : 1;
unsigned char RelAddr : 1;
uint8_t VendorID[8];
uint8_t ProductID[16];
uint8_t RevisionID[4];
} SCSI_Inquiry_Response_t;
/** Type define for a SCSI sense structure to a SCSI REQUEST SENSE command. For details of the
* structure contents, refer to the SCSI specifications.
*/
typedef struct
{
uint8_t ResponseCode;
uint8_t SegmentNumber;
unsigned char SenseKey : 4;
unsigned char _RESERVED1 : 1;
unsigned char ILI : 1;
unsigned char EOM : 1;
unsigned char FileMark : 1;
uint8_t Information[4];
uint8_t AdditionalLength;
uint8_t CmdSpecificInformation[4];
uint8_t AdditionalSenseCode;
uint8_t AdditionalSenseQualifier;
uint8_t FieldReplaceableUnitCode;
uint8_t SenseKeySpecific[3];
} SCSI_Request_Sense_Response_t;
/* Function Prototypes: */ /* Function Prototypes: */
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);

File diff suppressed because one or more lines are too long

@ -213,6 +213,69 @@
uint8_t Status; /**< Status code of the issued command - a value from the MassStorage_CommandStatusCodes_t enum */ uint8_t Status; /**< Status code of the issued command - a value from the MassStorage_CommandStatusCodes_t enum */
} MS_CommandStatusWrapper_t; } MS_CommandStatusWrapper_t;
/** Type define for a SCSI Sense structure. Structures of this type are filled out by the
* device via the MassStore_RequestSense() function, indicating the current sense data of the
* device (giving explicit error codes for the last issued command). For details of the
* structure contents, refer to the SCSI specifications.
*/
typedef struct
{
uint8_t ResponseCode;
uint8_t SegmentNumber;
unsigned char SenseKey : 4;
unsigned char _RESERVED1 : 1;
unsigned char ILI : 1;
unsigned char EOM : 1;
unsigned char FileMark : 1;
uint8_t Information[4];
uint8_t AdditionalLength;
uint8_t CmdSpecificInformation[4];
uint8_t AdditionalSenseCode;
uint8_t AdditionalSenseQualifier;
uint8_t FieldReplaceableUnitCode;
uint8_t SenseKeySpecific[3];
} SCSI_Request_Sense_Response_t;
/** Type define for a SCSI Inquiry structure. Structures of this type are filled out by the
* device via the MassStore_Inquiry() function, retrieving the attached device's information.
* For details of the structure contents, refer to the SCSI specifications.
*/
typedef struct
{
unsigned char DeviceType : 5;
unsigned char PeripheralQualifier : 3;
unsigned char _RESERVED1 : 7;
unsigned char Removable : 1;
uint8_t Version;
unsigned char ResponseDataFormat : 4;
unsigned char _RESERVED2 : 1;
unsigned char NormACA : 1;
unsigned char TrmTsk : 1;
unsigned char AERC : 1;
uint8_t AdditionalLength;
uint8_t _RESERVED3[2];
unsigned char SoftReset : 1;
unsigned char CmdQue : 1;
unsigned char _RESERVED4 : 1;
unsigned char Linked : 1;
unsigned char Sync : 1;
unsigned char WideBus16Bit : 1;
unsigned char WideBus32Bit : 1;
unsigned char RelAddr : 1;
uint8_t VendorID[8];
uint8_t ProductID[16];
uint8_t RevisionID[4];
} SCSI_Inquiry_Response_t;
/* Enums: */ /* Enums: */
/** Enum for the possible command status wrapper return status codes. */ /** Enum for the possible command status wrapper return status codes. */
enum MassStorage_CommandStatusCodes_t enum MassStorage_CommandStatusCodes_t

@ -340,6 +340,12 @@ void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, FILE* Str
fdev_set_udata(Stream, CDCInterfaceInfo); fdev_set_udata(Stream, CDCInterfaceInfo);
} }
void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo, FILE* Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
static int CDC_Host_putchar(char c, FILE* Stream) static int CDC_Host_putchar(char c, FILE* Stream)
{ {
return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;

@ -93,69 +93,6 @@
*/ */
} USB_ClassInfo_MS_Host_t; } USB_ClassInfo_MS_Host_t;
/** Type define for a SCSI Sense structure. Structures of this type are filled out by the
* device via the MassStore_RequestSense() function, indicating the current sense data of the
* device (giving explicit error codes for the last issued command). For details of the
* structure contents, refer to the SCSI specifications.
*/
typedef struct
{
uint8_t ResponseCode;
uint8_t SegmentNumber;
unsigned char SenseKey : 4;
unsigned char _RESERVED1 : 1;
unsigned char ILI : 1;
unsigned char EOM : 1;
unsigned char FileMark : 1;
uint8_t Information[4];
uint8_t AdditionalLength;
uint8_t CmdSpecificInformation[4];
uint8_t AdditionalSenseCode;
uint8_t AdditionalSenseQualifier;
uint8_t FieldReplaceableUnitCode;
uint8_t SenseKeySpecific[3];
} SCSI_Request_Sense_Response_t;
/** Type define for a SCSI Inquiry structure. Structures of this type are filled out by the
* device via the MassStore_Inquiry() function, retrieving the attached device's information.
* For details of the structure contents, refer to the SCSI specifications.
*/
typedef struct
{
unsigned char DeviceType : 5;
unsigned char PeripheralQualifier : 3;
unsigned char _RESERVED1 : 7;
unsigned char Removable : 1;
uint8_t Version;
unsigned char ResponseDataFormat : 4;
unsigned char _RESERVED2 : 1;
unsigned char NormACA : 1;
unsigned char TrmTsk : 1;
unsigned char AERC : 1;
uint8_t AdditionalLength;
uint8_t _RESERVED3[2];
unsigned char SoftReset : 1;
unsigned char CmdQue : 1;
unsigned char _RESERVED4 : 1;
unsigned char Linked : 1;
unsigned char Sync : 1;
unsigned char WideBus16Bit : 1;
unsigned char WideBus32Bit : 1;
unsigned char RelAddr : 1;
uint8_t VendorID[8];
uint8_t ProductID[16];
uint8_t RevisionID[4];
} SCSI_Inquiry_Response_t;
/** SCSI capacity structure, to hold the total capacity of the device in both the number /** SCSI capacity structure, to hold the total capacity of the device in both the number
* of blocks in the current LUN, and the size of each block. This structure is filled by * of blocks in the current LUN, and the size of each block. This structure is filled by
* the device when the MassStore_ReadCapacity() function is called. * the device when the MassStore_ReadCapacity() function is called.

@ -28,11 +28,58 @@
this software. this software.
*/ */
/** \ingroup Group_USB
* @defgroup Group_USBMode USB Configuration Tokens
*
* After the inclusion of the master USB driver header, one or more of the following
* tokens may be defined, to allow the user code to conditionally enable or disable
* code based on the USB controller family and allowable USB modes. These tokens may
* be tested against to eliminate code relating to a USB mode which is not enabled for
* the given compilation.
*
* @{
*/
#ifndef __USBMODE_H__ #ifndef __USBMODE_H__
#define __USBMODE_H__ #define __USBMODE_H__
/* Private Interface - For use in library only: */ /* Public Interface - May be used in end-application: */
#if !defined(__DOXYGEN__) #if defined(__DOXYGEN__)
/** Indicates that the target AVR microcontroller belongs to the Series 2 USB controller
* (i.e. AT90USBXXX2 or ATMEGAXXU2) when defined.
*/
#define USB_SERIES_2_AVR
/** Indicates that the target AVR microcontroller belongs to the Series 4 USB controller
* (i.e. ATMEGAXXU4) when defined.
*/
#define USB_SERIES_4_AVR
/** Indicates that the target AVR microcontroller belongs to the Series 6 USB controller
* (i.e. AT90USBXXX6) when defined.
*/
#define USB_SERIES_6_AVR
/** Indicates that the target AVR microcontroller belongs to the Series 7 USB controller
* (i.e. AT90USBXXX7) when defined.
*/
#define USB_SERIES_7_AVR
/** Indicates that the target AVR microcontroller and compilation settings allow for the
* target to be configured in USB Device mode when defined.
*/
#define USB_CAN_BE_DEVICE
/** Indicates that the target AVR microcontroller and compilation settings allow for the
* target to be configured in USB Host mode when defined.
*/
#define USB_CAN_BE_HOST
/** Indicates that the target AVR microcontroller and compilation settings allow for the
* target to be configured in either USB Device or Host mode when defined.
*/
#define USB_CAN_BE_BOTH
#else
/* Macros: */ /* Macros: */
#if (defined(__AVR_AT90USB162__) || defined(__AVR_AT90USB82__) || \ #if (defined(__AVR_AT90USB162__) || defined(__AVR_AT90USB82__) || \
defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)) defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__))
@ -71,3 +118,5 @@
#endif #endif
#endif #endif
/** @} */

@ -112,14 +112,10 @@
*/ */
#define USB_MODE_DEVICE 1 #define USB_MODE_DEVICE 1
#if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__) /** Mode mask for the \ref USB_CurrentMode global and the \ref USB_Init() function. This indicates that the
/** Mode mask for the \ref USB_CurrentMode global and the \ref USB_Init() function. This indicates that the * USB interface is or should be initialized in the USB host mode.
* USB interface is or should be initialized in the USB host mode. */
* #define USB_MODE_HOST 2
* \note This token is not available on AVR models which do not support host mode.
*/
#define USB_MODE_HOST 2
#endif
#if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__) #if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__)
/** Mode mask for the the \ref USB_Init() function. This indicates that the USB interface should be /** Mode mask for the the \ref USB_Init() function. This indicates that the USB interface should be

@ -10,10 +10,17 @@
* *
* <b>New:</b> * <b>New:</b>
* - Added activity LED indicators to the AVRISP project to indicate when the device is busy processing a command * - Added activity LED indicators to the AVRISP project to indicate when the device is busy processing a command
* - The USB target family and allowable USB mode tokens are now public and documented (USB_CAN_BE_*, USB_SERIES_*_AVR)
* *
* <b>Changed:</b> * <b>Changed:</b>
* - Removed code in the Keyboard demos to send zeroed reports between two reports with differing numbers of keycodes * - Removed code in the Keyboard demos to send zeroed reports between two reports with differing numbers of keycodes
* as this relied on non-standard OS driver behaviour to repeat key groups * as this relied on non-standard OS driver behaviour to repeat key groups
* - The SCSI_Request_Sense_Response_t and SCSI_Inquiry_Response_t type defines are now part of the Mass Storage Class
* driver common defines, rather than being defined in the Host mode Class driver section only
* - The USB_MODE_HOST token is now defined even when host mode is not available
*
* <b>Fixed:</b>
* - Added missing CDC_Host_CreateBlockingStream() function code to the CDC Host Class driver
* *
* \section Sec_ChangeLog091122 Version 091122 * \section Sec_ChangeLog091122 Version 091122
* *

@ -37,6 +37,8 @@
#include "Descriptors.h" #include "Descriptors.h"
#if defined(USB_CAN_BE_DEVICE)
/* On some devices, there is a factory set internal serial number which can be automatically sent to the host as /* On some devices, there is a factory set internal serial number which can be automatically sent to the host as
* the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL. * the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL.
* This allows the host to track a device across insertions on different ports, allowing them to retain allocated * This allows the host to track a device across insertions on different ports, allowing them to retain allocated
@ -67,7 +69,7 @@ USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.VendorID = 0x03EB, .VendorID = 0x03EB,
.ProductID = 0x2063, .ProductID = 0x2063,
.ReleaseNumber = 0x0000, .ReleaseNumber = 0x0001,
.ManufacturerStrIndex = 0x01, .ManufacturerStrIndex = 0x01,
.ProductStrIndex = 0x02, .ProductStrIndex = 0x02,
@ -88,7 +90,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 3, .TotalInterfaces = 1,
.ConfigurationNumber = 1, .ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR, .ConfigurationStrIndex = NO_DESCRIPTOR,
@ -98,119 +100,11 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100) .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
}, },
.CDC_IAD =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
.FirstInterfaceIndex = 0,
.TotalInterfaces = 2,
.Class = 0x02,
.SubClass = 0x02,
.Protocol = 0x01,
.IADStrIndex = NO_DESCRIPTOR
},
.CCI_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0,
.AlternateSetting = 0,
.TotalEndpoints = 1,
.Class = 0x02,
.SubClass = 0x02,
.Protocol = 0x01,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.CDC_Functional_IntHeader =
{
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x00,
.Data = {0x01, 0x10}
},
.CDC_Functional_CallManagement =
{
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x01,
.Data = {0x03, 0x01}
},
.CDC_Functional_AbstractControlManagement =
{
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(1)), .Type = 0x24},
.SubType = 0x02,
.Data = {0x06}
},
.CDC_Functional_Union =
{
.Header = {.Size = sizeof(CDC_FUNCTIONAL_DESCRIPTOR(2)), .Type = 0x24},
.SubType = 0x06,
.Data = {0x00, 0x01}
},
.ManagementEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_NOTIFICATION_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
.PollingIntervalMS = 0xFF
},
.DCI_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1,
.AlternateSetting = 0,
.TotalEndpoints = 2,
.Class = 0x0A,
.SubClass = 0x00,
.Protocol = 0x00,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.DataOutEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_OUT | CDC_RX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x00
},
.DataInEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | CDC_TX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x00
},
.MSInterface = .MSInterface =
{ {
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 2, .InterfaceNumber = 0,
.AlternateSetting = 0, .AlternateSetting = 0,
.TotalEndpoints = 2, .TotalEndpoints = 2,
@ -323,3 +217,5 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex,
*DescriptorAddress = Address; *DescriptorAddress = Address;
return Size; return Size;
} }
#endif

@ -76,16 +76,6 @@
typedef struct typedef struct
{ {
USB_Descriptor_Configuration_Header_t Config; USB_Descriptor_Configuration_Header_t Config;
USB_Descriptor_Interface_Association_t CDC_IAD;
USB_Descriptor_Interface_t CCI_Interface;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_CallManagement;
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_AbstractControlManagement;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union;
USB_Descriptor_Endpoint_t ManagementEndpoint;
USB_Descriptor_Interface_t DCI_Interface;
USB_Descriptor_Endpoint_t DataOutEndpoint;
USB_Descriptor_Endpoint_t DataInEndpoint;
USB_Descriptor_Interface_t MSInterface; USB_Descriptor_Interface_t MSInterface;
USB_Descriptor_Endpoint_t MSDataInEndpoint; USB_Descriptor_Endpoint_t MSDataInEndpoint;
USB_Descriptor_Endpoint_t MSDataOutEndpoint; USB_Descriptor_Endpoint_t MSDataOutEndpoint;

@ -0,0 +1,104 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#include "DiskDevice.h"
#if defined(USB_CAN_BE_DEVICE)
/** LUFA Mass Storage Class driver interface configuration and state information. This structure is
* passed to all Mass Storage Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
*/
USB_ClassInfo_MS_Device_t DiskDevice_MS_Interface =
{
.Config =
{
.InterfaceNumber = 0,
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
.DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
.DataOUTEndpointDoubleBank = false,
.TotalLUNs = 1,
},
};
void DiskDevice_USBTask(void)
{
MS_Device_USBTask(&DiskDevice_MS_Interface);
}
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(MS_Device_ConfigureEndpoints(&DiskDevice_MS_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
pf_mount(&DiskFATState);
}
/** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void)
{
MS_Device_ProcessControlRequest(&DiskDevice_MS_Interface);
}
/** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed.
*
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced
*/
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{
bool CommandSuccess;
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
LEDs_SetAllLEDs(LEDMASK_USB_READY);
return CommandSuccess;
}
#endif

@ -0,0 +1,61 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for DiskDevice.c.
*/
#ifndef _DISK_DEVICE_H_
#define _DISK_DEVICE_H_
/* Includes: */
#include <avr/io.h>
#include "Descriptors.h"
#include "StandaloneProgrammer.h"
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h>
/* Function Prototypes: */
#if defined(USB_CAN_BE_DEVICE)
void DiskDevice_USBTask(void);
void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
#endif
#endif

@ -0,0 +1,130 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#include "DiskHost.h"
#if defined(USB_CAN_BE_HOST)
/** LUFA Mass Storage Class driver interface configuration and state information. This structure is
* passed to all Mass Storage Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
*/
USB_ClassInfo_MS_Host_t DiskHost_MS_Interface =
{
.Config =
{
.DataINPipeNumber = 1,
.DataINPipeDoubleBank = false,
.DataOUTPipeNumber = 2,
.DataOUTPipeDoubleBank = false,
},
};
void DiskHost_USBTask(void)
{
if (USB_HostState == HOST_STATE_Addressed)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
uint16_t ConfigDescriptorSize;
uint8_t ConfigDescriptorData[512];
if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
{
printf("ERROR - GetConfig\r\n");
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
return;
}
if (MS_Host_ConfigurePipes(&DiskHost_MS_Interface,
ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError)
{
printf("ERROR - Pipes\r\n");
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
return;
}
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
{
printf("ERROR - SetConfig\r\n");
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
return;
}
uint8_t MaxLUNIndex;
if (MS_Host_GetMaxLUN(&DiskHost_MS_Interface, &MaxLUNIndex))
{
printf("ERROR - MaxLUN\r\n");
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
return;
}
if (MS_Host_ResetMSInterface(&DiskHost_MS_Interface))
{
printf("ERROR - ResetMS\r\n");
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
return;
}
SCSI_Request_Sense_Response_t SenseData;
if (MS_Host_RequestSense(&DiskHost_MS_Interface, 0, &SenseData) != 0)
{
printf("ERROR - Sense\r\n");
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
return;
}
pf_mount(&DiskFATState);
LEDs_SetAllLEDs(LEDMASK_USB_READY);
USB_HostState = HOST_STATE_Configured;
}
MS_Host_USBTask(&DiskHost_MS_Interface);
}
void EVENT_USB_Host_DeviceAttached(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
void EVENT_USB_Host_DeviceUnattached(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
#endif

@ -0,0 +1,62 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Header file for DiskHost.c.
*/
#ifndef _DISK_HOST_H_
#define _DISK_HOST_H_
/* Includes: */
#include <avr/io.h>
#include "Descriptors.h"
#include "StandaloneProgrammer.h"
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h>
/* External Variables: */
#if defined(USB_CAN_BE_HOST)
extern USB_ClassInfo_MS_Host_t DiskHost_MS_Interface;
#endif
/* Function Prototypes: */
#if defined(USB_CAN_BE_HOST)
void DiskHost_USBTask(void);
void EVENT_USB_Host_DeviceAttached(void);
void EVENT_USB_Host_DeviceUnattached(void);
#endif
#endif

@ -39,6 +39,7 @@
#define INCLUDE_FROM_DATAFLASHMANAGER_C #define INCLUDE_FROM_DATAFLASHMANAGER_C
#include "DataflashManager.h" #include "DataflashManager.h"
#if defined(USB_CAN_BE_DEVICE)
/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from /** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from
* the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes * the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes
* them to the dataflash in Dataflash page sized blocks. * them to the dataflash in Dataflash page sized blocks.
@ -523,3 +524,4 @@ bool DataflashManager_CheckDataflashOperation(void)
return true; return true;
} }
#endif

@ -42,10 +42,9 @@
#include "StandaloneProgrammer.h" #include "StandaloneProgrammer.h"
#include "Descriptors.h" #include "Descriptors.h"
#include <LUFA/Common/Common.h> // Function Attribute, Atomic, Debug and ISR Macros #include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/USB.h> // USB Functionality #include <LUFA/Drivers/USB/Class/MassStorage.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h> // Mass Storage Class Driver #include <LUFA/Drivers/Board/Dataflash.h>
#include <LUFA/Drivers/Board/Dataflash.h> // Dataflash chip driver
/* Preprocessor Checks: */ /* Preprocessor Checks: */
#if (DATAFLASH_PAGE_SIZE % 16) #if (DATAFLASH_PAGE_SIZE % 16)
@ -67,15 +66,17 @@
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE) #define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
/* Function Prototypes: */ /* Function Prototypes: */
void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, #if defined(USB_CAN_BE_DEVICE)
uint16_t TotalBlocks); void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress,
void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks);
uint16_t TotalBlocks); void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const uint32_t BlockAddress,
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint16_t TotalBlocks);
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3); void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
void DataflashManager_ResetDataflashProtections(void); uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
bool DataflashManager_CheckDataflashOperation(void); void DataflashManager_ResetDataflashProtections(void);
bool DataflashManager_CheckDataflashOperation(void);
#endif
#endif #endif

@ -5,7 +5,9 @@
#include "diskio.h" #include "diskio.h"
#include <string.h> #include <string.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h>
#include "../DataflashManager.h" #include "../DataflashManager.h"
#include "../../DiskHost.h"
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */ /* Initialize Disk Drive */
@ -33,14 +35,29 @@ DRESULT disk_readp (
WORD count /* Byte count (bit15:destination) */ WORD count /* Byte count (bit15:destination) */
) )
{ {
DRESULT res; DRESULT ErrorCode = RES_OK;
uint8_t BlockTemp[512]; uint8_t BlockTemp[512];
DataflashManager_ReadBlocks_RAM(sector, 1, BlockTemp);
memcpy(dest, &BlockTemp[sofs], count);
res = RES_OK; if (USB_CurrentMode == USB_MODE_HOST)
{
#if defined(USB_CAN_BE_HOST)
if (USB_HostState != HOST_STATE_Configured)
ErrorCode = RES_NOTRDY;
else if (MS_Host_ReadDeviceBlocks(&DiskHost_MS_Interface, 0, sector, 1, 512, BlockTemp))
ErrorCode = RES_ERROR;
printf("BLOCK READ #%lu Ret %d\r\n", sector, MS_Host_ReadDeviceBlocks(&DiskHost_MS_Interface, 0, sector, 1, 512, BlockTemp));
#endif
}
else
{
#if defined(USB_CAN_BE_DEVICE)
DataflashManager_ReadBlocks_RAM(sector, 1, BlockTemp);
#endif
}
memcpy(dest, &BlockTemp[sofs], count);
return res; return ErrorCode;
} }

@ -44,7 +44,7 @@ bool ProgrammerConfig_ProcessConfiguration(void)
if (!(pf_open("CONF.txt") == FR_OK)) if (!(pf_open("CONF.txt") == FR_OK))
{ {
fputs(" >> ERROR: CONF.txt File Not Found.\r\n", &USBSerialStream); puts(" >> ERROR: CONF.txt File Not Found.\r\n");
return false; return false;
} }
@ -53,7 +53,7 @@ bool ProgrammerConfig_ProcessConfiguration(void)
do do
{ {
CurrentLine = fgets(LineBuff, sizeof(LineBuff), &DataflashStream); CurrentLine = fgets(LineBuff, sizeof(LineBuff), &DiskStream);
if (CurrentLine) if (CurrentLine)
{ {
@ -66,12 +66,12 @@ bool ProgrammerConfig_ProcessConfiguration(void)
} }
} while (CurrentLine); } while (CurrentLine);
fprintf(&USBSerialStream, " >> *** Configuration: ***\r\n"); printf(" >> *** Configuration: ***\r\n");
fprintf(&USBSerialStream, " >> Device Signature: 0x%02x 0x%02x 0x%02x 0x%02x\r\n", ProgrammerConfig.SigBytes[0], printf(" >> Device Signature: 0x%02x 0x%02x 0x%02x 0x%02x\r\n", ProgrammerConfig.SigBytes[0],
ProgrammerConfig.SigBytes[1], ProgrammerConfig.SigBytes[1],
ProgrammerConfig.SigBytes[2], ProgrammerConfig.SigBytes[2],
ProgrammerConfig.SigBytes[3]); ProgrammerConfig.SigBytes[3]);
fprintf(&USBSerialStream, " >> Programming Speed: %lu Hz\r\n", ProgrammerConfig.ProgrammingSpeed); printf(" >> Programming Speed: %lu Hz\r\n", ProgrammerConfig.ProgrammingSpeed);
return true; return true;
} }

@ -38,6 +38,7 @@
#define INCLUDE_FROM_SCSI_C #define INCLUDE_FROM_SCSI_C
#include "SCSI.h" #include "SCSI.h"
#if defined(USB_CAN_BE_DEVICE)
/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's /** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's
* features and capabilities. * features and capabilities.
*/ */
@ -279,3 +280,4 @@ static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo
/* Update the bytes transferred counter and succeed the command */ /* Update the bytes transferred counter and succeed the command */
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE); MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
} }
#endif

@ -71,76 +71,17 @@
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */ /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
#define DEVICE_TYPE_CDROM 0x05 #define DEVICE_TYPE_CDROM 0x05
/* Type Defines: */
/** Type define for a SCSI response structure to a SCSI INQUIRY command. For details of the
* structure contents, refer to the SCSI specifications.
*/
typedef struct
{
unsigned char DeviceType : 5;
unsigned char PeripheralQualifier : 3;
unsigned char _RESERVED1 : 7;
unsigned char Removable : 1;
uint8_t Version;
unsigned char ResponseDataFormat : 4;
unsigned char _RESERVED2 : 1;
unsigned char NormACA : 1;
unsigned char TrmTsk : 1;
unsigned char AERC : 1;
uint8_t AdditionalLength;
uint8_t _RESERVED3[2];
unsigned char SoftReset : 1;
unsigned char CmdQue : 1;
unsigned char _RESERVED4 : 1;
unsigned char Linked : 1;
unsigned char Sync : 1;
unsigned char WideBus16Bit : 1;
unsigned char WideBus32Bit : 1;
unsigned char RelAddr : 1;
uint8_t VendorID[8];
uint8_t ProductID[16];
uint8_t RevisionID[4];
} SCSI_Inquiry_Response_t;
/** Type define for a SCSI sense structure to a SCSI REQUEST SENSE command. For details of the
* structure contents, refer to the SCSI specifications.
*/
typedef struct
{
uint8_t ResponseCode;
uint8_t SegmentNumber;
unsigned char SenseKey : 4;
unsigned char _RESERVED1 : 1;
unsigned char ILI : 1;
unsigned char EOM : 1;
unsigned char FileMark : 1;
uint8_t Information[4];
uint8_t AdditionalLength;
uint8_t CmdSpecificInformation[4];
uint8_t AdditionalSenseCode;
uint8_t AdditionalSenseQualifier;
uint8_t FieldReplaceableUnitCode;
uint8_t SenseKeySpecific[3];
} SCSI_Request_Sense_Response_t;
/* Function Prototypes: */ /* Function Prototypes: */
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); #if defined(USB_CAN_BE_DEVICE)
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
#if defined(INCLUDE_FROM_SCSI_C)
static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); #if defined(INCLUDE_FROM_SCSI_C)
static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static void SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static void SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static void SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static void SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo); static void SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead); static void SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, const bool IsDataRead);
#endif
#endif #endif
#endif #endif

@ -37,68 +37,16 @@
#define INCLUDE_FROM_STANDALONEPROG_C #define INCLUDE_FROM_STANDALONEPROG_C
#include "StandaloneProgrammer.h" #include "StandaloneProgrammer.h"
/** LUFA Mass Storage Class driver interface configuration and state information. This structure is /** Standard file stream for the currently open file on the disk. */
* passed to all Mass Storage Class driver functions, so that multiple instances of the same class FILE DiskStream = FDEV_SETUP_STREAM(NULL, Disk_getchar, _FDEV_SETUP_READ);
* within a device can be differentiated from one another.
*/
USB_ClassInfo_MS_Device_t Disk_MS_Interface =
{
.Config =
{
.InterfaceNumber = 0,
.DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
.DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
.DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
.DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
.DataOUTEndpointDoubleBank = false,
.TotalLUNs = 1,
},
};
/** LUFA CDC Class driver interface configuration and state information. This structure is
* passed to all CDC Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
*/
USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
{
.Config =
{
.ControlInterfaceNumber = 0,
.DataINEndpointNumber = CDC_TX_EPNUM,
.DataINEndpointSize = CDC_TXRX_EPSIZE,
.DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = CDC_RX_EPNUM,
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
.DataOUTEndpointDoubleBank = false,
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
.NotificationEndpointDoubleBank = false,
},
};
/** Standard file stream for the CDC interface when set up, so that the virtual CDC COM port can be
* used like any regular character stream in the C APIs
*/
FILE USBSerialStream;
/** Standard file stream for the currently open file on the dataflash disk. */
FILE DataflashStream = FDEV_SETUP_STREAM(NULL, Dataflash_getchar, _FDEV_SETUP_READ);
/** Petite FAT Fs structure to hold the internal state of the FAT driver for the dataflash contents. */ /** Petite FAT Fs structure to hold the internal state of the FAT driver for the dataflash contents. */
FATFS DataflashData; FATFS DiskFATState;
/** Stream character fetching routine for the FAT driver so that characters from the currently open file can be /** Stream character fetching routine for the FAT driver so that characters from the currently open file can be
* read in sequence when applied to a stdio stream. * read in sequence when applied to a stdio stream.
*/ */
static int Dataflash_getchar(FILE* Stream) static int Disk_getchar(FILE* Stream)
{ {
char ReadByte; char ReadByte;
WORD ByteWasRead; WORD ByteWasRead;
@ -123,15 +71,19 @@ void Programmer_Task(void)
else else
return; return;
fputs("==== PROGRAMMING CYCLE STARTED ====\r\n", &USBSerialStream); puts("==== PROGRAMMING CYCLE STARTED ====\r\n");
#if defined(USB_CAN_BE_BOTH)
printf("Using %s Drive...\r\n", (USB_CurrentMode == USB_MODE_HOST) ? "External" : "Internal");
#endif
fputs("Reading Configuration File...\r\n", &USBSerialStream); puts("Reading Configuration File...\r\n");
if (!(ProgrammerConfig_ProcessConfiguration())) if (!(ProgrammerConfig_ProcessConfiguration()))
goto EndOfProgCycle; goto EndOfProgCycle;
EndOfProgCycle: EndOfProgCycle:
fputs("==== PROGRAMMING CYCLE FINISHED ====\r\n", &USBSerialStream); puts("==== PROGRAMMING CYCLE FINISHED ====\r\n");
} }
else else
{ {
@ -146,21 +98,25 @@ int main(void)
{ {
SetupHardware(); SetupHardware();
/* Create a regular character stream for the interface so that it can be used with the stdio.h functions */
CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream);
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
for (;;) for (;;)
{ {
Programmer_Task(); Programmer_Task();
/* Must throw away unused bytes from the host, or it will lock up while waiting for the device */ if (USB_CurrentMode == USB_MODE_HOST)
while (CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface)) {
CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); #if defined(USB_CAN_BE_HOST)
DiskHost_USBTask();
#endif
}
else
{
#if defined(USB_CAN_BE_DEVICE)
DiskDevice_USBTask();
#endif
}
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
MS_Device_USBTask(&Disk_MS_Interface);
USB_USBTask(); USB_USBTask();
} }
} }
@ -176,59 +132,20 @@ void SetupHardware(void)
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
/* Hardware Initialization */ /* Hardware Initialization */
#if defined(USB_CAN_BE_BOTH)
USB_Init(USB_MODE_UID);
#else
USB_Init();
#endif
LEDs_Init(); LEDs_Init();
SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER); SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
Dataflash_Init(); Dataflash_Init();
USB_Init();
Buttons_Init(); Buttons_Init();
pf_mount(&DataflashData); SerialStream_Init(9600, true);
#if defined(USB_CAN_BE_DEVICE)
/* Clear Dataflash sector protections, if enabled */ /* Clear Dataflash sector protections, if enabled */
DataflashManager_ResetDataflashProtections(); DataflashManager_ResetDataflashProtections();
} #endif
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_READY);
if (!(MS_Device_ConfigureEndpoints(&Disk_MS_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void)
{
MS_Device_ProcessControlRequest(&Disk_MS_Interface);
CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
}
/** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed.
*
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced
*/
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfaceInfo)
{
bool CommandSuccess;
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
LEDs_SetAllLEDs(LEDMASK_USB_READY);
return CommandSuccess;
} }

@ -42,7 +42,8 @@
#include <avr/power.h> #include <avr/power.h>
#include <stdio.h> #include <stdio.h>
#include "Descriptors.h" #include "DiskDevice.h"
#include "DiskHost.h"
#include "Lib/SCSI.h" #include "Lib/SCSI.h"
#include "Lib/DataflashManager.h" #include "Lib/DataflashManager.h"
@ -50,11 +51,8 @@
#include "Lib/PetiteFATFs/pff.h" #include "Lib/PetiteFATFs/pff.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Board/Buttons.h> #include <LUFA/Drivers/Board/Buttons.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/Peripheral/SerialStream.h>
#include <LUFA/Drivers/USB/Class/MassStorage.h>
#include <LUFA/Drivers/USB/Class/CDC.h>
/* Macros: */ /* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */ /** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
@ -73,22 +71,15 @@
#define LEDMASK_USB_BUSY (LEDS_LED2) #define LEDMASK_USB_BUSY (LEDS_LED2)
/* External Variables: */ /* External Variables: */
extern FILE USBSerialStream; extern FILE DiskStream;
extern FILE DataflashStream; extern FATFS DiskFATState;
/* Function Prototypes: */ /* Function Prototypes: */
#if defined(INCLUDE_FROM_STANDALONEPROG_C) #if defined(INCLUDE_FROM_STANDALONEPROG_C)
static int Dataflash_getchar(FILE* Stream); static int Disk_getchar(FILE* Stream);
#endif #endif
void SetupHardware(void); void SetupHardware(void);
void Programmer_Task(void); void Programmer_Task(void);
void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* MSInterfaceInfo);
#endif #endif

@ -116,7 +116,6 @@ LUFA_PATH = ../../../
# LUFA library compile-time options # LUFA library compile-time options
LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS LUFA_OPTS += -D USE_FLASH_DESCRIPTORS
@ -127,11 +126,15 @@ LUFA_OPTS += -D INTERRUPT_CONTROL_ENDPOINT
# List C source files here. (C dependencies are automatically generated.) # List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \ SRC = $(TARGET).c \
Descriptors.c \ Descriptors.c \
DiskHost.c \
DiskDevice.c \
Lib/SCSI.c \ Lib/SCSI.c \
Lib/DataflashManager.c \ Lib/DataflashManager.c \
Lib/ProgrammerConfig.c \ Lib/ProgrammerConfig.c \
Lib/PetiteFATFs/diskio.c \ Lib/PetiteFATFs/diskio.c \
Lib/PetiteFATFs/pff.c \ Lib/PetiteFATFs/pff.c \
$(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c \
$(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \ $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \
@ -144,8 +147,6 @@ SRC = $(TARGET).c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c \ $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c \
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/MassStorage.c \ $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/MassStorage.c \
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/MassStorage.c \ $(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/MassStorage.c \
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/CDC.c \
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/CDC.c \
# List C++ source files here. (C dependencies are automatically generated.) # List C++ source files here. (C dependencies are automatically generated.)

Loading…
Cancel
Save