Merge remote-tracking branch 'origin/Marlin_v1' into Marlin_v1
Conflicts: Marlin/Configuration.h Marlin/EEPROMwrite.h Marlin/Marlin.h Marlin/Marlin.pde Marlin/temperature.cpp Marlin/temperature.h Marlin/thermistortables.h
This commit is contained in:
		| @@ -54,9 +54,8 @@ const bool ENDSTOPS_INVERTING = true; // set to true to invert the logic of the | ||||
| // Comment out (using // at the start of the line) to disable SD support: | ||||
|  | ||||
| // #define ULTRA_LCD  //any lcd  | ||||
| #define LCD_WIDTH 16 | ||||
| #define LCD_HEIGHT 2 | ||||
|  | ||||
| #define ULTIPANEL | ||||
| #define ULTIPANEL | ||||
| #ifdef ULTIPANEL | ||||
|  //#define NEWPANEL  //enable this if you have a click-encoder panel | ||||
| @@ -64,6 +63,11 @@ const bool ENDSTOPS_INVERTING = true; // set to true to invert the logic of the | ||||
|  #define ULTRA_LCD | ||||
|  #define LCD_WIDTH 20 | ||||
| #define LCD_HEIGHT 4 | ||||
| #else //no panel but just lcd  | ||||
|   #ifdef ULTRA_LCD | ||||
|     #define LCD_WIDTH 16 | ||||
|     #define LCD_HEIGHT 2 | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
|  | ||||
| @@ -169,25 +173,46 @@ const int dropsegments=5; //everything with this number of steps  will be ignore | ||||
| //#define_HEATER_1_MAXTEMP 275 | ||||
| //#define BED_MAXTEMP 150 | ||||
|  | ||||
| /// PID settings: | ||||
| // Uncomment the following line to enable PID support. | ||||
| //#define SMOOTHING | ||||
| //#define SMOOTHFACTOR 5.0 | ||||
| //float current_raw_average=0; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #define PIDTEMP | ||||
| #ifdef PIDTEMP | ||||
| //#define PID_DEBUG // Sends debug data to the serial port.  | ||||
| //#define PID_OPENLOOP 1 // Puts PID in open loop. M104 sets the output power in % | ||||
| #define PID_MAX 255 // limits current to nozzle | ||||
| #define PID_INTEGRAL_DRIVE_MAX 255 | ||||
| #define PID_dT 0.10 // 100ms sample time | ||||
| #define DEFAULT_Kp 20.0 | ||||
| #define DEFAULT_Ki 1.5*PID_dT | ||||
| #define DEFAULT_Kd 80/PID_dT | ||||
| #define DEFAULT_Kc 0 | ||||
| #endif // PIDTEMP | ||||
|   /// PID settings: | ||||
|   // Uncomment the following line to enable PID support. | ||||
|   //#define SMOOTHING | ||||
|   //#define SMOOTHFACTOR 5.0 | ||||
|   //float current_raw_average=0; | ||||
|     #define K1 0.95 //smoothing of the PID | ||||
|   //#define PID_DEBUG // Sends debug data to the serial port.  | ||||
|   //#define PID_OPENLOOP 1 // Puts PID in open loop. M104 sets the output power in % | ||||
|   #define PID_MAX 255 // limits current to nozzle | ||||
|   #define PID_INTEGRAL_DRIVE_MAX 255 | ||||
|   #define PID_dT 0.1 | ||||
|  //machine with red silicon: 1950:45 second ; with fan fully blowin 3000:47 | ||||
|  | ||||
|   #define PID_CRITIAL_GAIN 3000 | ||||
|   #define PID_SWING_AT_CRITIAL 45 //seconds | ||||
|   #define PIDIADD 5 | ||||
|   /* | ||||
|   //PID according to Ziegler-Nichols method | ||||
|   float Kp = 0.6*PID_CRITIAL_GAIN;  | ||||
|   float Ki =PIDIADD+2*Kp/PID_SWING_AT_CRITIAL*PID_dT;   | ||||
|   float Kd = Kp*PID_SWING_AT_CRITIAL/8./PID_dT;   | ||||
|   */ | ||||
|   //PI according to Ziegler-Nichols method | ||||
|   #define  DEFAULT_Kp (PID_CRITIAL_GAIN/2.2)  | ||||
|   #define  DEFAULT_Ki (1.2*Kp/PID_SWING_AT_CRITIAL*PID_dT) | ||||
|   #define  DEFAULT_Kd (0) | ||||
|    | ||||
|   #define PID_ADD_EXTRUSION_RATE   | ||||
|   #ifdef PID_ADD_EXTRUSION_RATE | ||||
|     #define  DEFAULT_Kc (5) //heatingpower=Kc*(e_speed) | ||||
|   #endif | ||||
| #endif // PIDTEMP | ||||
|  | ||||
| // extruder advance constant (s2/mm3) | ||||
| // | ||||
| @@ -208,6 +233,7 @@ const int dropsegments=5; //everything with this number of steps  will be ignore | ||||
|  | ||||
| #endif // ADVANCE | ||||
|  | ||||
| // THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, e.g. 8,16,32  | ||||
| #if defined SDSUPPORT | ||||
| // The number of linear motions that can be in the plan at any give time.   | ||||
|   #define BLOCK_BUFFER_SIZE 16   // SD,LCD,Buttons take more memory, block buffer needs to be smaller | ||||
| @@ -215,8 +241,5 @@ const int dropsegments=5; //everything with this number of steps  will be ignore | ||||
|   #define BLOCK_BUFFER_SIZE 16 // maximize block buffer | ||||
| #endif | ||||
|  | ||||
| #ifdef SIMPLE_LCD | ||||
|   #define BLOCK_BUFFER_SIZE 16 // A little less buffer for just a simple LCD | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,13 +1,17 @@ | ||||
| 
 | ||||
| #ifndef __EEPROMH | ||||
| #define __EEPROMH | ||||
| #include "planner.h" | ||||
| #include "temperature.h" | ||||
| #include <EEPROM.h> | ||||
| #include "Marlin.h" | ||||
| #include "streaming.h" | ||||
| 
 | ||||
| //======================================================================================
 | ||||
| template <class T> int EEPROM_writeAnything(int &ee, const T& value) | ||||
| { | ||||
|     const byte* p = (const byte*)(const void*)&value; | ||||
|     int i; | ||||
|     for (i = 0; i < sizeof(value); i++) | ||||
|     for (i = 0; i < (int)sizeof(value); i++) | ||||
| 	  EEPROM.write(ee++, *p++); | ||||
|     return i; | ||||
| } | ||||
| @@ -16,7 +20,7 @@ template <class T> int EEPROM_readAnything(int &ee, T& value) | ||||
| { | ||||
|     byte* p = (byte*)(void*)&value; | ||||
|     int i; | ||||
|     for (i = 0; i < sizeof(value); i++) | ||||
|     for (i = 0; i < (int)sizeof(value); i++) | ||||
| 	  *p++ = EEPROM.read(ee++); | ||||
|     return i; | ||||
| } | ||||
| @@ -120,4 +124,6 @@ void RetrieveSettings(bool def=false){  // if def=true, the default values will | ||||
|    | ||||
| }   | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| @@ -1,418 +1,418 @@ | ||||
| /* Arduino SdFat Library | ||||
|  * Copyright (C) 2009 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino SdFat Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino SdFat Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| #ifndef FatStructs_h | ||||
| #define FatStructs_h | ||||
| /** | ||||
|  * \file | ||||
|  * FAT file structures | ||||
|  */ | ||||
| /* | ||||
|  * mostly from Microsoft document fatgen103.doc | ||||
|  * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx | ||||
|  */ | ||||
| //------------------------------------------------------------------------------ | ||||
| /** Value for byte 510 of boot block or MBR */ | ||||
| uint8_t const BOOTSIG0 = 0X55; | ||||
| /** Value for byte 511 of boot block or MBR */ | ||||
| uint8_t const BOOTSIG1 = 0XAA; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * \struct partitionTable | ||||
|  * \brief MBR partition table entry | ||||
|  * | ||||
|  * A partition table entry for a MBR formatted storage device. | ||||
|  * The MBR partition table has four entries. | ||||
|  */ | ||||
| struct partitionTable { | ||||
|           /** | ||||
|            * Boot Indicator . Indicates whether the volume is the active | ||||
|            * partition.  Legal values include: 0X00. Do not use for booting. | ||||
|            * 0X80 Active partition. | ||||
|            */ | ||||
|   uint8_t  boot; | ||||
|           /** | ||||
|             * Head part of Cylinder-head-sector address of the first block in | ||||
|             * the partition. Legal values are 0-255. Only used in old PC BIOS. | ||||
|             */ | ||||
|   uint8_t  beginHead; | ||||
|           /** | ||||
|            * Sector part of Cylinder-head-sector address of the first block in | ||||
|            * the partition. Legal values are 1-63. Only used in old PC BIOS. | ||||
|            */ | ||||
|   unsigned beginSector : 6; | ||||
|            /** High bits cylinder for first block in partition. */ | ||||
|   unsigned beginCylinderHigh : 2; | ||||
|           /** | ||||
|            * Combine beginCylinderLow with beginCylinderHigh. Legal values | ||||
|            * are 0-1023.  Only used in old PC BIOS. | ||||
|            */ | ||||
|   uint8_t  beginCylinderLow; | ||||
|           /** | ||||
|            * Partition type. See defines that begin with PART_TYPE_ for | ||||
|            * some Microsoft partition types. | ||||
|            */ | ||||
|   uint8_t  type; | ||||
|           /** | ||||
|            * head part of cylinder-head-sector address of the last sector in the | ||||
|            * partition.  Legal values are 0-255. Only used in old PC BIOS. | ||||
|            */ | ||||
|   uint8_t  endHead; | ||||
|           /** | ||||
|            * Sector part of cylinder-head-sector address of the last sector in | ||||
|            * the partition.  Legal values are 1-63. Only used in old PC BIOS. | ||||
|            */ | ||||
|   unsigned endSector : 6; | ||||
|            /** High bits of end cylinder */ | ||||
|   unsigned endCylinderHigh : 2; | ||||
|           /** | ||||
|            * Combine endCylinderLow with endCylinderHigh. Legal values | ||||
|            * are 0-1023.  Only used in old PC BIOS. | ||||
|            */ | ||||
|   uint8_t  endCylinderLow; | ||||
|            /** Logical block address of the first block in the partition. */ | ||||
|   uint32_t firstSector; | ||||
|            /** Length of the partition, in blocks. */ | ||||
|   uint32_t totalSectors; | ||||
| }; | ||||
| /** Type name for partitionTable */ | ||||
| typedef struct partitionTable part_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * \struct masterBootRecord | ||||
|  * | ||||
|  * \brief Master Boot Record | ||||
|  * | ||||
|  * The first block of a storage device that is formatted with a MBR. | ||||
|  */ | ||||
| struct masterBootRecord { | ||||
|            /** Code Area for master boot program. */ | ||||
|   uint8_t  codeArea[440]; | ||||
|            /** Optional WindowsNT disk signature. May contain more boot code. */ | ||||
|   uint32_t diskSignature; | ||||
|            /** Usually zero but may be more boot code. */ | ||||
|   uint16_t usuallyZero; | ||||
|            /** Partition tables. */ | ||||
|   part_t   part[4]; | ||||
|            /** First MBR signature byte. Must be 0X55 */ | ||||
|   uint8_t  mbrSig0; | ||||
|            /** Second MBR signature byte. Must be 0XAA */ | ||||
|   uint8_t  mbrSig1; | ||||
| }; | ||||
| /** Type name for masterBootRecord */ | ||||
| typedef struct masterBootRecord mbr_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| /**  | ||||
|  * \struct biosParmBlock | ||||
|  * | ||||
|  * \brief BIOS parameter block | ||||
|  *  | ||||
|  *  The BIOS parameter block describes the physical layout of a FAT volume. | ||||
|  */ | ||||
| struct biosParmBlock { | ||||
|           /** | ||||
|            * Count of bytes per sector. This value may take on only the | ||||
|            * following values: 512, 1024, 2048 or 4096 | ||||
|            */ | ||||
|   uint16_t bytesPerSector; | ||||
|           /** | ||||
|            * Number of sectors per allocation unit. This value must be a | ||||
|            * power of 2 that is greater than 0. The legal values are | ||||
|            * 1, 2, 4, 8, 16, 32, 64, and 128. | ||||
|            */ | ||||
|   uint8_t  sectorsPerCluster; | ||||
|           /** | ||||
|            * Number of sectors before the first FAT. | ||||
|            * This value must not be zero. | ||||
|            */ | ||||
|   uint16_t reservedSectorCount; | ||||
|           /** The count of FAT data structures on the volume. This field should | ||||
|            *  always contain the value 2 for any FAT volume of any type. | ||||
|            */ | ||||
|   uint8_t  fatCount; | ||||
|           /** | ||||
|           * For FAT12 and FAT16 volumes, this field contains the count of | ||||
|           * 32-byte directory entries in the root directory. For FAT32 volumes, | ||||
|           * this field must be set to 0. For FAT12 and FAT16 volumes, this | ||||
|           * value should always specify a count that when multiplied by 32 | ||||
|           * results in a multiple of bytesPerSector.  FAT16 volumes should | ||||
|           * use the value 512. | ||||
|           */ | ||||
|   uint16_t rootDirEntryCount; | ||||
|           /** | ||||
|            * This field is the old 16-bit total count of sectors on the volume. | ||||
|            * This count includes the count of all sectors in all four regions | ||||
|            * of the volume. This field can be 0; if it is 0, then totalSectors32 | ||||
|            * must be non-zero.  For FAT32 volumes, this field must be 0. For | ||||
|            * FAT12 and FAT16 volumes, this field contains the sector count, and | ||||
|            * totalSectors32 is 0 if the total sector count fits | ||||
|            * (is less than 0x10000). | ||||
|            */ | ||||
|   uint16_t totalSectors16; | ||||
|           /** | ||||
|            * This dates back to the old MS-DOS 1.x media determination and is | ||||
|            * no longer usually used for anything.  0xF8 is the standard value | ||||
|            * for fixed (non-removable) media. For removable media, 0xF0 is | ||||
|            * frequently used. Legal values are 0xF0 or 0xF8-0xFF. | ||||
|            */ | ||||
|   uint8_t  mediaType; | ||||
|           /** | ||||
|            * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. | ||||
|            * On FAT32 volumes this field must be 0, and sectorsPerFat32 | ||||
|            * contains the FAT size count. | ||||
|            */ | ||||
|   uint16_t sectorsPerFat16; | ||||
|            /** Sectors per track for interrupt 0x13. Not used otherwise. */ | ||||
|   uint16_t sectorsPerTrtack; | ||||
|            /** Number of heads for interrupt 0x13.  Not used otherwise. */ | ||||
|   uint16_t headCount; | ||||
|           /** | ||||
|            * Count of hidden sectors preceding the partition that contains this | ||||
|            * FAT volume. This field is generally only relevant for media | ||||
|            *  visible on interrupt 0x13. | ||||
|            */ | ||||
|   uint32_t hidddenSectors; | ||||
|           /** | ||||
|            * This field is the new 32-bit total count of sectors on the volume. | ||||
|            * This count includes the count of all sectors in all four regions | ||||
|            * of the volume.  This field can be 0; if it is 0, then | ||||
|            * totalSectors16 must be non-zero. | ||||
|            */ | ||||
|   uint32_t totalSectors32; | ||||
|           /** | ||||
|            * Count of sectors occupied by one FAT on FAT32 volumes. | ||||
|            */ | ||||
|   uint32_t sectorsPerFat32; | ||||
|           /** | ||||
|            * This field is only defined for FAT32 media and does not exist on | ||||
|            * FAT12 and FAT16 media. | ||||
|            * Bits 0-3 -- Zero-based number of active FAT. | ||||
|            *             Only valid if mirroring is disabled. | ||||
|            * Bits 4-6 -- Reserved. | ||||
|            * Bit 7	-- 0 means the FAT is mirrored at runtime into all FATs. | ||||
| 	         *        -- 1 means only one FAT is active; it is the one referenced in bits 0-3. | ||||
|            * Bits 8-15 	-- Reserved. | ||||
|            */ | ||||
|   uint16_t fat32Flags; | ||||
|           /** | ||||
|            * FAT32 version. High byte is major revision number. | ||||
|            * Low byte is minor revision number. Only 0.0 define. | ||||
|            */ | ||||
|   uint16_t fat32Version; | ||||
|           /** | ||||
|            * Cluster number of the first cluster of the root directory for FAT32. | ||||
|            * This usually 2 but not required to be 2. | ||||
|            */ | ||||
|   uint32_t fat32RootCluster; | ||||
|           /** | ||||
|            * Sector number of FSINFO structure in the reserved area of the | ||||
|            * FAT32 volume. Usually 1. | ||||
|            */ | ||||
|   uint16_t fat32FSInfo; | ||||
|           /** | ||||
|            * If non-zero, indicates the sector number in the reserved area | ||||
|            * of the volume of a copy of the boot record. Usually 6. | ||||
|            * No value other than 6 is recommended. | ||||
|            */ | ||||
|   uint16_t fat32BackBootBlock; | ||||
|           /** | ||||
|            * Reserved for future expansion. Code that formats FAT32 volumes | ||||
|            * should always set all of the bytes of this field to 0. | ||||
|            */ | ||||
|   uint8_t  fat32Reserved[12]; | ||||
| }; | ||||
| /** Type name for biosParmBlock */ | ||||
| typedef struct biosParmBlock bpb_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * \struct fat32BootSector | ||||
|  * | ||||
|  * \brief Boot sector for a FAT16 or FAT32 volume. | ||||
|  *  | ||||
|  */   | ||||
| struct fat32BootSector { | ||||
|            /** X86 jmp to boot program */ | ||||
|   uint8_t  jmpToBootCode[3]; | ||||
|            /** informational only - don't depend on it */ | ||||
|   char     oemName[8]; | ||||
|            /** BIOS Parameter Block */ | ||||
|   bpb_t    bpb; | ||||
|            /** for int0x13 use value 0X80 for hard drive */ | ||||
|   uint8_t  driveNumber; | ||||
|            /** used by Windows NT - should be zero for FAT */ | ||||
|   uint8_t  reserved1; | ||||
|            /** 0X29 if next three fields are valid */ | ||||
|   uint8_t  bootSignature; | ||||
|            /** usually generated by combining date and time */ | ||||
|   uint32_t volumeSerialNumber; | ||||
|            /** should match volume label in root dir */ | ||||
|   char     volumeLabel[11]; | ||||
|            /** informational only - don't depend on it */ | ||||
|   char     fileSystemType[8]; | ||||
|            /** X86 boot code */ | ||||
|   uint8_t  bootCode[420]; | ||||
|            /** must be 0X55 */ | ||||
|   uint8_t  bootSectorSig0; | ||||
|            /** must be 0XAA */ | ||||
|   uint8_t  bootSectorSig1; | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| // End Of Chain values for FAT entries | ||||
| /** FAT16 end of chain value used by Microsoft. */ | ||||
| uint16_t const FAT16EOC = 0XFFFF; | ||||
| /** Minimum value for FAT16 EOC.  Use to test for EOC. */ | ||||
| uint16_t const FAT16EOC_MIN = 0XFFF8; | ||||
| /** FAT32 end of chain value used by Microsoft. */ | ||||
| uint32_t const FAT32EOC = 0X0FFFFFFF; | ||||
| /** Minimum value for FAT32 EOC.  Use to test for EOC. */ | ||||
| uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; | ||||
| /** Mask a for FAT32 entry. Entries are 28 bits. */ | ||||
| uint32_t const FAT32MASK = 0X0FFFFFFF; | ||||
|  | ||||
| /** Type name for fat32BootSector */ | ||||
| typedef struct fat32BootSector fbs_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * \struct directoryEntry | ||||
|  * \brief FAT short directory entry | ||||
|  * | ||||
|  * Short means short 8.3 name, not the entry size. | ||||
|  *   | ||||
|  * Date Format. A FAT directory entry date stamp is a 16-bit field that is  | ||||
|  * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the | ||||
|  * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the  | ||||
|  * 16-bit word): | ||||
|  *    | ||||
|  * Bits 9-15: Count of years from 1980, valid value range 0-127  | ||||
|  * inclusive (1980-2107). | ||||
|  *    | ||||
|  * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. | ||||
|  * | ||||
|  * Bits 0-4: Day of month, valid value range 1-31 inclusive. | ||||
|  * | ||||
|  * Time Format. A FAT directory entry time stamp is a 16-bit field that has | ||||
|  * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the  | ||||
|  * 16-bit word, bit 15 is the MSB of the 16-bit word). | ||||
|  *    | ||||
|  * Bits 11-15: Hours, valid value range 0-23 inclusive. | ||||
|  *  | ||||
|  * Bits 5-10: Minutes, valid value range 0-59 inclusive. | ||||
|  *       | ||||
|  * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). | ||||
|  *    | ||||
|  * The valid time range is from Midnight 00:00:00 to 23:59:58. | ||||
|  */ | ||||
| struct directoryEntry { | ||||
|            /** | ||||
|             * Short 8.3 name. | ||||
|             * The first eight bytes contain the file name with blank fill. | ||||
|             * The last three bytes contain the file extension with blank fill. | ||||
|             */ | ||||
|   uint8_t  name[11]; | ||||
|           /** Entry attributes. | ||||
|            * | ||||
|            * The upper two bits of the attribute byte are reserved and should | ||||
|            * always be set to 0 when a file is created and never modified or | ||||
|            * looked at after that.  See defines that begin with DIR_ATT_. | ||||
|            */ | ||||
|   uint8_t  attributes; | ||||
|           /** | ||||
|            * Reserved for use by Windows NT. Set value to 0 when a file is | ||||
|            * created and never modify or look at it after that. | ||||
|            */ | ||||
|   uint8_t  reservedNT; | ||||
|           /** | ||||
|            * The granularity of the seconds part of creationTime is 2 seconds | ||||
|            * so this field is a count of tenths of a second and its valid | ||||
|            * value range is 0-199 inclusive. (WHG note - seems to be hundredths) | ||||
|            */ | ||||
|   uint8_t  creationTimeTenths; | ||||
|            /** Time file was created. */ | ||||
|   uint16_t creationTime; | ||||
|            /** Date file was created. */ | ||||
|   uint16_t creationDate; | ||||
|           /** | ||||
|            * Last access date. Note that there is no last access time, only | ||||
|            * a date.  This is the date of last read or write. In the case of | ||||
|            * a write, this should be set to the same date as lastWriteDate. | ||||
|            */ | ||||
|   uint16_t lastAccessDate; | ||||
|           /** | ||||
|            * High word of this entry's first cluster number (always 0 for a | ||||
|            * FAT12 or FAT16 volume). | ||||
|            */ | ||||
|   uint16_t firstClusterHigh; | ||||
|            /** Time of last write. File creation is considered a write. */ | ||||
|   uint16_t lastWriteTime; | ||||
|            /** Date of last write. File creation is considered a write. */ | ||||
|   uint16_t lastWriteDate; | ||||
|            /** Low word of this entry's first cluster number. */ | ||||
|   uint16_t firstClusterLow; | ||||
|            /** 32-bit unsigned holding this file's size in bytes. */ | ||||
|   uint32_t fileSize; | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| // Definitions for directory entries | ||||
| // | ||||
| /** Type name for directoryEntry */ | ||||
| typedef struct directoryEntry dir_t; | ||||
| /** escape for name[0] = 0XE5 */ | ||||
| uint8_t const DIR_NAME_0XE5 = 0X05; | ||||
| /** name[0] value for entry that is free after being "deleted" */ | ||||
| uint8_t const DIR_NAME_DELETED = 0XE5; | ||||
| /** name[0] value for entry that is free and no allocated entries follow */ | ||||
| uint8_t const DIR_NAME_FREE = 0X00; | ||||
| /** file is read-only */ | ||||
| uint8_t const DIR_ATT_READ_ONLY = 0X01; | ||||
| /** File should hidden in directory listings */ | ||||
| uint8_t const DIR_ATT_HIDDEN = 0X02; | ||||
| /** Entry is for a system file */ | ||||
| uint8_t const DIR_ATT_SYSTEM = 0X04; | ||||
| /** Directory entry contains the volume label */ | ||||
| uint8_t const DIR_ATT_VOLUME_ID = 0X08; | ||||
| /** Entry is for a directory */ | ||||
| uint8_t const DIR_ATT_DIRECTORY = 0X10; | ||||
| /** Old DOS archive bit for backup support */ | ||||
| uint8_t const DIR_ATT_ARCHIVE = 0X20; | ||||
| /** Test value for long name entry.  Test is | ||||
|   (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ | ||||
| uint8_t const DIR_ATT_LONG_NAME = 0X0F; | ||||
| /** Test mask for long name entry */ | ||||
| uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; | ||||
| /** defined attribute bits */ | ||||
| uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; | ||||
| /** Directory entry is part of a long name */ | ||||
| static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { | ||||
|   return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; | ||||
| } | ||||
| /** Mask for file/subdirectory tests */ | ||||
| uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); | ||||
| /** Directory entry is for a file */ | ||||
| static inline uint8_t DIR_IS_FILE(const dir_t* dir) { | ||||
|   return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; | ||||
| } | ||||
| /** Directory entry is for a subdirectory */ | ||||
| static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { | ||||
|   return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; | ||||
| } | ||||
| /** Directory entry is for a file or subdirectory */ | ||||
| static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { | ||||
|   return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; | ||||
| } | ||||
| #endif  // FatStructs_h | ||||
| /* Arduino SdFat Library | ||||
|  * Copyright (C) 2009 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino SdFat Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino SdFat Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| #ifndef FatStructs_h | ||||
| #define FatStructs_h | ||||
| /** | ||||
|  * \file | ||||
|  * FAT file structures | ||||
|  */ | ||||
| /* | ||||
|  * mostly from Microsoft document fatgen103.doc | ||||
|  * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx | ||||
|  */ | ||||
| //------------------------------------------------------------------------------ | ||||
| /** Value for byte 510 of boot block or MBR */ | ||||
| uint8_t const BOOTSIG0 = 0X55; | ||||
| /** Value for byte 511 of boot block or MBR */ | ||||
| uint8_t const BOOTSIG1 = 0XAA; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * \struct partitionTable | ||||
|  * \brief MBR partition table entry | ||||
|  * | ||||
|  * A partition table entry for a MBR formatted storage device. | ||||
|  * The MBR partition table has four entries. | ||||
|  */ | ||||
| struct partitionTable { | ||||
|           /** | ||||
|            * Boot Indicator . Indicates whether the volume is the active | ||||
|            * partition.  Legal values include: 0X00. Do not use for booting. | ||||
|            * 0X80 Active partition. | ||||
|            */ | ||||
|   uint8_t  boot; | ||||
|           /** | ||||
|             * Head part of Cylinder-head-sector address of the first block in | ||||
|             * the partition. Legal values are 0-255. Only used in old PC BIOS. | ||||
|             */ | ||||
|   uint8_t  beginHead; | ||||
|           /** | ||||
|            * Sector part of Cylinder-head-sector address of the first block in | ||||
|            * the partition. Legal values are 1-63. Only used in old PC BIOS. | ||||
|            */ | ||||
|   unsigned beginSector : 6; | ||||
|            /** High bits cylinder for first block in partition. */ | ||||
|   unsigned beginCylinderHigh : 2; | ||||
|           /** | ||||
|            * Combine beginCylinderLow with beginCylinderHigh. Legal values | ||||
|            * are 0-1023.  Only used in old PC BIOS. | ||||
|            */ | ||||
|   uint8_t  beginCylinderLow; | ||||
|           /** | ||||
|            * Partition type. See defines that begin with PART_TYPE_ for | ||||
|            * some Microsoft partition types. | ||||
|            */ | ||||
|   uint8_t  type; | ||||
|           /** | ||||
|            * head part of cylinder-head-sector address of the last sector in the | ||||
|            * partition.  Legal values are 0-255. Only used in old PC BIOS. | ||||
|            */ | ||||
|   uint8_t  endHead; | ||||
|           /** | ||||
|            * Sector part of cylinder-head-sector address of the last sector in | ||||
|            * the partition.  Legal values are 1-63. Only used in old PC BIOS. | ||||
|            */ | ||||
|   unsigned endSector : 6; | ||||
|            /** High bits of end cylinder */ | ||||
|   unsigned endCylinderHigh : 2; | ||||
|           /** | ||||
|            * Combine endCylinderLow with endCylinderHigh. Legal values | ||||
|            * are 0-1023.  Only used in old PC BIOS. | ||||
|            */ | ||||
|   uint8_t  endCylinderLow; | ||||
|            /** Logical block address of the first block in the partition. */ | ||||
|   uint32_t firstSector; | ||||
|            /** Length of the partition, in blocks. */ | ||||
|   uint32_t totalSectors; | ||||
| }; | ||||
| /** Type name for partitionTable */ | ||||
| typedef struct partitionTable part_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * \struct masterBootRecord | ||||
|  * | ||||
|  * \brief Master Boot Record | ||||
|  * | ||||
|  * The first block of a storage device that is formatted with a MBR. | ||||
|  */ | ||||
| struct masterBootRecord { | ||||
|            /** Code Area for master boot program. */ | ||||
|   uint8_t  codeArea[440]; | ||||
|            /** Optional WindowsNT disk signature. May contain more boot code. */ | ||||
|   uint32_t diskSignature; | ||||
|            /** Usually zero but may be more boot code. */ | ||||
|   uint16_t usuallyZero; | ||||
|            /** Partition tables. */ | ||||
|   part_t   part[4]; | ||||
|            /** First MBR signature byte. Must be 0X55 */ | ||||
|   uint8_t  mbrSig0; | ||||
|            /** Second MBR signature byte. Must be 0XAA */ | ||||
|   uint8_t  mbrSig1; | ||||
| }; | ||||
| /** Type name for masterBootRecord */ | ||||
| typedef struct masterBootRecord mbr_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| /**  | ||||
|  * \struct biosParmBlock | ||||
|  * | ||||
|  * \brief BIOS parameter block | ||||
|  *  | ||||
|  *  The BIOS parameter block describes the physical layout of a FAT volume. | ||||
|  */ | ||||
| struct biosParmBlock { | ||||
|           /** | ||||
|            * Count of bytes per sector. This value may take on only the | ||||
|            * following values: 512, 1024, 2048 or 4096 | ||||
|            */ | ||||
|   uint16_t bytesPerSector; | ||||
|           /** | ||||
|            * Number of sectors per allocation unit. This value must be a | ||||
|            * power of 2 that is greater than 0. The legal values are | ||||
|            * 1, 2, 4, 8, 16, 32, 64, and 128. | ||||
|            */ | ||||
|   uint8_t  sectorsPerCluster; | ||||
|           /** | ||||
|            * Number of sectors before the first FAT. | ||||
|            * This value must not be zero. | ||||
|            */ | ||||
|   uint16_t reservedSectorCount; | ||||
|           /** The count of FAT data structures on the volume. This field should | ||||
|            *  always contain the value 2 for any FAT volume of any type. | ||||
|            */ | ||||
|   uint8_t  fatCount; | ||||
|           /** | ||||
|           * For FAT12 and FAT16 volumes, this field contains the count of | ||||
|           * 32-byte directory entries in the root directory. For FAT32 volumes, | ||||
|           * this field must be set to 0. For FAT12 and FAT16 volumes, this | ||||
|           * value should always specify a count that when multiplied by 32 | ||||
|           * results in a multiple of bytesPerSector.  FAT16 volumes should | ||||
|           * use the value 512. | ||||
|           */ | ||||
|   uint16_t rootDirEntryCount; | ||||
|           /** | ||||
|            * This field is the old 16-bit total count of sectors on the volume. | ||||
|            * This count includes the count of all sectors in all four regions | ||||
|            * of the volume. This field can be 0; if it is 0, then totalSectors32 | ||||
|            * must be non-zero.  For FAT32 volumes, this field must be 0. For | ||||
|            * FAT12 and FAT16 volumes, this field contains the sector count, and | ||||
|            * totalSectors32 is 0 if the total sector count fits | ||||
|            * (is less than 0x10000). | ||||
|            */ | ||||
|   uint16_t totalSectors16; | ||||
|           /** | ||||
|            * This dates back to the old MS-DOS 1.x media determination and is | ||||
|            * no longer usually used for anything.  0xF8 is the standard value | ||||
|            * for fixed (non-removable) media. For removable media, 0xF0 is | ||||
|            * frequently used. Legal values are 0xF0 or 0xF8-0xFF. | ||||
|            */ | ||||
|   uint8_t  mediaType; | ||||
|           /** | ||||
|            * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. | ||||
|            * On FAT32 volumes this field must be 0, and sectorsPerFat32 | ||||
|            * contains the FAT size count. | ||||
|            */ | ||||
|   uint16_t sectorsPerFat16; | ||||
|            /** Sectors per track for interrupt 0x13. Not used otherwise. */ | ||||
|   uint16_t sectorsPerTrtack; | ||||
|            /** Number of heads for interrupt 0x13.  Not used otherwise. */ | ||||
|   uint16_t headCount; | ||||
|           /** | ||||
|            * Count of hidden sectors preceding the partition that contains this | ||||
|            * FAT volume. This field is generally only relevant for media | ||||
|            *  visible on interrupt 0x13. | ||||
|            */ | ||||
|   uint32_t hidddenSectors; | ||||
|           /** | ||||
|            * This field is the new 32-bit total count of sectors on the volume. | ||||
|            * This count includes the count of all sectors in all four regions | ||||
|            * of the volume.  This field can be 0; if it is 0, then | ||||
|            * totalSectors16 must be non-zero. | ||||
|            */ | ||||
|   uint32_t totalSectors32; | ||||
|           /** | ||||
|            * Count of sectors occupied by one FAT on FAT32 volumes. | ||||
|            */ | ||||
|   uint32_t sectorsPerFat32; | ||||
|           /** | ||||
|            * This field is only defined for FAT32 media and does not exist on | ||||
|            * FAT12 and FAT16 media. | ||||
|            * Bits 0-3 -- Zero-based number of active FAT. | ||||
|            *             Only valid if mirroring is disabled. | ||||
|            * Bits 4-6 -- Reserved. | ||||
|            * Bit 7	-- 0 means the FAT is mirrored at runtime into all FATs. | ||||
| 	         *        -- 1 means only one FAT is active; it is the one referenced in bits 0-3. | ||||
|            * Bits 8-15 	-- Reserved. | ||||
|            */ | ||||
|   uint16_t fat32Flags; | ||||
|           /** | ||||
|            * FAT32 version. High byte is major revision number. | ||||
|            * Low byte is minor revision number. Only 0.0 define. | ||||
|            */ | ||||
|   uint16_t fat32Version; | ||||
|           /** | ||||
|            * Cluster number of the first cluster of the root directory for FAT32. | ||||
|            * This usually 2 but not required to be 2. | ||||
|            */ | ||||
|   uint32_t fat32RootCluster; | ||||
|           /** | ||||
|            * Sector number of FSINFO structure in the reserved area of the | ||||
|            * FAT32 volume. Usually 1. | ||||
|            */ | ||||
|   uint16_t fat32FSInfo; | ||||
|           /** | ||||
|            * If non-zero, indicates the sector number in the reserved area | ||||
|            * of the volume of a copy of the boot record. Usually 6. | ||||
|            * No value other than 6 is recommended. | ||||
|            */ | ||||
|   uint16_t fat32BackBootBlock; | ||||
|           /** | ||||
|            * Reserved for future expansion. Code that formats FAT32 volumes | ||||
|            * should always set all of the bytes of this field to 0. | ||||
|            */ | ||||
|   uint8_t  fat32Reserved[12]; | ||||
| }; | ||||
| /** Type name for biosParmBlock */ | ||||
| typedef struct biosParmBlock bpb_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * \struct fat32BootSector | ||||
|  * | ||||
|  * \brief Boot sector for a FAT16 or FAT32 volume. | ||||
|  *  | ||||
|  */   | ||||
| struct fat32BootSector { | ||||
|            /** X86 jmp to boot program */ | ||||
|   uint8_t  jmpToBootCode[3]; | ||||
|            /** informational only - don't depend on it */ | ||||
|   char     oemName[8]; | ||||
|            /** BIOS Parameter Block */ | ||||
|   bpb_t    bpb; | ||||
|            /** for int0x13 use value 0X80 for hard drive */ | ||||
|   uint8_t  driveNumber; | ||||
|            /** used by Windows NT - should be zero for FAT */ | ||||
|   uint8_t  reserved1; | ||||
|            /** 0X29 if next three fields are valid */ | ||||
|   uint8_t  bootSignature; | ||||
|            /** usually generated by combining date and time */ | ||||
|   uint32_t volumeSerialNumber; | ||||
|            /** should match volume label in root dir */ | ||||
|   char     volumeLabel[11]; | ||||
|            /** informational only - don't depend on it */ | ||||
|   char     fileSystemType[8]; | ||||
|            /** X86 boot code */ | ||||
|   uint8_t  bootCode[420]; | ||||
|            /** must be 0X55 */ | ||||
|   uint8_t  bootSectorSig0; | ||||
|            /** must be 0XAA */ | ||||
|   uint8_t  bootSectorSig1; | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| // End Of Chain values for FAT entries | ||||
| /** FAT16 end of chain value used by Microsoft. */ | ||||
| uint16_t const FAT16EOC = 0XFFFF; | ||||
| /** Minimum value for FAT16 EOC.  Use to test for EOC. */ | ||||
| uint16_t const FAT16EOC_MIN = 0XFFF8; | ||||
| /** FAT32 end of chain value used by Microsoft. */ | ||||
| uint32_t const FAT32EOC = 0X0FFFFFFF; | ||||
| /** Minimum value for FAT32 EOC.  Use to test for EOC. */ | ||||
| uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; | ||||
| /** Mask a for FAT32 entry. Entries are 28 bits. */ | ||||
| uint32_t const FAT32MASK = 0X0FFFFFFF; | ||||
|  | ||||
| /** Type name for fat32BootSector */ | ||||
| typedef struct fat32BootSector fbs_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * \struct directoryEntry | ||||
|  * \brief FAT short directory entry | ||||
|  * | ||||
|  * Short means short 8.3 name, not the entry size. | ||||
|  *   | ||||
|  * Date Format. A FAT directory entry date stamp is a 16-bit field that is  | ||||
|  * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the | ||||
|  * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the  | ||||
|  * 16-bit word): | ||||
|  *    | ||||
|  * Bits 9-15: Count of years from 1980, valid value range 0-127  | ||||
|  * inclusive (1980-2107). | ||||
|  *    | ||||
|  * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. | ||||
|  * | ||||
|  * Bits 0-4: Day of month, valid value range 1-31 inclusive. | ||||
|  * | ||||
|  * Time Format. A FAT directory entry time stamp is a 16-bit field that has | ||||
|  * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the  | ||||
|  * 16-bit word, bit 15 is the MSB of the 16-bit word). | ||||
|  *    | ||||
|  * Bits 11-15: Hours, valid value range 0-23 inclusive. | ||||
|  *  | ||||
|  * Bits 5-10: Minutes, valid value range 0-59 inclusive. | ||||
|  *       | ||||
|  * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). | ||||
|  *    | ||||
|  * The valid time range is from Midnight 00:00:00 to 23:59:58. | ||||
|  */ | ||||
| struct directoryEntry { | ||||
|            /** | ||||
|             * Short 8.3 name. | ||||
|             * The first eight bytes contain the file name with blank fill. | ||||
|             * The last three bytes contain the file extension with blank fill. | ||||
|             */ | ||||
|   uint8_t  name[11]; | ||||
|           /** Entry attributes. | ||||
|            * | ||||
|            * The upper two bits of the attribute byte are reserved and should | ||||
|            * always be set to 0 when a file is created and never modified or | ||||
|            * looked at after that.  See defines that begin with DIR_ATT_. | ||||
|            */ | ||||
|   uint8_t  attributes; | ||||
|           /** | ||||
|            * Reserved for use by Windows NT. Set value to 0 when a file is | ||||
|            * created and never modify or look at it after that. | ||||
|            */ | ||||
|   uint8_t  reservedNT; | ||||
|           /** | ||||
|            * The granularity of the seconds part of creationTime is 2 seconds | ||||
|            * so this field is a count of tenths of a second and its valid | ||||
|            * value range is 0-199 inclusive. (WHG note - seems to be hundredths) | ||||
|            */ | ||||
|   uint8_t  creationTimeTenths; | ||||
|            /** Time file was created. */ | ||||
|   uint16_t creationTime; | ||||
|            /** Date file was created. */ | ||||
|   uint16_t creationDate; | ||||
|           /** | ||||
|            * Last access date. Note that there is no last access time, only | ||||
|            * a date.  This is the date of last read or write. In the case of | ||||
|            * a write, this should be set to the same date as lastWriteDate. | ||||
|            */ | ||||
|   uint16_t lastAccessDate; | ||||
|           /** | ||||
|            * High word of this entry's first cluster number (always 0 for a | ||||
|            * FAT12 or FAT16 volume). | ||||
|            */ | ||||
|   uint16_t firstClusterHigh; | ||||
|            /** Time of last write. File creation is considered a write. */ | ||||
|   uint16_t lastWriteTime; | ||||
|            /** Date of last write. File creation is considered a write. */ | ||||
|   uint16_t lastWriteDate; | ||||
|            /** Low word of this entry's first cluster number. */ | ||||
|   uint16_t firstClusterLow; | ||||
|            /** 32-bit unsigned holding this file's size in bytes. */ | ||||
|   uint32_t fileSize; | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| // Definitions for directory entries | ||||
| // | ||||
| /** Type name for directoryEntry */ | ||||
| typedef struct directoryEntry dir_t; | ||||
| /** escape for name[0] = 0XE5 */ | ||||
| uint8_t const DIR_NAME_0XE5 = 0X05; | ||||
| /** name[0] value for entry that is free after being "deleted" */ | ||||
| uint8_t const DIR_NAME_DELETED = 0XE5; | ||||
| /** name[0] value for entry that is free and no allocated entries follow */ | ||||
| uint8_t const DIR_NAME_FREE = 0X00; | ||||
| /** file is read-only */ | ||||
| uint8_t const DIR_ATT_READ_ONLY = 0X01; | ||||
| /** File should hidden in directory listings */ | ||||
| uint8_t const DIR_ATT_HIDDEN = 0X02; | ||||
| /** Entry is for a system file */ | ||||
| uint8_t const DIR_ATT_SYSTEM = 0X04; | ||||
| /** Directory entry contains the volume label */ | ||||
| uint8_t const DIR_ATT_VOLUME_ID = 0X08; | ||||
| /** Entry is for a directory */ | ||||
| uint8_t const DIR_ATT_DIRECTORY = 0X10; | ||||
| /** Old DOS archive bit for backup support */ | ||||
| uint8_t const DIR_ATT_ARCHIVE = 0X20; | ||||
| /** Test value for long name entry.  Test is | ||||
|   (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ | ||||
| uint8_t const DIR_ATT_LONG_NAME = 0X0F; | ||||
| /** Test mask for long name entry */ | ||||
| uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; | ||||
| /** defined attribute bits */ | ||||
| uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; | ||||
| /** Directory entry is part of a long name */ | ||||
| static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { | ||||
|   return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; | ||||
| } | ||||
| /** Mask for file/subdirectory tests */ | ||||
| uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); | ||||
| /** Directory entry is for a file */ | ||||
| static inline uint8_t DIR_IS_FILE(const dir_t* dir) { | ||||
|   return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; | ||||
| } | ||||
| /** Directory entry is for a subdirectory */ | ||||
| static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { | ||||
|   return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; | ||||
| } | ||||
| /** Directory entry is for a file or subdirectory */ | ||||
| static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { | ||||
|   return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; | ||||
| } | ||||
| #endif  // FatStructs_h | ||||
|   | ||||
							
								
								
									
										508
									
								
								Marlin/Makefile
									
									
									
									
									
								
							
							
						
						
									
										508
									
								
								Marlin/Makefile
									
									
									
									
									
								
							| @@ -1,274 +1,320 @@ | ||||
