changed end of line to windows, which seems to be the majority of developers main platform.
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
							
								
								
									
										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; | ||||
| } | ||||
|   | ||||
							
								
								
									
										5116
									
								
								Marlin/fastio.h
									
									
									
									
									
								
							
							
						
						
									
										5116
									
								
								Marlin/fastio.h
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1140
									
								
								Marlin/pins.h
									
									
									
									
									
								
							
							
						
						
									
										1140
									
								
								Marlin/pins.h
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1154
									
								
								Marlin/planner.cpp
									
									
									
									
									
								
							
							
						
						
									
										1154
									
								
								Marlin/planner.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -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,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 | ||||
|  | ||||
|   | ||||
| @@ -1,483 +1,483 @@ | ||||
| /* | ||||
|   temperature.c - temperature control | ||||
|   Part of Marlin | ||||
|    | ||||
|  Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|   | ||||
|  This program 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 program 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 this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  This firmware is a mashup between Sprinter and grbl. | ||||
|   (https://github.com/kliment/Sprinter) | ||||
|   (https://github.com/simen/grbl/tree) | ||||
|   | ||||
|  It has preliminary support for Matthew Roberts advance algorithm  | ||||
|     http://reprap.org/pipermail/reprap-dev/2011-May/003323.html | ||||
|  | ||||
|  This firmware is optimized for gen6 electronics. | ||||
|  */ | ||||
|  | ||||
| #include "fastio.h" | ||||
| #include "Configuration.h" | ||||
| #include "pins.h" | ||||
| #include "Marlin.h" | ||||
| #include "ultralcd.h" | ||||
| #include "streaming.h" | ||||
| #include "temperature.h" | ||||
|  | ||||
| int target_bed_raw = 0; | ||||
| int current_bed_raw = 0; | ||||
|  | ||||
| int target_raw[3] = {0, 0, 0}; | ||||
| int current_raw[3] = {0, 0, 0}; | ||||
| unsigned char temp_meas_ready = false; | ||||
|  | ||||
| unsigned long previous_millis_heater, previous_millis_bed_heater; | ||||
|  | ||||
| #ifdef PIDTEMP | ||||
|   double temp_iState = 0; | ||||
|   double temp_dState = 0; | ||||
|   double pTerm; | ||||
|   double iTerm; | ||||
|   double dTerm; | ||||
|       //int output; | ||||
|   double pid_error; | ||||
|   double temp_iState_min; | ||||
|   double temp_iState_max; | ||||
|   double pid_setpoint = 0.0; | ||||
|   double pid_input; | ||||
|   double pid_output; | ||||
|   bool pid_reset; | ||||
|   float HeaterPower; | ||||
|    | ||||
|   float Kp=DEFAULT_Kp; | ||||
|   float Ki=DEFAULT_Ki; | ||||
|   float Kd=DEFAULT_Kd; | ||||
|   float Kc=DEFAULT_Kc; | ||||
| #endif //PIDTEMP | ||||
|  | ||||
| #ifdef MINTEMP | ||||
| int minttemp = temp2analog(MINTEMP); | ||||
| #endif //MINTEMP | ||||
| #ifdef MAXTEMP | ||||
| int maxttemp = temp2analog(MAXTEMP); | ||||
| #endif //MAXTEMP | ||||
|  | ||||
| #ifdef BED_MINTEMP | ||||
| int bed_minttemp = temp2analog(BED_MINTEMP); | ||||
| #endif //BED_MINTEMP | ||||
| #ifdef BED_MAXTEMP | ||||
| int bed_maxttemp = temp2analog(BED_MAXTEMP); | ||||
| #endif //BED_MAXTEMP | ||||
|  | ||||
| void manage_heater() | ||||
| { | ||||
| #ifdef USE_WATCHDOG | ||||
|   wd_reset(); | ||||
| #endif | ||||
|    | ||||
|   float pid_input; | ||||
|   float pid_output; | ||||
| /* | ||||
|   temperature.c - temperature control | ||||
|   Part of Marlin | ||||
|    | ||||
|  Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|   | ||||
|  This program 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 program 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 this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  This firmware is a mashup between Sprinter and grbl. | ||||
|   (https://github.com/kliment/Sprinter) | ||||
|   (https://github.com/simen/grbl/tree) | ||||
|   | ||||
|  It has preliminary support for Matthew Roberts advance algorithm  | ||||
|     http://reprap.org/pipermail/reprap-dev/2011-May/003323.html | ||||
|  | ||||
|  This firmware is optimized for gen6 electronics. | ||||
|  */ | ||||
|  | ||||
| #include "fastio.h" | ||||
| #include "Configuration.h" | ||||
| #include "pins.h" | ||||
| #include "Marlin.h" | ||||
| #include "ultralcd.h" | ||||
| #include "streaming.h" | ||||
| #include "temperature.h" | ||||
|  | ||||
| int target_bed_raw = 0; | ||||
| int current_bed_raw = 0; | ||||
|  | ||||
| int target_raw[3] = {0, 0, 0}; | ||||
| int current_raw[3] = {0, 0, 0}; | ||||
| unsigned char temp_meas_ready = false; | ||||
|  | ||||
| unsigned long previous_millis_heater, previous_millis_bed_heater; | ||||
|  | ||||
| #ifdef PIDTEMP | ||||
|   double temp_iState = 0; | ||||
|   double temp_dState = 0; | ||||
|   double pTerm; | ||||
|   double iTerm; | ||||
|   double dTerm; | ||||
|       //int output; | ||||
|   double pid_error; | ||||
|   double temp_iState_min; | ||||
|   double temp_iState_max; | ||||
|   double pid_setpoint = 0.0; | ||||
|   double pid_input; | ||||
|   double pid_output; | ||||
|   bool pid_reset; | ||||
|   float HeaterPower; | ||||
|    | ||||
|   float Kp=DEFAULT_Kp; | ||||
|   float Ki=DEFAULT_Ki; | ||||
|   float Kd=DEFAULT_Kd; | ||||
|   float Kc=DEFAULT_Kc; | ||||
| #endif //PIDTEMP | ||||
|  | ||||
| #ifdef MINTEMP | ||||
| int minttemp = temp2analog(MINTEMP); | ||||
| #endif //MINTEMP | ||||
| #ifdef MAXTEMP | ||||
| int maxttemp = temp2analog(MAXTEMP); | ||||
| #endif //MAXTEMP | ||||
|  | ||||
| #ifdef BED_MINTEMP | ||||
| int bed_minttemp = temp2analog(BED_MINTEMP); | ||||
| #endif //BED_MINTEMP | ||||
| #ifdef BED_MAXTEMP | ||||
| int bed_maxttemp = temp2analog(BED_MAXTEMP); | ||||
| #endif //BED_MAXTEMP | ||||
|  | ||||
| void manage_heater() | ||||
| { | ||||
| #ifdef USE_WATCHDOG | ||||
|   wd_reset(); | ||||
| #endif | ||||
|    | ||||
|   float pid_input; | ||||
|   float pid_output; | ||||
|   if(temp_meas_ready != true)   //better readability | ||||
|     return;  | ||||
|  | ||||
| CRITICAL_SECTION_START; | ||||
|     temp_meas_ready = false; | ||||
| CRITICAL_SECTION_END; | ||||
|  | ||||
| #ifdef PIDTEMP | ||||
|  | ||||
| CRITICAL_SECTION_START; | ||||
|     temp_meas_ready = false; | ||||
| CRITICAL_SECTION_END; | ||||
|  | ||||
| #ifdef PIDTEMP | ||||
|     pid_input = analog2temp(current_raw[TEMPSENSOR_HOTEND]); | ||||
|  | ||||
| #ifndef PID_OPENLOOP | ||||
|     pid_error = pid_setpoint - pid_input; | ||||
|     if(pid_error > 10){ | ||||
|       pid_output = PID_MAX; | ||||
|       pid_reset = true; | ||||
|     } | ||||
|     else if(pid_error < -10) { | ||||
|       pid_output = 0; | ||||
|       pid_reset = true; | ||||
|     } | ||||
|     else { | ||||
|       if(pid_reset == true) { | ||||
|         temp_iState = 0.0; | ||||
|         pid_reset = false; | ||||
|       } | ||||
|       pTerm = Kp * pid_error; | ||||
|       temp_iState += pid_error; | ||||
|       temp_iState = constrain(temp_iState, temp_iState_min, temp_iState_max); | ||||
|       iTerm = Ki * temp_iState; | ||||
|  | ||||
| #ifndef PID_OPENLOOP | ||||
|     pid_error = pid_setpoint - pid_input; | ||||
|     if(pid_error > 10){ | ||||
|       pid_output = PID_MAX; | ||||
|       pid_reset = true; | ||||
|     } | ||||
|     else if(pid_error < -10) { | ||||
|       pid_output = 0; | ||||
|       pid_reset = true; | ||||
|     } | ||||
|     else { | ||||
|       if(pid_reset == true) { | ||||
|         temp_iState = 0.0; | ||||
|         pid_reset = false; | ||||
|       } | ||||
|       pTerm = Kp * pid_error; | ||||
|       temp_iState += pid_error; | ||||
|       temp_iState = constrain(temp_iState, temp_iState_min, temp_iState_max); | ||||
|       iTerm = Ki * temp_iState; | ||||
|       //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; | ||||
|       #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 | ||||
| #ifdef PID_DEBUG | ||||
|      Serial.print(" Input "); | ||||
|      Serial.print(pid_input); | ||||
|      Serial.print(" Output "); | ||||
|      Serial.print(pid_output);     | ||||
|      Serial.print(" pTerm "); | ||||
|      Serial.print(pTerm);  | ||||
|      Serial.print(" iTerm "); | ||||
|      Serial.print(iTerm);  | ||||
|      Serial.print(" dTerm "); | ||||
|      Serial.print(dTerm);  | ||||
|      Serial.println(); | ||||
| #endif //PID_DEBUG | ||||
|     analogWrite(HEATER_0_PIN, pid_output); | ||||
| #endif //PIDTEMP | ||||
|  | ||||
| #ifndef PIDTEMP | ||||
|     if(current_raw[0] >= target_raw[0]) | ||||
|     { | ||||
|       WRITE(HEATER_0_PIN,LOW); | ||||
|     } | ||||
|     else  | ||||
|     { | ||||
|       WRITE(HEATER_0_PIN,HIGH); | ||||
|     } | ||||
| #endif | ||||
|      | ||||
|   if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL) | ||||
|     return; | ||||
|   previous_millis_bed_heater = millis(); | ||||
|    | ||||
|   #if TEMP_1_PIN > -1 | ||||
|       pid_output = constrain(pTerm + iTerm - dTerm, 0, PID_MAX); | ||||
|     } | ||||
| #endif //PID_OPENLOOP | ||||
| #ifdef PID_DEBUG | ||||
|      Serial.print(" Input "); | ||||
|      Serial.print(pid_input); | ||||
|      Serial.print(" Output "); | ||||
|      Serial.print(pid_output);     | ||||
|      Serial.print(" pTerm "); | ||||
|      Serial.print(pTerm);  | ||||
|      Serial.print(" iTerm "); | ||||
|      Serial.print(iTerm);  | ||||
|      Serial.print(" dTerm "); | ||||
|      Serial.print(dTerm);  | ||||
|      Serial.println(); | ||||
| #endif //PID_DEBUG | ||||
|     analogWrite(HEATER_0_PIN, pid_output); | ||||
| #endif //PIDTEMP | ||||
|  | ||||
| #ifndef PIDTEMP | ||||
|     if(current_raw[0] >= target_raw[0]) | ||||
|     { | ||||
|       WRITE(HEATER_0_PIN,LOW); | ||||
|     } | ||||
|     else  | ||||
|     { | ||||
|       WRITE(HEATER_0_PIN,HIGH); | ||||
|     } | ||||
| #endif | ||||
|      | ||||
|   if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL) | ||||
|     return; | ||||
|   previous_millis_bed_heater = millis(); | ||||
|    | ||||
|   #if TEMP_1_PIN > -1 | ||||
|     if(current_raw[TEMPSENSOR_BED] >= target_raw[TEMPSENSOR_BED]) | ||||
|     { | ||||
|       WRITE(HEATER_1_PIN,LOW); | ||||
|     } | ||||
|     else  | ||||
|     { | ||||
|       WRITE(HEATER_1_PIN,HIGH); | ||||
|     } | ||||
|   #endif | ||||
|   } | ||||
|  | ||||
| // Takes hot end temperature value as input and returns corresponding raw value.  | ||||
| // For a thermistor, it uses the RepRap thermistor temp table. | ||||
| // This is needed because PID in hydra firmware hovers around a given analog value, not a temp value. | ||||
| // This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware. | ||||
| float temp2analog(int celsius) { | ||||
|   #ifdef HEATER_USES_THERMISTOR_1 | ||||
|     int raw = 0; | ||||
|     byte i; | ||||
|      | ||||
|     for (i=1; i<NUMTEMPS_HEATER_1; i++) | ||||
|     { | ||||
|       if (temptable_1[i][1] < celsius) | ||||
|       { | ||||
|         raw = temptable_1[i-1][0] +  | ||||
|           (celsius - temptable_1[i-1][1]) *  | ||||
|           (temptable_1[i][0] - temptable_1[i-1][0]) / | ||||
|           (temptable_1[i][1] - temptable_1[i-1][1]); | ||||
|        | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Overflow: Set to last value in the table | ||||
|     if (i == NUMTEMPS_1) raw = temptable_1[i-1][0]; | ||||
|  | ||||
|     return (1023 * OVERSAMPLENR) - raw; | ||||
|   #elif defined HEATER_1_USES_AD595 | ||||
|     return celsius * (1024.0 / (5.0 * 100.0) ) * OVERSAMPLENR; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| // Takes bed temperature value as input and returns corresponding raw value.  | ||||
| // For a thermistor, it uses the RepRap thermistor temp table. | ||||
| // This is needed because PID in hydra firmware hovers around a given analog value, not a temp value. | ||||
| // This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware. | ||||
| float temp2analogBed(int celsius) { | ||||
|   #ifdef BED_USES_THERMISTOR | ||||
|  | ||||
|     int raw = 0; | ||||
|     byte i; | ||||
|      | ||||
|     for (i=1; i<BNUMTEMPS; i++) | ||||
|     { | ||||
|       if (bedtemptable[i][1] < celsius) | ||||
|       { | ||||
|         raw = bedtemptable[i-1][0] +  | ||||
|           (celsius - bedtemptable[i-1][1]) *  | ||||
|           (bedtemptable[i][0] - bedtemptable[i-1][0]) / | ||||
|           (bedtemptable[i][1] - bedtemptable[i-1][1]); | ||||
|        | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Overflow: Set to last value in the table | ||||
|     if (i == BNUMTEMPS) raw = bedtemptable[i-1][0]; | ||||
|  | ||||
|     return (1023 * OVERSAMPLENR) - raw; | ||||
|   #elif defined BED_USES_AD595 | ||||
|     return celsius * (1024.0 / (5.0 * 100.0) ) * OVERSAMPLENR; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| // Derived from RepRap FiveD extruder::getTemperature() | ||||
| // For hot end temperature measurement. | ||||
| float analog2temp(int raw) { | ||||
|   #ifdef HEATER_1_USES_THERMISTOR | ||||
|     int celsius = 0; | ||||
|     byte i;   | ||||
|     raw = (1023 * OVERSAMPLENR) - raw; | ||||
|     for (i=1; i<NUMTEMPS_HEATER_1; i++) | ||||
|     { | ||||
|       if (temptable_1[i][0] > raw) | ||||
|       { | ||||
|         celsius  = temptable_1[i-1][1] +  | ||||
|           (raw - temptable_1[i-1][0]) *  | ||||
|           (temptable_1[i][1] - temptable_1[i-1][1]) / | ||||
|           (temptable_1[i][0] - temptable_1[i-1][0]); | ||||
|  | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Overflow: Set to last value in the table | ||||
|     if (i == NUMTEMPS_HEATER_1) celsius = temptable_1[i-1][1]; | ||||
|  | ||||
|     return celsius; | ||||
|   #elif defined HEATER_1_USES_AD595 | ||||
|     return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| // Derived from RepRap FiveD extruder::getTemperature() | ||||
| // For bed temperature measurement. | ||||
| float analog2tempBed(int raw) { | ||||
|   #ifdef BED_USES_THERMISTOR | ||||
|     int celsius = 0; | ||||
|     byte i; | ||||
|  | ||||
|     raw = (1023 * OVERSAMPLENR) - raw; | ||||
|  | ||||
|     for (i=1; i<BNUMTEMPS; i++) | ||||
|     { | ||||
|       if (bedtemptable[i][0] > raw) | ||||
|       { | ||||
|         celsius  = bedtemptable[i-1][1] +  | ||||
|           (raw - bedtemptable[i-1][0]) *  | ||||
|           (bedtemptable[i][1] - bedtemptable[i-1][1]) / | ||||
|           (bedtemptable[i][0] - bedtemptable[i-1][0]); | ||||
|  | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Overflow: Set to last value in the table | ||||
|     if (i == BNUMTEMPS) celsius = bedtemptable[i-1][1]; | ||||
|  | ||||
|     return celsius; | ||||
|      | ||||
|   #elif defined BED_USES_AD595 | ||||
|     return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| void tp_init() | ||||
| { | ||||
| #if (HEATER_0_PIN > -1)  | ||||
|   SET_OUTPUT(HEATER_0_PIN); | ||||
| #endif   | ||||
| #if (HEATER_1_PIN > -1)  | ||||
|   SET_OUTPUT(HEATER_1_PIN); | ||||
| #endif   | ||||
| #if (HEATER_2_PIN > -1)  | ||||
|   SET_OUTPUT(HEATER_2_PIN); | ||||
| #endif   | ||||
|  | ||||
| #ifdef PIDTEMP | ||||
|   temp_iState_min = 0.0; | ||||
|   temp_iState_max = PID_INTEGRAL_DRIVE_MAX / Ki; | ||||
| #endif //PIDTEMP | ||||
|  | ||||
| // Set analog inputs | ||||
|   ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07; | ||||
|    | ||||
| // Use timer0 for temperature measurement | ||||
| // Interleave temperature interrupt with millies interrupt | ||||
|   OCR0B = 128; | ||||
|   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) | ||||
| { | ||||
|   switch(temp_state) { | ||||
|     case 0: // Prepare TEMP_0 | ||||
|             #if (TEMP_0_PIN > -1) | ||||
|               #if TEMP_0_PIN < 8 | ||||
|                 DIDR0 = 1 << TEMP_0_PIN;  | ||||
|               #else | ||||
|                 DIDR2 = 1<<(TEMP_0_PIN - 8);  | ||||
|                 ADCSRB = 1<<MUX5; | ||||
|               #endif | ||||
|               ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07)); | ||||
|               ADCSRA |= 1<<ADSC; // Start conversion | ||||
|             #endif | ||||
|             #ifdef ULTIPANEL | ||||
|               buttons_check(); | ||||
|             #endif | ||||
|             temp_state = 1; | ||||
|             break; | ||||
|     case 1: // Measure TEMP_0 | ||||
|             #if (TEMP_0_PIN > -1) | ||||
|               raw_temp_0_value += ADC; | ||||
|             #endif | ||||
|             temp_state = 2; | ||||
|             break; | ||||
|     case 2: // Prepare TEMP_1 | ||||
|             #if (TEMP_1_PIN > -1) | ||||
|               #if TEMP_1_PIN < 7 | ||||
|                 DIDR0 = 1<<TEMP_1_PIN;  | ||||
|               #else | ||||
|                 DIDR2 = 1<<(TEMP_1_PIN - 8);  | ||||
|                 ADCSRB = 1<<MUX5; | ||||
|               #endif | ||||
|               ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07)); | ||||
|               ADCSRA |= 1<<ADSC; // Start conversion | ||||
|             #endif | ||||
|             #ifdef ULTIPANEL | ||||
|               buttons_check(); | ||||
|             #endif | ||||
|             temp_state = 3; | ||||
|             break; | ||||
|     case 3: // Measure TEMP_1 | ||||
|             #if (TEMP_1_PIN > -1) | ||||
|               raw_temp_1_value += ADC; | ||||
|             #endif | ||||
|             temp_state = 4; | ||||
|             break; | ||||
|     case 4: // Prepare TEMP_2 | ||||
|             #if (TEMP_2_PIN > -1) | ||||
|               #if TEMP_2_PIN < 7 | ||||
|                 DIDR0 = 1 << TEMP_2_PIN;  | ||||
|               #else | ||||
|                 DIDR2 = 1<<(TEMP_2_PIN - 8);  | ||||
|                 ADCSRB = 1<<MUX5; | ||||
|               #endif | ||||
|               ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07)); | ||||
|               ADCSRA |= 1<<ADSC; // Start conversion | ||||
|             #endif | ||||
|             #ifdef ULTIPANEL | ||||
|               buttons_check(); | ||||
|             #endif | ||||
|             temp_state = 5; | ||||
|             break; | ||||
|     case 5: // Measure TEMP_2 | ||||
|             #if (TEMP_2_PIN > -1) | ||||
|               raw_temp_2_value += ADC; | ||||
|             #endif | ||||
|             temp_state = 0; | ||||
|             temp_count++; | ||||
|             break; | ||||
|     default: | ||||
|             Serial.println("!! Temp measurement error !!"); | ||||
|             break; | ||||
|   } | ||||
|      | ||||
|   if(temp_count >= 16) // 6 ms * 16 = 96ms. | ||||
|   { | ||||
|     #ifdef HEATER_1_USES_AD595 | ||||
|       current_raw[0] = raw_temp_0_value; | ||||
|     #else | ||||
|       current_raw[0] = 16383 - raw_temp_0_value; | ||||
|     #endif | ||||
|      | ||||
|     #ifdef HEATER_2_USES_AD595 | ||||
|       current_raw[2] = raw_temp_2_value; | ||||
|     #else | ||||
|       current_raw[2] = 16383 - raw_temp_2_value; | ||||
|     #endif | ||||
|      | ||||
|     #ifdef BED_USES_AD595 | ||||
|       current_raw[1] = raw_temp_1_value; | ||||
|     #else | ||||
|       current_raw[1] = 16383 - raw_temp_1_value; | ||||
|     #endif | ||||
|      | ||||
|     temp_meas_ready = true; | ||||
|     temp_count = 0; | ||||
|     raw_temp_0_value = 0; | ||||
|     raw_temp_1_value = 0; | ||||
|     raw_temp_2_value = 0; | ||||
| #ifdef MAXTEMP | ||||
|   #if (HEATER_0_PIN > -1) | ||||
|     { | ||||
|       WRITE(HEATER_1_PIN,LOW); | ||||
|     } | ||||
|     else  | ||||
|     { | ||||
|       WRITE(HEATER_1_PIN,HIGH); | ||||
|     } | ||||
|   #endif | ||||
|   } | ||||
|  | ||||
| // Takes hot end temperature value as input and returns corresponding raw value.  | ||||
| // For a thermistor, it uses the RepRap thermistor temp table. | ||||
| // This is needed because PID in hydra firmware hovers around a given analog value, not a temp value. | ||||
| // This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware. | ||||
| float temp2analog(int celsius) { | ||||
|   #ifdef HEATER_USES_THERMISTOR_1 | ||||
|     int raw = 0; | ||||
|     byte i; | ||||
|      | ||||
|     for (i=1; i<NUMTEMPS_HEATER_1; i++) | ||||
|     { | ||||
|       if (temptable_1[i][1] < celsius) | ||||
|       { | ||||
|         raw = temptable_1[i-1][0] +  | ||||
|           (celsius - temptable_1[i-1][1]) *  | ||||
|           (temptable_1[i][0] - temptable_1[i-1][0]) / | ||||
|           (temptable_1[i][1] - temptable_1[i-1][1]); | ||||
|        | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Overflow: Set to last value in the table | ||||
|     if (i == NUMTEMPS_1) raw = temptable_1[i-1][0]; | ||||
|  | ||||
|     return (1023 * OVERSAMPLENR) - raw; | ||||
|   #elif defined HEATER_1_USES_AD595 | ||||
|     return celsius * (1024.0 / (5.0 * 100.0) ) * OVERSAMPLENR; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| // Takes bed temperature value as input and returns corresponding raw value.  | ||||
| // For a thermistor, it uses the RepRap thermistor temp table. | ||||
| // This is needed because PID in hydra firmware hovers around a given analog value, not a temp value. | ||||
| // This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware. | ||||
| float temp2analogBed(int celsius) { | ||||
|   #ifdef BED_USES_THERMISTOR | ||||
|  | ||||
|     int raw = 0; | ||||
|     byte i; | ||||
|      | ||||
|     for (i=1; i<BNUMTEMPS; i++) | ||||
|     { | ||||
|       if (bedtemptable[i][1] < celsius) | ||||
|       { | ||||
|         raw = bedtemptable[i-1][0] +  | ||||
|           (celsius - bedtemptable[i-1][1]) *  | ||||
|           (bedtemptable[i][0] - bedtemptable[i-1][0]) / | ||||
|           (bedtemptable[i][1] - bedtemptable[i-1][1]); | ||||
|        | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Overflow: Set to last value in the table | ||||
|     if (i == BNUMTEMPS) raw = bedtemptable[i-1][0]; | ||||
|  | ||||
|     return (1023 * OVERSAMPLENR) - raw; | ||||
|   #elif defined BED_USES_AD595 | ||||
|     return celsius * (1024.0 / (5.0 * 100.0) ) * OVERSAMPLENR; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| // Derived from RepRap FiveD extruder::getTemperature() | ||||
| // For hot end temperature measurement. | ||||
| float analog2temp(int raw) { | ||||
|   #ifdef HEATER_1_USES_THERMISTOR | ||||
|     int celsius = 0; | ||||
|     byte i;   | ||||
|     raw = (1023 * OVERSAMPLENR) - raw; | ||||
|     for (i=1; i<NUMTEMPS_HEATER_1; i++) | ||||
|     { | ||||
|       if (temptable_1[i][0] > raw) | ||||
|       { | ||||
|         celsius  = temptable_1[i-1][1] +  | ||||
|           (raw - temptable_1[i-1][0]) *  | ||||
|           (temptable_1[i][1] - temptable_1[i-1][1]) / | ||||
|           (temptable_1[i][0] - temptable_1[i-1][0]); | ||||
|  | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Overflow: Set to last value in the table | ||||
|     if (i == NUMTEMPS_HEATER_1) celsius = temptable_1[i-1][1]; | ||||
|  | ||||
|     return celsius; | ||||
|   #elif defined HEATER_1_USES_AD595 | ||||
|     return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| // Derived from RepRap FiveD extruder::getTemperature() | ||||
| // For bed temperature measurement. | ||||
| float analog2tempBed(int raw) { | ||||
|   #ifdef BED_USES_THERMISTOR | ||||
|     int celsius = 0; | ||||
|     byte i; | ||||
|  | ||||
|     raw = (1023 * OVERSAMPLENR) - raw; | ||||
|  | ||||
|     for (i=1; i<BNUMTEMPS; i++) | ||||
|     { | ||||
|       if (bedtemptable[i][0] > raw) | ||||
|       { | ||||
|         celsius  = bedtemptable[i-1][1] +  | ||||
|           (raw - bedtemptable[i-1][0]) *  | ||||
|           (bedtemptable[i][1] - bedtemptable[i-1][1]) / | ||||
|           (bedtemptable[i][0] - bedtemptable[i-1][0]); | ||||
|  | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Overflow: Set to last value in the table | ||||
|     if (i == BNUMTEMPS) celsius = bedtemptable[i-1][1]; | ||||
|  | ||||
|     return celsius; | ||||
|      | ||||
|   #elif defined BED_USES_AD595 | ||||
|     return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| void tp_init() | ||||
| { | ||||
| #if (HEATER_0_PIN > -1)  | ||||
|   SET_OUTPUT(HEATER_0_PIN); | ||||
| #endif   | ||||
| #if (HEATER_1_PIN > -1)  | ||||
|   SET_OUTPUT(HEATER_1_PIN); | ||||
| #endif   | ||||
| #if (HEATER_2_PIN > -1)  | ||||
|   SET_OUTPUT(HEATER_2_PIN); | ||||
| #endif   | ||||
|  | ||||
| #ifdef PIDTEMP | ||||
|   temp_iState_min = 0.0; | ||||
|   temp_iState_max = PID_INTEGRAL_DRIVE_MAX / Ki; | ||||
| #endif //PIDTEMP | ||||
|  | ||||
| // Set analog inputs | ||||
|   ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07; | ||||
|    | ||||
| // Use timer0 for temperature measurement | ||||
| // Interleave temperature interrupt with millies interrupt | ||||
|   OCR0B = 128; | ||||
|   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) | ||||
| { | ||||
|   switch(temp_state) { | ||||
|     case 0: // Prepare TEMP_0 | ||||
|             #if (TEMP_0_PIN > -1) | ||||
|               #if TEMP_0_PIN < 8 | ||||
|                 DIDR0 = 1 << TEMP_0_PIN;  | ||||
|               #else | ||||
|                 DIDR2 = 1<<(TEMP_0_PIN - 8);  | ||||
|                 ADCSRB = 1<<MUX5; | ||||
|               #endif | ||||
|               ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07)); | ||||
|               ADCSRA |= 1<<ADSC; // Start conversion | ||||
|             #endif | ||||
|             #ifdef ULTIPANEL | ||||
|               buttons_check(); | ||||
|             #endif | ||||
|             temp_state = 1; | ||||
|             break; | ||||
|     case 1: // Measure TEMP_0 | ||||
|             #if (TEMP_0_PIN > -1) | ||||
|               raw_temp_0_value += ADC; | ||||
|             #endif | ||||
|             temp_state = 2; | ||||
|             break; | ||||
|     case 2: // Prepare TEMP_1 | ||||
|             #if (TEMP_1_PIN > -1) | ||||
|               #if TEMP_1_PIN < 7 | ||||
|                 DIDR0 = 1<<TEMP_1_PIN;  | ||||
|               #else | ||||
|                 DIDR2 = 1<<(TEMP_1_PIN - 8);  | ||||
|                 ADCSRB = 1<<MUX5; | ||||
|               #endif | ||||
|               ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07)); | ||||
|               ADCSRA |= 1<<ADSC; // Start conversion | ||||
|             #endif | ||||
|             #ifdef ULTIPANEL | ||||
|               buttons_check(); | ||||
|             #endif | ||||
|             temp_state = 3; | ||||
|             break; | ||||
|     case 3: // Measure TEMP_1 | ||||
|             #if (TEMP_1_PIN > -1) | ||||
|               raw_temp_1_value += ADC; | ||||
|             #endif | ||||
|             temp_state = 4; | ||||
|             break; | ||||
|     case 4: // Prepare TEMP_2 | ||||
|             #if (TEMP_2_PIN > -1) | ||||
|               #if TEMP_2_PIN < 7 | ||||
|                 DIDR0 = 1 << TEMP_2_PIN;  | ||||
|               #else | ||||
|                 DIDR2 = 1<<(TEMP_2_PIN - 8);  | ||||
|                 ADCSRB = 1<<MUX5; | ||||
|               #endif | ||||
|               ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07)); | ||||
|               ADCSRA |= 1<<ADSC; // Start conversion | ||||
|             #endif | ||||
|             #ifdef ULTIPANEL | ||||
|               buttons_check(); | ||||
|             #endif | ||||
|             temp_state = 5; | ||||
|             break; | ||||
|     case 5: // Measure TEMP_2 | ||||
|             #if (TEMP_2_PIN > -1) | ||||
|               raw_temp_2_value += ADC; | ||||
|             #endif | ||||
|             temp_state = 0; | ||||
|             temp_count++; | ||||
|             break; | ||||
|     default: | ||||
|             Serial.println("!! Temp measurement error !!"); | ||||
|             break; | ||||
|   } | ||||
|      | ||||
|   if(temp_count >= 16) // 6 ms * 16 = 96ms. | ||||
|   { | ||||
|     #ifdef HEATER_1_USES_AD595 | ||||
|       current_raw[0] = raw_temp_0_value; | ||||
|     #else | ||||
|       current_raw[0] = 16383 - raw_temp_0_value; | ||||
|     #endif | ||||
|      | ||||
|     #ifdef HEATER_2_USES_AD595 | ||||
|       current_raw[2] = raw_temp_2_value; | ||||
|     #else | ||||
|       current_raw[2] = 16383 - raw_temp_2_value; | ||||
|     #endif | ||||
|      | ||||
|     #ifdef BED_USES_AD595 | ||||
|       current_raw[1] = raw_temp_1_value; | ||||
|     #else | ||||
|       current_raw[1] = 16383 - raw_temp_1_value; | ||||
|     #endif | ||||
|      | ||||
|     temp_meas_ready = true; | ||||
|     temp_count = 0; | ||||
|     raw_temp_0_value = 0; | ||||
|     raw_temp_1_value = 0; | ||||
|     raw_temp_2_value = 0; | ||||
| #ifdef MAXTEMP | ||||
|   #if (HEATER_0_PIN > -1) | ||||
|     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 !!"); | ||||
|     } | ||||
|   #endif | ||||
|   #if (HEATER_2_PIN > -1) | ||||
|       analogWrite(HEATER_0_PIN, 0); | ||||
|       Serial.println("!! Temperature extruder 0 switched off. MAXTEMP triggered !!"); | ||||
|     } | ||||
|   #endif | ||||
|   #if (HEATER_2_PIN > -1) | ||||
|     if(current_raw[TEMPSENSOR_AUX] >= maxttemp) { | ||||
|       target_raw[TEMPSENSOR_AUX] = 0; | ||||
|       analogWrite(HEATER_2_PIN, 0); | ||||
|       Serial.println("!! Temperature extruder 1 switched off. MAXTEMP triggered !!"); | ||||
|     } | ||||
|   #endif | ||||
| #endif //MAXTEMP | ||||
| #ifdef MINTEMP | ||||
|   #if (HEATER_0_PIN > -1) | ||||
|       analogWrite(HEATER_2_PIN, 0); | ||||
|       Serial.println("!! Temperature extruder 1 switched off. MAXTEMP triggered !!"); | ||||
|     } | ||||
|   #endif | ||||
| #endif //MAXTEMP | ||||
| #ifdef MINTEMP | ||||
|   #if (HEATER_0_PIN > -1) | ||||
|     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 !!"); | ||||
|     } | ||||
|   #endif | ||||
|   #if (HEATER_2_PIN > -1) | ||||
|       analogWrite(HEATER_0_PIN, 0); | ||||
|       Serial.println("!! Temperature extruder 0 switched off. MINTEMP triggered !!"); | ||||
|     } | ||||
|   #endif | ||||
|   #if (HEATER_2_PIN > -1) | ||||
|     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 !!"); | ||||
|     } | ||||
|   #endif | ||||
| #endif //MAXTEMP | ||||
| #ifdef BED_MINTEMP | ||||
|   #if (HEATER_1_PIN > -1) | ||||
|     if(current_raw[1] <= bed_minttemp) { | ||||
|       target_raw[1] = 0; | ||||
|       WRITE(HEATER_1_PIN, 0); | ||||
|       Serial.println("!! Temperatur heated bed switched off. MINTEMP triggered !!"); | ||||
|     } | ||||
|   #endif | ||||
| #endif | ||||
| #ifdef BED_MAXTEMP | ||||
|   #if (HEATER_1_PIN > -1) | ||||
|     if(current_raw[1] >= bed_maxttemp) { | ||||
|       target_raw[1] = 0; | ||||
|       WRITE(HEATER_1_PIN, 0); | ||||
|       Serial.println("!! Temperature heated bed switched off. MAXTEMP triggered !!"); | ||||
|     } | ||||
|   #endif | ||||
| #endif | ||||
|   } | ||||
| } | ||||
|       analogWrite(HEATER_2_PIN, 0); | ||||
|       Serial.println("!! Temperature extruder 1 switched off. MINTEMP triggered !!"); | ||||
|     } | ||||
|   #endif | ||||
| #endif //MAXTEMP | ||||
| #ifdef BED_MINTEMP | ||||
|   #if (HEATER_1_PIN > -1) | ||||
|     if(current_raw[1] <= bed_minttemp) { | ||||
|       target_raw[1] = 0; | ||||
|       WRITE(HEATER_1_PIN, 0); | ||||
|       Serial.println("!! Temperatur heated bed switched off. MINTEMP triggered !!"); | ||||
|     } | ||||
|   #endif | ||||
| #endif | ||||
| #ifdef BED_MAXTEMP | ||||
|   #if (HEATER_1_PIN > -1) | ||||
|     if(current_raw[1] >= bed_maxttemp) { | ||||
|       target_raw[1] = 0; | ||||
|       WRITE(HEATER_1_PIN, 0); | ||||
|       Serial.println("!! Temperature heated bed switched off. MAXTEMP triggered !!"); | ||||
|     } | ||||
|   #endif | ||||
| #endif | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,410 +1,410 @@ | ||||
| #ifndef THERMISTORTABLES_H_ | ||||
| #define THERMISTORTABLES_H_ | ||||
|  | ||||
| #define OVERSAMPLENR 16 | ||||
|  | ||||
| #if (THERMISTORHEATER_1 == 1) || (THERMISTORHEATER_2 == 1) || (THERMISTORBED == 1) //100k bed thermistor | ||||
|  | ||||
| #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 | ||||
| }; | ||||
| #endif | ||||
| #if (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORBED == 2) //200k bed thermistor | ||||
| #define NUMTEMPS_2 21 | ||||
| const short temptable_2[NUMTEMPS_2][2] = { | ||||
|    {1*OVERSAMPLENR, 848}, | ||||
|    {54*OVERSAMPLENR, 275}, | ||||
|    {107*OVERSAMPLENR, 228}, | ||||
|    {160*OVERSAMPLENR, 202}, | ||||
|    {213*OVERSAMPLENR, 185}, | ||||
|    {266*OVERSAMPLENR, 171}, | ||||
|    {319*OVERSAMPLENR, 160}, | ||||
|    {372*OVERSAMPLENR, 150}, | ||||
|    {425*OVERSAMPLENR, 141}, | ||||
|    {478*OVERSAMPLENR, 133}, | ||||
|    {531*OVERSAMPLENR, 125}, | ||||
|    {584*OVERSAMPLENR, 118}, | ||||
|    {637*OVERSAMPLENR, 110}, | ||||
|    {690*OVERSAMPLENR, 103}, | ||||
|    {743*OVERSAMPLENR, 95}, | ||||
|    {796*OVERSAMPLENR, 86}, | ||||
|    {849*OVERSAMPLENR, 77}, | ||||
|    {902*OVERSAMPLENR, 65}, | ||||
|    {955*OVERSAMPLENR, 49}, | ||||
|    {1008*OVERSAMPLENR, 17}, | ||||
|    {1020*OVERSAMPLENR, 0} //safety | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| #if (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 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} | ||||
|         }; | ||||
|  | ||||
| #endif | ||||
| #if (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORBED == 4) //10k thermistor | ||||
|  | ||||
| #define NUMTEMPS_4 20 | ||||
| short temptable_4[NUMTEMPS_4][2] = { | ||||
|    {1*OVERSAMPLENR, 430}, | ||||
|    {54*OVERSAMPLENR, 137}, | ||||
|    {107*OVERSAMPLENR, 107}, | ||||
|    {160*OVERSAMPLENR, 91}, | ||||
|    {213*OVERSAMPLENR, 80}, | ||||
|    {266*OVERSAMPLENR, 71}, | ||||
|    {319*OVERSAMPLENR, 64}, | ||||
|    {372*OVERSAMPLENR, 57}, | ||||
|    {425*OVERSAMPLENR, 51}, | ||||
|    {478*OVERSAMPLENR, 46}, | ||||
|    {531*OVERSAMPLENR, 41}, | ||||
|    {584*OVERSAMPLENR, 35}, | ||||
|    {637*OVERSAMPLENR, 30}, | ||||
|    {690*OVERSAMPLENR, 25}, | ||||
|    {743*OVERSAMPLENR, 20}, | ||||
|    {796*OVERSAMPLENR, 14}, | ||||
|    {849*OVERSAMPLENR, 7}, | ||||
|    {902*OVERSAMPLENR, 0}, | ||||
|    {955*OVERSAMPLENR, -11}, | ||||
|    {1008*OVERSAMPLENR, -35} | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2) | ||||
|  | ||||
| #define NUMTEMPS_5 61 | ||||
| const short temptable_5[NUMTEMPS_5][2] = { | ||||
| {1*OVERSAMPLENR, 713}, | ||||
| {18*OVERSAMPLENR, 316}, | ||||
| {35*OVERSAMPLENR, 266}, | ||||
| {52*OVERSAMPLENR, 239}, | ||||
| {69*OVERSAMPLENR, 221}, | ||||
| {86*OVERSAMPLENR, 208}, | ||||
| {103*OVERSAMPLENR, 197}, | ||||
| {120*OVERSAMPLENR, 188}, | ||||
| {137*OVERSAMPLENR, 181}, | ||||
| {154*OVERSAMPLENR, 174}, | ||||
| {171*OVERSAMPLENR, 169}, | ||||
| {188*OVERSAMPLENR, 163}, | ||||
| {205*OVERSAMPLENR, 159}, | ||||
| {222*OVERSAMPLENR, 154}, | ||||
| {239*OVERSAMPLENR, 150}, | ||||
| {256*OVERSAMPLENR, 147}, | ||||
| {273*OVERSAMPLENR, 143}, | ||||
| {290*OVERSAMPLENR, 140}, | ||||
| {307*OVERSAMPLENR, 136}, | ||||
| {324*OVERSAMPLENR, 133}, | ||||
| {341*OVERSAMPLENR, 130}, | ||||
| {358*OVERSAMPLENR, 128}, | ||||
| {375*OVERSAMPLENR, 125}, | ||||
| {392*OVERSAMPLENR, 122}, | ||||
| {409*OVERSAMPLENR, 120}, | ||||
| {426*OVERSAMPLENR, 117}, | ||||
| {443*OVERSAMPLENR, 115}, | ||||
| {460*OVERSAMPLENR, 112}, | ||||
| {477*OVERSAMPLENR, 110}, | ||||
| {494*OVERSAMPLENR, 108}, | ||||
| {511*OVERSAMPLENR, 106}, | ||||
| {528*OVERSAMPLENR, 103}, | ||||
| {545*OVERSAMPLENR, 101}, | ||||
| {562*OVERSAMPLENR, 99}, | ||||
| {579*OVERSAMPLENR, 97}, | ||||
| {596*OVERSAMPLENR, 95}, | ||||
| {613*OVERSAMPLENR, 92}, | ||||
| {630*OVERSAMPLENR, 90}, | ||||
| {647*OVERSAMPLENR, 88}, | ||||
| {664*OVERSAMPLENR, 86}, | ||||
| {681*OVERSAMPLENR, 84}, | ||||
| {698*OVERSAMPLENR, 81}, | ||||
| {715*OVERSAMPLENR, 79}, | ||||
| {732*OVERSAMPLENR, 77}, | ||||
| {749*OVERSAMPLENR, 75}, | ||||
| {766*OVERSAMPLENR, 72}, | ||||
| {783*OVERSAMPLENR, 70}, | ||||
| {800*OVERSAMPLENR, 67}, | ||||
| {817*OVERSAMPLENR, 64}, | ||||
| {834*OVERSAMPLENR, 61}, | ||||
| {851*OVERSAMPLENR, 58}, | ||||
| {868*OVERSAMPLENR, 55}, | ||||
| {885*OVERSAMPLENR, 52}, | ||||
| {902*OVERSAMPLENR, 48}, | ||||
| {919*OVERSAMPLENR, 44}, | ||||
| {936*OVERSAMPLENR, 40}, | ||||
| {953*OVERSAMPLENR, 34}, | ||||
| {970*OVERSAMPLENR, 28}, | ||||
| {987*OVERSAMPLENR, 20}, | ||||
| {1004*OVERSAMPLENR, 8}, | ||||
| {1021*OVERSAMPLENR, 0} | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor | ||||
| #define NUMTEMPS_6 36 | ||||
| const short temptable_6[NUMTEMPS_6][2] = { | ||||
|    {28*OVERSAMPLENR, 250}, | ||||
|    {31*OVERSAMPLENR, 245}, | ||||
|    {35*OVERSAMPLENR, 240}, | ||||
|    {39*OVERSAMPLENR, 235}, | ||||
|    {42*OVERSAMPLENR, 230}, | ||||
|    {44*OVERSAMPLENR, 225}, | ||||
|    {49*OVERSAMPLENR, 220}, | ||||
|    {53*OVERSAMPLENR, 215}, | ||||
|    {62*OVERSAMPLENR, 210}, | ||||
|    {73*OVERSAMPLENR, 205}, | ||||
|    {72*OVERSAMPLENR, 200}, | ||||
|    {94*OVERSAMPLENR, 190}, | ||||
|    {102*OVERSAMPLENR, 185}, | ||||
|    {116*OVERSAMPLENR, 170}, | ||||
|    {143*OVERSAMPLENR, 160}, | ||||
|    {183*OVERSAMPLENR, 150}, | ||||
|    {223*OVERSAMPLENR, 140}, | ||||
|    {270*OVERSAMPLENR, 130}, | ||||
|    {318*OVERSAMPLENR, 120}, | ||||
|    {383*OVERSAMPLENR, 110}, | ||||
|    {413*OVERSAMPLENR, 105}, | ||||
|    {439*OVERSAMPLENR, 100}, | ||||
|    {484*OVERSAMPLENR, 95}, | ||||
|    {513*OVERSAMPLENR, 90}, | ||||
|    {607*OVERSAMPLENR, 80}, | ||||
|    {664*OVERSAMPLENR, 70}, | ||||
|    {781*OVERSAMPLENR, 60}, | ||||
|    {810*OVERSAMPLENR, 55}, | ||||
|    {849*OVERSAMPLENR, 50}, | ||||
|    {914*OVERSAMPLENR, 45}, | ||||
|    {914*OVERSAMPLENR, 40}, | ||||
|    {935*OVERSAMPLENR, 35}, | ||||
|    {954*OVERSAMPLENR, 30}, | ||||
|    {970*OVERSAMPLENR, 25}, | ||||
|    {978*OVERSAMPLENR, 22}, | ||||
|    {1008*OVERSAMPLENR, 3} | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01 | ||||
| #define NUMTEMPS_7 54 | ||||
| const short temptable_7[NUMTEMPS_7][2] = { | ||||
|    {46*OVERSAMPLENR, 270}, | ||||
|    {50*OVERSAMPLENR, 265}, | ||||
|    {54*OVERSAMPLENR, 260}, | ||||
|    {58*OVERSAMPLENR, 255}, | ||||
|    {62*OVERSAMPLENR, 250}, | ||||
|    {67*OVERSAMPLENR, 245}, | ||||
|    {72*OVERSAMPLENR, 240}, | ||||
|    {79*OVERSAMPLENR, 235}, | ||||
|    {85*OVERSAMPLENR, 230}, | ||||
|    {91*OVERSAMPLENR, 225}, | ||||
|    {99*OVERSAMPLENR, 220}, | ||||
|    {107*OVERSAMPLENR, 215}, | ||||
|    {116*OVERSAMPLENR, 210}, | ||||
|    {126*OVERSAMPLENR, 205}, | ||||
|    {136*OVERSAMPLENR, 200}, | ||||
|    {149*OVERSAMPLENR, 195}, | ||||
|    {160*OVERSAMPLENR, 190}, | ||||
|    {175*OVERSAMPLENR, 185}, | ||||
|    {191*OVERSAMPLENR, 180}, | ||||
|    {209*OVERSAMPLENR, 175}, | ||||
|    {224*OVERSAMPLENR, 170}, | ||||
|    {246*OVERSAMPLENR, 165}, | ||||
|    {267*OVERSAMPLENR, 160}, | ||||
|    {293*OVERSAMPLENR, 155}, | ||||
|    {316*OVERSAMPLENR, 150}, | ||||
|    {340*OVERSAMPLENR, 145}, | ||||
|    {364*OVERSAMPLENR, 140}, | ||||
|    {396*OVERSAMPLENR, 135}, | ||||
|    {425*OVERSAMPLENR, 130}, | ||||
|    {460*OVERSAMPLENR, 125}, | ||||
|    {489*OVERSAMPLENR, 120}, | ||||
|    {526*OVERSAMPLENR, 115}, | ||||
|    {558*OVERSAMPLENR, 110}, | ||||
|    {591*OVERSAMPLENR, 105}, | ||||
|    {628*OVERSAMPLENR, 100}, | ||||
|    {660*OVERSAMPLENR, 95}, | ||||
|    {696*OVERSAMPLENR, 90}, | ||||
|    {733*OVERSAMPLENR, 85}, | ||||
|    {761*OVERSAMPLENR, 80}, | ||||
|    {794*OVERSAMPLENR, 75}, | ||||
|    {819*OVERSAMPLENR, 70}, | ||||
|    {847*OVERSAMPLENR, 65}, | ||||
|    {870*OVERSAMPLENR, 60}, | ||||
|    {892*OVERSAMPLENR, 55}, | ||||
|    {911*OVERSAMPLENR, 50}, | ||||
|    {929*OVERSAMPLENR, 45}, | ||||
|    {944*OVERSAMPLENR, 40}, | ||||
|    {959*OVERSAMPLENR, 35}, | ||||
|    {971*OVERSAMPLENR, 30}, | ||||
|    {981*OVERSAMPLENR, 25}, | ||||
|    {989*OVERSAMPLENR, 20}, | ||||
|    {994*OVERSAMPLENR, 15}, | ||||
|    {1001*OVERSAMPLENR, 10}, | ||||
|    {1005*OVERSAMPLENR, 5} | ||||
| }; | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| #if THERMISTORHEATER_1 == 1 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_1 | ||||
| #define temptable_1 temptable_1 | ||||
| #elif THERMISTORHEATER_1 == 2 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_2 | ||||
| #define temptable_1 temptable_2 | ||||
| #elif THERMISTORHEATER_1 == 3 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_3 | ||||
| #define temptable_1 temptable_3 | ||||
| #elif THERMISTORHEATER_1 == 4 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_4 | ||||
| #define temptable_1 temptable_4 | ||||
| #elif THERMISTORHEATER_1 == 5 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_5 | ||||
| #define temptable_1 temptable_5 | ||||
| #elif THERMISTORHEATER_1 == 6 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_6 | ||||
| #define temptable_1 temptable_6 | ||||
| #elif THERMISTORHEATER_1 == 7 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_7 | ||||
| #define temptable_1 temptable_7 | ||||
| #elif defined HEATER_1_USES_THERMISTOR | ||||
| #error No heater 1 thermistor table specified | ||||
| #endif | ||||
|  | ||||
| #if THERMISTORHEATER_2 == 1 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_1 | ||||
| #define temptable_2 temptable_1 | ||||
| #elif THERMISTORHEATER_2 == 2 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_2 | ||||
| #define temptable_2 temptable_2 | ||||
| #elif THERMISTORHEATER_2 == 3 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_3 | ||||
| #define temptable_2 temptable_3 | ||||
| #elif THERMISTORHEATER_2 == 4 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_4 | ||||
| #define temptable_2 temptable_4 | ||||
| #elif THERMISTORHEATER_2 == 5 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_5 | ||||
| #define temptable_2 temptable_5 | ||||
| #elif THERMISTORHEATER_2 == 6 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_6 | ||||
| #define temptable_2 temptable_6 | ||||
| #elif THERMISTORHEATER_2 == 7 | ||||
| #define NUMTEMPS_HEATER22 NUMTEMPS_7 | ||||
| #define temptable_2 temptable_7 | ||||
| #elif defined HEATER_2_USES_THERMISTOR | ||||
| #error No heater 2 thermistor table specified | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #if THERMISTORBED == 1 | ||||
| #define BNUMTEMPS NUMTEMPS_1 | ||||
| #define bedtemptable temptable_1 | ||||
| #elif THERMISTORBED == 2 | ||||
| #define BNUMTEMPS NUMTEMPS_2 | ||||
| #define bedtemptable temptable_2 | ||||
| #elif THERMISTORBED == 3 | ||||
| #define BNUMTEMPS NUMTEMPS_3 | ||||
| #define bedtemptable temptable_3 | ||||
| #elif THERMISTORBED == 4 | ||||
| #define BNUMTEMPS NUMTEMPS_4 | ||||
| #define bedtemptable temptable_4 | ||||
| #elif THERMISTORBED == 5 | ||||
| #define BNUMTEMPS NUMTEMPS_5 | ||||
| #define bedtemptable temptable_5 | ||||
| #elif THERMISTORBED == 6 | ||||
| #define BNUMTEMPS NUMTEMPS_6 | ||||
| #define bedtemptable temptable_6 | ||||
| #elif THERMISTORBED == 7 | ||||
| #define BNUMTEMPS NUMTEMPS_7 | ||||
| #define bedtemptable temptable_7 | ||||
| #elif defined BED_USES_THERMISTOR | ||||
| #error No bed thermistor table specified | ||||
| #endif | ||||
|  | ||||
| #endif //THERMISTORTABLES_H_ | ||||
|  | ||||
| #ifndef THERMISTORTABLES_H_ | ||||
| #define THERMISTORTABLES_H_ | ||||
|  | ||||
| #define OVERSAMPLENR 16 | ||||
|  | ||||
| #if (THERMISTORHEATER_1 == 1) || (THERMISTORHEATER_2 == 1) || (THERMISTORBED == 1) //100k bed thermistor | ||||
|  | ||||
| #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 | ||||
| }; | ||||
| #endif | ||||
| #if (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORBED == 2) //200k bed thermistor | ||||
| #define NUMTEMPS_2 21 | ||||
| const short temptable_2[NUMTEMPS_2][2] = { | ||||
|    {1*OVERSAMPLENR, 848}, | ||||
|    {54*OVERSAMPLENR, 275}, | ||||
|    {107*OVERSAMPLENR, 228}, | ||||
|    {160*OVERSAMPLENR, 202}, | ||||
|    {213*OVERSAMPLENR, 185}, | ||||
|    {266*OVERSAMPLENR, 171}, | ||||
|    {319*OVERSAMPLENR, 160}, | ||||
|    {372*OVERSAMPLENR, 150}, | ||||
|    {425*OVERSAMPLENR, 141}, | ||||
|    {478*OVERSAMPLENR, 133}, | ||||
|    {531*OVERSAMPLENR, 125}, | ||||
|    {584*OVERSAMPLENR, 118}, | ||||
|    {637*OVERSAMPLENR, 110}, | ||||
|    {690*OVERSAMPLENR, 103}, | ||||
|    {743*OVERSAMPLENR, 95}, | ||||
|    {796*OVERSAMPLENR, 86}, | ||||
|    {849*OVERSAMPLENR, 77}, | ||||
|    {902*OVERSAMPLENR, 65}, | ||||
|    {955*OVERSAMPLENR, 49}, | ||||
|    {1008*OVERSAMPLENR, 17}, | ||||
|    {1020*OVERSAMPLENR, 0} //safety | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| #if (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 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} | ||||
|         }; | ||||
|  | ||||
| #endif | ||||
| #if (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORBED == 4) //10k thermistor | ||||
|  | ||||
| #define NUMTEMPS_4 20 | ||||
| short temptable_4[NUMTEMPS_4][2] = { | ||||
|    {1*OVERSAMPLENR, 430}, | ||||
|    {54*OVERSAMPLENR, 137}, | ||||
|    {107*OVERSAMPLENR, 107}, | ||||
|    {160*OVERSAMPLENR, 91}, | ||||
|    {213*OVERSAMPLENR, 80}, | ||||
|    {266*OVERSAMPLENR, 71}, | ||||
|    {319*OVERSAMPLENR, 64}, | ||||
|    {372*OVERSAMPLENR, 57}, | ||||
|    {425*OVERSAMPLENR, 51}, | ||||
|    {478*OVERSAMPLENR, 46}, | ||||
|    {531*OVERSAMPLENR, 41}, | ||||
|    {584*OVERSAMPLENR, 35}, | ||||
|    {637*OVERSAMPLENR, 30}, | ||||
|    {690*OVERSAMPLENR, 25}, | ||||
|    {743*OVERSAMPLENR, 20}, | ||||
|    {796*OVERSAMPLENR, 14}, | ||||
|    {849*OVERSAMPLENR, 7}, | ||||
|    {902*OVERSAMPLENR, 0}, | ||||
|    {955*OVERSAMPLENR, -11}, | ||||
|    {1008*OVERSAMPLENR, -35} | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2) | ||||
|  | ||||
| #define NUMTEMPS_5 61 | ||||
| const short temptable_5[NUMTEMPS_5][2] = { | ||||
| {1*OVERSAMPLENR, 713}, | ||||
| {18*OVERSAMPLENR, 316}, | ||||
| {35*OVERSAMPLENR, 266}, | ||||
| {52*OVERSAMPLENR, 239}, | ||||
| {69*OVERSAMPLENR, 221}, | ||||
| {86*OVERSAMPLENR, 208}, | ||||
| {103*OVERSAMPLENR, 197}, | ||||
| {120*OVERSAMPLENR, 188}, | ||||
| {137*OVERSAMPLENR, 181}, | ||||
| {154*OVERSAMPLENR, 174}, | ||||
| {171*OVERSAMPLENR, 169}, | ||||
| {188*OVERSAMPLENR, 163}, | ||||
| {205*OVERSAMPLENR, 159}, | ||||
| {222*OVERSAMPLENR, 154}, | ||||
| {239*OVERSAMPLENR, 150}, | ||||
| {256*OVERSAMPLENR, 147}, | ||||
| {273*OVERSAMPLENR, 143}, | ||||
| {290*OVERSAMPLENR, 140}, | ||||
| {307*OVERSAMPLENR, 136}, | ||||
| {324*OVERSAMPLENR, 133}, | ||||
| {341*OVERSAMPLENR, 130}, | ||||
| {358*OVERSAMPLENR, 128}, | ||||
| {375*OVERSAMPLENR, 125}, | ||||
| {392*OVERSAMPLENR, 122}, | ||||
| {409*OVERSAMPLENR, 120}, | ||||
| {426*OVERSAMPLENR, 117}, | ||||
| {443*OVERSAMPLENR, 115}, | ||||
| {460*OVERSAMPLENR, 112}, | ||||
| {477*OVERSAMPLENR, 110}, | ||||
| {494*OVERSAMPLENR, 108}, | ||||
| {511*OVERSAMPLENR, 106}, | ||||
| {528*OVERSAMPLENR, 103}, | ||||
| {545*OVERSAMPLENR, 101}, | ||||
| {562*OVERSAMPLENR, 99}, | ||||
| {579*OVERSAMPLENR, 97}, | ||||
| {596*OVERSAMPLENR, 95}, | ||||
| {613*OVERSAMPLENR, 92}, | ||||
| {630*OVERSAMPLENR, 90}, | ||||
| {647*OVERSAMPLENR, 88}, | ||||
| {664*OVERSAMPLENR, 86}, | ||||
| {681*OVERSAMPLENR, 84}, | ||||
| {698*OVERSAMPLENR, 81}, | ||||
| {715*OVERSAMPLENR, 79}, | ||||
| {732*OVERSAMPLENR, 77}, | ||||
| {749*OVERSAMPLENR, 75}, | ||||
| {766*OVERSAMPLENR, 72}, | ||||
| {783*OVERSAMPLENR, 70}, | ||||
| {800*OVERSAMPLENR, 67}, | ||||
| {817*OVERSAMPLENR, 64}, | ||||
| {834*OVERSAMPLENR, 61}, | ||||
| {851*OVERSAMPLENR, 58}, | ||||
| {868*OVERSAMPLENR, 55}, | ||||
| {885*OVERSAMPLENR, 52}, | ||||
| {902*OVERSAMPLENR, 48}, | ||||
| {919*OVERSAMPLENR, 44}, | ||||
| {936*OVERSAMPLENR, 40}, | ||||
| {953*OVERSAMPLENR, 34}, | ||||
| {970*OVERSAMPLENR, 28}, | ||||
| {987*OVERSAMPLENR, 20}, | ||||
| {1004*OVERSAMPLENR, 8}, | ||||
| {1021*OVERSAMPLENR, 0} | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor | ||||
| #define NUMTEMPS_6 36 | ||||
| const short temptable_6[NUMTEMPS_6][2] = { | ||||
|    {28*OVERSAMPLENR, 250}, | ||||
|    {31*OVERSAMPLENR, 245}, | ||||
|    {35*OVERSAMPLENR, 240}, | ||||
|    {39*OVERSAMPLENR, 235}, | ||||
|    {42*OVERSAMPLENR, 230}, | ||||
|    {44*OVERSAMPLENR, 225}, | ||||
|    {49*OVERSAMPLENR, 220}, | ||||
|    {53*OVERSAMPLENR, 215}, | ||||
|    {62*OVERSAMPLENR, 210}, | ||||
|    {73*OVERSAMPLENR, 205}, | ||||
|    {72*OVERSAMPLENR, 200}, | ||||
|    {94*OVERSAMPLENR, 190}, | ||||
|    {102*OVERSAMPLENR, 185}, | ||||
|    {116*OVERSAMPLENR, 170}, | ||||
|    {143*OVERSAMPLENR, 160}, | ||||
|    {183*OVERSAMPLENR, 150}, | ||||
|    {223*OVERSAMPLENR, 140}, | ||||
|    {270*OVERSAMPLENR, 130}, | ||||
|    {318*OVERSAMPLENR, 120}, | ||||
|    {383*OVERSAMPLENR, 110}, | ||||
|    {413*OVERSAMPLENR, 105}, | ||||
|    {439*OVERSAMPLENR, 100}, | ||||
|    {484*OVERSAMPLENR, 95}, | ||||
|    {513*OVERSAMPLENR, 90}, | ||||
|    {607*OVERSAMPLENR, 80}, | ||||
|    {664*OVERSAMPLENR, 70}, | ||||
|    {781*OVERSAMPLENR, 60}, | ||||
|    {810*OVERSAMPLENR, 55}, | ||||
|    {849*OVERSAMPLENR, 50}, | ||||
|    {914*OVERSAMPLENR, 45}, | ||||
|    {914*OVERSAMPLENR, 40}, | ||||
|    {935*OVERSAMPLENR, 35}, | ||||
|    {954*OVERSAMPLENR, 30}, | ||||
|    {970*OVERSAMPLENR, 25}, | ||||
|    {978*OVERSAMPLENR, 22}, | ||||
|    {1008*OVERSAMPLENR, 3} | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01 | ||||
| #define NUMTEMPS_7 54 | ||||
| const short temptable_7[NUMTEMPS_7][2] = { | ||||
|    {46*OVERSAMPLENR, 270}, | ||||
|    {50*OVERSAMPLENR, 265}, | ||||
|    {54*OVERSAMPLENR, 260}, | ||||
|    {58*OVERSAMPLENR, 255}, | ||||
|    {62*OVERSAMPLENR, 250}, | ||||
|    {67*OVERSAMPLENR, 245}, | ||||
|    {72*OVERSAMPLENR, 240}, | ||||
|    {79*OVERSAMPLENR, 235}, | ||||
|    {85*OVERSAMPLENR, 230}, | ||||
|    {91*OVERSAMPLENR, 225}, | ||||
|    {99*OVERSAMPLENR, 220}, | ||||
|    {107*OVERSAMPLENR, 215}, | ||||
|    {116*OVERSAMPLENR, 210}, | ||||
|    {126*OVERSAMPLENR, 205}, | ||||
|    {136*OVERSAMPLENR, 200}, | ||||
|    {149*OVERSAMPLENR, 195}, | ||||
|    {160*OVERSAMPLENR, 190}, | ||||
|    {175*OVERSAMPLENR, 185}, | ||||
|    {191*OVERSAMPLENR, 180}, | ||||
|    {209*OVERSAMPLENR, 175}, | ||||
|    {224*OVERSAMPLENR, 170}, | ||||
|    {246*OVERSAMPLENR, 165}, | ||||
|    {267*OVERSAMPLENR, 160}, | ||||
|    {293*OVERSAMPLENR, 155}, | ||||
|    {316*OVERSAMPLENR, 150}, | ||||
|    {340*OVERSAMPLENR, 145}, | ||||
|    {364*OVERSAMPLENR, 140}, | ||||
|    {396*OVERSAMPLENR, 135}, | ||||
|    {425*OVERSAMPLENR, 130}, | ||||
|    {460*OVERSAMPLENR, 125}, | ||||
|    {489*OVERSAMPLENR, 120}, | ||||
|    {526*OVERSAMPLENR, 115}, | ||||
|    {558*OVERSAMPLENR, 110}, | ||||
|    {591*OVERSAMPLENR, 105}, | ||||
|    {628*OVERSAMPLENR, 100}, | ||||
|    {660*OVERSAMPLENR, 95}, | ||||
|    {696*OVERSAMPLENR, 90}, | ||||
|    {733*OVERSAMPLENR, 85}, | ||||
|    {761*OVERSAMPLENR, 80}, | ||||
|    {794*OVERSAMPLENR, 75}, | ||||
|    {819*OVERSAMPLENR, 70}, | ||||
|    {847*OVERSAMPLENR, 65}, | ||||
|    {870*OVERSAMPLENR, 60}, | ||||
|    {892*OVERSAMPLENR, 55}, | ||||
|    {911*OVERSAMPLENR, 50}, | ||||
|    {929*OVERSAMPLENR, 45}, | ||||
|    {944*OVERSAMPLENR, 40}, | ||||
|    {959*OVERSAMPLENR, 35}, | ||||
|    {971*OVERSAMPLENR, 30}, | ||||
|    {981*OVERSAMPLENR, 25}, | ||||
|    {989*OVERSAMPLENR, 20}, | ||||
|    {994*OVERSAMPLENR, 15}, | ||||
|    {1001*OVERSAMPLENR, 10}, | ||||
|    {1005*OVERSAMPLENR, 5} | ||||
| }; | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| #if THERMISTORHEATER_1 == 1 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_1 | ||||
| #define temptable_1 temptable_1 | ||||
| #elif THERMISTORHEATER_1 == 2 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_2 | ||||
| #define temptable_1 temptable_2 | ||||
| #elif THERMISTORHEATER_1 == 3 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_3 | ||||
| #define temptable_1 temptable_3 | ||||
| #elif THERMISTORHEATER_1 == 4 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_4 | ||||
| #define temptable_1 temptable_4 | ||||
| #elif THERMISTORHEATER_1 == 5 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_5 | ||||
| #define temptable_1 temptable_5 | ||||
| #elif THERMISTORHEATER_1 == 6 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_6 | ||||
| #define temptable_1 temptable_6 | ||||
| #elif THERMISTORHEATER_1 == 7 | ||||
| #define NUMTEMPS_HEATER_1 NUMTEMPS_7 | ||||
| #define temptable_1 temptable_7 | ||||
| #elif defined HEATER_1_USES_THERMISTOR | ||||
| #error No heater 1 thermistor table specified | ||||
| #endif | ||||
|  | ||||
| #if THERMISTORHEATER_2 == 1 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_1 | ||||
| #define temptable_2 temptable_1 | ||||
| #elif THERMISTORHEATER_2 == 2 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_2 | ||||
| #define temptable_2 temptable_2 | ||||
| #elif THERMISTORHEATER_2 == 3 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_3 | ||||
| #define temptable_2 temptable_3 | ||||
| #elif THERMISTORHEATER_2 == 4 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_4 | ||||
| #define temptable_2 temptable_4 | ||||
| #elif THERMISTORHEATER_2 == 5 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_5 | ||||
| #define temptable_2 temptable_5 | ||||
| #elif THERMISTORHEATER_2 == 6 | ||||
| #define NUMTEMPS_HEATER_2 NUMTEMPS_6 | ||||
| #define temptable_2 temptable_6 | ||||
| #elif THERMISTORHEATER_2 == 7 | ||||
| #define NUMTEMPS_HEATER22 NUMTEMPS_7 | ||||
| #define temptable_2 temptable_7 | ||||
| #elif defined HEATER_2_USES_THERMISTOR | ||||
| #error No heater 2 thermistor table specified | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #if THERMISTORBED == 1 | ||||
| #define BNUMTEMPS NUMTEMPS_1 | ||||
| #define bedtemptable temptable_1 | ||||
| #elif THERMISTORBED == 2 | ||||
| #define BNUMTEMPS NUMTEMPS_2 | ||||
| #define bedtemptable temptable_2 | ||||
| #elif THERMISTORBED == 3 | ||||
| #define BNUMTEMPS NUMTEMPS_3 | ||||
| #define bedtemptable temptable_3 | ||||
| #elif THERMISTORBED == 4 | ||||
| #define BNUMTEMPS NUMTEMPS_4 | ||||
| #define bedtemptable temptable_4 | ||||
| #elif THERMISTORBED == 5 | ||||
| #define BNUMTEMPS NUMTEMPS_5 | ||||
| #define bedtemptable temptable_5 | ||||
| #elif THERMISTORBED == 6 | ||||
| #define BNUMTEMPS NUMTEMPS_6 | ||||
| #define bedtemptable temptable_6 | ||||
| #elif THERMISTORBED == 7 | ||||
| #define BNUMTEMPS NUMTEMPS_7 | ||||
| #define bedtemptable temptable_7 | ||||
| #elif defined BED_USES_THERMISTOR | ||||
| #error No bed thermistor table specified | ||||
| #endif | ||||
|  | ||||
| #endif //THERMISTORTABLES_H_ | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user