AppConfigHeaders: Update several additional user projects to use configuration header files, rather than makefile defines. Remove compile time warnings for projects lacking device serial support, remove incomplete StandaloneProgrammer project.
parent
33d9a75b03
commit
802910d49f
File diff suppressed because one or more lines are too long
@ -1,224 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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
|
|
||||||
*
|
|
||||||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
|
|
||||||
* computer-readable structures which the host requests upon device enumeration, to determine
|
|
||||||
* the device's capabilities and functions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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
|
|
||||||
* 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
|
|
||||||
* resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices
|
|
||||||
* so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value
|
|
||||||
* from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and
|
|
||||||
* port location).
|
|
||||||
*/
|
|
||||||
#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
|
|
||||||
#warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
|
|
||||||
#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
|
|
||||||
* process begins.
|
|
||||||
*/
|
|
||||||
const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
|
||||||
|
|
||||||
.USBSpecification = VERSION_BCD(01.10),
|
|
||||||
.Class = USB_CSCP_NoDeviceClass,
|
|
||||||
.SubClass = USB_CSCP_NoDeviceSubclass,
|
|
||||||
.Protocol = USB_CSCP_NoDeviceProtocol,
|
|
||||||
|
|
||||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
|
||||||
|
|
||||||
.VendorID = 0x03EB,
|
|
||||||
.ProductID = 0x2063,
|
|
||||||
.ReleaseNumber = VERSION_BCD(00.01),
|
|
||||||
|
|
||||||
.ManufacturerStrIndex = 0x01,
|
|
||||||
.ProductStrIndex = 0x02,
|
|
||||||
.SerialNumStrIndex = USE_INTERNAL_SERIAL,
|
|
||||||
|
|
||||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
|
|
||||||
* of the device in one of its supported configurations, including information about any device interfaces
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
|
||||||
{
|
|
||||||
.Config =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
|
||||||
|
|
||||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
|
||||||
.TotalInterfaces = 1,
|
|
||||||
|
|
||||||
.ConfigurationNumber = 1,
|
|
||||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
|
||||||
|
|
||||||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED,
|
|
||||||
|
|
||||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
|
||||||
},
|
|
||||||
|
|
||||||
.MS_Interface =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
|
||||||
|
|
||||||
.InterfaceNumber = 0,
|
|
||||||
.AlternateSetting = 0,
|
|
||||||
|
|
||||||
.TotalEndpoints = 2,
|
|
||||||
|
|
||||||
.Class = MS_CSCP_MassStorageClass,
|
|
||||||
.SubClass = MS_CSCP_SCSITransparentSubclass,
|
|
||||||
.Protocol = MS_CSCP_BulkOnlyTransportProtocol,
|
|
||||||
|
|
||||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
|
||||||
},
|
|
||||||
|
|
||||||
.MS_DataInEndpoint =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
|
||||||
|
|
||||||
.EndpointAddress = MASS_STORAGE_IN_EPADDR,
|
|
||||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
|
||||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
|
||||||
.PollingIntervalMS = 0x05
|
|
||||||
},
|
|
||||||
|
|
||||||
.MS_DataOutEndpoint =
|
|
||||||
{
|
|
||||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
|
||||||
|
|
||||||
.EndpointAddress = MASS_STORAGE_OUT_EPADDR,
|
|
||||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
|
||||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
|
||||||
.PollingIntervalMS = 0x05
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
|
|
||||||
* 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 LanguageString =
|
|
||||||
{
|
|
||||||
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
|
|
||||||
|
|
||||||
.UnicodeString = {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 ManufacturerString =
|
|
||||||
{
|
|
||||||
.Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
|
|
||||||
|
|
||||||
.UnicodeString = L"Dean Camera"
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 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 ProductString =
|
|
||||||
{
|
|
||||||
.Header = {.Size = USB_STRING_LEN(26), .Type = DTYPE_String},
|
|
||||||
|
|
||||||
.UnicodeString = L"LUFA Standalone Programmer"
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 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
|
|
||||||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
|
|
||||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
|
||||||
* USB host.
|
|
||||||
*/
|
|
||||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
|
||||||
const uint8_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;
|
|
||||||
|
|
||||||
switch (DescriptorType)
|
|
||||||
{
|
|
||||||
case DTYPE_Device:
|
|
||||||
Address = &DeviceDescriptor;
|
|
||||||
Size = sizeof(USB_Descriptor_Device_t);
|
|
||||||
break;
|
|
||||||
case DTYPE_Configuration:
|
|
||||||
Address = &ConfigurationDescriptor;
|
|
||||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
|
||||||
break;
|
|
||||||
case DTYPE_String:
|
|
||||||
switch (DescriptorNumber)
|
|
||||||
{
|
|
||||||
case 0x00:
|
|
||||||
Address = &LanguageString;
|
|
||||||
Size = pgm_read_byte(&LanguageString.Header.Size);
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
Address = &ManufacturerString;
|
|
||||||
Size = pgm_read_byte(&ManufacturerString.Header.Size);
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
Address = &ProductString;
|
|
||||||
Size = pgm_read_byte(&ProductString.Header.Size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*DescriptorAddress = Address;
|
|
||||||
return Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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 Descriptors.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _DESCRIPTORS_H_
|
|
||||||
#define _DESCRIPTORS_H_
|
|
||||||
|
|
||||||
/* Includes: */
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
|
|
||||||
#include <LUFA/Drivers/USB/USB.h>
|
|
||||||
|
|
||||||
/* Macros: */
|
|
||||||
/** Endpoint address of the CDC device-to-host notification IN endpoint. */
|
|
||||||
#define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | 5)
|
|
||||||
|
|
||||||
/** Endpoint address of the CDC device-to-host data IN endpoint. */
|
|
||||||
#define CDC_TX_EPADDR (ENDPOINT_DIR_IN | 1)
|
|
||||||
|
|
||||||
/** Endpoint address of the CDC host-to-device data OUT endpoint. */
|
|
||||||
#define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | 2)
|
|
||||||
|
|
||||||
/** Size in bytes of the CDC device-to-host notification IN endpoint. */
|
|
||||||
#define CDC_NOTIFICATION_EPSIZE 8
|
|
||||||
|
|
||||||
/** Size in bytes of the CDC data IN and OUT endpoints. */
|
|
||||||
#define CDC_TXRX_EPSIZE 16
|
|
||||||
|
|
||||||
/** Endpoint address of the Mass Storage device-to-host data IN endpoint. */
|
|
||||||
#define MASS_STORAGE_IN_EPADDR (ENDPOINT_DIR_IN | 3)
|
|
||||||
|
|
||||||
/** Endpoint address of the Mass Storage host-to-device data OUT endpoint. */
|
|
||||||
#define MASS_STORAGE_OUT_EPADDR (ENDPOINT_DIR_OUT | 4)
|
|
||||||
|
|
||||||
/** Size in bytes of the Mass Storage data endpoints. */
|
|
||||||
#define MASS_STORAGE_IO_EPSIZE 64
|
|
||||||
|
|
||||||
/* Type Defines: */
|
|
||||||
/** Type define for the device configuration descriptor structure. This must be defined in the
|
|
||||||
* application code, as the configuration descriptor contains several sub-descriptors which
|
|
||||||
* vary between devices, and which describe the device's usage to the host.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
USB_Descriptor_Configuration_Header_t Config;
|
|
||||||
|
|
||||||
// Mass Storage Interface
|
|
||||||
USB_Descriptor_Interface_t MS_Interface;
|
|
||||||
USB_Descriptor_Endpoint_t MS_DataInEndpoint;
|
|
||||||
USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
|
|
||||||
} USB_Descriptor_Configuration_t;
|
|
||||||
|
|
||||||
/* Function Prototypes: */
|
|
||||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
|
||||||
const uint8_t wIndex,
|
|
||||||
const void** const DescriptorAddress)
|
|
||||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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,
|
|
||||||
.DataINEndpoint =
|
|
||||||
{
|
|
||||||
.Address = MASS_STORAGE_IN_EPADDR,
|
|
||||||
.Size = MASS_STORAGE_IO_EPSIZE,
|
|
||||||
.Banks = 1,
|
|
||||||
},
|
|
||||||
.DataOUTEndpoint =
|
|
||||||
{
|
|
||||||
.Address = MASS_STORAGE_OUT_EPADDR,
|
|
||||||
.Size = MASS_STORAGE_IO_EPSIZE,
|
|
||||||
.Banks = 1,
|
|
||||||
},
|
|
||||||
.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)
|
|
||||||
{
|
|
||||||
bool ConfigSuccess = true;
|
|
||||||
|
|
||||||
ConfigSuccess &= MS_Device_ConfigureEndpoints(&DiskDevice_MS_Interface);
|
|
||||||
|
|
||||||
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Event handler for the library USB Control Request reception event. */
|
|
||||||
void EVENT_USB_Device_ControlRequest(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* const MSInterfaceInfo)
|
|
||||||
{
|
|
||||||
bool CommandSuccess;
|
|
||||||
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
|
||||||
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
|
||||||
|
|
||||||
return CommandSuccess;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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>
|
|
||||||
|
|
||||||
/* 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_ControlRequest(void);
|
|
||||||
|
|
||||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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 =
|
|
||||||
{
|
|
||||||
.DataINPipe =
|
|
||||||
{
|
|
||||||
.Address = (PIPE_DIR_IN | 1),
|
|
||||||
.Banks = 1,
|
|
||||||
},
|
|
||||||
.DataOUTPipe =
|
|
||||||
{
|
|
||||||
.Address = (PIPE_DIR_OUT | 2),
|
|
||||||
.Banks = 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void DiskHost_USBTask(void)
|
|
||||||
{
|
|
||||||
MS_Host_USBTask(&DiskHost_MS_Interface);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
|
||||||
{
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
|
||||||
|
|
||||||
uint16_t ConfigDescriptorSize;
|
|
||||||
uint8_t ConfigDescriptorData[512];
|
|
||||||
|
|
||||||
if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
|
|
||||||
sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
|
|
||||||
{
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MS_Host_ConfigurePipes(&DiskHost_MS_Interface,
|
|
||||||
ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError)
|
|
||||||
{
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
|
|
||||||
{
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t MaxLUNIndex;
|
|
||||||
if (MS_Host_GetMaxLUN(&DiskHost_MS_Interface, &MaxLUNIndex))
|
|
||||||
{
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MS_Host_ResetMSInterface(&DiskHost_MS_Interface))
|
|
||||||
{
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SCSI_Request_Sense_Response_t SenseData;
|
|
||||||
if (MS_Host_RequestSense(&DiskHost_MS_Interface, 0, &SenseData) != 0)
|
|
||||||
{
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pf_mount(&DiskFATState);
|
|
||||||
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EVENT_USB_Host_DeviceAttached(void)
|
|
||||||
{
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EVENT_USB_Host_DeviceUnattached(void)
|
|
||||||
{
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,536 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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
|
|
||||||
*
|
|
||||||
* Functions to manage the physical Dataflash media, including reading and writing of
|
|
||||||
* blocks of data. These functions are called by the SCSI layer when data must be stored
|
|
||||||
* or retrieved to/from the physical storage media. If a different media is used (such
|
|
||||||
* as a SD card or EEPROM), functions similar to these will need to be generated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define INCLUDE_FROM_DATAFLASHMANAGER_C
|
|
||||||
#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
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
|
|
||||||
* \param[in] BlockAddress Data block starting address for the write sequence
|
|
||||||
* \param[in] TotalBlocks Number of blocks of data to write
|
|
||||||
*/
|
|
||||||
void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
|
||||||
const uint32_t BlockAddress,
|
|
||||||
uint16_t TotalBlocks)
|
|
||||||
{
|
|
||||||
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
|
|
||||||
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
|
||||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
|
||||||
bool UsingSecondBuffer = false;
|
|
||||||
|
|
||||||
/* Select the correct starting Dataflash IC for the block requested */
|
|
||||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
|
||||||
|
|
||||||
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
|
|
||||||
/* Copy selected dataflash's current page contents to the Dataflash buffer */
|
|
||||||
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Send the Dataflash buffer write command */
|
|
||||||
Dataflash_SendByte(DF_CMD_BUFF1WRITE);
|
|
||||||
Dataflash_SendAddressBytes(0, CurrDFPageByte);
|
|
||||||
|
|
||||||
/* Wait until endpoint is ready before continuing */
|
|
||||||
if (Endpoint_WaitUntilReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (TotalBlocks)
|
|
||||||
{
|
|
||||||
uint8_t BytesInBlockDiv16 = 0;
|
|
||||||
|
|
||||||
/* Write an endpoint packet sized data block to the Dataflash */
|
|
||||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
|
||||||
{
|
|
||||||
/* Check if the endpoint is currently empty */
|
|
||||||
if (!(Endpoint_IsReadWriteAllowed()))
|
|
||||||
{
|
|
||||||
/* Clear the current endpoint bank */
|
|
||||||
Endpoint_ClearOUT();
|
|
||||||
|
|
||||||
/* Wait until the host has sent another packet */
|
|
||||||
if (Endpoint_WaitUntilReady())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if end of Dataflash page reached */
|
|
||||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
|
||||||
{
|
|
||||||
/* Write the Dataflash buffer contents back to the Dataflash page */
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
|
||||||
|
|
||||||
/* Reset the Dataflash buffer counter, increment the page counter */
|
|
||||||
CurrDFPageByteDiv16 = 0;
|
|
||||||
CurrDFPage++;
|
|
||||||
|
|
||||||
/* Once all the Dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
|
|
||||||
if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
|
|
||||||
UsingSecondBuffer = !(UsingSecondBuffer);
|
|
||||||
|
|
||||||
/* Select the next Dataflash chip based on the new Dataflash page index */
|
|
||||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
|
||||||
|
|
||||||
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
|
|
||||||
/* If less than one Dataflash page remaining, copy over the existing page to preserve trailing data */
|
|
||||||
if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
|
|
||||||
{
|
|
||||||
/* Copy selected dataflash's current page contents to the Dataflash buffer */
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Send the Dataflash buffer write command */
|
|
||||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
|
|
||||||
Dataflash_SendAddressBytes(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write one 16-byte chunk of data to the Dataflash */
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
Dataflash_SendByte(Endpoint_Read_8());
|
|
||||||
|
|
||||||
/* Increment the Dataflash page 16 byte block counter */
|
|
||||||
CurrDFPageByteDiv16++;
|
|
||||||
|
|
||||||
/* Increment the block 16 byte block counter */
|
|
||||||
BytesInBlockDiv16++;
|
|
||||||
|
|
||||||
/* Check if the current command is being aborted by the host */
|
|
||||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrement the blocks remaining counter */
|
|
||||||
TotalBlocks--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the Dataflash buffer contents back to the Dataflash page */
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, 0x00);
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
|
|
||||||
/* If the endpoint is empty, clear it ready for the next packet from the host */
|
|
||||||
if (!(Endpoint_IsReadWriteAllowed()))
|
|
||||||
Endpoint_ClearOUT();
|
|
||||||
|
|
||||||
/* Deselect all Dataflash chips */
|
|
||||||
Dataflash_DeselectChip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board Dataflash IC(s), into
|
|
||||||
* the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash
|
|
||||||
* and writes them in OS sized blocks to the endpoint.
|
|
||||||
*
|
|
||||||
* \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state
|
|
||||||
* \param[in] BlockAddress Data block starting address for the read sequence
|
|
||||||
* \param[in] TotalBlocks Number of blocks of data to read
|
|
||||||
*/
|
|
||||||
void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
|
||||||
const uint32_t BlockAddress,
|
|
||||||
uint16_t TotalBlocks)
|
|
||||||
{
|
|
||||||
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
|
|
||||||
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
|
||||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
|
||||||
|
|
||||||
/* Select the correct starting Dataflash IC for the block requested */
|
|
||||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
|
||||||
|
|
||||||
/* Send the Dataflash main memory page read command */
|
|
||||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
|
|
||||||
/* Wait until endpoint is ready before continuing */
|
|
||||||
if (Endpoint_WaitUntilReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (TotalBlocks)
|
|
||||||
{
|
|
||||||
uint8_t BytesInBlockDiv16 = 0;
|
|
||||||
|
|
||||||
/* Write an endpoint packet sized data block to the Dataflash */
|
|
||||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
|
||||||
{
|
|
||||||
/* Check if the endpoint is currently full */
|
|
||||||
if (!(Endpoint_IsReadWriteAllowed()))
|
|
||||||
{
|
|
||||||
/* Clear the endpoint bank to send its contents to the host */
|
|
||||||
Endpoint_ClearIN();
|
|
||||||
|
|
||||||
/* Wait until the endpoint is ready for more data */
|
|
||||||
if (Endpoint_WaitUntilReady())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if end of Dataflash page reached */
|
|
||||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
|
||||||
{
|
|
||||||
/* Reset the Dataflash buffer counter, increment the page counter */
|
|
||||||
CurrDFPageByteDiv16 = 0;
|
|
||||||
CurrDFPage++;
|
|
||||||
|
|
||||||
/* Select the next Dataflash chip based on the new Dataflash page index */
|
|
||||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
|
||||||
|
|
||||||
/* Send the Dataflash main memory page read command */
|
|
||||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read one 16-byte chunk of data from the Dataflash */
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
Endpoint_Write_8(Dataflash_ReceiveByte());
|
|
||||||
|
|
||||||
/* Increment the Dataflash page 16 byte block counter */
|
|
||||||
CurrDFPageByteDiv16++;
|
|
||||||
|
|
||||||
/* Increment the block 16 byte block counter */
|
|
||||||
BytesInBlockDiv16++;
|
|
||||||
|
|
||||||
/* Check if the current command is being aborted by the host */
|
|
||||||
if (MSInterfaceInfo->State.IsMassStoreReset)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrement the blocks remaining counter */
|
|
||||||
TotalBlocks--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the endpoint is full, send its contents to the host */
|
|
||||||
if (!(Endpoint_IsReadWriteAllowed()))
|
|
||||||
Endpoint_ClearIN();
|
|
||||||
|
|
||||||
/* Deselect all Dataflash chips */
|
|
||||||
Dataflash_DeselectChip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board Dataflash IC(s), from
|
|
||||||
* the given RAM buffer. This routine reads in OS sized blocks from the buffer and writes them to the
|
|
||||||
* Dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the
|
|
||||||
* Dataflash.
|
|
||||||
*
|
|
||||||
* \param[in] BlockAddress Data block starting address for the write sequence
|
|
||||||
* \param[in] TotalBlocks Number of blocks of data to write
|
|
||||||
* \param[in] BufferPtr Pointer to the data source RAM buffer
|
|
||||||
*/
|
|
||||||
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress,
|
|
||||||
uint16_t TotalBlocks,
|
|
||||||
const uint8_t* BufferPtr)
|
|
||||||
{
|
|
||||||
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
|
|
||||||
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
|
||||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
|
||||||
bool UsingSecondBuffer = false;
|
|
||||||
|
|
||||||
/* Select the correct starting Dataflash IC for the block requested */
|
|
||||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
|
||||||
|
|
||||||
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
|
|
||||||
/* Copy selected dataflash's current page contents to the Dataflash buffer */
|
|
||||||
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Send the Dataflash buffer write command */
|
|
||||||
Dataflash_SendByte(DF_CMD_BUFF1WRITE);
|
|
||||||
Dataflash_SendAddressBytes(0, CurrDFPageByte);
|
|
||||||
|
|
||||||
while (TotalBlocks)
|
|
||||||
{
|
|
||||||
uint8_t BytesInBlockDiv16 = 0;
|
|
||||||
|
|
||||||
/* Write an endpoint packet sized data block to the Dataflash */
|
|
||||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
|
||||||
{
|
|
||||||
/* Check if end of Dataflash page reached */
|
|
||||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
|
||||||
{
|
|
||||||
/* Write the Dataflash buffer contents back to the Dataflash page */
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
|
||||||
|
|
||||||
/* Reset the Dataflash buffer counter, increment the page counter */
|
|
||||||
CurrDFPageByteDiv16 = 0;
|
|
||||||
CurrDFPage++;
|
|
||||||
|
|
||||||
/* Once all the Dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
|
|
||||||
if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
|
|
||||||
UsingSecondBuffer = !(UsingSecondBuffer);
|
|
||||||
|
|
||||||
/* Select the next Dataflash chip based on the new Dataflash page index */
|
|
||||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
|
||||||
|
|
||||||
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
|
|
||||||
/* If less than one Dataflash page remaining, copy over the existing page to preserve trailing data */
|
|
||||||
if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
|
|
||||||
{
|
|
||||||
/* Copy selected dataflash's current page contents to the Dataflash buffer */
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Send the Dataflash buffer write command */
|
|
||||||
Dataflash_ToggleSelectedChipCS();
|
|
||||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
|
|
||||||
Dataflash_SendAddressBytes(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write one 16-byte chunk of data to the Dataflash */
|
|
||||||
for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
|
|
||||||
Dataflash_SendByte(*(BufferPtr++));
|
|
||||||
|
|
||||||
/* Increment the Dataflash page 16 byte block counter */
|
|
||||||
CurrDFPageByteDiv16++;
|
|
||||||
|
|
||||||
/* Increment the block 16 byte block counter */
|
|
||||||
BytesInBlockDiv16++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrement the blocks remaining counter */
|
|
||||||
TotalBlocks--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the Dataflash buffer contents back to the Dataflash page */
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, 0x00);
|
|
||||||
Dataflash_WaitWhileBusy();
|
|
||||||
|
|
||||||
/* Deselect all Dataflash chips */
|
|
||||||
Dataflash_DeselectChip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board Dataflash IC(s), into
|
|
||||||
* the preallocated RAM buffer. This routine reads in Dataflash page sized blocks from the Dataflash
|
|
||||||
* and writes them in OS sized blocks to the given buffer. This can be linked to FAT libraries to read
|
|
||||||
* the files stored on the Dataflash.
|
|
||||||
*
|
|
||||||
* \param[in] BlockAddress Data block starting address for the read sequence
|
|
||||||
* \param[in] TotalBlocks Number of blocks of data to read
|
|
||||||
* \param[out] BufferPtr Pointer to the data destination RAM buffer
|
|
||||||
*/
|
|
||||||
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress,
|
|
||||||
uint16_t TotalBlocks,
|
|
||||||
uint8_t* BufferPtr)
|
|
||||||
{
|
|
||||||
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
|
|
||||||
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
|
|
||||||
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
|
|
||||||
|
|
||||||
/* Select the correct starting Dataflash IC for the block requested */
|
|
||||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
|
||||||
|
|
||||||
/* Send the Dataflash main memory page read command */
|
|
||||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
|
|
||||||
while (TotalBlocks)
|
|
||||||
{
|
|
||||||
uint8_t BytesInBlockDiv16 = 0;
|
|
||||||
|
|
||||||
/* Write an endpoint packet sized data block to the Dataflash */
|
|
||||||
while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
|
|
||||||
{
|
|
||||||
/* Check if end of Dataflash page reached */
|
|
||||||
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
|
|
||||||
{
|
|
||||||
/* Reset the Dataflash buffer counter, increment the page counter */
|
|
||||||
CurrDFPageByteDiv16 = 0;
|
|
||||||
CurrDFPage++;
|
|
||||||
|
|
||||||
/* Select the next Dataflash chip based on the new Dataflash page index */
|
|
||||||
Dataflash_SelectChipFromPage(CurrDFPage);
|
|
||||||
|
|
||||||
/* Send the Dataflash main memory page read command */
|
|
||||||
Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
|
|
||||||
Dataflash_SendAddressBytes(CurrDFPage, 0);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
Dataflash_SendByte(0x00);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read one 16-byte chunk of data from the Dataflash */
|
|
||||||
for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
|
|
||||||
*(BufferPtr++) = Dataflash_ReceiveByte();
|
|
||||||
|
|
||||||
/* Increment the Dataflash page 16 byte block counter */
|
|
||||||
CurrDFPageByteDiv16++;
|
|
||||||
|
|
||||||
/* Increment the block 16 byte block counter */
|
|
||||||
BytesInBlockDiv16++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrement the blocks remaining counter */
|
|
||||||
TotalBlocks--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Deselect all Dataflash chips */
|
|
||||||
Dataflash_DeselectChip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Disables the Dataflash memory write protection bits on the board Dataflash ICs, if enabled. */
|
|
||||||
void DataflashManager_ResetDataflashProtections(void)
|
|
||||||
{
|
|
||||||
/* Select first Dataflash chip, send the read status register command */
|
|
||||||
Dataflash_SelectChip(DATAFLASH_CHIP1);
|
|
||||||
Dataflash_SendByte(DF_CMD_GETSTATUS);
|
|
||||||
|
|
||||||
/* Check if sector protection is enabled */
|
|
||||||
if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
|
|
||||||
{
|
|
||||||
Dataflash_ToggleSelectedChipCS();
|
|
||||||
|
|
||||||
/* Send the commands to disable sector protection */
|
|
||||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
|
|
||||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
|
|
||||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
|
|
||||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Select second Dataflash chip (if present on selected board), send read status register command */
|
|
||||||
#if (DATAFLASH_TOTALCHIPS == 2)
|
|
||||||
Dataflash_SelectChip(DATAFLASH_CHIP2);
|
|
||||||
Dataflash_SendByte(DF_CMD_GETSTATUS);
|
|
||||||
|
|
||||||
/* Check if sector protection is enabled */
|
|
||||||
if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
|
|
||||||
{
|
|
||||||
Dataflash_ToggleSelectedChipCS();
|
|
||||||
|
|
||||||
/* Send the commands to disable sector protection */
|
|
||||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
|
|
||||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
|
|
||||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
|
|
||||||
Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Deselect current Dataflash chip */
|
|
||||||
Dataflash_DeselectChip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Performs a simple test on the attached Dataflash IC(s) to ensure that they are working.
|
|
||||||
*
|
|
||||||
* \return Boolean true if all media chips are working, false otherwise
|
|
||||||
*/
|
|
||||||
bool DataflashManager_CheckDataflashOperation(void)
|
|
||||||
{
|
|
||||||
uint8_t ReturnByte;
|
|
||||||
|
|
||||||
/* Test first Dataflash IC is present and responding to commands */
|
|
||||||
Dataflash_SelectChip(DATAFLASH_CHIP1);
|
|
||||||
Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
|
|
||||||
ReturnByte = Dataflash_ReceiveByte();
|
|
||||||
Dataflash_DeselectChip();
|
|
||||||
|
|
||||||
/* If returned data is invalid, fail the command */
|
|
||||||
if (ReturnByte != DF_MANUFACTURER_ATMEL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#if (DATAFLASH_TOTALCHIPS == 2)
|
|
||||||
/* Test second Dataflash IC is present and responding to commands */
|
|
||||||
Dataflash_SelectChip(DATAFLASH_CHIP2);
|
|
||||||
Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
|
|
||||||
ReturnByte = Dataflash_ReceiveByte();
|
|
||||||
Dataflash_DeselectChip();
|
|
||||||
|
|
||||||
/* If returned data is invalid, fail the command */
|
|
||||||
if (ReturnByte != DF_MANUFACTURER_ATMEL)
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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 DataflashManager.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _DATAFLASH_MANAGER_H_
|
|
||||||
#define _DATAFLASH_MANAGER_H_
|
|
||||||
|
|
||||||
/* Includes: */
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
#include "../StandaloneProgrammer.h"
|
|
||||||
#include "../Descriptors.h"
|
|
||||||
|
|
||||||
#include <LUFA/Drivers/USB/USB.h>
|
|
||||||
#include <LUFA/Drivers/Board/Dataflash.h>
|
|
||||||
|
|
||||||
/* Preprocessor Checks: */
|
|
||||||
#if (DATAFLASH_PAGE_SIZE % 16)
|
|
||||||
#error Dataflash page size must be a multiple of 16 bytes.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Defines: */
|
|
||||||
/** Total number of bytes of the storage medium, comprised of one or more dataflash ICs. */
|
|
||||||
#define VIRTUAL_MEMORY_BYTES ((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS)
|
|
||||||
|
|
||||||
/** Block size of the device. This is kept at 512 to remain compatible with the OS despite the underlying
|
|
||||||
* storage media (Dataflash) using a different native block size. Do not change this value.
|
|
||||||
*/
|
|
||||||
#define VIRTUAL_MEMORY_BLOCK_SIZE 512
|
|
||||||
|
|
||||||
/** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. Do not
|
|
||||||
* change this value; change VIRTUAL_MEMORY_BYTES instead to alter the media size.
|
|
||||||
*/
|
|
||||||
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
|
|
||||||
|
|
||||||
/** Indicates if the disk is write protected or not. */
|
|
||||||
#define DISK_READ_ONLY false
|
|
||||||
|
|
||||||
/* Function Prototypes: */
|
|
||||||
#if defined(USB_CAN_BE_DEVICE)
|
|
||||||
void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
|
||||||
const uint32_t BlockAddress,
|
|
||||||
uint16_t TotalBlocks);
|
|
||||||
void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
|
||||||
const uint32_t BlockAddress,
|
|
||||||
uint16_t TotalBlocks);
|
|
||||||
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress,
|
|
||||||
uint16_t TotalBlocks,
|
|
||||||
const uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
|
||||||
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress,
|
|
||||||
uint16_t TotalBlocks,
|
|
||||||
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
|
|
||||||
void DataflashManager_ResetDataflashProtections(void);
|
|
||||||
bool DataflashManager_CheckDataflashOperation(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
Petit FatFs Module Source Files R0.02a (C)ChaN, 2010
|
|
||||||
|
|
||||||
|
|
||||||
FILES
|
|
||||||
|
|
||||||
pff.h Common include file for Petit FatFs and application module.
|
|
||||||
pff.c Petit FatFs module.
|
|
||||||
diskio.h Common include file for Petit FatFs and disk I/O module.
|
|
||||||
diskio.c Skeleton of low level disk I/O module.
|
|
||||||
integer.h Alternative type definitions for integer variables.
|
|
||||||
|
|
||||||
Low level disk I/O module is not included in this archive because the Petit
|
|
||||||
FatFs module is only a generic file system layer and not depend on any
|
|
||||||
specific storage device. You have to provide a low level disk I/O module that
|
|
||||||
written to control your storage device.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AGREEMENTS
|
|
||||||
|
|
||||||
Petit FatFs module is an open source software to implement FAT file system to
|
|
||||||
small embedded systems. This is a free software and is opened for education,
|
|
||||||
research and commercial developments under license policy of following trems.
|
|
||||||
|
|
||||||
Copyright (C) 2010, ChaN, all right reserved.
|
|
||||||
|
|
||||||
* The Petit FatFs module is a free software and there is NO WARRANTY.
|
|
||||||
* No restriction on use. You can use, modify and redistribute it for
|
|
||||||
personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
|
|
||||||
* Redistributions of source code must retain the above copyright notice.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
REVISION HISTORY
|
|
||||||
|
|
||||||
Jun 15, 2009 R0.01a First release (Branched from FatFs R0.07b)
|
|
||||||
Dec 14, 2009 R0.02 Added multiple code page support.
|
|
||||||
Added write funciton.
|
|
||||||
Changed stream read mode interface.
|
|
||||||
Dec 07,'2010 R0.02a Added some configuration options.
|
|
||||||
Fixed fails to open objects with DBCS character.
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Low level disk I/O module skeleton for Petit FatFs (C)ChaN, 2009 */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "diskio.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <LUFA/Drivers/USB/USB.h>
|
|
||||||
#include "../DataflashManager.h"
|
|
||||||
#include "../../DiskHost.h"
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Initialize Disk Drive */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DSTATUS disk_initialize (void)
|
|
||||||
{
|
|
||||||
return RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read Partial Sector */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DRESULT disk_readp (
|
|
||||||
BYTE* dest, /* Pointer to the destination object */
|
|
||||||
DWORD sector, /* Sector number (LBA) */
|
|
||||||
WORD sofs, /* Offset in the sector */
|
|
||||||
WORD count /* Byte count (bit15:destination) */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DRESULT ErrorCode = RES_OK;
|
|
||||||
uint8_t BlockTemp[512];
|
|
||||||
|
|
||||||
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;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if defined(USB_CAN_BE_DEVICE)
|
|
||||||
DataflashManager_ReadBlocks_RAM(sector, 1, BlockTemp);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dest, &BlockTemp[sofs], count);
|
|
||||||
|
|
||||||
return ErrorCode;
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------
|
|
||||||
/ PFF - Low level disk interface module include file (C)ChaN, 2010
|
|
||||||
/-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _DISKIO
|
|
||||||
|
|
||||||
#include "integer.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Status of Disk Functions */
|
|
||||||
typedef BYTE DSTATUS;
|
|
||||||
|
|
||||||
|
|
||||||
/* Results of Disk Functions */
|
|
||||||
typedef enum {
|
|
||||||
RES_OK = 0, /* 0: Function succeeded */
|
|
||||||
RES_ERROR, /* 1: Disk error */
|
|
||||||
RES_NOTRDY, /* 2: Not ready */
|
|
||||||
RES_PARERR /* 3: Invalid parameter */
|
|
||||||
} DRESULT;
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------*/
|
|
||||||
/* Prototypes for disk control functions */
|
|
||||||
|
|
||||||
DSTATUS disk_initialize (void);
|
|
||||||
DRESULT disk_readp (BYTE*, DWORD, WORD, WORD);
|
|
||||||
|
|
||||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
|
||||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
|
||||||
|
|
||||||
#define _DISKIO
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
/*-------------------------------------------*/
|
|
||||||
/* Integer type definitions for FatFs module */
|
|
||||||
/*-------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _INTEGER
|
|
||||||
#define _INTEGER
|
|
||||||
|
|
||||||
#ifdef _WIN32 /* FatFs development platform */
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <tchar.h>
|
|
||||||
|
|
||||||
#else /* Embedded platform */
|
|
||||||
|
|
||||||
/* These types must be 16-bit, 32-bit or larger integer */
|
|
||||||
typedef int INT;
|
|
||||||
typedef unsigned int UINT;
|
|
||||||
|
|
||||||
/* These types must be 8-bit integer */
|
|
||||||
typedef char CHAR;
|
|
||||||
typedef unsigned char UCHAR;
|
|
||||||
typedef unsigned char BYTE;
|
|
||||||
|
|
||||||
/* These types must be 16-bit integer */
|
|
||||||
typedef short SHORT;
|
|
||||||
typedef unsigned short USHORT;
|
|
||||||
typedef unsigned short WORD;
|
|
||||||
typedef unsigned short WCHAR;
|
|
||||||
|
|
||||||
/* These types must be 32-bit integer */
|
|
||||||
typedef long LONG;
|
|
||||||
typedef unsigned long ULONG;
|
|
||||||
typedef unsigned long DWORD;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,1114 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------/
|
|
||||||
/ Petit FatFs - FAT file system module R0.02a (C)ChaN, 2010
|
|
||||||
/-----------------------------------------------------------------------------/
|
|
||||||
/ Petit FatFs module is an open source software to implement FAT file system to
|
|
||||||
/ small embedded systems. This is a free software and is opened for education,
|
|
||||||
/ research and commercial developments under license policy of following trems.
|
|
||||||
/
|
|
||||||
/ Copyright (C) 2010, ChaN, all right reserved.
|
|
||||||
/
|
|
||||||
/ * The Petit FatFs module is a free software and there is NO WARRANTY.
|
|
||||||
/ * No restriction on use. You can use, modify and redistribute it for
|
|
||||||
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
|
|
||||||
/ * Redistributions of source code must retain the above copyright notice.
|
|
||||||
/
|
|
||||||
/-----------------------------------------------------------------------------/
|
|
||||||
/ Jun 15,'09 R0.01a First release. (Branched from FatFs R0.07b.)
|
|
||||||
/
|
|
||||||
/ Dec 14,'09 R0.02 Added multiple code page support.
|
|
||||||
/ Added write funciton.
|
|
||||||
/ Changed stream read mode interface.
|
|
||||||
/ Dec 07,'10 R0.02a Added some configuration options.
|
|
||||||
/ Fixed fails to open objects with DBCS character.
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "pff.h" /* Petit FatFs configurations and declarations */
|
|
||||||
#include "diskio.h" /* Declarations of low level disk I/O functions */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Module Private Definitions
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
#if _FS_FAT32
|
|
||||||
#define LD_CLUST(dir) (((DWORD)LD_WORD(dir+DIR_FstClusHI)<<16) | LD_WORD(dir+DIR_FstClusLO))
|
|
||||||
#else
|
|
||||||
#define LD_CLUST(dir) LD_WORD(dir+DIR_FstClusLO)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------*/
|
|
||||||
/* DBCS code ranges and SBCS extend char conversion table */
|
|
||||||
|
|
||||||
#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
|
|
||||||
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
|
|
||||||
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
|
|
||||||
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
|
|
||||||
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
|
|
||||||
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
|
|
||||||
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
|
|
||||||
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
|
|
||||||
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
|
|
||||||
#define _DF1S 0x81
|
|
||||||
#define _DF1E 0xFE
|
|
||||||
#define _DS1S 0x40
|
|
||||||
#define _DS1E 0x7E
|
|
||||||
#define _DS2S 0x80
|
|
||||||
#define _DS2E 0xFE
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 949 /* Korean */
|
|
||||||
#define _DF1S 0x81
|
|
||||||
#define _DF1E 0xFE
|
|
||||||
#define _DS1S 0x41
|
|
||||||
#define _DS1E 0x5A
|
|
||||||
#define _DS2S 0x61
|
|
||||||
#define _DS2E 0x7A
|
|
||||||
#define _DS3S 0x81
|
|
||||||
#define _DS3E 0xFE
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
|
||||||
#define _DF1S 0x81
|
|
||||||
#define _DF1E 0xFE
|
|
||||||
#define _DS1S 0x40
|
|
||||||
#define _DS1E 0x7E
|
|
||||||
#define _DS2S 0xA1
|
|
||||||
#define _DS2E 0xFE
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 437 /* U.S. (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 720 /* Arabic (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 737 /* Greek (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
|
|
||||||
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 775 /* Baltic (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
|
|
||||||
0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
|
|
||||||
0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
|
|
||||||
0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 857 /* Turkish (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
|
|
||||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 866 /* Russian (OEM) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
|
|
||||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
|
|
||||||
0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
|
|
||||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 1253 /* Greek (Windows) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
|
|
||||||
0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 1254 /* Turkish (Windows) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
|
|
||||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 1256 /* Arabic (Windows) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
|
|
||||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 1257 /* Baltic (Windows) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
|
||||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
|
|
||||||
#define _DF1S 0
|
|
||||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
|
|
||||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
|
||||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
|
|
||||||
#define _DF1S 0
|
|
||||||
|
|
||||||
#else
|
|
||||||
#error Unknown code page
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Character code support macros */
|
|
||||||
|
|
||||||
#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
|
|
||||||
#define IsLower(c) (((c)>='a')&&((c)<='z'))
|
|
||||||
|
|
||||||
#if _DF1S /* DBCS configuration */
|
|
||||||
|
|
||||||
#ifdef _DF2S /* Two 1st byte areas */
|
|
||||||
#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
|
|
||||||
#else /* One 1st byte area */
|
|
||||||
#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _DS3S /* Three 2nd byte areas */
|
|
||||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
|
|
||||||
#else /* Two 2nd byte areas */
|
|
||||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* SBCS configuration */
|
|
||||||
|
|
||||||
#define IsDBCS1(c) 0
|
|
||||||
#define IsDBCS2(c) 0
|
|
||||||
|
|
||||||
#endif /* _DF1S */
|
|
||||||
|
|
||||||
|
|
||||||
/* FatFs refers the members in the FAT structures with byte offset instead
|
|
||||||
/ of structure member because there are incompatibility of the packing option
|
|
||||||
/ between various compilers. */
|
|
||||||
|
|
||||||
#define BS_jmpBoot 0
|
|
||||||
#define BS_OEMName 3
|
|
||||||
#define BPB_BytsPerSec 11
|
|
||||||
#define BPB_SecPerClus 13
|
|
||||||
#define BPB_RsvdSecCnt 14
|
|
||||||
#define BPB_NumFATs 16
|
|
||||||
#define BPB_RootEntCnt 17
|
|
||||||
#define BPB_TotSec16 19
|
|
||||||
#define BPB_Media 21
|
|
||||||
#define BPB_FATSz16 22
|
|
||||||
#define BPB_SecPerTrk 24
|
|
||||||
#define BPB_NumHeads 26
|
|
||||||
#define BPB_HiddSec 28
|
|
||||||
#define BPB_TotSec32 32
|
|
||||||
#define BS_55AA 510
|
|
||||||
|
|
||||||
#define BS_DrvNum 36
|
|
||||||
#define BS_BootSig 38
|
|
||||||
#define BS_VolID 39
|
|
||||||
#define BS_VolLab 43
|
|
||||||
#define BS_FilSysType 54
|
|
||||||
|
|
||||||
#define BPB_FATSz32 36
|
|
||||||
#define BPB_ExtFlags 40
|
|
||||||
#define BPB_FSVer 42
|
|
||||||
#define BPB_RootClus 44
|
|
||||||
#define BPB_FSInfo 48
|
|
||||||
#define BPB_BkBootSec 50
|
|
||||||
#define BS_DrvNum32 64
|
|
||||||
#define BS_BootSig32 66
|
|
||||||
#define BS_VolID32 67
|
|
||||||
#define BS_VolLab32 71
|
|
||||||
#define BS_FilSysType32 82
|
|
||||||
|
|
||||||
#define MBR_Table 446
|
|
||||||
|
|
||||||
#define DIR_Name 0
|
|
||||||
#define DIR_Attr 11
|
|
||||||
#define DIR_NTres 12
|
|
||||||
#define DIR_CrtTime 14
|
|
||||||
#define DIR_CrtDate 16
|
|
||||||
#define DIR_FstClusHI 20
|
|
||||||
#define DIR_WrtTime 22
|
|
||||||
#define DIR_WrtDate 24
|
|
||||||
#define DIR_FstClusLO 26
|
|
||||||
#define DIR_FileSize 28
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Private Functions
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
FATFS *FatFs; /* Pointer to the file system object (logical drive) */
|
|
||||||
|
|
||||||
|
|
||||||
/* Fill memory */
|
|
||||||
static
|
|
||||||
void mem_set (void* dst, int val, int cnt) {
|
|
||||||
char *d = (char*)dst;
|
|
||||||
while (cnt--) *d++ = (char)val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare memory to memory */
|
|
||||||
static
|
|
||||||
int mem_cmp (const void* dst, const void* src, int cnt) {
|
|
||||||
const char *d = (const char *)dst, *s = (const char *)src;
|
|
||||||
int r = 0;
|
|
||||||
while (cnt-- && (r = *d++ - *s++) == 0) ;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* FAT access - Read value of a FAT entry */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static
|
|
||||||
CLUST get_fat ( /* 1:IO error, Else:Cluster status */
|
|
||||||
CLUST clst /* Cluster# to get the link information */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
WORD wc, bc, ofs;
|
|
||||||
BYTE buf[4];
|
|
||||||
FATFS *fs = FatFs;
|
|
||||||
|
|
||||||
|
|
||||||
if (clst < 2 || clst >= fs->n_fatent) /* Range check */
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
switch (fs->fs_type) {
|
|
||||||
#if _FS_FAT12
|
|
||||||
case FS_FAT12 :
|
|
||||||
bc = (WORD)clst; bc += bc / 2;
|
|
||||||
ofs = bc % 512; bc /= 512;
|
|
||||||
if (ofs != 511) {
|
|
||||||
if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break;
|
|
||||||
} else {
|
|
||||||
if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break;
|
|
||||||
if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break;
|
|
||||||
}
|
|
||||||
wc = LD_WORD(buf);
|
|
||||||
return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
|
|
||||||
#endif
|
|
||||||
case FS_FAT16 :
|
|
||||||
if (disk_readp(buf, fs->fatbase + clst / 256, (WORD)(((WORD)clst % 256) * 2), 2)) break;
|
|
||||||
return LD_WORD(buf);
|
|
||||||
#if _FS_FAT32
|
|
||||||
case FS_FAT32 :
|
|
||||||
if (disk_readp(buf, fs->fatbase + clst / 128, (WORD)(((WORD)clst % 128) * 4), 4)) break;
|
|
||||||
return LD_DWORD(buf) & 0x0FFFFFFF;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1; /* An error occured at the disk I/O layer */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Get sector# from cluster# */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static
|
|
||||||
DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
|
|
||||||
CLUST clst /* Cluster# to be converted */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FATFS *fs = FatFs;
|
|
||||||
|
|
||||||
|
|
||||||
clst -= 2;
|
|
||||||
if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */
|
|
||||||
return (DWORD)clst * fs->csize + fs->database;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Directory handling - Rewind directory index */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static
|
|
||||||
FRESULT dir_rewind (
|
|
||||||
DIR *dj /* Pointer to directory object */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CLUST clst;
|
|
||||||
FATFS *fs = FatFs;
|
|
||||||
|
|
||||||
|
|
||||||
dj->index = 0;
|
|
||||||
clst = dj->sclust;
|
|
||||||
if (clst == 1 || clst >= fs->n_fatent) /* Check start cluster range */
|
|
||||||
return FR_DISK_ERR;
|
|
||||||
if (_FS_FAT32 && !clst && fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */
|
|
||||||
clst = (CLUST)fs->dirbase;
|
|
||||||
dj->clust = clst; /* Current cluster */
|
|
||||||
dj->sect = clst ? clust2sect(clst) : fs->dirbase; /* Current sector */
|
|
||||||
|
|
||||||
return FR_OK; /* Seek succeeded */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Directory handling - Move directory index next */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static
|
|
||||||
FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table */
|
|
||||||
DIR *dj /* Pointer to directory object */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CLUST clst;
|
|
||||||
WORD i;
|
|
||||||
FATFS *fs = FatFs;
|
|
||||||
|
|
||||||
|
|
||||||
i = dj->index + 1;
|
|
||||||
if (!i || !dj->sect) /* Report EOT when index has reached 65535 */
|
|
||||||
return FR_NO_FILE;
|
|
||||||
|
|
||||||
if (!(i % 16)) { /* Sector changed? */
|
|
||||||
dj->sect++; /* Next sector */
|
|
||||||
|
|
||||||
if (dj->clust == 0) { /* Static table */
|
|
||||||
if (i >= fs->n_rootdir) /* Report EOT when end of table */
|
|
||||||
return FR_NO_FILE;
|
|
||||||
}
|
|
||||||
else { /* Dynamic table */
|
|
||||||
if (((i / 16) & (fs->csize-1)) == 0) { /* Cluster changed? */
|
|
||||||
clst = get_fat(dj->clust); /* Get next cluster */
|
|
||||||
if (clst <= 1) return FR_DISK_ERR;
|
|
||||||
if (clst >= fs->n_fatent) /* When it reached end of dynamic table */
|
|
||||||
return FR_NO_FILE; /* Report EOT */
|
|
||||||
dj->clust = clst; /* Initialize data for new cluster */
|
|
||||||
dj->sect = clust2sect(clst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dj->index = i;
|
|
||||||
|
|
||||||
return FR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Directory handling - Find an object in the directory */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static
|
|
||||||
FRESULT dir_find (
|
|
||||||
DIR *dj, /* Pointer to the directory object linked to the file name */
|
|
||||||
BYTE *dir /* 32-byte working buffer */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FRESULT res;
|
|
||||||
BYTE c;
|
|
||||||
|
|
||||||
|
|
||||||
res = dir_rewind(dj); /* Rewind directory object */
|
|
||||||
if (res != FR_OK) return res;
|
|
||||||
|
|
||||||
do {
|
|
||||||
res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
|
|
||||||
? FR_DISK_ERR : FR_OK;
|
|
||||||
if (res != FR_OK) break;
|
|
||||||
c = dir[DIR_Name]; /* First character */
|
|
||||||
if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
|
|
||||||
if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
|
|
||||||
break;
|
|
||||||
res = dir_next(dj); /* Next entry */
|
|
||||||
} while (res == FR_OK);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read an object from the directory */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
#if _USE_DIR
|
|
||||||
static
|
|
||||||
FRESULT dir_read (
|
|
||||||
DIR *dj, /* Pointer to the directory object to store read object name */
|
|
||||||
BYTE *dir /* 32-byte working buffer */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FRESULT res;
|
|
||||||
BYTE a, c;
|
|
||||||
|
|
||||||
|
|
||||||
res = FR_NO_FILE;
|
|
||||||
while (dj->sect) {
|
|
||||||
res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
|
|
||||||
? FR_DISK_ERR : FR_OK;
|
|
||||||
if (res != FR_OK) break;
|
|
||||||
c = dir[DIR_Name];
|
|
||||||
if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */
|
|
||||||
a = dir[DIR_Attr] & AM_MASK;
|
|
||||||
if (c != 0xE5 && c != '.' && !(a & AM_VOL)) /* Is it a valid entry? */
|
|
||||||
break;
|
|
||||||
res = dir_next(dj); /* Next entry */
|
|
||||||
if (res != FR_OK) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != FR_OK) dj->sect = 0;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Pick a segment and create the object name in directory form */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifdef _EXCVT
|
|
||||||
static const BYTE cvt[] = _EXCVT;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static
|
|
||||||
FRESULT create_name (
|
|
||||||
DIR *dj, /* Pointer to the directory object */
|
|
||||||
const char **path /* Pointer to pointer to the segment in the path string */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
BYTE c, d, ni, si, i, *sfn;
|
|
||||||
const char *p;
|
|
||||||
|
|
||||||
/* Create file name in directory form */
|
|
||||||
sfn = dj->fn;
|
|
||||||
mem_set(sfn, ' ', 11);
|
|
||||||
si = i = 0; ni = 8;
|
|
||||||
p = *path;
|
|
||||||
for (;;) {
|
|
||||||
c = p[si++];
|
|
||||||
if (c <= ' ' || c == '/') break; /* Break on end of segment */
|
|
||||||
if (c == '.' || i >= ni) {
|
|
||||||
if (ni != 8 || c != '.') break;
|
|
||||||
i = 8; ni = 11;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#ifdef _EXCVT
|
|
||||||
if (c >= 0x80) /* To upper extended char (SBCS) */
|
|
||||||
c = cvt[c - 0x80];
|
|
||||||
#endif
|
|
||||||
if (IsDBCS1(c) && i < ni - 1) { /* DBC 1st byte? */
|
|
||||||
d = p[si++]; /* Get 2nd byte */
|
|
||||||
sfn[i++] = c;
|
|
||||||
sfn[i++] = d;
|
|
||||||
} else { /* Single byte code */
|
|
||||||
if (IsLower(c)) c -= 0x20; /* toupper */
|
|
||||||
sfn[i++] = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*path = &p[si]; /* Rerurn pointer to the next segment */
|
|
||||||
|
|
||||||
sfn[11] = (c <= ' ') ? 1 : 0; /* Set last segment flag if end of path */
|
|
||||||
|
|
||||||
return FR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Get file information from directory entry */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
#if _USE_DIR
|
|
||||||
static
|
|
||||||
void get_fileinfo ( /* No return code */
|
|
||||||
DIR *dj, /* Pointer to the directory object */
|
|
||||||
BYTE *dir, /* 32-byte working buffer */
|
|
||||||
FILINFO *fno /* Pointer to store the file information */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
BYTE i, c;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
|
|
||||||
p = fno->fname;
|
|
||||||
if (dj->sect) {
|
|
||||||
for (i = 0; i < 8; i++) { /* Copy file name body */
|
|
||||||
c = dir[i];
|
|
||||||
if (c == ' ') break;
|
|
||||||
if (c == 0x05) c = 0xE5;
|
|
||||||
*p++ = c;
|
|
||||||
}
|
|
||||||
if (dir[8] != ' ') { /* Copy file name extension */
|
|
||||||
*p++ = '.';
|
|
||||||
for (i = 8; i < 11; i++) {
|
|
||||||
c = dir[i];
|
|
||||||
if (c == ' ') break;
|
|
||||||
*p++ = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fno->fattrib = dir[DIR_Attr]; /* Attribute */
|
|
||||||
fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */
|
|
||||||
fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */
|
|
||||||
fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */
|
|
||||||
}
|
|
||||||
*p = 0;
|
|
||||||
}
|
|
||||||
#endif /* _USE_DIR */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Follow a file path */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static
|
|
||||||
FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */
|
|
||||||
DIR *dj, /* Directory object to return last directory and found object */
|
|
||||||
BYTE *dir, /* 32-byte working buffer */
|
|
||||||
const char *path /* Full-path string to find a file or directory */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FRESULT res;
|
|
||||||
|
|
||||||
|
|
||||||
while (*path == ' ') path++; /* Skip leading spaces */
|
|
||||||
if (*path == '/') path++; /* Strip heading separator */
|
|
||||||
dj->sclust = 0; /* Set start directory (always root dir) */
|
|
||||||
|
|
||||||
if ((BYTE)*path <= ' ') { /* Null path means the root directory */
|
|
||||||
res = dir_rewind(dj);
|
|
||||||
dir[0] = 0;
|
|
||||||
|
|
||||||
} else { /* Follow path */
|
|
||||||
for (;;) {
|
|
||||||
res = create_name(dj, &path); /* Get a segment */
|
|
||||||
if (res != FR_OK) break;
|
|
||||||
res = dir_find(dj, dir); /* Find it */
|
|
||||||
if (res != FR_OK) { /* Could not find the object */
|
|
||||||
if (res == FR_NO_FILE && !*(dj->fn+11))
|
|
||||||
res = FR_NO_PATH;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (*(dj->fn+11)) break; /* Last segment match. Function completed. */
|
|
||||||
if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */
|
|
||||||
res = FR_NO_PATH; break;
|
|
||||||
}
|
|
||||||
dj->sclust = LD_CLUST(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Check a sector if it is an FAT boot record */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static
|
|
||||||
BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */
|
|
||||||
BYTE *buf, /* Working buffer */
|
|
||||||
DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (disk_readp(buf, sect, 510, 2)) /* Read the boot sector */
|
|
||||||
return 3;
|
|
||||||
if (LD_WORD(buf) != 0xAA55) /* Check record signature */
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
if (!disk_readp(buf, sect, BS_FilSysType, 2) && LD_WORD(buf) == 0x4146) /* Check FAT12/16 */
|
|
||||||
return 0;
|
|
||||||
if (_FS_FAT32 && !disk_readp(buf, sect, BS_FilSysType32, 2) && LD_WORD(buf) == 0x4146) /* Check FAT32 */
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Public Functions
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Mount/Unmount a Locical Drive */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
FRESULT pf_mount (
|
|
||||||
FATFS *fs /* Pointer to new file system object (NULL: Unmount) */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
BYTE fmt, buf[36];
|
|
||||||
DWORD bsect, fsize, tsect, mclst;
|
|
||||||
|
|
||||||
|
|
||||||
FatFs = 0;
|
|
||||||
if (!fs) return FR_OK; /* Unregister fs object */
|
|
||||||
|
|
||||||
if (disk_initialize() & STA_NOINIT) /* Check if the drive is ready or not */
|
|
||||||
return FR_NOT_READY;
|
|
||||||
|
|
||||||
/* Search FAT partition on the drive */
|
|
||||||
bsect = 0;
|
|
||||||
fmt = check_fs(buf, bsect); /* Check sector 0 as an SFD format */
|
|
||||||
if (fmt == 1) { /* Not an FAT boot record, it may be FDISK format */
|
|
||||||
/* Check a partition listed in top of the partition table */
|
|
||||||
if (disk_readp(buf, bsect, MBR_Table, 16)) { /* 1st partition entry */
|
|
||||||
fmt = 3;
|
|
||||||
} else {
|
|
||||||
if (buf[4]) { /* Is the partition existing? */
|
|
||||||
bsect = LD_DWORD(&buf[8]); /* Partition offset in LBA */
|
|
||||||
fmt = check_fs(buf, bsect); /* Check the partition */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fmt == 3) return FR_DISK_ERR;
|
|
||||||
if (fmt) return FR_NO_FILESYSTEM; /* No valid FAT patition is found */
|
|
||||||
|
|
||||||
/* Initialize the file system object */
|
|
||||||
if (disk_readp(buf, bsect, 13, sizeof(buf))) return FR_DISK_ERR;
|
|
||||||
|
|
||||||
fsize = LD_WORD(buf+BPB_FATSz16-13); /* Number of sectors per FAT */
|
|
||||||
if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13);
|
|
||||||
|
|
||||||
fsize *= buf[BPB_NumFATs-13]; /* Number of sectors in FAT area */
|
|
||||||
fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */
|
|
||||||
fs->csize = buf[BPB_SecPerClus-13]; /* Number of sectors per cluster */
|
|
||||||
fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13); /* Nmuber of root directory entries */
|
|
||||||
tsect = LD_WORD(buf+BPB_TotSec16-13); /* Number of sectors on the file system */
|
|
||||||
if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13);
|
|
||||||
mclst = (tsect /* Last cluster# + 1 */
|
|
||||||
- LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16
|
|
||||||
) / fs->csize + 2;
|
|
||||||
fs->n_fatent = (CLUST)mclst;
|
|
||||||
|
|
||||||
fmt = FS_FAT16; /* Determine the FAT sub type */
|
|
||||||
if (mclst < 0xFF7) /* Number of clusters < 0xFF5 */
|
|
||||||
#if _FS_FAT12
|
|
||||||
fmt = FS_FAT12;
|
|
||||||
#else
|
|
||||||
return FR_NO_FILESYSTEM;
|
|
||||||
#endif
|
|
||||||
if (mclst >= 0xFFF7) /* Number of clusters >= 0xFFF5 */
|
|
||||||
#if _FS_FAT32
|
|
||||||
fmt = FS_FAT32;
|
|
||||||
#else
|
|
||||||
return FR_NO_FILESYSTEM;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fs->fs_type = fmt; /* FAT sub-type */
|
|
||||||
if (_FS_FAT32 && fmt == FS_FAT32)
|
|
||||||
fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13)); /* Root directory start cluster */
|
|
||||||
else
|
|
||||||
fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */
|
|
||||||
fs->database = fs->fatbase + fsize + fs->n_rootdir / 16; /* Data start sector (lba) */
|
|
||||||
|
|
||||||
fs->flag = 0;
|
|
||||||
FatFs = fs;
|
|
||||||
|
|
||||||
return FR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Open or Create a File */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
FRESULT pf_open (
|
|
||||||
const char *path /* Pointer to the file name */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FRESULT res;
|
|
||||||
DIR dj;
|
|
||||||
BYTE sp[12], dir[32];
|
|
||||||
FATFS *fs = FatFs;
|
|
||||||
|
|
||||||
|
|
||||||
if (!fs) /* Check file system */
|
|
||||||
return FR_NOT_ENABLED;
|
|
||||||
|
|
||||||
fs->flag = 0;
|
|
||||||
dj.fn = sp;
|
|
||||||
res = follow_path(&dj, dir, path); /* Follow the file path */
|
|
||||||
if (res != FR_OK) return res; /* Follow failed */
|
|
||||||
if (!dir[0] || (dir[DIR_Attr] & AM_DIR)) /* It is a directory */
|
|
||||||
return FR_NO_FILE;
|
|
||||||
|
|
||||||
fs->org_clust = LD_CLUST(dir); /* File start cluster */
|
|
||||||
fs->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */
|
|
||||||
fs->fptr = 0; /* File pointer */
|
|
||||||
fs->flag = FA_OPENED;
|
|
||||||
|
|
||||||
return FR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read File */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
#if _USE_READ
|
|
||||||
|
|
||||||
FRESULT pf_read (
|
|
||||||
void* buff, /* Pointer to the read buffer (NULL:Forward data to the stream)*/
|
|
||||||
WORD btr, /* Number of bytes to read */
|
|
||||||
WORD* br /* Pointer to number of bytes read */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DRESULT dr;
|
|
||||||
CLUST clst;
|
|
||||||
DWORD sect, remain;
|
|
||||||
WORD rcnt;
|
|
||||||
BYTE cs, *rbuff = buff;
|
|
||||||
FATFS *fs = FatFs;
|
|
||||||
|
|
||||||
|
|
||||||
*br = 0;
|
|
||||||
if (!fs) return FR_NOT_ENABLED; /* Check file system */
|
|
||||||
if (!(fs->flag & FA_OPENED)) /* Check if opened */
|
|
||||||
return FR_NOT_OPENED;
|
|
||||||
|
|
||||||
remain = fs->fsize - fs->fptr;
|
|
||||||
if (btr > remain) btr = (WORD)remain; /* Truncate btr by remaining bytes */
|
|
||||||
|
|
||||||
while (btr) { /* Repeat until all data transferred */
|
|
||||||
if ((fs->fptr % 512) == 0) { /* On the sector boundary? */
|
|
||||||
cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */
|
|
||||||
if (!cs) { /* On the cluster boundary? */
|
|
||||||
clst = (fs->fptr == 0) ? /* On the top of the file? */
|
|
||||||
fs->org_clust : get_fat(fs->curr_clust);
|
|
||||||
if (clst <= 1) goto fr_abort;
|
|
||||||
fs->curr_clust = clst; /* Update current cluster */
|
|
||||||
}
|
|
||||||
sect = clust2sect(fs->curr_clust); /* Get current sector */
|
|
||||||
if (!sect) goto fr_abort;
|
|
||||||
fs->dsect = sect + cs;
|
|
||||||
}
|
|
||||||
rcnt = (WORD)(512 - (fs->fptr % 512)); /* Get partial sector data from sector buffer */
|
|
||||||
if (rcnt > btr) rcnt = btr;
|
|
||||||
dr = disk_readp(!buff ? 0 : rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt);
|
|
||||||
if (dr) goto fr_abort;
|
|
||||||
fs->fptr += rcnt; rbuff += rcnt; /* Update pointers and counters */
|
|
||||||
btr -= rcnt; *br += rcnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FR_OK;
|
|
||||||
|
|
||||||
fr_abort:
|
|
||||||
fs->flag = 0;
|
|
||||||
return FR_DISK_ERR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write File */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
#if _USE_WRITE
|
|
||||||
|
|
||||||
FRESULT pf_write (
|
|
||||||
const void* buff, /* Pointer to the data to be written */
|
|
||||||
WORD btw, /* Number of bytes to write (0:Finalize the current write operation) */
|
|
||||||
WORD* bw /* Pointer to number of bytes written */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CLUST clst;
|
|
||||||
DWORD sect, remain;
|
|
||||||
const BYTE *p = buff;
|
|
||||||
BYTE cs;
|
|
||||||
WORD wcnt;
|
|
||||||
FATFS *fs = FatFs;
|
|
||||||
|
|
||||||
|
|
||||||
*bw = 0;
|
|
||||||
if (!fs) return FR_NOT_ENABLED; /* Check file system */
|
|
||||||
if (!(fs->flag & FA_OPENED)) /* Check if opened */
|
|
||||||
return FR_NOT_OPENED;
|
|
||||||
|
|
||||||
if (!btw) { /* Finalize request */
|
|
||||||
if ((fs->flag & FA__WIP) && disk_writep(0, 0)) goto fw_abort;
|
|
||||||
fs->flag &= ~FA__WIP;
|
|
||||||
return FR_OK;
|
|
||||||
} else { /* Write data request */
|
|
||||||
if (!(fs->flag & FA__WIP)) /* Round-down fptr to the sector boundary */
|
|
||||||
fs->fptr &= 0xFFFFFE00;
|
|
||||||
}
|
|
||||||
remain = fs->fsize - fs->fptr;
|
|
||||||
if (btw > remain) btw = (WORD)remain; /* Truncate btw by remaining bytes */
|
|
||||||
|
|
||||||
while (btw) { /* Repeat until all data transferred */
|
|
||||||
if (((WORD)fs->fptr % 512) == 0) { /* On the sector boundary? */
|
|
||||||
cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */
|
|
||||||
if (!cs) { /* On the cluster boundary? */
|
|
||||||
clst = (fs->fptr == 0) ? /* On the top of the file? */
|
|
||||||
fs->org_clust : get_fat(fs->curr_clust);
|
|
||||||
if (clst <= 1) goto fw_abort;
|
|
||||||
fs->curr_clust = clst; /* Update current cluster */
|
|
||||||
}
|
|
||||||
sect = clust2sect(fs->curr_clust); /* Get current sector */
|
|
||||||
if (!sect) goto fw_abort;
|
|
||||||
fs->dsect = sect + cs;
|
|
||||||
if (disk_writep(0, fs->dsect)) goto fw_abort; /* Initiate a sector write operation */
|
|
||||||
fs->flag |= FA__WIP;
|
|
||||||
}
|
|
||||||
wcnt = 512 - ((WORD)fs->fptr % 512); /* Number of bytes to write to the sector */
|
|
||||||
if (wcnt > btw) wcnt = btw;
|
|
||||||
if (disk_writep(p, wcnt)) goto fw_abort; /* Send data to the sector */
|
|
||||||
fs->fptr += wcnt; p += wcnt; /* Update pointers and counters */
|
|
||||||
btw -= wcnt; *bw += wcnt;
|
|
||||||
if (((WORD)fs->fptr % 512) == 0) {
|
|
||||||
if (disk_writep(0, 0)) goto fw_abort; /* Finalize the currtent secter write operation */
|
|
||||||
fs->flag &= ~FA__WIP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FR_OK;
|
|
||||||
|
|
||||||
fw_abort:
|
|
||||||
fs->flag = 0;
|
|
||||||
return FR_DISK_ERR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Seek File R/W Pointer */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
#if _USE_LSEEK
|
|
||||||
|
|
||||||
FRESULT pf_lseek (
|
|
||||||
DWORD ofs /* File pointer from top of file */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
CLUST clst;
|
|
||||||
DWORD bcs, sect, ifptr;
|
|
||||||
FATFS *fs = FatFs;
|
|
||||||
|
|
||||||
|
|
||||||
if (!fs) return FR_NOT_ENABLED; /* Check file system */
|
|
||||||
if (!(fs->flag & FA_OPENED)) /* Check if opened */
|
|
||||||
return FR_NOT_OPENED;
|
|
||||||
|
|
||||||
if (ofs > fs->fsize) ofs = fs->fsize; /* Clip offset with the file size */
|
|
||||||
ifptr = fs->fptr;
|
|
||||||
fs->fptr = 0;
|
|
||||||
if (ofs > 0) {
|
|
||||||
bcs = (DWORD)fs->csize * 512; /* Cluster size (byte) */
|
|
||||||
if (ifptr > 0 &&
|
|
||||||
(ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
|
|
||||||
fs->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */
|
|
||||||
ofs -= fs->fptr;
|
|
||||||
clst = fs->curr_clust;
|
|
||||||
} else { /* When seek to back cluster, */
|
|
||||||
clst = fs->org_clust; /* start from the first cluster */
|
|
||||||
fs->curr_clust = clst;
|
|
||||||
}
|
|
||||||
while (ofs > bcs) { /* Cluster following loop */
|
|
||||||
clst = get_fat(clst); /* Follow cluster chain */
|
|
||||||
if (clst <= 1 || clst >= fs->n_fatent) goto fe_abort;
|
|
||||||
fs->curr_clust = clst;
|
|
||||||
fs->fptr += bcs;
|
|
||||||
ofs -= bcs;
|
|
||||||
}
|
|
||||||
fs->fptr += ofs;
|
|
||||||
sect = clust2sect(clst); /* Current sector */
|
|
||||||
if (!sect) goto fe_abort;
|
|
||||||
fs->dsect = sect + (fs->fptr / 512 & (fs->csize - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return FR_OK;
|
|
||||||
|
|
||||||
fe_abort:
|
|
||||||
fs->flag = 0;
|
|
||||||
return FR_DISK_ERR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Create a Directroy Object */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
#if _USE_DIR
|
|
||||||
|
|
||||||
FRESULT pf_opendir (
|
|
||||||
DIR *dj, /* Pointer to directory object to create */
|
|
||||||
const char *path /* Pointer to the directory path */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FRESULT res;
|
|
||||||
BYTE sp[12], dir[32];
|
|
||||||
FATFS *fs = FatFs;
|
|
||||||
|
|
||||||
|
|
||||||
if (!fs) { /* Check file system */
|
|
||||||
res = FR_NOT_ENABLED;
|
|
||||||
} else {
|
|
||||||
dj->fn = sp;
|
|
||||||
res = follow_path(dj, dir, path); /* Follow the path to the directory */
|
|
||||||
if (res == FR_OK) { /* Follow completed */
|
|
||||||
if (dir[0]) { /* It is not the root dir */
|
|
||||||
if (dir[DIR_Attr] & AM_DIR) /* The object is a directory */
|
|
||||||
dj->sclust = LD_CLUST(dir);
|
|
||||||
else /* The object is not a directory */
|
|
||||||
res = FR_NO_PATH;
|
|
||||||
}
|
|
||||||
if (res == FR_OK)
|
|
||||||
res = dir_rewind(dj); /* Rewind dir */
|
|
||||||
}
|
|
||||||
if (res == FR_NO_FILE) res = FR_NO_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read Directory Entry in Sequense */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
FRESULT pf_readdir (
|
|
||||||
DIR *dj, /* Pointer to the open directory object */
|
|
||||||
FILINFO *fno /* Pointer to file information to return */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FRESULT res;
|
|
||||||
BYTE sp[12], dir[32];
|
|
||||||
FATFS *fs = FatFs;
|
|
||||||
|
|
||||||
|
|
||||||
if (!fs) { /* Check file system */
|
|
||||||
res = FR_NOT_ENABLED;
|
|
||||||
} else {
|
|
||||||
dj->fn = sp;
|
|
||||||
if (!fno) {
|
|
||||||
res = dir_rewind(dj);
|
|
||||||
} else {
|
|
||||||
res = dir_read(dj, dir);
|
|
||||||
if (res == FR_NO_FILE) {
|
|
||||||
dj->sect = 0;
|
|
||||||
res = FR_OK;
|
|
||||||
}
|
|
||||||
if (res == FR_OK) { /* A valid entry is found */
|
|
||||||
get_fileinfo(dj, dir, fno); /* Get the object information */
|
|
||||||
res = dir_next(dj); /* Increment index for next */
|
|
||||||
if (res == FR_NO_FILE) {
|
|
||||||
dj->sect = 0;
|
|
||||||
res = FR_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _USE_DIR */
|
|
||||||
|
|
@ -1,193 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Petit FatFs - FAT file system module include file R0.02a (C)ChaN, 2010
|
|
||||||
/----------------------------------------------------------------------------/
|
|
||||||
/ Petit FatFs module is an open source software to implement FAT file system to
|
|
||||||
/ small embedded systems. This is a free software and is opened for education,
|
|
||||||
/ research and commercial developments under license policy of following trems.
|
|
||||||
/
|
|
||||||
/ Copyright (C) 2010, ChaN, all right reserved.
|
|
||||||
/
|
|
||||||
/ * The Petit FatFs module is a free software and there is NO WARRANTY.
|
|
||||||
/ * No restriction on use. You can use, modify and redistribute it for
|
|
||||||
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
|
|
||||||
/ * Redistributions of source code must retain the above copyright notice.
|
|
||||||
/
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "integer.h"
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Petit FatFs Configuration Options
|
|
||||||
/
|
|
||||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
|
||||||
/ the configuration options.
|
|
||||||
/
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
#ifndef _FATFS
|
|
||||||
#define _FATFS
|
|
||||||
|
|
||||||
#define _USE_READ 1 /* 1:Enable pf_read() */
|
|
||||||
|
|
||||||
#define _USE_DIR 0 /* 1:Enable pf_opendir() and pf_readdir() */
|
|
||||||
|
|
||||||
#define _USE_LSEEK 0 /* 1:Enable pf_lseek() */
|
|
||||||
|
|
||||||
#define _USE_WRITE 0 /* 1:Enable pf_write() */
|
|
||||||
|
|
||||||
#define _FS_FAT12 1 /* 1:Enable FAT12 support */
|
|
||||||
#define _FS_FAT32 0 /* 1:Enable FAT32 support */
|
|
||||||
|
|
||||||
|
|
||||||
#define _CODE_PAGE 1
|
|
||||||
/* Defines which code page is used for path name. Supported code pages are:
|
|
||||||
/ 932, 936, 949, 950, 437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866,
|
|
||||||
/ 874, 1250, 1251, 1252, 1253, 1254, 1255, 1257, 1258 and 1 (ASCII only).
|
|
||||||
/ SBCS code pages except for 1 requiers a case conversion table. This
|
|
||||||
/ might occupy 128 bytes on the RAM on some platforms, e.g. avr-gcc. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _WORD_ACCESS 0
|
|
||||||
/* The _WORD_ACCESS option defines which access method is used to the word
|
|
||||||
/ data in the FAT structure.
|
|
||||||
/
|
|
||||||
/ 0: Byte-by-byte access. Always compatible with all platforms.
|
|
||||||
/ 1: Word access. Do not choose this unless following condition is met.
|
|
||||||
/
|
|
||||||
/ When the byte order on the memory is big-endian or address miss-aligned
|
|
||||||
/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
|
||||||
/ If it is not the case, the value can also be set to 1 to improve the
|
|
||||||
/ performance and code efficiency. */
|
|
||||||
|
|
||||||
|
|
||||||
/* End of configuration options. Do not change followings without care. */
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if _FS_FAT32
|
|
||||||
#define CLUST DWORD
|
|
||||||
#else
|
|
||||||
#define CLUST WORD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* File system object structure */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
BYTE fs_type; /* FAT sub type */
|
|
||||||
BYTE flag; /* File status flags */
|
|
||||||
BYTE csize; /* Number of sectors per cluster */
|
|
||||||
BYTE pad1;
|
|
||||||
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
|
|
||||||
CLUST n_fatent; /* Number of FAT entries (= number of clusters + 2) */
|
|
||||||
DWORD fatbase; /* FAT start sector */
|
|
||||||
DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */
|
|
||||||
DWORD database; /* Data start sector */
|
|
||||||
DWORD fptr; /* File R/W pointer */
|
|
||||||
DWORD fsize; /* File size */
|
|
||||||
CLUST org_clust; /* File start cluster */
|
|
||||||
CLUST curr_clust; /* File current cluster */
|
|
||||||
DWORD dsect; /* File current data sector */
|
|
||||||
} FATFS;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Directory object structure */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
WORD index; /* Current read/write index number */
|
|
||||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
|
||||||
CLUST sclust; /* Table start cluster (0:Static table) */
|
|
||||||
CLUST clust; /* Current cluster */
|
|
||||||
DWORD sect; /* Current sector */
|
|
||||||
} DIR;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File status structure */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DWORD fsize; /* File size */
|
|
||||||
WORD fdate; /* Last modified date */
|
|
||||||
WORD ftime; /* Last modified time */
|
|
||||||
BYTE fattrib; /* Attribute */
|
|
||||||
char fname[13]; /* File name */
|
|
||||||
} FILINFO;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File function return code (FRESULT) */
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FR_OK = 0, /* 0 */
|
|
||||||
FR_DISK_ERR, /* 1 */
|
|
||||||
FR_NOT_READY, /* 2 */
|
|
||||||
FR_NO_FILE, /* 3 */
|
|
||||||
FR_NO_PATH, /* 4 */
|
|
||||||
FR_NOT_OPENED, /* 5 */
|
|
||||||
FR_NOT_ENABLED, /* 6 */
|
|
||||||
FR_NO_FILESYSTEM /* 7 */
|
|
||||||
} FRESULT;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------*/
|
|
||||||
/* Petit FatFs module application interface */
|
|
||||||
|
|
||||||
FRESULT pf_mount (FATFS*); /* Mount/Unmount a logical drive */
|
|
||||||
FRESULT pf_open (const char*); /* Open a file */
|
|
||||||
FRESULT pf_read (void*, WORD, WORD*); /* Read data from the open file */
|
|
||||||
FRESULT pf_write (const void*, WORD, WORD*); /* Write data to the open file */
|
|
||||||
FRESULT pf_lseek (DWORD); /* Move file pointer of the open file */
|
|
||||||
FRESULT pf_opendir (DIR*, const char*); /* Open a directory */
|
|
||||||
FRESULT pf_readdir (DIR*, FILINFO*); /* Read a directory item from the open directory */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------*/
|
|
||||||
/* Flags and offset address */
|
|
||||||
|
|
||||||
/* File status flag (FATFS.flag) */
|
|
||||||
|
|
||||||
#define FA_OPENED 0x01
|
|
||||||
#define FA_WPRT 0x02
|
|
||||||
#define FA__WIP 0x40
|
|
||||||
|
|
||||||
|
|
||||||
/* FAT sub type (FATFS.fs_type) */
|
|
||||||
|
|
||||||
#define FS_FAT12 1
|
|
||||||
#define FS_FAT16 2
|
|
||||||
#define FS_FAT32 3
|
|
||||||
|
|
||||||
|
|
||||||
/* File attribute bits for directory entry */
|
|
||||||
|
|
||||||
#define AM_RDO 0x01 /* Read only */
|
|
||||||
#define AM_HID 0x02 /* Hidden */
|
|
||||||
#define AM_SYS 0x04 /* System */
|
|
||||||
#define AM_VOL 0x08 /* Volume label */
|
|
||||||
#define AM_LFN 0x0F /* LFN entry */
|
|
||||||
#define AM_DIR 0x10 /* Directory */
|
|
||||||
#define AM_ARC 0x20 /* Archive */
|
|
||||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------*/
|
|
||||||
/* Multi-byte word access macros */
|
|
||||||
|
|
||||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
|
||||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
|
||||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
|
||||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
|
||||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
|
||||||
#else /* Use byte-by-byte access to the FAT structure */
|
|
||||||
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
|
||||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
|
|
||||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
|
|
||||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _FATFS */
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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 "ProgrammerConfig.h"
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16_t SigBytes[4];
|
|
||||||
bool EnforceSigBytes;
|
|
||||||
|
|
||||||
uint32_t ProgrammingSpeed;
|
|
||||||
} ProgrammerConfig;
|
|
||||||
|
|
||||||
bool ProgrammerConfig_ProcessConfiguration(void)
|
|
||||||
{
|
|
||||||
memset(&ProgrammerConfig, 0x00, sizeof(ProgrammerConfig));
|
|
||||||
|
|
||||||
if (!(pf_open("CONF.txt") == FR_OK))
|
|
||||||
{
|
|
||||||
puts(" >> ERROR: CONF.txt File Not Found.\r\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char LineBuff[100];
|
|
||||||
char* CurrentLine;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
CurrentLine = fgets(LineBuff, sizeof(LineBuff), &DiskStream);
|
|
||||||
|
|
||||||
if (CurrentLine)
|
|
||||||
{
|
|
||||||
sscanf(CurrentLine, "SIGNATURE = %02x %02x %02x %02x", &ProgrammerConfig.SigBytes[0],
|
|
||||||
&ProgrammerConfig.SigBytes[1],
|
|
||||||
&ProgrammerConfig.SigBytes[2],
|
|
||||||
&ProgrammerConfig.SigBytes[3]);
|
|
||||||
|
|
||||||
sscanf(CurrentLine, "SPEED = %08lu", &ProgrammerConfig.ProgrammingSpeed);
|
|
||||||
}
|
|
||||||
} while (CurrentLine);
|
|
||||||
|
|
||||||
printf(" >> *** Configuration: ***\r\n");
|
|
||||||
printf(" >> Device Signature: 0x%02x 0x%02x 0x%02x 0x%02x\r\n", ProgrammerConfig.SigBytes[0],
|
|
||||||
ProgrammerConfig.SigBytes[1],
|
|
||||||
ProgrammerConfig.SigBytes[2],
|
|
||||||
ProgrammerConfig.SigBytes[3]);
|
|
||||||
printf(" >> Programming Speed: %lu Hz\r\n", ProgrammerConfig.ProgrammingSpeed);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _PROGRAMMER_CONFIG_H_
|
|
||||||
#define _PROGRAMMER_CONFIG_H_
|
|
||||||
|
|
||||||
/* Includes: */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "../StandaloneProgrammer.h"
|
|
||||||
|
|
||||||
/* Function Prototypes: */
|
|
||||||
bool ProgrammerConfig_ProcessConfiguration(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,344 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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
|
|
||||||
*
|
|
||||||
* SCSI command processing routines, for SCSI commands issued by the host. Mass Storage
|
|
||||||
* devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information,
|
|
||||||
* which wrap around standard SCSI device commands for controlling the actual storage medium.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define INCLUDE_FROM_SCSI_C
|
|
||||||
#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
|
|
||||||
* features and capabilities.
|
|
||||||
*/
|
|
||||||
static const SCSI_Inquiry_Response_t InquiryData =
|
|
||||||
{
|
|
||||||
.DeviceType = DEVICE_TYPE_BLOCK,
|
|
||||||
.PeripheralQualifier = 0,
|
|
||||||
|
|
||||||
.Removable = true,
|
|
||||||
|
|
||||||
.Version = 0,
|
|
||||||
|
|
||||||
.ResponseDataFormat = 2,
|
|
||||||
.NormACA = false,
|
|
||||||
.TrmTsk = false,
|
|
||||||
.AERC = false,
|
|
||||||
|
|
||||||
.AdditionalLength = 0x1F,
|
|
||||||
|
|
||||||
.SoftReset = false,
|
|
||||||
.CmdQue = false,
|
|
||||||
.Linked = false,
|
|
||||||
.Sync = false,
|
|
||||||
.WideBus16Bit = false,
|
|
||||||
.WideBus32Bit = false,
|
|
||||||
.RelAddr = false,
|
|
||||||
|
|
||||||
.VendorID = "LUFA",
|
|
||||||
.ProductID = "Dataflash Disk",
|
|
||||||
.RevisionID = {'0','.','0','0'},
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE
|
|
||||||
* command is issued. This gives information on exactly why the last command failed to complete.
|
|
||||||
*/
|
|
||||||
static SCSI_Request_Sense_Response_t SenseData =
|
|
||||||
{
|
|
||||||
.ResponseCode = 0x70,
|
|
||||||
.AdditionalLength = 0x0A,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches
|
|
||||||
* to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns
|
|
||||||
* a command failure due to a ILLEGAL REQUEST.
|
|
||||||
*
|
|
||||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
|
||||||
*
|
|
||||||
* \return Boolean true if the command completed successfully, false otherwise
|
|
||||||
*/
|
|
||||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
|
||||||
{
|
|
||||||
bool CommandSuccess = false;
|
|
||||||
|
|
||||||
/* Run the appropriate SCSI command hander function based on the passed command */
|
|
||||||
switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0])
|
|
||||||
{
|
|
||||||
case SCSI_CMD_INQUIRY:
|
|
||||||
CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo);
|
|
||||||
break;
|
|
||||||
case SCSI_CMD_REQUEST_SENSE:
|
|
||||||
CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo);
|
|
||||||
break;
|
|
||||||
case SCSI_CMD_READ_CAPACITY_10:
|
|
||||||
CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
|
|
||||||
break;
|
|
||||||
case SCSI_CMD_SEND_DIAGNOSTIC:
|
|
||||||
CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
|
|
||||||
break;
|
|
||||||
case SCSI_CMD_WRITE_10:
|
|
||||||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
|
|
||||||
break;
|
|
||||||
case SCSI_CMD_READ_10:
|
|
||||||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
|
|
||||||
break;
|
|
||||||
case SCSI_CMD_MODE_SENSE_6:
|
|
||||||
CommandSuccess = SCSI_Command_ModeSense_6(MSInterfaceInfo);
|
|
||||||
break;
|
|
||||||
case SCSI_CMD_TEST_UNIT_READY:
|
|
||||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
|
||||||
case SCSI_CMD_VERIFY_10:
|
|
||||||
/* These commands should just succeed, no handling required */
|
|
||||||
CommandSuccess = true;
|
|
||||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Update the SENSE key to reflect the invalid command */
|
|
||||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
|
||||||
SCSI_ASENSE_INVALID_COMMAND,
|
|
||||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if command was successfully processed */
|
|
||||||
if (CommandSuccess)
|
|
||||||
{
|
|
||||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
|
|
||||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
|
||||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
|
|
||||||
* and capabilities to the host.
|
|
||||||
*
|
|
||||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
|
||||||
*
|
|
||||||
* \return Boolean true if the command completed successfully, false otherwise.
|
|
||||||
*/
|
|
||||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
|
||||||
{
|
|
||||||
uint16_t AllocationLength = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[3]);
|
|
||||||
uint16_t BytesTransferred = MIN(AllocationLength, sizeof(InquiryData));
|
|
||||||
|
|
||||||
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
|
|
||||||
if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
|
|
||||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[2])
|
|
||||||
{
|
|
||||||
/* Optional but unsupported bits set - update the SENSE key and fail the request */
|
|
||||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
|
||||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
|
||||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NULL);
|
|
||||||
|
|
||||||
/* Pad out remaining bytes with 0x00 */
|
|
||||||
Endpoint_Null_Stream((AllocationLength - BytesTransferred), NULL);
|
|
||||||
|
|
||||||
/* Finalize the stream transfer to send the last packet */
|
|
||||||
Endpoint_ClearIN();
|
|
||||||
|
|
||||||
/* Succeed the command and update the bytes transferred counter */
|
|
||||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command,
|
|
||||||
* including the error code and additional error information so that the host can determine why a command failed to complete.
|
|
||||||
*
|
|
||||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
|
||||||
*
|
|
||||||
* \return Boolean true if the command completed successfully, false otherwise.
|
|
||||||
*/
|
|
||||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
|
||||||
{
|
|
||||||
uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
|
|
||||||
uint8_t BytesTransferred = MIN(AllocationLength, sizeof(SenseData));
|
|
||||||
|
|
||||||
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NULL);
|
|
||||||
Endpoint_Null_Stream((AllocationLength - BytesTransferred), NULL);
|
|
||||||
Endpoint_ClearIN();
|
|
||||||
|
|
||||||
/* Succeed the command and update the bytes transferred counter */
|
|
||||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity
|
|
||||||
* on the selected Logical Unit (drive), as a number of OS-sized blocks.
|
|
||||||
*
|
|
||||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
|
||||||
*
|
|
||||||
* \return Boolean true if the command completed successfully, false otherwise.
|
|
||||||
*/
|
|
||||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
|
||||||
{
|
|
||||||
uint32_t LastBlockAddressInLUN = (VIRTUAL_MEMORY_BLOCKS - 1);
|
|
||||||
uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
|
|
||||||
|
|
||||||
Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NULL);
|
|
||||||
Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NULL);
|
|
||||||
Endpoint_ClearIN();
|
|
||||||
|
|
||||||
/* Succeed the command and update the bytes transferred counter */
|
|
||||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the
|
|
||||||
* board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is
|
|
||||||
* supported.
|
|
||||||
*
|
|
||||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
|
||||||
*
|
|
||||||
* \return Boolean true if the command completed successfully, false otherwise.
|
|
||||||
*/
|
|
||||||
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
|
||||||
{
|
|
||||||
/* Check to see if the SELF TEST bit is not set */
|
|
||||||
if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2)))
|
|
||||||
{
|
|
||||||
/* Only self-test supported - update SENSE key and fail the command */
|
|
||||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
|
||||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
|
||||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check to see if all attached Dataflash ICs are functional */
|
|
||||||
if (!(DataflashManager_CheckDataflashOperation()))
|
|
||||||
{
|
|
||||||
/* Update SENSE key with a hardware error condition and return command fail */
|
|
||||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,
|
|
||||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
|
||||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Succeed the command and update the bytes transferred counter */
|
|
||||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address
|
|
||||||
* and total number of blocks to process, then calls the appropriate low-level Dataflash routine to handle the actual
|
|
||||||
* reading and writing of the data.
|
|
||||||
*
|
|
||||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
|
||||||
* \param[in] IsDataRead Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE)
|
|
||||||
*
|
|
||||||
* \return Boolean true if the command completed successfully, false otherwise.
|
|
||||||
*/
|
|
||||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
|
||||||
const bool IsDataRead)
|
|
||||||
{
|
|
||||||
uint32_t BlockAddress;
|
|
||||||
uint16_t TotalBlocks;
|
|
||||||
|
|
||||||
/* Check if the disk is write protected or not */
|
|
||||||
if ((IsDataRead == DATA_WRITE) && DISK_READ_ONLY)
|
|
||||||
{
|
|
||||||
/* Block address is invalid, update SENSE key and return command fail */
|
|
||||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_DATA_PROTECT,
|
|
||||||
SCSI_ASENSE_WRITE_PROTECTED,
|
|
||||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
|
|
||||||
BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]);
|
|
||||||
|
|
||||||
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
|
|
||||||
TotalBlocks = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]);
|
|
||||||
|
|
||||||
/* Check if the block address is outside the maximum allowable value for the LUN */
|
|
||||||
if (BlockAddress >= VIRTUAL_MEMORY_BLOCKS)
|
|
||||||
{
|
|
||||||
/* Block address is invalid, update SENSE key and return command fail */
|
|
||||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
|
||||||
SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
|
|
||||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
|
|
||||||
if (IsDataRead == DATA_READ)
|
|
||||||
DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
|
||||||
else
|
|
||||||
DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
|
|
||||||
|
|
||||||
/* Update the bytes transferred counter and succeed the command */
|
|
||||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
|
|
||||||
* the SCSI device, as well as the device's Write Protect status.
|
|
||||||
*
|
|
||||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
|
||||||
*
|
|
||||||
* \return Boolean true if the command completed successfully, false otherwise.
|
|
||||||
*/
|
|
||||||
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
|
||||||
{
|
|
||||||
/* Send an empty header response with the Write Protect flag status */
|
|
||||||
Endpoint_Write_8(0x00);
|
|
||||||
Endpoint_Write_8(0x00);
|
|
||||||
Endpoint_Write_8(DISK_READ_ONLY ? 0x80 : 0x00);
|
|
||||||
Endpoint_Write_8(0x00);
|
|
||||||
Endpoint_ClearIN();
|
|
||||||
|
|
||||||
/* Update the bytes transferred counter and succeed the command */
|
|
||||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 4;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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 SCSI.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SCSI_H_
|
|
||||||
#define _SCSI_H_
|
|
||||||
|
|
||||||
/* Includes: */
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
|
|
||||||
#include <LUFA/Drivers/USB/USB.h>
|
|
||||||
|
|
||||||
#include "../StandaloneProgrammer.h"
|
|
||||||
#include "../Descriptors.h"
|
|
||||||
#include "DataflashManager.h"
|
|
||||||
|
|
||||||
/* Macros: */
|
|
||||||
/** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This
|
|
||||||
* is for convenience, as it allows for all three sense values (returned upon request to the host to give information about
|
|
||||||
* the last command failure) in a quick and easy manner.
|
|
||||||
*
|
|
||||||
* \param[in] Key New SCSI sense key to set the sense code to
|
|
||||||
* \param[in] Acode New SCSI additional sense key to set the additional sense code to
|
|
||||||
* \param[in] Aqual New SCSI additional sense key qualifier to set the additional sense qualifier code to
|
|
||||||
*/
|
|
||||||
#define SCSI_SET_SENSE(Key, Acode, Aqual) MACROS{ SenseData.SenseKey = (Key); \
|
|
||||||
SenseData.AdditionalSenseCode = (Acode); \
|
|
||||||
SenseData.AdditionalSenseQualifier = (Aqual); }MACROE
|
|
||||||
|
|
||||||
/** Macro for the \ref SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
|
|
||||||
#define DATA_READ true
|
|
||||||
|
|
||||||
/** Macro for the \ref SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
|
|
||||||
#define DATA_WRITE false
|
|
||||||
|
|
||||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
|
|
||||||
#define DEVICE_TYPE_BLOCK 0x00
|
|
||||||
|
|
||||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
|
|
||||||
#define DEVICE_TYPE_CDROM 0x05
|
|
||||||
|
|
||||||
/* Function Prototypes: */
|
|
||||||
#if defined(USB_CAN_BE_DEVICE)
|
|
||||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
|
||||||
|
|
||||||
#if defined(INCLUDE_FROM_SCSI_C)
|
|
||||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
|
||||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
|
||||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
|
||||||
static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
|
||||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
|
||||||
const bool IsDataRead);
|
|
||||||
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
|||||||
;************************************************************
|
|
||||||
; Windows USB CDC ACM Setup File
|
|
||||||
; Copyright (c) 2000 Microsoft Corporation
|
|
||||||
|
|
||||||
|
|
||||||
[Version]
|
|
||||||
Signature="$Windows NT$"
|
|
||||||
Class=Ports
|
|
||||||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
|
|
||||||
Provider=%MFGNAME%
|
|
||||||
LayoutFile=layout.inf
|
|
||||||
CatalogFile=%MFGFILENAME%.cat
|
|
||||||
DriverVer=11/15/2007,5.1.2600.0
|
|
||||||
|
|
||||||
[Manufacturer]
|
|
||||||
%MFGNAME%=DeviceList, NTamd64
|
|
||||||
|
|
||||||
[DestinationDirs]
|
|
||||||
DefaultDestDir=12
|
|
||||||
|
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
; Windows 2000/XP/Vista-32bit Sections
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[DriverInstall.nt]
|
|
||||||
include=mdmcpq.inf
|
|
||||||
CopyFiles=DriverCopyFiles.nt
|
|
||||||
AddReg=DriverInstall.nt.AddReg
|
|
||||||
|
|
||||||
[DriverCopyFiles.nt]
|
|
||||||
usbser.sys,,,0x20
|
|
||||||
|
|
||||||
[DriverInstall.nt.AddReg]
|
|
||||||
HKR,,DevLoader,,*ntkern
|
|
||||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
|
||||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
|
||||||
|
|
||||||
[DriverInstall.nt.Services]
|
|
||||||
AddService=usbser, 0x00000002, DriverService.nt
|
|
||||||
|
|
||||||
[DriverService.nt]
|
|
||||||
DisplayName=%SERVICE%
|
|
||||||
ServiceType=1
|
|
||||||
StartType=3
|
|
||||||
ErrorControl=1
|
|
||||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
; Vista-64bit Sections
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[DriverInstall.NTamd64]
|
|
||||||
include=mdmcpq.inf
|
|
||||||
CopyFiles=DriverCopyFiles.NTamd64
|
|
||||||
AddReg=DriverInstall.NTamd64.AddReg
|
|
||||||
|
|
||||||
[DriverCopyFiles.NTamd64]
|
|
||||||
%DRIVERFILENAME%.sys,,,0x20
|
|
||||||
|
|
||||||
[DriverInstall.NTamd64.AddReg]
|
|
||||||
HKR,,DevLoader,,*ntkern
|
|
||||||
HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
|
|
||||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
|
||||||
|
|
||||||
[DriverInstall.NTamd64.Services]
|
|
||||||
AddService=usbser, 0x00000002, DriverService.NTamd64
|
|
||||||
|
|
||||||
[DriverService.NTamd64]
|
|
||||||
DisplayName=%SERVICE%
|
|
||||||
ServiceType=1
|
|
||||||
StartType=3
|
|
||||||
ErrorControl=1
|
|
||||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
|
||||||
|
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
; Vendor and Product ID Definitions
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
; When developing your USB device, the VID and PID used in the PC side
|
|
||||||
; application program and the firmware on the microcontroller must match.
|
|
||||||
; Modify the below line to use your VID and PID. Use the format as shown below.
|
|
||||||
; Note: One INF file can be used for multiple devices with different VID and PIDs.
|
|
||||||
; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
[SourceDisksFiles]
|
|
||||||
[SourceDisksNames]
|
|
||||||
[DeviceList]
|
|
||||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2063&MI_00
|
|
||||||
|
|
||||||
[DeviceList.NTamd64]
|
|
||||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_2063&MI_00
|
|
||||||
|
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
; String Definitions
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
;Modify these strings to customize your device
|
|
||||||
;------------------------------------------------------------------------------
|
|
||||||
[Strings]
|
|
||||||
MFGFILENAME="CDC_vista"
|
|
||||||
DRIVERFILENAME ="usbser"
|
|
||||||
MFGNAME="CCS, Inc."
|
|
||||||
INSTDISK="LUFA Benito Programmer Driver Installer"
|
|
||||||
DESCRIPTION="Communications Port"
|
|
||||||
SERVICE="USB RS-232 Emulation Driver"
|
|
@ -1,169 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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
|
|
||||||
*
|
|
||||||
* Main source file for the Standalone Programmer project. This file contains the main tasks of
|
|
||||||
* the project and is responsible for the initial application hardware configuration.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define INCLUDE_FROM_STANDALONEPROG_C
|
|
||||||
#include "StandaloneProgrammer.h"
|
|
||||||
|
|
||||||
/** Standard file stream for the currently open file on the disk. */
|
|
||||||
FILE DiskStream = FDEV_SETUP_STREAM(NULL, Disk_getchar, _FDEV_SETUP_READ);
|
|
||||||
|
|
||||||
/** Petite FAT Fs structure to hold the internal state of the FAT driver for the Dataflash contents. */
|
|
||||||
FATFS DiskFATState;
|
|
||||||
|
|
||||||
/** 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.
|
|
||||||
*/
|
|
||||||
static int Disk_getchar(FILE* Stream)
|
|
||||||
{
|
|
||||||
char ReadByte;
|
|
||||||
WORD ByteWasRead;
|
|
||||||
|
|
||||||
if (pf_read(&ReadByte, 1, &ByteWasRead) != FR_OK)
|
|
||||||
return _FDEV_ERR;
|
|
||||||
|
|
||||||
return (ByteWasRead ? ReadByte : _FDEV_EOF);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(USB_CAN_BE_BOTH)
|
|
||||||
/** Event to handle mode changes in the library, to clear the FAT library's drive state structure when transitioning
|
|
||||||
* between modes. This ensures that the library always works with current disk data.
|
|
||||||
*/
|
|
||||||
void EVENT_USB_UIDChange(void)
|
|
||||||
{
|
|
||||||
pf_mount(&DiskFATState);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Task to determine if the user is wishes to start the programming sequence, and if so executes the
|
|
||||||
* required functions to program the attached target (if any) with the files loaded to the Dataflash.
|
|
||||||
*/
|
|
||||||
void Programmer_Task(void)
|
|
||||||
{
|
|
||||||
static bool HasAttempted = false;
|
|
||||||
|
|
||||||
if (Buttons_GetStatus() & BUTTONS_BUTTON1)
|
|
||||||
{
|
|
||||||
if (!(HasAttempted))
|
|
||||||
HasAttempted = true;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
puts("Reading Configuration File...\r\n");
|
|
||||||
if (!(ProgrammerConfig_ProcessConfiguration()))
|
|
||||||
goto EndOfProgCycle;
|
|
||||||
|
|
||||||
EndOfProgCycle:
|
|
||||||
puts("==== PROGRAMMING CYCLE FINISHED ====\r\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HasAttempted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Main program entry point. This routine contains the overall program flow, including initial
|
|
||||||
* setup of all components and the main program loop.
|
|
||||||
*/
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
SetupHardware();
|
|
||||||
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
|
||||||
sei();
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
Programmer_Task();
|
|
||||||
|
|
||||||
#if defined(USB_CAN_BE_HOST)
|
|
||||||
if (USB_CurrentMode == USB_MODE_Host)
|
|
||||||
DiskHost_USBTask();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(USB_CAN_BE_DEVICE)
|
|
||||||
if (USB_CurrentMode == USB_MODE_Device)
|
|
||||||
DiskDevice_USBTask();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
USB_USBTask();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
|
||||||
void SetupHardware(void)
|
|
||||||
{
|
|
||||||
/* Disable watchdog if enabled by bootloader/fuses */
|
|
||||||
MCUSR &= ~(1 << WDRF);
|
|
||||||
wdt_disable();
|
|
||||||
|
|
||||||
/* Disable clock division */
|
|
||||||
clock_prescale_set(clock_div_1);
|
|
||||||
|
|
||||||
/* Hardware Initialization */
|
|
||||||
#if defined(USB_CAN_BE_BOTH)
|
|
||||||
USB_Init(USB_MODE_UID);
|
|
||||||
#else
|
|
||||||
USB_Init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LEDs_Init();
|
|
||||||
SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_SCK_LEAD_FALLING | SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
|
|
||||||
Dataflash_Init();
|
|
||||||
Buttons_Init();
|
|
||||||
Serial_Init(9600, true);
|
|
||||||
|
|
||||||
/* Create a stdio stream for the serial port for stdin and stdout */
|
|
||||||
Serial_CreateStream(NULL);
|
|
||||||
|
|
||||||
#if defined(USB_CAN_BE_DEVICE)
|
|
||||||
/* Check if the Dataflash is working, abort if not */
|
|
||||||
if (!(DataflashManager_CheckDataflashOperation()))
|
|
||||||
{
|
|
||||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
|
||||||
for(;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear Dataflash sector protections, if enabled */
|
|
||||||
DataflashManager_ResetDataflashProtections();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
LUFA Library
|
|
||||||
Copyright (C) Dean Camera, 2012.
|
|
||||||
|
|
||||||
dean [at] fourwalledcubicle [dot] com
|
|
||||||
www.lufa-lib.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2012 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
|
|
||||||
without fee, 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 StandaloneProgrammer.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _STANDALONE_PROG_H_
|
|
||||||
#define _STANDALONE_PROG_H_
|
|
||||||
|
|
||||||
/* Includes: */
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/wdt.h>
|
|
||||||
#include <avr/power.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "DiskDevice.h"
|
|
||||||
#include "DiskHost.h"
|
|
||||||
|
|
||||||
#include "Lib/SCSI.h"
|
|
||||||
#include "Lib/DataflashManager.h"
|
|
||||||
#include "Lib/ProgrammerConfig.h"
|
|
||||||
#include "Lib/PetiteFATFs/pff.h"
|
|
||||||
|
|
||||||
#include <LUFA/Version.h>
|
|
||||||
#include <LUFA/Drivers/Board/Buttons.h>
|
|
||||||
#include <LUFA/Drivers/Peripheral/Serial.h>
|
|
||||||
|
|
||||||
/* Macros: */
|
|
||||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
|
||||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
|
||||||
|
|
||||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
|
||||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
|
||||||
|
|
||||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
|
||||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
|
||||||
|
|
||||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
|
||||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
|
||||||
|
|
||||||
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
|
|
||||||
#define LEDMASK_USB_BUSY LEDS_LED2
|
|
||||||
|
|
||||||
/* External Variables: */
|
|
||||||
extern FILE DiskStream;
|
|
||||||
extern FATFS DiskFATState;
|
|
||||||
|
|
||||||
/* Function Prototypes: */
|
|
||||||
#if defined(INCLUDE_FROM_STANDALONEPROG_C)
|
|
||||||
static int Disk_getchar(FILE* Stream);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void EVENT_USB_UIDChange(void);
|
|
||||||
|
|
||||||
void SetupHardware(void);
|
|
||||||
void Programmer_Task(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,738 +0,0 @@
|
|||||||
# Hey Emacs, this is a -*- makefile -*-
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
|
|
||||||
# >> Modified for use with the LUFA project. <<
|
|
||||||
#
|
|
||||||
# Released to the Public Domain
|
|
||||||
#
|
|
||||||
# Additional material for this makefile was written by:
|
|
||||||
# Peter Fleury
|
|
||||||
# Tim Henigan
|
|
||||||
# Colin O'Flynn
|
|
||||||
# Reiner Patommel
|
|
||||||
# Markus Pfaff
|
|
||||||
# Sander Pool
|
|
||||||
# Frederik Rouleau
|
|
||||||
# Carlos Lamas
|
|
||||||
# Dean Camera
|
|
||||||
# Opendous Inc.
|
|
||||||
# Denver Gingerich
|
|
||||||
#
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
# On command line:
|
|
||||||
#
|
|
||||||
# make all = Make software.
|
|
||||||
#
|
|
||||||
# make clean = Clean out built project files.
|
|
||||||
#
|
|
||||||
# make coff = Convert ELF to AVR COFF.
|
|
||||||
#
|
|
||||||
# make extcoff = Convert ELF to AVR Extended COFF.
|
|
||||||
#
|
|
||||||
# make program = Download the hex file to the device, using avrdude.
|
|
||||||
# Please customize the avrdude settings below first!
|
|
||||||
#
|
|
||||||
# make dfu = Download the hex file to the device, using dfu-programmer (must
|
|
||||||
# have dfu-programmer installed).
|
|
||||||
#
|
|
||||||
# make flip = Download the hex file to the device, using Atmel FLIP (must
|
|
||||||
# have Atmel FLIP installed).
|
|
||||||
#
|
|
||||||
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
|
|
||||||
# (must have dfu-programmer installed).
|
|
||||||
#
|
|
||||||
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
|
|
||||||
# (must have Atmel FLIP installed).
|
|
||||||
#
|
|
||||||
# make doxygen = Generate DoxyGen documentation for the project (must have
|
|
||||||
# DoxyGen installed)
|
|
||||||
#
|
|
||||||
# make debug = Start either simulavr or avarice as specified for debugging,
|
|
||||||
# with avr-gdb or avr-insight as the front end for debugging.
|
|
||||||
#
|
|
||||||
# make filename.s = Just compile filename.c into the assembler code only.
|
|
||||||
#
|
|
||||||
# make filename.i = Create a preprocessed source file for use in submitting
|
|
||||||
# bug reports to the GCC project.
|
|
||||||
#
|
|
||||||
# To rebuild project do "make clean" then "make all".
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
# MCU name
|
|
||||||
MCU = at90usb1287
|
|
||||||
|
|
||||||
|
|
||||||
# Target architecture (see library "Board Types" documentation).
|
|
||||||
ARCH = AVR8
|
|
||||||
|
|
||||||
|
|
||||||
# Target board (see library "Board Types" documentation, NONE for projects not requiring
|
|
||||||
# LUFA board drivers). If USER is selected, put custom board drivers in a directory called
|
|
||||||
# "Board" inside the application directory.
|
|
||||||
BOARD = USBKEY
|
|
||||||
|
|
||||||
|
|
||||||
# Processor frequency.
|
|
||||||
# This will define a symbol, F_CPU, in all source code files equal to the
|
|
||||||
# processor frequency in Hz. You can then use this symbol in your source code to
|
|
||||||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
|
||||||
# automatically to create a 32-bit value in your source code.
|
|
||||||
#
|
|
||||||
# This will be an integer division of F_USB below, as it is sourced by
|
|
||||||
# F_USB after it has run through any CPU prescalers. Note that this value
|
|
||||||
# does not *change* the processor frequency - it should merely be updated to
|
|
||||||
# reflect the processor speed set externally so that the code can use accurate
|
|
||||||
# software delays.
|
|
||||||
F_CPU = 8000000
|
|
||||||
|
|
||||||
|
|
||||||
# Input clock frequency.
|
|
||||||
# This will define a symbol, F_USB, in all source code files equal to the
|
|
||||||
# input clock frequency (before any prescaling is performed) in Hz. This value may
|
|
||||||
# differ from F_CPU if prescaling is used on the latter, and is required as the
|
|
||||||
# raw input clock is fed directly to the PLL sections of the AVR for high speed
|
|
||||||
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
|
|
||||||
# at the end, this will be done automatically to create a 32-bit value in your
|
|
||||||
# source code.
|
|
||||||
#
|
|
||||||
# If no clock division is performed on the input clock inside the AVR (via the
|
|
||||||
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
|
|
||||||
F_USB = $(F_CPU)
|
|
||||||
|
|
||||||
|
|
||||||
# Output format. (can be srec, ihex, binary)
|
|
||||||
FORMAT = ihex
|
|
||||||
|
|
||||||
|
|
||||||
# Target file name (without extension).
|
|
||||||
TARGET = StandaloneProgrammer
|
|
||||||
|
|
||||||
|
|
||||||
# Object files directory
|
|
||||||
# To put object files in current directory, use a dot (.), do NOT make
|
|
||||||
# this an empty or blank macro!
|
|
||||||
OBJDIR = .
|
|
||||||
|
|
||||||
|
|
||||||
# Path to the LUFA library
|
|
||||||
LUFA_PATH = ../../..
|
|
||||||
|
|
||||||
|
|
||||||
# LUFA library compile-time options and predefined tokens
|
|
||||||
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
|
|
||||||
LUFA_OPTS += -D HOST_STATE_AS_GPIOR=1
|
|
||||||
LUFA_OPTS += -D ORDERED_EP_CONFIG
|
|
||||||
LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
|
|
||||||
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
|
|
||||||
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS
|
|
||||||
LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
|
|
||||||
LUFA_OPTS += -D INTERRUPT_CONTROL_ENDPOINT
|
|
||||||
|
|
||||||
|
|
||||||
# Create the LUFA source path variables by including the LUFA root makefile
|
|
||||||
include $(LUFA_PATH)/LUFA/makefile
|
|
||||||
|
|
||||||
|
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
|
||||||
SRC = $(TARGET).c \
|
|
||||||
Descriptors.c \
|
|
||||||
DiskHost.c \
|
|
||||||
DiskDevice.c \
|
|
||||||
Lib/SCSI.c \
|
|
||||||
Lib/DataflashManager.c \
|
|
||||||
Lib/ProgrammerConfig.c \
|
|
||||||
Lib/PetiteFATFs/diskio.c \
|
|
||||||
Lib/PetiteFATFs/pff.c \
|
|
||||||
$(LUFA_SRC_USB) \
|
|
||||||
$(LUFA_SRC_USBCLASS) \
|
|
||||||
$(LUFA_SRC_SERIAL)
|
|
||||||
|
|
||||||
|
|
||||||
# List C++ source files here. (C dependencies are automatically generated.)
|
|
||||||
CPPSRC =
|
|
||||||
|
|
||||||
|
|
||||||
# List Assembler source files here.
|
|
||||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
|
||||||
# will not be considered source files but generated files (assembler
|
|
||||||
# output from the compiler), and will be deleted upon "make clean"!
|
|
||||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
|
||||||
# it will preserve the spelling of the filenames, and gcc itself does
|
|
||||||
# care about how the name is spelled on its command-line.
|
|
||||||
ASRC =
|
|
||||||
|
|
||||||
|
|
||||||
# Optimization level, can be [0, 1, 2, 3, s].
|
|
||||||
# 0 = turn off optimization. s = optimize for size.
|
|
||||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
|
||||||
OPT = s
|
|
||||||
|
|
||||||
|
|
||||||
# Debugging format.
|
|
||||||
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
|
|
||||||
# AVR Studio 4.10 requires dwarf-2.
|
|
||||||
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
|
|
||||||
DEBUG = dwarf-2
|
|
||||||
|
|
||||||
|
|
||||||
# List any extra directories to look for include files here.
|
|
||||||
# Each directory must be seperated by a space.
|
|
||||||
# Use forward slashes for directory separators.
|
|
||||||
# For a directory that has spaces, enclose it in quotes.
|
|
||||||
EXTRAINCDIRS = $(LUFA_PATH)/
|
|
||||||
|
|
||||||
|
|
||||||
# Compiler flag to set the C Standard level.
|
|
||||||
# c89 = "ANSI" C
|
|
||||||
# gnu89 = c89 plus GCC extensions
|
|
||||||
# c99 = ISO C99 standard (not yet fully implemented)
|
|
||||||
# gnu99 = c99 plus GCC extensions
|
|
||||||
CSTANDARD = -std=c99
|
|
||||||
|
|
||||||
|
|
||||||
# Place -D or -U options here for C sources
|
|
||||||
CDEFS = -DF_CPU=$(F_CPU)UL
|
|
||||||
CDEFS += -DF_USB=$(F_USB)UL
|
|
||||||
CDEFS += -DBOARD=BOARD_$(BOARD) -DARCH=ARCH_$(ARCH)
|
|
||||||
CDEFS += $(LUFA_OPTS)
|
|
||||||
|
|
||||||
|
|
||||||
# Place -D or -U options here for ASM sources
|
|
||||||
ADEFS = -DF_CPU=$(F_CPU)
|
|
||||||
ADEFS += -DF_USB=$(F_USB)UL
|
|
||||||
ADEFS += -DBOARD=BOARD_$(BOARD)
|
|
||||||
ADEFS += $(LUFA_OPTS)
|
|
||||||
|
|
||||||
# Place -D or -U options here for C++ sources
|
|
||||||
CPPDEFS = -DF_CPU=$(F_CPU)UL
|
|
||||||
CPPDEFS += -DF_USB=$(F_USB)UL
|
|
||||||
CPPDEFS += -DBOARD=BOARD_$(BOARD)
|
|
||||||
CPPDEFS += $(LUFA_OPTS)
|
|
||||||
#CPPDEFS += -D__STDC_LIMIT_MACROS
|
|
||||||
#CPPDEFS += -D__STDC_CONSTANT_MACROS
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Compiler Options C ----------------
|
|
||||||
# -g*: generate debugging information
|
|
||||||
# -O*: optimization level
|
|
||||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
|
||||||
# -Wall...: warning level
|
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
# -adhlns...: create assembler listing
|
|
||||||
CFLAGS = -g$(DEBUG)
|
|
||||||
CFLAGS += $(CDEFS)
|
|
||||||
CFLAGS += -O$(OPT)
|
|
||||||
CFLAGS += -funsigned-char
|
|
||||||
CFLAGS += -funsigned-bitfields
|
|
||||||
CFLAGS += -ffunction-sections
|
|
||||||
CFLAGS += -fno-inline-small-functions
|
|
||||||
CFLAGS += -fpack-struct
|
|
||||||
CFLAGS += -fshort-enums
|
|
||||||
CFLAGS += -fno-strict-aliasing
|
|
||||||
CFLAGS += -Wall
|
|
||||||
CFLAGS += -Wstrict-prototypes
|
|
||||||
#CFLAGS += -mshort-calls
|
|
||||||
#CFLAGS += -fno-unit-at-a-time
|
|
||||||
#CFLAGS += -Wundef
|
|
||||||
#CFLAGS += -Wunreachable-code
|
|
||||||
#CFLAGS += -Wsign-compare
|
|
||||||
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
|
|
||||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
|
||||||
CFLAGS += $(CSTANDARD)
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Compiler Options C++ ----------------
|
|
||||||
# -g*: generate debugging information
|
|
||||||
# -O*: optimization level
|
|
||||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
|
||||||
# -Wall...: warning level
|
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
# -adhlns...: create assembler listing
|
|
||||||
CPPFLAGS = -g$(DEBUG)
|
|
||||||
CPPFLAGS += $(CPPDEFS)
|
|
||||||
CPPFLAGS += -O$(OPT)
|
|
||||||
CPPFLAGS += -funsigned-char
|
|
||||||
CPPFLAGS += -funsigned-bitfields
|
|
||||||
CPPFLAGS += -fpack-struct
|
|
||||||
CPPFLAGS += -fshort-enums
|
|
||||||
CPPFLAGS += -fno-exceptions
|
|
||||||
CPPFLAGS += -Wall
|
|
||||||
CPPFLAGS += -Wundef
|
|
||||||
#CPPFLAGS += -mshort-calls
|
|
||||||
#CPPFLAGS += -fno-unit-at-a-time
|
|
||||||
#CPPFLAGS += -Wstrict-prototypes
|
|
||||||
#CPPFLAGS += -Wunreachable-code
|
|
||||||
#CPPFLAGS += -Wsign-compare
|
|
||||||
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
|
|
||||||
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
|
||||||
#CPPFLAGS += $(CSTANDARD)
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Assembler Options ----------------
|
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
# -adhlns: create listing
|
|
||||||
# -gstabs: have the assembler create line number information; note that
|
|
||||||
# for use in COFF files, additional information about filenames
|
|
||||||
# and function names needs to be present in the assembler source
|
|
||||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
|
||||||
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
|
|
||||||
# dump that will be displayed for a given single line of source input.
|
|
||||||
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Library Options ----------------
|
|
||||||
# Minimalistic printf version
|
|
||||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
|
||||||
|
|
||||||
# Floating point printf version (requires MATH_LIB = -lm below)
|
|
||||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
|
||||||
|
|
||||||
# If this is left blank, then it will use the Standard printf version.
|
|
||||||
PRINTF_LIB =
|
|
||||||
#PRINTF_LIB = $(PRINTF_LIB_MIN)
|
|
||||||
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
|
|
||||||
|
|
||||||
|
|
||||||
# Minimalistic scanf version
|
|
||||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
|
|
||||||
|
|
||||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
|
|
||||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
|
|
||||||
|
|
||||||
# If this is left blank, then it will use the Standard scanf version.
|
|
||||||
SCANF_LIB =
|
|
||||||
#SCANF_LIB = $(SCANF_LIB_MIN)
|
|
||||||
#SCANF_LIB = $(SCANF_LIB_FLOAT)
|
|
||||||
|
|
||||||
|
|
||||||
MATH_LIB = -lm
|
|
||||||
|
|
||||||
|
|
||||||
# List any extra directories to look for libraries here.
|
|
||||||
# Each directory must be seperated by a space.
|
|
||||||
# Use forward slashes for directory separators.
|
|
||||||
# For a directory that has spaces, enclose it in quotes.
|
|
||||||
EXTRALIBDIRS =
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- External Memory Options ----------------
|
|
||||||
|
|
||||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
|
||||||
# used for variables (.data/.bss) and heap (malloc()).
|
|
||||||
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
|
|
||||||
|
|
||||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
|
||||||
# only used for heap (malloc()).
|
|
||||||
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
|
|
||||||
|
|
||||||
EXTMEMOPTS =
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Linker Options ----------------
|
|
||||||
# -Wl,...: tell GCC to pass this to linker.
|
|
||||||
# -Map: create map file
|
|
||||||
# --cref: add cross reference to map file
|
|
||||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
|
||||||
LDFLAGS += -Wl,--relax
|
|
||||||
LDFLAGS += -Wl,--gc-sections
|
|
||||||
LDFLAGS += $(EXTMEMOPTS)
|
|
||||||
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
|
|
||||||
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
|
||||||
#LDFLAGS += -T linker_script.x
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Programming Options (avrdude) ----------------
|
|
||||||
|
|
||||||
# Programming hardware
|
|
||||||
# Type: avrdude -c ?
|
|
||||||
# to get a full listing.
|
|
||||||
#
|
|
||||||
AVRDUDE_PROGRAMMER = jtagmkII
|
|
||||||
|
|
||||||
# com1 = serial port. Use lpt1 to connect to parallel port.
|
|
||||||
AVRDUDE_PORT = usb
|
|
||||||
|
|
||||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
|
||||||
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
|
||||||
|
|
||||||
|
|
||||||
# Uncomment the following if you want avrdude's erase cycle counter.
|
|
||||||
# Note that this counter needs to be initialized first using -Yn,
|
|
||||||
# see avrdude manual.
|
|
||||||
#AVRDUDE_ERASE_COUNTER = -y
|
|
||||||
|
|
||||||
# Uncomment the following if you do /not/ wish a verification to be
|
|
||||||
# performed after programming the device.
|
|
||||||
#AVRDUDE_NO_VERIFY = -V
|
|
||||||
|
|
||||||
# Increase verbosity level. Please use this when submitting bug
|
|
||||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
|
||||||
# to submit bug reports.
|
|
||||||
#AVRDUDE_VERBOSE = -v -v
|
|
||||||
|
|
||||||
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Debugging Options ----------------
|
|
||||||
|
|
||||||
# For simulavr only - target MCU frequency.
|
|
||||||
DEBUG_MFREQ = $(F_CPU)
|
|
||||||
|
|
||||||
# Set the DEBUG_UI to either gdb or insight.
|
|
||||||
# DEBUG_UI = gdb
|
|
||||||
DEBUG_UI = insight
|
|
||||||
|
|
||||||
# Set the debugging back-end to either avarice, simulavr.
|
|
||||||
DEBUG_BACKEND = avarice
|
|
||||||
#DEBUG_BACKEND = simulavr
|
|
||||||
|
|
||||||
# GDB Init Filename.
|
|
||||||
GDBINIT_FILE = __avr_gdbinit
|
|
||||||
|
|
||||||
# When using avarice settings for the JTAG
|
|
||||||
JTAG_DEV = /dev/com1
|
|
||||||
|
|
||||||
# Debugging port used to communicate between GDB / avarice / simulavr.
|
|
||||||
DEBUG_PORT = 4242
|
|
||||||
|
|
||||||
# Debugging host used to communicate between GDB / avarice / simulavr, normally
|
|
||||||
# just set to localhost unless doing some sort of crazy debugging when
|
|
||||||
# avarice is running on a different computer.
|
|
||||||
DEBUG_HOST = localhost
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
# Define programs and commands.
|
|
||||||
SHELL = sh
|
|
||||||
CC = avr-gcc
|
|
||||||
OBJCOPY = avr-objcopy
|
|
||||||
OBJDUMP = avr-objdump
|
|
||||||
SIZE = avr-size
|
|
||||||
AR = avr-ar rcs
|
|
||||||
NM = avr-nm
|
|
||||||
AVRDUDE = avrdude
|
|
||||||
REMOVE = rm -f
|
|
||||||
REMOVEDIR = rm -rf
|
|
||||||
COPY = cp
|
|
||||||
WINSHELL = cmd
|
|
||||||
|
|
||||||
|
|
||||||
# Define Messages
|
|
||||||
# English
|
|
||||||
MSG_ERRORS_NONE = Errors: none
|
|
||||||
MSG_BEGIN = -------- begin --------
|
|
||||||
MSG_END = -------- end --------
|
|
||||||
MSG_SIZE_BEFORE = Size before:
|
|
||||||
MSG_SIZE_AFTER = Size after:
|
|
||||||
MSG_COFF = Converting to AVR COFF:
|
|
||||||
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
|
|
||||||
MSG_FLASH = Creating load file for Flash:
|
|
||||||
MSG_EEPROM = Creating load file for EEPROM:
|
|
||||||
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
|
||||||
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
|
||||||
MSG_LINKING = Linking:
|
|
||||||
MSG_COMPILING = Compiling C:
|
|
||||||
MSG_COMPILING_CPP = Compiling C++:
|
|
||||||
MSG_ASSEMBLING = Assembling:
|
|
||||||
MSG_CLEANING = Cleaning project:
|
|
||||||
MSG_CREATING_LIBRARY = Creating library:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Define all object files.
|
|
||||||
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
|
|
||||||
|
|
||||||
# Define all listing files.
|
|
||||||
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
|
|
||||||
|
|
||||||
|
|
||||||
# Compiler flags to generate dependency files.
|
|
||||||
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
|
|
||||||
|
|
||||||
|
|
||||||
# Combine all necessary flags and optional flags.
|
|
||||||
# Add target processor to flags.
|
|
||||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
|
|
||||||
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
|
|
||||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Default target.
|
|
||||||
all: begin gccversion sizebefore build sizeafter end
|
|
||||||
|
|
||||||
# Change the build target to build a HEX file or a library.
|
|
||||||
build: elf hex eep lss sym
|
|
||||||
#build: lib
|
|
||||||
|
|
||||||
|
|
||||||
elf: $(TARGET).elf
|
|
||||||
hex: $(TARGET).hex
|
|
||||||
eep: $(TARGET).eep
|
|
||||||
lss: $(TARGET).lss
|
|
||||||
sym: $(TARGET).sym
|
|
||||||
LIBNAME=lib$(TARGET).a
|
|
||||||
lib: $(LIBNAME)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Eye candy.
|
|
||||||
# AVR Studio 3.x does not check make's exit code but relies on
|
|
||||||
# the following magic strings to be generated by the compile job.
|
|
||||||
begin:
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_BEGIN)
|
|
||||||
|
|
||||||
end:
|
|
||||||
@echo $(MSG_END)
|
|
||||||
@echo
|
|
||||||
|
|
||||||
|
|
||||||
# Display size of file.
|
|
||||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
|
||||||
ELFSIZE = $(SIZE) $(MCU_FLAG) $(FORMAT_FLAG) $(TARGET).elf
|
|
||||||
MCU_FLAG = $(shell $(SIZE) --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) )
|
|
||||||
FORMAT_FLAG = $(shell $(SIZE) --help | grep -- --format=.*avr > /dev/null && echo --format=avr )
|
|
||||||
|
|
||||||
|
|
||||||
sizebefore:
|
|
||||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
|
|
||||||
2>/dev/null; echo; fi
|
|
||||||
|
|
||||||
sizeafter:
|
|
||||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
|
|
||||||
2>/dev/null; echo; fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Display compiler version information.
|
|
||||||
gccversion :
|
|
||||||
@$(CC) --version
|
|
||||||
|
|
||||||
|
|
||||||
# Program the device.
|
|
||||||
program: $(TARGET).hex $(TARGET).eep
|
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
|
|
||||||
|
|
||||||
flip: $(TARGET).hex
|
|
||||||
batchisp -hardware usb -device $(MCU) -operation erase f
|
|
||||||
batchisp -hardware usb -device $(MCU) -operation loadbuffer $(TARGET).hex program
|
|
||||||
batchisp -hardware usb -device $(MCU) -operation start reset 0
|
|
||||||
|
|
||||||
dfu: $(TARGET).hex
|
|
||||||
dfu-programmer $(MCU) erase
|
|
||||||
dfu-programmer $(MCU) flash $(TARGET).hex
|
|
||||||
dfu-programmer $(MCU) reset
|
|
||||||
|
|
||||||
flip-ee: $(TARGET).hex $(TARGET).eep
|
|
||||||
$(COPY) $(TARGET).eep $(TARGET)eep.hex
|
|
||||||
batchisp -hardware usb -device $(MCU) -operation memory EEPROM erase
|
|
||||||
batchisp -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $(TARGET)eep.hex program
|
|
||||||
batchisp -hardware usb -device $(MCU) -operation start reset 0
|
|
||||||
$(REMOVE) $(TARGET)eep.hex
|
|
||||||
|
|
||||||
dfu-ee: $(TARGET).hex $(TARGET).eep
|
|
||||||
dfu-programmer $(MCU) eeprom-flash $(TARGET).eep
|
|
||||||
dfu-programmer $(MCU) reset
|
|
||||||
|
|
||||||
|
|
||||||
# Generate avr-gdb config/init file which does the following:
|
|
||||||
# define the reset signal, load the target file, connect to target, and set
|
|
||||||
# a breakpoint at main().
|
|
||||||
gdb-config:
|
|
||||||
@$(REMOVE) $(GDBINIT_FILE)
|
|
||||||
@echo define reset >> $(GDBINIT_FILE)
|
|
||||||
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
|
|
||||||
@echo end >> $(GDBINIT_FILE)
|
|
||||||
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
|
|
||||||
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
|
|
||||||
ifeq ($(DEBUG_BACKEND),simulavr)
|
|
||||||
@echo load >> $(GDBINIT_FILE)
|
|
||||||
endif
|
|
||||||
@echo break main >> $(GDBINIT_FILE)
|
|
||||||
|
|
||||||
debug: gdb-config $(TARGET).elf
|
|
||||||
ifeq ($(DEBUG_BACKEND), avarice)
|
|
||||||
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
|
|
||||||
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
|
|
||||||
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
|
|
||||||
@$(WINSHELL) /c pause
|
|
||||||
|
|
||||||
else
|
|
||||||
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
|
|
||||||
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
|
|
||||||
endif
|
|
||||||
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
|
|
||||||
COFFCONVERT = $(OBJCOPY) --debugging
|
|
||||||
COFFCONVERT += --change-section-address .data-0x800000
|
|
||||||
COFFCONVERT += --change-section-address .bss-0x800000
|
|
||||||
COFFCONVERT += --change-section-address .noinit-0x800000
|
|
||||||
COFFCONVERT += --change-section-address .eeprom-0x810000
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
coff: $(TARGET).elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_COFF) $(TARGET).cof
|
|
||||||
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
|
|
||||||
|
|
||||||
|
|
||||||
extcoff: $(TARGET).elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
|
|
||||||
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Create final output files (.hex, .eep) from ELF output file.
|
|
||||||
%.hex: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_FLASH) $@
|
|
||||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@
|
|
||||||
|
|
||||||
%.eep: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_EEPROM) $@
|
|
||||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
|
||||||
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
|
|
||||||
|
|
||||||
# Create extended listing file from ELF output file.
|
|
||||||
%.lss: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_EXTENDED_LISTING) $@
|
|
||||||
$(OBJDUMP) -h -S -z $< > $@
|
|
||||||
|
|
||||||
# Create a symbol table from ELF output file.
|
|
||||||
%.sym: %.elf
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_SYMBOL_TABLE) $@
|
|
||||||
$(NM) -n $< > $@
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Create library from object files.
|
|
||||||
.SECONDARY : $(TARGET).a
|
|
||||||
.PRECIOUS : $(OBJ)
|
|
||||||
%.a: $(OBJ)
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_CREATING_LIBRARY) $@
|
|
||||||
$(AR) $@ $(OBJ)
|
|
||||||
|
|
||||||
|
|
||||||
# Link: create ELF output file from object files.
|
|
||||||
.SECONDARY : $(TARGET).elf
|
|
||||||
.PRECIOUS : $(OBJ)
|
|
||||||
%.elf: $(OBJ)
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_LINKING) $@
|
|
||||||
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
# Compile: create object files from C source files.
|
|
||||||
$(OBJDIR)/%.o : %.c
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_COMPILING) $<
|
|
||||||
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Compile: create object files from C++ source files.
|
|
||||||
$(OBJDIR)/%.o : %.cpp
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_COMPILING_CPP) $<
|
|
||||||
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Compile: create assembler files from C source files.
|
|
||||||
%.s : %.c
|
|
||||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Compile: create assembler files from C++ source files.
|
|
||||||
%.s : %.cpp
|
|
||||||
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Assemble: create object files from assembler source files.
|
|
||||||
$(OBJDIR)/%.o : %.S
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_ASSEMBLING) $<
|
|
||||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Create preprocessed source for use in sending a bug report.
|
|
||||||
%.i : %.c
|
|
||||||
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
|
|
||||||
# Target: clean project.
|
|
||||||
clean: begin clean_list end
|
|
||||||
|
|
||||||
clean_list :
|
|
||||||
@echo
|
|
||||||
@echo $(MSG_CLEANING)
|
|
||||||
$(REMOVE) $(TARGET).hex
|
|
||||||
$(REMOVE) $(TARGET).eep
|
|
||||||
$(REMOVE) $(TARGET).cof
|
|
||||||
$(REMOVE) $(TARGET).elf
|
|
||||||
$(REMOVE) $(TARGET).map
|
|
||||||
$(REMOVE) $(TARGET).sym
|
|
||||||
$(REMOVE) $(TARGET).lss
|
|
||||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
|
|
||||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
|
|
||||||
$(REMOVE) $(SRC:.c=.s)
|
|
||||||
$(REMOVE) $(SRC:.c=.d)
|
|
||||||
$(REMOVE) $(SRC:.c=.i)
|
|
||||||
$(REMOVEDIR) .dep
|
|
||||||
|
|
||||||
doxygen:
|
|
||||||
@echo Generating Project Documentation \($(TARGET)\)...
|
|
||||||
@if ( doxygen Doxygen.conf 2>&1 | grep -v "warning: ignoring unsupported tag" ;); then \
|
|
||||||
exit 1; \
|
|
||||||
fi;
|
|
||||||
@echo Documentation Generation Complete.
|
|
||||||
|
|
||||||
clean_doxygen:
|
|
||||||
rm -rf Documentation
|
|
||||||
|
|
||||||
checksource:
|
|
||||||
@for f in $(SRC) $(CPPSRC) $(ASRC); do \
|
|
||||||
if [ -f $$f ]; then \
|
|
||||||
echo "Found Source File: $$f" ; \
|
|
||||||
else \
|
|
||||||
echo "Source File Not Found: $$f" ; \
|
|
||||||
fi; done
|
|
||||||
|
|
||||||
|
|
||||||
# Create object files directory
|
|
||||||
$(shell mkdir $(OBJDIR) 2>/dev/null)
|
|
||||||
|
|
||||||
|
|
||||||
# Include the dependency files.
|
|
||||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
|
||||||
|
|
||||||
|
|
||||||
# Listing of phony targets.
|
|
||||||
.PHONY : all begin finish end sizebefore sizeafter gccversion \
|
|
||||||
build elf hex eep lss sym coff extcoff doxygen clean \
|
|
||||||
clean_list clean_doxygen program dfu flip flip-ee dfu-ee \
|
|
||||||
debug gdb-config checksource
|
|
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
LUFA Library
|
||||||
|
Copyright (C) Dean Camera, 2012.
|
||||||
|
|
||||||
|
dean [at] fourwalledcubicle [dot] com
|
||||||
|
www.lufa-lib.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2012 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
|
||||||
|
without fee, 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
|
||||||
|
* \brief LUFA Library Configuration Header File
|
||||||
|
*
|
||||||
|
* This header file is used to configure LUFA's compile time options,
|
||||||
|
* as an alternative to the compile time constants supplied through
|
||||||
|
* a makefile.
|
||||||
|
*
|
||||||
|
* For information on what each token does, refer to the LUFA
|
||||||
|
* manual section "Summary of Compile Tokens".
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LUFA_CONFIG_H_
|
||||||
|
#define _LUFA_CONFIG_H_
|
||||||
|
|
||||||
|
#if (ARCH == ARCH_AVR8)
|
||||||
|
|
||||||
|
/* Non-USB Related Configuration Tokens: */
|
||||||
|
// #define DISABLE_TERMINAL_CODES
|
||||||
|
|
||||||
|
/* USB Class Driver Related Tokens: */
|
||||||
|
// #define HID_HOST_BOOT_PROTOCOL_ONLY
|
||||||
|
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
|
||||||
|
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
|
||||||
|
// #define HID_MAX_COLLECTIONS {Insert Value Here}
|
||||||
|
// #define HID_MAX_REPORTITEMS {Insert Value Here}
|
||||||
|
// #define HID_MAX_REPORT_IDS {Insert Value Here}
|
||||||
|
// #define NO_CLASS_DRIVER_AUTOFLUSH
|
||||||
|
|
||||||
|
/* General USB Driver Related Tokens: */
|
||||||
|
// #define ORDERED_EP_CONFIG
|
||||||
|
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
|
||||||
|
#define USB_DEVICE_ONLY
|
||||||
|
// #define USB_HOST_ONLY
|
||||||
|
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
|
||||||
|
// #define NO_LIMITED_CONTROLLER_CONNECT
|
||||||
|
// #define NO_SOF_EVENTS
|
||||||
|
|
||||||
|
/* USB Device Mode Driver Related Tokens: */
|
||||||
|
// #define USE_RAM_DESCRIPTORS
|
||||||
|
#define USE_FLASH_DESCRIPTORS
|
||||||
|
// #define USE_EEPROM_DESCRIPTORS
|
||||||
|
// #define NO_INTERNAL_SERIAL
|
||||||
|
#define FIXED_CONTROL_ENDPOINT_SIZE 8
|
||||||
|
#define DEVICE_STATE_AS_GPIOR 0
|
||||||
|
#define FIXED_NUM_CONFIGURATIONS 1
|
||||||
|
// #define CONTROL_ONLY_DEVICE
|
||||||
|
#define INTERRUPT_CONTROL_ENDPOINT
|
||||||
|
// #define NO_DEVICE_REMOTE_WAKEUP
|
||||||
|
// #define NO_DEVICE_SELF_POWER
|
||||||
|
|
||||||
|
/* USB Host Mode Driver Related Tokens: */
|
||||||
|
// #define HOST_STATE_AS_GPIOR 0
|
||||||
|
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
|
||||||
|
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
|
||||||
|
// #define NO_AUTO_VBUS_MANAGEMENT
|
||||||
|
// #define INVERTED_VBUS_ENABLE_LINE
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error Unsupported architecture for this LUFA configuration file.
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
LUFA Library
|
||||||
|
Copyright (C) Dean Camera, 2012.
|
||||||
|
|
||||||
|
dean [at] fourwalledcubicle [dot] com
|
||||||
|
www.lufa-lib.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2012 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
|
||||||
|
without fee, 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
|
||||||
|
* \brief Application Configuration Header File
|
||||||
|
*
|
||||||
|
* This is a header file which is be used to configure some of
|
||||||
|
* the application's compile time options, as an alternative to
|
||||||
|
* specifying the compile time constants supplied through a
|
||||||
|
* makefile or build system.
|
||||||
|
*
|
||||||
|
* For information on what each token does, refer to the
|
||||||
|
* \ref Sec_Options section of the application documentation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _APP_CONFIG_H_
|
||||||
|
#define _APP_CONFIG_H_
|
||||||
|
|
||||||
|
#define ENABLE_DHCP_CLIENT
|
||||||
|
#define ENABLE_DHCP_SERVER
|
||||||
|
#define ENABLE_TELNET_SERVER
|
||||||
|
#define MAX_URI_LENGTH 50
|
||||||
|
|
||||||
|
#define UIP_CONF_UDP (defined(ENABLE_DHCP_CLIENT) || defined(ENABLE_DHCP_SERVER))
|
||||||
|
#define UIP_CONF_BROADCAST 1
|
||||||
|
#define UIP_CONF_TCP 1
|
||||||
|
#define UIP_CONF_UDP_CONNS 1
|
||||||
|
#define UIP_CONF_MAX_CONNECTIONS 3
|
||||||
|
#define UIP_CONF_MAX_LISTENPORTS 5
|
||||||
|
#define UIP_CONF_BUFFER_SIZE 1514
|
||||||
|
#define UIP_CONF_LL_802154 0
|
||||||
|
#define UIP_CONF_LL_80211 0
|
||||||
|
#define UIP_CONF_ROUTER 0
|
||||||
|
#define UIP_CONF_ICMP6 0
|
||||||
|
#define UIP_CONF_ICMP_DEST_UNREACH 1
|
||||||
|
#define UIP_URGDATA 0
|
||||||
|
#define UIP_ARCH_CHKSUM 0
|
||||||
|
#define UIP_ARCH_ADD32 0
|
||||||
|
#define UIP_NEIGHBOR_CONF_ADDRTYPE 0
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
LUFA Library
|
||||||
|
Copyright (C) Dean Camera, 2012.
|
||||||
|
|
||||||
|
dean [at] fourwalledcubicle [dot] com
|
||||||
|
www.lufa-lib.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2012 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
|
||||||
|
without fee, 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
|
||||||
|
* \brief LUFA Library Configuration Header File
|
||||||
|
*
|
||||||
|
* This header file is used to configure LUFA's compile time options,
|
||||||
|
* as an alternative to the compile time constants supplied through
|
||||||
|
* a makefile.
|
||||||
|
*
|
||||||
|
* For information on what each token does, refer to the LUFA
|
||||||
|
* manual section "Summary of Compile Tokens".
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LUFA_CONFIG_H_
|
||||||
|
#define _LUFA_CONFIG_H_
|
||||||
|
|
||||||
|
#if (ARCH == ARCH_AVR8)
|
||||||
|
|
||||||
|
/* Non-USB Related Configuration Tokens: */
|
||||||
|
// #define DISABLE_TERMINAL_CODES
|
||||||
|
|
||||||
|
/* USB Class Driver Related Tokens: */
|
||||||
|
// #define HID_HOST_BOOT_PROTOCOL_ONLY
|
||||||
|
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
|
||||||
|
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
|
||||||
|
// #define HID_MAX_COLLECTIONS {Insert Value Here}
|
||||||
|
// #define HID_MAX_REPORTITEMS {Insert Value Here}
|
||||||
|
// #define HID_MAX_REPORT_IDS {Insert Value Here}
|
||||||
|
// #define NO_CLASS_DRIVER_AUTOFLUSH
|
||||||
|
|
||||||
|
/* General USB Driver Related Tokens: */
|
||||||
|
// #define ORDERED_EP_CONFIG
|
||||||
|
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
|
||||||
|
// #define USB_DEVICE_ONLY
|
||||||
|
// #define USB_HOST_ONLY
|
||||||
|
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
|
||||||
|
// #define NO_LIMITED_CONTROLLER_CONNECT
|
||||||
|
// #define NO_SOF_EVENTS
|
||||||
|
|
||||||
|
/* USB Device Mode Driver Related Tokens: */
|
||||||
|
// #define USE_RAM_DESCRIPTORS
|
||||||
|
#define USE_FLASH_DESCRIPTORS
|
||||||
|
// #define USE_EEPROM_DESCRIPTORS
|
||||||
|
// #define NO_INTERNAL_SERIAL
|
||||||
|
#define FIXED_CONTROL_ENDPOINT_SIZE 8
|
||||||
|
#define DEVICE_STATE_AS_GPIOR 0
|
||||||
|
#define FIXED_NUM_CONFIGURATIONS 1
|
||||||
|
// #define CONTROL_ONLY_DEVICE
|
||||||
|
#define INTERRUPT_CONTROL_ENDPOINT
|
||||||
|
// #define NO_DEVICE_REMOTE_WAKEUP
|
||||||
|
// #define NO_DEVICE_SELF_POWER
|
||||||
|
|
||||||
|
/* USB Host Mode Driver Related Tokens: */
|
||||||
|
#define HOST_STATE_AS_GPIOR 0
|
||||||
|
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
|
||||||
|
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
|
||||||
|
// #define NO_AUTO_VBUS_MANAGEMENT
|
||||||
|
// #define INVERTED_VBUS_ENABLE_LINE
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error Unsupported architecture for this LUFA configuration file.
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
LUFA Library
|
||||||
|
Copyright (C) Dean Camera, 2012.
|
||||||
|
|
||||||
|
dean [at] fourwalledcubicle [dot] com
|
||||||
|
www.lufa-lib.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2012 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
|
||||||
|
without fee, 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
|
||||||
|
* \brief LUFA Library Configuration Header File
|
||||||
|
*
|
||||||
|
* This header file is used to configure LUFA's compile time options,
|
||||||
|
* as an alternative to the compile time constants supplied through
|
||||||
|
* a makefile.
|
||||||
|
*
|
||||||
|
* For information on what each token does, refer to the LUFA
|
||||||
|
* manual section "Summary of Compile Tokens".
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LUFA_CONFIG_H_
|
||||||
|
#define _LUFA_CONFIG_H_
|
||||||
|
|
||||||
|
#if (ARCH == ARCH_AVR8)
|
||||||
|
|
||||||
|
/* Non-USB Related Configuration Tokens: */
|
||||||
|
// #define DISABLE_TERMINAL_CODES
|
||||||
|
|
||||||
|
/* USB Class Driver Related Tokens: */
|
||||||
|
// #define HID_HOST_BOOT_PROTOCOL_ONLY
|
||||||
|
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
|
||||||
|
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
|
||||||
|
// #define HID_MAX_COLLECTIONS {Insert Value Here}
|
||||||
|
// #define HID_MAX_REPORTITEMS {Insert Value Here}
|
||||||
|
// #define HID_MAX_REPORT_IDS {Insert Value Here}
|
||||||
|
// #define NO_CLASS_DRIVER_AUTOFLUSH
|
||||||
|
|
||||||
|
/* General USB Driver Related Tokens: */
|
||||||
|
#define ORDERED_EP_CONFIG
|
||||||
|
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
|
||||||
|
#define USB_DEVICE_ONLY
|
||||||
|
// #define USB_HOST_ONLY
|
||||||
|
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
|
||||||
|
// #define NO_LIMITED_CONTROLLER_CONNECT
|
||||||
|
#define NO_SOF_EVENTS
|
||||||
|
|
||||||
|
/* USB Device Mode Driver Related Tokens: */
|
||||||
|
// #define USE_RAM_DESCRIPTORS
|
||||||
|
#define USE_FLASH_DESCRIPTORS
|
||||||
|
// #define USE_EEPROM_DESCRIPTORS
|
||||||
|
// #define NO_INTERNAL_SERIAL
|
||||||
|
#define FIXED_CONTROL_ENDPOINT_SIZE 16
|
||||||
|
#define DEVICE_STATE_AS_GPIOR 0
|
||||||
|
#define FIXED_NUM_CONFIGURATIONS 1
|
||||||
|
// #define CONTROL_ONLY_DEVICE
|
||||||
|
// #define INTERRUPT_CONTROL_ENDPOINT
|
||||||
|
#define NO_DEVICE_REMOTE_WAKEUP
|
||||||
|
#define NO_DEVICE_SELF_POWER
|
||||||
|
|
||||||
|
/* USB Host Mode Driver Related Tokens: */
|
||||||
|
// #define HOST_STATE_AS_GPIOR {Insert Value Here}
|
||||||
|
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
|
||||||
|
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
|
||||||
|
// #define NO_AUTO_VBUS_MANAGEMENT
|
||||||
|
// #define INVERTED_VBUS_ENABLE_LINE
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error Unsupported architecture for this LUFA configuration file.
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
Loading…
Reference in new issue