| TARGET = $(notdir $(CURDIR)) | ||||
| # CHANGE BELOW: | ||||
| #~ INSTALL_DIR = /Applications/Arduino.app/Contents/Resources/Java | ||||
| INSTALL_DIR = /home/bkubicek/software/arduino-0022 | ||||
| #~ PORT = /dev/cu.usbserial* | ||||
| PORT = /dev/ttyACM0 | ||||
|  | ||||
| # Get these values from: | ||||
| #     $(INSTALL_DIR)/hardware/boards.txt | ||||
| #     (arduino-0022/hardware/arduino/boards.txt) | ||||
| # The values below are for the "Arduino Duemilanove or Nano w/ ATmega328" | ||||
| # now for "Arduino Mega 2560" | ||||
| UPLOAD_SPEED = 115200 | ||||
| UPLOAD_PROTOCOL = stk500v2 | ||||
| BUILD_MCU = atmega2560 | ||||
| BUILD_F_CPU = 16000000L | ||||
|  | ||||
| # getting undefined reference to `__cxa_pure_virtual' | ||||
| #~ [http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1254180518 Arduino Forum - Makefile] | ||||
| #~ http://www.arduino.cc/playground/OpenBSD/CLI | ||||
| #~ [http://arduino.cc/forum/index.php?topic=52041.0 A "simple" makefile for Arduino] | ||||
| #~ [http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1275488191 Arduino Forum - Configuring avr-gcc options in arduino IDE] | ||||
| # found in /usr/lib/gcc/avr/4.3.5/cc1plus; fixed with -Wl,--gc-section | ||||
|  | ||||
| ############################################################################ | ||||
| # Below here nothing should be changed... | ||||
|  | ||||
| ARDUINO = $(INSTALL_DIR)/hardware/arduino/cores/arduino | ||||
| # | ||||
| # Arduino 0022 Makefile  | ||||
| # Uno with DOGS102 Shield | ||||
| # | ||||
| # written by olikraus@gmail.com | ||||
| # | ||||
| # Features: | ||||
| #   - boards.txt is used to derive parameters | ||||
| #   - All intermediate files are put into a separate directory (TMPDIRNAME) | ||||
| #   - Simple use: Copy Makefile into the same directory of the .pde file | ||||
| # | ||||
| # Limitations: | ||||
| #   - requires UNIX environment | ||||
| #   - TMPDIRNAME must be subdirectory of the current directory. | ||||
| # | ||||
| # Targets | ||||
| # 	all		build everything | ||||
| #	upload	build and upload to arduino | ||||
| #	clean	remove all temporary files (includes final hex file) | ||||
| # | ||||
| # History | ||||
| #	001	28 Apr 2010	first  release | ||||
| #	002  05 Oct 2010	added 'uno' | ||||
| #~ AVR_TOOLS_PATH = $(INSTALL_DIR)/hardware/tools/avr/bin | ||||
| # in Ubuntu, avr-gcc is installed separate; | ||||
| # only avrdude comes with the IDE | ||||
| AVR_TOOLS_PATH = /usr/bin | ||||
| AVR_DUDE_PATH = $(INSTALL_DIR)/hardware/tools | ||||
| # | ||||
| SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \ | ||||
|     $(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \ | ||||
|     $(ARDUINO)/wiring_pulse.c \ | ||||
|     $(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c | ||||
| # added applet/$(TARGET).cpp as in IDE 0022 | ||||
| CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WMath.cpp \ | ||||
|     $(ARDUINO)/Print.cpp \ | ||||
|     $(ARDUINO)/main.cpp | ||||
| #    applet/$(TARGET).cpp # no need, having a rule now for applet/$(TARGET).cpp.o | ||||
| # added main.cpp, as in 0022 | ||||
| FORMAT = ihex | ||||
|  | ||||
| #=== user configuration === | ||||
| # All ...PATH variables must have a '/' at the end | ||||
| # Name of this Makefile (used for "make depend"). | ||||
| MAKEFILE = Makefile | ||||
|  | ||||
| # Board (and prozessor) information: see $(ARDUINO_PATH)hardware/arduino/boards.txt | ||||
| # Some examples: | ||||
| #	BOARD		DESCRIPTION | ||||
| #	uno			Arduino Uno | ||||
| #	atmega328	Arduino Duemilanove or Nano w/ ATmega328 | ||||
| #	diecimila		Arduino Diecimila, Duemilanove, or Nano w/ ATmega168 | ||||
| #	mega		Arduino Mega | ||||
| #	mini			Arduino Mini | ||||
| #	lilypad328	LilyPad Arduino w/ ATmega328   | ||||
| BOARD:=mega | ||||
| # Debugging format. | ||||
| # Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. | ||||
| # AVR (extended) COFF requires stabs, plus an avr-objcopy run. | ||||
| DEBUG = stabs | ||||
|  | ||||
| # additional (comma separated) defines  | ||||
| # -DDOGM128_HW		board is connected to DOGM128 display | ||||
| # -DDOGM132_HW		board is connected to DOGM132 display | ||||
| # -DDOGS102_HW		board is connected to DOGS102 display | ||||
| # -DDOG_REVERSE		180 degree rotation | ||||
| # -DDOG_SPI_SW_ARDUINO	force SW shiftOut | ||||
| DEFS=-DDOGS102_HW -DDOG_DOUBLE_MEMORY -DDOG_SPI_SW_ARDUINO | ||||
| OPT = 2 | ||||
|  | ||||
| # The location where the avr tools (e.g. avr-gcc) are located. Requires a '/' at the end. | ||||
| # Can be empty if all tools are accessable through the search path | ||||
| AVR_TOOLS_PATH:=/usr/bin/ | ||||
| # Place -D or -U options here | ||||
| #~ CDEFS = -DBUILD_F_CPU=$(BUILD_F_CPU) | ||||
| #~ CXXDEFS = -DBUILD_F_CPU=$(BUILD_F_CPU) | ||||
| # now called DF_CPU | ||||
| CDEFS = -DF_CPU=$(BUILD_F_CPU) -DARDUINO=22 | ||||
| CXXDEFS = -DF_CPU=$(BUILD_F_CPU) -DARDUINO=22 | ||||
|  | ||||
| # Install path of the arduino software. Requires a '/' at the end. | ||||
| ARDUINO_PATH:=/home/bkubicek/software/arduino-0022/ | ||||
| # Place -I options here | ||||
| CINCS = -I$(ARDUINO) -I$(INSTALL_DIR)/libraries/LiquidCrystal/ -I$(INSTALL_DIR)/libraries/EEPROM/ | ||||
| CXXINCS = -I$(ARDUINO) | ||||
|  | ||||
| # Install path for avrdude. Requires a '/' at the end. Can be empty if avrdude is in the search path. | ||||
| AVRDUDE_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=gnu99 | ||||
| CDEBUG = -g$(DEBUG) | ||||
| # note that typically, IDE 0022 uses -w to suppress warnings (both in cpp and c)! | ||||
| CWARN = -Wall | ||||
| #~ CWARN = -w | ||||
| #  "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++: | ||||
| CCWARN = -Wstrict-prototypes | ||||
| CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums | ||||
| #CEXTRA = -Wa,-adhlns=$(<:.c=.lst) | ||||
|  | ||||
| # The unix device where we can reach the arduino board | ||||
| # Uno: /dev/ttyACM0 | ||||
| # Duemilanove: /dev/ttyUSB0 | ||||
| AVRDUDE_PORT:=/dev/ttyACM0 | ||||
| # to eliminate pins_ardiuno warnings: | ||||
| # http://arduino.cc/pipermail/developers_arduino.cc/2010-December/004005.html | ||||
|  | ||||
| # List of all libaries which should be included. | ||||
| #EXTRA_DIRS=$(ARDUINO_PATH)libraries/LiquidCrystal/ | ||||
| #EXTRA_DIRS+=$(ARDUINO_PATH)libraries/Dogm/ | ||||
| #EXTRA_DIRS+=/home/kraus/src/arduino/dogm128/hg/libraries/Dogm/ | ||||
| # [http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1254180518 Arduino Forum - Makefile] | ||||
| #~ For building the objects files "-ffunction-sections -fdata-sections" was missing | ||||
| #~ and the final avr-gcc call needs "-Wl,--gc-section". | ||||
| CXSECTF = -fno-exceptions -ffunction-sections -fdata-sections | ||||
| CFINALF = -Wl,--gc-section | ||||
|  | ||||
| #=== fetch parameter from boards.txt processor parameter === | ||||
| # the basic idea is to get most of the information from boards.txt | ||||
| CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CCWARN) $(CSTANDARD) $(CEXTRA) | ||||
| # added CWARN also to .cpp | ||||
| CXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CXSECTF) | ||||
| #ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs | ||||
| LDFLAGS = -lm | ||||
|  | ||||
| BOARDS_TXT:=$(ARDUINO_PATH)hardware/arduino/boards.txt | ||||
| # Programming support using avrdude. Settings and variables. | ||||
| AVRDUDE_PORT = $(PORT) | ||||
| AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex | ||||
| AVRDUDE_FLAGS = -V -F \ | ||||
|     -p $(BUILD_MCU) -P $(AVRDUDE_PORT) -c $(UPLOAD_PROTOCOL) \ | ||||
|     -b $(UPLOAD_SPEED) -C $(INSTALL_DIR)/hardware/tools/avrdude.conf | ||||
| #    -b $(UPLOAD_SPEED) -C $(INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf | ||||
|  | ||||
| # get the MCU value from the $(BOARD).build.mcu variable. For the atmega328 board this is atmega328p | ||||
| MCU:=$(shell sed -n -e "s/$(BOARD).build.mcu=\(.*\)/\1/p" $(BOARDS_TXT)) | ||||
| # get the F_CPU value from the $(BOARD).build.f_cpu variable. For the atmega328 board this is 16000000 | ||||
| F_CPU:=$(shell sed -n -e "s/$(BOARD).build.f_cpu=\(.*\)/\1/p" $(BOARDS_TXT)) | ||||
| # Program settings | ||||
| CC = $(AVR_TOOLS_PATH)/avr-gcc | ||||
| CXX = $(AVR_TOOLS_PATH)/avr-g++ | ||||
| OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy | ||||
| OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump | ||||
| AR = $(AVR_TOOLS_PATH)/avr-ar | ||||
| SIZE = $(AVR_TOOLS_PATH)/avr-size | ||||
| NM = $(AVR_TOOLS_PATH)/avr-nm | ||||
| #~ AVRDUDE = $(AVR_TOOLS_PATH)/avrdude | ||||
| AVRDUDE = $(AVR_DUDE_PATH)/avrdude | ||||
| REMOVE = rm -f | ||||
| MV = mv -f | ||||
|  | ||||
| # avrdude | ||||
| # get the AVRDUDE_UPLOAD_RATE value from the $(BOARD).upload.speed variable. For the atmega328 board this is 57600 | ||||
| AVRDUDE_UPLOAD_RATE:=$(shell sed -n -e "s/$(BOARD).upload.speed=\(.*\)/\1/p" $(BOARDS_TXT)) | ||||
| # get the AVRDUDE_PROGRAMMER value from the $(BOARD).upload.protocol variable. For the atmega328 board this is stk500 | ||||
| # AVRDUDE_PROGRAMMER:=$(shell sed -n -e "s/$(BOARD).upload.protocol=\(.*\)/\1/p" $(BOARDS_TXT)) | ||||
| # use stk500v1, because stk500 will default to stk500v2 | ||||
| AVRDUDE_PROGRAMMER:=stk500v1 | ||||
| # Define all object files. | ||||
| # NOTE: obj files will be created in respective src directories (libraries or $(INSTALL_DIR)); | ||||
| #  make clean deletes them fine | ||||
| # note that srcs are in libraries or other directories; | ||||
| # $(CXXSRC:.cpp=.o) will cause obj files to be in same loc as src files | ||||
| #~ OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) | ||||
| # to change the output directory for object files; | ||||
| # must change the obj list here! | ||||
| # and then, match to corresponding rule somehow? | ||||
| # or leave this - and parse in rule (auth automatic variable $(@F))? | ||||
| # "Suffix Replacement" | ||||
| OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) | ||||
|  | ||||
| #=== identify user files === | ||||
| PDESRC:=$(shell ls *.pde) | ||||
| TARGETNAME=$(basename $(PDESRC)) | ||||
| # added - OBJ list, transformed into applet/ | ||||
| OBJT = $(addprefix applet/,$(notdir $(OBJ))) | ||||
| ALLSRC = $(SRC) $(CXXSRC) $(ASRC) | ||||
|  | ||||
| CDIRS:=$(EXTRA_DIRS) $(addsuffix utility/,$(EXTRA_DIRS)) | ||||
| CDIRS:=*.c utility/*.c $(addsuffix *.c,$(CDIRS)) $(ARDUINO_PATH)hardware/arduino/cores/arduino/*.c | ||||
| CSRC:=$(shell ls $(CDIRS) 2>/dev/null) | ||||
| # Define all listing files. | ||||
| LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) | ||||
|  | ||||
| CCSRC:=$(shell ls *.cc 2>/dev/null) | ||||
| # Combine all necessary flags and optional flags. | ||||
| # Add target processor to flags. | ||||
| ALL_CFLAGS = -mmcu=$(BUILD_MCU) -I. $(CFLAGS) | ||||
| ALL_CXXFLAGS = -mmcu=$(BUILD_MCU) -I. $(CXXFLAGS) | ||||
| ALL_ASFLAGS = -mmcu=$(BUILD_MCU) -I. -x assembler-with-cpp $(ASFLAGS) | ||||
|  | ||||
| CPPDIRS:=$(EXTRA_DIRS) $(addsuffix utility/,$(EXTRA_DIRS)) | ||||
| CPPDIRS:=*.cpp utility/*.cpp $(addsuffix *.cpp,$(CPPDIRS)) $(ARDUINO_PATH)hardware/arduino/cores/arduino/*.cpp  | ||||
| CPPSRC:=$(shell ls $(CPPDIRS) 2>/dev/null) | ||||
| # depended libraries of .pde need to be added from | ||||
| # $(INSTALL_DIR)/libraries (TODO: and/or ~/sketchbook/libraries) | ||||
| # grep for 'include', test if exists, add... | ||||
| # note: prefix "a real tab character" http://www.delorie.com/djgpp/doc/ug/larger/makefiles.html | ||||
| # $$ to escape $ for shell; | ||||
| # note: must NOT put comments # inside bash execution; | ||||
| # those would get removed by make; making shell see "EOF in backquote substitution" | ||||
| #		 echo $$ix ; \ | ||||
| # 'shell' twice - for each subprocess! Backtick doesn't get expanded? | ||||
| GREPRES:=$(shell for ix in $(shell grep include $(TARGET).pde | sed 's/.*[<"]\(.*\).h[>"].*/\1/'); do \ | ||||
| 		if [ -d $(INSTALL_DIR)/libraries/$$ix ] ; then \ | ||||
| 			LINCS="$$LINCS -I$(INSTALL_DIR)/libraries/$$ix" ;\ | ||||
| 		fi; \ | ||||
| 	done; \ | ||||
| 	echo $$LINCS) | ||||
| # append includes: | ||||
| CINCS += $(GREPRES) | ||||
| CXXINCS += $(GREPRES) | ||||
| # append library source .cpp files too (CXXSRC) | ||||
| GREPRESB:=$(shell for ix in $(shell grep include $(TARGET).pde | sed 's/.*[<"]\(.*\).h[>"].*/\1/'); do \ | ||||
| 		if [ -d $(INSTALL_DIR)/libraries/$$ix ] ; then \ | ||||
| 			CPPSRCS="$$CPPSRCS $(INSTALL_DIR)/libraries/$$ix/*.cpp" ;\ | ||||
| 		fi; \ | ||||
| 	done; \ | ||||
| 	echo $$CPPSRCS) | ||||
| CXXSRC += $(GREPRESB) | ||||
| # added - only CXX obj from libraries: | ||||
| CXXLIBOBJ = $(GREPRESB:.cpp=.o) | ||||
|  | ||||
| #=== build internal variables === | ||||
| # Default target. | ||||
| all: applet_files build sizeafter | ||||
|  | ||||
| # the name of the subdirectory where everything is stored | ||||
| TMPDIRNAME:=tmp | ||||
| TMPDIRPATH:=$(TMPDIRNAME)/ | ||||
| build: elf hex | ||||
|  | ||||
| AVRTOOLSPATH:=$(AVR_TOOLS_PATH) | ||||
|  | ||||
| OBJCOPY:=$(AVRTOOLSPATH)avr-objcopy | ||||
| OBJDUMP:=$(AVRTOOLSPATH)avr-objdump | ||||
| SIZE:=$(AVRTOOLSPATH)avr-size | ||||
|  | ||||
| CPPSRC:=$(addprefix $(TMPDIRPATH),$(PDESRC:.pde=.cpp)) $(CPPSRC) | ||||
|  | ||||
| COBJ:=$(CSRC:.c=.o) | ||||
| CCOBJ:=$(CCSRC:.cc=.o) | ||||
| CPPOBJ:=$(CPPSRC:.cpp=.o) | ||||
|  | ||||
| OBJFILES:=$(COBJ)  $(CCOBJ)  $(CPPOBJ) | ||||
| DIRS:= $(dir $(OBJFILES)) | ||||
|  | ||||
| DEPFILES:=$(OBJFILES:.o=.d) | ||||
| # assembler files from avr-gcc -S | ||||
| ASSFILES:=$(OBJFILES:.o=.s) | ||||
| # disassembled object files with avr-objdump -S | ||||
| DISFILES:=$(OBJFILES:.o=.dis) | ||||
| applet_files: $(TARGET).pde | ||||
|     # Here is the "preprocessing". | ||||
|     # It creates a .cpp file based with the same name as the .pde file. | ||||
|     # On top of the new .cpp file comes the WProgram.h header. | ||||
|     # At the end there is a generic main() function attached. | ||||
|     # Then the .cpp file will be compiled. Errors during compile will | ||||
|     # refer to this new, automatically generated, file. | ||||
|     # Not the original .pde file you actually edit... | ||||
| 	test -d applet || mkdir applet | ||||
|     # @ supresses printout of the cmdline itself; so only the out of echo is printed | ||||
| 	@echo ALL OBJT: $(OBJT) | ||||
| 	@echo ALL CXXLIBOBJ: $(CXXLIBOBJ) | ||||
| #	echo '#include "WProgram.h"' > applet/$(TARGET).cpp | ||||
| 	@echo "#include \"WProgram.h\"\nvoid setup();\nvoid loop();\n" > applet/$(TARGET).cpp | ||||
| 	cat $(TARGET).pde >> applet/$(TARGET).cpp | ||||
|     # no more need to cat main.cpp (v0022) - now it is compiled in | ||||
| #	cat $(ARDUINO)/main.cpp >> applet/$(TARGET).cpp | ||||
|  | ||||
|  | ||||
| LIBNAME:=$(TMPDIRPATH)$(TARGETNAME).a | ||||
| ELFNAME:=$(TMPDIRPATH)$(TARGETNAME).elf | ||||
| HEXNAME:=$(TMPDIRPATH)$(TARGETNAME).hex | ||||
| elf: applet/$(TARGET).elf | ||||
| hex: applet/$(TARGET).hex | ||||
| eep: applet/$(TARGET).eep | ||||
| lss: applet/$(TARGET).lss | ||||
| sym: applet/$(TARGET).sym | ||||
|  | ||||
| AVRDUDE_FLAGS = -V -F | ||||
| AVRDUDE_FLAGS += -C $(ARDUINO_PATH)/hardware/tools/avrdude.conf  | ||||
| AVRDUDE_FLAGS += -p $(MCU) | ||||
| AVRDUDE_FLAGS += -P $(AVRDUDE_PORT) | ||||
| AVRDUDE_FLAGS += -c $(AVRDUDE_PROGRAMMER)  | ||||
| AVRDUDE_FLAGS += -b $(AVRDUDE_UPLOAD_RATE) | ||||
| AVRDUDE_FLAGS += -U flash:w:$(HEXNAME) | ||||
| # Program the device. | ||||
| upload: applet/$(TARGET).hex | ||||
| 	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) | ||||
|  | ||||
| AVRDUDE = avrdude | ||||
| # Display size of file. | ||||
| HEXSIZE = $(SIZE) --target=$(FORMAT) applet/$(TARGET).hex | ||||
| ELFSIZE = $(SIZE) applet/$(TARGET).elf | ||||
| sizebefore: | ||||
| 	@if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi | ||||
|  | ||||
| #=== predefined variable override === | ||||
| # use "make -p -f/dev/null" to see the default rules and definitions | ||||
| sizeafter: | ||||
| 	@if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(HEXSIZE); echo; fi | ||||
|  | ||||
| # Build C and C++ flags. Include path information must be placed here | ||||
| COMMON_FLAGS = -DF_CPU=$(F_CPU) -mmcu=$(MCU) $(DEFS) | ||||
| # COMMON_FLAGS += -gdwarf-2 | ||||
| COMMON_FLAGS += -Os | ||||
| COMMON_FLAGS += -Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums | ||||
| COMMON_FLAGS += -I.  | ||||
| COMMON_FLAGS += -I$(ARDUINO_PATH)hardware/arduino/cores/arduino | ||||
| COMMON_FLAGS += $(addprefix -I,$(EXTRA_DIRS)) | ||||
| COMMON_FLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections | ||||
| COMMON_FLAGS += -Wl,--relax | ||||
| COMMON_FLAGS += -mcall-prologues | ||||
| # Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. | ||||
| COFFCONVERT=$(OBJCOPY) --debugging \ | ||||
|     --change-section-address .data-0x800000 \ | ||||
|     --change-section-address .bss-0x800000 \ | ||||
|     --change-section-address .noinit-0x800000 \ | ||||
|     --change-section-address .eeprom-0x810000 | ||||
|  | ||||
| CFLAGS = $(COMMON_FLAGS) -std=gnu99 -Wstrict-prototypes   | ||||
| CXXFLAGS = $(COMMON_FLAGS)  | ||||
| coff: applet/$(TARGET).elf | ||||
| 	$(COFFCONVERT) -O coff-avr applet/$(TARGET).elf $(TARGET).cof | ||||
|  | ||||
| # Replace standard build tools by avr tools | ||||
| CC = $(AVRTOOLSPATH)avr-gcc | ||||
| CXX = $(AVRTOOLSPATH)avr-g++ | ||||
| AR  = @$(AVRTOOLSPATH)avr-ar | ||||
| extcoff: $(TARGET).elf | ||||
| 	$(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf $(TARGET).cof | ||||
|  | ||||
|  | ||||
| # "rm" must be able to delete a directory tree | ||||
| RM = rm -rf  | ||||
|  | ||||
| #=== rules === | ||||
|  | ||||
| # add rules for the C/C++ files where the .o file is placed in the TMPDIRPATH | ||||
| # reuse existing variables as far as possible | ||||
|  | ||||
| $(TMPDIRPATH)%.o: %.c | ||||
| 	@echo compile $< | ||||
| 	@$(COMPILE.c) $(OUTPUT_OPTION) $< | ||||
|  | ||||
| $(TMPDIRPATH)%.o: %.cc | ||||
| 	@echo compile $<  | ||||
| 	@$(COMPILE.cc) $(OUTPUT_OPTION) $< | ||||
|  | ||||
| $(TMPDIRPATH)%.o: %.cpp | ||||
| 	@echo compile $< | ||||
| 	@$(COMPILE.cpp) $(OUTPUT_OPTION) $< | ||||
|  | ||||
| $(TMPDIRPATH)%.s: %.c | ||||
| 	@$(COMPILE.c) $(OUTPUT_OPTION) -S $< | ||||
|  | ||||
| $(TMPDIRPATH)%.s: %.cc | ||||
| 	@$(COMPILE.cc) $(OUTPUT_OPTION) -S $< | ||||
|  | ||||
| $(TMPDIRPATH)%.s: %.cpp | ||||
| 	@$(COMPILE.cpp) $(OUTPUT_OPTION) -S $< | ||||
|  | ||||
| $(TMPDIRPATH)%.dis: $(TMPDIRPATH)%.o | ||||
| 	@$(OBJDUMP) -S $< > $@ | ||||
|  | ||||
| .SUFFIXES: .elf .hex .pde | ||||
| .SUFFIXES: .elf .hex .eep .lss .sym | ||||
|  | ||||
| .elf.hex: | ||||
| 	@$(OBJCOPY) -O ihex -R .eeprom $< $@ | ||||
| 	 | ||||
| $(TMPDIRPATH)%.cpp: %.pde | ||||
| 	@cat $(ARDUINO_PATH)hardware/arduino/cores/arduino/main.cpp > $@ | ||||
| 	@cat $< >> $@ | ||||
| 	@echo >> $@ | ||||
| 	@echo 'extern "C" void __cxa_pure_virtual() { while (1); }' >> $@ | ||||
| 	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ | ||||
|  | ||||
| .elf.eep: | ||||
|     -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ | ||||
|     --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ | ||||
|  | ||||
| .PHONY: all | ||||
| all: tmpdir $(HEXNAME) assemblersource showsize | ||||
| 	ls -al $(HEXNAME) $(ELFNAME) | ||||
| # Create extended listing file from ELF output file. | ||||
| .elf.lss: | ||||
| 	$(OBJDUMP) -h -S $< > $@ | ||||
|  | ||||
| $(ELFNAME): $(LIBNAME)($(addprefix $(TMPDIRPATH),$(OBJFILES)))  | ||||
| 	$(LINK.o) $(COMMON_FLAGS) $(LIBNAME) $(LOADLIBES) $(LDLIBS) -o $@ | ||||
| # Create a symbol table from ELF output file. | ||||
| .elf.sym: | ||||
| 	$(NM) -n $< > $@ | ||||
|  | ||||
| $(LIBNAME)(): $(addprefix $(TMPDIRPATH),$(OBJFILES)) | ||||
| # Link: create ELF output file from library. | ||||
| # NOTE: applet/$(TARGET).cpp.o MUST BE BEFORE applet/core.a | ||||
| #  in the dependency list, so its rule runs first! | ||||
| applet/$(TARGET).elf: $(TARGET).pde applet/$(TARGET).cpp.o applet/core.a | ||||
| #	$(CC) $(ALL_CFLAGS) -o $@ applet/$(TARGET).cpp -L. applet/core.a $(LDFLAGS) | ||||
| # changed as in IDE v0022: link cpp obj files | ||||
| 	@echo $$(tput bold)$$(tput setaf 2) $(CC) $$(tput sgr0) $(ALL_CFLAGS) $(CFINALF) -o $@ applet/$(TARGET).cpp.o $(CXXOBJ) -L. applet/core.a $(LDFLAGS) | ||||
| 	@$(CC) $(ALL_CFLAGS) $(CFINALF) -o $@ applet/$(TARGET).cpp.o $(CXXOBJ) -L. applet/core.a $(LDFLAGS) | ||||
|  | ||||
| #=== create temp directory === | ||||
| # not really required, because it will be also created during the dependency handling | ||||
| .PHONY: tmpdir | ||||
| tmpdir: | ||||
| 	@test -d $(TMPDIRPATH) || mkdir $(TMPDIRPATH) | ||||
| # added: cpp.o depends on cpp (and .pde which generates it) | ||||
| # $< "first item in the dependencies list"; $@ "left side of the :"; $^ "right side of the :" | ||||
| # http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/ | ||||
| applet/$(TARGET).cpp.o: applet/$(TARGET).cpp | ||||
| 	@echo $$(tput bold) $(CXX) $$(tput sgr0) -c $(ALL_CXXFLAGS) $< -o $@ | ||||
| 	@$(CXX) -c $(ALL_CXXFLAGS) $< -o $@ | ||||
|  | ||||
| #=== create assembler files for each C/C++ file === | ||||
| .PHONY: assemblersource | ||||
| assemblersource: $(addprefix $(TMPDIRPATH),$(ASSFILES)) $(addprefix $(TMPDIRPATH),$(DISFILES)) | ||||
| #~ applet/core.a: $(OBJ) | ||||
| #~	 @for i in $(OBJ); do echo $(AR) rcs applet/core.a $$i; $(AR) rcs applet/core.a $$i; done | ||||
|  | ||||
| applet/core.a: $(OBJT) | ||||
| 	 @for i in $(OBJT); do echo $(AR) rcs applet/core.a $$i; $(AR) rcs applet/core.a $$i; done | ||||
|  | ||||
| #=== show the section sizes of the ELF file === | ||||
| .PHONY: showsize | ||||
| showsize: $(ELFNAME) | ||||
| 	$(SIZE) $< | ||||
| # iterate through OBJ to find the original location; then build depending on source extension | ||||
| # TODO: add handling of assembler files | ||||
| applet/%.o: | ||||
| 	@for iob in $(OBJ); do \ | ||||
| 		if [ "`basename $$iob`" = "`basename $@`" ]; then \ | ||||
| 			for ios in $(ALLSRC); do \ | ||||
| 				if [ "$${iob%%.*}" = "$${ios%%.*}" ]; then \ | ||||
| 					case $${ios##*.} in \ | ||||
| 						"cpp") \ | ||||
| 							echo "$$(tput bold)$$(tput setaf 1) $(CXX) $$(tput sgr0) -c $(ALL_CXXFLAGS) $$ios -o $@"; \ | ||||
| 							$(CXX) -c $(ALL_CXXFLAGS) $$ios -o $@;; \ | ||||
| 						"c") \ | ||||
| 							echo "$$(tput bold)$$(tput setaf 1) $(CC) $$(tput sgr0) -c $(ALL_CFLAGS) $$ios -o $@"; \ | ||||
| 							$(CC) -c $(ALL_CFLAGS) $$ios -o $@;; \ | ||||
| 					esac; \ | ||||
| 				fi; \ | ||||
| 			done; \ | ||||
| 		fi; \ | ||||
| 	done; | ||||
|  | ||||
| #=== clean up target === | ||||
| # this is simple: the TMPDIRPATH is removed | ||||
| .PHONY: clean | ||||
| #~ # Compile: create object files from C++ source files. | ||||
| #~ .cpp.o: | ||||
| #~	 $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ | ||||
|  | ||||
| #~ # Compile: create object files from C source files. | ||||
| #~ .c.o: | ||||
| #~	 $(CC) -c $(ALL_CFLAGS) $< -o $@ | ||||
|  | ||||
| #~ # Compile: create assembler files from C source files. | ||||
| #~ .c.s: | ||||
| #~	 $(CC) -S $(ALL_CFLAGS) $< -o $@ | ||||
|  | ||||
| #~ # Assemble: create object files from assembler source files. | ||||
| #~ .S.o: | ||||
| #~	 $(CC) -c $(ALL_ASFLAGS) $< -o $@ | ||||
|  | ||||
| #~ # Automatic dependencies | ||||
| #~ %.d: %.c | ||||
| #~	 $(CC) -M $(ALL_CFLAGS) $< | sed "s;$(notdir $*).o:;$*.o $*.d:;" > $@ | ||||
|  | ||||
| #~ %.d: %.cpp | ||||
| #~	 $(CXX) -M $(ALL_CXXFLAGS) $< | sed "s;$(notdir $*).o:;$*.o $*.d:;" > $@ | ||||
|  | ||||
| # Target: clean project. | ||||
| clean: | ||||
| 	$(RM) $(TMPDIRPATH) | ||||
|  | ||||
| # Program the device.   | ||||
| # step 1: reset the arduino board with the stty command | ||||
| # step 2: user avrdude to upload the software | ||||
| .PHONY: upload | ||||
| upload: $(HEXNAME) | ||||
| 	stty -F $(AVRDUDE_PORT) hupcl | ||||
| 	$(AVRDUDE) $(AVRDUDE_FLAGS) | ||||
|  | ||||
|  | ||||
| # === dependency handling === | ||||
| # From the gnu make manual (section 4.14, Generating Prerequisites Automatically) | ||||
| # Additionally (because this will be the first executed rule) TMPDIRPATH is created here. | ||||
| # Instead of "sed" the "echo" command is used | ||||
| # cd $(TMPDIRPATH); mkdir -p $(DIRS) 2> /dev/null; cd .. | ||||
| DEPACTION=test -d $(TMPDIRPATH) || mkdir $(TMPDIRPATH);\ | ||||
| mkdir -p $(addprefix $(TMPDIRPATH),$(DIRS));\ | ||||
| set -e; echo -n $@ $(dir $@) > $@; $(CC) -MM $(COMMON_FLAGS) $< >> $@ | ||||
|  | ||||
|  | ||||
| $(TMPDIRPATH)%.d: %.c | ||||
| 	@$(DEPACTION) | ||||
|  | ||||
| $(TMPDIRPATH)%.d: %.cc | ||||
| 	@$(DEPACTION) | ||||
|  | ||||
|  | ||||
| $(TMPDIRPATH)%.d: %.cpp | ||||
| 	@$(DEPACTION) | ||||
|  | ||||
| # Include dependency files. If a .d file is missing, a warning is created and the .d file is created | ||||
| # This warning is not a problem (gnu make manual, section 3.3 Including Other Makefiles) | ||||
| -include $(addprefix $(TMPDIRPATH),$(DEPFILES)) | ||||
|  | ||||
| 	$(REMOVE) applet/$(TARGET).hex applet/$(TARGET).eep applet/$(TARGET).cof applet/$(TARGET).elf \ | ||||
|         applet/$(TARGET).map applet/$(TARGET).sym applet/$(TARGET).lss applet/core.a \ | ||||
|         $(OBJT) applet/$(TARGET).cpp.o \ | ||||
|         $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) | ||||
|  | ||||
| .PHONY: all build elf hex eep lss sym program coff extcoff clean applet_files sizebefore sizeafter | ||||
|   | ||||
| @@ -68,7 +68,7 @@ void kill(); | ||||
| //void st_wake_up(); | ||||
| //void st_synchronize(); | ||||
| void enquecommand(const char *cmd); | ||||
| void wd_reset(); | ||||
|  | ||||
|  | ||||
| #ifndef CRITICAL_SECTION_START | ||||
| #define CRITICAL_SECTION_START  unsigned char _sreg = SREG; cli(); | ||||
| @@ -78,6 +78,5 @@ void wd_reset(); | ||||
| extern float homing_feedrate[]; | ||||
| extern bool axis_relative_modes[]; | ||||
|  | ||||
| void manage_inactivity(byte debug); | ||||
|  | ||||
| void wd_reset() ; | ||||
| #endif | ||||
|   | ||||
| @@ -25,7 +25,7 @@ | ||||
|     http://reprap.org/pipermail/reprap-dev/2011-May/003323.html | ||||
|  */ | ||||
|  | ||||
| #include <EEPROM.h> | ||||
| #include "EEPROMwrite.h" | ||||
| #include "fastio.h" | ||||
| #include "Configuration.h" | ||||
| #include "pins.h" | ||||
| @@ -171,7 +171,7 @@ bool sdmode = false; | ||||
| bool sdactive = false; | ||||
| bool savetosd = false; | ||||
| int16_t n; | ||||
| long autostart_atmillis=0; | ||||
| unsigned long autostart_atmillis=0; | ||||
|  | ||||
| void initsd(){ | ||||
|   sdactive = false; | ||||
| @@ -290,24 +290,24 @@ void checkautostart(bool force) | ||||
| 		if(!sdactive) //fail | ||||
| 		return; | ||||
| 	} | ||||
| 	static int lastnr=0; | ||||
| 	char autoname[30]; | ||||
| 	sprintf(autoname,"auto%i.g",lastnr); | ||||
| 	for(int i=0;i<strlen(autoname);i++) | ||||
| 		autoname[i]=tolower(autoname[i]); | ||||
| 	dir_t p; | ||||
|         static int lastnr=0; | ||||
|         char autoname[30]; | ||||
|         sprintf(autoname,"auto%i.g",lastnr); | ||||
|         for(int i=0;i<(int)strlen(autoname);i++) | ||||
|                 autoname[i]=tolower(autoname[i]); | ||||
|         dir_t p; | ||||
|  | ||||
| 	root.rewind(); | ||||
| 	char filename[11]; | ||||
| 	int cnt=0; | ||||
|         root.rewind(); | ||||
|         //char filename[11]; | ||||
|         //int cnt=0; | ||||
|  | ||||
| 	bool found=false; | ||||
| 	while (root.readDir(p) > 0)  | ||||
| 	{ | ||||
| 		for(int i=0;i<strlen((char*)p.name);i++) | ||||
| 			p.name[i]=tolower(p.name[i]); | ||||
| 		//Serial.print((char*)p.name); | ||||
| 		//Serial.print(" "); | ||||
|         bool found=false; | ||||
|         while (root.readDir(p) > 0)  | ||||
|         { | ||||
|                 for(int i=0;i<(int)strlen((char*)p.name);i++) | ||||
|                         p.name[i]=tolower(p.name[i]); | ||||
|                 //Serial.print((char*)p.name); | ||||
|                 //Serial.print(" "); | ||||
| 		//Serial.println(autoname); | ||||
| 		if(p.name[9]!='~') //skip safety copies | ||||
| 		if(strncmp((char*)p.name,autoname,5)==0) | ||||
| @@ -774,8 +774,8 @@ inline void process_commands() | ||||
| 				sprintf(time,"%i min, %i sec",min,sec); | ||||
| 				Serial.println(time); | ||||
| 				LCD_MESSAGE(time); | ||||
| 		} | ||||
| 				break; | ||||
|                 } | ||||
|                                 break; | ||||
| #endif //SDSUPPORT | ||||
|       case 42: //M42 -Change pin status via gcode | ||||
|         if (code_seen('S')) | ||||
| @@ -784,7 +784,7 @@ inline void process_commands() | ||||
|           if (code_seen('P') && pin_status >= 0 && pin_status <= 255) | ||||
|           { | ||||
|             int pin_number = code_value(); | ||||
|             for(int i = 0; i < sizeof(sensitive_pins); i++) | ||||
|             for(int i = 0; i < (int)sizeof(sensitive_pins); i++) | ||||
|             { | ||||
|               if (sensitive_pins[i] == pin_number) | ||||
|               { | ||||
| @@ -803,28 +803,28 @@ inline void process_commands() | ||||
|         } | ||||
|         break; | ||||
|       case 104: // M104 | ||||
|                 if (code_seen('S')) target_raw[0] = temp2analog(code_value()); | ||||
|                 if (code_seen('S')) target_raw[TEMPSENSOR_HOTEND] = temp2analog(code_value()); | ||||
| #ifdef PIDTEMP | ||||
|                 pid_setpoint = code_value(); | ||||
| #endif //PIDTEM | ||||
|         #ifdef WATCHPERIOD | ||||
|             if(target_raw[0] > current_raw[0]){ | ||||
|             if(target_raw[TEMPSENSOR_HOTEND] > current_raw[TEMPSENSOR_HOTEND]){ | ||||
|                 watchmillis = max(1,millis()); | ||||
|                 watch_raw = current_raw[0]; | ||||
|                 watch_raw[TEMPSENSOR_HOTEND] = current_raw[TEMPSENSOR_HOTEND]; | ||||
|             }else{ | ||||
|                 watchmillis = 0; | ||||
|             } | ||||
|         #endif | ||||
|         break; | ||||
|       case 140: // M140 set bed temp | ||||
|                 if (code_seen('S')) target_raw[1] = temp2analogBed(code_value()); | ||||
|                 if (code_seen('S')) target_raw[TEMPSENSOR_BED] = temp2analogBed(code_value()); | ||||
|         break; | ||||
|       case 105: // M105 | ||||
|         #if (TEMP_0_PIN > -1) || defined (HEATER_USES_AD595) | ||||
|                 tt = analog2temp(current_raw[0]); | ||||
|                 tt = analog2temp(current_raw[TEMPSENSOR_HOTEND]); | ||||
|         #endif | ||||
|         #if TEMP_1_PIN > -1 | ||||
|                 bt = analog2tempBed(current_raw[1]); | ||||
|                 bt = analog2tempBed(current_raw[TEMPSENSOR_BED]); | ||||
|         #endif | ||||
|         #if (TEMP_0_PIN > -1) || defined (HEATER_USES_AD595) | ||||
|             Serial.print("ok T:"); | ||||
| @@ -852,14 +852,14 @@ inline void process_commands() | ||||
|         //break; | ||||
|       case 109: {// M109 - Wait for extruder heater to reach target. | ||||
|             LCD_MESSAGE("Heating..."); | ||||
|             if (code_seen('S')) target_raw[0] = temp2analog(code_value()); | ||||
|                if (code_seen('S')) target_raw[TEMPSENSOR_HOTEND] = temp2analog(code_value()); | ||||
|             #ifdef PIDTEMP | ||||
|             pid_setpoint = code_value(); | ||||
|             #endif //PIDTEM | ||||
|             #ifdef WATCHPERIOD | ||||
|             if(target_raw[0]>current_raw[0]) { | ||||
|           if(target_raw[TEMPSENSOR_HOTEND]>current_raw[TEMPSENSOR_HOTEND]){ | ||||
|               watchmillis = max(1,millis()); | ||||
|               watch_raw = current_raw[0]; | ||||
|               watch_raw[TEMPSENSOR_HOTEND] = current_raw[TEMPSENSOR_HOTEND]; | ||||
|             } else { | ||||
|               watchmillis = 0; | ||||
|             } | ||||
| @@ -881,7 +881,7 @@ inline void process_commands() | ||||
|             #endif //TEMP_RESIDENCY_TIME | ||||
|               if( (millis() - codenum) > 1000 ) { //Print Temp Reading every 1 second while heating up/cooling down | ||||
|                 Serial.print("T:"); | ||||
|                 Serial.println( analog2temp(current_raw[0]) ); | ||||
|               Serial.println( analog2temp(current_raw[TEMPSENSOR_HOTEND]) );  | ||||
|                 codenum = millis(); | ||||
|               } | ||||
|               manage_heater(); | ||||
| @@ -895,25 +895,25 @@ inline void process_commands() | ||||
|                 residencyStart = millis(); | ||||
|               } | ||||
|               #endif //TEMP_RESIDENCY_TIME | ||||
| 	    } | ||||
|             } | ||||
|             LCD_MESSAGE("Marlin ready."); | ||||
|           } | ||||
|           break; | ||||
|       case 190: // M190 - Wait bed for heater to reach target. | ||||
|       #if TEMP_1_PIN > -1 | ||||
|           if (code_seen('S')) target_raw[1] = temp2analog(code_value()); | ||||
|           if (code_seen('S')) target_raw[TEMPSENSOR_BED] = temp2analog(code_value()); | ||||
|         codenum = millis();  | ||||
|           while(current_raw[1] < target_raw[1])  | ||||
|           while(current_raw[TEMPSENSOR_BED] < target_raw[TEMPSENSOR_BED])  | ||||
|                                 { | ||||
|           if( (millis()-codenum) > 1000 ) //Print Temp Reading every 1 second while heating up. | ||||
|           { | ||||
|             float tt=analog2temp(current_raw[0]); | ||||
|             float tt=analog2temp(current_raw[TEMPSENSOR_HOTEND]); | ||||
|             Serial.print("T:"); | ||||
|             Serial.println( tt ); | ||||
|             Serial.print("ok T:"); | ||||
|             Serial.print( tt );  | ||||
|             Serial.print(" B:"); | ||||
|             Serial.println( analog2temp(current_raw[1]) );  | ||||
|             Serial.println( analog2temp(current_raw[TEMPSENSOR_BED]) );  | ||||
|             codenum = millis();  | ||||
|           } | ||||
|             manage_heater(); | ||||
|   | ||||
							
								
								
									
										1286
									
								
								Marlin/Sd2Card.cpp
									
									
									
									
									
								
							
							
						
						
									
										1286
									
								
								Marlin/Sd2Card.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										466
									
								
								Marlin/Sd2Card.h
									
									
									
									
									
								
							
							
						
						
									
										466
									
								
								Marlin/Sd2Card.h
									
									
									
									
									
								
							| @@ -1,233 +1,233 @@ | ||||
| /* Arduino Sd2Card Library | ||||
|  * Copyright (C) 2009 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino Sd2Card Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino Sd2Card Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| #ifndef Sd2Card_h | ||||
| #define Sd2Card_h | ||||
| /** | ||||
|  * \file | ||||
|  * Sd2Card class | ||||
|  */ | ||||
| #include "Sd2PinMap.h" | ||||
| #include "SdInfo.h" | ||||
| /** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */ | ||||
| uint8_t const SPI_FULL_SPEED = 0; | ||||
| /** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */ | ||||
| uint8_t const SPI_HALF_SPEED = 1; | ||||
| /** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */ | ||||
| uint8_t const SPI_QUARTER_SPEED = 2; | ||||
| /** | ||||
|  * Define MEGA_SOFT_SPI non-zero to use software SPI on Mega Arduinos. | ||||
|  * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13. | ||||
|  * | ||||
|  * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used | ||||
|  * on Mega Arduinos.  Software SPI works well with GPS Shield V1.1 | ||||
|  * but many SD cards will fail with GPS Shield V1.0. | ||||
|  */ | ||||
| #define MEGA_SOFT_SPI 0 | ||||
| //------------------------------------------------------------------------------ | ||||
| #if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__)) | ||||
| #define SOFTWARE_SPI | ||||
| #endif  // MEGA_SOFT_SPI | ||||
| //------------------------------------------------------------------------------ | ||||
| // SPI pin definitions | ||||
| // | ||||
| #ifndef SOFTWARE_SPI | ||||
| // hardware pin defs | ||||
| /** | ||||
|  * SD Chip Select pin | ||||
|  * | ||||
|  * Warning if this pin is redefined the hardware SS will pin will be enabled | ||||
|  * as an output by init().  An avr processor will not function as an SPI | ||||
|  * master unless SS is set to output mode. | ||||
|  */ | ||||
| /** The default chip select pin for the SD card is SS. */ | ||||
| uint8_t const  SD_CHIP_SELECT_PIN = SS_PIN; | ||||
| // The following three pins must not be redefined for hardware SPI. | ||||
| /** SPI Master Out Slave In pin */ | ||||
| uint8_t const  SPI_MOSI_PIN = MOSI_PIN; | ||||
| /** SPI Master In Slave Out pin */ | ||||
| uint8_t const  SPI_MISO_PIN = MISO_PIN; | ||||
| /** SPI Clock pin */ | ||||
| uint8_t const  SPI_SCK_PIN = SCK_PIN; | ||||
| /** optimize loops for hardware SPI */ | ||||
| #define OPTIMIZE_HARDWARE_SPI | ||||
|  | ||||
| #else  // SOFTWARE_SPI | ||||
| // define software SPI pins so Mega can use unmodified GPS Shield | ||||
| /** SPI chip select pin */ | ||||
| uint8_t const SD_CHIP_SELECT_PIN = 10; | ||||
| /** SPI Master Out Slave In pin */ | ||||
| uint8_t const SPI_MOSI_PIN = 11; | ||||
| /** SPI Master In Slave Out pin */ | ||||
| uint8_t const SPI_MISO_PIN = 12; | ||||
| /** SPI Clock pin */ | ||||
| uint8_t const SPI_SCK_PIN = 13; | ||||
| #endif  // SOFTWARE_SPI | ||||
| //------------------------------------------------------------------------------ | ||||
| /** Protect block zero from write if nonzero */ | ||||
| #define SD_PROTECT_BLOCK_ZERO 1 | ||||
| /** init timeout ms */ | ||||
| uint16_t const SD_INIT_TIMEOUT = 2000; | ||||
| /** erase timeout ms */ | ||||
| uint16_t const SD_ERASE_TIMEOUT = 10000; | ||||
| /** read timeout ms */ | ||||
| uint16_t const SD_READ_TIMEOUT = 300; | ||||
| /** write time out ms */ | ||||
| uint16_t const SD_WRITE_TIMEOUT = 600; | ||||
| //------------------------------------------------------------------------------ | ||||
| // SD card errors | ||||
| /** timeout error for command CMD0 */ | ||||
| uint8_t const SD_CARD_ERROR_CMD0 = 0X1; | ||||
| /** CMD8 was not accepted - not a valid SD card*/ | ||||
| uint8_t const SD_CARD_ERROR_CMD8 = 0X2; | ||||
| /** card returned an error response for CMD17 (read block) */ | ||||
| uint8_t const SD_CARD_ERROR_CMD17 = 0X3; | ||||
| /** card returned an error response for CMD24 (write block) */ | ||||
| uint8_t const SD_CARD_ERROR_CMD24 = 0X4; | ||||
| /**  WRITE_MULTIPLE_BLOCKS command failed */ | ||||
| uint8_t const SD_CARD_ERROR_CMD25 = 0X05; | ||||
| /** card returned an error response for CMD58 (read OCR) */ | ||||
| uint8_t const SD_CARD_ERROR_CMD58 = 0X06; | ||||
| /** SET_WR_BLK_ERASE_COUNT failed */ | ||||
| uint8_t const SD_CARD_ERROR_ACMD23 = 0X07; | ||||
| /** card's ACMD41 initialization process timeout */ | ||||
| uint8_t const SD_CARD_ERROR_ACMD41 = 0X08; | ||||
| /** card returned a bad CSR version field */ | ||||
| uint8_t const SD_CARD_ERROR_BAD_CSD = 0X09; | ||||
| /** erase block group command failed */ | ||||
| uint8_t const SD_CARD_ERROR_ERASE = 0X0A; | ||||
| /** card not capable of single block erase */ | ||||
| uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0X0B; | ||||
| /** Erase sequence timed out */ | ||||
| uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0X0C; | ||||
| /** card returned an error token instead of read data */ | ||||
| uint8_t const SD_CARD_ERROR_READ = 0X0D; | ||||
| /** read CID or CSD failed */ | ||||
| uint8_t const SD_CARD_ERROR_READ_REG = 0X0E; | ||||
| /** timeout while waiting for start of read data */ | ||||
| uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X0F; | ||||
| /** card did not accept STOP_TRAN_TOKEN */ | ||||
| uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X10; | ||||
| /** card returned an error token as a response to a write operation */ | ||||
| uint8_t const SD_CARD_ERROR_WRITE = 0X11; | ||||
| /** attempt to write protected block zero */ | ||||
| uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X12; | ||||
| /** card did not go ready for a multiple block write */ | ||||
| uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X13; | ||||
| /** card returned an error to a CMD13 status check after a write */ | ||||
| uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X14; | ||||
| /** timeout occurred during write programming */ | ||||
| uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X15; | ||||
| /** incorrect rate selected */ | ||||
| uint8_t const SD_CARD_ERROR_SCK_RATE = 0X16; | ||||
| //------------------------------------------------------------------------------ | ||||
| // card types | ||||
| /** Standard capacity V1 SD card */ | ||||
| uint8_t const SD_CARD_TYPE_SD1 = 1; | ||||
| /** Standard capacity V2 SD card */ | ||||
| uint8_t const SD_CARD_TYPE_SD2 = 2; | ||||
| /** High Capacity SD card */ | ||||
| uint8_t const SD_CARD_TYPE_SDHC = 3; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * \class Sd2Card | ||||
|  * \brief Raw access to SD and SDHC flash memory cards. | ||||
|  */ | ||||
| class Sd2Card { | ||||
|  public: | ||||
|   /** Construct an instance of Sd2Card. */ | ||||
|   Sd2Card(void) : errorCode_(0), inBlock_(0), partialBlockRead_(0), type_(0) {} | ||||
|   uint32_t cardSize(void); | ||||
|   uint8_t erase(uint32_t firstBlock, uint32_t lastBlock); | ||||
|   uint8_t eraseSingleBlockEnable(void); | ||||
|   /** | ||||
|    * \return error code for last error. See Sd2Card.h for a list of error codes. | ||||
|    */ | ||||
|   uint8_t errorCode(void) const {return errorCode_;} | ||||
|   /** \return error data for last error. */ | ||||
|   uint8_t errorData(void) const {return status_;} | ||||
|   /** | ||||
|    * Initialize an SD flash memory card with default clock rate and chip | ||||
|    * select pin.  See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). | ||||
|    */ | ||||
|   uint8_t init(void) { | ||||
|     return init(SPI_FULL_SPEED, SD_CHIP_SELECT_PIN); | ||||
|   } | ||||
|   /** | ||||
|    * Initialize an SD flash memory card with the selected SPI clock rate | ||||
|    * and the default SD chip select pin. | ||||
|    * See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). | ||||
|    */ | ||||
|   uint8_t init(uint8_t sckRateID) { | ||||
|     return init(sckRateID, SD_CHIP_SELECT_PIN); | ||||
|   } | ||||
|   uint8_t init(uint8_t sckRateID, uint8_t chipSelectPin); | ||||
|   void partialBlockRead(uint8_t value); | ||||
|   /** Returns the current value, true or false, for partial block read. */ | ||||
|   uint8_t partialBlockRead(void) const {return partialBlockRead_;} | ||||
|   uint8_t readBlock(uint32_t block, uint8_t* dst); | ||||
|   uint8_t readData(uint32_t block, | ||||
|           uint16_t offset, uint16_t count, uint8_t* dst); | ||||
|   /** | ||||
|    * Read a cards CID register. The CID contains card identification | ||||
|    * information such as Manufacturer ID, Product name, Product serial | ||||
|    * number and Manufacturing date. */ | ||||
|   uint8_t readCID(cid_t* cid) { | ||||
|     return readRegister(CMD10, cid); | ||||
|   } | ||||
|   /** | ||||
|    * Read a cards CSD register. The CSD contains Card-Specific Data that | ||||
|    * provides information regarding access to the card's contents. */ | ||||
|   uint8_t readCSD(csd_t* csd) { | ||||
|     return readRegister(CMD9, csd); | ||||
|   } | ||||
|   void readEnd(void); | ||||
|   uint8_t setSckRate(uint8_t sckRateID); | ||||
|   /** Return the card type: SD V1, SD V2 or SDHC */ | ||||
|   uint8_t type(void) const {return type_;} | ||||
|   uint8_t writeBlock(uint32_t blockNumber, const uint8_t* src); | ||||
|   uint8_t writeData(const uint8_t* src); | ||||
|   uint8_t writeStart(uint32_t blockNumber, uint32_t eraseCount); | ||||
|   uint8_t writeStop(void); | ||||
|  private: | ||||
|   uint32_t block_; | ||||
|   uint8_t chipSelectPin_; | ||||
|   uint8_t errorCode_; | ||||
|   uint8_t inBlock_; | ||||
|   uint16_t offset_; | ||||
|   uint8_t partialBlockRead_; | ||||
|   uint8_t status_; | ||||
|   uint8_t type_; | ||||
|   // private functions | ||||
|   uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { | ||||
|     cardCommand(CMD55, 0); | ||||
|     return cardCommand(cmd, arg); | ||||
|   } | ||||
|   uint8_t cardCommand(uint8_t cmd, uint32_t arg); | ||||
|   void error(uint8_t code) {errorCode_ = code;} | ||||
|   uint8_t readRegister(uint8_t cmd, void* buf); | ||||
|   uint8_t sendWriteCommand(uint32_t blockNumber, uint32_t eraseCount); | ||||
|   void chipSelectHigh(void); | ||||
|   void chipSelectLow(void); | ||||
|   void type(uint8_t value) {type_ = value;} | ||||
|   uint8_t waitNotBusy(uint16_t timeoutMillis); | ||||
|   uint8_t writeData(uint8_t token, const uint8_t* src); | ||||
|   uint8_t waitStartBlock(void); | ||||
| }; | ||||
| #endif  // Sd2Card_h | ||||
| /* Arduino Sd2Card Library | ||||
|  * Copyright (C) 2009 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino Sd2Card Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino Sd2Card Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| #ifndef Sd2Card_h | ||||
| #define Sd2Card_h | ||||
| /** | ||||
|  * \file | ||||
|  * Sd2Card class | ||||
|  */ | ||||
| #include "Sd2PinMap.h" | ||||
| #include "SdInfo.h" | ||||
| /** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */ | ||||
| uint8_t const SPI_FULL_SPEED = 0; | ||||
| /** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */ | ||||
| uint8_t const SPI_HALF_SPEED = 1; | ||||
| /** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */ | ||||
| uint8_t const SPI_QUARTER_SPEED = 2; | ||||
| /** | ||||
|  * Define MEGA_SOFT_SPI non-zero to use software SPI on Mega Arduinos. | ||||
|  * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13. | ||||
|  * | ||||
|  * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used | ||||
|  * on Mega Arduinos.  Software SPI works well with GPS Shield V1.1 | ||||
|  * but many SD cards will fail with GPS Shield V1.0. | ||||
|  */ | ||||
| #define MEGA_SOFT_SPI 0 | ||||
| //------------------------------------------------------------------------------ | ||||
| #if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__)) | ||||
| #define SOFTWARE_SPI | ||||
| #endif  // MEGA_SOFT_SPI | ||||
| //------------------------------------------------------------------------------ | ||||
| // SPI pin definitions | ||||
| // | ||||
| #ifndef SOFTWARE_SPI | ||||
| // hardware pin defs | ||||
| /** | ||||
|  * SD Chip Select pin | ||||
|  * | ||||
|  * Warning if this pin is redefined the hardware SS will pin will be enabled | ||||
|  * as an output by init().  An avr processor will not function as an SPI | ||||
|  * master unless SS is set to output mode. | ||||
|  */ | ||||
| /** The default chip select pin for the SD card is SS. */ | ||||
| uint8_t const  SD_CHIP_SELECT_PIN = SS_PIN; | ||||
| // The following three pins must not be redefined for hardware SPI. | ||||
| /** SPI Master Out Slave In pin */ | ||||
| uint8_t const  SPI_MOSI_PIN = MOSI_PIN; | ||||
| /** SPI Master In Slave Out pin */ | ||||
| uint8_t const  SPI_MISO_PIN = MISO_PIN; | ||||
| /** SPI Clock pin */ | ||||
| uint8_t const  SPI_SCK_PIN = SCK_PIN; | ||||
| /** optimize loops for hardware SPI */ | ||||
| #define OPTIMIZE_HARDWARE_SPI | ||||
|  | ||||
| #else  // SOFTWARE_SPI | ||||
| // define software SPI pins so Mega can use unmodified GPS Shield | ||||
| /** SPI chip select pin */ | ||||
| uint8_t const SD_CHIP_SELECT_PIN = 10; | ||||
| /** SPI Master Out Slave In pin */ | ||||
| uint8_t const SPI_MOSI_PIN = 11; | ||||
| /** SPI Master In Slave Out pin */ | ||||
| uint8_t const SPI_MISO_PIN = 12; | ||||
| /** SPI Clock pin */ | ||||
| uint8_t const SPI_SCK_PIN = 13; | ||||
| #endif  // SOFTWARE_SPI | ||||
| //------------------------------------------------------------------------------ | ||||
| /** Protect block zero from write if nonzero */ | ||||
| #define SD_PROTECT_BLOCK_ZERO 1 | ||||
| /** init timeout ms */ | ||||
| uint16_t const SD_INIT_TIMEOUT = 2000; | ||||
| /** erase timeout ms */ | ||||
| uint16_t const SD_ERASE_TIMEOUT = 10000; | ||||
| /** read timeout ms */ | ||||
| uint16_t const SD_READ_TIMEOUT = 300; | ||||
| /** write time out ms */ | ||||
| uint16_t const SD_WRITE_TIMEOUT = 600; | ||||
| //------------------------------------------------------------------------------ | ||||
| // SD card errors | ||||
| /** timeout error for command CMD0 */ | ||||
| uint8_t const SD_CARD_ERROR_CMD0 = 0X1; | ||||
| /** CMD8 was not accepted - not a valid SD card*/ | ||||
| uint8_t const SD_CARD_ERROR_CMD8 = 0X2; | ||||
| /** card returned an error response for CMD17 (read block) */ | ||||
| uint8_t const SD_CARD_ERROR_CMD17 = 0X3; | ||||
| /** card returned an error response for CMD24 (write block) */ | ||||
| uint8_t const SD_CARD_ERROR_CMD24 = 0X4; | ||||
| /**  WRITE_MULTIPLE_BLOCKS command failed */ | ||||
| uint8_t const SD_CARD_ERROR_CMD25 = 0X05; | ||||
| /** card returned an error response for CMD58 (read OCR) */ | ||||
| uint8_t const SD_CARD_ERROR_CMD58 = 0X06; | ||||
| /** SET_WR_BLK_ERASE_COUNT failed */ | ||||
| uint8_t const SD_CARD_ERROR_ACMD23 = 0X07; | ||||
| /** card's ACMD41 initialization process timeout */ | ||||
| uint8_t const SD_CARD_ERROR_ACMD41 = 0X08; | ||||
| /** card returned a bad CSR version field */ | ||||
| uint8_t const SD_CARD_ERROR_BAD_CSD = 0X09; | ||||
| /** erase block group command failed */ | ||||
| uint8_t const SD_CARD_ERROR_ERASE = 0X0A; | ||||
| /** card not capable of single block erase */ | ||||
| uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0X0B; | ||||
| /** Erase sequence timed out */ | ||||
| uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0X0C; | ||||
| /** card returned an error token instead of read data */ | ||||
| uint8_t const SD_CARD_ERROR_READ = 0X0D; | ||||
| /** read CID or CSD failed */ | ||||
| uint8_t const SD_CARD_ERROR_READ_REG = 0X0E; | ||||
| /** timeout while waiting for start of read data */ | ||||
| uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X0F; | ||||
| /** card did not accept STOP_TRAN_TOKEN */ | ||||
| uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X10; | ||||
| /** card returned an error token as a response to a write operation */ | ||||
| uint8_t const SD_CARD_ERROR_WRITE = 0X11; | ||||
| /** attempt to write protected block zero */ | ||||
| uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X12; | ||||
| /** card did not go ready for a multiple block write */ | ||||
| uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X13; | ||||
| /** card returned an error to a CMD13 status check after a write */ | ||||
| uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X14; | ||||
| /** timeout occurred during write programming */ | ||||
| uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X15; | ||||
| /** incorrect rate selected */ | ||||
| uint8_t const SD_CARD_ERROR_SCK_RATE = 0X16; | ||||
| //------------------------------------------------------------------------------ | ||||
| // card types | ||||
| /** Standard capacity V1 SD card */ | ||||
| uint8_t const SD_CARD_TYPE_SD1 = 1; | ||||
| /** Standard capacity V2 SD card */ | ||||
| uint8_t const SD_CARD_TYPE_SD2 = 2; | ||||
| /** High Capacity SD card */ | ||||
| uint8_t const SD_CARD_TYPE_SDHC = 3; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * \class Sd2Card | ||||
|  * \brief Raw access to SD and SDHC flash memory cards. | ||||
|  */ | ||||
| class Sd2Card { | ||||
|  public: | ||||
|   /** Construct an instance of Sd2Card. */ | ||||
|   Sd2Card(void) : errorCode_(0), inBlock_(0), partialBlockRead_(0), type_(0) {} | ||||
|   uint32_t cardSize(void); | ||||
|   uint8_t erase(uint32_t firstBlock, uint32_t lastBlock); | ||||
|   uint8_t eraseSingleBlockEnable(void); | ||||
|   /** | ||||
|    * \return error code for last error. See Sd2Card.h for a list of error codes. | ||||
|    */ | ||||
|   uint8_t errorCode(void) const {return errorCode_;} | ||||
|   /** \return error data for last error. */ | ||||
|   uint8_t errorData(void) const {return status_;} | ||||
|   /** | ||||
|    * Initialize an SD flash memory card with default clock rate and chip | ||||
|    * select pin.  See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). | ||||
|    */ | ||||
|   uint8_t init(void) { | ||||
|     return init(SPI_FULL_SPEED, SD_CHIP_SELECT_PIN); | ||||
|   } | ||||
|   /** | ||||
|    * Initialize an SD flash memory card with the selected SPI clock rate | ||||
|    * and the default SD chip select pin. | ||||
|    * See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). | ||||
|    */ | ||||
|   uint8_t init(uint8_t sckRateID) { | ||||
|     return init(sckRateID, SD_CHIP_SELECT_PIN); | ||||
|   } | ||||
|   uint8_t init(uint8_t sckRateID, uint8_t chipSelectPin); | ||||
|   void partialBlockRead(uint8_t value); | ||||
|   /** Returns the current value, true or false, for partial block read. */ | ||||
|   uint8_t partialBlockRead(void) const {return partialBlockRead_;} | ||||
|   uint8_t readBlock(uint32_t block, uint8_t* dst); | ||||
|   uint8_t readData(uint32_t block, | ||||
|           uint16_t offset, uint16_t count, uint8_t* dst); | ||||
|   /** | ||||
|    * Read a cards CID register. The CID contains card identification | ||||
|    * information such as Manufacturer ID, Product name, Product serial | ||||
|    * number and Manufacturing date. */ | ||||
|   uint8_t readCID(cid_t* cid) { | ||||
|     return readRegister(CMD10, cid); | ||||
|   } | ||||
|   /** | ||||
|    * Read a cards CSD register. The CSD contains Card-Specific Data that | ||||
|    * provides information regarding access to the card's contents. */ | ||||
|   uint8_t readCSD(csd_t* csd) { | ||||
|     return readRegister(CMD9, csd); | ||||
|   } | ||||
|   void readEnd(void); | ||||
|   uint8_t setSckRate(uint8_t sckRateID); | ||||
|   /** Return the card type: SD V1, SD V2 or SDHC */ | ||||
|   uint8_t type(void) const {return type_;} | ||||
|   uint8_t writeBlock(uint32_t blockNumber, const uint8_t* src); | ||||
|   uint8_t writeData(const uint8_t* src); | ||||
|   uint8_t writeStart(uint32_t blockNumber, uint32_t eraseCount); | ||||
|   uint8_t writeStop(void); | ||||
|  private: | ||||
|   uint32_t block_; | ||||
|   uint8_t chipSelectPin_; | ||||
|   uint8_t errorCode_; | ||||
|   uint8_t inBlock_; | ||||
|   uint16_t offset_; | ||||
|   uint8_t partialBlockRead_; | ||||
|   uint8_t status_; | ||||
|   uint8_t type_; | ||||
|   // private functions | ||||
|   uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { | ||||
|     cardCommand(CMD55, 0); | ||||
|     return cardCommand(cmd, arg); | ||||
|   } | ||||
|   uint8_t cardCommand(uint8_t cmd, uint32_t arg); | ||||
|   void error(uint8_t code) {errorCode_ = code;} | ||||
|   uint8_t readRegister(uint8_t cmd, void* buf); | ||||
|   uint8_t sendWriteCommand(uint32_t blockNumber, uint32_t eraseCount); | ||||
|   void chipSelectHigh(void); | ||||
|   void chipSelectLow(void); | ||||
|   void type(uint8_t value) {type_ = value;} | ||||
|   uint8_t waitNotBusy(uint16_t timeoutMillis); | ||||
|   uint8_t writeData(uint8_t token, const uint8_t* src); | ||||
|   uint8_t waitStartBlock(void); | ||||
| }; | ||||
| #endif  // Sd2Card_h | ||||
|   | ||||
| @@ -1,353 +1,353 @@ | ||||
| /* Arduino SdFat Library | ||||
|  * Copyright (C) 2010 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino SdFat Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino SdFat Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| // Warning this file was generated by a program. | ||||
| #ifndef Sd2PinMap_h | ||||
| #define Sd2PinMap_h | ||||
| #include <avr/io.h> | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| /** struct for mapping digital pins */ | ||||
| struct pin_map_t { | ||||
|   volatile uint8_t* ddr; | ||||
|   volatile uint8_t* pin; | ||||
|   volatile uint8_t* port; | ||||
|   uint8_t bit; | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) | ||||
| // Mega | ||||
|  | ||||
| // Two Wire (aka I2C) ports | ||||
| uint8_t const SDA_PIN = 20; | ||||
| uint8_t const SCL_PIN = 21; | ||||
|  | ||||
| // SPI port | ||||
| uint8_t const SS_PIN = 53; | ||||
| uint8_t const MOSI_PIN = 51; | ||||
| uint8_t const MISO_PIN = 50; | ||||
| uint8_t const SCK_PIN = 52; | ||||
|  | ||||
| static const pin_map_t digitalPinMap[] = { | ||||
|   {&DDRE, &PINE, &PORTE, 0},  // E0  0 | ||||
|   {&DDRE, &PINE, &PORTE, 1},  // E1  1 | ||||
|   {&DDRE, &PINE, &PORTE, 4},  // E4  2 | ||||
|   {&DDRE, &PINE, &PORTE, 5},  // E5  3 | ||||
|   {&DDRG, &PING, &PORTG, 5},  // G5  4 | ||||
|   {&DDRE, &PINE, &PORTE, 3},  // E3  5 | ||||
|   {&DDRH, &PINH, &PORTH, 3},  // H3  6 | ||||
|   {&DDRH, &PINH, &PORTH, 4},  // H4  7 | ||||
|   {&DDRH, &PINH, &PORTH, 5},  // H5  8 | ||||
|   {&DDRH, &PINH, &PORTH, 6},  // H6  9 | ||||
|   {&DDRB, &PINB, &PORTB, 4},  // B4 10 | ||||
|   {&DDRB, &PINB, &PORTB, 5},  // B5 11 | ||||
|   {&DDRB, &PINB, &PORTB, 6},  // B6 12 | ||||
|   {&DDRB, &PINB, &PORTB, 7},  // B7 13 | ||||
|   {&DDRJ, &PINJ, &PORTJ, 1},  // J1 14 | ||||
|   {&DDRJ, &PINJ, &PORTJ, 0},  // J0 15 | ||||
|   {&DDRH, &PINH, &PORTH, 1},  // H1 16 | ||||
|   {&DDRH, &PINH, &PORTH, 0},  // H0 17 | ||||
|   {&DDRD, &PIND, &PORTD, 3},  // D3 18 | ||||
|   {&DDRD, &PIND, &PORTD, 2},  // D2 19 | ||||
|   {&DDRD, &PIND, &PORTD, 1},  // D1 20 | ||||
|   {&DDRD, &PIND, &PORTD, 0},  // D0 21 | ||||
|   {&DDRA, &PINA, &PORTA, 0},  // A0 22 | ||||
|   {&DDRA, &PINA, &PORTA, 1},  // A1 23 | ||||
|   {&DDRA, &PINA, &PORTA, 2},  // A2 24 | ||||
|   {&DDRA, &PINA, &PORTA, 3},  // A3 25 | ||||
|   {&DDRA, &PINA, &PORTA, 4},  // A4 26 | ||||
|   {&DDRA, &PINA, &PORTA, 5},  // A5 27 | ||||
|   {&DDRA, &PINA, &PORTA, 6},  // A6 28 | ||||
|   {&DDRA, &PINA, &PORTA, 7},  // A7 29 | ||||
|   {&DDRC, &PINC, &PORTC, 7},  // C7 30 | ||||
|   {&DDRC, &PINC, &PORTC, 6},  // C6 31 | ||||
|   {&DDRC, &PINC, &PORTC, 5},  // C5 32 | ||||
|   {&DDRC, &PINC, &PORTC, 4},  // C4 33 | ||||
|   {&DDRC, &PINC, &PORTC, 3},  // C3 34 | ||||
|   {&DDRC, &PINC, &PORTC, 2},  // C2 35 | ||||
|   {&DDRC, &PINC, &PORTC, 1},  // C1 36 | ||||
|   {&DDRC, &PINC, &PORTC, 0},  // C0 37 | ||||
|   {&DDRD, &PIND, &PORTD, 7},  // D7 38 | ||||
|   {&DDRG, &PING, &PORTG, 2},  // G2 39 | ||||
|   {&DDRG, &PING, &PORTG, 1},  // G1 40 | ||||
|   {&DDRG, &PING, &PORTG, 0},  // G0 41 | ||||
|   {&DDRL, &PINL, &PORTL, 7},  // L7 42 | ||||
|   {&DDRL, &PINL, &PORTL, 6},  // L6 43 | ||||
|   {&DDRL, &PINL, &PORTL, 5},  // L5 44 | ||||
|   {&DDRL, &PINL, &PORTL, 4},  // L4 45 | ||||
|   {&DDRL, &PINL, &PORTL, 3},  // L3 46 | ||||
|   {&DDRL, &PINL, &PORTL, 2},  // L2 47 | ||||
|   {&DDRL, &PINL, &PORTL, 1},  // L1 48 | ||||
|   {&DDRL, &PINL, &PORTL, 0},  // L0 49 | ||||
|   {&DDRB, &PINB, &PORTB, 3},  // B3 50 | ||||
|   {&DDRB, &PINB, &PORTB, 2},  // B2 51 | ||||
|   {&DDRB, &PINB, &PORTB, 1},  // B1 52 | ||||
|   {&DDRB, &PINB, &PORTB, 0},  // B0 53 | ||||
|   {&DDRF, &PINF, &PORTF, 0},  // F0 54 | ||||
|   {&DDRF, &PINF, &PORTF, 1},  // F1 55 | ||||
|   {&DDRF, &PINF, &PORTF, 2},  // F2 56 | ||||
|   {&DDRF, &PINF, &PORTF, 3},  // F3 57 | ||||
|   {&DDRF, &PINF, &PORTF, 4},  // F4 58 | ||||
|   {&DDRF, &PINF, &PORTF, 5},  // F5 59 | ||||
|   {&DDRF, &PINF, &PORTF, 6},  // F6 60 | ||||
|   {&DDRF, &PINF, &PORTF, 7},  // F7 61 | ||||
|   {&DDRK, &PINK, &PORTK, 0},  // K0 62 | ||||
|   {&DDRK, &PINK, &PORTK, 1},  // K1 63 | ||||
|   {&DDRK, &PINK, &PORTK, 2},  // K2 64 | ||||
|   {&DDRK, &PINK, &PORTK, 3},  // K3 65 | ||||
|   {&DDRK, &PINK, &PORTK, 4},  // K4 66 | ||||
|   {&DDRK, &PINK, &PORTK, 5},  // K5 67 | ||||
|   {&DDRK, &PINK, &PORTK, 6},  // K6 68 | ||||
|   {&DDRK, &PINK, &PORTK, 7}   // K7 69 | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) | ||||
| // Sanguino | ||||
|  | ||||
| // Two Wire (aka I2C) ports | ||||
| uint8_t const SDA_PIN = 17; | ||||
| uint8_t const SCL_PIN = 18; | ||||
|  | ||||
| // SPI port | ||||
| uint8_t const SS_PIN = 4; | ||||
| uint8_t const MOSI_PIN = 5; | ||||
| uint8_t const MISO_PIN = 6; | ||||
| uint8_t const SCK_PIN = 7; | ||||
|  | ||||
| static const pin_map_t digitalPinMap[] = { | ||||
|   {&DDRB, &PINB, &PORTB, 0},  // B0  0 | ||||
|   {&DDRB, &PINB, &PORTB, 1},  // B1  1 | ||||
|   {&DDRB, &PINB, &PORTB, 2},  // B2  2 | ||||
|   {&DDRB, &PINB, &PORTB, 3},  // B3  3 | ||||
|   {&DDRB, &PINB, &PORTB, 4},  // B4  4 | ||||
|   {&DDRB, &PINB, &PORTB, 5},  // B5  5 | ||||
|   {&DDRB, &PINB, &PORTB, 6},  // B6  6 | ||||
|   {&DDRB, &PINB, &PORTB, 7},  // B7  7 | ||||
|   {&DDRD, &PIND, &PORTD, 0},  // D0  8 | ||||
|   {&DDRD, &PIND, &PORTD, 1},  // D1  9 | ||||
|   {&DDRD, &PIND, &PORTD, 2},  // D2 10 | ||||
|   {&DDRD, &PIND, &PORTD, 3},  // D3 11 | ||||
|   {&DDRD, &PIND, &PORTD, 4},  // D4 12 | ||||
|   {&DDRD, &PIND, &PORTD, 5},  // D5 13 | ||||
|   {&DDRD, &PIND, &PORTD, 6},  // D6 14 | ||||
|   {&DDRD, &PIND, &PORTD, 7},  // D7 15 | ||||
|   {&DDRC, &PINC, &PORTC, 0},  // C0 16 | ||||
|   {&DDRC, &PINC, &PORTC, 1},  // C1 17 | ||||
|   {&DDRC, &PINC, &PORTC, 2},  // C2 18 | ||||
|   {&DDRC, &PINC, &PORTC, 3},  // C3 19 | ||||
|   {&DDRC, &PINC, &PORTC, 4},  // C4 20 | ||||
|   {&DDRC, &PINC, &PORTC, 5},  // C5 21 | ||||
|   {&DDRC, &PINC, &PORTC, 6},  // C6 22 | ||||
|   {&DDRC, &PINC, &PORTC, 7},  // C7 23 | ||||
|   {&DDRA, &PINA, &PORTA, 7},  // A7 24 | ||||
|   {&DDRA, &PINA, &PORTA, 6},  // A6 25 | ||||
|   {&DDRA, &PINA, &PORTA, 5},  // A5 26 | ||||
|   {&DDRA, &PINA, &PORTA, 4},  // A4 27 | ||||
|   {&DDRA, &PINA, &PORTA, 3},  // A3 28 | ||||
|   {&DDRA, &PINA, &PORTA, 2},  // A2 29 | ||||
|   {&DDRA, &PINA, &PORTA, 1},  // A1 30 | ||||
|   {&DDRA, &PINA, &PORTA, 0}   // A0 31 | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| #elif defined(__AVR_ATmega32U4__) | ||||
| // Teensy 2.0 | ||||
|  | ||||
| // Two Wire (aka I2C) ports | ||||
| uint8_t const SDA_PIN = 6; | ||||
| uint8_t const SCL_PIN = 5; | ||||
|  | ||||
| // SPI port | ||||
| uint8_t const SS_PIN = 0; | ||||
| uint8_t const MOSI_PIN = 2; | ||||
| uint8_t const MISO_PIN = 3; | ||||
| uint8_t const SCK_PIN = 1; | ||||
|  | ||||
| static const pin_map_t digitalPinMap[] = { | ||||
|   {&DDRB, &PINB, &PORTB, 0},  // B0  0 | ||||
|   {&DDRB, &PINB, &PORTB, 1},  // B1  1 | ||||
|   {&DDRB, &PINB, &PORTB, 2},  // B2  2 | ||||
|   {&DDRB, &PINB, &PORTB, 3},  // B3  3 | ||||
|   {&DDRB, &PINB, &PORTB, 7},  // B7  4 | ||||
|   {&DDRD, &PIND, &PORTD, 0},  // D0  5 | ||||
|   {&DDRD, &PIND, &PORTD, 1},  // D1  6 | ||||
|   {&DDRD, &PIND, &PORTD, 2},  // D2  7 | ||||
|   {&DDRD, &PIND, &PORTD, 3},  // D3  8 | ||||
|   {&DDRC, &PINC, &PORTC, 6},  // C6  9 | ||||
|   {&DDRC, &PINC, &PORTC, 7},  // C7 10 | ||||
|   {&DDRD, &PIND, &PORTD, 6},  // D6 11 | ||||
|   {&DDRD, &PIND, &PORTD, 7},  // D7 12 | ||||
|   {&DDRB, &PINB, &PORTB, 4},  // B4 13 | ||||
|   {&DDRB, &PINB, &PORTB, 5},  // B5 14 | ||||
|   {&DDRB, &PINB, &PORTB, 6},  // B6 15 | ||||
|   {&DDRF, &PINF, &PORTF, 7},  // F7 16 | ||||
|   {&DDRF, &PINF, &PORTF, 6},  // F6 17 | ||||
|   {&DDRF, &PINF, &PORTF, 5},  // F5 18 | ||||
|   {&DDRF, &PINF, &PORTF, 4},  // F4 19 | ||||
|   {&DDRF, &PINF, &PORTF, 1},  // F1 20 | ||||
|   {&DDRF, &PINF, &PORTF, 0},  // F0 21 | ||||
|   {&DDRD, &PIND, &PORTD, 4},  // D4 22 | ||||
|   {&DDRD, &PIND, &PORTD, 5},  // D5 23 | ||||
|   {&DDRE, &PINE, &PORTE, 6}   // E6 24 | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) | ||||
| // Teensy++ 1.0 & 2.0 | ||||
|  | ||||
| // Two Wire (aka I2C) ports | ||||
| uint8_t const SDA_PIN = 1; | ||||
| uint8_t const SCL_PIN = 0; | ||||
|  | ||||
| // SPI port | ||||
| uint8_t const SS_PIN = 20; | ||||
| uint8_t const MOSI_PIN = 22; | ||||
| uint8_t const MISO_PIN = 23; | ||||
| uint8_t const SCK_PIN = 21; | ||||
|  | ||||
| static const pin_map_t digitalPinMap[] = { | ||||
|   {&DDRD, &PIND, &PORTD, 0},  // D0  0 | ||||
|   {&DDRD, &PIND, &PORTD, 1},  // D1  1 | ||||
|   {&DDRD, &PIND, &PORTD, 2},  // D2  2 | ||||
|   {&DDRD, &PIND, &PORTD, 3},  // D3  3 | ||||
|   {&DDRD, &PIND, &PORTD, 4},  // D4  4 | ||||
|   {&DDRD, &PIND, &PORTD, 5},  // D5  5 | ||||
|   {&DDRD, &PIND, &PORTD, 6},  // D6  6 | ||||
|   {&DDRD, &PIND, &PORTD, 7},  // D7  7 | ||||
|   {&DDRE, &PINE, &PORTE, 0},  // E0  8 | ||||
|   {&DDRE, &PINE, &PORTE, 1},  // E1  9 | ||||
|   {&DDRC, &PINC, &PORTC, 0},  // C0 10 | ||||
|   {&DDRC, &PINC, &PORTC, 1},  // C1 11 | ||||
|   {&DDRC, &PINC, &PORTC, 2},  // C2 12 | ||||
|   {&DDRC, &PINC, &PORTC, 3},  // C3 13 | ||||
|   {&DDRC, &PINC, &PORTC, 4},  // C4 14 | ||||
|   {&DDRC, &PINC, &PORTC, 5},  // C5 15 | ||||
|   {&DDRC, &PINC, &PORTC, 6},  // C6 16 | ||||
|   {&DDRC, &PINC, &PORTC, 7},  // C7 17 | ||||
|   {&DDRE, &PINE, &PORTE, 6},  // E6 18 | ||||
|   {&DDRE, &PINE, &PORTE, 7},  // E7 19 | ||||
|   {&DDRB, &PINB, &PORTB, 0},  // B0 20 | ||||
|   {&DDRB, &PINB, &PORTB, 1},  // B1 21 | ||||
|   {&DDRB, &PINB, &PORTB, 2},  // B2 22 | ||||
|   {&DDRB, &PINB, &PORTB, 3},  // B3 23 | ||||
|   {&DDRB, &PINB, &PORTB, 4},  // B4 24 | ||||
|   {&DDRB, &PINB, &PORTB, 5},  // B5 25 | ||||
|   {&DDRB, &PINB, &PORTB, 6},  // B6 26 | ||||
|   {&DDRB, &PINB, &PORTB, 7},  // B7 27 | ||||
|   {&DDRA, &PINA, &PORTA, 0},  // A0 28 | ||||
|   {&DDRA, &PINA, &PORTA, 1},  // A1 29 | ||||
|   {&DDRA, &PINA, &PORTA, 2},  // A2 30 | ||||
|   {&DDRA, &PINA, &PORTA, 3},  // A3 31 | ||||
|   {&DDRA, &PINA, &PORTA, 4},  // A4 32 | ||||
|   {&DDRA, &PINA, &PORTA, 5},  // A5 33 | ||||
|   {&DDRA, &PINA, &PORTA, 6},  // A6 34 | ||||
|   {&DDRA, &PINA, &PORTA, 7},  // A7 35 | ||||
|   {&DDRE, &PINE, &PORTE, 4},  // E4 36 | ||||
|   {&DDRE, &PINE, &PORTE, 5},  // E5 37 | ||||
|   {&DDRF, &PINF, &PORTF, 0},  // F0 38 | ||||
|   {&DDRF, &PINF, &PORTF, 1},  // F1 39 | ||||
|   {&DDRF, &PINF, &PORTF, 2},  // F2 40 | ||||
|   {&DDRF, &PINF, &PORTF, 3},  // F3 41 | ||||
|   {&DDRF, &PINF, &PORTF, 4},  // F4 42 | ||||
|   {&DDRF, &PINF, &PORTF, 5},  // F5 43 | ||||
|   {&DDRF, &PINF, &PORTF, 6},  // F6 44 | ||||
|   {&DDRF, &PINF, &PORTF, 7}   // F7 45 | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| #else  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) | ||||
| // 168 and 328 Arduinos | ||||
|  | ||||
| // Two Wire (aka I2C) ports | ||||
| uint8_t const SDA_PIN = 18; | ||||
| uint8_t const SCL_PIN = 19; | ||||
|  | ||||
| // SPI port | ||||
| uint8_t const SS_PIN = 10; | ||||
| uint8_t const MOSI_PIN = 11; | ||||
| uint8_t const MISO_PIN = 12; | ||||
| uint8_t const SCK_PIN = 13; | ||||
|  | ||||
| static const pin_map_t digitalPinMap[] = { | ||||
|   {&DDRD, &PIND, &PORTD, 0},  // D0  0 | ||||
|   {&DDRD, &PIND, &PORTD, 1},  // D1  1 | ||||
|   {&DDRD, &PIND, &PORTD, 2},  // D2  2 | ||||
|   {&DDRD, &PIND, &PORTD, 3},  // D3  3 | ||||
|   {&DDRD, &PIND, &PORTD, 4},  // D4  4 | ||||
|   {&DDRD, &PIND, &PORTD, 5},  // D5  5 | ||||
|   {&DDRD, &PIND, &PORTD, 6},  // D6  6 | ||||
|   {&DDRD, &PIND, &PORTD, 7},  // D7  7 | ||||
|   {&DDRB, &PINB, &PORTB, 0},  // B0  8 | ||||
|   {&DDRB, &PINB, &PORTB, 1},  // B1  9 | ||||
|   {&DDRB, &PINB, &PORTB, 2},  // B2 10 | ||||
|   {&DDRB, &PINB, &PORTB, 3},  // B3 11 | ||||
|   {&DDRB, &PINB, &PORTB, 4},  // B4 12 | ||||
|   {&DDRB, &PINB, &PORTB, 5},  // B5 13 | ||||
|   {&DDRC, &PINC, &PORTC, 0},  // C0 14 | ||||
|   {&DDRC, &PINC, &PORTC, 1},  // C1 15 | ||||
|   {&DDRC, &PINC, &PORTC, 2},  // C2 16 | ||||
|   {&DDRC, &PINC, &PORTC, 3},  // C3 17 | ||||
|   {&DDRC, &PINC, &PORTC, 4},  // C4 18 | ||||
|   {&DDRC, &PINC, &PORTC, 5}   // C5 19 | ||||
| }; | ||||
| #endif  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) | ||||
| //------------------------------------------------------------------------------ | ||||
| static const uint8_t digitalPinCount = sizeof(digitalPinMap)/sizeof(pin_map_t); | ||||
|  | ||||
| uint8_t badPinNumber(void) | ||||
|   __attribute__((error("Pin number is too large or not a constant"))); | ||||
|  | ||||
| static inline __attribute__((always_inline)) | ||||
|   uint8_t getPinMode(uint8_t pin) { | ||||
|   if (__builtin_constant_p(pin) && pin < digitalPinCount) { | ||||
|     return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1; | ||||
|   } else { | ||||
|     return badPinNumber(); | ||||
|   } | ||||
| } | ||||
| static inline __attribute__((always_inline)) | ||||
|   void setPinMode(uint8_t pin, uint8_t mode) { | ||||
|   if (__builtin_constant_p(pin) && pin < digitalPinCount) { | ||||
|     if (mode) { | ||||
|       *digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit; | ||||
|     } else { | ||||
|       *digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit); | ||||
|     } | ||||
|   } else { | ||||
|     badPinNumber(); | ||||
|   } | ||||
| } | ||||
| static inline __attribute__((always_inline)) | ||||
|   uint8_t fastDigitalRead(uint8_t pin) { | ||||
|   if (__builtin_constant_p(pin) && pin < digitalPinCount) { | ||||
|     return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1; | ||||
|   } else { | ||||
|     return badPinNumber(); | ||||
|   } | ||||
| } | ||||
| static inline __attribute__((always_inline)) | ||||
|   void fastDigitalWrite(uint8_t pin, uint8_t value) { | ||||
|   if (__builtin_constant_p(pin) && pin < digitalPinCount) { | ||||
|     if (value) { | ||||
|       *digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit; | ||||
|     } else { | ||||
|       *digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit); | ||||
|     } | ||||
|   } else { | ||||
|     badPinNumber(); | ||||
|   } | ||||
| } | ||||
| #endif  // Sd2PinMap_h | ||||
| /* Arduino SdFat Library | ||||
|  * Copyright (C) 2010 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino SdFat Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino SdFat Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| // Warning this file was generated by a program. | ||||
| #ifndef Sd2PinMap_h | ||||
| #define Sd2PinMap_h | ||||
| #include <avr/io.h> | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| /** struct for mapping digital pins */ | ||||
| struct pin_map_t { | ||||
|   volatile uint8_t* ddr; | ||||
|   volatile uint8_t* pin; | ||||
|   volatile uint8_t* port; | ||||
|   uint8_t bit; | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) | ||||
| // Mega | ||||
|  | ||||
| // Two Wire (aka I2C) ports | ||||
| uint8_t const SDA_PIN = 20; | ||||
| uint8_t const SCL_PIN = 21; | ||||
|  | ||||
| // SPI port | ||||
| uint8_t const SS_PIN = 53; | ||||
| uint8_t const MOSI_PIN = 51; | ||||
| uint8_t const MISO_PIN = 50; | ||||
| uint8_t const SCK_PIN = 52; | ||||
|  | ||||
| static const pin_map_t digitalPinMap[] = { | ||||
|   {&DDRE, &PINE, &PORTE, 0},  // E0  0 | ||||
|   {&DDRE, &PINE, &PORTE, 1},  // E1  1 | ||||
|   {&DDRE, &PINE, &PORTE, 4},  // E4  2 | ||||
|   {&DDRE, &PINE, &PORTE, 5},  // E5  3 | ||||
|   {&DDRG, &PING, &PORTG, 5},  // G5  4 | ||||
|   {&DDRE, &PINE, &PORTE, 3},  // E3  5 | ||||
|   {&DDRH, &PINH, &PORTH, 3},  // H3  6 | ||||
|   {&DDRH, &PINH, &PORTH, 4},  // H4  7 | ||||
|   {&DDRH, &PINH, &PORTH, 5},  // H5  8 | ||||
|   {&DDRH, &PINH, &PORTH, 6},  // H6  9 | ||||
|   {&DDRB, &PINB, &PORTB, 4},  // B4 10 | ||||
|   {&DDRB, &PINB, &PORTB, 5},  // B5 11 | ||||
|   {&DDRB, &PINB, &PORTB, 6},  // B6 12 | ||||
|   {&DDRB, &PINB, &PORTB, 7},  // B7 13 | ||||
|   {&DDRJ, &PINJ, &PORTJ, 1},  // J1 14 | ||||
|   {&DDRJ, &PINJ, &PORTJ, 0},  // J0 15 | ||||
|   {&DDRH, &PINH, &PORTH, 1},  // H1 16 | ||||
|   {&DDRH, &PINH, &PORTH, 0},  // H0 17 | ||||
|   {&DDRD, &PIND, &PORTD, 3},  // D3 18 | ||||
|   {&DDRD, &PIND, &PORTD, 2},  // D2 19 | ||||
|   {&DDRD, &PIND, &PORTD, 1},  // D1 20 | ||||
|   {&DDRD, &PIND, &PORTD, 0},  // D0 21 | ||||
|   {&DDRA, &PINA, &PORTA, 0},  // A0 22 | ||||
|   {&DDRA, &PINA, &PORTA, 1},  // A1 23 | ||||
|   {&DDRA, &PINA, &PORTA, 2},  // A2 24 | ||||
|   {&DDRA, &PINA, &PORTA, 3},  // A3 25 | ||||
|   {&DDRA, &PINA, &PORTA, 4},  // A4 26 | ||||
|   {&DDRA, &PINA, &PORTA, 5},  // A5 27 | ||||
|   {&DDRA, &PINA, &PORTA, 6},  // A6 28 | ||||
|   {&DDRA, &PINA, &PORTA, 7},  // A7 29 | ||||
|   {&DDRC, &PINC, &PORTC, 7},  // C7 30 | ||||
|   {&DDRC, &PINC, &PORTC, 6},  // C6 31 | ||||
|   {&DDRC, &PINC, &PORTC, 5},  // C5 32 | ||||
|   {&DDRC, &PINC, &PORTC, 4},  // C4 33 | ||||
|   {&DDRC, &PINC, &PORTC, 3},  // C3 34 | ||||
|   {&DDRC, &PINC, &PORTC, 2},  // C2 35 | ||||
|   {&DDRC, &PINC, &PORTC, 1},  // C1 36 | ||||
|   {&DDRC, &PINC, &PORTC, 0},  // C0 37 | ||||
|   {&DDRD, &PIND, &PORTD, 7},  // D7 38 | ||||
|   {&DDRG, &PING, &PORTG, 2},  // G2 39 | ||||
|   {&DDRG, &PING, &PORTG, 1},  // G1 40 | ||||
|   {&DDRG, &PING, &PORTG, 0},  // G0 41 | ||||
|   {&DDRL, &PINL, &PORTL, 7},  // L7 42 | ||||
|   {&DDRL, &PINL, &PORTL, 6},  // L6 43 | ||||
|   {&DDRL, &PINL, &PORTL, 5},  // L5 44 | ||||
|   {&DDRL, &PINL, &PORTL, 4},  // L4 45 | ||||
|   {&DDRL, &PINL, &PORTL, 3},  // L3 46 | ||||
|   {&DDRL, &PINL, &PORTL, 2},  // L2 47 | ||||
|   {&DDRL, &PINL, &PORTL, 1},  // L1 48 | ||||
|   {&DDRL, &PINL, &PORTL, 0},  // L0 49 | ||||
|   {&DDRB, &PINB, &PORTB, 3},  // B3 50 | ||||
|   {&DDRB, &PINB, &PORTB, 2},  // B2 51 | ||||
|   {&DDRB, &PINB, &PORTB, 1},  // B1 52 | ||||
|   {&DDRB, &PINB, &PORTB, 0},  // B0 53 | ||||
|   {&DDRF, &PINF, &PORTF, 0},  // F0 54 | ||||
|   {&DDRF, &PINF, &PORTF, 1},  // F1 55 | ||||
|   {&DDRF, &PINF, &PORTF, 2},  // F2 56 | ||||
|   {&DDRF, &PINF, &PORTF, 3},  // F3 57 | ||||
|   {&DDRF, &PINF, &PORTF, 4},  // F4 58 | ||||
|   {&DDRF, &PINF, &PORTF, 5},  // F5 59 | ||||
|   {&DDRF, &PINF, &PORTF, 6},  // F6 60 | ||||
|   {&DDRF, &PINF, &PORTF, 7},  // F7 61 | ||||
|   {&DDRK, &PINK, &PORTK, 0},  // K0 62 | ||||
|   {&DDRK, &PINK, &PORTK, 1},  // K1 63 | ||||
|   {&DDRK, &PINK, &PORTK, 2},  // K2 64 | ||||
|   {&DDRK, &PINK, &PORTK, 3},  // K3 65 | ||||
|   {&DDRK, &PINK, &PORTK, 4},  // K4 66 | ||||
|   {&DDRK, &PINK, &PORTK, 5},  // K5 67 | ||||
|   {&DDRK, &PINK, &PORTK, 6},  // K6 68 | ||||
|   {&DDRK, &PINK, &PORTK, 7}   // K7 69 | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) | ||||
| // Sanguino | ||||
|  | ||||
| // Two Wire (aka I2C) ports | ||||
| uint8_t const SDA_PIN = 17; | ||||
| uint8_t const SCL_PIN = 18; | ||||
|  | ||||
| // SPI port | ||||
| uint8_t const SS_PIN = 4; | ||||
| uint8_t const MOSI_PIN = 5; | ||||
| uint8_t const MISO_PIN = 6; | ||||
| uint8_t const SCK_PIN = 7; | ||||
|  | ||||
| static const pin_map_t digitalPinMap[] = { | ||||
|   {&DDRB, &PINB, &PORTB, 0},  // B0  0 | ||||
|   {&DDRB, &PINB, &PORTB, 1},  // B1  1 | ||||
|   {&DDRB, &PINB, &PORTB, 2},  // B2  2 | ||||
|   {&DDRB, &PINB, &PORTB, 3},  // B3  3 | ||||
|   {&DDRB, &PINB, &PORTB, 4},  // B4  4 | ||||
|   {&DDRB, &PINB, &PORTB, 5},  // B5  5 | ||||
|   {&DDRB, &PINB, &PORTB, 6},  // B6  6 | ||||
|   {&DDRB, &PINB, &PORTB, 7},  // B7  7 | ||||
|   {&DDRD, &PIND, &PORTD, 0},  // D0  8 | ||||
|   {&DDRD, &PIND, &PORTD, 1},  // D1  9 | ||||
|   {&DDRD, &PIND, &PORTD, 2},  // D2 10 | ||||
|   {&DDRD, &PIND, &PORTD, 3},  // D3 11 | ||||
|   {&DDRD, &PIND, &PORTD, 4},  // D4 12 | ||||
|   {&DDRD, &PIND, &PORTD, 5},  // D5 13 | ||||
|   {&DDRD, &PIND, &PORTD, 6},  // D6 14 | ||||
|   {&DDRD, &PIND, &PORTD, 7},  // D7 15 | ||||
|   {&DDRC, &PINC, &PORTC, 0},  // C0 16 | ||||
|   {&DDRC, &PINC, &PORTC, 1},  // C1 17 | ||||
|   {&DDRC, &PINC, &PORTC, 2},  // C2 18 | ||||
|   {&DDRC, &PINC, &PORTC, 3},  // C3 19 | ||||
|   {&DDRC, &PINC, &PORTC, 4},  // C4 20 | ||||
|   {&DDRC, &PINC, &PORTC, 5},  // C5 21 | ||||
|   {&DDRC, &PINC, &PORTC, 6},  // C6 22 | ||||
|   {&DDRC, &PINC, &PORTC, 7},  // C7 23 | ||||
|   {&DDRA, &PINA, &PORTA, 7},  // A7 24 | ||||
|   {&DDRA, &PINA, &PORTA, 6},  // A6 25 | ||||
|   {&DDRA, &PINA, &PORTA, 5},  // A5 26 | ||||
|   {&DDRA, &PINA, &PORTA, 4},  // A4 27 | ||||
|   {&DDRA, &PINA, &PORTA, 3},  // A3 28 | ||||
|   {&DDRA, &PINA, &PORTA, 2},  // A2 29 | ||||
|   {&DDRA, &PINA, &PORTA, 1},  // A1 30 | ||||
|   {&DDRA, &PINA, &PORTA, 0}   // A0 31 | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| #elif defined(__AVR_ATmega32U4__) | ||||
| // Teensy 2.0 | ||||
|  | ||||
| // Two Wire (aka I2C) ports | ||||
| uint8_t const SDA_PIN = 6; | ||||
| uint8_t const SCL_PIN = 5; | ||||
|  | ||||
| // SPI port | ||||
| uint8_t const SS_PIN = 0; | ||||
| uint8_t const MOSI_PIN = 2; | ||||
| uint8_t const MISO_PIN = 3; | ||||
| uint8_t const SCK_PIN = 1; | ||||
|  | ||||
| static const pin_map_t digitalPinMap[] = { | ||||
|   {&DDRB, &PINB, &PORTB, 0},  // B0  0 | ||||
|   {&DDRB, &PINB, &PORTB, 1},  // B1  1 | ||||
|   {&DDRB, &PINB, &PORTB, 2},  // B2  2 | ||||
|   {&DDRB, &PINB, &PORTB, 3},  // B3  3 | ||||
|   {&DDRB, &PINB, &PORTB, 7},  // B7  4 | ||||
|   {&DDRD, &PIND, &PORTD, 0},  // D0  5 | ||||
|   {&DDRD, &PIND, &PORTD, 1},  // D1  6 | ||||
|   {&DDRD, &PIND, &PORTD, 2},  // D2  7 | ||||
|   {&DDRD, &PIND, &PORTD, 3},  // D3  8 | ||||
|   {&DDRC, &PINC, &PORTC, 6},  // C6  9 | ||||
|   {&DDRC, &PINC, &PORTC, 7},  // C7 10 | ||||
|   {&DDRD, &PIND, &PORTD, 6},  // D6 11 | ||||
|   {&DDRD, &PIND, &PORTD, 7},  // D7 12 | ||||
|   {&DDRB, &PINB, &PORTB, 4},  // B4 13 | ||||
|   {&DDRB, &PINB, &PORTB, 5},  // B5 14 | ||||
|   {&DDRB, &PINB, &PORTB, 6},  // B6 15 | ||||
|   {&DDRF, &PINF, &PORTF, 7},  // F7 16 | ||||
|   {&DDRF, &PINF, &PORTF, 6},  // F6 17 | ||||
|   {&DDRF, &PINF, &PORTF, 5},  // F5 18 | ||||
|   {&DDRF, &PINF, &PORTF, 4},  // F4 19 | ||||
|   {&DDRF, &PINF, &PORTF, 1},  // F1 20 | ||||
|   {&DDRF, &PINF, &PORTF, 0},  // F0 21 | ||||
|   {&DDRD, &PIND, &PORTD, 4},  // D4 22 | ||||
|   {&DDRD, &PIND, &PORTD, 5},  // D5 23 | ||||
|   {&DDRE, &PINE, &PORTE, 6}   // E6 24 | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) | ||||
| // Teensy++ 1.0 & 2.0 | ||||
|  | ||||
| // Two Wire (aka I2C) ports | ||||
| uint8_t const SDA_PIN = 1; | ||||
| uint8_t const SCL_PIN = 0; | ||||
|  | ||||
| // SPI port | ||||
| uint8_t const SS_PIN = 20; | ||||
| uint8_t const MOSI_PIN = 22; | ||||
| uint8_t const MISO_PIN = 23; | ||||
| uint8_t const SCK_PIN = 21; | ||||
|  | ||||
| static const pin_map_t digitalPinMap[] = { | ||||
|   {&DDRD, &PIND, &PORTD, 0},  // D0  0 | ||||
|   {&DDRD, &PIND, &PORTD, 1},  // D1  1 | ||||
|   {&DDRD, &PIND, &PORTD, 2},  // D2  2 | ||||
|   {&DDRD, &PIND, &PORTD, 3},  // D3  3 | ||||
|   {&DDRD, &PIND, &PORTD, 4},  // D4  4 | ||||
|   {&DDRD, &PIND, &PORTD, 5},  // D5  5 | ||||
|   {&DDRD, &PIND, &PORTD, 6},  // D6  6 | ||||
|   {&DDRD, &PIND, &PORTD, 7},  // D7  7 | ||||
|   {&DDRE, &PINE, &PORTE, 0},  // E0  8 | ||||
|   {&DDRE, &PINE, &PORTE, 1},  // E1  9 | ||||
|   {&DDRC, &PINC, &PORTC, 0},  // C0 10 | ||||
|   {&DDRC, &PINC, &PORTC, 1},  // C1 11 | ||||
|   {&DDRC, &PINC, &PORTC, 2},  // C2 12 | ||||
|   {&DDRC, &PINC, &PORTC, 3},  // C3 13 | ||||
|   {&DDRC, &PINC, &PORTC, 4},  // C4 14 | ||||
|   {&DDRC, &PINC, &PORTC, 5},  // C5 15 | ||||
|   {&DDRC, &PINC, &PORTC, 6},  // C6 16 | ||||
|   {&DDRC, &PINC, &PORTC, 7},  // C7 17 | ||||
|   {&DDRE, &PINE, &PORTE, 6},  // E6 18 | ||||
|   {&DDRE, &PINE, &PORTE, 7},  // E7 19 | ||||
|   {&DDRB, &PINB, &PORTB, 0},  // B0 20 | ||||
|   {&DDRB, &PINB, &PORTB, 1},  // B1 21 | ||||
|   {&DDRB, &PINB, &PORTB, 2},  // B2 22 | ||||
|   {&DDRB, &PINB, &PORTB, 3},  // B3 23 | ||||
|   {&DDRB, &PINB, &PORTB, 4},  // B4 24 | ||||
|   {&DDRB, &PINB, &PORTB, 5},  // B5 25 | ||||
|   {&DDRB, &PINB, &PORTB, 6},  // B6 26 | ||||
|   {&DDRB, &PINB, &PORTB, 7},  // B7 27 | ||||
|   {&DDRA, &PINA, &PORTA, 0},  // A0 28 | ||||
|   {&DDRA, &PINA, &PORTA, 1},  // A1 29 | ||||
|   {&DDRA, &PINA, &PORTA, 2},  // A2 30 | ||||
|   {&DDRA, &PINA, &PORTA, 3},  // A3 31 | ||||
|   {&DDRA, &PINA, &PORTA, 4},  // A4 32 | ||||
|   {&DDRA, &PINA, &PORTA, 5},  // A5 33 | ||||
|   {&DDRA, &PINA, &PORTA, 6},  // A6 34 | ||||
|   {&DDRA, &PINA, &PORTA, 7},  // A7 35 | ||||
|   {&DDRE, &PINE, &PORTE, 4},  // E4 36 | ||||
|   {&DDRE, &PINE, &PORTE, 5},  // E5 37 | ||||
|   {&DDRF, &PINF, &PORTF, 0},  // F0 38 | ||||
|   {&DDRF, &PINF, &PORTF, 1},  // F1 39 | ||||
|   {&DDRF, &PINF, &PORTF, 2},  // F2 40 | ||||
|   {&DDRF, &PINF, &PORTF, 3},  // F3 41 | ||||
|   {&DDRF, &PINF, &PORTF, 4},  // F4 42 | ||||
|   {&DDRF, &PINF, &PORTF, 5},  // F5 43 | ||||
|   {&DDRF, &PINF, &PORTF, 6},  // F6 44 | ||||
|   {&DDRF, &PINF, &PORTF, 7}   // F7 45 | ||||
| }; | ||||
| //------------------------------------------------------------------------------ | ||||
| #else  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) | ||||
| // 168 and 328 Arduinos | ||||
|  | ||||
| // Two Wire (aka I2C) ports | ||||
| uint8_t const SDA_PIN = 18; | ||||
| uint8_t const SCL_PIN = 19; | ||||
|  | ||||
| // SPI port | ||||
| uint8_t const SS_PIN = 10; | ||||
| uint8_t const MOSI_PIN = 11; | ||||
| uint8_t const MISO_PIN = 12; | ||||
| uint8_t const SCK_PIN = 13; | ||||
|  | ||||
| static const pin_map_t digitalPinMap[] = { | ||||
|   {&DDRD, &PIND, &PORTD, 0},  // D0  0 | ||||
|   {&DDRD, &PIND, &PORTD, 1},  // D1  1 | ||||
|   {&DDRD, &PIND, &PORTD, 2},  // D2  2 | ||||
|   {&DDRD, &PIND, &PORTD, 3},  // D3  3 | ||||
|   {&DDRD, &PIND, &PORTD, 4},  // D4  4 | ||||
|   {&DDRD, &PIND, &PORTD, 5},  // D5  5 | ||||
|   {&DDRD, &PIND, &PORTD, 6},  // D6  6 | ||||
|   {&DDRD, &PIND, &PORTD, 7},  // D7  7 | ||||
|   {&DDRB, &PINB, &PORTB, 0},  // B0  8 | ||||
|   {&DDRB, &PINB, &PORTB, 1},  // B1  9 | ||||
|   {&DDRB, &PINB, &PORTB, 2},  // B2 10 | ||||
|   {&DDRB, &PINB, &PORTB, 3},  // B3 11 | ||||
|   {&DDRB, &PINB, &PORTB, 4},  // B4 12 | ||||
|   {&DDRB, &PINB, &PORTB, 5},  // B5 13 | ||||
|   {&DDRC, &PINC, &PORTC, 0},  // C0 14 | ||||
|   {&DDRC, &PINC, &PORTC, 1},  // C1 15 | ||||
|   {&DDRC, &PINC, &PORTC, 2},  // C2 16 | ||||
|   {&DDRC, &PINC, &PORTC, 3},  // C3 17 | ||||
|   {&DDRC, &PINC, &PORTC, 4},  // C4 18 | ||||
|   {&DDRC, &PINC, &PORTC, 5}   // C5 19 | ||||
| }; | ||||
| #endif  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) | ||||
| //------------------------------------------------------------------------------ | ||||
| static const uint8_t digitalPinCount = sizeof(digitalPinMap)/sizeof(pin_map_t); | ||||
|  | ||||
| uint8_t badPinNumber(void) | ||||
|   __attribute__((error("Pin number is too large or not a constant"))); | ||||
|  | ||||
| static inline __attribute__((always_inline)) | ||||
|   uint8_t getPinMode(uint8_t pin) { | ||||
|   if (__builtin_constant_p(pin) && pin < digitalPinCount) { | ||||
|     return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1; | ||||
|   } else { | ||||
|     return badPinNumber(); | ||||
|   } | ||||
| } | ||||
| static inline __attribute__((always_inline)) | ||||
|   void setPinMode(uint8_t pin, uint8_t mode) { | ||||
|   if (__builtin_constant_p(pin) && pin < digitalPinCount) { | ||||
|     if (mode) { | ||||
|       *digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit; | ||||
|     } else { | ||||
|       *digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit); | ||||
|     } | ||||
|   } else { | ||||
|     badPinNumber(); | ||||
|   } | ||||
| } | ||||
| static inline __attribute__((always_inline)) | ||||
|   uint8_t fastDigitalRead(uint8_t pin) { | ||||
|   if (__builtin_constant_p(pin) && pin < digitalPinCount) { | ||||
|     return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1; | ||||
|   } else { | ||||
|     return badPinNumber(); | ||||
|   } | ||||
| } | ||||
| static inline __attribute__((always_inline)) | ||||
|   void fastDigitalWrite(uint8_t pin, uint8_t value) { | ||||
|   if (__builtin_constant_p(pin) && pin < digitalPinCount) { | ||||
|     if (value) { | ||||
|       *digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit; | ||||
|     } else { | ||||
|       *digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit); | ||||
|     } | ||||
|   } else { | ||||
|     badPinNumber(); | ||||
|   } | ||||
| } | ||||
| #endif  // Sd2PinMap_h | ||||
|   | ||||
							
								
								
									
										1094
									
								
								Marlin/SdFat.h
									
									
									
									
									
								
							
							
						
						
									
										1094
									
								
								Marlin/SdFat.h
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,70 +1,70 @@ | ||||
| /* Arduino SdFat Library | ||||
|  * Copyright (C) 2008 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino SdFat Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino SdFat Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| #ifndef SdFatUtil_h | ||||
| #define SdFatUtil_h | ||||
| /** | ||||
|  * \file | ||||
|  * Useful utility functions. | ||||
|  */ | ||||
| #include <WProgram.h> | ||||
| #include <avr/pgmspace.h> | ||||
| /** Store and print a string in flash memory.*/ | ||||
| #define PgmPrint(x) SerialPrint_P(PSTR(x)) | ||||
| /** Store and print a string in flash memory followed by a CR/LF.*/ | ||||
| #define PgmPrintln(x) SerialPrintln_P(PSTR(x)) | ||||
| /** Defined so doxygen works for function definitions. */ | ||||
| #define NOINLINE __attribute__((noinline)) | ||||
| //------------------------------------------------------------------------------ | ||||
| /** Return the number of bytes currently free in RAM. */ | ||||
| static int FreeRam(void) { | ||||
|   extern int  __bss_end; | ||||
|   extern int* __brkval; | ||||
|   int free_memory; | ||||
|   if (reinterpret_cast<int>(__brkval) == 0) { | ||||
|     // if no heap use from end of bss section | ||||
|     free_memory = reinterpret_cast<int>(&free_memory) | ||||
|                   - reinterpret_cast<int>(&__bss_end); | ||||
|   } else { | ||||
|     // use from top of stack to heap | ||||
|     free_memory = reinterpret_cast<int>(&free_memory) | ||||
|                   - reinterpret_cast<int>(__brkval); | ||||
|   } | ||||
|   return free_memory; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * %Print a string in flash memory to the serial port. | ||||
|  * | ||||
|  * \param[in] str Pointer to string stored in flash memory. | ||||
|  */ | ||||
| static NOINLINE void SerialPrint_P(PGM_P str) { | ||||
|   for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.print(c); | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * %Print a string in flash memory followed by a CR/LF. | ||||
|  * | ||||
|  * \param[in] str Pointer to string stored in flash memory. | ||||
|  */ | ||||
| static NOINLINE void SerialPrintln_P(PGM_P str) { | ||||
|   SerialPrint_P(str); | ||||
|   Serial.println(); | ||||
| } | ||||
| #endif  // #define SdFatUtil_h | ||||
| /* Arduino SdFat Library | ||||
|  * Copyright (C) 2008 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino SdFat Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino SdFat Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| #ifndef SdFatUtil_h | ||||
| #define SdFatUtil_h | ||||
| /** | ||||
|  * \file | ||||
|  * Useful utility functions. | ||||
|  */ | ||||
| #include <WProgram.h> | ||||
| #include <avr/pgmspace.h> | ||||
| /** Store and print a string in flash memory.*/ | ||||
| #define PgmPrint(x) SerialPrint_P(PSTR(x)) | ||||
| /** Store and print a string in flash memory followed by a CR/LF.*/ | ||||
| #define PgmPrintln(x) SerialPrintln_P(PSTR(x)) | ||||
| /** Defined so doxygen works for function definitions. */ | ||||
| #define NOINLINE __attribute__((noinline)) | ||||
| //------------------------------------------------------------------------------ | ||||
| /** Return the number of bytes currently free in RAM. */ | ||||
| static int FreeRam(void) { | ||||
|   extern int  __bss_end; | ||||
|   extern int* __brkval; | ||||
|   int free_memory; | ||||
|   if (reinterpret_cast<int>(__brkval) == 0) { | ||||
|     // if no heap use from end of bss section | ||||
|     free_memory = reinterpret_cast<int>(&free_memory) | ||||
|                   - reinterpret_cast<int>(&__bss_end); | ||||
|   } else { | ||||
|     // use from top of stack to heap | ||||
|     free_memory = reinterpret_cast<int>(&free_memory) | ||||
|                   - reinterpret_cast<int>(__brkval); | ||||
|   } | ||||
|   return free_memory; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * %Print a string in flash memory to the serial port. | ||||
|  * | ||||
|  * \param[in] str Pointer to string stored in flash memory. | ||||
|  */ | ||||
| static NOINLINE void SerialPrint_P(PGM_P str) { | ||||
|   for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.print(c); | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * %Print a string in flash memory followed by a CR/LF. | ||||
|  * | ||||
|  * \param[in] str Pointer to string stored in flash memory. | ||||
|  */ | ||||
| static NOINLINE void SerialPrintln_P(PGM_P str) { | ||||
|   SerialPrint_P(str); | ||||
|   Serial.println(); | ||||
| } | ||||
| #endif  // #define SdFatUtil_h | ||||
|   | ||||
| @@ -1,202 +1,202 @@ | ||||
| /* Arduino SdFat Library | ||||
|  * Copyright (C) 2009 by William Greiman | ||||
|  *   | ||||
|  * This file is part of the Arduino SdFat Library | ||||
|  *   | ||||
|  * This Library is free software: you can redistribute it and/or modify  | ||||
|  * it under the terms of the GNU General Public License as published by  | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  *  | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino SdFat Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
| \mainpage Arduino SdFat Library | ||||
| <CENTER>Copyright © 2009 by William Greiman | ||||
| </CENTER> | ||||
|  | ||||
| \section Intro Introduction | ||||
| The Arduino SdFat Library is a minimal implementation of FAT16 and FAT32 | ||||
| file systems on SD flash memory cards.  Standard SD and high capacity | ||||
| SDHC cards are supported. | ||||
|  | ||||
| The SdFat only supports short 8.3 names. | ||||
|  | ||||
| The main classes in SdFat are Sd2Card, SdVolume, and SdFile. | ||||
|  | ||||
| The Sd2Card class supports access to standard SD cards and SDHC cards.  Most | ||||
| applications will only need to call the Sd2Card::init() member function. | ||||
|  | ||||
| The SdVolume class supports FAT16 and FAT32 partitions.  Most applications | ||||
| will only need to call the SdVolume::init() member function. | ||||
|  | ||||
| The SdFile class provides file access functions such as open(), read(), | ||||
| remove(), write(), close() and sync(). This class supports access to the root | ||||
| directory and subdirectories. | ||||
|  | ||||
| A number of example are provided in the SdFat/examples folder.  These were | ||||
| developed to test SdFat and illustrate its use. | ||||
|  | ||||
| SdFat was developed for high speed data recording.  SdFat was used to implement | ||||
| an audio record/play class, WaveRP, for the Adafruit Wave Shield.  This | ||||
| application uses special Sd2Card calls to write to contiguous files in raw mode. | ||||
| These functions reduce write latency so that audio can be recorded with the | ||||
| small amount of RAM in the Arduino. | ||||
|  | ||||
| \section SDcard SD\SDHC Cards | ||||
|  | ||||
| Arduinos access SD cards using the cards SPI protocol.  PCs, Macs, and | ||||
| most consumer devices use the 4-bit parallel SD protocol.  A card that | ||||
| functions well on A PC or Mac may not work well on the Arduino. | ||||
|  | ||||
| Most cards have good SPI read performance but cards vary widely in SPI | ||||
| write performance.  Write performance is limited by how efficiently the | ||||
| card manages internal erase/remapping operations.  The Arduino cannot | ||||
| optimize writes to reduce erase operations because of its limit RAM. | ||||
|  | ||||
| SanDisk cards generally have good write performance.  They seem to have | ||||
| more internal RAM buffering than other cards and therefore can limit | ||||
| the number of flash erase operations that the Arduino forces due to its | ||||
| limited RAM. | ||||
|  | ||||
| \section Hardware Hardware Configuration | ||||
|  | ||||
| SdFat was developed using an | ||||
| <A HREF = "http://www.adafruit.com/"> Adafruit Industries</A>  | ||||
| <A HREF = "http://www.ladyada.net/make/waveshield/"> Wave Shield</A>. | ||||
|  | ||||
| The hardware interface to the SD card should not use a resistor based level | ||||
| shifter.  SdFat sets the SPI bus frequency to 8 MHz which results in signal | ||||
| rise times that are too slow for the edge detectors in many newer SD card | ||||
| controllers when resistor voltage dividers are used. | ||||
|  | ||||
| The 5 to 3.3 V level shifter for 5 V Arduinos should be IC based like the | ||||
| 74HC4050N based circuit shown in the file SdLevel.png.  The Adafruit Wave Shield | ||||
| uses a 74AHC125N.  Gravitech sells SD and MicroSD Card Adapters based on the | ||||
| 74LCX245. | ||||
|  | ||||
| If you are using a resistor based level shifter and are having problems try | ||||
| setting the SPI bus frequency to 4 MHz.  This can be done by using  | ||||
| card.init(SPI_HALF_SPEED) to initialize the SD card. | ||||
|  | ||||
| \section comment Bugs and Comments | ||||
|  | ||||
| If you wish to report bugs or have comments, send email to fat16lib@sbcglobal.net. | ||||
|  | ||||
| \section SdFatClass SdFat Usage | ||||
|  | ||||
| SdFat uses a slightly restricted form of short names. | ||||
| Only printable ASCII characters are supported. No characters with code point | ||||
| values greater than 127 are allowed.  Space is not allowed even though space | ||||
| was allowed in the API of early versions of DOS. | ||||
|  | ||||
| Short names are limited to 8 characters followed by an optional period (.) | ||||
| and extension of up to 3 characters.  The characters may be any combination | ||||
| of letters and digits.  The following special characters are also allowed: | ||||
|  | ||||
| $ % ' - _ @ ~ ` ! ( ) { } ^ # & | ||||
|  | ||||
| Short names are always converted to upper case and their original case | ||||
| value is lost. | ||||
|  | ||||
| \note | ||||
|   The Arduino Print class uses character | ||||
| at a time writes so it was necessary to use a \link SdFile::sync() sync() \endlink | ||||
| function to control when data is written to the SD card. | ||||
|  | ||||
| \par | ||||
| An application which writes to a file using \link Print::print() print()\endlink, | ||||
| \link Print::println() println() \endlink | ||||
| or \link SdFile::write write() \endlink must call \link SdFile::sync() sync() \endlink | ||||
| at the appropriate time to force data and directory information to be written | ||||
| to the SD Card.  Data and directory information are also written to the SD card | ||||
| when \link SdFile::close() close() \endlink is called. | ||||
|  | ||||
| \par | ||||
| Applications must use care calling \link SdFile::sync() sync() \endlink | ||||
| since 2048 bytes of I/O is required to update file and | ||||
| directory information.  This includes writing the current data block, reading | ||||
| the block that contains the directory entry for update, writing the directory | ||||
| block back and reading back the current data block. | ||||
|  | ||||
| It is possible to open a file with two or more instances of SdFile.  A file may | ||||
| be corrupted if data is written to the file by more than one instance of SdFile. | ||||
|  | ||||
| \section HowTo How to format SD Cards as FAT Volumes | ||||
|  | ||||
| You should use a freshly formatted SD card for best performance.  FAT | ||||
| file systems become slower if many files have been created and deleted. | ||||
| This is because the directory entry for a deleted file is marked as deleted, | ||||
| but is not deleted.  When a new file is created, these entries must be scanned | ||||
| before creating the file, a flaw in the FAT design.  Also files can become | ||||
| fragmented which causes reads and writes to be slower. | ||||
|  | ||||
| Microsoft operating systems support removable media formatted with a | ||||
| Master Boot Record, MBR, or formatted as a super floppy with a FAT Boot Sector | ||||
| in block zero. | ||||
|  | ||||
| Microsoft operating systems expect MBR formatted removable media | ||||
| to have only one partition. The first partition should be used. | ||||
|  | ||||
| Microsoft operating systems do not support partitioning SD flash cards. | ||||
| If you erase an SD card with a program like KillDisk, Most versions of | ||||
| Windows will format the card as a super floppy. | ||||
|  | ||||
| The best way to restore an SD card's format is to use SDFormatter | ||||
| which can be downloaded from: | ||||
|  | ||||
| http://www.sdcard.org/consumers/formatter/ | ||||
|  | ||||
| SDFormatter aligns flash erase boundaries with file | ||||
| system structures which reduces write latency and file system overhead. | ||||
|  | ||||
| SDFormatter does not have an option for FAT type so it may format | ||||
| small cards as FAT12. | ||||
|  | ||||
| After the MBR is restored by SDFormatter you may need to reformat small | ||||
| cards that have been formatted FAT12 to force the volume type to be FAT16. | ||||
|  | ||||
| If you reformat the SD card with an OS utility, choose a cluster size that | ||||
| will result in: | ||||
|  | ||||
| 4084 < CountOfClusters && CountOfClusters < 65525 | ||||
|  | ||||
| The volume will then be FAT16. | ||||
|  | ||||
| If you are formatting an SD card on OS X or Linux, be sure to use the first | ||||
| partition. Format this partition with a cluster count in above range. | ||||
|  | ||||
| \section  References References | ||||
|  | ||||
| Adafruit Industries: | ||||
|  | ||||
| http://www.adafruit.com/ | ||||
|  | ||||
| http://www.ladyada.net/make/waveshield/ | ||||
|  | ||||
| The Arduino site: | ||||
|  | ||||
| http://www.arduino.cc/ | ||||
|  | ||||
| For more information about FAT file systems see: | ||||
|  | ||||
| http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx | ||||
|  | ||||
| For information about using SD cards as SPI devices see: | ||||
|  | ||||
| http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf | ||||
|  | ||||
| The ATmega328 datasheet: | ||||
|  | ||||
| http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf | ||||
|   | ||||
|  | ||||
|  */   | ||||
| /* Arduino SdFat Library | ||||
|  * Copyright (C) 2009 by William Greiman | ||||
|  *   | ||||
|  * This file is part of the Arduino SdFat Library | ||||
|  *   | ||||
|  * This Library is free software: you can redistribute it and/or modify  | ||||
|  * it under the terms of the GNU General Public License as published by  | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  *  | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino SdFat Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
| \mainpage Arduino SdFat Library | ||||
| <CENTER>Copyright © 2009 by William Greiman | ||||
| </CENTER> | ||||
|  | ||||
| \section Intro Introduction | ||||
| The Arduino SdFat Library is a minimal implementation of FAT16 and FAT32 | ||||
| file systems on SD flash memory cards.  Standard SD and high capacity | ||||
| SDHC cards are supported. | ||||
|  | ||||
| The SdFat only supports short 8.3 names. | ||||
|  | ||||
| The main classes in SdFat are Sd2Card, SdVolume, and SdFile. | ||||
|  | ||||
| The Sd2Card class supports access to standard SD cards and SDHC cards.  Most | ||||
| applications will only need to call the Sd2Card::init() member function. | ||||
|  | ||||
| The SdVolume class supports FAT16 and FAT32 partitions.  Most applications | ||||
| will only need to call the SdVolume::init() member function. | ||||
|  | ||||
| The SdFile class provides file access functions such as open(), read(), | ||||
| remove(), write(), close() and sync(). This class supports access to the root | ||||
| directory and subdirectories. | ||||
|  | ||||
| A number of example are provided in the SdFat/examples folder.  These were | ||||
| developed to test SdFat and illustrate its use. | ||||
|  | ||||
| SdFat was developed for high speed data recording.  SdFat was used to implement | ||||
| an audio record/play class, WaveRP, for the Adafruit Wave Shield.  This | ||||
| application uses special Sd2Card calls to write to contiguous files in raw mode. | ||||
| These functions reduce write latency so that audio can be recorded with the | ||||
| small amount of RAM in the Arduino. | ||||
|  | ||||
| \section SDcard SD\SDHC Cards | ||||
|  | ||||
| Arduinos access SD cards using the cards SPI protocol.  PCs, Macs, and | ||||
| most consumer devices use the 4-bit parallel SD protocol.  A card that | ||||
| functions well on A PC or Mac may not work well on the Arduino. | ||||
|  | ||||
| Most cards have good SPI read performance but cards vary widely in SPI | ||||
| write performance.  Write performance is limited by how efficiently the | ||||
| card manages internal erase/remapping operations.  The Arduino cannot | ||||
| optimize writes to reduce erase operations because of its limit RAM. | ||||
|  | ||||
| SanDisk cards generally have good write performance.  They seem to have | ||||
| more internal RAM buffering than other cards and therefore can limit | ||||
| the number of flash erase operations that the Arduino forces due to its | ||||
| limited RAM. | ||||
|  | ||||
| \section Hardware Hardware Configuration | ||||
|  | ||||
| SdFat was developed using an | ||||
| <A HREF = "http://www.adafruit.com/"> Adafruit Industries</A>  | ||||
| <A HREF = "http://www.ladyada.net/make/waveshield/"> Wave Shield</A>. | ||||
|  | ||||
| The hardware interface to the SD card should not use a resistor based level | ||||
| shifter.  SdFat sets the SPI bus frequency to 8 MHz which results in signal | ||||
| rise times that are too slow for the edge detectors in many newer SD card | ||||
| controllers when resistor voltage dividers are used. | ||||
|  | ||||
| The 5 to 3.3 V level shifter for 5 V Arduinos should be IC based like the | ||||
| 74HC4050N based circuit shown in the file SdLevel.png.  The Adafruit Wave Shield | ||||
| uses a 74AHC125N.  Gravitech sells SD and MicroSD Card Adapters based on the | ||||
| 74LCX245. | ||||
|  | ||||
| If you are using a resistor based level shifter and are having problems try | ||||
| setting the SPI bus frequency to 4 MHz.  This can be done by using  | ||||
| card.init(SPI_HALF_SPEED) to initialize the SD card. | ||||
|  | ||||
| \section comment Bugs and Comments | ||||
|  | ||||
| If you wish to report bugs or have comments, send email to fat16lib@sbcglobal.net. | ||||
|  | ||||
| \section SdFatClass SdFat Usage | ||||
|  | ||||
| SdFat uses a slightly restricted form of short names. | ||||
| Only printable ASCII characters are supported. No characters with code point | ||||
| values greater than 127 are allowed.  Space is not allowed even though space | ||||
| was allowed in the API of early versions of DOS. | ||||
|  | ||||
| Short names are limited to 8 characters followed by an optional period (.) | ||||
| and extension of up to 3 characters.  The characters may be any combination | ||||
| of letters and digits.  The following special characters are also allowed: | ||||
|  | ||||
| $ % ' - _ @ ~ ` ! ( ) { } ^ # & | ||||
|  | ||||
| Short names are always converted to upper case and their original case | ||||
| value is lost. | ||||
|  | ||||
| \note | ||||
|   The Arduino Print class uses character | ||||
| at a time writes so it was necessary to use a \link SdFile::sync() sync() \endlink | ||||
| function to control when data is written to the SD card. | ||||
|  | ||||
| \par | ||||
| An application which writes to a file using \link Print::print() print()\endlink, | ||||
| \link Print::println() println() \endlink | ||||
| or \link SdFile::write write() \endlink must call \link SdFile::sync() sync() \endlink | ||||
| at the appropriate time to force data and directory information to be written | ||||
| to the SD Card.  Data and directory information are also written to the SD card | ||||
| when \link SdFile::close() close() \endlink is called. | ||||
|  | ||||
| \par | ||||
| Applications must use care calling \link SdFile::sync() sync() \endlink | ||||
| since 2048 bytes of I/O is required to update file and | ||||
| directory information.  This includes writing the current data block, reading | ||||
| the block that contains the directory entry for update, writing the directory | ||||
| block back and reading back the current data block. | ||||
|  | ||||
| It is possible to open a file with two or more instances of SdFile.  A file may | ||||
| be corrupted if data is written to the file by more than one instance of SdFile. | ||||
|  | ||||
| \section HowTo How to format SD Cards as FAT Volumes | ||||
|  | ||||
| You should use a freshly formatted SD card for best performance.  FAT | ||||
| file systems become slower if many files have been created and deleted. | ||||
| This is because the directory entry for a deleted file is marked as deleted, | ||||
| but is not deleted.  When a new file is created, these entries must be scanned | ||||
| before creating the file, a flaw in the FAT design.  Also files can become | ||||
| fragmented which causes reads and writes to be slower. | ||||
|  | ||||
| Microsoft operating systems support removable media formatted with a | ||||
| Master Boot Record, MBR, or formatted as a super floppy with a FAT Boot Sector | ||||
| in block zero. | ||||
|  | ||||
| Microsoft operating systems expect MBR formatted removable media | ||||
| to have only one partition. The first partition should be used. | ||||
|  | ||||
| Microsoft operating systems do not support partitioning SD flash cards. | ||||
| If you erase an SD card with a program like KillDisk, Most versions of | ||||
| Windows will format the card as a super floppy. | ||||
|  | ||||
| The best way to restore an SD card's format is to use SDFormatter | ||||
| which can be downloaded from: | ||||
|  | ||||
| http://www.sdcard.org/consumers/formatter/ | ||||
|  | ||||
| SDFormatter aligns flash erase boundaries with file | ||||
| system structures which reduces write latency and file system overhead. | ||||
|  | ||||
| SDFormatter does not have an option for FAT type so it may format | ||||
| small cards as FAT12. | ||||
|  | ||||
| After the MBR is restored by SDFormatter you may need to reformat small | ||||
| cards that have been formatted FAT12 to force the volume type to be FAT16. | ||||
|  | ||||
| If you reformat the SD card with an OS utility, choose a cluster size that | ||||
| will result in: | ||||
|  | ||||
| 4084 < CountOfClusters && CountOfClusters < 65525 | ||||
|  | ||||
| The volume will then be FAT16. | ||||
|  | ||||
| If you are formatting an SD card on OS X or Linux, be sure to use the first | ||||
| partition. Format this partition with a cluster count in above range. | ||||
|  | ||||
| \section  References References | ||||
|  | ||||
| Adafruit Industries: | ||||
|  | ||||
| http://www.adafruit.com/ | ||||
|  | ||||
| http://www.ladyada.net/make/waveshield/ | ||||
|  | ||||
| The Arduino site: | ||||
|  | ||||
| http://www.arduino.cc/ | ||||
|  | ||||
| For more information about FAT file systems see: | ||||
|  | ||||
| http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx | ||||
|  | ||||
| For information about using SD cards as SPI devices see: | ||||
|  | ||||
| http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf | ||||
|  | ||||
| The ATmega328 datasheet: | ||||
|  | ||||
| http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf | ||||
|   | ||||
|  | ||||
|  */   | ||||
|   | ||||
							
								
								
									
										2504
									
								
								Marlin/SdFile.cpp
									
									
									
									
									
								
							
							
						
						
									
										2504
									
								
								Marlin/SdFile.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										464
									
								
								Marlin/SdInfo.h
									
									
									
									
									
								
							
							
						
						
									
										464
									
								
								Marlin/SdInfo.h
									
									
									
									
									
								
							| @@ -1,232 +1,232 @@ | ||||
| /* Arduino Sd2Card Library | ||||
|  * Copyright (C) 2009 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino Sd2Card Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino Sd2Card Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| #ifndef SdInfo_h | ||||
| #define SdInfo_h | ||||
| #include <stdint.h> | ||||
| // Based on the document: | ||||
| // | ||||
| // SD Specifications | ||||
| // Part 1 | ||||
| // Physical Layer | ||||
| // Simplified Specification | ||||
| // Version 2.00 | ||||
| // September 25, 2006 | ||||
| // | ||||
| // www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf | ||||
| //------------------------------------------------------------------------------ | ||||
| // SD card commands | ||||
| /** GO_IDLE_STATE - init card in spi mode if CS low */ | ||||
| uint8_t const CMD0 = 0X00; | ||||
| /** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ | ||||
| uint8_t const CMD8 = 0X08; | ||||
| /** SEND_CSD - read the Card Specific Data (CSD register) */ | ||||
| uint8_t const CMD9 = 0X09; | ||||
| /** SEND_CID - read the card identification information (CID register) */ | ||||
| uint8_t const CMD10 = 0X0A; | ||||
| /** SEND_STATUS - read the card status register */ | ||||
| uint8_t const CMD13 = 0X0D; | ||||
| /** READ_BLOCK - read a single data block from the card */ | ||||
| uint8_t const CMD17 = 0X11; | ||||
| /** WRITE_BLOCK - write a single data block to the card */ | ||||
| uint8_t const CMD24 = 0X18; | ||||
| /** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ | ||||
| uint8_t const CMD25 = 0X19; | ||||
| /** ERASE_WR_BLK_START - sets the address of the first block to be erased */ | ||||
| uint8_t const CMD32 = 0X20; | ||||
| /** ERASE_WR_BLK_END - sets the address of the last block of the continuous | ||||
|     range to be erased*/ | ||||
| uint8_t const CMD33 = 0X21; | ||||
| /** ERASE - erase all previously selected blocks */ | ||||
| uint8_t const CMD38 = 0X26; | ||||
| /** APP_CMD - escape for application specific command */ | ||||
| uint8_t const CMD55 = 0X37; | ||||
| /** READ_OCR - read the OCR register of a card */ | ||||
| uint8_t const CMD58 = 0X3A; | ||||
| /** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be | ||||
|      pre-erased before writing */ | ||||
| uint8_t const ACMD23 = 0X17; | ||||
| /** SD_SEND_OP_COMD - Sends host capacity support information and | ||||
|     activates the card's initialization process */ | ||||
| uint8_t const ACMD41 = 0X29; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** status for card in the ready state */ | ||||
| uint8_t const R1_READY_STATE = 0X00; | ||||
| /** status for card in the idle state */ | ||||
| uint8_t const R1_IDLE_STATE = 0X01; | ||||
| /** status bit for illegal command */ | ||||
| uint8_t const R1_ILLEGAL_COMMAND = 0X04; | ||||
| /** start data token for read or write single block*/ | ||||
| uint8_t const DATA_START_BLOCK = 0XFE; | ||||
| /** stop token for write multiple blocks*/ | ||||
| uint8_t const STOP_TRAN_TOKEN = 0XFD; | ||||
| /** start data token for write multiple blocks*/ | ||||
| uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC; | ||||
| /** mask for data response tokens after a write block operation */ | ||||
| uint8_t const DATA_RES_MASK = 0X1F; | ||||
| /** write data accepted token */ | ||||
| uint8_t const DATA_RES_ACCEPTED = 0X05; | ||||
| //------------------------------------------------------------------------------ | ||||
| typedef struct CID { | ||||
|   // byte 0 | ||||
|   uint8_t mid;  // Manufacturer ID | ||||
|   // byte 1-2 | ||||
|   char oid[2];  // OEM/Application ID | ||||
|   // byte 3-7 | ||||
|   char pnm[5];  // Product name | ||||
|   // byte 8 | ||||
|   unsigned prv_m : 4;  // Product revision n.m | ||||
|   unsigned prv_n : 4; | ||||
|   // byte 9-12 | ||||
|   uint32_t psn;  // Product serial number | ||||
|   // byte 13 | ||||
|   unsigned mdt_year_high : 4;  // Manufacturing date | ||||
|   unsigned reserved : 4; | ||||
|   // byte 14 | ||||
|   unsigned mdt_month : 4; | ||||
|   unsigned mdt_year_low :4; | ||||
|   // byte 15 | ||||
|   unsigned always1 : 1; | ||||
|   unsigned crc : 7; | ||||
| }cid_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| // CSD for version 1.00 cards | ||||
| typedef struct CSDV1 { | ||||
|   // byte 0 | ||||
|   unsigned reserved1 : 6; | ||||
|   unsigned csd_ver : 2; | ||||
|   // byte 1 | ||||
|   uint8_t taac; | ||||
|   // byte 2 | ||||
|   uint8_t nsac; | ||||
|   // byte 3 | ||||
|   uint8_t tran_speed; | ||||
|   // byte 4 | ||||
|   uint8_t ccc_high; | ||||
|   // byte 5 | ||||
|   unsigned read_bl_len : 4; | ||||
|   unsigned ccc_low : 4; | ||||
|   // byte 6 | ||||
|   unsigned c_size_high : 2; | ||||
|   unsigned reserved2 : 2; | ||||
|   unsigned dsr_imp : 1; | ||||
|   unsigned read_blk_misalign :1; | ||||
|   unsigned write_blk_misalign : 1; | ||||
|   unsigned read_bl_partial : 1; | ||||
|   // byte 7 | ||||
|   uint8_t c_size_mid; | ||||
|   // byte 8 | ||||
|   unsigned vdd_r_curr_max : 3; | ||||
|   unsigned vdd_r_curr_min : 3; | ||||
|   unsigned c_size_low :2; | ||||
|   // byte 9 | ||||
|   unsigned c_size_mult_high : 2; | ||||
|   unsigned vdd_w_cur_max : 3; | ||||
|   unsigned vdd_w_curr_min : 3; | ||||
|   // byte 10 | ||||
|   unsigned sector_size_high : 6; | ||||
|   unsigned erase_blk_en : 1; | ||||
|   unsigned c_size_mult_low : 1; | ||||
|   // byte 11 | ||||
|   unsigned wp_grp_size : 7; | ||||
|   unsigned sector_size_low : 1; | ||||
|   // byte 12 | ||||
|   unsigned write_bl_len_high : 2; | ||||
|   unsigned r2w_factor : 3; | ||||
|   unsigned reserved3 : 2; | ||||
|   unsigned wp_grp_enable : 1; | ||||
|   // byte 13 | ||||
|   unsigned reserved4 : 5; | ||||
|   unsigned write_partial : 1; | ||||
|   unsigned write_bl_len_low : 2; | ||||
|   // byte 14 | ||||
|   unsigned reserved5: 2; | ||||
|   unsigned file_format : 2; | ||||
|   unsigned tmp_write_protect : 1; | ||||
|   unsigned perm_write_protect : 1; | ||||
|   unsigned copy : 1; | ||||
|   unsigned file_format_grp : 1; | ||||
|   // byte 15 | ||||
|   unsigned always1 : 1; | ||||
|   unsigned crc : 7; | ||||
| }csd1_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| // CSD for version 2.00 cards | ||||
| typedef struct CSDV2 { | ||||
|   // byte 0 | ||||
|   unsigned reserved1 : 6; | ||||
|   unsigned csd_ver : 2; | ||||
|   // byte 1 | ||||
|   uint8_t taac; | ||||
|   // byte 2 | ||||
|   uint8_t nsac; | ||||
|   // byte 3 | ||||
|   uint8_t tran_speed; | ||||
|   // byte 4 | ||||
|   uint8_t ccc_high; | ||||
|   // byte 5 | ||||
|   unsigned read_bl_len : 4; | ||||
|   unsigned ccc_low : 4; | ||||
|   // byte 6 | ||||
|   unsigned reserved2 : 4; | ||||
|   unsigned dsr_imp : 1; | ||||
|   unsigned read_blk_misalign :1; | ||||
|   unsigned write_blk_misalign : 1; | ||||
|   unsigned read_bl_partial : 1; | ||||
|   // byte 7 | ||||
|   unsigned reserved3 : 2; | ||||
|   unsigned c_size_high : 6; | ||||
|   // byte 8 | ||||
|   uint8_t c_size_mid; | ||||
|   // byte 9 | ||||
|   uint8_t c_size_low; | ||||
|   // byte 10 | ||||
|   unsigned sector_size_high : 6; | ||||
|   unsigned erase_blk_en : 1; | ||||
|   unsigned reserved4 : 1; | ||||
|   // byte 11 | ||||
|   unsigned wp_grp_size : 7; | ||||
|   unsigned sector_size_low : 1; | ||||
|   // byte 12 | ||||
|   unsigned write_bl_len_high : 2; | ||||
|   unsigned r2w_factor : 3; | ||||
|   unsigned reserved5 : 2; | ||||
|   unsigned wp_grp_enable : 1; | ||||
|   // byte 13 | ||||
|   unsigned reserved6 : 5; | ||||
|   unsigned write_partial : 1; | ||||
|   unsigned write_bl_len_low : 2; | ||||
|   // byte 14 | ||||
|   unsigned reserved7: 2; | ||||
|   unsigned file_format : 2; | ||||
|   unsigned tmp_write_protect : 1; | ||||
|   unsigned perm_write_protect : 1; | ||||
|   unsigned copy : 1; | ||||
|   unsigned file_format_grp : 1; | ||||
|   // byte 15 | ||||
|   unsigned always1 : 1; | ||||
|   unsigned crc : 7; | ||||
| }csd2_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| // union of old and new style CSD register | ||||
| union csd_t { | ||||
|   csd1_t v1; | ||||
|   csd2_t v2; | ||||
| }; | ||||
| #endif  // SdInfo_h | ||||
| /* Arduino Sd2Card Library | ||||
|  * Copyright (C) 2009 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino Sd2Card Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino Sd2Card Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| #ifndef SdInfo_h | ||||
| #define SdInfo_h | ||||
| #include <stdint.h> | ||||
| // Based on the document: | ||||
| // | ||||
| // SD Specifications | ||||
| // Part 1 | ||||
| // Physical Layer | ||||
| // Simplified Specification | ||||
| // Version 2.00 | ||||
| // September 25, 2006 | ||||
| // | ||||
| // www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf | ||||
| //------------------------------------------------------------------------------ | ||||
| // SD card commands | ||||
| /** GO_IDLE_STATE - init card in spi mode if CS low */ | ||||
| uint8_t const CMD0 = 0X00; | ||||
| /** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ | ||||
| uint8_t const CMD8 = 0X08; | ||||
| /** SEND_CSD - read the Card Specific Data (CSD register) */ | ||||
| uint8_t const CMD9 = 0X09; | ||||
| /** SEND_CID - read the card identification information (CID register) */ | ||||
| uint8_t const CMD10 = 0X0A; | ||||
| /** SEND_STATUS - read the card status register */ | ||||
| uint8_t const CMD13 = 0X0D; | ||||
| /** READ_BLOCK - read a single data block from the card */ | ||||
| uint8_t const CMD17 = 0X11; | ||||
| /** WRITE_BLOCK - write a single data block to the card */ | ||||
| uint8_t const CMD24 = 0X18; | ||||
| /** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ | ||||
| uint8_t const CMD25 = 0X19; | ||||
| /** ERASE_WR_BLK_START - sets the address of the first block to be erased */ | ||||
| uint8_t const CMD32 = 0X20; | ||||
| /** ERASE_WR_BLK_END - sets the address of the last block of the continuous | ||||
|     range to be erased*/ | ||||
| uint8_t const CMD33 = 0X21; | ||||
| /** ERASE - erase all previously selected blocks */ | ||||
| uint8_t const CMD38 = 0X26; | ||||
| /** APP_CMD - escape for application specific command */ | ||||
| uint8_t const CMD55 = 0X37; | ||||
| /** READ_OCR - read the OCR register of a card */ | ||||
| uint8_t const CMD58 = 0X3A; | ||||
| /** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be | ||||
|      pre-erased before writing */ | ||||
| uint8_t const ACMD23 = 0X17; | ||||
| /** SD_SEND_OP_COMD - Sends host capacity support information and | ||||
|     activates the card's initialization process */ | ||||
| uint8_t const ACMD41 = 0X29; | ||||
| //------------------------------------------------------------------------------ | ||||
| /** status for card in the ready state */ | ||||
| uint8_t const R1_READY_STATE = 0X00; | ||||
| /** status for card in the idle state */ | ||||
| uint8_t const R1_IDLE_STATE = 0X01; | ||||
| /** status bit for illegal command */ | ||||
| uint8_t const R1_ILLEGAL_COMMAND = 0X04; | ||||
| /** start data token for read or write single block*/ | ||||
| uint8_t const DATA_START_BLOCK = 0XFE; | ||||
| /** stop token for write multiple blocks*/ | ||||
| uint8_t const STOP_TRAN_TOKEN = 0XFD; | ||||
| /** start data token for write multiple blocks*/ | ||||
| uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC; | ||||
| /** mask for data response tokens after a write block operation */ | ||||
| uint8_t const DATA_RES_MASK = 0X1F; | ||||
| /** write data accepted token */ | ||||
| uint8_t const DATA_RES_ACCEPTED = 0X05; | ||||
| //------------------------------------------------------------------------------ | ||||
| typedef struct CID { | ||||
|   // byte 0 | ||||
|   uint8_t mid;  // Manufacturer ID | ||||
|   // byte 1-2 | ||||
|   char oid[2];  // OEM/Application ID | ||||
|   // byte 3-7 | ||||
|   char pnm[5];  // Product name | ||||
|   // byte 8 | ||||
|   unsigned prv_m : 4;  // Product revision n.m | ||||
|   unsigned prv_n : 4; | ||||
|   // byte 9-12 | ||||
|   uint32_t psn;  // Product serial number | ||||
|   // byte 13 | ||||
|   unsigned mdt_year_high : 4;  // Manufacturing date | ||||
|   unsigned reserved : 4; | ||||
|   // byte 14 | ||||
|   unsigned mdt_month : 4; | ||||
|   unsigned mdt_year_low :4; | ||||
|   // byte 15 | ||||
|   unsigned always1 : 1; | ||||
|   unsigned crc : 7; | ||||
| }cid_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| // CSD for version 1.00 cards | ||||
| typedef struct CSDV1 { | ||||
|   // byte 0 | ||||
|   unsigned reserved1 : 6; | ||||
|   unsigned csd_ver : 2; | ||||
|   // byte 1 | ||||
|   uint8_t taac; | ||||
|   // byte 2 | ||||
|   uint8_t nsac; | ||||
|   // byte 3 | ||||
|   uint8_t tran_speed; | ||||
|   // byte 4 | ||||
|   uint8_t ccc_high; | ||||
|   // byte 5 | ||||
|   unsigned read_bl_len : 4; | ||||
|   unsigned ccc_low : 4; | ||||
|   // byte 6 | ||||
|   unsigned c_size_high : 2; | ||||
|   unsigned reserved2 : 2; | ||||
|   unsigned dsr_imp : 1; | ||||
|   unsigned read_blk_misalign :1; | ||||
|   unsigned write_blk_misalign : 1; | ||||
|   unsigned read_bl_partial : 1; | ||||
|   // byte 7 | ||||
|   uint8_t c_size_mid; | ||||
|   // byte 8 | ||||
|   unsigned vdd_r_curr_max : 3; | ||||
|   unsigned vdd_r_curr_min : 3; | ||||
|   unsigned c_size_low :2; | ||||
|   // byte 9 | ||||
|   unsigned c_size_mult_high : 2; | ||||
|   unsigned vdd_w_cur_max : 3; | ||||
|   unsigned vdd_w_curr_min : 3; | ||||
|   // byte 10 | ||||
|   unsigned sector_size_high : 6; | ||||
|   unsigned erase_blk_en : 1; | ||||
|   unsigned c_size_mult_low : 1; | ||||
|   // byte 11 | ||||
|   unsigned wp_grp_size : 7; | ||||
|   unsigned sector_size_low : 1; | ||||
|   // byte 12 | ||||
|   unsigned write_bl_len_high : 2; | ||||
|   unsigned r2w_factor : 3; | ||||
|   unsigned reserved3 : 2; | ||||
|   unsigned wp_grp_enable : 1; | ||||
|   // byte 13 | ||||
|   unsigned reserved4 : 5; | ||||
|   unsigned write_partial : 1; | ||||
|   unsigned write_bl_len_low : 2; | ||||
|   // byte 14 | ||||
|   unsigned reserved5: 2; | ||||
|   unsigned file_format : 2; | ||||
|   unsigned tmp_write_protect : 1; | ||||
|   unsigned perm_write_protect : 1; | ||||
|   unsigned copy : 1; | ||||
|   unsigned file_format_grp : 1; | ||||
|   // byte 15 | ||||
|   unsigned always1 : 1; | ||||
|   unsigned crc : 7; | ||||
| }csd1_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| // CSD for version 2.00 cards | ||||
| typedef struct CSDV2 { | ||||
|   // byte 0 | ||||
|   unsigned reserved1 : 6; | ||||
|   unsigned csd_ver : 2; | ||||
|   // byte 1 | ||||
|   uint8_t taac; | ||||
|   // byte 2 | ||||
|   uint8_t nsac; | ||||
|   // byte 3 | ||||
|   uint8_t tran_speed; | ||||
|   // byte 4 | ||||
|   uint8_t ccc_high; | ||||
|   // byte 5 | ||||
|   unsigned read_bl_len : 4; | ||||
|   unsigned ccc_low : 4; | ||||
|   // byte 6 | ||||
|   unsigned reserved2 : 4; | ||||
|   unsigned dsr_imp : 1; | ||||
|   unsigned read_blk_misalign :1; | ||||
|   unsigned write_blk_misalign : 1; | ||||
|   unsigned read_bl_partial : 1; | ||||
|   // byte 7 | ||||
|   unsigned reserved3 : 2; | ||||
|   unsigned c_size_high : 6; | ||||
|   // byte 8 | ||||
|   uint8_t c_size_mid; | ||||
|   // byte 9 | ||||
|   uint8_t c_size_low; | ||||
|   // byte 10 | ||||
|   unsigned sector_size_high : 6; | ||||
|   unsigned erase_blk_en : 1; | ||||
|   unsigned reserved4 : 1; | ||||
|   // byte 11 | ||||
|   unsigned wp_grp_size : 7; | ||||
|   unsigned sector_size_low : 1; | ||||
|   // byte 12 | ||||
|   unsigned write_bl_len_high : 2; | ||||
|   unsigned r2w_factor : 3; | ||||
|   unsigned reserved5 : 2; | ||||
|   unsigned wp_grp_enable : 1; | ||||
|   // byte 13 | ||||
|   unsigned reserved6 : 5; | ||||
|   unsigned write_partial : 1; | ||||
|   unsigned write_bl_len_low : 2; | ||||
|   // byte 14 | ||||
|   unsigned reserved7: 2; | ||||
|   unsigned file_format : 2; | ||||
|   unsigned tmp_write_protect : 1; | ||||
|   unsigned perm_write_protect : 1; | ||||
|   unsigned copy : 1; | ||||
|   unsigned file_format_grp : 1; | ||||
|   // byte 15 | ||||
|   unsigned always1 : 1; | ||||
|   unsigned crc : 7; | ||||
| }csd2_t; | ||||
| //------------------------------------------------------------------------------ | ||||
| // union of old and new style CSD register | ||||
| union csd_t { | ||||
|   csd1_t v1; | ||||
|   csd2_t v2; | ||||
| }; | ||||
| #endif  // SdInfo_h | ||||
|   | ||||
| @@ -1,295 +1,295 @@ | ||||
| /* Arduino SdFat Library | ||||
|  * Copyright (C) 2009 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino SdFat Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino SdFat Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| #include "SdFat.h" | ||||
| //------------------------------------------------------------------------------ | ||||
| // raw block cache | ||||
| // init cacheBlockNumber_to invalid SD block number | ||||
| uint32_t SdVolume::cacheBlockNumber_ = 0XFFFFFFFF; | ||||
| cache_t  SdVolume::cacheBuffer_;     // 512 byte cache for Sd2Card | ||||
| Sd2Card* SdVolume::sdCard_;          // pointer to SD card object | ||||
| uint8_t  SdVolume::cacheDirty_ = 0;  // cacheFlush() will write block if true | ||||
| uint32_t SdVolume::cacheMirrorBlock_ = 0;  // mirror  block for second FAT | ||||
| //------------------------------------------------------------------------------ | ||||
| // find a contiguous group of clusters | ||||
| uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { | ||||
|   // start of group | ||||
|   uint32_t bgnCluster; | ||||
|  | ||||
|   // flag to save place to start next search | ||||
|   uint8_t setStart; | ||||
|  | ||||
|   // set search start cluster | ||||
|   if (*curCluster) { | ||||
|     // try to make file contiguous | ||||
|     bgnCluster = *curCluster + 1; | ||||
|  | ||||
|     // don't save new start location | ||||
|     setStart = false; | ||||
|   } else { | ||||
|     // start at likely place for free cluster | ||||
|     bgnCluster = allocSearchStart_; | ||||
|  | ||||
|     // save next search start if one cluster | ||||
|     setStart = 1 == count; | ||||
|   } | ||||
|   // end of group | ||||
|   uint32_t endCluster = bgnCluster; | ||||
|  | ||||
|   // last cluster of FAT | ||||
|   uint32_t fatEnd = clusterCount_ + 1; | ||||
|  | ||||
|   // search the FAT for free clusters | ||||
|   for (uint32_t n = 0;; n++, endCluster++) { | ||||
|     // can't find space checked all clusters | ||||
|     if (n >= clusterCount_) return false; | ||||
|  | ||||
|     // past end - start from beginning of FAT | ||||
|     if (endCluster > fatEnd) { | ||||
|       bgnCluster = endCluster = 2; | ||||
|     } | ||||
|     uint32_t f; | ||||
|     if (!fatGet(endCluster, &f)) return false; | ||||
|  | ||||
|     if (f != 0) { | ||||
|       // cluster in use try next cluster as bgnCluster | ||||
|       bgnCluster = endCluster + 1; | ||||
|     } else if ((endCluster - bgnCluster + 1) == count) { | ||||
|       // done - found space | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|   // mark end of chain | ||||
|   if (!fatPutEOC(endCluster)) return false; | ||||
|  | ||||
|   // link clusters | ||||
|   while (endCluster > bgnCluster) { | ||||
|     if (!fatPut(endCluster - 1, endCluster)) return false; | ||||
|     endCluster--; | ||||
|   } | ||||
|   if (*curCluster != 0) { | ||||
|     // connect chains | ||||
|     if (!fatPut(*curCluster, bgnCluster)) return false; | ||||
|   } | ||||
|   // return first cluster number to caller | ||||
|   *curCluster = bgnCluster; | ||||
|  | ||||
|   // remember possible next free cluster | ||||
|   if (setStart) allocSearchStart_ = bgnCluster + 1; | ||||
|  | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| uint8_t SdVolume::cacheFlush(void) { | ||||
|   if (cacheDirty_) { | ||||
|     if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) { | ||||
|       return false; | ||||
|     } | ||||
|     // mirror FAT tables | ||||
|     if (cacheMirrorBlock_) { | ||||
|       if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) { | ||||
|         return false; | ||||
|       } | ||||
|       cacheMirrorBlock_ = 0; | ||||
|     } | ||||
|     cacheDirty_ = 0; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| uint8_t SdVolume::cacheRawBlock(uint32_t blockNumber, uint8_t action) { | ||||
|   if (cacheBlockNumber_ != blockNumber) { | ||||
|     if (!cacheFlush()) return false; | ||||
|     if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) return false; | ||||
|     cacheBlockNumber_ = blockNumber; | ||||
|   } | ||||
|   cacheDirty_ |= action; | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| // cache a zero block for blockNumber | ||||
| uint8_t SdVolume::cacheZeroBlock(uint32_t blockNumber) { | ||||
|   if (!cacheFlush()) return false; | ||||
|  | ||||
|   // loop take less flash than memset(cacheBuffer_.data, 0, 512); | ||||
|   for (uint16_t i = 0; i < 512; i++) { | ||||
|     cacheBuffer_.data[i] = 0; | ||||
|   } | ||||
|   cacheBlockNumber_ = blockNumber; | ||||
|   cacheSetDirty(); | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| // return the size in bytes of a cluster chain | ||||
| uint8_t SdVolume::chainSize(uint32_t cluster, uint32_t* size) const { | ||||
|   uint32_t s = 0; | ||||
|   do { | ||||
|     if (!fatGet(cluster, &cluster)) return false; | ||||
|     s += 512UL << clusterSizeShift_; | ||||
|   } while (!isEOC(cluster)); | ||||
|   *size = s; | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| // Fetch a FAT entry | ||||
| uint8_t SdVolume::fatGet(uint32_t cluster, uint32_t* value) const { | ||||
|   if (cluster > (clusterCount_ + 1)) return false; | ||||
|   uint32_t lba = fatStartBlock_; | ||||
|   lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7; | ||||
|   if (lba != cacheBlockNumber_) { | ||||
|     if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; | ||||
|   } | ||||
|   if (fatType_ == 16) { | ||||
|     *value = cacheBuffer_.fat16[cluster & 0XFF]; | ||||
|   } else { | ||||
|     *value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| // Store a FAT entry | ||||
| uint8_t SdVolume::fatPut(uint32_t cluster, uint32_t value) { | ||||
|   // error if reserved cluster | ||||
|   if (cluster < 2) return false; | ||||
|  | ||||
|   // error if not in FAT | ||||
|   if (cluster > (clusterCount_ + 1)) return false; | ||||
|  | ||||
|   // calculate block address for entry | ||||
|   uint32_t lba = fatStartBlock_; | ||||
|   lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7; | ||||
|  | ||||
|   if (lba != cacheBlockNumber_) { | ||||
|     if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; | ||||
|   } | ||||
|   // store entry | ||||
|   if (fatType_ == 16) { | ||||
|     cacheBuffer_.fat16[cluster & 0XFF] = value; | ||||
|   } else { | ||||
|     cacheBuffer_.fat32[cluster & 0X7F] = value; | ||||
|   } | ||||
|   cacheSetDirty(); | ||||
|  | ||||
|   // mirror second FAT | ||||
|   if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| // free a cluster chain | ||||
| uint8_t SdVolume::freeChain(uint32_t cluster) { | ||||
|   // clear free cluster location | ||||
|   allocSearchStart_ = 2; | ||||
|  | ||||
|   do { | ||||
|     uint32_t next; | ||||
|     if (!fatGet(cluster, &next)) return false; | ||||
|  | ||||
|     // free cluster | ||||
|     if (!fatPut(cluster, 0)) return false; | ||||
|  | ||||
|     cluster = next; | ||||
|   } while (!isEOC(cluster)); | ||||
|  | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * Initialize a FAT volume. | ||||
|  * | ||||
|  * \param[in] dev The SD card where the volume is located. | ||||
|  * | ||||
|  * \param[in] part The partition to be used.  Legal values for \a part are | ||||
|  * 1-4 to use the corresponding partition on a device formatted with | ||||
|  * a MBR, Master Boot Record, or zero if the device is formatted as | ||||
|  * a super floppy with the FAT boot sector in block zero. | ||||
|  * | ||||
|  * \return The value one, true, is returned for success and | ||||
|  * the value zero, false, is returned for failure.  Reasons for | ||||
|  * failure include not finding a valid partition, not finding a valid | ||||
|  * FAT file system in the specified partition or an I/O error. | ||||
|  */ | ||||
| uint8_t SdVolume::init(Sd2Card* dev, uint8_t part) { | ||||
|   uint32_t volumeStartBlock = 0; | ||||
|   sdCard_ = dev; | ||||
|   // if part == 0 assume super floppy with FAT boot sector in block zero | ||||
|   // if part > 0 assume mbr volume with partition table | ||||
|   if (part) { | ||||
|     if (part > 4)return false; | ||||
|     if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false; | ||||
|     part_t* p = &cacheBuffer_.mbr.part[part-1]; | ||||
|     if ((p->boot & 0X7F) !=0  || | ||||
|       p->totalSectors < 100 || | ||||
|       p->firstSector == 0) { | ||||
|       // not a valid partition | ||||
|       return false; | ||||
|     } | ||||
|     volumeStartBlock = p->firstSector; | ||||
|   } | ||||
|   if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false; | ||||
|   bpb_t* bpb = &cacheBuffer_.fbs.bpb; | ||||
|   if (bpb->bytesPerSector != 512 || | ||||
|     bpb->fatCount == 0 || | ||||
|     bpb->reservedSectorCount == 0 || | ||||
|     bpb->sectorsPerCluster == 0) { | ||||
|        // not valid FAT volume | ||||
|       return false; | ||||
|   } | ||||
|   fatCount_ = bpb->fatCount; | ||||
|   blocksPerCluster_ = bpb->sectorsPerCluster; | ||||
|  | ||||
|   // determine shift that is same as multiply by blocksPerCluster_ | ||||
|   clusterSizeShift_ = 0; | ||||
|   while (blocksPerCluster_ != (1 << clusterSizeShift_)) { | ||||
|     // error if not power of 2 | ||||
|     if (clusterSizeShift_++ > 7) return false; | ||||
|   } | ||||
|   blocksPerFat_ = bpb->sectorsPerFat16 ? | ||||
|                     bpb->sectorsPerFat16 : bpb->sectorsPerFat32; | ||||
|  | ||||
|   fatStartBlock_ = volumeStartBlock + bpb->reservedSectorCount; | ||||
|  | ||||
|   // count for FAT16 zero for FAT32 | ||||
|   rootDirEntryCount_ = bpb->rootDirEntryCount; | ||||
|  | ||||
|   // directory start for FAT16 dataStart for FAT32 | ||||
|   rootDirStart_ = fatStartBlock_ + bpb->fatCount * blocksPerFat_; | ||||
|  | ||||
|   // data start for FAT16 and FAT32 | ||||
|   dataStartBlock_ = rootDirStart_ + ((32 * bpb->rootDirEntryCount + 511)/512); | ||||
|  | ||||
|   // total blocks for FAT16 or FAT32 | ||||
|   uint32_t totalBlocks = bpb->totalSectors16 ? | ||||
|                            bpb->totalSectors16 : bpb->totalSectors32; | ||||
|   // total data blocks | ||||
|   clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock); | ||||
|  | ||||
|   // divide by cluster size to get cluster count | ||||
|   clusterCount_ >>= clusterSizeShift_; | ||||
|  | ||||
|   // FAT type is determined by cluster count | ||||
|   if (clusterCount_ < 4085) { | ||||
|     fatType_ = 12; | ||||
|   } else if (clusterCount_ < 65525) { | ||||
|     fatType_ = 16; | ||||
|   } else { | ||||
|     rootDirStart_ = bpb->fat32RootCluster; | ||||
|     fatType_ = 32; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| /* Arduino SdFat Library | ||||
|  * Copyright (C) 2009 by William Greiman | ||||
|  * | ||||
|  * This file is part of the Arduino SdFat Library | ||||
|  * | ||||
|  * This Library is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This Library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with the Arduino SdFat Library.  If not, see | ||||
|  * <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| #include "SdFat.h" | ||||
| //------------------------------------------------------------------------------ | ||||
| // raw block cache | ||||
| // init cacheBlockNumber_to invalid SD block number | ||||
| uint32_t SdVolume::cacheBlockNumber_ = 0XFFFFFFFF; | ||||
| cache_t  SdVolume::cacheBuffer_;     // 512 byte cache for Sd2Card | ||||
| Sd2Card* SdVolume::sdCard_;          // pointer to SD card object | ||||
| uint8_t  SdVolume::cacheDirty_ = 0;  // cacheFlush() will write block if true | ||||
| uint32_t SdVolume::cacheMirrorBlock_ = 0;  // mirror  block for second FAT | ||||
| //------------------------------------------------------------------------------ | ||||
| // find a contiguous group of clusters | ||||
| uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { | ||||
|   // start of group | ||||
|   uint32_t bgnCluster; | ||||
|  | ||||
|   // flag to save place to start next search | ||||
|   uint8_t setStart; | ||||
|  | ||||
|   // set search start cluster | ||||
|   if (*curCluster) { | ||||
|     // try to make file contiguous | ||||
|     bgnCluster = *curCluster + 1; | ||||
|  | ||||
|     // don't save new start location | ||||
|     setStart = false; | ||||
|   } else { | ||||
|     // start at likely place for free cluster | ||||
|     bgnCluster = allocSearchStart_; | ||||
|  | ||||
|     // save next search start if one cluster | ||||
|     setStart = 1 == count; | ||||
|   } | ||||
|   // end of group | ||||
|   uint32_t endCluster = bgnCluster; | ||||
|  | ||||
|   // last cluster of FAT | ||||
|   uint32_t fatEnd = clusterCount_ + 1; | ||||
|  | ||||
|   // search the FAT for free clusters | ||||
|   for (uint32_t n = 0;; n++, endCluster++) { | ||||
|     // can't find space checked all clusters | ||||
|     if (n >= clusterCount_) return false; | ||||
|  | ||||
|     // past end - start from beginning of FAT | ||||
|     if (endCluster > fatEnd) { | ||||
|       bgnCluster = endCluster = 2; | ||||
|     } | ||||
|     uint32_t f; | ||||
|     if (!fatGet(endCluster, &f)) return false; | ||||
|  | ||||
|     if (f != 0) { | ||||
|       // cluster in use try next cluster as bgnCluster | ||||
|       bgnCluster = endCluster + 1; | ||||
|     } else if ((endCluster - bgnCluster + 1) == count) { | ||||
|       // done - found space | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|   // mark end of chain | ||||
|   if (!fatPutEOC(endCluster)) return false; | ||||
|  | ||||
|   // link clusters | ||||
|   while (endCluster > bgnCluster) { | ||||
|     if (!fatPut(endCluster - 1, endCluster)) return false; | ||||
|     endCluster--; | ||||
|   } | ||||
|   if (*curCluster != 0) { | ||||
|     // connect chains | ||||
|     if (!fatPut(*curCluster, bgnCluster)) return false; | ||||
|   } | ||||
|   // return first cluster number to caller | ||||
|   *curCluster = bgnCluster; | ||||
|  | ||||
|   // remember possible next free cluster | ||||
|   if (setStart) allocSearchStart_ = bgnCluster + 1; | ||||
|  | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| uint8_t SdVolume::cacheFlush(void) { | ||||
|   if (cacheDirty_) { | ||||
|     if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) { | ||||
|       return false; | ||||
|     } | ||||
|     // mirror FAT tables | ||||
|     if (cacheMirrorBlock_) { | ||||
|       if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) { | ||||
|         return false; | ||||
|       } | ||||
|       cacheMirrorBlock_ = 0; | ||||
|     } | ||||
|     cacheDirty_ = 0; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| uint8_t SdVolume::cacheRawBlock(uint32_t blockNumber, uint8_t action) { | ||||
|   if (cacheBlockNumber_ != blockNumber) { | ||||
|     if (!cacheFlush()) return false; | ||||
|     if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) return false; | ||||
|     cacheBlockNumber_ = blockNumber; | ||||
|   } | ||||
|   cacheDirty_ |= action; | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| // cache a zero block for blockNumber | ||||
| uint8_t SdVolume::cacheZeroBlock(uint32_t blockNumber) { | ||||
|   if (!cacheFlush()) return false; | ||||
|  | ||||
|   // loop take less flash than memset(cacheBuffer_.data, 0, 512); | ||||
|   for (uint16_t i = 0; i < 512; i++) { | ||||
|     cacheBuffer_.data[i] = 0; | ||||
|   } | ||||
|   cacheBlockNumber_ = blockNumber; | ||||
|   cacheSetDirty(); | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| // return the size in bytes of a cluster chain | ||||
| uint8_t SdVolume::chainSize(uint32_t cluster, uint32_t* size) const { | ||||
|   uint32_t s = 0; | ||||
|   do { | ||||
|     if (!fatGet(cluster, &cluster)) return false; | ||||
|     s += 512UL << clusterSizeShift_; | ||||
|   } while (!isEOC(cluster)); | ||||
|   *size = s; | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| // Fetch a FAT entry | ||||
| uint8_t SdVolume::fatGet(uint32_t cluster, uint32_t* value) const { | ||||
|   if (cluster > (clusterCount_ + 1)) return false; | ||||
|   uint32_t lba = fatStartBlock_; | ||||
|   lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7; | ||||
|   if (lba != cacheBlockNumber_) { | ||||
|     if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; | ||||
|   } | ||||
|   if (fatType_ == 16) { | ||||
|     *value = cacheBuffer_.fat16[cluster & 0XFF]; | ||||
|   } else { | ||||
|     *value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| // Store a FAT entry | ||||
| uint8_t SdVolume::fatPut(uint32_t cluster, uint32_t value) { | ||||
|   // error if reserved cluster | ||||
|   if (cluster < 2) return false; | ||||
|  | ||||
|   // error if not in FAT | ||||
|   if (cluster > (clusterCount_ + 1)) return false; | ||||
|  | ||||
|   // calculate block address for entry | ||||
|   uint32_t lba = fatStartBlock_; | ||||
|   lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7; | ||||
|  | ||||
|   if (lba != cacheBlockNumber_) { | ||||
|     if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; | ||||
|   } | ||||
|   // store entry | ||||
|   if (fatType_ == 16) { | ||||
|     cacheBuffer_.fat16[cluster & 0XFF] = value; | ||||
|   } else { | ||||
|     cacheBuffer_.fat32[cluster & 0X7F] = value; | ||||
|   } | ||||
|   cacheSetDirty(); | ||||
|  | ||||
|   // mirror second FAT | ||||
|   if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| // free a cluster chain | ||||
| uint8_t SdVolume::freeChain(uint32_t cluster) { | ||||
|   // clear free cluster location | ||||
|   allocSearchStart_ = 2; | ||||
|  | ||||
|   do { | ||||
|     uint32_t next; | ||||
|     if (!fatGet(cluster, &next)) return false; | ||||
|  | ||||
|     // free cluster | ||||
|     if (!fatPut(cluster, 0)) return false; | ||||
|  | ||||
|     cluster = next; | ||||
|   } while (!isEOC(cluster)); | ||||
|  | ||||
|   return true; | ||||
| } | ||||
| //------------------------------------------------------------------------------ | ||||
| /** | ||||
|  * Initialize a FAT volume. | ||||
|  * | ||||
|  * \param[in] dev The SD card where the volume is located. | ||||
|  * | ||||
|  * \param[in] part The partition to be used.  Legal values for \a part are | ||||
|  * 1-4 to use the corresponding partition on a device formatted with | ||||
|  * a MBR, Master Boot Record, or zero if the device is formatted as | ||||
|  * a super floppy with the FAT boot sector in block zero. | ||||
|  * | ||||
|  * \return The value one, true, is returned for success and | ||||
|  * the value zero, false, is returned for failure.  Reasons for | ||||
|  * failure include not finding a valid partition, not finding a valid | ||||
|  * FAT file system in the specified partition or an I/O error. | ||||
|  */ | ||||
| uint8_t SdVolume::init(Sd2Card* dev, uint8_t part) { | ||||
|   uint32_t volumeStartBlock = 0; | ||||
|   sdCard_ = dev; | ||||
|   // if part == 0 assume super floppy with FAT boot sector in block zero | ||||
|   // if part > 0 assume mbr volume with partition table | ||||
|   if (part) { | ||||
|     if (part > 4)return false; | ||||
|     if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false; | ||||
|     part_t* p = &cacheBuffer_.mbr.part[part-1]; | ||||
|     if ((p->boot & 0X7F) !=0  || | ||||
|       p->totalSectors < 100 || | ||||
|       p->firstSector == 0) { | ||||
|       // not a valid partition | ||||
|       return false; | ||||
|     } | ||||
|     volumeStartBlock = p->firstSector; | ||||
|   } | ||||
|   if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false; | ||||
|   bpb_t* bpb = &cacheBuffer_.fbs.bpb; | ||||
|   if (bpb->bytesPerSector != 512 || | ||||
|     bpb->fatCount == 0 || | ||||
|     bpb->reservedSectorCount == 0 || | ||||
|     bpb->sectorsPerCluster == 0) { | ||||
|        // not valid FAT volume | ||||
|       return false; | ||||
|   } | ||||
|   fatCount_ = bpb->fatCount; | ||||
|   blocksPerCluster_ = bpb->sectorsPerCluster; | ||||
|  | ||||
|   // determine shift that is same as multiply by blocksPerCluster_ | ||||
|   clusterSizeShift_ = 0; | ||||
|   while (blocksPerCluster_ != (1 << clusterSizeShift_)) { | ||||
|     // error if not power of 2 | ||||
|     if (clusterSizeShift_++ > 7) return false; | ||||
|   } | ||||
|   blocksPerFat_ = bpb->sectorsPerFat16 ? | ||||
|                     bpb->sectorsPerFat16 : bpb->sectorsPerFat32; | ||||
|  | ||||
|   fatStartBlock_ = volumeStartBlock + bpb->reservedSectorCount; | ||||
|  | ||||
|   // count for FAT16 zero for FAT32 | ||||
|   rootDirEntryCount_ = bpb->rootDirEntryCount; | ||||
|  | ||||
|   // directory start for FAT16 dataStart for FAT32 | ||||
|   rootDirStart_ = fatStartBlock_ + bpb->fatCount * blocksPerFat_; | ||||
|  | ||||
|   // data start for FAT16 and FAT32 | ||||
|   dataStartBlock_ = rootDirStart_ + ((32 * bpb->rootDirEntryCount + 511)/512); | ||||
|  | ||||
|   // total blocks for FAT16 or FAT32 | ||||
|   uint32_t totalBlocks = bpb->totalSectors16 ? | ||||
|                            bpb->totalSectors16 : bpb->totalSectors32; | ||||
|   // total data blocks | ||||
|   clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock); | ||||
|  | ||||
|   // divide by cluster size to get cluster count | ||||
|   clusterCount_ >>= clusterSizeShift_; | ||||
|  | ||||
|   // FAT type is determined by cluster count | ||||
|   if (clusterCount_ < 4085) { | ||||
|     fatType_ = 12; | ||||
|   } else if (clusterCount_ < 65525) { | ||||
|     fatType_ = 16; | ||||
|   } else { | ||||
|     rootDirStart_ = bpb->fat32RootCluster; | ||||
|     fatType_ = 32; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|   | ||||
							
								
								
									
										5118
									
								
								Marlin/fastio.h
									
									
									
									
									
								
							
							
						
						
									
										5118
									
								
								Marlin/fastio.h
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								Marlin/lcd.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								Marlin/lcd.h
									
									
									
									
									
								
							| @@ -1,10 +0,0 @@ | ||||
| #ifndef __LCDH | ||||
| #define __LCDH | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif | ||||
| @@ -1 +0,0 @@ | ||||
|  | ||||
							
								
								
									
										1140
									
								
								Marlin/pins.h
									
									
									
									
									
								
							
							
						
						
									
										1140
									
								
								Marlin/pins.h
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1170
									
								
								Marlin/planner.cpp
									
									
									
									
									
								
							
							
						
						
									
										1170
									
								
								Marlin/planner.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										182
									
								
								Marlin/planner.h
									
									
									
									
									
								
							
							
						
						
									
										182
									
								
								Marlin/planner.h
									
									
									
									
									
								
							| @@ -1,90 +1,92 @@ | ||||
| /* | ||||
|   planner.h - buffers movement commands and manages the acceleration profile plan | ||||
|   Part of Grbl | ||||
|  | ||||
|   Copyright (c) 2009-2011 Simen Svale Skogsrud | ||||
|  | ||||
|   Grbl is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
|  | ||||
|   Grbl is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|   GNU General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with Grbl.  If not, see <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
|  | ||||
| // This module is to be considered a sub-module of stepper.c. Please don't include  | ||||
| // this file from any other module. | ||||
|  | ||||
| #ifndef planner_h | ||||
| #define planner_h | ||||
|  | ||||
| // This struct is used when buffering the setup for each linear movement "nominal" values are as specified in  | ||||
| // the source g-code and may never actually be reached if acceleration management is active. | ||||
| typedef struct { | ||||
|   // Fields used by the bresenham algorithm for tracing the line | ||||
|   long steps_x, steps_y, steps_z, steps_e;  // Step count along each axis | ||||
|   long step_event_count;                    // The number of step events required to complete this block | ||||
|   volatile long accelerate_until;                    // The index of the step event on which to stop acceleration | ||||
|   volatile long decelerate_after;                    // The index of the step event on which to start decelerating | ||||
|   volatile long acceleration_rate;                   // The acceleration rate used for acceleration calculation | ||||
|   unsigned char direction_bits;             // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) | ||||
| #ifdef ADVANCE | ||||
|   long advance_rate; | ||||
|   volatile long initial_advance; | ||||
|   volatile long final_advance; | ||||
|   float advance; | ||||
| #endif | ||||
|  | ||||
|   // Fields used by the motion planner to manage acceleration | ||||
|   float speed_x, speed_y, speed_z, speed_e;          // Nominal mm/minute for each axis | ||||
|   float nominal_speed;                               // The nominal speed for this block in mm/min   | ||||
|   float millimeters;                                 // The total travel of this block in mm | ||||
|   float entry_speed; | ||||
|   float acceleration;                                // acceleration mm/sec^2 | ||||
|  | ||||
|   // Settings for the trapezoid generator | ||||
|   long nominal_rate;                                 // The nominal step rate for this block in step_events/sec  | ||||
|   volatile long initial_rate;                        // The jerk-adjusted step rate at start of block   | ||||
|   volatile long final_rate;                          // The minimal rate at exit | ||||
|   long acceleration_st;                              // acceleration steps/sec^2 | ||||
|   volatile char busy; | ||||
| } block_t; | ||||
|        | ||||
| // Initialize the motion plan subsystem       | ||||
| void plan_init(); | ||||
|  | ||||
| // Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in  | ||||
| // millimaters. Feed rate specifies the speed of the motion. | ||||
| void plan_buffer_line(float x, float y, float z, float e, float feed_rate); | ||||
|  | ||||
| // Set position. Used for G92 instructions. | ||||
| void plan_set_position(float x, float y, float z, float e); | ||||
|  | ||||
| // Called when the current block is no longer needed. Discards the block and makes the memory | ||||
| // availible for new blocks. | ||||
| void plan_discard_current_block(); | ||||
|  | ||||
| // Gets the current block. Returns NULL if buffer empty | ||||
| block_t *plan_get_current_block(); | ||||
|  | ||||
| void check_axes_activity(); | ||||
|  | ||||
| extern unsigned long minsegmenttime; | ||||
| extern float max_feedrate[4]; // set the max speeds | ||||
| extern float axis_steps_per_unit[4]; | ||||
| extern long max_acceleration_units_per_sq_second[4]; // Use M201 to override by software | ||||
| extern float minimumfeedrate; | ||||
| extern float acceleration;         // Normal acceleration mm/s^2  THIS IS THE DEFAULT ACCELERATION for all moves. M204 SXXXX | ||||
| extern float retract_acceleration; //  mm/s^2   filament pull-pack and push-forward  while standing still in the other axis M204 TXXXX | ||||
| extern float max_xy_jerk; //speed than can be stopped at once, if i understand correctly. | ||||
| extern float max_z_jerk; | ||||
| extern float mintravelfeedrate; | ||||
| extern unsigned long axis_steps_per_sqr_second[NUM_AXIS]; | ||||
|  | ||||
| #endif | ||||
| /* | ||||
|   planner.h - buffers movement commands and manages the acceleration profile plan | ||||
|   Part of Grbl | ||||
|  | ||||
|   Copyright (c) 2009-2011 Simen Svale Skogsrud | ||||
|  | ||||
|   Grbl is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
|  | ||||
|   Grbl is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|   GNU General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with Grbl.  If not, see <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
|  | ||||
| // This module is to be considered a sub-module of stepper.c. Please don't include  | ||||
| // this file from any other module. | ||||
|  | ||||
| #ifndef planner_h | ||||
| #define planner_h | ||||
|  | ||||
| #include "Configuration.h" | ||||
|  | ||||
| // This struct is used when buffering the setup for each linear movement "nominal" values are as specified in  | ||||
| // the source g-code and may never actually be reached if acceleration management is active. | ||||
| typedef struct { | ||||
|   // Fields used by the bresenham algorithm for tracing the line | ||||
|   long steps_x, steps_y, steps_z, steps_e;  // Step count along each axis | ||||
|   long step_event_count;                    // The number of step events required to complete this block | ||||
|   volatile long accelerate_until;                    // The index of the step event on which to stop acceleration | ||||
|   volatile long decelerate_after;                    // The index of the step event on which to start decelerating | ||||
|   volatile long acceleration_rate;                   // The acceleration rate used for acceleration calculation | ||||
|   unsigned char direction_bits;             // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) | ||||
| #ifdef ADVANCE | ||||
|   long advance_rate; | ||||
|   volatile long initial_advance; | ||||
|   volatile long final_advance; | ||||
|   float advance; | ||||
| #endif | ||||
|  | ||||
|   // Fields used by the motion planner to manage acceleration | ||||
|   float speed_x, speed_y, speed_z, speed_e;          // Nominal mm/minute for each axis | ||||
|   float nominal_speed;                               // The nominal speed for this block in mm/min   | ||||
|   float millimeters;                                 // The total travel of this block in mm | ||||
|   float entry_speed; | ||||
|   float acceleration;                                // acceleration mm/sec^2 | ||||
|  | ||||
|   // Settings for the trapezoid generator | ||||
|   long nominal_rate;                                 // The nominal step rate for this block in step_events/sec  | ||||
|   volatile long initial_rate;                        // The jerk-adjusted step rate at start of block   | ||||
|   volatile long final_rate;                          // The minimal rate at exit | ||||
|   long acceleration_st;                              // acceleration steps/sec^2 | ||||
|   volatile char busy; | ||||
| } block_t; | ||||
|        | ||||
| // Initialize the motion plan subsystem       | ||||
| void plan_init(); | ||||
|  | ||||
| // Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in  | ||||
| // millimaters. Feed rate specifies the speed of the motion. | ||||
| void plan_buffer_line(float x, float y, float z, float e, float feed_rate); | ||||
|  | ||||
| // Set position. Used for G92 instructions. | ||||
| void plan_set_position(float x, float y, float z, float e); | ||||
|  | ||||
| // Called when the current block is no longer needed. Discards the block and makes the memory | ||||
| // availible for new blocks. | ||||
| void plan_discard_current_block(); | ||||
|  | ||||
| // Gets the current block. Returns NULL if buffer empty | ||||
| block_t *plan_get_current_block(); | ||||
|  | ||||
| void check_axes_activity(); | ||||
|  | ||||
| extern unsigned long minsegmenttime; | ||||
| extern float max_feedrate[4]; // set the max speeds | ||||
| extern float axis_steps_per_unit[4]; | ||||
| extern long max_acceleration_units_per_sq_second[4]; // Use M201 to override by software | ||||
| extern float minimumfeedrate; | ||||
| extern float acceleration;         // Normal acceleration mm/s^2  THIS IS THE DEFAULT ACCELERATION for all moves. M204 SXXXX | ||||
| extern float retract_acceleration; //  mm/s^2   filament pull-pack and push-forward  while standing still in the other axis M204 TXXXX | ||||
| extern float max_xy_jerk; //speed than can be stopped at once, if i understand correctly. | ||||
| extern float max_z_jerk; | ||||
| extern float mintravelfeedrate; | ||||
| extern unsigned long axis_steps_per_sqr_second[NUM_AXIS]; | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,75 +1,75 @@ | ||||
| #ifndef SPEED_LOOKUPTABLE_H | ||||
| #define SPEED_LOOKUPTABLE_H | ||||
|  | ||||
| #include <avr/pgmspace.h> | ||||
|  | ||||
| uint16_t speed_lookuptable_fast[256][2] PROGMEM = {\ | ||||
| { 62500, 55556}, { 6944, 3268}, { 3676, 1176}, { 2500, 607}, { 1893, 369}, { 1524, 249}, { 1275, 179}, { 1096, 135},  | ||||
| { 961, 105}, { 856, 85}, { 771, 69}, { 702, 58}, { 644, 49}, { 595, 42}, { 553, 37}, { 516, 32},  | ||||
| { 484, 28}, { 456, 25}, { 431, 23}, { 408, 20}, { 388, 19}, { 369, 16}, { 353, 16}, { 337, 14},  | ||||
| { 323, 13}, { 310, 11}, { 299, 11}, { 288, 11}, { 277, 9}, { 268, 9}, { 259, 8}, { 251, 8},  | ||||
| { 243, 8}, { 235, 7}, { 228, 6}, { 222, 6}, { 216, 6}, { 210, 6}, { 204, 5}, { 199, 5},  | ||||
| { 194, 5}, { 189, 4}, { 185, 4}, { 181, 4}, { 177, 4}, { 173, 4}, { 169, 4}, { 165, 3},  | ||||
| { 162, 3}, { 159, 4}, { 155, 3}, { 152, 3}, { 149, 2}, { 147, 3}, { 144, 3}, { 141, 2},  | ||||
| { 139, 3}, { 136, 2}, { 134, 2}, { 132, 3}, { 129, 2}, { 127, 2}, { 125, 2}, { 123, 2},  | ||||
| { 121, 2}, { 119, 1}, { 118, 2}, { 116, 2}, { 114, 1}, { 113, 2}, { 111, 2}, { 109, 1},  | ||||
| { 108, 2}, { 106, 1}, { 105, 2}, { 103, 1}, { 102, 1}, { 101, 1}, { 100, 2}, { 98, 1},  | ||||
| { 97, 1}, { 96, 1}, { 95, 2}, { 93, 1}, { 92, 1}, { 91, 1}, { 90, 1}, { 89, 1},  | ||||
| { 88, 1}, { 87, 1}, { 86, 1}, { 85, 1}, { 84, 1}, { 83, 0}, { 83, 1}, { 82, 1},  | ||||
| { 81, 1}, { 80, 1}, { 79, 1}, { 78, 0}, { 78, 1}, { 77, 1}, { 76, 1}, { 75, 0},  | ||||
| { 75, 1}, { 74, 1}, { 73, 1}, { 72, 0}, { 72, 1}, { 71, 1}, { 70, 0}, { 70, 1},  | ||||
| { 69, 0}, { 69, 1}, { 68, 1}, { 67, 0}, { 67, 1}, { 66, 0}, { 66, 1}, { 65, 0},  | ||||
| { 65, 1}, { 64, 1}, { 63, 0}, { 63, 1}, { 62, 0}, { 62, 1}, { 61, 0}, { 61, 1},  | ||||
| { 60, 0}, { 60, 0}, { 60, 1}, { 59, 0}, { 59, 1}, { 58, 0}, { 58, 1}, { 57, 0},  | ||||
| { 57, 1}, { 56, 0}, { 56, 0}, { 56, 1}, { 55, 0}, { 55, 1}, { 54, 0}, { 54, 0},  | ||||
| { 54, 1}, { 53, 0}, { 53, 0}, { 53, 1}, { 52, 0}, { 52, 0}, { 52, 1}, { 51, 0},  | ||||
| { 51, 0}, { 51, 1}, { 50, 0}, { 50, 0}, { 50, 1}, { 49, 0}, { 49, 0}, { 49, 1},  | ||||
| { 48, 0}, { 48, 0}, { 48, 1}, { 47, 0}, { 47, 0}, { 47, 0}, { 47, 1}, { 46, 0},  | ||||
| { 46, 0}, { 46, 1}, { 45, 0}, { 45, 0}, { 45, 0}, { 45, 1}, { 44, 0}, { 44, 0},  | ||||
| { 44, 0}, { 44, 1}, { 43, 0}, { 43, 0}, { 43, 0}, { 43, 1}, { 42, 0}, { 42, 0},  | ||||
| { 42, 0}, { 42, 1}, { 41, 0}, { 41, 0}, { 41, 0}, { 41, 0}, { 41, 1}, { 40, 0},  | ||||
| { 40, 0}, { 40, 0}, { 40, 0}, { 40, 1}, { 39, 0}, { 39, 0}, { 39, 0}, { 39, 0},  | ||||
| { 39, 1}, { 38, 0}, { 38, 0}, { 38, 0}, { 38, 0}, { 38, 1}, { 37, 0}, { 37, 0},  | ||||
| { 37, 0}, { 37, 0}, { 37, 0}, { 37, 1}, { 36, 0}, { 36, 0}, { 36, 0}, { 36, 0},  | ||||
| { 36, 1}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 1},  | ||||
| { 34, 0}, { 34, 0}, { 34, 0}, { 34, 0}, { 34, 0}, { 34, 1}, { 33, 0}, { 33, 0},  | ||||
| { 33, 0}, { 33, 0}, { 33, 0}, { 33, 0}, { 33, 1}, { 32, 0}, { 32, 0}, { 32, 0},  | ||||
| { 32, 0}, { 32, 0}, { 32, 0}, { 32, 0}, { 32, 1}, { 31, 0}, { 31, 0}, { 31, 0},  | ||||
| { 31, 0}, { 31, 0}, { 31, 0}, { 31, 1}, { 30, 0}, { 30, 0}, { 30, 0}, { 30, 0} | ||||
| }; | ||||
| uint16_t speed_lookuptable_slow[256][2] PROGMEM = {\ | ||||
| { 62500, 12500}, { 50000, 8334}, { 41666, 5952}, { 35714, 4464}, { 31250, 3473}, { 27777, 2777}, { 25000, 2273}, { 22727, 1894},  | ||||
| { 20833, 1603}, { 19230, 1373}, { 17857, 1191}, { 16666, 1041}, { 15625, 920}, { 14705, 817}, { 13888, 731}, { 13157, 657},  | ||||
| { 12500, 596}, { 11904, 541}, { 11363, 494}, { 10869, 453}, { 10416, 416}, { 10000, 385}, { 9615, 356}, { 9259, 331},  | ||||
| { 8928, 308}, { 8620, 287}, { 8333, 269}, { 8064, 252}, { 7812, 237}, { 7575, 223}, { 7352, 210}, { 7142, 198},  | ||||
| { 6944, 188}, { 6756, 178}, { 6578, 168}, { 6410, 160}, { 6250, 153}, { 6097, 145}, { 5952, 139}, { 5813, 132},  | ||||
| { 5681, 126}, { 5555, 121}, { 5434, 115}, { 5319, 111}, { 5208, 106}, { 5102, 102}, { 5000, 99}, { 4901, 94},  | ||||
| { 4807, 91}, { 4716, 87}, { 4629, 84}, { 4545, 81}, { 4464, 79}, { 4385, 75}, { 4310, 73}, { 4237, 71},  | ||||
| { 4166, 68}, { 4098, 66}, { 4032, 64}, { 3968, 62}, { 3906, 60}, { 3846, 59}, { 3787, 56}, { 3731, 55},  | ||||
| { 3676, 53}, { 3623, 52}, { 3571, 50}, { 3521, 49}, { 3472, 48}, { 3424, 46}, { 3378, 45}, { 3333, 44},  | ||||
| { 3289, 43}, { 3246, 41}, { 3205, 41}, { 3164, 39}, { 3125, 39}, { 3086, 38}, { 3048, 36}, { 3012, 36},  | ||||
| { 2976, 35}, { 2941, 35}, { 2906, 33}, { 2873, 33}, { 2840, 32}, { 2808, 31}, { 2777, 30}, { 2747, 30},  | ||||
| { 2717, 29}, { 2688, 29}, { 2659, 28}, { 2631, 27}, { 2604, 27}, { 2577, 26}, { 2551, 26}, { 2525, 25},  | ||||
| { 2500, 25}, { 2475, 25}, { 2450, 23}, { 2427, 24}, { 2403, 23}, { 2380, 22}, { 2358, 22}, { 2336, 22},  | ||||
| { 2314, 21}, { 2293, 21}, { 2272, 20}, { 2252, 20}, { 2232, 20}, { 2212, 20}, { 2192, 19}, { 2173, 18},  | ||||
| { 2155, 19}, { 2136, 18}, { 2118, 18}, { 2100, 17}, { 2083, 17}, { 2066, 17}, { 2049, 17}, { 2032, 16},  | ||||
| { 2016, 16}, { 2000, 16}, { 1984, 16}, { 1968, 15}, { 1953, 16}, { 1937, 14}, { 1923, 15}, { 1908, 15},  | ||||
| { 1893, 14}, { 1879, 14}, { 1865, 14}, { 1851, 13}, { 1838, 14}, { 1824, 13}, { 1811, 13}, { 1798, 13},  | ||||
| { 1785, 12}, { 1773, 13}, { 1760, 12}, { 1748, 12}, { 1736, 12}, { 1724, 12}, { 1712, 12}, { 1700, 11},  | ||||
| { 1689, 12}, { 1677, 11}, { 1666, 11}, { 1655, 11}, { 1644, 11}, { 1633, 10}, { 1623, 11}, { 1612, 10},  | ||||
| { 1602, 10}, { 1592, 10}, { 1582, 10}, { 1572, 10}, { 1562, 10}, { 1552, 9}, { 1543, 10}, { 1533, 9},  | ||||
| { 1524, 9}, { 1515, 9}, { 1506, 9}, { 1497, 9}, { 1488, 9}, { 1479, 9}, { 1470, 9}, { 1461, 8},  | ||||
| { 1453, 8}, { 1445, 9}, { 1436, 8}, { 1428, 8}, { 1420, 8}, { 1412, 8}, { 1404, 8}, { 1396, 8},  | ||||
| { 1388, 7}, { 1381, 8}, { 1373, 7}, { 1366, 8}, { 1358, 7}, { 1351, 7}, { 1344, 8}, { 1336, 7},  | ||||
| { 1329, 7}, { 1322, 7}, { 1315, 7}, { 1308, 6}, { 1302, 7}, { 1295, 7}, { 1288, 6}, { 1282, 7},  | ||||
| { 1275, 6}, { 1269, 7}, { 1262, 6}, { 1256, 6}, { 1250, 7}, { 1243, 6}, { 1237, 6}, { 1231, 6},  | ||||
| { 1225, 6}, { 1219, 6}, { 1213, 6}, { 1207, 6}, { 1201, 5}, { 1196, 6}, { 1190, 6}, { 1184, 5},  | ||||
| { 1179, 6}, { 1173, 5}, { 1168, 6}, { 1162, 5}, { 1157, 5}, { 1152, 6}, { 1146, 5}, { 1141, 5},  | ||||
| { 1136, 5}, { 1131, 5}, { 1126, 5}, { 1121, 5}, { 1116, 5}, { 1111, 5}, { 1106, 5}, { 1101, 5},  | ||||
| { 1096, 5}, { 1091, 5}, { 1086, 4}, { 1082, 5}, { 1077, 5}, { 1072, 4}, { 1068, 5}, { 1063, 4},  | ||||
| { 1059, 5}, { 1054, 4}, { 1050, 4}, { 1046, 5}, { 1041, 4}, { 1037, 4}, { 1033, 5}, { 1028, 4},  | ||||
| { 1024, 4}, { 1020, 4}, { 1016, 4}, { 1012, 4}, { 1008, 4}, { 1004, 4}, { 1000, 4}, { 996, 4},  | ||||
| { 992, 4}, { 988, 4}, { 984, 4}, { 980, 4}, { 976, 4}, { 972, 4}, { 968, 3}, { 965, 3} | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| #ifndef SPEED_LOOKUPTABLE_H | ||||
| #define SPEED_LOOKUPTABLE_H | ||||
|  | ||||
| #include <avr/pgmspace.h> | ||||
|  | ||||
| uint16_t speed_lookuptable_fast[256][2] PROGMEM = {\ | ||||
| { 62500, 55556}, { 6944, 3268}, { 3676, 1176}, { 2500, 607}, { 1893, 369}, { 1524, 249}, { 1275, 179}, { 1096, 135},  | ||||
| { 961, 105}, { 856, 85}, { 771, 69}, { 702, 58}, { 644, 49}, { 595, 42}, { 553, 37}, { 516, 32},  | ||||
| { 484, 28}, { 456, 25}, { 431, 23}, { 408, 20}, { 388, 19}, { 369, 16}, { 353, 16}, { 337, 14},  | ||||
| { 323, 13}, { 310, 11}, { 299, 11}, { 288, 11}, { 277, 9}, { 268, 9}, { 259, 8}, { 251, 8},  | ||||
| { 243, 8}, { 235, 7}, { 228, 6}, { 222, 6}, { 216, 6}, { 210, 6}, { 204, 5}, { 199, 5},  | ||||
| { 194, 5}, { 189, 4}, { 185, 4}, { 181, 4}, { 177, 4}, { 173, 4}, { 169, 4}, { 165, 3},  | ||||
| { 162, 3}, { 159, 4}, { 155, 3}, { 152, 3}, { 149, 2}, { 147, 3}, { 144, 3}, { 141, 2},  | ||||
| { 139, 3}, { 136, 2}, { 134, 2}, { 132, 3}, { 129, 2}, { 127, 2}, { 125, 2}, { 123, 2},  | ||||
| { 121, 2}, { 119, 1}, { 118, 2}, { 116, 2}, { 114, 1}, { 113, 2}, { 111, 2}, { 109, 1},  | ||||
| { 108, 2}, { 106, 1}, { 105, 2}, { 103, 1}, { 102, 1}, { 101, 1}, { 100, 2}, { 98, 1},  | ||||
| { 97, 1}, { 96, 1}, { 95, 2}, { 93, 1}, { 92, 1}, { 91, 1}, { 90, 1}, { 89, 1},  | ||||
| { 88, 1}, { 87, 1}, { 86, 1}, { 85, 1}, { 84, 1}, { 83, 0}, { 83, 1}, { 82, 1},  | ||||
| { 81, 1}, { 80, 1}, { 79, 1}, { 78, 0}, { 78, 1}, { 77, 1}, { 76, 1}, { 75, 0},  | ||||
| { 75, 1}, { 74, 1}, { 73, 1}, { 72, 0}, { 72, 1}, { 71, 1}, { 70, 0}, { 70, 1},  | ||||
| { 69, 0}, { 69, 1}, { 68, 1}, { 67, 0}, { 67, 1}, { 66, 0}, { 66, 1}, { 65, 0},  | ||||
| { 65, 1}, { 64, 1}, { 63, 0}, { 63, 1}, { 62, 0}, { 62, 1}, { 61, 0}, { 61, 1},  | ||||
| { 60, 0}, { 60, 0}, { 60, 1}, { 59, 0}, { 59, 1}, { 58, 0}, { 58, 1}, { 57, 0},  | ||||
| { 57, 1}, { 56, 0}, { 56, 0}, { 56, 1}, { 55, 0}, { 55, 1}, { 54, 0}, { 54, 0},  | ||||
| { 54, 1}, { 53, 0}, { 53, 0}, { 53, 1}, { 52, 0}, { 52, 0}, { 52, 1}, { 51, 0},  | ||||
| { 51, 0}, { 51, 1}, { 50, 0}, { 50, 0}, { 50, 1}, { 49, 0}, { 49, 0}, { 49, 1},  | ||||
| { 48, 0}, { 48, 0}, { 48, 1}, { 47, 0}, { 47, 0}, { 47, 0}, { 47, 1}, { 46, 0},  | ||||
| { 46, 0}, { 46, 1}, { 45, 0}, { 45, 0}, { 45, 0}, { 45, 1}, { 44, 0}, { 44, 0},  | ||||
| { 44, 0}, { 44, 1}, { 43, 0}, { 43, 0}, { 43, 0}, { 43, 1}, { 42, 0}, { 42, 0},  | ||||
| { 42, 0}, { 42, 1}, { 41, 0}, { 41, 0}, { 41, 0}, { 41, 0}, { 41, 1}, { 40, 0},  | ||||
| { 40, 0}, { 40, 0}, { 40, 0}, { 40, 1}, { 39, 0}, { 39, 0}, { 39, 0}, { 39, 0},  | ||||
| { 39, 1}, { 38, 0}, { 38, 0}, { 38, 0}, { 38, 0}, { 38, 1}, { 37, 0}, { 37, 0},  | ||||
| { 37, 0}, { 37, 0}, { 37, 0}, { 37, 1}, { 36, 0}, { 36, 0}, { 36, 0}, { 36, 0},  | ||||
| { 36, 1}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 0}, { 35, 1},  | ||||
| { 34, 0}, { 34, 0}, { 34, 0}, { 34, 0}, { 34, 0}, { 34, 1}, { 33, 0}, { 33, 0},  | ||||
| { 33, 0}, { 33, 0}, { 33, 0}, { 33, 0}, { 33, 1}, { 32, 0}, { 32, 0}, { 32, 0},  | ||||
| { 32, 0}, { 32, 0}, { 32, 0}, { 32, 0}, { 32, 1}, { 31, 0}, { 31, 0}, { 31, 0},  | ||||
| { 31, 0}, { 31, 0}, { 31, 0}, { 31, 1}, { 30, 0}, { 30, 0}, { 30, 0}, { 30, 0} | ||||
| }; | ||||
| uint16_t speed_lookuptable_slow[256][2] PROGMEM = {\ | ||||
| { 62500, 12500}, { 50000, 8334}, { 41666, 5952}, { 35714, 4464}, { 31250, 3473}, { 27777, 2777}, { 25000, 2273}, { 22727, 1894},  | ||||
| { 20833, 1603}, { 19230, 1373}, { 17857, 1191}, { 16666, 1041}, { 15625, 920}, { 14705, 817}, { 13888, 731}, { 13157, 657},  | ||||
| { 12500, 596}, { 11904, 541}, { 11363, 494}, { 10869, 453}, { 10416, 416}, { 10000, 385}, { 9615, 356}, { 9259, 331},  | ||||
| { 8928, 308}, { 8620, 287}, { 8333, 269}, { 8064, 252}, { 7812, 237}, { 7575, 223}, { 7352, 210}, { 7142, 198},  | ||||
| { 6944, 188}, { 6756, 178}, { 6578, 168}, { 6410, 160}, { 6250, 153}, { 6097, 145}, { 5952, 139}, { 5813, 132},  | ||||
| { 5681, 126}, { 5555, 121}, { 5434, 115}, { 5319, 111}, { 5208, 106}, { 5102, 102}, { 5000, 99}, { 4901, 94},  | ||||
| { 4807, 91}, { 4716, 87}, { 4629, 84}, { 4545, 81}, { 4464, 79}, { 4385, 75}, { 4310, 73}, { 4237, 71},  | ||||
| { 4166, 68}, { 4098, 66}, { 4032, 64}, { 3968, 62}, { 3906, 60}, { 3846, 59}, { 3787, 56}, { 3731, 55},  | ||||
| { 3676, 53}, { 3623, 52}, { 3571, 50}, { 3521, 49}, { 3472, 48}, { 3424, 46}, { 3378, 45}, { 3333, 44},  | ||||
| { 3289, 43}, { 3246, 41}, { 3205, 41}, { 3164, 39}, { 3125, 39}, { 3086, 38}, { 3048, 36}, { 3012, 36},  | ||||
| { 2976, 35}, { 2941, 35}, { 2906, 33}, { 2873, 33}, { 2840, 32}, { 2808, 31}, { 2777, 30}, { 2747, 30},  | ||||
| { 2717, 29}, { 2688, 29}, { 2659, 28}, { 2631, 27}, { 2604, 27}, { 2577, 26}, { 2551, 26}, { 2525, 25},  | ||||
| { 2500, 25}, { 2475, 25}, { 2450, 23}, { 2427, 24}, { 2403, 23}, { 2380, 22}, { 2358, 22}, { 2336, 22},  | ||||
| { 2314, 21}, { 2293, 21}, { 2272, 20}, { 2252, 20}, { 2232, 20}, { 2212, 20}, { 2192, 19}, { 2173, 18},  | ||||
| { 2155, 19}, { 2136, 18}, { 2118, 18}, { 2100, 17}, { 2083, 17}, { 2066, 17}, { 2049, 17}, { 2032, 16},  | ||||
| { 2016, 16}, { 2000, 16}, { 1984, 16}, { 1968, 15}, { 1953, 16}, { 1937, 14}, { 1923, 15}, { 1908, 15},  | ||||
| { 1893, 14}, { 1879, 14}, { 1865, 14}, { 1851, 13}, { 1838, 14}, { 1824, 13}, { 1811, 13}, { 1798, 13},  | ||||
| { 1785, 12}, { 1773, 13}, { 1760, 12}, { 1748, 12}, { 1736, 12}, { 1724, 12}, { 1712, 12}, { 1700, 11},  | ||||
| { 1689, 12}, { 1677, 11}, { 1666, 11}, { 1655, 11}, { 1644, 11}, { 1633, 10}, { 1623, 11}, { 1612, 10},  | ||||
| { 1602, 10}, { 1592, 10}, { 1582, 10}, { 1572, 10}, { 1562, 10}, { 1552, 9}, { 1543, 10}, { 1533, 9},  | ||||
| { 1524, 9}, { 1515, 9}, { 1506, 9}, { 1497, 9}, { 1488, 9}, { 1479, 9}, { 1470, 9}, { 1461, 8},  | ||||
| { 1453, 8}, { 1445, 9}, { 1436, 8}, { 1428, 8}, { 1420, 8}, { 1412, 8}, { 1404, 8}, { 1396, 8},  | ||||
| { 1388, 7}, { 1381, 8}, { 1373, 7}, { 1366, 8}, { 1358, 7}, { 1351, 7}, { 1344, 8}, { 1336, 7},  | ||||
| { 1329, 7}, { 1322, 7}, { 1315, 7}, { 1308, 6}, { 1302, 7}, { 1295, 7}, { 1288, 6}, { 1282, 7},  | ||||
| { 1275, 6}, { 1269, 7}, { 1262, 6}, { 1256, 6}, { 1250, 7}, { 1243, 6}, { 1237, 6}, { 1231, 6},  | ||||
| { 1225, 6}, { 1219, 6}, { 1213, 6}, { 1207, 6}, { 1201, 5}, { 1196, 6}, { 1190, 6}, { 1184, 5},  | ||||
| { 1179, 6}, { 1173, 5}, { 1168, 6}, { 1162, 5}, { 1157, 5}, { 1152, 6}, { 1146, 5}, { 1141, 5},  | ||||
| { 1136, 5}, { 1131, 5}, { 1126, 5}, { 1121, 5}, { 1116, 5}, { 1111, 5}, { 1106, 5}, { 1101, 5},  | ||||
| { 1096, 5}, { 1091, 5}, { 1086, 4}, { 1082, 5}, { 1077, 5}, { 1072, 4}, { 1068, 5}, { 1063, 4},  | ||||
| { 1059, 5}, { 1054, 4}, { 1050, 4}, { 1046, 5}, { 1041, 4}, { 1037, 4}, { 1033, 5}, { 1028, 4},  | ||||
| { 1024, 4}, { 1020, 4}, { 1016, 4}, { 1012, 4}, { 1008, 4}, { 1004, 4}, { 1000, 4}, { 996, 4},  | ||||
| { 992, 4}, { 988, 4}, { 984, 4}, { 980, 4}, { 976, 4}, { 972, 4}, { 968, 3}, { 965, 3} | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										1184
									
								
								Marlin/stepper.cpp
									
									
									
									
									
								
							
							
						
						
									
										1184
									
								
								Marlin/stepper.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,40 +1,44 @@ | ||||
| /* | ||||
|   stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors | ||||
|   Part of Grbl | ||||
|  | ||||
|   Copyright (c) 2009-2011 Simen Svale Skogsrud | ||||
|  | ||||
|   Grbl is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
|  | ||||
|   Grbl is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|   GNU General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with Grbl.  If not, see <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
|  | ||||
| #ifndef stepper_h | ||||
| #define stepper_h  | ||||
| // Initialize and start the stepper motor subsystem | ||||
| void st_init(); | ||||
|  | ||||
| // Block until all buffered steps are executed | ||||
| void st_synchronize(); | ||||
|  | ||||
| // The stepper subsystem goes to sleep when it runs out of things to execute. Call this | ||||
| // to notify the subsystem that it is time to go to work. | ||||
| void st_wake_up(); | ||||
|  | ||||
| // if DEBUG_STEPS is enabled, M114 can be used to compare two methods of determining the X,Y,Z position of the printer. | ||||
| // for debugging purposes only, should be disabled by default | ||||
| #ifdef DEBUG_STEPS | ||||
| extern volatile long count_position[NUM_AXIS]; | ||||
| extern volatile int count_direction[NUM_AXIS]; | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
| /* | ||||
|   stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors | ||||
|   Part of Grbl | ||||
|  | ||||
|   Copyright (c) 2009-2011 Simen Svale Skogsrud | ||||
|  | ||||
|   Grbl is free software: you can redistribute it and/or modify | ||||
|   it under the terms of the GNU General Public License as published by | ||||
|   the Free Software Foundation, either version 3 of the License, or | ||||
|   (at your option) any later version. | ||||
|  | ||||
|   Grbl is distributed in the hope that it will be useful, | ||||
|   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|   GNU General Public License for more details. | ||||
|  | ||||
|   You should have received a copy of the GNU General Public License | ||||
|   along with Grbl.  If not, see <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
|  | ||||
| #ifndef stepper_h | ||||
| #define stepper_h  | ||||
|  | ||||
| #include "planner.h" | ||||
|  | ||||
| // Initialize and start the stepper motor subsystem | ||||
| void st_init(); | ||||
|  | ||||
| // Block until all buffered steps are executed | ||||
| void st_synchronize(); | ||||
|  | ||||
| // The stepper subsystem goes to sleep when it runs out of things to execute. Call this | ||||
| // to notify the subsystem that it is time to go to work. | ||||
| void st_wake_up(); | ||||
|  | ||||
| // if DEBUG_STEPS is enabled, M114 can be used to compare two methods of determining the X,Y,Z position of the printer. | ||||
| // for debugging purposes only, should be disabled by default | ||||
| #ifdef DEBUG_STEPS | ||||
| extern volatile long count_position[NUM_AXIS]; | ||||
| extern volatile int count_direction[NUM_AXIS]; | ||||
| #endif | ||||
|  | ||||
| extern block_t *current_block;  // A pointer to the block currently being traced | ||||
| #endif | ||||
|   | ||||
| @@ -1,84 +1,84 @@ | ||||
| /* | ||||
| Streaming.h - Arduino library for supporting the << streaming operator | ||||
| Copyright (c) 2010 Mikal Hart.  All rights reserved. | ||||
|  | ||||
| This library is free software; you can redistribute it and/or | ||||
| modify it under the terms of the GNU Lesser General Public | ||||
| License as published by the Free Software Foundation; either | ||||
| version 2.1 of the License, or (at your option) any later version. | ||||
|  | ||||
| This library is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
| Lesser General Public License for more details. | ||||
|  | ||||
| You should have received a copy of the GNU Lesser General Public | ||||
| License along with this library; if not, write to the Free Software | ||||
| Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||
| */ | ||||
|  | ||||
| #ifndef ARDUINO_STREAMING | ||||
| #define ARDUINO_STREAMING | ||||
|  | ||||
| //#include <WProgram.h> | ||||
|  | ||||
| #define STREAMING_LIBRARY_VERSION 4 | ||||
|  | ||||
| // Generic template | ||||
| template<class T>  | ||||
| inline Print &operator <<(Print &stream, T arg)  | ||||
| { stream.print(arg); return stream; } | ||||
|  | ||||
| struct _BASED  | ||||
| {  | ||||
|   long val;  | ||||
|   int base; | ||||
|   _BASED(long v, int b): val(v), base(b)  | ||||
|   {} | ||||
| }; | ||||
|  | ||||
| #define _HEX(a)     _BASED(a, HEX) | ||||
| #define _DEC(a)     _BASED(a, DEC) | ||||
| #define _OCT(a)     _BASED(a, OCT) | ||||
| #define _BIN(a)     _BASED(a, BIN) | ||||
| #define _BYTE(a)    _BASED(a, BYTE) | ||||
|  | ||||
| // Specialization for class _BASED | ||||
| // Thanks to Arduino forum user Ben Combee who suggested this  | ||||
| // clever technique to allow for expressions like | ||||
| //   Serial << _HEX(a); | ||||
|  | ||||
| inline Print &operator <<(Print &obj, const _BASED &arg) | ||||
| { obj.print(arg.val, arg.base); return obj; }  | ||||
|  | ||||
| #if ARDUINO >= 18 | ||||
| // Specialization for class _FLOAT | ||||
| // Thanks to Michael Margolis for suggesting a way | ||||
| // to accommodate Arduino 0018's floating point precision | ||||
| // feature like this: | ||||
| //   Serial << _FLOAT(gps_latitude, 6); // 6 digits of precision | ||||
|  | ||||
| struct _FLOAT | ||||
| { | ||||
|   float val; | ||||
|   int digits; | ||||
|   _FLOAT(double v, int d): val(v), digits(d) | ||||
|   {} | ||||
| }; | ||||
|  | ||||
| inline Print &operator <<(Print &obj, const _FLOAT &arg) | ||||
| { obj.print(arg.val, arg.digits); return obj; } | ||||
| #endif | ||||
|  | ||||
| // Specialization for enum _EndLineCode | ||||
| // Thanks to Arduino forum user Paul V. who suggested this | ||||
| // clever technique to allow for expressions like | ||||
| //   Serial << "Hello!" << endl; | ||||
|  | ||||
| enum _EndLineCode { endl }; | ||||
|  | ||||
| inline Print &operator <<(Print &obj, _EndLineCode arg)  | ||||
| { obj.println(); return obj; } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /* | ||||
| Streaming.h - Arduino library for supporting the << streaming operator | ||||
| Copyright (c) 2010 Mikal Hart.  All rights reserved. | ||||
|  | ||||
| This library is free software; you can redistribute it and/or | ||||
| modify it under the terms of the GNU Lesser General Public | ||||
| License as published by the Free Software Foundation; either | ||||
| version 2.1 of the License, or (at your option) any later version. | ||||
|  | ||||
| This library is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
| Lesser General Public License for more details. | ||||
|  | ||||
| You should have received a copy of the GNU Lesser General Public | ||||
| License along with this library; if not, write to the Free Software | ||||
| Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||
| */ | ||||
|  | ||||
| #ifndef ARDUINO_STREAMING | ||||
| #define ARDUINO_STREAMING | ||||
|  | ||||
| //#include <WProgram.h> | ||||
|  | ||||
| #define STREAMING_LIBRARY_VERSION 4 | ||||
|  | ||||
| // Generic template | ||||
| template<class T>  | ||||
| inline Print &operator <<(Print &stream, T arg)  | ||||
| { stream.print(arg); return stream; } | ||||
|  | ||||
| struct _BASED  | ||||
| {  | ||||
|   long val;  | ||||
|   int base; | ||||
|   _BASED(long v, int b): val(v), base(b)  | ||||
|   {} | ||||
| }; | ||||
|  | ||||
| #define _HEX(a)     _BASED(a, HEX) | ||||
| #define _DEC(a)     _BASED(a, DEC) | ||||
| #define _OCT(a)     _BASED(a, OCT) | ||||
| #define _BIN(a)     _BASED(a, BIN) | ||||
| #define _BYTE(a)    _BASED(a, BYTE) | ||||
|  | ||||
| // Specialization for class _BASED | ||||
| // Thanks to Arduino forum user Ben Combee who suggested this  | ||||
| // clever technique to allow for expressions like | ||||
| //   Serial << _HEX(a); | ||||
|  | ||||
| inline Print &operator <<(Print &obj, const _BASED &arg) | ||||
| { obj.print(arg.val, arg.base); return obj; }  | ||||
|  | ||||
| #if ARDUINO >= 18 | ||||
| // Specialization for class _FLOAT | ||||
| // Thanks to Michael Margolis for suggesting a way | ||||
| // to accommodate Arduino 0018's floating point precision | ||||
| // feature like this: | ||||
| //   Serial << _FLOAT(gps_latitude, 6); // 6 digits of precision | ||||
|  | ||||
| struct _FLOAT | ||||
| { | ||||
|   float val; | ||||
|   int digits; | ||||
|   _FLOAT(double v, int d): val(v), digits(d) | ||||
|   {} | ||||
| }; | ||||
|  | ||||
| inline Print &operator <<(Print &obj, const _FLOAT &arg) | ||||
| { obj.print(arg.val, arg.digits); return obj; } | ||||
| #endif | ||||
|  | ||||
| // Specialization for enum _EndLineCode | ||||
| // Thanks to Arduino forum user Paul V. who suggested this | ||||
| // clever technique to allow for expressions like | ||||
| //   Serial << "Hello!" << endl; | ||||
|  | ||||
| enum _EndLineCode { endl }; | ||||
|  | ||||
| inline Print &operator <<(Print &obj, _EndLineCode arg)  | ||||
| { obj.println(); return obj; } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -97,14 +97,15 @@ void manage_heater() | ||||
|    | ||||
|   float pid_input; | ||||
|   float pid_output; | ||||
|   if(temp_meas_ready == true) { | ||||
|   if(temp_meas_ready != true)   //better readability | ||||
|     return;  | ||||
|  | ||||
| CRITICAL_SECTION_START; | ||||
|     temp_meas_ready = false; | ||||
| CRITICAL_SECTION_END; | ||||
|  | ||||
| #ifdef PIDTEMP | ||||
|     pid_input = analog2temp(current_raw[0]); | ||||
|     pid_input = analog2temp(current_raw[TEMPSENSOR_HOTEND]); | ||||
|  | ||||
| #ifndef PID_OPENLOOP | ||||
|     pid_error = pid_setpoint - pid_input; | ||||
| @@ -125,10 +126,13 @@ CRITICAL_SECTION_END; | ||||
|       temp_iState += pid_error; | ||||
|       temp_iState = constrain(temp_iState, temp_iState_min, temp_iState_max); | ||||
|       iTerm = Ki * temp_iState; | ||||
|       #define K1 0.95 | ||||
|       //K1 defined in Configuration.h in the PID settings | ||||
|       #define K2 (1.0-K1) | ||||
|       dTerm = (Kd * (pid_input - temp_dState))*K2 + (K1 * dTerm); | ||||
|       temp_dState = pid_input; | ||||
|       #ifdef PID_ADD_EXTRUSION_RATE | ||||
|         pTerm+=Kc*current_block->speed_e; //additional heating if extrusion speed is high | ||||
|       #endif | ||||
|       pid_output = constrain(pTerm + iTerm - dTerm, 0, PID_MAX); | ||||
|     } | ||||
| #endif //PID_OPENLOOP | ||||
| @@ -164,7 +168,7 @@ CRITICAL_SECTION_END; | ||||
|   previous_millis_bed_heater = millis(); | ||||
|    | ||||
|   #if TEMP_1_PIN > -1 | ||||
|     if(current_raw[1] >= target_raw[1]) | ||||
|     if(current_raw[TEMPSENSOR_BED] >= target_raw[TEMPSENSOR_BED]) | ||||
|     { | ||||
|       WRITE(HEATER_1_PIN,LOW); | ||||
|     } | ||||
| @@ -174,7 +178,6 @@ CRITICAL_SECTION_END; | ||||
|     } | ||||
|   #endif | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Takes hot end temperature value as input and returns corresponding raw value.  | ||||
| // For a thermistor, it uses the RepRap thermistor temp table. | ||||
| @@ -325,15 +328,18 @@ void tp_init() | ||||
|   TIMSK0 |= (1<<OCIE0B);   | ||||
| } | ||||
|  | ||||
| static unsigned char temp_count = 0; | ||||
| static unsigned long raw_temp_0_value = 0; | ||||
| static unsigned long raw_temp_1_value = 0; | ||||
| static unsigned long raw_temp_2_value = 0; | ||||
| static unsigned char temp_state = 0; | ||||
|  | ||||
|  | ||||
| // Timer 0 is shared with millies | ||||
| ISR(TIMER0_COMPB_vect) | ||||
| { | ||||
|   //these variables are only accesible from the ISR, but static, so they don't loose their value | ||||
|   static unsigned char temp_count = 0; | ||||
|   static unsigned long raw_temp_0_value = 0; | ||||
|   static unsigned long raw_temp_1_value = 0; | ||||
|   static unsigned long raw_temp_2_value = 0; | ||||
|   static unsigned char temp_state = 0; | ||||
|    | ||||
|   switch(temp_state) { | ||||
|     case 0: // Prepare TEMP_0 | ||||
|             #if (TEMP_0_PIN > -1) | ||||
| @@ -434,18 +440,17 @@ ISR(TIMER0_COMPB_vect) | ||||
|     raw_temp_2_value = 0; | ||||
| #ifdef HEATER_0_MAXTEMP | ||||
|   #if (HEATER_0_PIN > -1) | ||||
|     if(current_raw[0] >= maxttemp_0) { | ||||
|       target_raw[0] = 0; | ||||
|     if(current_raw[TEMPSENSOR_HOTEND] >= maxttemp) { | ||||
|       target_raw[TEMPSENSOR_HOTEND] = 0; | ||||
|       analogWrite(HEATER_0_PIN, 0); | ||||
|       Serial.println("!! Temperature extruder 0 switched off. MAXTEMP triggered !!"); | ||||
|       kill(); | ||||
|     } | ||||
|   #endif | ||||
| #endif | ||||
| #ifdef HEATER_1_MAXTEMP | ||||
|   #if (HEATER_1_PIN > -1) | ||||
|     if(current_raw[TEMPSENSOR_AUX] >= maxttemp) { | ||||
|       target_raw[TEMPSENSOR_AUX] = 0; | ||||
|     if(current_raw[2] >= maxttemp_1) { | ||||
|       target_raw[2] = 0; | ||||
|       analogWrite(HEATER_2_PIN, 0); | ||||
|       Serial.println("!! Temperature extruder 1 switched off. MAXTEMP triggered !!"); | ||||
|       kill() | ||||
| @@ -454,8 +459,8 @@ ISR(TIMER0_COMPB_vect) | ||||
| #endif //MAXTEMP | ||||
| #ifdef HEATER_0_MINTEMP | ||||
|   #if (HEATER_0_PIN > -1) | ||||
|     if(current_raw[0] <= minttemp_0) { | ||||
|       target_raw[0] = 0; | ||||
|     if(current_raw[TEMPSENSOR_HOTEND] <= minttemp) { | ||||
|       target_raw[TEMPSENSOR_HOTEND] = 0; | ||||
|       analogWrite(HEATER_0_PIN, 0); | ||||
|       Serial.println("!! Temperature extruder 0 switched off. MINTEMP triggered !!"); | ||||
|       kill(); | ||||
| @@ -464,8 +469,8 @@ ISR(TIMER0_COMPB_vect) | ||||
| #endif | ||||
| #ifdef HEATER_1_MINTEMP | ||||
|   #if (HEATER_2_PIN > -1) | ||||
|     if(current_raw[2] <= minttemp_1) { | ||||
|       target_raw[2] = 0; | ||||
|     if(current_raw[TEMPSENSOR_AUX] <= minttemp) { | ||||
|       target_raw[TEMPSENSOR_AUX] = 0; | ||||
|       analogWrite(HEATER_2_PIN, 0); | ||||
|       Serial.println("!! Temperature extruder 1 switched off. MINTEMP triggered !!"); | ||||
|       kill(); | ||||
|   | ||||
| @@ -21,8 +21,10 @@ | ||||
| #ifndef temperature_h | ||||
| #define temperature_h  | ||||
|  | ||||
| void manage_inactivity(byte debug); | ||||
|  | ||||
| #include "Marlin.h" | ||||
| #ifdef PID_ADD_EXTRUSION_RATE | ||||
|   #include "stepper.h" | ||||
| #endif | ||||
| void tp_init(); | ||||
| void manage_heater(); | ||||
| //int temp2analogu(int celsius, const short table[][2], int numtemps); | ||||
| @@ -48,6 +50,7 @@ extern float Ki; | ||||
| extern float Kd; | ||||
| extern float Kc; | ||||
|  | ||||
| enum {TEMPSENSOR_HOTEND=0,TEMPSENSOR_BED=1, TEMPSENSOR_AUX=2}; | ||||
| extern int target_raw[3]; | ||||
| extern int current_raw[3]; | ||||
| extern double pid_setpoint; | ||||
|   | ||||
| @@ -7,67 +7,67 @@ | ||||
|  | ||||
| #define NUMTEMPS_1 61 | ||||
| const short temptable_1[NUMTEMPS_1][2] = { | ||||
| {	23*OVERSAMPLENR	,	300	}, | ||||
| {	25*OVERSAMPLENR	,	295	}, | ||||
| {	27*OVERSAMPLENR	,	290	}, | ||||
| {	28*OVERSAMPLENR	,	285	}, | ||||
| {	31*OVERSAMPLENR	,	280	}, | ||||
| {	33*OVERSAMPLENR	,	275	}, | ||||
| {	35*OVERSAMPLENR	,	270	}, | ||||
| {	38*OVERSAMPLENR	,	265	}, | ||||
| {	41*OVERSAMPLENR	,	260	}, | ||||
| {	44*OVERSAMPLENR	,	255	}, | ||||
| {	48*OVERSAMPLENR	,	250	}, | ||||
| {	52*OVERSAMPLENR	,	245	}, | ||||
| {	56*OVERSAMPLENR	,	240	}, | ||||
| {	61*OVERSAMPLENR	,	235	}, | ||||
| {	66*OVERSAMPLENR	,	230	}, | ||||
| {	71*OVERSAMPLENR	,	225	}, | ||||
| {	78*OVERSAMPLENR	,	220	}, | ||||
| {	84*OVERSAMPLENR	,	215	}, | ||||
| {	92*OVERSAMPLENR	,	210	}, | ||||
| {	100*OVERSAMPLENR	,	205	}, | ||||
| {	109*OVERSAMPLENR	,	200	}, | ||||
| {	120*OVERSAMPLENR	,	195	}, | ||||
| {	131*OVERSAMPLENR	,	190	}, | ||||
| {	143*OVERSAMPLENR	,	185	}, | ||||
| {	156*OVERSAMPLENR	,	180	}, | ||||
| {	171*OVERSAMPLENR	,	175	}, | ||||
| {	187*OVERSAMPLENR	,	170	}, | ||||
| {	205*OVERSAMPLENR	,	165	}, | ||||
| {	224*OVERSAMPLENR	,	160	}, | ||||
| {	245*OVERSAMPLENR	,	155	}, | ||||
| {	268*OVERSAMPLENR	,	150	}, | ||||
| {	293*OVERSAMPLENR	,	145	}, | ||||
| {	320*OVERSAMPLENR	,	140	}, | ||||
| {	348*OVERSAMPLENR	,	135	}, | ||||
| {	379*OVERSAMPLENR	,	130	}, | ||||
| {	411*OVERSAMPLENR	,	125	}, | ||||
| {	445*OVERSAMPLENR	,	120	}, | ||||
| {	480*OVERSAMPLENR	,	115	}, | ||||
| {	516*OVERSAMPLENR	,	110	}, | ||||
| {	553*OVERSAMPLENR	,	105	}, | ||||
| {	591*OVERSAMPLENR	,	100	}, | ||||
| {	628*OVERSAMPLENR	,	95	}, | ||||
| {	665*OVERSAMPLENR	,	90	}, | ||||
| {	702*OVERSAMPLENR	,	85	}, | ||||
| {	737*OVERSAMPLENR	,	80	}, | ||||
| {	770*OVERSAMPLENR	,	75	}, | ||||
| {	801*OVERSAMPLENR	,	70	}, | ||||
| {	830*OVERSAMPLENR	,	65	}, | ||||
| {	857*OVERSAMPLENR	,	60	}, | ||||
| {	881*OVERSAMPLENR	,	55	}, | ||||
| {	903*OVERSAMPLENR	,	50	}, | ||||
| {	922*OVERSAMPLENR	,	45	}, | ||||
| {	939*OVERSAMPLENR	,	40	}, | ||||
| {	954*OVERSAMPLENR	,	35	}, | ||||
| {	966*OVERSAMPLENR	,	30	}, | ||||
| {	977*OVERSAMPLENR	,	25	}, | ||||
| {	985*OVERSAMPLENR	,	20	}, | ||||
| {	993*OVERSAMPLENR	,	15	}, | ||||
| {	999*OVERSAMPLENR	,	10	}, | ||||
| {	1004*OVERSAMPLENR	,	5	}, | ||||
| {	1008*OVERSAMPLENR	,	0	} //safety | ||||
| {       23*OVERSAMPLENR ,       300     }, | ||||
| {       25*OVERSAMPLENR ,       295     }, | ||||
| {       27*OVERSAMPLENR ,       290     }, | ||||
| {       28*OVERSAMPLENR ,       285     }, | ||||
| {       31*OVERSAMPLENR ,       280     }, | ||||
| {       33*OVERSAMPLENR ,       275     }, | ||||
| {       35*OVERSAMPLENR ,       270     }, | ||||
| {       38*OVERSAMPLENR ,       265     }, | ||||
| {       41*OVERSAMPLENR ,       260     }, | ||||
| {       44*OVERSAMPLENR ,       255     }, | ||||
| {       48*OVERSAMPLENR ,       250     }, | ||||
| {       52*OVERSAMPLENR ,       245     }, | ||||
| {       56*OVERSAMPLENR ,       240     }, | ||||
| {       61*OVERSAMPLENR ,       235     }, | ||||
| {       66*OVERSAMPLENR ,       230     }, | ||||
| {       71*OVERSAMPLENR ,       225     }, | ||||
| {       78*OVERSAMPLENR ,       220     }, | ||||
| {       84*OVERSAMPLENR ,       215     }, | ||||
| {       92*OVERSAMPLENR ,       210     }, | ||||
| {       100*OVERSAMPLENR        ,       205     }, | ||||
| {       109*OVERSAMPLENR        ,       200     }, | ||||
| {       120*OVERSAMPLENR        ,       195     }, | ||||
| {       131*OVERSAMPLENR        ,       190     }, | ||||
| {       143*OVERSAMPLENR        ,       185     }, | ||||
| {       156*OVERSAMPLENR        ,       180     }, | ||||
| {       171*OVERSAMPLENR        ,       175     }, | ||||
| {       187*OVERSAMPLENR        ,       170     }, | ||||
| {       205*OVERSAMPLENR        ,       165     }, | ||||
| {       224*OVERSAMPLENR        ,       160     }, | ||||
| {       245*OVERSAMPLENR        ,       155     }, | ||||
| {       268*OVERSAMPLENR        ,       150     }, | ||||
| {       293*OVERSAMPLENR        ,       145     }, | ||||
| {       320*OVERSAMPLENR        ,       140     }, | ||||
| {       348*OVERSAMPLENR        ,       135     }, | ||||
| {       379*OVERSAMPLENR        ,       130     }, | ||||
| {       411*OVERSAMPLENR        ,       125     }, | ||||
| {       445*OVERSAMPLENR        ,       120     }, | ||||
| {       480*OVERSAMPLENR        ,       115     }, | ||||
| {       516*OVERSAMPLENR        ,       110     }, | ||||
| {       553*OVERSAMPLENR        ,       105     }, | ||||
| {       591*OVERSAMPLENR        ,       100     }, | ||||
| {       628*OVERSAMPLENR        ,       95      }, | ||||
| {       665*OVERSAMPLENR        ,       90      }, | ||||
| {       702*OVERSAMPLENR        ,       85      }, | ||||
| {       737*OVERSAMPLENR        ,       80      }, | ||||
| {       770*OVERSAMPLENR        ,       75      }, | ||||
| {       801*OVERSAMPLENR        ,       70      }, | ||||
| {       830*OVERSAMPLENR        ,       65      }, | ||||
| {       857*OVERSAMPLENR        ,       60      }, | ||||
| {       881*OVERSAMPLENR        ,       55      }, | ||||
| {       903*OVERSAMPLENR        ,       50      }, | ||||
| {       922*OVERSAMPLENR        ,       45      }, | ||||
| {       939*OVERSAMPLENR        ,       40      }, | ||||
| {       954*OVERSAMPLENR        ,       35      }, | ||||
| {       966*OVERSAMPLENR        ,       30      }, | ||||
| {       977*OVERSAMPLENR        ,       25      }, | ||||
| {       985*OVERSAMPLENR        ,       20      }, | ||||
| {       993*OVERSAMPLENR        ,       15      }, | ||||
| {       999*OVERSAMPLENR        ,       10      }, | ||||
| {       1004*OVERSAMPLENR       ,       5       }, | ||||
| {       1008*OVERSAMPLENR       ,       0       } //safety | ||||
| }; | ||||
| #endif | ||||
| #if (THERMISTORHEATER_0 == 2) || (THERMISTORHEATER_1 == 2) || (THERMISTORBED == 2) //200k bed thermistor | ||||
| @@ -100,35 +100,35 @@ const short temptable_2[NUMTEMPS_2][2] = { | ||||
| #if (THERMISTORHEATER_0 == 3) || (THERMISTORHEATER_1 == 3) || (THERMISTORBED == 3) //mendel-parts | ||||
| #define NUMTEMPS_3 28 | ||||
| const short temptable_3[NUMTEMPS_3][2] = { | ||||
| 		{1*OVERSAMPLENR,864}, | ||||
| 		{21*OVERSAMPLENR,300}, | ||||
| 		{25*OVERSAMPLENR,290}, | ||||
| 		{29*OVERSAMPLENR,280}, | ||||
| 		{33*OVERSAMPLENR,270}, | ||||
| 		{39*OVERSAMPLENR,260}, | ||||
| 		{46*OVERSAMPLENR,250}, | ||||
| 		{54*OVERSAMPLENR,240}, | ||||
| 		{64*OVERSAMPLENR,230}, | ||||
| 		{75*OVERSAMPLENR,220}, | ||||
| 		{90*OVERSAMPLENR,210}, | ||||
| 		{107*OVERSAMPLENR,200}, | ||||
| 		{128*OVERSAMPLENR,190}, | ||||
| 		{154*OVERSAMPLENR,180}, | ||||
| 		{184*OVERSAMPLENR,170}, | ||||
| 		{221*OVERSAMPLENR,160}, | ||||
| 		{265*OVERSAMPLENR,150}, | ||||
| 		{316*OVERSAMPLENR,140}, | ||||
| 		{375*OVERSAMPLENR,130}, | ||||
| 		{441*OVERSAMPLENR,120}, | ||||
| 		{513*OVERSAMPLENR,110}, | ||||
| 		{588*OVERSAMPLENR,100}, | ||||
| 		{734*OVERSAMPLENR,80}, | ||||
| 		{856*OVERSAMPLENR,60}, | ||||
| 		{938*OVERSAMPLENR,40}, | ||||
| 		{986*OVERSAMPLENR,20}, | ||||
| 		{1008*OVERSAMPLENR,0}, | ||||
| 		{1018*OVERSAMPLENR,-20} | ||||
| 	}; | ||||
|                 {1*OVERSAMPLENR,864}, | ||||
|                 {21*OVERSAMPLENR,300}, | ||||
|                 {25*OVERSAMPLENR,290}, | ||||
|                 {29*OVERSAMPLENR,280}, | ||||
|                 {33*OVERSAMPLENR,270}, | ||||
|                 {39*OVERSAMPLENR,260}, | ||||
|                 {46*OVERSAMPLENR,250}, | ||||
|                 {54*OVERSAMPLENR,240}, | ||||
|                 {64*OVERSAMPLENR,230}, | ||||
|                 {75*OVERSAMPLENR,220}, | ||||
|                 {90*OVERSAMPLENR,210}, | ||||
|                 {107*OVERSAMPLENR,200}, | ||||
|                 {128*OVERSAMPLENR,190}, | ||||
|                 {154*OVERSAMPLENR,180}, | ||||
|                 {184*OVERSAMPLENR,170}, | ||||
|                 {221*OVERSAMPLENR,160}, | ||||
|                 {265*OVERSAMPLENR,150}, | ||||
|                 {316*OVERSAMPLENR,140}, | ||||
|                 {375*OVERSAMPLENR,130}, | ||||
|                 {441*OVERSAMPLENR,120}, | ||||
|                 {513*OVERSAMPLENR,110}, | ||||
|                 {588*OVERSAMPLENR,100}, | ||||
|                 {734*OVERSAMPLENR,80}, | ||||
|                 {856*OVERSAMPLENR,60}, | ||||
|                 {938*OVERSAMPLENR,40}, | ||||
|                 {986*OVERSAMPLENR,20}, | ||||
|                 {1008*OVERSAMPLENR,0}, | ||||
|                 {1018*OVERSAMPLENR,-20} | ||||
|         }; | ||||
|  | ||||
| #endif | ||||
| #if (THERMISTORHEATER_0 == 4) || (THERMISTORHEATER_1 == 4) || (THERMISTORBED == 4) //10k thermistor | ||||
|   | ||||
| @@ -1,156 +1,156 @@ | ||||
| #ifndef __ULTRALCDH | ||||
| #define __ULTRALCDH | ||||
| #include "Configuration.h" | ||||
|  | ||||
| #ifdef ULTRA_LCD | ||||
|  | ||||
|   void lcd_status(); | ||||
|   void lcd_init(); | ||||
|   void lcd_status(const char* message); | ||||
|   void beep(); | ||||
|   void buttons_check(); | ||||
|   #define LCDSTATUSRIGHT | ||||
|  | ||||
|   #define LCD_UPDATE_INTERVAL 100 | ||||
|   #define STATUSTIMEOUT 15000 | ||||
|  | ||||
|   #include "Configuration.h" | ||||
|  | ||||
|   #include <LiquidCrystal.h> | ||||
|   extern LiquidCrystal lcd; | ||||
|  | ||||
|   //lcd display size | ||||
|  | ||||
| #ifdef NEWPANEL | ||||
|  //arduino pin witch triggers an piezzo beeper | ||||
|   #define BEEPER 18 | ||||
|  | ||||
|   #define LCD_PINS_RS 20  | ||||
|   #define LCD_PINS_ENABLE 17 | ||||
|   #define LCD_PINS_D4 16 | ||||
|   #define LCD_PINS_D5 21  | ||||
|   #define LCD_PINS_D6 5 | ||||
|   #define LCD_PINS_D7 6 | ||||
|    | ||||
|   //buttons are directly attached | ||||
|   #define BTN_EN1 40 | ||||
|   #define BTN_EN2 42 | ||||
|   #define BTN_ENC 19  //the click | ||||
|    | ||||
|   #define BLEN_C 2 | ||||
|   #define BLEN_B 1 | ||||
|   #define BLEN_A 0 | ||||
|    | ||||
|   #define SDCARDDETECT 38 | ||||
|    | ||||
|   #define EN_C (1<<BLEN_C) | ||||
|   #define EN_B (1<<BLEN_B) | ||||
|   #define EN_A (1<<BLEN_A) | ||||
|    | ||||
|    //encoder rotation values | ||||
|   #define encrot0 0 | ||||
|   #define encrot1 2 | ||||
|   #define encrot2 3 | ||||
|   #define encrot3 1 | ||||
|  | ||||
|    | ||||
|   #define CLICKED (buttons&EN_C) | ||||
|   #define BLOCK {blocking=millis()+blocktime;} | ||||
|   #define CARDINSERTED (READ(SDCARDDETECT)==0) | ||||
|    | ||||
| #else | ||||
|   //arduino pin witch triggers an piezzo beeper | ||||
|   #define BEEPER 18 | ||||
|  | ||||
|   //buttons are attached to a shift register | ||||
|   #define SHIFT_CLK 38 | ||||
|   #define SHIFT_LD 42 | ||||
|   #define SHIFT_OUT 40 | ||||
|   #define SHIFT_EN 17 | ||||
|    | ||||
|   #define LCD_PINS_RS 16  | ||||
|   #define LCD_PINS_ENABLE 5 | ||||
|   #define LCD_PINS_D4 6 | ||||
|   #define LCD_PINS_D5 21  | ||||
|   #define LCD_PINS_D6 20 | ||||
|   #define LCD_PINS_D7 19 | ||||
|    | ||||
|    //bits in the shift register that carry the buttons for: | ||||
|   // left up center down right red | ||||
|   #define BL_LE 7 | ||||
|   #define BL_UP 6 | ||||
|   #define BL_MI 5 | ||||
|   #define BL_DW 4 | ||||
|   #define BL_RI 3 | ||||
|   #define BL_ST 2 | ||||
|  | ||||
|   #define BLEN_B 1 | ||||
|   #define BLEN_A 0 | ||||
|  | ||||
|   //encoder rotation values | ||||
|   #define encrot0 0 | ||||
|   #define encrot1 2 | ||||
|   #define encrot2 3 | ||||
|   #define encrot3 1 | ||||
|  | ||||
|   //atomatic, do not change | ||||
|   #define B_LE (1<<BL_LE) | ||||
|   #define B_UP (1<<BL_UP) | ||||
|   #define B_MI (1<<BL_MI) | ||||
|   #define B_DW (1<<BL_DW) | ||||
|   #define B_RI (1<<BL_RI) | ||||
|   #define B_ST (1<<BL_ST) | ||||
|   #define EN_B (1<<BLEN_B) | ||||
|   #define EN_A (1<<BLEN_A) | ||||
|    | ||||
|   #define CLICKED ((buttons&B_MI)||(buttons&B_ST)) | ||||
|   #define BLOCK {blocking[BL_MI]=millis()+blocktime;blocking[BL_ST]=millis()+blocktime;} | ||||
|    | ||||
| #endif | ||||
|   // blocking time for recognizing a new keypress of one key, ms | ||||
| #define blocktime 500 | ||||
| #define lcdslow 5 | ||||
|   enum MainStatus{Main_Status, Main_Menu, Main_Prepare, Main_Control, Main_SD}; | ||||
|  | ||||
|   class MainMenu{ | ||||
|   public: | ||||
|     MainMenu(); | ||||
|     void update(); | ||||
|     void getfilename(const uint8_t nr); | ||||
|     uint8_t activeline; | ||||
|     MainStatus status; | ||||
|     uint8_t displayStartingRow; | ||||
|      | ||||
|     void showStatus(); | ||||
|     void showMainMenu(); | ||||
|     void showPrepare(); | ||||
|     void showControl(); | ||||
|     void showSD(); | ||||
|     bool force_lcd_update; | ||||
|     int lastencoderpos; | ||||
|     int8_t lineoffset; | ||||
|     int8_t lastlineoffset; | ||||
|     char filename[11]; | ||||
|     bool linechanging; | ||||
|   }; | ||||
|  | ||||
|   char *fillto(int8_t n,char *c); | ||||
|   char *ftostr51(const float &x); | ||||
|   char *ftostr31(const float &x); | ||||
|   char *ftostr3(const float &x); | ||||
|  | ||||
|  | ||||
|  | ||||
|   #define LCD_MESSAGE(x) lcd_status(x); | ||||
|   #define LCD_STATUS lcd_status() | ||||
| #else //no lcd | ||||
|   #define LCD_STATUS | ||||
|   #define LCD_MESSAGE(x) | ||||
| #endif | ||||
|    | ||||
| #ifndef ULTIPANEL   | ||||
|  #define CLICKED false | ||||
| #define BLOCK ; | ||||
| #endif  | ||||
| #endif //ULTRALCD | ||||
|  | ||||
| #ifndef __ULTRALCDH | ||||
| #define __ULTRALCDH | ||||
| #include "Configuration.h" | ||||
|  | ||||
| #ifdef ULTRA_LCD | ||||
|  | ||||
|   void lcd_status(); | ||||
|   void lcd_init(); | ||||
|   void lcd_status(const char* message); | ||||
|   void beep(); | ||||
|   void buttons_check(); | ||||
|   #define LCDSTATUSRIGHT | ||||
|  | ||||
|   #define LCD_UPDATE_INTERVAL 100 | ||||
|   #define STATUSTIMEOUT 15000 | ||||
|  | ||||
|   #include "Configuration.h" | ||||
|  | ||||
|   #include <LiquidCrystal.h> | ||||
|   extern LiquidCrystal lcd; | ||||
|  | ||||
|   //lcd display size | ||||
|  | ||||
| #ifdef NEWPANEL | ||||
|  //arduino pin witch triggers an piezzo beeper | ||||
|   #define BEEPER 18 | ||||
|  | ||||
|   #define LCD_PINS_RS 20  | ||||
|   #define LCD_PINS_ENABLE 17 | ||||
|   #define LCD_PINS_D4 16 | ||||
|   #define LCD_PINS_D5 21  | ||||
|   #define LCD_PINS_D6 5 | ||||
|   #define LCD_PINS_D7 6 | ||||
|    | ||||
|   //buttons are directly attached | ||||
|   #define BTN_EN1 40 | ||||
|   #define BTN_EN2 42 | ||||
|   #define BTN_ENC 19  //the click | ||||
|    | ||||
|   #define BLEN_C 2 | ||||
|   #define BLEN_B 1 | ||||
|   #define BLEN_A 0 | ||||
|    | ||||
|   #define SDCARDDETECT 38 | ||||
|    | ||||
|   #define EN_C (1<<BLEN_C) | ||||
|   #define EN_B (1<<BLEN_B) | ||||
|   #define EN_A (1<<BLEN_A) | ||||
|    | ||||
|    //encoder rotation values | ||||
|   #define encrot0 0 | ||||
|   #define encrot1 2 | ||||
|   #define encrot2 3 | ||||
|   #define encrot3 1 | ||||
|  | ||||
|    | ||||
|   #define CLICKED (buttons&EN_C) | ||||
|   #define BLOCK {blocking=millis()+blocktime;} | ||||
|   #define CARDINSERTED (READ(SDCARDDETECT)==0) | ||||
|    | ||||
| #else | ||||
|   //arduino pin witch triggers an piezzo beeper | ||||
|   #define BEEPER 18 | ||||
|  | ||||
|   //buttons are attached to a shift register | ||||
|   #define SHIFT_CLK 38 | ||||
|   #define SHIFT_LD 42 | ||||
|   #define SHIFT_OUT 40 | ||||
|   #define SHIFT_EN 17 | ||||
|    | ||||
|   #define LCD_PINS_RS 16  | ||||
|   #define LCD_PINS_ENABLE 5 | ||||
|   #define LCD_PINS_D4 6 | ||||
|   #define LCD_PINS_D5 21  | ||||
|   #define LCD_PINS_D6 20 | ||||
|   #define LCD_PINS_D7 19 | ||||
|    | ||||
|    //bits in the shift register that carry the buttons for: | ||||
|   // left up center down right red | ||||
|   #define BL_LE 7 | ||||
|   #define BL_UP 6 | ||||
|   #define BL_MI 5 | ||||
|   #define BL_DW 4 | ||||
|   #define BL_RI 3 | ||||
|   #define BL_ST 2 | ||||
|  | ||||
|   #define BLEN_B 1 | ||||
|   #define BLEN_A 0 | ||||
|  | ||||
|   //encoder rotation values | ||||
|   #define encrot0 0 | ||||
|   #define encrot1 2 | ||||
|   #define encrot2 3 | ||||
|   #define encrot3 1 | ||||
|  | ||||
|   //atomatic, do not change | ||||
|   #define B_LE (1<<BL_LE) | ||||
|   #define B_UP (1<<BL_UP) | ||||
|   #define B_MI (1<<BL_MI) | ||||
|   #define B_DW (1<<BL_DW) | ||||
|   #define B_RI (1<<BL_RI) | ||||
|   #define B_ST (1<<BL_ST) | ||||
|   #define EN_B (1<<BLEN_B) | ||||
|   #define EN_A (1<<BLEN_A) | ||||
|    | ||||
|   #define CLICKED ((buttons&B_MI)||(buttons&B_ST)) | ||||
|   #define BLOCK {blocking[BL_MI]=millis()+blocktime;blocking[BL_ST]=millis()+blocktime;} | ||||
|    | ||||
| #endif | ||||
|   // blocking time for recognizing a new keypress of one key, ms | ||||
| #define blocktime 500 | ||||
| #define lcdslow 5 | ||||
|   enum MainStatus{Main_Status, Main_Menu, Main_Prepare, Main_Control, Main_SD}; | ||||
|  | ||||
|   class MainMenu{ | ||||
|   public: | ||||
|     MainMenu(); | ||||
|     void update(); | ||||
|     void getfilename(const uint8_t nr); | ||||
|     uint8_t activeline; | ||||
|     MainStatus status; | ||||
|     uint8_t displayStartingRow; | ||||
|      | ||||
|     void showStatus(); | ||||
|     void showMainMenu(); | ||||
|     void showPrepare(); | ||||
|     void showControl(); | ||||
|     void showSD(); | ||||
|     bool force_lcd_update; | ||||
|     int lastencoderpos; | ||||
|     int8_t lineoffset; | ||||
|     int8_t lastlineoffset; | ||||
|     char filename[11]; | ||||
|     bool linechanging; | ||||
|   }; | ||||
|  | ||||
|   char *fillto(int8_t n,char *c); | ||||
|   char *ftostr51(const float &x); | ||||
|   char *ftostr31(const float &x); | ||||
|   char *ftostr3(const float &x); | ||||
|  | ||||
|  | ||||
|  | ||||
|   #define LCD_MESSAGE(x) lcd_status(x); | ||||
|   #define LCD_STATUS lcd_status() | ||||
| #else //no lcd | ||||
|   #define LCD_STATUS | ||||
|   #define LCD_MESSAGE(x) | ||||
| #endif | ||||
|    | ||||
| #ifndef ULTIPANEL   | ||||
|  #define CLICKED false | ||||
| #define BLOCK ; | ||||
| #endif  | ||||
| #endif //ULTRALCD | ||||
|  | ||||
|   | ||||
							
								
								
									
										3186
									
								
								Marlin/ultralcd.pde
									
									
									
									
									
								
							
							
						
						
									
										3186
									
								
								Marlin/ultralcd.pde
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user