changed end of line to windows, which seems to be the majority of developers main platform.
This commit is contained in:
parent
00674af3a8
commit
40e8081623
22 changed files with 9923 additions and 9923 deletions
|
@ -1,418 +1,418 @@
|
||||||
/* Arduino SdFat Library
|
/* Arduino SdFat Library
|
||||||
* Copyright (C) 2009 by William Greiman
|
* Copyright (C) 2009 by William Greiman
|
||||||
*
|
*
|
||||||
* This file is part of the Arduino SdFat Library
|
* This file is part of the Arduino SdFat Library
|
||||||
*
|
*
|
||||||
* This Library is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This Library is distributed in the hope that it will be useful,
|
* This Library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with the Arduino SdFat Library. If not, see
|
* along with the Arduino SdFat Library. If not, see
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#ifndef FatStructs_h
|
#ifndef FatStructs_h
|
||||||
#define FatStructs_h
|
#define FatStructs_h
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* FAT file structures
|
* FAT file structures
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* mostly from Microsoft document fatgen103.doc
|
* mostly from Microsoft document fatgen103.doc
|
||||||
* http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
* http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
||||||
*/
|
*/
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Value for byte 510 of boot block or MBR */
|
/** Value for byte 510 of boot block or MBR */
|
||||||
uint8_t const BOOTSIG0 = 0X55;
|
uint8_t const BOOTSIG0 = 0X55;
|
||||||
/** Value for byte 511 of boot block or MBR */
|
/** Value for byte 511 of boot block or MBR */
|
||||||
uint8_t const BOOTSIG1 = 0XAA;
|
uint8_t const BOOTSIG1 = 0XAA;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* \struct partitionTable
|
* \struct partitionTable
|
||||||
* \brief MBR partition table entry
|
* \brief MBR partition table entry
|
||||||
*
|
*
|
||||||
* A partition table entry for a MBR formatted storage device.
|
* A partition table entry for a MBR formatted storage device.
|
||||||
* The MBR partition table has four entries.
|
* The MBR partition table has four entries.
|
||||||
*/
|
*/
|
||||||
struct partitionTable {
|
struct partitionTable {
|
||||||
/**
|
/**
|
||||||
* Boot Indicator . Indicates whether the volume is the active
|
* Boot Indicator . Indicates whether the volume is the active
|
||||||
* partition. Legal values include: 0X00. Do not use for booting.
|
* partition. Legal values include: 0X00. Do not use for booting.
|
||||||
* 0X80 Active partition.
|
* 0X80 Active partition.
|
||||||
*/
|
*/
|
||||||
uint8_t boot;
|
uint8_t boot;
|
||||||
/**
|
/**
|
||||||
* Head part of Cylinder-head-sector address of the first block in
|
* 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.
|
* the partition. Legal values are 0-255. Only used in old PC BIOS.
|
||||||
*/
|
*/
|
||||||
uint8_t beginHead;
|
uint8_t beginHead;
|
||||||
/**
|
/**
|
||||||
* Sector part of Cylinder-head-sector address of the first block in
|
* 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.
|
* the partition. Legal values are 1-63. Only used in old PC BIOS.
|
||||||
*/
|
*/
|
||||||
unsigned beginSector : 6;
|
unsigned beginSector : 6;
|
||||||
/** High bits cylinder for first block in partition. */
|
/** High bits cylinder for first block in partition. */
|
||||||
unsigned beginCylinderHigh : 2;
|
unsigned beginCylinderHigh : 2;
|
||||||
/**
|
/**
|
||||||
* Combine beginCylinderLow with beginCylinderHigh. Legal values
|
* Combine beginCylinderLow with beginCylinderHigh. Legal values
|
||||||
* are 0-1023. Only used in old PC BIOS.
|
* are 0-1023. Only used in old PC BIOS.
|
||||||
*/
|
*/
|
||||||
uint8_t beginCylinderLow;
|
uint8_t beginCylinderLow;
|
||||||
/**
|
/**
|
||||||
* Partition type. See defines that begin with PART_TYPE_ for
|
* Partition type. See defines that begin with PART_TYPE_ for
|
||||||
* some Microsoft partition types.
|
* some Microsoft partition types.
|
||||||
*/
|
*/
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
/**
|
/**
|
||||||
* head part of cylinder-head-sector address of the last sector in the
|
* 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.
|
* partition. Legal values are 0-255. Only used in old PC BIOS.
|
||||||
*/
|
*/
|
||||||
uint8_t endHead;
|
uint8_t endHead;
|
||||||
/**
|
/**
|
||||||
* Sector part of cylinder-head-sector address of the last sector in
|
* 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.
|
* the partition. Legal values are 1-63. Only used in old PC BIOS.
|
||||||
*/
|
*/
|
||||||
unsigned endSector : 6;
|
unsigned endSector : 6;
|
||||||
/** High bits of end cylinder */
|
/** High bits of end cylinder */
|
||||||
unsigned endCylinderHigh : 2;
|
unsigned endCylinderHigh : 2;
|
||||||
/**
|
/**
|
||||||
* Combine endCylinderLow with endCylinderHigh. Legal values
|
* Combine endCylinderLow with endCylinderHigh. Legal values
|
||||||
* are 0-1023. Only used in old PC BIOS.
|
* are 0-1023. Only used in old PC BIOS.
|
||||||
*/
|
*/
|
||||||
uint8_t endCylinderLow;
|
uint8_t endCylinderLow;
|
||||||
/** Logical block address of the first block in the partition. */
|
/** Logical block address of the first block in the partition. */
|
||||||
uint32_t firstSector;
|
uint32_t firstSector;
|
||||||
/** Length of the partition, in blocks. */
|
/** Length of the partition, in blocks. */
|
||||||
uint32_t totalSectors;
|
uint32_t totalSectors;
|
||||||
};
|
};
|
||||||
/** Type name for partitionTable */
|
/** Type name for partitionTable */
|
||||||
typedef struct partitionTable part_t;
|
typedef struct partitionTable part_t;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* \struct masterBootRecord
|
* \struct masterBootRecord
|
||||||
*
|
*
|
||||||
* \brief Master Boot Record
|
* \brief Master Boot Record
|
||||||
*
|
*
|
||||||
* The first block of a storage device that is formatted with a MBR.
|
* The first block of a storage device that is formatted with a MBR.
|
||||||
*/
|
*/
|
||||||
struct masterBootRecord {
|
struct masterBootRecord {
|
||||||
/** Code Area for master boot program. */
|
/** Code Area for master boot program. */
|
||||||
uint8_t codeArea[440];
|
uint8_t codeArea[440];
|
||||||
/** Optional WindowsNT disk signature. May contain more boot code. */
|
/** Optional WindowsNT disk signature. May contain more boot code. */
|
||||||
uint32_t diskSignature;
|
uint32_t diskSignature;
|
||||||
/** Usually zero but may be more boot code. */
|
/** Usually zero but may be more boot code. */
|
||||||
uint16_t usuallyZero;
|
uint16_t usuallyZero;
|
||||||
/** Partition tables. */
|
/** Partition tables. */
|
||||||
part_t part[4];
|
part_t part[4];
|
||||||
/** First MBR signature byte. Must be 0X55 */
|
/** First MBR signature byte. Must be 0X55 */
|
||||||
uint8_t mbrSig0;
|
uint8_t mbrSig0;
|
||||||
/** Second MBR signature byte. Must be 0XAA */
|
/** Second MBR signature byte. Must be 0XAA */
|
||||||
uint8_t mbrSig1;
|
uint8_t mbrSig1;
|
||||||
};
|
};
|
||||||
/** Type name for masterBootRecord */
|
/** Type name for masterBootRecord */
|
||||||
typedef struct masterBootRecord mbr_t;
|
typedef struct masterBootRecord mbr_t;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* \struct biosParmBlock
|
* \struct biosParmBlock
|
||||||
*
|
*
|
||||||
* \brief BIOS parameter block
|
* \brief BIOS parameter block
|
||||||
*
|
*
|
||||||
* The BIOS parameter block describes the physical layout of a FAT volume.
|
* The BIOS parameter block describes the physical layout of a FAT volume.
|
||||||
*/
|
*/
|
||||||
struct biosParmBlock {
|
struct biosParmBlock {
|
||||||
/**
|
/**
|
||||||
* Count of bytes per sector. This value may take on only the
|
* Count of bytes per sector. This value may take on only the
|
||||||
* following values: 512, 1024, 2048 or 4096
|
* following values: 512, 1024, 2048 or 4096
|
||||||
*/
|
*/
|
||||||
uint16_t bytesPerSector;
|
uint16_t bytesPerSector;
|
||||||
/**
|
/**
|
||||||
* Number of sectors per allocation unit. This value must be a
|
* Number of sectors per allocation unit. This value must be a
|
||||||
* power of 2 that is greater than 0. The legal values are
|
* power of 2 that is greater than 0. The legal values are
|
||||||
* 1, 2, 4, 8, 16, 32, 64, and 128.
|
* 1, 2, 4, 8, 16, 32, 64, and 128.
|
||||||
*/
|
*/
|
||||||
uint8_t sectorsPerCluster;
|
uint8_t sectorsPerCluster;
|
||||||
/**
|
/**
|
||||||
* Number of sectors before the first FAT.
|
* Number of sectors before the first FAT.
|
||||||
* This value must not be zero.
|
* This value must not be zero.
|
||||||
*/
|
*/
|
||||||
uint16_t reservedSectorCount;
|
uint16_t reservedSectorCount;
|
||||||
/** The count of FAT data structures on the volume. This field should
|
/** The count of FAT data structures on the volume. This field should
|
||||||
* always contain the value 2 for any FAT volume of any type.
|
* always contain the value 2 for any FAT volume of any type.
|
||||||
*/
|
*/
|
||||||
uint8_t fatCount;
|
uint8_t fatCount;
|
||||||
/**
|
/**
|
||||||
* For FAT12 and FAT16 volumes, this field contains the count of
|
* For FAT12 and FAT16 volumes, this field contains the count of
|
||||||
* 32-byte directory entries in the root directory. For FAT32 volumes,
|
* 32-byte directory entries in the root directory. For FAT32 volumes,
|
||||||
* this field must be set to 0. For FAT12 and FAT16 volumes, this
|
* this field must be set to 0. For FAT12 and FAT16 volumes, this
|
||||||
* value should always specify a count that when multiplied by 32
|
* value should always specify a count that when multiplied by 32
|
||||||
* results in a multiple of bytesPerSector. FAT16 volumes should
|
* results in a multiple of bytesPerSector. FAT16 volumes should
|
||||||
* use the value 512.
|
* use the value 512.
|
||||||
*/
|
*/
|
||||||
uint16_t rootDirEntryCount;
|
uint16_t rootDirEntryCount;
|
||||||
/**
|
/**
|
||||||
* This field is the old 16-bit total count of sectors on the volume.
|
* 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
|
* 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
|
* 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
|
* must be non-zero. For FAT32 volumes, this field must be 0. For
|
||||||
* FAT12 and FAT16 volumes, this field contains the sector count, and
|
* FAT12 and FAT16 volumes, this field contains the sector count, and
|
||||||
* totalSectors32 is 0 if the total sector count fits
|
* totalSectors32 is 0 if the total sector count fits
|
||||||
* (is less than 0x10000).
|
* (is less than 0x10000).
|
||||||
*/
|
*/
|
||||||
uint16_t totalSectors16;
|
uint16_t totalSectors16;
|
||||||
/**
|
/**
|
||||||
* This dates back to the old MS-DOS 1.x media determination and is
|
* 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
|
* no longer usually used for anything. 0xF8 is the standard value
|
||||||
* for fixed (non-removable) media. For removable media, 0xF0 is
|
* for fixed (non-removable) media. For removable media, 0xF0 is
|
||||||
* frequently used. Legal values are 0xF0 or 0xF8-0xFF.
|
* frequently used. Legal values are 0xF0 or 0xF8-0xFF.
|
||||||
*/
|
*/
|
||||||
uint8_t mediaType;
|
uint8_t mediaType;
|
||||||
/**
|
/**
|
||||||
* Count of sectors occupied by one FAT on FAT12/FAT16 volumes.
|
* Count of sectors occupied by one FAT on FAT12/FAT16 volumes.
|
||||||
* On FAT32 volumes this field must be 0, and sectorsPerFat32
|
* On FAT32 volumes this field must be 0, and sectorsPerFat32
|
||||||
* contains the FAT size count.
|
* contains the FAT size count.
|
||||||
*/
|
*/
|
||||||
uint16_t sectorsPerFat16;
|
uint16_t sectorsPerFat16;
|
||||||
/** Sectors per track for interrupt 0x13. Not used otherwise. */
|
/** Sectors per track for interrupt 0x13. Not used otherwise. */
|
||||||
uint16_t sectorsPerTrtack;
|
uint16_t sectorsPerTrtack;
|
||||||
/** Number of heads for interrupt 0x13. Not used otherwise. */
|
/** Number of heads for interrupt 0x13. Not used otherwise. */
|
||||||
uint16_t headCount;
|
uint16_t headCount;
|
||||||
/**
|
/**
|
||||||
* Count of hidden sectors preceding the partition that contains this
|
* Count of hidden sectors preceding the partition that contains this
|
||||||
* FAT volume. This field is generally only relevant for media
|
* FAT volume. This field is generally only relevant for media
|
||||||
* visible on interrupt 0x13.
|
* visible on interrupt 0x13.
|
||||||
*/
|
*/
|
||||||
uint32_t hidddenSectors;
|
uint32_t hidddenSectors;
|
||||||
/**
|
/**
|
||||||
* This field is the new 32-bit total count of sectors on the volume.
|
* 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
|
* 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
|
* of the volume. This field can be 0; if it is 0, then
|
||||||
* totalSectors16 must be non-zero.
|
* totalSectors16 must be non-zero.
|
||||||
*/
|
*/
|
||||||
uint32_t totalSectors32;
|
uint32_t totalSectors32;
|
||||||
/**
|
/**
|
||||||
* Count of sectors occupied by one FAT on FAT32 volumes.
|
* Count of sectors occupied by one FAT on FAT32 volumes.
|
||||||
*/
|
*/
|
||||||
uint32_t sectorsPerFat32;
|
uint32_t sectorsPerFat32;
|
||||||
/**
|
/**
|
||||||
* This field is only defined for FAT32 media and does not exist on
|
* This field is only defined for FAT32 media and does not exist on
|
||||||
* FAT12 and FAT16 media.
|
* FAT12 and FAT16 media.
|
||||||
* Bits 0-3 -- Zero-based number of active FAT.
|
* Bits 0-3 -- Zero-based number of active FAT.
|
||||||
* Only valid if mirroring is disabled.
|
* Only valid if mirroring is disabled.
|
||||||
* Bits 4-6 -- Reserved.
|
* Bits 4-6 -- Reserved.
|
||||||
* Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs.
|
* 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.
|
* -- 1 means only one FAT is active; it is the one referenced in bits 0-3.
|
||||||
* Bits 8-15 -- Reserved.
|
* Bits 8-15 -- Reserved.
|
||||||
*/
|
*/
|
||||||
uint16_t fat32Flags;
|
uint16_t fat32Flags;
|
||||||
/**
|
/**
|
||||||
* FAT32 version. High byte is major revision number.
|
* FAT32 version. High byte is major revision number.
|
||||||
* Low byte is minor revision number. Only 0.0 define.
|
* Low byte is minor revision number. Only 0.0 define.
|
||||||
*/
|
*/
|
||||||
uint16_t fat32Version;
|
uint16_t fat32Version;
|
||||||
/**
|
/**
|
||||||
* Cluster number of the first cluster of the root directory for FAT32.
|
* Cluster number of the first cluster of the root directory for FAT32.
|
||||||
* This usually 2 but not required to be 2.
|
* This usually 2 but not required to be 2.
|
||||||
*/
|
*/
|
||||||
uint32_t fat32RootCluster;
|
uint32_t fat32RootCluster;
|
||||||
/**
|
/**
|
||||||
* Sector number of FSINFO structure in the reserved area of the
|
* Sector number of FSINFO structure in the reserved area of the
|
||||||
* FAT32 volume. Usually 1.
|
* FAT32 volume. Usually 1.
|
||||||
*/
|
*/
|
||||||
uint16_t fat32FSInfo;
|
uint16_t fat32FSInfo;
|
||||||
/**
|
/**
|
||||||
* If non-zero, indicates the sector number in the reserved area
|
* If non-zero, indicates the sector number in the reserved area
|
||||||
* of the volume of a copy of the boot record. Usually 6.
|
* of the volume of a copy of the boot record. Usually 6.
|
||||||
* No value other than 6 is recommended.
|
* No value other than 6 is recommended.
|
||||||
*/
|
*/
|
||||||
uint16_t fat32BackBootBlock;
|
uint16_t fat32BackBootBlock;
|
||||||
/**
|
/**
|
||||||
* Reserved for future expansion. Code that formats FAT32 volumes
|
* Reserved for future expansion. Code that formats FAT32 volumes
|
||||||
* should always set all of the bytes of this field to 0.
|
* should always set all of the bytes of this field to 0.
|
||||||
*/
|
*/
|
||||||
uint8_t fat32Reserved[12];
|
uint8_t fat32Reserved[12];
|
||||||
};
|
};
|
||||||
/** Type name for biosParmBlock */
|
/** Type name for biosParmBlock */
|
||||||
typedef struct biosParmBlock bpb_t;
|
typedef struct biosParmBlock bpb_t;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* \struct fat32BootSector
|
* \struct fat32BootSector
|
||||||
*
|
*
|
||||||
* \brief Boot sector for a FAT16 or FAT32 volume.
|
* \brief Boot sector for a FAT16 or FAT32 volume.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct fat32BootSector {
|
struct fat32BootSector {
|
||||||
/** X86 jmp to boot program */
|
/** X86 jmp to boot program */
|
||||||
uint8_t jmpToBootCode[3];
|
uint8_t jmpToBootCode[3];
|
||||||
/** informational only - don't depend on it */
|
/** informational only - don't depend on it */
|
||||||
char oemName[8];
|
char oemName[8];
|
||||||
/** BIOS Parameter Block */
|
/** BIOS Parameter Block */
|
||||||
bpb_t bpb;
|
bpb_t bpb;
|
||||||
/** for int0x13 use value 0X80 for hard drive */
|
/** for int0x13 use value 0X80 for hard drive */
|
||||||
uint8_t driveNumber;
|
uint8_t driveNumber;
|
||||||
/** used by Windows NT - should be zero for FAT */
|
/** used by Windows NT - should be zero for FAT */
|
||||||
uint8_t reserved1;
|
uint8_t reserved1;
|
||||||
/** 0X29 if next three fields are valid */
|
/** 0X29 if next three fields are valid */
|
||||||
uint8_t bootSignature;
|
uint8_t bootSignature;
|
||||||
/** usually generated by combining date and time */
|
/** usually generated by combining date and time */
|
||||||
uint32_t volumeSerialNumber;
|
uint32_t volumeSerialNumber;
|
||||||
/** should match volume label in root dir */
|
/** should match volume label in root dir */
|
||||||
char volumeLabel[11];
|
char volumeLabel[11];
|
||||||
/** informational only - don't depend on it */
|
/** informational only - don't depend on it */
|
||||||
char fileSystemType[8];
|
char fileSystemType[8];
|
||||||
/** X86 boot code */
|
/** X86 boot code */
|
||||||
uint8_t bootCode[420];
|
uint8_t bootCode[420];
|
||||||
/** must be 0X55 */
|
/** must be 0X55 */
|
||||||
uint8_t bootSectorSig0;
|
uint8_t bootSectorSig0;
|
||||||
/** must be 0XAA */
|
/** must be 0XAA */
|
||||||
uint8_t bootSectorSig1;
|
uint8_t bootSectorSig1;
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// End Of Chain values for FAT entries
|
// End Of Chain values for FAT entries
|
||||||
/** FAT16 end of chain value used by Microsoft. */
|
/** FAT16 end of chain value used by Microsoft. */
|
||||||
uint16_t const FAT16EOC = 0XFFFF;
|
uint16_t const FAT16EOC = 0XFFFF;
|
||||||
/** Minimum value for FAT16 EOC. Use to test for EOC. */
|
/** Minimum value for FAT16 EOC. Use to test for EOC. */
|
||||||
uint16_t const FAT16EOC_MIN = 0XFFF8;
|
uint16_t const FAT16EOC_MIN = 0XFFF8;
|
||||||
/** FAT32 end of chain value used by Microsoft. */
|
/** FAT32 end of chain value used by Microsoft. */
|
||||||
uint32_t const FAT32EOC = 0X0FFFFFFF;
|
uint32_t const FAT32EOC = 0X0FFFFFFF;
|
||||||
/** Minimum value for FAT32 EOC. Use to test for EOC. */
|
/** Minimum value for FAT32 EOC. Use to test for EOC. */
|
||||||
uint32_t const FAT32EOC_MIN = 0X0FFFFFF8;
|
uint32_t const FAT32EOC_MIN = 0X0FFFFFF8;
|
||||||
/** Mask a for FAT32 entry. Entries are 28 bits. */
|
/** Mask a for FAT32 entry. Entries are 28 bits. */
|
||||||
uint32_t const FAT32MASK = 0X0FFFFFFF;
|
uint32_t const FAT32MASK = 0X0FFFFFFF;
|
||||||
|
|
||||||
/** Type name for fat32BootSector */
|
/** Type name for fat32BootSector */
|
||||||
typedef struct fat32BootSector fbs_t;
|
typedef struct fat32BootSector fbs_t;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* \struct directoryEntry
|
* \struct directoryEntry
|
||||||
* \brief FAT short directory entry
|
* \brief FAT short directory entry
|
||||||
*
|
*
|
||||||
* Short means short 8.3 name, not the entry size.
|
* 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
|
* 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
|
* 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
|
* format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the
|
||||||
* 16-bit word):
|
* 16-bit word):
|
||||||
*
|
*
|
||||||
* Bits 9-15: Count of years from 1980, valid value range 0-127
|
* Bits 9-15: Count of years from 1980, valid value range 0-127
|
||||||
* inclusive (1980-2107).
|
* inclusive (1980-2107).
|
||||||
*
|
*
|
||||||
* Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive.
|
* 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.
|
* 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
|
* 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
|
* 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).
|
* 16-bit word, bit 15 is the MSB of the 16-bit word).
|
||||||
*
|
*
|
||||||
* Bits 11-15: Hours, valid value range 0-23 inclusive.
|
* Bits 11-15: Hours, valid value range 0-23 inclusive.
|
||||||
*
|
*
|
||||||
* Bits 5-10: Minutes, valid value range 0-59 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).
|
* 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.
|
* The valid time range is from Midnight 00:00:00 to 23:59:58.
|
||||||
*/
|
*/
|
||||||
struct directoryEntry {
|
struct directoryEntry {
|
||||||
/**
|
/**
|
||||||
* Short 8.3 name.
|
* Short 8.3 name.
|
||||||
* The first eight bytes contain the file name with blank fill.
|
* The first eight bytes contain the file name with blank fill.
|
||||||
* The last three bytes contain the file extension with blank fill.
|
* The last three bytes contain the file extension with blank fill.
|
||||||
*/
|
*/
|
||||||
uint8_t name[11];
|
uint8_t name[11];
|
||||||
/** Entry attributes.
|
/** Entry attributes.
|
||||||
*
|
*
|
||||||
* The upper two bits of the attribute byte are reserved and should
|
* 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
|
* 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_.
|
* looked at after that. See defines that begin with DIR_ATT_.
|
||||||
*/
|
*/
|
||||||
uint8_t attributes;
|
uint8_t attributes;
|
||||||
/**
|
/**
|
||||||
* Reserved for use by Windows NT. Set value to 0 when a file is
|
* Reserved for use by Windows NT. Set value to 0 when a file is
|
||||||
* created and never modify or look at it after that.
|
* created and never modify or look at it after that.
|
||||||
*/
|
*/
|
||||||
uint8_t reservedNT;
|
uint8_t reservedNT;
|
||||||
/**
|
/**
|
||||||
* The granularity of the seconds part of creationTime is 2 seconds
|
* 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
|
* 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)
|
* value range is 0-199 inclusive. (WHG note - seems to be hundredths)
|
||||||
*/
|
*/
|
||||||
uint8_t creationTimeTenths;
|
uint8_t creationTimeTenths;
|
||||||
/** Time file was created. */
|
/** Time file was created. */
|
||||||
uint16_t creationTime;
|
uint16_t creationTime;
|
||||||
/** Date file was created. */
|
/** Date file was created. */
|
||||||
uint16_t creationDate;
|
uint16_t creationDate;
|
||||||
/**
|
/**
|
||||||
* Last access date. Note that there is no last access time, only
|
* 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 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.
|
* a write, this should be set to the same date as lastWriteDate.
|
||||||
*/
|
*/
|
||||||
uint16_t lastAccessDate;
|
uint16_t lastAccessDate;
|
||||||
/**
|
/**
|
||||||
* High word of this entry's first cluster number (always 0 for a
|
* High word of this entry's first cluster number (always 0 for a
|
||||||
* FAT12 or FAT16 volume).
|
* FAT12 or FAT16 volume).
|
||||||
*/
|
*/
|
||||||
uint16_t firstClusterHigh;
|
uint16_t firstClusterHigh;
|
||||||
/** Time of last write. File creation is considered a write. */
|
/** Time of last write. File creation is considered a write. */
|
||||||
uint16_t lastWriteTime;
|
uint16_t lastWriteTime;
|
||||||
/** Date of last write. File creation is considered a write. */
|
/** Date of last write. File creation is considered a write. */
|
||||||
uint16_t lastWriteDate;
|
uint16_t lastWriteDate;
|
||||||
/** Low word of this entry's first cluster number. */
|
/** Low word of this entry's first cluster number. */
|
||||||
uint16_t firstClusterLow;
|
uint16_t firstClusterLow;
|
||||||
/** 32-bit unsigned holding this file's size in bytes. */
|
/** 32-bit unsigned holding this file's size in bytes. */
|
||||||
uint32_t fileSize;
|
uint32_t fileSize;
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Definitions for directory entries
|
// Definitions for directory entries
|
||||||
//
|
//
|
||||||
/** Type name for directoryEntry */
|
/** Type name for directoryEntry */
|
||||||
typedef struct directoryEntry dir_t;
|
typedef struct directoryEntry dir_t;
|
||||||
/** escape for name[0] = 0XE5 */
|
/** escape for name[0] = 0XE5 */
|
||||||
uint8_t const DIR_NAME_0XE5 = 0X05;
|
uint8_t const DIR_NAME_0XE5 = 0X05;
|
||||||
/** name[0] value for entry that is free after being "deleted" */
|
/** name[0] value for entry that is free after being "deleted" */
|
||||||
uint8_t const DIR_NAME_DELETED = 0XE5;
|
uint8_t const DIR_NAME_DELETED = 0XE5;
|
||||||
/** name[0] value for entry that is free and no allocated entries follow */
|
/** name[0] value for entry that is free and no allocated entries follow */
|
||||||
uint8_t const DIR_NAME_FREE = 0X00;
|
uint8_t const DIR_NAME_FREE = 0X00;
|
||||||
/** file is read-only */
|
/** file is read-only */
|
||||||
uint8_t const DIR_ATT_READ_ONLY = 0X01;
|
uint8_t const DIR_ATT_READ_ONLY = 0X01;
|
||||||
/** File should hidden in directory listings */
|
/** File should hidden in directory listings */
|
||||||
uint8_t const DIR_ATT_HIDDEN = 0X02;
|
uint8_t const DIR_ATT_HIDDEN = 0X02;
|
||||||
/** Entry is for a system file */
|
/** Entry is for a system file */
|
||||||
uint8_t const DIR_ATT_SYSTEM = 0X04;
|
uint8_t const DIR_ATT_SYSTEM = 0X04;
|
||||||
/** Directory entry contains the volume label */
|
/** Directory entry contains the volume label */
|
||||||
uint8_t const DIR_ATT_VOLUME_ID = 0X08;
|
uint8_t const DIR_ATT_VOLUME_ID = 0X08;
|
||||||
/** Entry is for a directory */
|
/** Entry is for a directory */
|
||||||
uint8_t const DIR_ATT_DIRECTORY = 0X10;
|
uint8_t const DIR_ATT_DIRECTORY = 0X10;
|
||||||
/** Old DOS archive bit for backup support */
|
/** Old DOS archive bit for backup support */
|
||||||
uint8_t const DIR_ATT_ARCHIVE = 0X20;
|
uint8_t const DIR_ATT_ARCHIVE = 0X20;
|
||||||
/** Test value for long name entry. Test is
|
/** Test value for long name entry. Test is
|
||||||
(d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */
|
(d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */
|
||||||
uint8_t const DIR_ATT_LONG_NAME = 0X0F;
|
uint8_t const DIR_ATT_LONG_NAME = 0X0F;
|
||||||
/** Test mask for long name entry */
|
/** Test mask for long name entry */
|
||||||
uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F;
|
uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F;
|
||||||
/** defined attribute bits */
|
/** defined attribute bits */
|
||||||
uint8_t const DIR_ATT_DEFINED_BITS = 0X3F;
|
uint8_t const DIR_ATT_DEFINED_BITS = 0X3F;
|
||||||
/** Directory entry is part of a long name */
|
/** Directory entry is part of a long name */
|
||||||
static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) {
|
static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) {
|
||||||
return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME;
|
return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME;
|
||||||
}
|
}
|
||||||
/** Mask for file/subdirectory tests */
|
/** Mask for file/subdirectory tests */
|
||||||
uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY);
|
uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY);
|
||||||
/** Directory entry is for a file */
|
/** Directory entry is for a file */
|
||||||
static inline uint8_t DIR_IS_FILE(const dir_t* dir) {
|
static inline uint8_t DIR_IS_FILE(const dir_t* dir) {
|
||||||
return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0;
|
return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0;
|
||||||
}
|
}
|
||||||
/** Directory entry is for a subdirectory */
|
/** Directory entry is for a subdirectory */
|
||||||
static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) {
|
static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) {
|
||||||
return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY;
|
return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY;
|
||||||
}
|
}
|
||||||
/** Directory entry is for a file or subdirectory */
|
/** Directory entry is for a file or subdirectory */
|
||||||
static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) {
|
static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) {
|
||||||
return (dir->attributes & DIR_ATT_VOLUME_ID) == 0;
|
return (dir->attributes & DIR_ATT_VOLUME_ID) == 0;
|
||||||
}
|
}
|
||||||
#endif // FatStructs_h
|
#endif // FatStructs_h
|
||||||
|
|
1286
Marlin/Sd2Card.cpp
1286
Marlin/Sd2Card.cpp
|
@ -1,643 +1,643 @@
|
||||||
/* Arduino Sd2Card Library
|
/* Arduino Sd2Card Library
|
||||||
* Copyright (C) 2009 by William Greiman
|
* Copyright (C) 2009 by William Greiman
|
||||||
*
|
*
|
||||||
* This file is part of the Arduino Sd2Card Library
|
* This file is part of the Arduino Sd2Card Library
|
||||||
*
|
*
|
||||||
* This Library is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This Library is distributed in the hope that it will be useful,
|
* This Library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with the Arduino Sd2Card Library. If not, see
|
* along with the Arduino Sd2Card Library. If not, see
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
#include "Sd2Card.h"
|
#include "Sd2Card.h"
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#ifndef SOFTWARE_SPI
|
#ifndef SOFTWARE_SPI
|
||||||
// functions for hardware SPI
|
// functions for hardware SPI
|
||||||
/** Send a byte to the card */
|
/** Send a byte to the card */
|
||||||
static void spiSend(uint8_t b) {
|
static void spiSend(uint8_t b) {
|
||||||
SPDR = b;
|
SPDR = b;
|
||||||
while (!(SPSR & (1 << SPIF)));
|
while (!(SPSR & (1 << SPIF)));
|
||||||
}
|
}
|
||||||
/** Receive a byte from the card */
|
/** Receive a byte from the card */
|
||||||
static uint8_t spiRec(void) {
|
static uint8_t spiRec(void) {
|
||||||
spiSend(0XFF);
|
spiSend(0XFF);
|
||||||
return SPDR;
|
return SPDR;
|
||||||
}
|
}
|
||||||
#else // SOFTWARE_SPI
|
#else // SOFTWARE_SPI
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** nop to tune soft SPI timing */
|
/** nop to tune soft SPI timing */
|
||||||
#define nop asm volatile ("nop\n\t")
|
#define nop asm volatile ("nop\n\t")
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Soft SPI receive */
|
/** Soft SPI receive */
|
||||||
uint8_t spiRec(void) {
|
uint8_t spiRec(void) {
|
||||||
uint8_t data = 0;
|
uint8_t data = 0;
|
||||||
// no interrupts during byte receive - about 8 us
|
// no interrupts during byte receive - about 8 us
|
||||||
cli();
|
cli();
|
||||||
// output pin high - like sending 0XFF
|
// output pin high - like sending 0XFF
|
||||||
fastDigitalWrite(SPI_MOSI_PIN, HIGH);
|
fastDigitalWrite(SPI_MOSI_PIN, HIGH);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 8; i++) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
fastDigitalWrite(SPI_SCK_PIN, HIGH);
|
fastDigitalWrite(SPI_SCK_PIN, HIGH);
|
||||||
|
|
||||||
// adjust so SCK is nice
|
// adjust so SCK is nice
|
||||||
nop;
|
nop;
|
||||||
nop;
|
nop;
|
||||||
|
|
||||||
data <<= 1;
|
data <<= 1;
|
||||||
|
|
||||||
if (fastDigitalRead(SPI_MISO_PIN)) data |= 1;
|
if (fastDigitalRead(SPI_MISO_PIN)) data |= 1;
|
||||||
|
|
||||||
fastDigitalWrite(SPI_SCK_PIN, LOW);
|
fastDigitalWrite(SPI_SCK_PIN, LOW);
|
||||||
}
|
}
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
sei();
|
sei();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Soft SPI send */
|
/** Soft SPI send */
|
||||||
void spiSend(uint8_t data) {
|
void spiSend(uint8_t data) {
|
||||||
// no interrupts during byte send - about 8 us
|
// no interrupts during byte send - about 8 us
|
||||||
cli();
|
cli();
|
||||||
for (uint8_t i = 0; i < 8; i++) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
fastDigitalWrite(SPI_SCK_PIN, LOW);
|
fastDigitalWrite(SPI_SCK_PIN, LOW);
|
||||||
|
|
||||||
fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
|
fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
|
||||||
|
|
||||||
data <<= 1;
|
data <<= 1;
|
||||||
|
|
||||||
fastDigitalWrite(SPI_SCK_PIN, HIGH);
|
fastDigitalWrite(SPI_SCK_PIN, HIGH);
|
||||||
}
|
}
|
||||||
// hold SCK high for a few ns
|
// hold SCK high for a few ns
|
||||||
nop;
|
nop;
|
||||||
nop;
|
nop;
|
||||||
nop;
|
nop;
|
||||||
nop;
|
nop;
|
||||||
|
|
||||||
fastDigitalWrite(SPI_SCK_PIN, LOW);
|
fastDigitalWrite(SPI_SCK_PIN, LOW);
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
#endif // SOFTWARE_SPI
|
#endif // SOFTWARE_SPI
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// send command and return error code. Return zero for OK
|
// send command and return error code. Return zero for OK
|
||||||
uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
|
uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
|
||||||
// end read if in partialBlockRead mode
|
// end read if in partialBlockRead mode
|
||||||
readEnd();
|
readEnd();
|
||||||
|
|
||||||
// select card
|
// select card
|
||||||
chipSelectLow();
|
chipSelectLow();
|
||||||
|
|
||||||
// wait up to 300 ms if busy
|
// wait up to 300 ms if busy
|
||||||
waitNotBusy(300);
|
waitNotBusy(300);
|
||||||
|
|
||||||
// send command
|
// send command
|
||||||
spiSend(cmd | 0x40);
|
spiSend(cmd | 0x40);
|
||||||
|
|
||||||
// send argument
|
// send argument
|
||||||
for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s);
|
for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s);
|
||||||
|
|
||||||
// send CRC
|
// send CRC
|
||||||
uint8_t crc = 0XFF;
|
uint8_t crc = 0XFF;
|
||||||
if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0
|
if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0
|
||||||
if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA
|
if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA
|
||||||
spiSend(crc);
|
spiSend(crc);
|
||||||
|
|
||||||
// wait for response
|
// wait for response
|
||||||
for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++);
|
for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++);
|
||||||
return status_;
|
return status_;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Determine the size of an SD flash memory card.
|
* Determine the size of an SD flash memory card.
|
||||||
*
|
*
|
||||||
* \return The number of 512 byte data blocks in the card
|
* \return The number of 512 byte data blocks in the card
|
||||||
* or zero if an error occurs.
|
* or zero if an error occurs.
|
||||||
*/
|
*/
|
||||||
uint32_t Sd2Card::cardSize(void) {
|
uint32_t Sd2Card::cardSize(void) {
|
||||||
csd_t csd;
|
csd_t csd;
|
||||||
if (!readCSD(&csd)) return 0;
|
if (!readCSD(&csd)) return 0;
|
||||||
if (csd.v1.csd_ver == 0) {
|
if (csd.v1.csd_ver == 0) {
|
||||||
uint8_t read_bl_len = csd.v1.read_bl_len;
|
uint8_t read_bl_len = csd.v1.read_bl_len;
|
||||||
uint16_t c_size = (csd.v1.c_size_high << 10)
|
uint16_t c_size = (csd.v1.c_size_high << 10)
|
||||||
| (csd.v1.c_size_mid << 2) | csd.v1.c_size_low;
|
| (csd.v1.c_size_mid << 2) | csd.v1.c_size_low;
|
||||||
uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1)
|
uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1)
|
||||||
| csd.v1.c_size_mult_low;
|
| csd.v1.c_size_mult_low;
|
||||||
return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7);
|
return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7);
|
||||||
} else if (csd.v2.csd_ver == 1) {
|
} else if (csd.v2.csd_ver == 1) {
|
||||||
uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16)
|
uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16)
|
||||||
| (csd.v2.c_size_mid << 8) | csd.v2.c_size_low;
|
| (csd.v2.c_size_mid << 8) | csd.v2.c_size_low;
|
||||||
return (c_size + 1) << 10;
|
return (c_size + 1) << 10;
|
||||||
} else {
|
} else {
|
||||||
error(SD_CARD_ERROR_BAD_CSD);
|
error(SD_CARD_ERROR_BAD_CSD);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void Sd2Card::chipSelectHigh(void) {
|
void Sd2Card::chipSelectHigh(void) {
|
||||||
digitalWrite(chipSelectPin_, HIGH);
|
digitalWrite(chipSelectPin_, HIGH);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void Sd2Card::chipSelectLow(void) {
|
void Sd2Card::chipSelectLow(void) {
|
||||||
digitalWrite(chipSelectPin_, LOW);
|
digitalWrite(chipSelectPin_, LOW);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Erase a range of blocks.
|
/** Erase a range of blocks.
|
||||||
*
|
*
|
||||||
* \param[in] firstBlock The address of the first block in the range.
|
* \param[in] firstBlock The address of the first block in the range.
|
||||||
* \param[in] lastBlock The address of the last block in the range.
|
* \param[in] lastBlock The address of the last block in the range.
|
||||||
*
|
*
|
||||||
* \note This function requests the SD card to do a flash erase for a
|
* \note This function requests the SD card to do a flash erase for a
|
||||||
* range of blocks. The data on the card after an erase operation is
|
* range of blocks. The data on the card after an erase operation is
|
||||||
* either 0 or 1, depends on the card vendor. The card must support
|
* either 0 or 1, depends on the card vendor. The card must support
|
||||||
* single block erase.
|
* single block erase.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
*/
|
*/
|
||||||
uint8_t Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
|
uint8_t Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
|
||||||
if (!eraseSingleBlockEnable()) {
|
if (!eraseSingleBlockEnable()) {
|
||||||
error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);
|
error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (type_ != SD_CARD_TYPE_SDHC) {
|
if (type_ != SD_CARD_TYPE_SDHC) {
|
||||||
firstBlock <<= 9;
|
firstBlock <<= 9;
|
||||||
lastBlock <<= 9;
|
lastBlock <<= 9;
|
||||||
}
|
}
|
||||||
if (cardCommand(CMD32, firstBlock)
|
if (cardCommand(CMD32, firstBlock)
|
||||||
|| cardCommand(CMD33, lastBlock)
|
|| cardCommand(CMD33, lastBlock)
|
||||||
|| cardCommand(CMD38, 0)) {
|
|| cardCommand(CMD38, 0)) {
|
||||||
error(SD_CARD_ERROR_ERASE);
|
error(SD_CARD_ERROR_ERASE);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!waitNotBusy(SD_ERASE_TIMEOUT)) {
|
if (!waitNotBusy(SD_ERASE_TIMEOUT)) {
|
||||||
error(SD_CARD_ERROR_ERASE_TIMEOUT);
|
error(SD_CARD_ERROR_ERASE_TIMEOUT);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Determine if card supports single block erase.
|
/** Determine if card supports single block erase.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned if single block erase is supported.
|
* \return The value one, true, is returned if single block erase is supported.
|
||||||
* The value zero, false, is returned if single block erase is not supported.
|
* The value zero, false, is returned if single block erase is not supported.
|
||||||
*/
|
*/
|
||||||
uint8_t Sd2Card::eraseSingleBlockEnable(void) {
|
uint8_t Sd2Card::eraseSingleBlockEnable(void) {
|
||||||
csd_t csd;
|
csd_t csd;
|
||||||
return readCSD(&csd) ? csd.v1.erase_blk_en : 0;
|
return readCSD(&csd) ? csd.v1.erase_blk_en : 0;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Initialize an SD flash memory card.
|
* Initialize an SD flash memory card.
|
||||||
*
|
*
|
||||||
* \param[in] sckRateID SPI clock rate selector. See setSckRate().
|
* \param[in] sckRateID SPI clock rate selector. See setSckRate().
|
||||||
* \param[in] chipSelectPin SD chip select pin number.
|
* \param[in] chipSelectPin SD chip select pin number.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure. The reason for failure
|
* the value zero, false, is returned for failure. The reason for failure
|
||||||
* can be determined by calling errorCode() and errorData().
|
* can be determined by calling errorCode() and errorData().
|
||||||
*/
|
*/
|
||||||
uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
|
uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
|
||||||
errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
|
errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
|
||||||
chipSelectPin_ = chipSelectPin;
|
chipSelectPin_ = chipSelectPin;
|
||||||
// 16-bit init start time allows over a minute
|
// 16-bit init start time allows over a minute
|
||||||
uint16_t t0 = (uint16_t)millis();
|
uint16_t t0 = (uint16_t)millis();
|
||||||
uint32_t arg;
|
uint32_t arg;
|
||||||
|
|
||||||
// set pin modes
|
// set pin modes
|
||||||
pinMode(chipSelectPin_, OUTPUT);
|
pinMode(chipSelectPin_, OUTPUT);
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
pinMode(SPI_MISO_PIN, INPUT);
|
pinMode(SPI_MISO_PIN, INPUT);
|
||||||
pinMode(SPI_MOSI_PIN, OUTPUT);
|
pinMode(SPI_MOSI_PIN, OUTPUT);
|
||||||
pinMode(SPI_SCK_PIN, OUTPUT);
|
pinMode(SPI_SCK_PIN, OUTPUT);
|
||||||
|
|
||||||
#ifndef SOFTWARE_SPI
|
#ifndef SOFTWARE_SPI
|
||||||
// SS must be in output mode even it is not chip select
|
// SS must be in output mode even it is not chip select
|
||||||
pinMode(SS_PIN, OUTPUT);
|
pinMode(SS_PIN, OUTPUT);
|
||||||
// Enable SPI, Master, clock rate f_osc/128
|
// Enable SPI, Master, clock rate f_osc/128
|
||||||
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
|
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
|
||||||
// clear double speed
|
// clear double speed
|
||||||
SPSR &= ~(1 << SPI2X);
|
SPSR &= ~(1 << SPI2X);
|
||||||
#endif // SOFTWARE_SPI
|
#endif // SOFTWARE_SPI
|
||||||
|
|
||||||
// must supply min of 74 clock cycles with CS high.
|
// must supply min of 74 clock cycles with CS high.
|
||||||
for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
|
for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
|
||||||
|
|
||||||
chipSelectLow();
|
chipSelectLow();
|
||||||
|
|
||||||
// command to go idle in SPI mode
|
// command to go idle in SPI mode
|
||||||
while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
|
while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
|
||||||
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
|
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
|
||||||
error(SD_CARD_ERROR_CMD0);
|
error(SD_CARD_ERROR_CMD0);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check SD version
|
// check SD version
|
||||||
if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
|
if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
|
||||||
type(SD_CARD_TYPE_SD1);
|
type(SD_CARD_TYPE_SD1);
|
||||||
} else {
|
} else {
|
||||||
// only need last byte of r7 response
|
// only need last byte of r7 response
|
||||||
for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
|
for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
|
||||||
if (status_ != 0XAA) {
|
if (status_ != 0XAA) {
|
||||||
error(SD_CARD_ERROR_CMD8);
|
error(SD_CARD_ERROR_CMD8);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
type(SD_CARD_TYPE_SD2);
|
type(SD_CARD_TYPE_SD2);
|
||||||
}
|
}
|
||||||
// initialize card and send host supports SDHC if SD2
|
// initialize card and send host supports SDHC if SD2
|
||||||
arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;
|
arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;
|
||||||
|
|
||||||
while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
|
while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
|
||||||
// check for timeout
|
// check for timeout
|
||||||
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
|
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
|
||||||
error(SD_CARD_ERROR_ACMD41);
|
error(SD_CARD_ERROR_ACMD41);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if SD2 read OCR register to check for SDHC card
|
// if SD2 read OCR register to check for SDHC card
|
||||||
if (type() == SD_CARD_TYPE_SD2) {
|
if (type() == SD_CARD_TYPE_SD2) {
|
||||||
if (cardCommand(CMD58, 0)) {
|
if (cardCommand(CMD58, 0)) {
|
||||||
error(SD_CARD_ERROR_CMD58);
|
error(SD_CARD_ERROR_CMD58);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC);
|
if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC);
|
||||||
// discard rest of ocr - contains allowed voltage range
|
// discard rest of ocr - contains allowed voltage range
|
||||||
for (uint8_t i = 0; i < 3; i++) spiRec();
|
for (uint8_t i = 0; i < 3; i++) spiRec();
|
||||||
}
|
}
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
|
|
||||||
#ifndef SOFTWARE_SPI
|
#ifndef SOFTWARE_SPI
|
||||||
return setSckRate(sckRateID);
|
return setSckRate(sckRateID);
|
||||||
#else // SOFTWARE_SPI
|
#else // SOFTWARE_SPI
|
||||||
return true;
|
return true;
|
||||||
#endif // SOFTWARE_SPI
|
#endif // SOFTWARE_SPI
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Enable or disable partial block reads.
|
* Enable or disable partial block reads.
|
||||||
*
|
*
|
||||||
* Enabling partial block reads improves performance by allowing a block
|
* Enabling partial block reads improves performance by allowing a block
|
||||||
* to be read over the SPI bus as several sub-blocks. Errors may occur
|
* to be read over the SPI bus as several sub-blocks. Errors may occur
|
||||||
* if the time between reads is too long since the SD card may timeout.
|
* if the time between reads is too long since the SD card may timeout.
|
||||||
* The SPI SS line will be held low until the entire block is read or
|
* The SPI SS line will be held low until the entire block is read or
|
||||||
* readEnd() is called.
|
* readEnd() is called.
|
||||||
*
|
*
|
||||||
* Use this for applications like the Adafruit Wave Shield.
|
* Use this for applications like the Adafruit Wave Shield.
|
||||||
*
|
*
|
||||||
* \param[in] value The value TRUE (non-zero) or FALSE (zero).)
|
* \param[in] value The value TRUE (non-zero) or FALSE (zero).)
|
||||||
*/
|
*/
|
||||||
void Sd2Card::partialBlockRead(uint8_t value) {
|
void Sd2Card::partialBlockRead(uint8_t value) {
|
||||||
readEnd();
|
readEnd();
|
||||||
partialBlockRead_ = value;
|
partialBlockRead_ = value;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Read a 512 byte block from an SD card device.
|
* Read a 512 byte block from an SD card device.
|
||||||
*
|
*
|
||||||
* \param[in] block Logical block to be read.
|
* \param[in] block Logical block to be read.
|
||||||
* \param[out] dst Pointer to the location that will receive the data.
|
* \param[out] dst Pointer to the location that will receive the data.
|
||||||
|
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
*/
|
*/
|
||||||
uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) {
|
uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) {
|
||||||
return readData(block, 0, 512, dst);
|
return readData(block, 0, 512, dst);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Read part of a 512 byte block from an SD card.
|
* Read part of a 512 byte block from an SD card.
|
||||||
*
|
*
|
||||||
* \param[in] block Logical block to be read.
|
* \param[in] block Logical block to be read.
|
||||||
* \param[in] offset Number of bytes to skip at start of block
|
* \param[in] offset Number of bytes to skip at start of block
|
||||||
* \param[out] dst Pointer to the location that will receive the data.
|
* \param[out] dst Pointer to the location that will receive the data.
|
||||||
* \param[in] count Number of bytes to read
|
* \param[in] count Number of bytes to read
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
*/
|
*/
|
||||||
uint8_t Sd2Card::readData(uint32_t block,
|
uint8_t Sd2Card::readData(uint32_t block,
|
||||||
uint16_t offset, uint16_t count, uint8_t* dst) {
|
uint16_t offset, uint16_t count, uint8_t* dst) {
|
||||||
uint16_t n;
|
uint16_t n;
|
||||||
if (count == 0) return true;
|
if (count == 0) return true;
|
||||||
if ((count + offset) > 512) {
|
if ((count + offset) > 512) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!inBlock_ || block != block_ || offset < offset_) {
|
if (!inBlock_ || block != block_ || offset < offset_) {
|
||||||
block_ = block;
|
block_ = block;
|
||||||
// use address if not SDHC card
|
// use address if not SDHC card
|
||||||
if (type()!= SD_CARD_TYPE_SDHC) block <<= 9;
|
if (type()!= SD_CARD_TYPE_SDHC) block <<= 9;
|
||||||
if (cardCommand(CMD17, block)) {
|
if (cardCommand(CMD17, block)) {
|
||||||
error(SD_CARD_ERROR_CMD17);
|
error(SD_CARD_ERROR_CMD17);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!waitStartBlock()) {
|
if (!waitStartBlock()) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
offset_ = 0;
|
offset_ = 0;
|
||||||
inBlock_ = 1;
|
inBlock_ = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPTIMIZE_HARDWARE_SPI
|
#ifdef OPTIMIZE_HARDWARE_SPI
|
||||||
// start first spi transfer
|
// start first spi transfer
|
||||||
SPDR = 0XFF;
|
SPDR = 0XFF;
|
||||||
|
|
||||||
// skip data before offset
|
// skip data before offset
|
||||||
for (;offset_ < offset; offset_++) {
|
for (;offset_ < offset; offset_++) {
|
||||||
while (!(SPSR & (1 << SPIF)));
|
while (!(SPSR & (1 << SPIF)));
|
||||||
SPDR = 0XFF;
|
SPDR = 0XFF;
|
||||||
}
|
}
|
||||||
// transfer data
|
// transfer data
|
||||||
n = count - 1;
|
n = count - 1;
|
||||||
for (uint16_t i = 0; i < n; i++) {
|
for (uint16_t i = 0; i < n; i++) {
|
||||||
while (!(SPSR & (1 << SPIF)));
|
while (!(SPSR & (1 << SPIF)));
|
||||||
dst[i] = SPDR;
|
dst[i] = SPDR;
|
||||||
SPDR = 0XFF;
|
SPDR = 0XFF;
|
||||||
}
|
}
|
||||||
// wait for last byte
|
// wait for last byte
|
||||||
while (!(SPSR & (1 << SPIF)));
|
while (!(SPSR & (1 << SPIF)));
|
||||||
dst[n] = SPDR;
|
dst[n] = SPDR;
|
||||||
|
|
||||||
#else // OPTIMIZE_HARDWARE_SPI
|
#else // OPTIMIZE_HARDWARE_SPI
|
||||||
|
|
||||||
// skip data before offset
|
// skip data before offset
|
||||||
for (;offset_ < offset; offset_++) {
|
for (;offset_ < offset; offset_++) {
|
||||||
spiRec();
|
spiRec();
|
||||||
}
|
}
|
||||||
// transfer data
|
// transfer data
|
||||||
for (uint16_t i = 0; i < count; i++) {
|
for (uint16_t i = 0; i < count; i++) {
|
||||||
dst[i] = spiRec();
|
dst[i] = spiRec();
|
||||||
}
|
}
|
||||||
#endif // OPTIMIZE_HARDWARE_SPI
|
#endif // OPTIMIZE_HARDWARE_SPI
|
||||||
|
|
||||||
offset_ += count;
|
offset_ += count;
|
||||||
if (!partialBlockRead_ || offset_ >= 512) {
|
if (!partialBlockRead_ || offset_ >= 512) {
|
||||||
// read rest of data, checksum and set chip select high
|
// read rest of data, checksum and set chip select high
|
||||||
readEnd();
|
readEnd();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Skip remaining data in a block when in partial block read mode. */
|
/** Skip remaining data in a block when in partial block read mode. */
|
||||||
void Sd2Card::readEnd(void) {
|
void Sd2Card::readEnd(void) {
|
||||||
if (inBlock_) {
|
if (inBlock_) {
|
||||||
// skip data and crc
|
// skip data and crc
|
||||||
#ifdef OPTIMIZE_HARDWARE_SPI
|
#ifdef OPTIMIZE_HARDWARE_SPI
|
||||||
// optimize skip for hardware
|
// optimize skip for hardware
|
||||||
SPDR = 0XFF;
|
SPDR = 0XFF;
|
||||||
while (offset_++ < 513) {
|
while (offset_++ < 513) {
|
||||||
while (!(SPSR & (1 << SPIF)));
|
while (!(SPSR & (1 << SPIF)));
|
||||||
SPDR = 0XFF;
|
SPDR = 0XFF;
|
||||||
}
|
}
|
||||||
// wait for last crc byte
|
// wait for last crc byte
|
||||||
while (!(SPSR & (1 << SPIF)));
|
while (!(SPSR & (1 << SPIF)));
|
||||||
#else // OPTIMIZE_HARDWARE_SPI
|
#else // OPTIMIZE_HARDWARE_SPI
|
||||||
while (offset_++ < 514) spiRec();
|
while (offset_++ < 514) spiRec();
|
||||||
#endif // OPTIMIZE_HARDWARE_SPI
|
#endif // OPTIMIZE_HARDWARE_SPI
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
inBlock_ = 0;
|
inBlock_ = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** read CID or CSR register */
|
/** read CID or CSR register */
|
||||||
uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
|
uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
|
||||||
uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
|
uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
|
||||||
if (cardCommand(cmd, 0)) {
|
if (cardCommand(cmd, 0)) {
|
||||||
error(SD_CARD_ERROR_READ_REG);
|
error(SD_CARD_ERROR_READ_REG);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!waitStartBlock()) goto fail;
|
if (!waitStartBlock()) goto fail;
|
||||||
// transfer data
|
// transfer data
|
||||||
for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec();
|
for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec();
|
||||||
spiRec(); // get first crc byte
|
spiRec(); // get first crc byte
|
||||||
spiRec(); // get second crc byte
|
spiRec(); // get second crc byte
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Set the SPI clock rate.
|
* Set the SPI clock rate.
|
||||||
*
|
*
|
||||||
* \param[in] sckRateID A value in the range [0, 6].
|
* \param[in] sckRateID A value in the range [0, 6].
|
||||||
*
|
*
|
||||||
* The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum
|
* The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum
|
||||||
* SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128
|
* SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128
|
||||||
* for \a scsRateID = 6.
|
* for \a scsRateID = 6.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and the value zero,
|
* \return The value one, true, is returned for success and the value zero,
|
||||||
* false, is returned for an invalid value of \a sckRateID.
|
* false, is returned for an invalid value of \a sckRateID.
|
||||||
*/
|
*/
|
||||||
uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
|
uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
|
||||||
if (sckRateID > 6) {
|
if (sckRateID > 6) {
|
||||||
error(SD_CARD_ERROR_SCK_RATE);
|
error(SD_CARD_ERROR_SCK_RATE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// see avr processor datasheet for SPI register bit definitions
|
// see avr processor datasheet for SPI register bit definitions
|
||||||
if ((sckRateID & 1) || sckRateID == 6) {
|
if ((sckRateID & 1) || sckRateID == 6) {
|
||||||
SPSR &= ~(1 << SPI2X);
|
SPSR &= ~(1 << SPI2X);
|
||||||
} else {
|
} else {
|
||||||
SPSR |= (1 << SPI2X);
|
SPSR |= (1 << SPI2X);
|
||||||
}
|
}
|
||||||
SPCR &= ~((1 <<SPR1) | (1 << SPR0));
|
SPCR &= ~((1 <<SPR1) | (1 << SPR0));
|
||||||
SPCR |= (sckRateID & 4 ? (1 << SPR1) : 0)
|
SPCR |= (sckRateID & 4 ? (1 << SPR1) : 0)
|
||||||
| (sckRateID & 2 ? (1 << SPR0) : 0);
|
| (sckRateID & 2 ? (1 << SPR0) : 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// wait for card to go not busy
|
// wait for card to go not busy
|
||||||
uint8_t Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
|
uint8_t Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
|
||||||
uint16_t t0 = millis();
|
uint16_t t0 = millis();
|
||||||
do {
|
do {
|
||||||
if (spiRec() == 0XFF) return true;
|
if (spiRec() == 0XFF) return true;
|
||||||
}
|
}
|
||||||
while (((uint16_t)millis() - t0) < timeoutMillis);
|
while (((uint16_t)millis() - t0) < timeoutMillis);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Wait for start block token */
|
/** Wait for start block token */
|
||||||
uint8_t Sd2Card::waitStartBlock(void) {
|
uint8_t Sd2Card::waitStartBlock(void) {
|
||||||
uint16_t t0 = millis();
|
uint16_t t0 = millis();
|
||||||
while ((status_ = spiRec()) == 0XFF) {
|
while ((status_ = spiRec()) == 0XFF) {
|
||||||
if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
|
if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
|
||||||
error(SD_CARD_ERROR_READ_TIMEOUT);
|
error(SD_CARD_ERROR_READ_TIMEOUT);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (status_ != DATA_START_BLOCK) {
|
if (status_ != DATA_START_BLOCK) {
|
||||||
error(SD_CARD_ERROR_READ);
|
error(SD_CARD_ERROR_READ);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Writes a 512 byte block to an SD card.
|
* Writes a 512 byte block to an SD card.
|
||||||
*
|
*
|
||||||
* \param[in] blockNumber Logical block to be written.
|
* \param[in] blockNumber Logical block to be written.
|
||||||
* \param[in] src Pointer to the location of the data to be written.
|
* \param[in] src Pointer to the location of the data to be written.
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
*/
|
*/
|
||||||
uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
|
uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
|
||||||
#if SD_PROTECT_BLOCK_ZERO
|
#if SD_PROTECT_BLOCK_ZERO
|
||||||
// don't allow write to first block
|
// don't allow write to first block
|
||||||
if (blockNumber == 0) {
|
if (blockNumber == 0) {
|
||||||
error(SD_CARD_ERROR_WRITE_BLOCK_ZERO);
|
error(SD_CARD_ERROR_WRITE_BLOCK_ZERO);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
#endif // SD_PROTECT_BLOCK_ZERO
|
#endif // SD_PROTECT_BLOCK_ZERO
|
||||||
|
|
||||||
// use address if not SDHC card
|
// use address if not SDHC card
|
||||||
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
|
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
|
||||||
if (cardCommand(CMD24, blockNumber)) {
|
if (cardCommand(CMD24, blockNumber)) {
|
||||||
error(SD_CARD_ERROR_CMD24);
|
error(SD_CARD_ERROR_CMD24);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!writeData(DATA_START_BLOCK, src)) goto fail;
|
if (!writeData(DATA_START_BLOCK, src)) goto fail;
|
||||||
|
|
||||||
// wait for flash programming to complete
|
// wait for flash programming to complete
|
||||||
if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
|
if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
|
||||||
error(SD_CARD_ERROR_WRITE_TIMEOUT);
|
error(SD_CARD_ERROR_WRITE_TIMEOUT);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
// response is r2 so get and check two bytes for nonzero
|
// response is r2 so get and check two bytes for nonzero
|
||||||
if (cardCommand(CMD13, 0) || spiRec()) {
|
if (cardCommand(CMD13, 0) || spiRec()) {
|
||||||
error(SD_CARD_ERROR_WRITE_PROGRAMMING);
|
error(SD_CARD_ERROR_WRITE_PROGRAMMING);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Write one data block in a multiple block write sequence */
|
/** Write one data block in a multiple block write sequence */
|
||||||
uint8_t Sd2Card::writeData(const uint8_t* src) {
|
uint8_t Sd2Card::writeData(const uint8_t* src) {
|
||||||
// wait for previous write to finish
|
// wait for previous write to finish
|
||||||
if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
|
if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
|
||||||
error(SD_CARD_ERROR_WRITE_MULTIPLE);
|
error(SD_CARD_ERROR_WRITE_MULTIPLE);
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return writeData(WRITE_MULTIPLE_TOKEN, src);
|
return writeData(WRITE_MULTIPLE_TOKEN, src);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// send one block of data for write block or write multiple blocks
|
// send one block of data for write block or write multiple blocks
|
||||||
uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {
|
uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {
|
||||||
#ifdef OPTIMIZE_HARDWARE_SPI
|
#ifdef OPTIMIZE_HARDWARE_SPI
|
||||||
|
|
||||||
// send data - optimized loop
|
// send data - optimized loop
|
||||||
SPDR = token;
|
SPDR = token;
|
||||||
|
|
||||||
// send two byte per iteration
|
// send two byte per iteration
|
||||||
for (uint16_t i = 0; i < 512; i += 2) {
|
for (uint16_t i = 0; i < 512; i += 2) {
|
||||||
while (!(SPSR & (1 << SPIF)));
|
while (!(SPSR & (1 << SPIF)));
|
||||||
SPDR = src[i];
|
SPDR = src[i];
|
||||||
while (!(SPSR & (1 << SPIF)));
|
while (!(SPSR & (1 << SPIF)));
|
||||||
SPDR = src[i+1];
|
SPDR = src[i+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for last data byte
|
// wait for last data byte
|
||||||
while (!(SPSR & (1 << SPIF)));
|
while (!(SPSR & (1 << SPIF)));
|
||||||
|
|
||||||
#else // OPTIMIZE_HARDWARE_SPI
|
#else // OPTIMIZE_HARDWARE_SPI
|
||||||
spiSend(token);
|
spiSend(token);
|
||||||
for (uint16_t i = 0; i < 512; i++) {
|
for (uint16_t i = 0; i < 512; i++) {
|
||||||
spiSend(src[i]);
|
spiSend(src[i]);
|
||||||
}
|
}
|
||||||
#endif // OPTIMIZE_HARDWARE_SPI
|
#endif // OPTIMIZE_HARDWARE_SPI
|
||||||
spiSend(0xff); // dummy crc
|
spiSend(0xff); // dummy crc
|
||||||
spiSend(0xff); // dummy crc
|
spiSend(0xff); // dummy crc
|
||||||
|
|
||||||
status_ = spiRec();
|
status_ = spiRec();
|
||||||
if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
|
if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
|
||||||
error(SD_CARD_ERROR_WRITE);
|
error(SD_CARD_ERROR_WRITE);
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Start a write multiple blocks sequence.
|
/** Start a write multiple blocks sequence.
|
||||||
*
|
*
|
||||||
* \param[in] blockNumber Address of first block in sequence.
|
* \param[in] blockNumber Address of first block in sequence.
|
||||||
* \param[in] eraseCount The number of blocks to be pre-erased.
|
* \param[in] eraseCount The number of blocks to be pre-erased.
|
||||||
*
|
*
|
||||||
* \note This function is used with writeData() and writeStop()
|
* \note This function is used with writeData() and writeStop()
|
||||||
* for optimized multiple block writes.
|
* for optimized multiple block writes.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
*/
|
*/
|
||||||
uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
|
uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
|
||||||
#if SD_PROTECT_BLOCK_ZERO
|
#if SD_PROTECT_BLOCK_ZERO
|
||||||
// don't allow write to first block
|
// don't allow write to first block
|
||||||
if (blockNumber == 0) {
|
if (blockNumber == 0) {
|
||||||
error(SD_CARD_ERROR_WRITE_BLOCK_ZERO);
|
error(SD_CARD_ERROR_WRITE_BLOCK_ZERO);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
#endif // SD_PROTECT_BLOCK_ZERO
|
#endif // SD_PROTECT_BLOCK_ZERO
|
||||||
// send pre-erase count
|
// send pre-erase count
|
||||||
if (cardAcmd(ACMD23, eraseCount)) {
|
if (cardAcmd(ACMD23, eraseCount)) {
|
||||||
error(SD_CARD_ERROR_ACMD23);
|
error(SD_CARD_ERROR_ACMD23);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
// use address if not SDHC card
|
// use address if not SDHC card
|
||||||
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
|
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
|
||||||
if (cardCommand(CMD25, blockNumber)) {
|
if (cardCommand(CMD25, blockNumber)) {
|
||||||
error(SD_CARD_ERROR_CMD25);
|
error(SD_CARD_ERROR_CMD25);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** End a write multiple blocks sequence.
|
/** End a write multiple blocks sequence.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
*/
|
*/
|
||||||
uint8_t Sd2Card::writeStop(void) {
|
uint8_t Sd2Card::writeStop(void) {
|
||||||
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
|
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
|
||||||
spiSend(STOP_TRAN_TOKEN);
|
spiSend(STOP_TRAN_TOKEN);
|
||||||
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
|
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
error(SD_CARD_ERROR_STOP_TRAN);
|
error(SD_CARD_ERROR_STOP_TRAN);
|
||||||
chipSelectHigh();
|
chipSelectHigh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
466
Marlin/Sd2Card.h
466
Marlin/Sd2Card.h
|
@ -1,233 +1,233 @@
|
||||||
/* Arduino Sd2Card Library
|
/* Arduino Sd2Card Library
|
||||||
* Copyright (C) 2009 by William Greiman
|
* Copyright (C) 2009 by William Greiman
|
||||||
*
|
*
|
||||||
* This file is part of the Arduino Sd2Card Library
|
* This file is part of the Arduino Sd2Card Library
|
||||||
*
|
*
|
||||||
* This Library is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This Library is distributed in the hope that it will be useful,
|
* This Library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with the Arduino Sd2Card Library. If not, see
|
* along with the Arduino Sd2Card Library. If not, see
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#ifndef Sd2Card_h
|
#ifndef Sd2Card_h
|
||||||
#define Sd2Card_h
|
#define Sd2Card_h
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* Sd2Card class
|
* Sd2Card class
|
||||||
*/
|
*/
|
||||||
#include "Sd2PinMap.h"
|
#include "Sd2PinMap.h"
|
||||||
#include "SdInfo.h"
|
#include "SdInfo.h"
|
||||||
/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */
|
/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */
|
||||||
uint8_t const SPI_FULL_SPEED = 0;
|
uint8_t const SPI_FULL_SPEED = 0;
|
||||||
/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */
|
/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */
|
||||||
uint8_t const SPI_HALF_SPEED = 1;
|
uint8_t const SPI_HALF_SPEED = 1;
|
||||||
/** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */
|
/** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */
|
||||||
uint8_t const SPI_QUARTER_SPEED = 2;
|
uint8_t const SPI_QUARTER_SPEED = 2;
|
||||||
/**
|
/**
|
||||||
* Define MEGA_SOFT_SPI non-zero to use software SPI on Mega Arduinos.
|
* 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.
|
* Pins used are SS 10, MOSI 11, MISO 12, and SCK 13.
|
||||||
*
|
*
|
||||||
* MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used
|
* MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used
|
||||||
* on Mega Arduinos. Software SPI works well with GPS Shield V1.1
|
* on Mega Arduinos. Software SPI works well with GPS Shield V1.1
|
||||||
* but many SD cards will fail with GPS Shield V1.0.
|
* but many SD cards will fail with GPS Shield V1.0.
|
||||||
*/
|
*/
|
||||||
#define MEGA_SOFT_SPI 0
|
#define MEGA_SOFT_SPI 0
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__))
|
#if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__))
|
||||||
#define SOFTWARE_SPI
|
#define SOFTWARE_SPI
|
||||||
#endif // MEGA_SOFT_SPI
|
#endif // MEGA_SOFT_SPI
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// SPI pin definitions
|
// SPI pin definitions
|
||||||
//
|
//
|
||||||
#ifndef SOFTWARE_SPI
|
#ifndef SOFTWARE_SPI
|
||||||
// hardware pin defs
|
// hardware pin defs
|
||||||
/**
|
/**
|
||||||
* SD Chip Select pin
|
* SD Chip Select pin
|
||||||
*
|
*
|
||||||
* Warning if this pin is redefined the hardware SS will pin will be enabled
|
* 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
|
* as an output by init(). An avr processor will not function as an SPI
|
||||||
* master unless SS is set to output mode.
|
* master unless SS is set to output mode.
|
||||||
*/
|
*/
|
||||||
/** The default chip select pin for the SD card is SS. */
|
/** The default chip select pin for the SD card is SS. */
|
||||||
uint8_t const SD_CHIP_SELECT_PIN = SS_PIN;
|
uint8_t const SD_CHIP_SELECT_PIN = SS_PIN;
|
||||||
// The following three pins must not be redefined for hardware SPI.
|
// The following three pins must not be redefined for hardware SPI.
|
||||||
/** SPI Master Out Slave In pin */
|
/** SPI Master Out Slave In pin */
|
||||||
uint8_t const SPI_MOSI_PIN = MOSI_PIN;
|
uint8_t const SPI_MOSI_PIN = MOSI_PIN;
|
||||||
/** SPI Master In Slave Out pin */
|
/** SPI Master In Slave Out pin */
|
||||||
uint8_t const SPI_MISO_PIN = MISO_PIN;
|
uint8_t const SPI_MISO_PIN = MISO_PIN;
|
||||||
/** SPI Clock pin */
|
/** SPI Clock pin */
|
||||||
uint8_t const SPI_SCK_PIN = SCK_PIN;
|
uint8_t const SPI_SCK_PIN = SCK_PIN;
|
||||||
/** optimize loops for hardware SPI */
|
/** optimize loops for hardware SPI */
|
||||||
#define OPTIMIZE_HARDWARE_SPI
|
#define OPTIMIZE_HARDWARE_SPI
|
||||||
|
|
||||||
#else // SOFTWARE_SPI
|
#else // SOFTWARE_SPI
|
||||||
// define software SPI pins so Mega can use unmodified GPS Shield
|
// define software SPI pins so Mega can use unmodified GPS Shield
|
||||||
/** SPI chip select pin */
|
/** SPI chip select pin */
|
||||||
uint8_t const SD_CHIP_SELECT_PIN = 10;
|
uint8_t const SD_CHIP_SELECT_PIN = 10;
|
||||||
/** SPI Master Out Slave In pin */
|
/** SPI Master Out Slave In pin */
|
||||||
uint8_t const SPI_MOSI_PIN = 11;
|
uint8_t const SPI_MOSI_PIN = 11;
|
||||||
/** SPI Master In Slave Out pin */
|
/** SPI Master In Slave Out pin */
|
||||||
uint8_t const SPI_MISO_PIN = 12;
|
uint8_t const SPI_MISO_PIN = 12;
|
||||||
/** SPI Clock pin */
|
/** SPI Clock pin */
|
||||||
uint8_t const SPI_SCK_PIN = 13;
|
uint8_t const SPI_SCK_PIN = 13;
|
||||||
#endif // SOFTWARE_SPI
|
#endif // SOFTWARE_SPI
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Protect block zero from write if nonzero */
|
/** Protect block zero from write if nonzero */
|
||||||
#define SD_PROTECT_BLOCK_ZERO 1
|
#define SD_PROTECT_BLOCK_ZERO 1
|
||||||
/** init timeout ms */
|
/** init timeout ms */
|
||||||
uint16_t const SD_INIT_TIMEOUT = 2000;
|
uint16_t const SD_INIT_TIMEOUT = 2000;
|
||||||
/** erase timeout ms */
|
/** erase timeout ms */
|
||||||
uint16_t const SD_ERASE_TIMEOUT = 10000;
|
uint16_t const SD_ERASE_TIMEOUT = 10000;
|
||||||
/** read timeout ms */
|
/** read timeout ms */
|
||||||
uint16_t const SD_READ_TIMEOUT = 300;
|
uint16_t const SD_READ_TIMEOUT = 300;
|
||||||
/** write time out ms */
|
/** write time out ms */
|
||||||
uint16_t const SD_WRITE_TIMEOUT = 600;
|
uint16_t const SD_WRITE_TIMEOUT = 600;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// SD card errors
|
// SD card errors
|
||||||
/** timeout error for command CMD0 */
|
/** timeout error for command CMD0 */
|
||||||
uint8_t const SD_CARD_ERROR_CMD0 = 0X1;
|
uint8_t const SD_CARD_ERROR_CMD0 = 0X1;
|
||||||
/** CMD8 was not accepted - not a valid SD card*/
|
/** CMD8 was not accepted - not a valid SD card*/
|
||||||
uint8_t const SD_CARD_ERROR_CMD8 = 0X2;
|
uint8_t const SD_CARD_ERROR_CMD8 = 0X2;
|
||||||
/** card returned an error response for CMD17 (read block) */
|
/** card returned an error response for CMD17 (read block) */
|
||||||
uint8_t const SD_CARD_ERROR_CMD17 = 0X3;
|
uint8_t const SD_CARD_ERROR_CMD17 = 0X3;
|
||||||
/** card returned an error response for CMD24 (write block) */
|
/** card returned an error response for CMD24 (write block) */
|
||||||
uint8_t const SD_CARD_ERROR_CMD24 = 0X4;
|
uint8_t const SD_CARD_ERROR_CMD24 = 0X4;
|
||||||
/** WRITE_MULTIPLE_BLOCKS command failed */
|
/** WRITE_MULTIPLE_BLOCKS command failed */
|
||||||
uint8_t const SD_CARD_ERROR_CMD25 = 0X05;
|
uint8_t const SD_CARD_ERROR_CMD25 = 0X05;
|
||||||
/** card returned an error response for CMD58 (read OCR) */
|
/** card returned an error response for CMD58 (read OCR) */
|
||||||
uint8_t const SD_CARD_ERROR_CMD58 = 0X06;
|
uint8_t const SD_CARD_ERROR_CMD58 = 0X06;
|
||||||
/** SET_WR_BLK_ERASE_COUNT failed */
|
/** SET_WR_BLK_ERASE_COUNT failed */
|
||||||
uint8_t const SD_CARD_ERROR_ACMD23 = 0X07;
|
uint8_t const SD_CARD_ERROR_ACMD23 = 0X07;
|
||||||
/** card's ACMD41 initialization process timeout */
|
/** card's ACMD41 initialization process timeout */
|
||||||
uint8_t const SD_CARD_ERROR_ACMD41 = 0X08;
|
uint8_t const SD_CARD_ERROR_ACMD41 = 0X08;
|
||||||
/** card returned a bad CSR version field */
|
/** card returned a bad CSR version field */
|
||||||
uint8_t const SD_CARD_ERROR_BAD_CSD = 0X09;
|
uint8_t const SD_CARD_ERROR_BAD_CSD = 0X09;
|
||||||
/** erase block group command failed */
|
/** erase block group command failed */
|
||||||
uint8_t const SD_CARD_ERROR_ERASE = 0X0A;
|
uint8_t const SD_CARD_ERROR_ERASE = 0X0A;
|
||||||
/** card not capable of single block erase */
|
/** card not capable of single block erase */
|
||||||
uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0X0B;
|
uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0X0B;
|
||||||
/** Erase sequence timed out */
|
/** Erase sequence timed out */
|
||||||
uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0X0C;
|
uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0X0C;
|
||||||
/** card returned an error token instead of read data */
|
/** card returned an error token instead of read data */
|
||||||
uint8_t const SD_CARD_ERROR_READ = 0X0D;
|
uint8_t const SD_CARD_ERROR_READ = 0X0D;
|
||||||
/** read CID or CSD failed */
|
/** read CID or CSD failed */
|
||||||
uint8_t const SD_CARD_ERROR_READ_REG = 0X0E;
|
uint8_t const SD_CARD_ERROR_READ_REG = 0X0E;
|
||||||
/** timeout while waiting for start of read data */
|
/** timeout while waiting for start of read data */
|
||||||
uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X0F;
|
uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X0F;
|
||||||
/** card did not accept STOP_TRAN_TOKEN */
|
/** card did not accept STOP_TRAN_TOKEN */
|
||||||
uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X10;
|
uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X10;
|
||||||
/** card returned an error token as a response to a write operation */
|
/** card returned an error token as a response to a write operation */
|
||||||
uint8_t const SD_CARD_ERROR_WRITE = 0X11;
|
uint8_t const SD_CARD_ERROR_WRITE = 0X11;
|
||||||
/** attempt to write protected block zero */
|
/** attempt to write protected block zero */
|
||||||
uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X12;
|
uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X12;
|
||||||
/** card did not go ready for a multiple block write */
|
/** card did not go ready for a multiple block write */
|
||||||
uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X13;
|
uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X13;
|
||||||
/** card returned an error to a CMD13 status check after a write */
|
/** card returned an error to a CMD13 status check after a write */
|
||||||
uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X14;
|
uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X14;
|
||||||
/** timeout occurred during write programming */
|
/** timeout occurred during write programming */
|
||||||
uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X15;
|
uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X15;
|
||||||
/** incorrect rate selected */
|
/** incorrect rate selected */
|
||||||
uint8_t const SD_CARD_ERROR_SCK_RATE = 0X16;
|
uint8_t const SD_CARD_ERROR_SCK_RATE = 0X16;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// card types
|
// card types
|
||||||
/** Standard capacity V1 SD card */
|
/** Standard capacity V1 SD card */
|
||||||
uint8_t const SD_CARD_TYPE_SD1 = 1;
|
uint8_t const SD_CARD_TYPE_SD1 = 1;
|
||||||
/** Standard capacity V2 SD card */
|
/** Standard capacity V2 SD card */
|
||||||
uint8_t const SD_CARD_TYPE_SD2 = 2;
|
uint8_t const SD_CARD_TYPE_SD2 = 2;
|
||||||
/** High Capacity SD card */
|
/** High Capacity SD card */
|
||||||
uint8_t const SD_CARD_TYPE_SDHC = 3;
|
uint8_t const SD_CARD_TYPE_SDHC = 3;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* \class Sd2Card
|
* \class Sd2Card
|
||||||
* \brief Raw access to SD and SDHC flash memory cards.
|
* \brief Raw access to SD and SDHC flash memory cards.
|
||||||
*/
|
*/
|
||||||
class Sd2Card {
|
class Sd2Card {
|
||||||
public:
|
public:
|
||||||
/** Construct an instance of Sd2Card. */
|
/** Construct an instance of Sd2Card. */
|
||||||
Sd2Card(void) : errorCode_(0), inBlock_(0), partialBlockRead_(0), type_(0) {}
|
Sd2Card(void) : errorCode_(0), inBlock_(0), partialBlockRead_(0), type_(0) {}
|
||||||
uint32_t cardSize(void);
|
uint32_t cardSize(void);
|
||||||
uint8_t erase(uint32_t firstBlock, uint32_t lastBlock);
|
uint8_t erase(uint32_t firstBlock, uint32_t lastBlock);
|
||||||
uint8_t eraseSingleBlockEnable(void);
|
uint8_t eraseSingleBlockEnable(void);
|
||||||
/**
|
/**
|
||||||
* \return error code for last error. See Sd2Card.h for a list of error codes.
|
* \return error code for last error. See Sd2Card.h for a list of error codes.
|
||||||
*/
|
*/
|
||||||
uint8_t errorCode(void) const {return errorCode_;}
|
uint8_t errorCode(void) const {return errorCode_;}
|
||||||
/** \return error data for last error. */
|
/** \return error data for last error. */
|
||||||
uint8_t errorData(void) const {return status_;}
|
uint8_t errorData(void) const {return status_;}
|
||||||
/**
|
/**
|
||||||
* Initialize an SD flash memory card with default clock rate and chip
|
* Initialize an SD flash memory card with default clock rate and chip
|
||||||
* select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
|
* select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
|
||||||
*/
|
*/
|
||||||
uint8_t init(void) {
|
uint8_t init(void) {
|
||||||
return init(SPI_FULL_SPEED, SD_CHIP_SELECT_PIN);
|
return init(SPI_FULL_SPEED, SD_CHIP_SELECT_PIN);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Initialize an SD flash memory card with the selected SPI clock rate
|
* Initialize an SD flash memory card with the selected SPI clock rate
|
||||||
* and the default SD chip select pin.
|
* and the default SD chip select pin.
|
||||||
* See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
|
* See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
|
||||||
*/
|
*/
|
||||||
uint8_t init(uint8_t sckRateID) {
|
uint8_t init(uint8_t sckRateID) {
|
||||||
return init(sckRateID, SD_CHIP_SELECT_PIN);
|
return init(sckRateID, SD_CHIP_SELECT_PIN);
|
||||||
}
|
}
|
||||||
uint8_t init(uint8_t sckRateID, uint8_t chipSelectPin);
|
uint8_t init(uint8_t sckRateID, uint8_t chipSelectPin);
|
||||||
void partialBlockRead(uint8_t value);
|
void partialBlockRead(uint8_t value);
|
||||||
/** Returns the current value, true or false, for partial block read. */
|
/** Returns the current value, true or false, for partial block read. */
|
||||||
uint8_t partialBlockRead(void) const {return partialBlockRead_;}
|
uint8_t partialBlockRead(void) const {return partialBlockRead_;}
|
||||||
uint8_t readBlock(uint32_t block, uint8_t* dst);
|
uint8_t readBlock(uint32_t block, uint8_t* dst);
|
||||||
uint8_t readData(uint32_t block,
|
uint8_t readData(uint32_t block,
|
||||||
uint16_t offset, uint16_t count, uint8_t* dst);
|
uint16_t offset, uint16_t count, uint8_t* dst);
|
||||||
/**
|
/**
|
||||||
* Read a cards CID register. The CID contains card identification
|
* Read a cards CID register. The CID contains card identification
|
||||||
* information such as Manufacturer ID, Product name, Product serial
|
* information such as Manufacturer ID, Product name, Product serial
|
||||||
* number and Manufacturing date. */
|
* number and Manufacturing date. */
|
||||||
uint8_t readCID(cid_t* cid) {
|
uint8_t readCID(cid_t* cid) {
|
||||||
return readRegister(CMD10, cid);
|
return readRegister(CMD10, cid);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Read a cards CSD register. The CSD contains Card-Specific Data that
|
* Read a cards CSD register. The CSD contains Card-Specific Data that
|
||||||
* provides information regarding access to the card's contents. */
|
* provides information regarding access to the card's contents. */
|
||||||
uint8_t readCSD(csd_t* csd) {
|
uint8_t readCSD(csd_t* csd) {
|
||||||
return readRegister(CMD9, csd);
|
return readRegister(CMD9, csd);
|
||||||
}
|
}
|
||||||
void readEnd(void);
|
void readEnd(void);
|
||||||
uint8_t setSckRate(uint8_t sckRateID);
|
uint8_t setSckRate(uint8_t sckRateID);
|
||||||
/** Return the card type: SD V1, SD V2 or SDHC */
|
/** Return the card type: SD V1, SD V2 or SDHC */
|
||||||
uint8_t type(void) const {return type_;}
|
uint8_t type(void) const {return type_;}
|
||||||
uint8_t writeBlock(uint32_t blockNumber, const uint8_t* src);
|
uint8_t writeBlock(uint32_t blockNumber, const uint8_t* src);
|
||||||
uint8_t writeData(const uint8_t* src);
|
uint8_t writeData(const uint8_t* src);
|
||||||
uint8_t writeStart(uint32_t blockNumber, uint32_t eraseCount);
|
uint8_t writeStart(uint32_t blockNumber, uint32_t eraseCount);
|
||||||
uint8_t writeStop(void);
|
uint8_t writeStop(void);
|
||||||
private:
|
private:
|
||||||
uint32_t block_;
|
uint32_t block_;
|
||||||
uint8_t chipSelectPin_;
|
uint8_t chipSelectPin_;
|
||||||
uint8_t errorCode_;
|
uint8_t errorCode_;
|
||||||
uint8_t inBlock_;
|
uint8_t inBlock_;
|
||||||
uint16_t offset_;
|
uint16_t offset_;
|
||||||
uint8_t partialBlockRead_;
|
uint8_t partialBlockRead_;
|
||||||
uint8_t status_;
|
uint8_t status_;
|
||||||
uint8_t type_;
|
uint8_t type_;
|
||||||
// private functions
|
// private functions
|
||||||
uint8_t cardAcmd(uint8_t cmd, uint32_t arg) {
|
uint8_t cardAcmd(uint8_t cmd, uint32_t arg) {
|
||||||
cardCommand(CMD55, 0);
|
cardCommand(CMD55, 0);
|
||||||
return cardCommand(cmd, arg);
|
return cardCommand(cmd, arg);
|
||||||
}
|
}
|
||||||
uint8_t cardCommand(uint8_t cmd, uint32_t arg);
|
uint8_t cardCommand(uint8_t cmd, uint32_t arg);
|
||||||
void error(uint8_t code) {errorCode_ = code;}
|
void error(uint8_t code) {errorCode_ = code;}
|
||||||
uint8_t readRegister(uint8_t cmd, void* buf);
|
uint8_t readRegister(uint8_t cmd, void* buf);
|
||||||
uint8_t sendWriteCommand(uint32_t blockNumber, uint32_t eraseCount);
|
uint8_t sendWriteCommand(uint32_t blockNumber, uint32_t eraseCount);
|
||||||
void chipSelectHigh(void);
|
void chipSelectHigh(void);
|
||||||
void chipSelectLow(void);
|
void chipSelectLow(void);
|
||||||
void type(uint8_t value) {type_ = value;}
|
void type(uint8_t value) {type_ = value;}
|
||||||
uint8_t waitNotBusy(uint16_t timeoutMillis);
|
uint8_t waitNotBusy(uint16_t timeoutMillis);
|
||||||
uint8_t writeData(uint8_t token, const uint8_t* src);
|
uint8_t writeData(uint8_t token, const uint8_t* src);
|
||||||
uint8_t waitStartBlock(void);
|
uint8_t waitStartBlock(void);
|
||||||
};
|
};
|
||||||
#endif // Sd2Card_h
|
#endif // Sd2Card_h
|
||||||
|
|
|
@ -1,353 +1,353 @@
|
||||||
/* Arduino SdFat Library
|
/* Arduino SdFat Library
|
||||||
* Copyright (C) 2010 by William Greiman
|
* Copyright (C) 2010 by William Greiman
|
||||||
*
|
*
|
||||||
* This file is part of the Arduino SdFat Library
|
* This file is part of the Arduino SdFat Library
|
||||||
*
|
*
|
||||||
* This Library is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This Library is distributed in the hope that it will be useful,
|
* This Library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with the Arduino SdFat Library. If not, see
|
* along with the Arduino SdFat Library. If not, see
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
// Warning this file was generated by a program.
|
// Warning this file was generated by a program.
|
||||||
#ifndef Sd2PinMap_h
|
#ifndef Sd2PinMap_h
|
||||||
#define Sd2PinMap_h
|
#define Sd2PinMap_h
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** struct for mapping digital pins */
|
/** struct for mapping digital pins */
|
||||||
struct pin_map_t {
|
struct pin_map_t {
|
||||||
volatile uint8_t* ddr;
|
volatile uint8_t* ddr;
|
||||||
volatile uint8_t* pin;
|
volatile uint8_t* pin;
|
||||||
volatile uint8_t* port;
|
volatile uint8_t* port;
|
||||||
uint8_t bit;
|
uint8_t bit;
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
// Mega
|
// Mega
|
||||||
|
|
||||||
// Two Wire (aka I2C) ports
|
// Two Wire (aka I2C) ports
|
||||||
uint8_t const SDA_PIN = 20;
|
uint8_t const SDA_PIN = 20;
|
||||||
uint8_t const SCL_PIN = 21;
|
uint8_t const SCL_PIN = 21;
|
||||||
|
|
||||||
// SPI port
|
// SPI port
|
||||||
uint8_t const SS_PIN = 53;
|
uint8_t const SS_PIN = 53;
|
||||||
uint8_t const MOSI_PIN = 51;
|
uint8_t const MOSI_PIN = 51;
|
||||||
uint8_t const MISO_PIN = 50;
|
uint8_t const MISO_PIN = 50;
|
||||||
uint8_t const SCK_PIN = 52;
|
uint8_t const SCK_PIN = 52;
|
||||||
|
|
||||||
static const pin_map_t digitalPinMap[] = {
|
static const pin_map_t digitalPinMap[] = {
|
||||||
{&DDRE, &PINE, &PORTE, 0}, // E0 0
|
{&DDRE, &PINE, &PORTE, 0}, // E0 0
|
||||||
{&DDRE, &PINE, &PORTE, 1}, // E1 1
|
{&DDRE, &PINE, &PORTE, 1}, // E1 1
|
||||||
{&DDRE, &PINE, &PORTE, 4}, // E4 2
|
{&DDRE, &PINE, &PORTE, 4}, // E4 2
|
||||||
{&DDRE, &PINE, &PORTE, 5}, // E5 3
|
{&DDRE, &PINE, &PORTE, 5}, // E5 3
|
||||||
{&DDRG, &PING, &PORTG, 5}, // G5 4
|
{&DDRG, &PING, &PORTG, 5}, // G5 4
|
||||||
{&DDRE, &PINE, &PORTE, 3}, // E3 5
|
{&DDRE, &PINE, &PORTE, 3}, // E3 5
|
||||||
{&DDRH, &PINH, &PORTH, 3}, // H3 6
|
{&DDRH, &PINH, &PORTH, 3}, // H3 6
|
||||||
{&DDRH, &PINH, &PORTH, 4}, // H4 7
|
{&DDRH, &PINH, &PORTH, 4}, // H4 7
|
||||||
{&DDRH, &PINH, &PORTH, 5}, // H5 8
|
{&DDRH, &PINH, &PORTH, 5}, // H5 8
|
||||||
{&DDRH, &PINH, &PORTH, 6}, // H6 9
|
{&DDRH, &PINH, &PORTH, 6}, // H6 9
|
||||||
{&DDRB, &PINB, &PORTB, 4}, // B4 10
|
{&DDRB, &PINB, &PORTB, 4}, // B4 10
|
||||||
{&DDRB, &PINB, &PORTB, 5}, // B5 11
|
{&DDRB, &PINB, &PORTB, 5}, // B5 11
|
||||||
{&DDRB, &PINB, &PORTB, 6}, // B6 12
|
{&DDRB, &PINB, &PORTB, 6}, // B6 12
|
||||||
{&DDRB, &PINB, &PORTB, 7}, // B7 13
|
{&DDRB, &PINB, &PORTB, 7}, // B7 13
|
||||||
{&DDRJ, &PINJ, &PORTJ, 1}, // J1 14
|
{&DDRJ, &PINJ, &PORTJ, 1}, // J1 14
|
||||||
{&DDRJ, &PINJ, &PORTJ, 0}, // J0 15
|
{&DDRJ, &PINJ, &PORTJ, 0}, // J0 15
|
||||||
{&DDRH, &PINH, &PORTH, 1}, // H1 16
|
{&DDRH, &PINH, &PORTH, 1}, // H1 16
|
||||||
{&DDRH, &PINH, &PORTH, 0}, // H0 17
|
{&DDRH, &PINH, &PORTH, 0}, // H0 17
|
||||||
{&DDRD, &PIND, &PORTD, 3}, // D3 18
|
{&DDRD, &PIND, &PORTD, 3}, // D3 18
|
||||||
{&DDRD, &PIND, &PORTD, 2}, // D2 19
|
{&DDRD, &PIND, &PORTD, 2}, // D2 19
|
||||||
{&DDRD, &PIND, &PORTD, 1}, // D1 20
|
{&DDRD, &PIND, &PORTD, 1}, // D1 20
|
||||||
{&DDRD, &PIND, &PORTD, 0}, // D0 21
|
{&DDRD, &PIND, &PORTD, 0}, // D0 21
|
||||||
{&DDRA, &PINA, &PORTA, 0}, // A0 22
|
{&DDRA, &PINA, &PORTA, 0}, // A0 22
|
||||||
{&DDRA, &PINA, &PORTA, 1}, // A1 23
|
{&DDRA, &PINA, &PORTA, 1}, // A1 23
|
||||||
{&DDRA, &PINA, &PORTA, 2}, // A2 24
|
{&DDRA, &PINA, &PORTA, 2}, // A2 24
|
||||||
{&DDRA, &PINA, &PORTA, 3}, // A3 25
|
{&DDRA, &PINA, &PORTA, 3}, // A3 25
|
||||||
{&DDRA, &PINA, &PORTA, 4}, // A4 26
|
{&DDRA, &PINA, &PORTA, 4}, // A4 26
|
||||||
{&DDRA, &PINA, &PORTA, 5}, // A5 27
|
{&DDRA, &PINA, &PORTA, 5}, // A5 27
|
||||||
{&DDRA, &PINA, &PORTA, 6}, // A6 28
|
{&DDRA, &PINA, &PORTA, 6}, // A6 28
|
||||||
{&DDRA, &PINA, &PORTA, 7}, // A7 29
|
{&DDRA, &PINA, &PORTA, 7}, // A7 29
|
||||||
{&DDRC, &PINC, &PORTC, 7}, // C7 30
|
{&DDRC, &PINC, &PORTC, 7}, // C7 30
|
||||||
{&DDRC, &PINC, &PORTC, 6}, // C6 31
|
{&DDRC, &PINC, &PORTC, 6}, // C6 31
|
||||||
{&DDRC, &PINC, &PORTC, 5}, // C5 32
|
{&DDRC, &PINC, &PORTC, 5}, // C5 32
|
||||||
{&DDRC, &PINC, &PORTC, 4}, // C4 33
|
{&DDRC, &PINC, &PORTC, 4}, // C4 33
|
||||||
{&DDRC, &PINC, &PORTC, 3}, // C3 34
|
{&DDRC, &PINC, &PORTC, 3}, // C3 34
|
||||||
{&DDRC, &PINC, &PORTC, 2}, // C2 35
|
{&DDRC, &PINC, &PORTC, 2}, // C2 35
|
||||||
{&DDRC, &PINC, &PORTC, 1}, // C1 36
|
{&DDRC, &PINC, &PORTC, 1}, // C1 36
|
||||||
{&DDRC, &PINC, &PORTC, 0}, // C0 37
|
{&DDRC, &PINC, &PORTC, 0}, // C0 37
|
||||||
{&DDRD, &PIND, &PORTD, 7}, // D7 38
|
{&DDRD, &PIND, &PORTD, 7}, // D7 38
|
||||||
{&DDRG, &PING, &PORTG, 2}, // G2 39
|
{&DDRG, &PING, &PORTG, 2}, // G2 39
|
||||||
{&DDRG, &PING, &PORTG, 1}, // G1 40
|
{&DDRG, &PING, &PORTG, 1}, // G1 40
|
||||||
{&DDRG, &PING, &PORTG, 0}, // G0 41
|
{&DDRG, &PING, &PORTG, 0}, // G0 41
|
||||||
{&DDRL, &PINL, &PORTL, 7}, // L7 42
|
{&DDRL, &PINL, &PORTL, 7}, // L7 42
|
||||||
{&DDRL, &PINL, &PORTL, 6}, // L6 43
|
{&DDRL, &PINL, &PORTL, 6}, // L6 43
|
||||||
{&DDRL, &PINL, &PORTL, 5}, // L5 44
|
{&DDRL, &PINL, &PORTL, 5}, // L5 44
|
||||||
{&DDRL, &PINL, &PORTL, 4}, // L4 45
|
{&DDRL, &PINL, &PORTL, 4}, // L4 45
|
||||||
{&DDRL, &PINL, &PORTL, 3}, // L3 46
|
{&DDRL, &PINL, &PORTL, 3}, // L3 46
|
||||||
{&DDRL, &PINL, &PORTL, 2}, // L2 47
|
{&DDRL, &PINL, &PORTL, 2}, // L2 47
|
||||||
{&DDRL, &PINL, &PORTL, 1}, // L1 48
|
{&DDRL, &PINL, &PORTL, 1}, // L1 48
|
||||||
{&DDRL, &PINL, &PORTL, 0}, // L0 49
|
{&DDRL, &PINL, &PORTL, 0}, // L0 49
|
||||||
{&DDRB, &PINB, &PORTB, 3}, // B3 50
|
{&DDRB, &PINB, &PORTB, 3}, // B3 50
|
||||||
{&DDRB, &PINB, &PORTB, 2}, // B2 51
|
{&DDRB, &PINB, &PORTB, 2}, // B2 51
|
||||||
{&DDRB, &PINB, &PORTB, 1}, // B1 52
|
{&DDRB, &PINB, &PORTB, 1}, // B1 52
|
||||||
{&DDRB, &PINB, &PORTB, 0}, // B0 53
|
{&DDRB, &PINB, &PORTB, 0}, // B0 53
|
||||||
{&DDRF, &PINF, &PORTF, 0}, // F0 54
|
{&DDRF, &PINF, &PORTF, 0}, // F0 54
|
||||||
{&DDRF, &PINF, &PORTF, 1}, // F1 55
|
{&DDRF, &PINF, &PORTF, 1}, // F1 55
|
||||||
{&DDRF, &PINF, &PORTF, 2}, // F2 56
|
{&DDRF, &PINF, &PORTF, 2}, // F2 56
|
||||||
{&DDRF, &PINF, &PORTF, 3}, // F3 57
|
{&DDRF, &PINF, &PORTF, 3}, // F3 57
|
||||||
{&DDRF, &PINF, &PORTF, 4}, // F4 58
|
{&DDRF, &PINF, &PORTF, 4}, // F4 58
|
||||||
{&DDRF, &PINF, &PORTF, 5}, // F5 59
|
{&DDRF, &PINF, &PORTF, 5}, // F5 59
|
||||||
{&DDRF, &PINF, &PORTF, 6}, // F6 60
|
{&DDRF, &PINF, &PORTF, 6}, // F6 60
|
||||||
{&DDRF, &PINF, &PORTF, 7}, // F7 61
|
{&DDRF, &PINF, &PORTF, 7}, // F7 61
|
||||||
{&DDRK, &PINK, &PORTK, 0}, // K0 62
|
{&DDRK, &PINK, &PORTK, 0}, // K0 62
|
||||||
{&DDRK, &PINK, &PORTK, 1}, // K1 63
|
{&DDRK, &PINK, &PORTK, 1}, // K1 63
|
||||||
{&DDRK, &PINK, &PORTK, 2}, // K2 64
|
{&DDRK, &PINK, &PORTK, 2}, // K2 64
|
||||||
{&DDRK, &PINK, &PORTK, 3}, // K3 65
|
{&DDRK, &PINK, &PORTK, 3}, // K3 65
|
||||||
{&DDRK, &PINK, &PORTK, 4}, // K4 66
|
{&DDRK, &PINK, &PORTK, 4}, // K4 66
|
||||||
{&DDRK, &PINK, &PORTK, 5}, // K5 67
|
{&DDRK, &PINK, &PORTK, 5}, // K5 67
|
||||||
{&DDRK, &PINK, &PORTK, 6}, // K6 68
|
{&DDRK, &PINK, &PORTK, 6}, // K6 68
|
||||||
{&DDRK, &PINK, &PORTK, 7} // K7 69
|
{&DDRK, &PINK, &PORTK, 7} // K7 69
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||||
// Sanguino
|
// Sanguino
|
||||||
|
|
||||||
// Two Wire (aka I2C) ports
|
// Two Wire (aka I2C) ports
|
||||||
uint8_t const SDA_PIN = 17;
|
uint8_t const SDA_PIN = 17;
|
||||||
uint8_t const SCL_PIN = 18;
|
uint8_t const SCL_PIN = 18;
|
||||||
|
|
||||||
// SPI port
|
// SPI port
|
||||||
uint8_t const SS_PIN = 4;
|
uint8_t const SS_PIN = 4;
|
||||||
uint8_t const MOSI_PIN = 5;
|
uint8_t const MOSI_PIN = 5;
|
||||||
uint8_t const MISO_PIN = 6;
|
uint8_t const MISO_PIN = 6;
|
||||||
uint8_t const SCK_PIN = 7;
|
uint8_t const SCK_PIN = 7;
|
||||||
|
|
||||||
static const pin_map_t digitalPinMap[] = {
|
static const pin_map_t digitalPinMap[] = {
|
||||||
{&DDRB, &PINB, &PORTB, 0}, // B0 0
|
{&DDRB, &PINB, &PORTB, 0}, // B0 0
|
||||||
{&DDRB, &PINB, &PORTB, 1}, // B1 1
|
{&DDRB, &PINB, &PORTB, 1}, // B1 1
|
||||||
{&DDRB, &PINB, &PORTB, 2}, // B2 2
|
{&DDRB, &PINB, &PORTB, 2}, // B2 2
|
||||||
{&DDRB, &PINB, &PORTB, 3}, // B3 3
|
{&DDRB, &PINB, &PORTB, 3}, // B3 3
|
||||||
{&DDRB, &PINB, &PORTB, 4}, // B4 4
|
{&DDRB, &PINB, &PORTB, 4}, // B4 4
|
||||||
{&DDRB, &PINB, &PORTB, 5}, // B5 5
|
{&DDRB, &PINB, &PORTB, 5}, // B5 5
|
||||||
{&DDRB, &PINB, &PORTB, 6}, // B6 6
|
{&DDRB, &PINB, &PORTB, 6}, // B6 6
|
||||||
{&DDRB, &PINB, &PORTB, 7}, // B7 7
|
{&DDRB, &PINB, &PORTB, 7}, // B7 7
|
||||||
{&DDRD, &PIND, &PORTD, 0}, // D0 8
|
{&DDRD, &PIND, &PORTD, 0}, // D0 8
|
||||||
{&DDRD, &PIND, &PORTD, 1}, // D1 9
|
{&DDRD, &PIND, &PORTD, 1}, // D1 9
|
||||||
{&DDRD, &PIND, &PORTD, 2}, // D2 10
|
{&DDRD, &PIND, &PORTD, 2}, // D2 10
|
||||||
{&DDRD, &PIND, &PORTD, 3}, // D3 11
|
{&DDRD, &PIND, &PORTD, 3}, // D3 11
|
||||||
{&DDRD, &PIND, &PORTD, 4}, // D4 12
|
{&DDRD, &PIND, &PORTD, 4}, // D4 12
|
||||||
{&DDRD, &PIND, &PORTD, 5}, // D5 13
|
{&DDRD, &PIND, &PORTD, 5}, // D5 13
|
||||||
{&DDRD, &PIND, &PORTD, 6}, // D6 14
|
{&DDRD, &PIND, &PORTD, 6}, // D6 14
|
||||||
{&DDRD, &PIND, &PORTD, 7}, // D7 15
|
{&DDRD, &PIND, &PORTD, 7}, // D7 15
|
||||||
{&DDRC, &PINC, &PORTC, 0}, // C0 16
|
{&DDRC, &PINC, &PORTC, 0}, // C0 16
|
||||||
{&DDRC, &PINC, &PORTC, 1}, // C1 17
|
{&DDRC, &PINC, &PORTC, 1}, // C1 17
|
||||||
{&DDRC, &PINC, &PORTC, 2}, // C2 18
|
{&DDRC, &PINC, &PORTC, 2}, // C2 18
|
||||||
{&DDRC, &PINC, &PORTC, 3}, // C3 19
|
{&DDRC, &PINC, &PORTC, 3}, // C3 19
|
||||||
{&DDRC, &PINC, &PORTC, 4}, // C4 20
|
{&DDRC, &PINC, &PORTC, 4}, // C4 20
|
||||||
{&DDRC, &PINC, &PORTC, 5}, // C5 21
|
{&DDRC, &PINC, &PORTC, 5}, // C5 21
|
||||||
{&DDRC, &PINC, &PORTC, 6}, // C6 22
|
{&DDRC, &PINC, &PORTC, 6}, // C6 22
|
||||||
{&DDRC, &PINC, &PORTC, 7}, // C7 23
|
{&DDRC, &PINC, &PORTC, 7}, // C7 23
|
||||||
{&DDRA, &PINA, &PORTA, 7}, // A7 24
|
{&DDRA, &PINA, &PORTA, 7}, // A7 24
|
||||||
{&DDRA, &PINA, &PORTA, 6}, // A6 25
|
{&DDRA, &PINA, &PORTA, 6}, // A6 25
|
||||||
{&DDRA, &PINA, &PORTA, 5}, // A5 26
|
{&DDRA, &PINA, &PORTA, 5}, // A5 26
|
||||||
{&DDRA, &PINA, &PORTA, 4}, // A4 27
|
{&DDRA, &PINA, &PORTA, 4}, // A4 27
|
||||||
{&DDRA, &PINA, &PORTA, 3}, // A3 28
|
{&DDRA, &PINA, &PORTA, 3}, // A3 28
|
||||||
{&DDRA, &PINA, &PORTA, 2}, // A2 29
|
{&DDRA, &PINA, &PORTA, 2}, // A2 29
|
||||||
{&DDRA, &PINA, &PORTA, 1}, // A1 30
|
{&DDRA, &PINA, &PORTA, 1}, // A1 30
|
||||||
{&DDRA, &PINA, &PORTA, 0} // A0 31
|
{&DDRA, &PINA, &PORTA, 0} // A0 31
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#elif defined(__AVR_ATmega32U4__)
|
#elif defined(__AVR_ATmega32U4__)
|
||||||
// Teensy 2.0
|
// Teensy 2.0
|
||||||
|
|
||||||
// Two Wire (aka I2C) ports
|
// Two Wire (aka I2C) ports
|
||||||
uint8_t const SDA_PIN = 6;
|
uint8_t const SDA_PIN = 6;
|
||||||
uint8_t const SCL_PIN = 5;
|
uint8_t const SCL_PIN = 5;
|
||||||
|
|
||||||
// SPI port
|
// SPI port
|
||||||
uint8_t const SS_PIN = 0;
|
uint8_t const SS_PIN = 0;
|
||||||
uint8_t const MOSI_PIN = 2;
|
uint8_t const MOSI_PIN = 2;
|
||||||
uint8_t const MISO_PIN = 3;
|
uint8_t const MISO_PIN = 3;
|
||||||
uint8_t const SCK_PIN = 1;
|
uint8_t const SCK_PIN = 1;
|
||||||
|
|
||||||
static const pin_map_t digitalPinMap[] = {
|
static const pin_map_t digitalPinMap[] = {
|
||||||
{&DDRB, &PINB, &PORTB, 0}, // B0 0
|
{&DDRB, &PINB, &PORTB, 0}, // B0 0
|
||||||
{&DDRB, &PINB, &PORTB, 1}, // B1 1
|
{&DDRB, &PINB, &PORTB, 1}, // B1 1
|
||||||
{&DDRB, &PINB, &PORTB, 2}, // B2 2
|
{&DDRB, &PINB, &PORTB, 2}, // B2 2
|
||||||
{&DDRB, &PINB, &PORTB, 3}, // B3 3
|
{&DDRB, &PINB, &PORTB, 3}, // B3 3
|
||||||
{&DDRB, &PINB, &PORTB, 7}, // B7 4
|
{&DDRB, &PINB, &PORTB, 7}, // B7 4
|
||||||
{&DDRD, &PIND, &PORTD, 0}, // D0 5
|
{&DDRD, &PIND, &PORTD, 0}, // D0 5
|
||||||
{&DDRD, &PIND, &PORTD, 1}, // D1 6
|
{&DDRD, &PIND, &PORTD, 1}, // D1 6
|
||||||
{&DDRD, &PIND, &PORTD, 2}, // D2 7
|
{&DDRD, &PIND, &PORTD, 2}, // D2 7
|
||||||
{&DDRD, &PIND, &PORTD, 3}, // D3 8
|
{&DDRD, &PIND, &PORTD, 3}, // D3 8
|
||||||
{&DDRC, &PINC, &PORTC, 6}, // C6 9
|
{&DDRC, &PINC, &PORTC, 6}, // C6 9
|
||||||
{&DDRC, &PINC, &PORTC, 7}, // C7 10
|
{&DDRC, &PINC, &PORTC, 7}, // C7 10
|
||||||
{&DDRD, &PIND, &PORTD, 6}, // D6 11
|
{&DDRD, &PIND, &PORTD, 6}, // D6 11
|
||||||
{&DDRD, &PIND, &PORTD, 7}, // D7 12
|
{&DDRD, &PIND, &PORTD, 7}, // D7 12
|
||||||
{&DDRB, &PINB, &PORTB, 4}, // B4 13
|
{&DDRB, &PINB, &PORTB, 4}, // B4 13
|
||||||
{&DDRB, &PINB, &PORTB, 5}, // B5 14
|
{&DDRB, &PINB, &PORTB, 5}, // B5 14
|
||||||
{&DDRB, &PINB, &PORTB, 6}, // B6 15
|
{&DDRB, &PINB, &PORTB, 6}, // B6 15
|
||||||
{&DDRF, &PINF, &PORTF, 7}, // F7 16
|
{&DDRF, &PINF, &PORTF, 7}, // F7 16
|
||||||
{&DDRF, &PINF, &PORTF, 6}, // F6 17
|
{&DDRF, &PINF, &PORTF, 6}, // F6 17
|
||||||
{&DDRF, &PINF, &PORTF, 5}, // F5 18
|
{&DDRF, &PINF, &PORTF, 5}, // F5 18
|
||||||
{&DDRF, &PINF, &PORTF, 4}, // F4 19
|
{&DDRF, &PINF, &PORTF, 4}, // F4 19
|
||||||
{&DDRF, &PINF, &PORTF, 1}, // F1 20
|
{&DDRF, &PINF, &PORTF, 1}, // F1 20
|
||||||
{&DDRF, &PINF, &PORTF, 0}, // F0 21
|
{&DDRF, &PINF, &PORTF, 0}, // F0 21
|
||||||
{&DDRD, &PIND, &PORTD, 4}, // D4 22
|
{&DDRD, &PIND, &PORTD, 4}, // D4 22
|
||||||
{&DDRD, &PIND, &PORTD, 5}, // D5 23
|
{&DDRD, &PIND, &PORTD, 5}, // D5 23
|
||||||
{&DDRE, &PINE, &PORTE, 6} // E6 24
|
{&DDRE, &PINE, &PORTE, 6} // E6 24
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||||
// Teensy++ 1.0 & 2.0
|
// Teensy++ 1.0 & 2.0
|
||||||
|
|
||||||
// Two Wire (aka I2C) ports
|
// Two Wire (aka I2C) ports
|
||||||
uint8_t const SDA_PIN = 1;
|
uint8_t const SDA_PIN = 1;
|
||||||
uint8_t const SCL_PIN = 0;
|
uint8_t const SCL_PIN = 0;
|
||||||
|
|
||||||
// SPI port
|
// SPI port
|
||||||
uint8_t const SS_PIN = 20;
|
uint8_t const SS_PIN = 20;
|
||||||
uint8_t const MOSI_PIN = 22;
|
uint8_t const MOSI_PIN = 22;
|
||||||
uint8_t const MISO_PIN = 23;
|
uint8_t const MISO_PIN = 23;
|
||||||
uint8_t const SCK_PIN = 21;
|
uint8_t const SCK_PIN = 21;
|
||||||
|
|
||||||
static const pin_map_t digitalPinMap[] = {
|
static const pin_map_t digitalPinMap[] = {
|
||||||
{&DDRD, &PIND, &PORTD, 0}, // D0 0
|
{&DDRD, &PIND, &PORTD, 0}, // D0 0
|
||||||
{&DDRD, &PIND, &PORTD, 1}, // D1 1
|
{&DDRD, &PIND, &PORTD, 1}, // D1 1
|
||||||
{&DDRD, &PIND, &PORTD, 2}, // D2 2
|
{&DDRD, &PIND, &PORTD, 2}, // D2 2
|
||||||
{&DDRD, &PIND, &PORTD, 3}, // D3 3
|
{&DDRD, &PIND, &PORTD, 3}, // D3 3
|
||||||
{&DDRD, &PIND, &PORTD, 4}, // D4 4
|
{&DDRD, &PIND, &PORTD, 4}, // D4 4
|
||||||
{&DDRD, &PIND, &PORTD, 5}, // D5 5
|
{&DDRD, &PIND, &PORTD, 5}, // D5 5
|
||||||
{&DDRD, &PIND, &PORTD, 6}, // D6 6
|
{&DDRD, &PIND, &PORTD, 6}, // D6 6
|
||||||
{&DDRD, &PIND, &PORTD, 7}, // D7 7
|
{&DDRD, &PIND, &PORTD, 7}, // D7 7
|
||||||
{&DDRE, &PINE, &PORTE, 0}, // E0 8
|
{&DDRE, &PINE, &PORTE, 0}, // E0 8
|
||||||
{&DDRE, &PINE, &PORTE, 1}, // E1 9
|
{&DDRE, &PINE, &PORTE, 1}, // E1 9
|
||||||
{&DDRC, &PINC, &PORTC, 0}, // C0 10
|
{&DDRC, &PINC, &PORTC, 0}, // C0 10
|
||||||
{&DDRC, &PINC, &PORTC, 1}, // C1 11
|
{&DDRC, &PINC, &PORTC, 1}, // C1 11
|
||||||
{&DDRC, &PINC, &PORTC, 2}, // C2 12
|
{&DDRC, &PINC, &PORTC, 2}, // C2 12
|
||||||
{&DDRC, &PINC, &PORTC, 3}, // C3 13
|
{&DDRC, &PINC, &PORTC, 3}, // C3 13
|
||||||
{&DDRC, &PINC, &PORTC, 4}, // C4 14
|
{&DDRC, &PINC, &PORTC, 4}, // C4 14
|
||||||
{&DDRC, &PINC, &PORTC, 5}, // C5 15
|
{&DDRC, &PINC, &PORTC, 5}, // C5 15
|
||||||
{&DDRC, &PINC, &PORTC, 6}, // C6 16
|
{&DDRC, &PINC, &PORTC, 6}, // C6 16
|
||||||
{&DDRC, &PINC, &PORTC, 7}, // C7 17
|
{&DDRC, &PINC, &PORTC, 7}, // C7 17
|
||||||
{&DDRE, &PINE, &PORTE, 6}, // E6 18
|
{&DDRE, &PINE, &PORTE, 6}, // E6 18
|
||||||
{&DDRE, &PINE, &PORTE, 7}, // E7 19
|
{&DDRE, &PINE, &PORTE, 7}, // E7 19
|
||||||
{&DDRB, &PINB, &PORTB, 0}, // B0 20
|
{&DDRB, &PINB, &PORTB, 0}, // B0 20
|
||||||
{&DDRB, &PINB, &PORTB, 1}, // B1 21
|
{&DDRB, &PINB, &PORTB, 1}, // B1 21
|
||||||
{&DDRB, &PINB, &PORTB, 2}, // B2 22
|
{&DDRB, &PINB, &PORTB, 2}, // B2 22
|
||||||
{&DDRB, &PINB, &PORTB, 3}, // B3 23
|
{&DDRB, &PINB, &PORTB, 3}, // B3 23
|
||||||
{&DDRB, &PINB, &PORTB, 4}, // B4 24
|
{&DDRB, &PINB, &PORTB, 4}, // B4 24
|
||||||
{&DDRB, &PINB, &PORTB, 5}, // B5 25
|
{&DDRB, &PINB, &PORTB, 5}, // B5 25
|
||||||
{&DDRB, &PINB, &PORTB, 6}, // B6 26
|
{&DDRB, &PINB, &PORTB, 6}, // B6 26
|
||||||
{&DDRB, &PINB, &PORTB, 7}, // B7 27
|
{&DDRB, &PINB, &PORTB, 7}, // B7 27
|
||||||
{&DDRA, &PINA, &PORTA, 0}, // A0 28
|
{&DDRA, &PINA, &PORTA, 0}, // A0 28
|
||||||
{&DDRA, &PINA, &PORTA, 1}, // A1 29
|
{&DDRA, &PINA, &PORTA, 1}, // A1 29
|
||||||
{&DDRA, &PINA, &PORTA, 2}, // A2 30
|
{&DDRA, &PINA, &PORTA, 2}, // A2 30
|
||||||
{&DDRA, &PINA, &PORTA, 3}, // A3 31
|
{&DDRA, &PINA, &PORTA, 3}, // A3 31
|
||||||
{&DDRA, &PINA, &PORTA, 4}, // A4 32
|
{&DDRA, &PINA, &PORTA, 4}, // A4 32
|
||||||
{&DDRA, &PINA, &PORTA, 5}, // A5 33
|
{&DDRA, &PINA, &PORTA, 5}, // A5 33
|
||||||
{&DDRA, &PINA, &PORTA, 6}, // A6 34
|
{&DDRA, &PINA, &PORTA, 6}, // A6 34
|
||||||
{&DDRA, &PINA, &PORTA, 7}, // A7 35
|
{&DDRA, &PINA, &PORTA, 7}, // A7 35
|
||||||
{&DDRE, &PINE, &PORTE, 4}, // E4 36
|
{&DDRE, &PINE, &PORTE, 4}, // E4 36
|
||||||
{&DDRE, &PINE, &PORTE, 5}, // E5 37
|
{&DDRE, &PINE, &PORTE, 5}, // E5 37
|
||||||
{&DDRF, &PINF, &PORTF, 0}, // F0 38
|
{&DDRF, &PINF, &PORTF, 0}, // F0 38
|
||||||
{&DDRF, &PINF, &PORTF, 1}, // F1 39
|
{&DDRF, &PINF, &PORTF, 1}, // F1 39
|
||||||
{&DDRF, &PINF, &PORTF, 2}, // F2 40
|
{&DDRF, &PINF, &PORTF, 2}, // F2 40
|
||||||
{&DDRF, &PINF, &PORTF, 3}, // F3 41
|
{&DDRF, &PINF, &PORTF, 3}, // F3 41
|
||||||
{&DDRF, &PINF, &PORTF, 4}, // F4 42
|
{&DDRF, &PINF, &PORTF, 4}, // F4 42
|
||||||
{&DDRF, &PINF, &PORTF, 5}, // F5 43
|
{&DDRF, &PINF, &PORTF, 5}, // F5 43
|
||||||
{&DDRF, &PINF, &PORTF, 6}, // F6 44
|
{&DDRF, &PINF, &PORTF, 6}, // F6 44
|
||||||
{&DDRF, &PINF, &PORTF, 7} // F7 45
|
{&DDRF, &PINF, &PORTF, 7} // F7 45
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#else // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
#else // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
// 168 and 328 Arduinos
|
// 168 and 328 Arduinos
|
||||||
|
|
||||||
// Two Wire (aka I2C) ports
|
// Two Wire (aka I2C) ports
|
||||||
uint8_t const SDA_PIN = 18;
|
uint8_t const SDA_PIN = 18;
|
||||||
uint8_t const SCL_PIN = 19;
|
uint8_t const SCL_PIN = 19;
|
||||||
|
|
||||||
// SPI port
|
// SPI port
|
||||||
uint8_t const SS_PIN = 10;
|
uint8_t const SS_PIN = 10;
|
||||||
uint8_t const MOSI_PIN = 11;
|
uint8_t const MOSI_PIN = 11;
|
||||||
uint8_t const MISO_PIN = 12;
|
uint8_t const MISO_PIN = 12;
|
||||||
uint8_t const SCK_PIN = 13;
|
uint8_t const SCK_PIN = 13;
|
||||||
|
|
||||||
static const pin_map_t digitalPinMap[] = {
|
static const pin_map_t digitalPinMap[] = {
|
||||||
{&DDRD, &PIND, &PORTD, 0}, // D0 0
|
{&DDRD, &PIND, &PORTD, 0}, // D0 0
|
||||||
{&DDRD, &PIND, &PORTD, 1}, // D1 1
|
{&DDRD, &PIND, &PORTD, 1}, // D1 1
|
||||||
{&DDRD, &PIND, &PORTD, 2}, // D2 2
|
{&DDRD, &PIND, &PORTD, 2}, // D2 2
|
||||||
{&DDRD, &PIND, &PORTD, 3}, // D3 3
|
{&DDRD, &PIND, &PORTD, 3}, // D3 3
|
||||||
{&DDRD, &PIND, &PORTD, 4}, // D4 4
|
{&DDRD, &PIND, &PORTD, 4}, // D4 4
|
||||||
{&DDRD, &PIND, &PORTD, 5}, // D5 5
|
{&DDRD, &PIND, &PORTD, 5}, // D5 5
|
||||||
{&DDRD, &PIND, &PORTD, 6}, // D6 6
|
{&DDRD, &PIND, &PORTD, 6}, // D6 6
|
||||||
{&DDRD, &PIND, &PORTD, 7}, // D7 7
|
{&DDRD, &PIND, &PORTD, 7}, // D7 7
|
||||||
{&DDRB, &PINB, &PORTB, 0}, // B0 8
|
{&DDRB, &PINB, &PORTB, 0}, // B0 8
|
||||||
{&DDRB, &PINB, &PORTB, 1}, // B1 9
|
{&DDRB, &PINB, &PORTB, 1}, // B1 9
|
||||||
{&DDRB, &PINB, &PORTB, 2}, // B2 10
|
{&DDRB, &PINB, &PORTB, 2}, // B2 10
|
||||||
{&DDRB, &PINB, &PORTB, 3}, // B3 11
|
{&DDRB, &PINB, &PORTB, 3}, // B3 11
|
||||||
{&DDRB, &PINB, &PORTB, 4}, // B4 12
|
{&DDRB, &PINB, &PORTB, 4}, // B4 12
|
||||||
{&DDRB, &PINB, &PORTB, 5}, // B5 13
|
{&DDRB, &PINB, &PORTB, 5}, // B5 13
|
||||||
{&DDRC, &PINC, &PORTC, 0}, // C0 14
|
{&DDRC, &PINC, &PORTC, 0}, // C0 14
|
||||||
{&DDRC, &PINC, &PORTC, 1}, // C1 15
|
{&DDRC, &PINC, &PORTC, 1}, // C1 15
|
||||||
{&DDRC, &PINC, &PORTC, 2}, // C2 16
|
{&DDRC, &PINC, &PORTC, 2}, // C2 16
|
||||||
{&DDRC, &PINC, &PORTC, 3}, // C3 17
|
{&DDRC, &PINC, &PORTC, 3}, // C3 17
|
||||||
{&DDRC, &PINC, &PORTC, 4}, // C4 18
|
{&DDRC, &PINC, &PORTC, 4}, // C4 18
|
||||||
{&DDRC, &PINC, &PORTC, 5} // C5 19
|
{&DDRC, &PINC, &PORTC, 5} // C5 19
|
||||||
};
|
};
|
||||||
#endif // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
#endif // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
static const uint8_t digitalPinCount = sizeof(digitalPinMap)/sizeof(pin_map_t);
|
static const uint8_t digitalPinCount = sizeof(digitalPinMap)/sizeof(pin_map_t);
|
||||||
|
|
||||||
uint8_t badPinNumber(void)
|
uint8_t badPinNumber(void)
|
||||||
__attribute__((error("Pin number is too large or not a constant")));
|
__attribute__((error("Pin number is too large or not a constant")));
|
||||||
|
|
||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
uint8_t getPinMode(uint8_t pin) {
|
uint8_t getPinMode(uint8_t pin) {
|
||||||
if (__builtin_constant_p(pin) && pin < digitalPinCount) {
|
if (__builtin_constant_p(pin) && pin < digitalPinCount) {
|
||||||
return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1;
|
return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1;
|
||||||
} else {
|
} else {
|
||||||
return badPinNumber();
|
return badPinNumber();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
void setPinMode(uint8_t pin, uint8_t mode) {
|
void setPinMode(uint8_t pin, uint8_t mode) {
|
||||||
if (__builtin_constant_p(pin) && pin < digitalPinCount) {
|
if (__builtin_constant_p(pin) && pin < digitalPinCount) {
|
||||||
if (mode) {
|
if (mode) {
|
||||||
*digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit;
|
*digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit;
|
||||||
} else {
|
} else {
|
||||||
*digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit);
|
*digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
badPinNumber();
|
badPinNumber();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
uint8_t fastDigitalRead(uint8_t pin) {
|
uint8_t fastDigitalRead(uint8_t pin) {
|
||||||
if (__builtin_constant_p(pin) && pin < digitalPinCount) {
|
if (__builtin_constant_p(pin) && pin < digitalPinCount) {
|
||||||
return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1;
|
return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1;
|
||||||
} else {
|
} else {
|
||||||
return badPinNumber();
|
return badPinNumber();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
void fastDigitalWrite(uint8_t pin, uint8_t value) {
|
void fastDigitalWrite(uint8_t pin, uint8_t value) {
|
||||||
if (__builtin_constant_p(pin) && pin < digitalPinCount) {
|
if (__builtin_constant_p(pin) && pin < digitalPinCount) {
|
||||||
if (value) {
|
if (value) {
|
||||||
*digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit;
|
*digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit;
|
||||||
} else {
|
} else {
|
||||||
*digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit);
|
*digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
badPinNumber();
|
badPinNumber();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // Sd2PinMap_h
|
#endif // Sd2PinMap_h
|
||||||
|
|
1094
Marlin/SdFat.h
1094
Marlin/SdFat.h
|
@ -1,547 +1,547 @@
|
||||||
/* Arduino SdFat Library
|
/* Arduino SdFat Library
|
||||||
* Copyright (C) 2009 by William Greiman
|
* Copyright (C) 2009 by William Greiman
|
||||||
*
|
*
|
||||||
* This file is part of the Arduino SdFat Library
|
* This file is part of the Arduino SdFat Library
|
||||||
*
|
*
|
||||||
* This Library is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This Library is distributed in the hope that it will be useful,
|
* This Library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with the Arduino SdFat Library. If not, see
|
* along with the Arduino SdFat Library. If not, see
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#ifndef SdFat_h
|
#ifndef SdFat_h
|
||||||
#define SdFat_h
|
#define SdFat_h
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* SdFile and SdVolume classes
|
* SdFile and SdVolume classes
|
||||||
*/
|
*/
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "Sd2Card.h"
|
#include "Sd2Card.h"
|
||||||
#include "FatStructs.h"
|
#include "FatStructs.h"
|
||||||
#include "Print.h"
|
#include "Print.h"
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Allow use of deprecated functions if non-zero
|
* Allow use of deprecated functions if non-zero
|
||||||
*/
|
*/
|
||||||
#define ALLOW_DEPRECATED_FUNCTIONS 1
|
#define ALLOW_DEPRECATED_FUNCTIONS 1
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// forward declaration since SdVolume is used in SdFile
|
// forward declaration since SdVolume is used in SdFile
|
||||||
class SdVolume;
|
class SdVolume;
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// SdFile class
|
// SdFile class
|
||||||
|
|
||||||
// flags for ls()
|
// flags for ls()
|
||||||
/** ls() flag to print modify date */
|
/** ls() flag to print modify date */
|
||||||
uint8_t const LS_DATE = 1;
|
uint8_t const LS_DATE = 1;
|
||||||
/** ls() flag to print file size */
|
/** ls() flag to print file size */
|
||||||
uint8_t const LS_SIZE = 2;
|
uint8_t const LS_SIZE = 2;
|
||||||
/** ls() flag for recursive list of subdirectories */
|
/** ls() flag for recursive list of subdirectories */
|
||||||
uint8_t const LS_R = 4;
|
uint8_t const LS_R = 4;
|
||||||
|
|
||||||
// use the gnu style oflag in open()
|
// use the gnu style oflag in open()
|
||||||
/** open() oflag for reading */
|
/** open() oflag for reading */
|
||||||
uint8_t const O_READ = 0X01;
|
uint8_t const O_READ = 0X01;
|
||||||
/** open() oflag - same as O_READ */
|
/** open() oflag - same as O_READ */
|
||||||
uint8_t const O_RDONLY = O_READ;
|
uint8_t const O_RDONLY = O_READ;
|
||||||
/** open() oflag for write */
|
/** open() oflag for write */
|
||||||
uint8_t const O_WRITE = 0X02;
|
uint8_t const O_WRITE = 0X02;
|
||||||
/** open() oflag - same as O_WRITE */
|
/** open() oflag - same as O_WRITE */
|
||||||
uint8_t const O_WRONLY = O_WRITE;
|
uint8_t const O_WRONLY = O_WRITE;
|
||||||
/** open() oflag for reading and writing */
|
/** open() oflag for reading and writing */
|
||||||
uint8_t const O_RDWR = (O_READ | O_WRITE);
|
uint8_t const O_RDWR = (O_READ | O_WRITE);
|
||||||
/** open() oflag mask for access modes */
|
/** open() oflag mask for access modes */
|
||||||
uint8_t const O_ACCMODE = (O_READ | O_WRITE);
|
uint8_t const O_ACCMODE = (O_READ | O_WRITE);
|
||||||
/** The file offset shall be set to the end of the file prior to each write. */
|
/** The file offset shall be set to the end of the file prior to each write. */
|
||||||
uint8_t const O_APPEND = 0X04;
|
uint8_t const O_APPEND = 0X04;
|
||||||
/** synchronous writes - call sync() after each write */
|
/** synchronous writes - call sync() after each write */
|
||||||
uint8_t const O_SYNC = 0X08;
|
uint8_t const O_SYNC = 0X08;
|
||||||
/** create the file if nonexistent */
|
/** create the file if nonexistent */
|
||||||
uint8_t const O_CREAT = 0X10;
|
uint8_t const O_CREAT = 0X10;
|
||||||
/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
|
/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
|
||||||
uint8_t const O_EXCL = 0X20;
|
uint8_t const O_EXCL = 0X20;
|
||||||
/** truncate the file to zero length */
|
/** truncate the file to zero length */
|
||||||
uint8_t const O_TRUNC = 0X40;
|
uint8_t const O_TRUNC = 0X40;
|
||||||
|
|
||||||
// flags for timestamp
|
// flags for timestamp
|
||||||
/** set the file's last access date */
|
/** set the file's last access date */
|
||||||
uint8_t const T_ACCESS = 1;
|
uint8_t const T_ACCESS = 1;
|
||||||
/** set the file's creation date and time */
|
/** set the file's creation date and time */
|
||||||
uint8_t const T_CREATE = 2;
|
uint8_t const T_CREATE = 2;
|
||||||
/** Set the file's write date and time */
|
/** Set the file's write date and time */
|
||||||
uint8_t const T_WRITE = 4;
|
uint8_t const T_WRITE = 4;
|
||||||
// values for type_
|
// values for type_
|
||||||
/** This SdFile has not been opened. */
|
/** This SdFile has not been opened. */
|
||||||
uint8_t const FAT_FILE_TYPE_CLOSED = 0;
|
uint8_t const FAT_FILE_TYPE_CLOSED = 0;
|
||||||
/** SdFile for a file */
|
/** SdFile for a file */
|
||||||
uint8_t const FAT_FILE_TYPE_NORMAL = 1;
|
uint8_t const FAT_FILE_TYPE_NORMAL = 1;
|
||||||
/** SdFile for a FAT16 root directory */
|
/** SdFile for a FAT16 root directory */
|
||||||
uint8_t const FAT_FILE_TYPE_ROOT16 = 2;
|
uint8_t const FAT_FILE_TYPE_ROOT16 = 2;
|
||||||
/** SdFile for a FAT32 root directory */
|
/** SdFile for a FAT32 root directory */
|
||||||
uint8_t const FAT_FILE_TYPE_ROOT32 = 3;
|
uint8_t const FAT_FILE_TYPE_ROOT32 = 3;
|
||||||
/** SdFile for a subdirectory */
|
/** SdFile for a subdirectory */
|
||||||
uint8_t const FAT_FILE_TYPE_SUBDIR = 4;
|
uint8_t const FAT_FILE_TYPE_SUBDIR = 4;
|
||||||
/** Test value for directory type */
|
/** Test value for directory type */
|
||||||
uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT16;
|
uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT16;
|
||||||
|
|
||||||
/** date field for FAT directory entry */
|
/** date field for FAT directory entry */
|
||||||
static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) {
|
static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) {
|
||||||
return (year - 1980) << 9 | month << 5 | day;
|
return (year - 1980) << 9 | month << 5 | day;
|
||||||
}
|
}
|
||||||
/** year part of FAT directory date field */
|
/** year part of FAT directory date field */
|
||||||
static inline uint16_t FAT_YEAR(uint16_t fatDate) {
|
static inline uint16_t FAT_YEAR(uint16_t fatDate) {
|
||||||
return 1980 + (fatDate >> 9);
|
return 1980 + (fatDate >> 9);
|
||||||
}
|
}
|
||||||
/** month part of FAT directory date field */
|
/** month part of FAT directory date field */
|
||||||
static inline uint8_t FAT_MONTH(uint16_t fatDate) {
|
static inline uint8_t FAT_MONTH(uint16_t fatDate) {
|
||||||
return (fatDate >> 5) & 0XF;
|
return (fatDate >> 5) & 0XF;
|
||||||
}
|
}
|
||||||
/** day part of FAT directory date field */
|
/** day part of FAT directory date field */
|
||||||
static inline uint8_t FAT_DAY(uint16_t fatDate) {
|
static inline uint8_t FAT_DAY(uint16_t fatDate) {
|
||||||
return fatDate & 0X1F;
|
return fatDate & 0X1F;
|
||||||
}
|
}
|
||||||
/** time field for FAT directory entry */
|
/** time field for FAT directory entry */
|
||||||
static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) {
|
static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) {
|
||||||
return hour << 11 | minute << 5 | second >> 1;
|
return hour << 11 | minute << 5 | second >> 1;
|
||||||
}
|
}
|
||||||
/** hour part of FAT directory time field */
|
/** hour part of FAT directory time field */
|
||||||
static inline uint8_t FAT_HOUR(uint16_t fatTime) {
|
static inline uint8_t FAT_HOUR(uint16_t fatTime) {
|
||||||
return fatTime >> 11;
|
return fatTime >> 11;
|
||||||
}
|
}
|
||||||
/** minute part of FAT directory time field */
|
/** minute part of FAT directory time field */
|
||||||
static inline uint8_t FAT_MINUTE(uint16_t fatTime) {
|
static inline uint8_t FAT_MINUTE(uint16_t fatTime) {
|
||||||
return(fatTime >> 5) & 0X3F;
|
return(fatTime >> 5) & 0X3F;
|
||||||
}
|
}
|
||||||
/** second part of FAT directory time field */
|
/** second part of FAT directory time field */
|
||||||
static inline uint8_t FAT_SECOND(uint16_t fatTime) {
|
static inline uint8_t FAT_SECOND(uint16_t fatTime) {
|
||||||
return 2*(fatTime & 0X1F);
|
return 2*(fatTime & 0X1F);
|
||||||
}
|
}
|
||||||
/** Default date for file timestamps is 1 Jan 2000 */
|
/** Default date for file timestamps is 1 Jan 2000 */
|
||||||
uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1;
|
uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1;
|
||||||
/** Default time for file timestamp is 1 am */
|
/** Default time for file timestamp is 1 am */
|
||||||
uint16_t const FAT_DEFAULT_TIME = (1 << 11);
|
uint16_t const FAT_DEFAULT_TIME = (1 << 11);
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* \class SdFile
|
* \class SdFile
|
||||||
* \brief Access FAT16 and FAT32 files on SD and SDHC cards.
|
* \brief Access FAT16 and FAT32 files on SD and SDHC cards.
|
||||||
*/
|
*/
|
||||||
class SdFile : public Print {
|
class SdFile : public Print {
|
||||||
public:
|
public:
|
||||||
/** Create an instance of SdFile. */
|
/** Create an instance of SdFile. */
|
||||||
SdFile(void) : type_(FAT_FILE_TYPE_CLOSED) {}
|
SdFile(void) : type_(FAT_FILE_TYPE_CLOSED) {}
|
||||||
/**
|
/**
|
||||||
* writeError is set to true if an error occurs during a write().
|
* writeError is set to true if an error occurs during a write().
|
||||||
* Set writeError to false before calling print() and/or write() and check
|
* Set writeError to false before calling print() and/or write() and check
|
||||||
* for true after calls to print() and/or write().
|
* for true after calls to print() and/or write().
|
||||||
*/
|
*/
|
||||||
bool writeError;
|
bool writeError;
|
||||||
/**
|
/**
|
||||||
* Cancel unbuffered reads for this file.
|
* Cancel unbuffered reads for this file.
|
||||||
* See setUnbufferedRead()
|
* See setUnbufferedRead()
|
||||||
*/
|
*/
|
||||||
void clearUnbufferedRead(void) {
|
void clearUnbufferedRead(void) {
|
||||||
flags_ &= ~F_FILE_UNBUFFERED_READ;
|
flags_ &= ~F_FILE_UNBUFFERED_READ;
|
||||||
}
|
}
|
||||||
uint8_t close(void);
|
uint8_t close(void);
|
||||||
uint8_t contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
|
uint8_t contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
|
||||||
uint8_t createContiguous(SdFile* dirFile,
|
uint8_t createContiguous(SdFile* dirFile,
|
||||||
const char* fileName, uint32_t size);
|
const char* fileName, uint32_t size);
|
||||||
/** \return The current cluster number for a file or directory. */
|
/** \return The current cluster number for a file or directory. */
|
||||||
uint32_t curCluster(void) const {return curCluster_;}
|
uint32_t curCluster(void) const {return curCluster_;}
|
||||||
/** \return The current position for a file or directory. */
|
/** \return The current position for a file or directory. */
|
||||||
uint32_t curPosition(void) const {return curPosition_;}
|
uint32_t curPosition(void) const {return curPosition_;}
|
||||||
/**
|
/**
|
||||||
* Set the date/time callback function
|
* Set the date/time callback function
|
||||||
*
|
*
|
||||||
* \param[in] dateTime The user's call back function. The callback
|
* \param[in] dateTime The user's call back function. The callback
|
||||||
* function is of the form:
|
* function is of the form:
|
||||||
*
|
*
|
||||||
* \code
|
* \code
|
||||||
* void dateTime(uint16_t* date, uint16_t* time) {
|
* void dateTime(uint16_t* date, uint16_t* time) {
|
||||||
* uint16_t year;
|
* uint16_t year;
|
||||||
* uint8_t month, day, hour, minute, second;
|
* uint8_t month, day, hour, minute, second;
|
||||||
*
|
*
|
||||||
* // User gets date and time from GPS or real-time clock here
|
* // User gets date and time from GPS or real-time clock here
|
||||||
*
|
*
|
||||||
* // return date using FAT_DATE macro to format fields
|
* // return date using FAT_DATE macro to format fields
|
||||||
* *date = FAT_DATE(year, month, day);
|
* *date = FAT_DATE(year, month, day);
|
||||||
*
|
*
|
||||||
* // return time using FAT_TIME macro to format fields
|
* // return time using FAT_TIME macro to format fields
|
||||||
* *time = FAT_TIME(hour, minute, second);
|
* *time = FAT_TIME(hour, minute, second);
|
||||||
* }
|
* }
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
* Sets the function that is called when a file is created or when
|
* Sets the function that is called when a file is created or when
|
||||||
* a file's directory entry is modified by sync(). All timestamps,
|
* a file's directory entry is modified by sync(). All timestamps,
|
||||||
* access, creation, and modify, are set when a file is created.
|
* access, creation, and modify, are set when a file is created.
|
||||||
* sync() maintains the last access date and last modify date/time.
|
* sync() maintains the last access date and last modify date/time.
|
||||||
*
|
*
|
||||||
* See the timestamp() function.
|
* See the timestamp() function.
|
||||||
*/
|
*/
|
||||||
static void dateTimeCallback(
|
static void dateTimeCallback(
|
||||||
void (*dateTime)(uint16_t* date, uint16_t* time)) {
|
void (*dateTime)(uint16_t* date, uint16_t* time)) {
|
||||||
dateTime_ = dateTime;
|
dateTime_ = dateTime;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Cancel the date/time callback function.
|
* Cancel the date/time callback function.
|
||||||
*/
|
*/
|
||||||
static void dateTimeCallbackCancel(void) {
|
static void dateTimeCallbackCancel(void) {
|
||||||
// use explicit zero since NULL is not defined for Sanguino
|
// use explicit zero since NULL is not defined for Sanguino
|
||||||
dateTime_ = 0;
|
dateTime_ = 0;
|
||||||
}
|
}
|
||||||
/** \return Address of the block that contains this file's directory. */
|
/** \return Address of the block that contains this file's directory. */
|
||||||
uint32_t dirBlock(void) const {return dirBlock_;}
|
uint32_t dirBlock(void) const {return dirBlock_;}
|
||||||
uint8_t dirEntry(dir_t* dir);
|
uint8_t dirEntry(dir_t* dir);
|
||||||
/** \return Index of this file's directory in the block dirBlock. */
|
/** \return Index of this file's directory in the block dirBlock. */
|
||||||
uint8_t dirIndex(void) const {return dirIndex_;}
|
uint8_t dirIndex(void) const {return dirIndex_;}
|
||||||
static void dirName(const dir_t& dir, char* name);
|
static void dirName(const dir_t& dir, char* name);
|
||||||
/** \return The total number of bytes in a file or directory. */
|
/** \return The total number of bytes in a file or directory. */
|
||||||
uint32_t fileSize(void) const {return fileSize_;}
|
uint32_t fileSize(void) const {return fileSize_;}
|
||||||
/** \return The first cluster number for a file or directory. */
|
/** \return The first cluster number for a file or directory. */
|
||||||
uint32_t firstCluster(void) const {return firstCluster_;}
|
uint32_t firstCluster(void) const {return firstCluster_;}
|
||||||
/** \return True if this is a SdFile for a directory else false. */
|
/** \return True if this is a SdFile for a directory else false. */
|
||||||
uint8_t isDir(void) const {return type_ >= FAT_FILE_TYPE_MIN_DIR;}
|
uint8_t isDir(void) const {return type_ >= FAT_FILE_TYPE_MIN_DIR;}
|
||||||
/** \return True if this is a SdFile for a file else false. */
|
/** \return True if this is a SdFile for a file else false. */
|
||||||
uint8_t isFile(void) const {return type_ == FAT_FILE_TYPE_NORMAL;}
|
uint8_t isFile(void) const {return type_ == FAT_FILE_TYPE_NORMAL;}
|
||||||
/** \return True if this is a SdFile for an open file/directory else false. */
|
/** \return True if this is a SdFile for an open file/directory else false. */
|
||||||
uint8_t isOpen(void) const {return type_ != FAT_FILE_TYPE_CLOSED;}
|
uint8_t isOpen(void) const {return type_ != FAT_FILE_TYPE_CLOSED;}
|
||||||
/** \return True if this is a SdFile for a subdirectory else false. */
|
/** \return True if this is a SdFile for a subdirectory else false. */
|
||||||
uint8_t isSubDir(void) const {return type_ == FAT_FILE_TYPE_SUBDIR;}
|
uint8_t isSubDir(void) const {return type_ == FAT_FILE_TYPE_SUBDIR;}
|
||||||
/** \return True if this is a SdFile for the root directory. */
|
/** \return True if this is a SdFile for the root directory. */
|
||||||
uint8_t isRoot(void) const {
|
uint8_t isRoot(void) const {
|
||||||
return type_ == FAT_FILE_TYPE_ROOT16 || type_ == FAT_FILE_TYPE_ROOT32;
|
return type_ == FAT_FILE_TYPE_ROOT16 || type_ == FAT_FILE_TYPE_ROOT32;
|
||||||
}
|
}
|
||||||
void ls(uint8_t flags = 0, uint8_t indent = 0);
|
void ls(uint8_t flags = 0, uint8_t indent = 0);
|
||||||
uint8_t makeDir(SdFile* dir, const char* dirName);
|
uint8_t makeDir(SdFile* dir, const char* dirName);
|
||||||
uint8_t open(SdFile* dirFile, uint16_t index, uint8_t oflag);
|
uint8_t open(SdFile* dirFile, uint16_t index, uint8_t oflag);
|
||||||
uint8_t open(SdFile* dirFile, const char* fileName, uint8_t oflag);
|
uint8_t open(SdFile* dirFile, const char* fileName, uint8_t oflag);
|
||||||
|
|
||||||
uint8_t openRoot(SdVolume* vol);
|
uint8_t openRoot(SdVolume* vol);
|
||||||
static void printDirName(const dir_t& dir, uint8_t width);
|
static void printDirName(const dir_t& dir, uint8_t width);
|
||||||
static void printFatDate(uint16_t fatDate);
|
static void printFatDate(uint16_t fatDate);
|
||||||
static void printFatTime(uint16_t fatTime);
|
static void printFatTime(uint16_t fatTime);
|
||||||
static void printTwoDigits(uint8_t v);
|
static void printTwoDigits(uint8_t v);
|
||||||
/**
|
/**
|
||||||
* Read the next byte from a file.
|
* Read the next byte from a file.
|
||||||
*
|
*
|
||||||
* \return For success read returns the next byte in the file as an int.
|
* \return For success read returns the next byte in the file as an int.
|
||||||
* If an error occurs or end of file is reached -1 is returned.
|
* If an error occurs or end of file is reached -1 is returned.
|
||||||
*/
|
*/
|
||||||
int16_t read(void) {
|
int16_t read(void) {
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
return read(&b, 1) == 1 ? b : -1;
|
return read(&b, 1) == 1 ? b : -1;
|
||||||
}
|
}
|
||||||
int16_t read(void* buf, uint16_t nbyte);
|
int16_t read(void* buf, uint16_t nbyte);
|
||||||
int8_t readDir(dir_t* dir);
|
int8_t readDir(dir_t* dir);
|
||||||
static uint8_t remove(SdFile* dirFile, const char* fileName);
|
static uint8_t remove(SdFile* dirFile, const char* fileName);
|
||||||
uint8_t remove(void);
|
uint8_t remove(void);
|
||||||
/** Set the file's current position to zero. */
|
/** Set the file's current position to zero. */
|
||||||
void rewind(void) {
|
void rewind(void) {
|
||||||
curPosition_ = curCluster_ = 0;
|
curPosition_ = curCluster_ = 0;
|
||||||
}
|
}
|
||||||
uint8_t rmDir(void);
|
uint8_t rmDir(void);
|
||||||
uint8_t rmRfStar(void);
|
uint8_t rmRfStar(void);
|
||||||
/** Set the files position to current position + \a pos. See seekSet(). */
|
/** Set the files position to current position + \a pos. See seekSet(). */
|
||||||
uint8_t seekCur(uint32_t pos) {
|
uint8_t seekCur(uint32_t pos) {
|
||||||
return seekSet(curPosition_ + pos);
|
return seekSet(curPosition_ + pos);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Set the files current position to end of file. Useful to position
|
* Set the files current position to end of file. Useful to position
|
||||||
* a file for append. See seekSet().
|
* a file for append. See seekSet().
|
||||||
*/
|
*/
|
||||||
uint8_t seekEnd(void) {return seekSet(fileSize_);}
|
uint8_t seekEnd(void) {return seekSet(fileSize_);}
|
||||||
uint8_t seekSet(uint32_t pos);
|
uint8_t seekSet(uint32_t pos);
|
||||||
/**
|
/**
|
||||||
* Use unbuffered reads to access this file. Used with Wave
|
* Use unbuffered reads to access this file. Used with Wave
|
||||||
* Shield ISR. Used with Sd2Card::partialBlockRead() in WaveRP.
|
* Shield ISR. Used with Sd2Card::partialBlockRead() in WaveRP.
|
||||||
*
|
*
|
||||||
* Not recommended for normal applications.
|
* Not recommended for normal applications.
|
||||||
*/
|
*/
|
||||||
void setUnbufferedRead(void) {
|
void setUnbufferedRead(void) {
|
||||||
if (isFile()) flags_ |= F_FILE_UNBUFFERED_READ;
|
if (isFile()) flags_ |= F_FILE_UNBUFFERED_READ;
|
||||||
}
|
}
|
||||||
uint8_t timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day,
|
uint8_t timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day,
|
||||||
uint8_t hour, uint8_t minute, uint8_t second);
|
uint8_t hour, uint8_t minute, uint8_t second);
|
||||||
uint8_t sync(void);
|
uint8_t sync(void);
|
||||||
/** Type of this SdFile. You should use isFile() or isDir() instead of type()
|
/** Type of this SdFile. You should use isFile() or isDir() instead of type()
|
||||||
* if possible.
|
* if possible.
|
||||||
*
|
*
|
||||||
* \return The file or directory type.
|
* \return The file or directory type.
|
||||||
*/
|
*/
|
||||||
uint8_t type(void) const {return type_;}
|
uint8_t type(void) const {return type_;}
|
||||||
uint8_t truncate(uint32_t size);
|
uint8_t truncate(uint32_t size);
|
||||||
/** \return Unbuffered read flag. */
|
/** \return Unbuffered read flag. */
|
||||||
uint8_t unbufferedRead(void) const {
|
uint8_t unbufferedRead(void) const {
|
||||||
return flags_ & F_FILE_UNBUFFERED_READ;
|
return flags_ & F_FILE_UNBUFFERED_READ;
|
||||||
}
|
}
|
||||||
/** \return SdVolume that contains this file. */
|
/** \return SdVolume that contains this file. */
|
||||||
SdVolume* volume(void) const {return vol_;}
|
SdVolume* volume(void) const {return vol_;}
|
||||||
void write(uint8_t b);
|
void write(uint8_t b);
|
||||||
int16_t write(const void* buf, uint16_t nbyte);
|
int16_t write(const void* buf, uint16_t nbyte);
|
||||||
void write(const char* str);
|
void write(const char* str);
|
||||||
void write_P(PGM_P str);
|
void write_P(PGM_P str);
|
||||||
void writeln_P(PGM_P str);
|
void writeln_P(PGM_P str);
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#if ALLOW_DEPRECATED_FUNCTIONS
|
#if ALLOW_DEPRECATED_FUNCTIONS
|
||||||
// Deprecated functions - suppress cpplint warnings with NOLINT comment
|
// Deprecated functions - suppress cpplint warnings with NOLINT comment
|
||||||
/** \deprecated Use:
|
/** \deprecated Use:
|
||||||
* uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
|
* uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
|
||||||
*/
|
*/
|
||||||
uint8_t contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT
|
uint8_t contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT
|
||||||
return contiguousRange(&bgnBlock, &endBlock);
|
return contiguousRange(&bgnBlock, &endBlock);
|
||||||
}
|
}
|
||||||
/** \deprecated Use:
|
/** \deprecated Use:
|
||||||
* uint8_t SdFile::createContiguous(SdFile* dirFile,
|
* uint8_t SdFile::createContiguous(SdFile* dirFile,
|
||||||
* const char* fileName, uint32_t size)
|
* const char* fileName, uint32_t size)
|
||||||
*/
|
*/
|
||||||
uint8_t createContiguous(SdFile& dirFile, // NOLINT
|
uint8_t createContiguous(SdFile& dirFile, // NOLINT
|
||||||
const char* fileName, uint32_t size) {
|
const char* fileName, uint32_t size) {
|
||||||
return createContiguous(&dirFile, fileName, size);
|
return createContiguous(&dirFile, fileName, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \deprecated Use:
|
* \deprecated Use:
|
||||||
* static void SdFile::dateTimeCallback(
|
* static void SdFile::dateTimeCallback(
|
||||||
* void (*dateTime)(uint16_t* date, uint16_t* time));
|
* void (*dateTime)(uint16_t* date, uint16_t* time));
|
||||||
*/
|
*/
|
||||||
static void dateTimeCallback(
|
static void dateTimeCallback(
|
||||||
void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT
|
void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT
|
||||||
oldDateTime_ = dateTime;
|
oldDateTime_ = dateTime;
|
||||||
dateTime_ = dateTime ? oldToNew : 0;
|
dateTime_ = dateTime ? oldToNew : 0;
|
||||||
}
|
}
|
||||||
/** \deprecated Use: uint8_t SdFile::dirEntry(dir_t* dir); */
|
/** \deprecated Use: uint8_t SdFile::dirEntry(dir_t* dir); */
|
||||||
uint8_t dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT
|
uint8_t dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT
|
||||||
/** \deprecated Use:
|
/** \deprecated Use:
|
||||||
* uint8_t SdFile::makeDir(SdFile* dir, const char* dirName);
|
* uint8_t SdFile::makeDir(SdFile* dir, const char* dirName);
|
||||||
*/
|
*/
|
||||||
uint8_t makeDir(SdFile& dir, const char* dirName) { // NOLINT
|
uint8_t makeDir(SdFile& dir, const char* dirName) { // NOLINT
|
||||||
return makeDir(&dir, dirName);
|
return makeDir(&dir, dirName);
|
||||||
}
|
}
|
||||||
/** \deprecated Use:
|
/** \deprecated Use:
|
||||||
* uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag);
|
* uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag);
|
||||||
*/
|
*/
|
||||||
uint8_t open(SdFile& dirFile, // NOLINT
|
uint8_t open(SdFile& dirFile, // NOLINT
|
||||||
const char* fileName, uint8_t oflag) {
|
const char* fileName, uint8_t oflag) {
|
||||||
return open(&dirFile, fileName, oflag);
|
return open(&dirFile, fileName, oflag);
|
||||||
}
|
}
|
||||||
/** \deprecated Do not use in new apps */
|
/** \deprecated Do not use in new apps */
|
||||||
uint8_t open(SdFile& dirFile, const char* fileName) { // NOLINT
|
uint8_t open(SdFile& dirFile, const char* fileName) { // NOLINT
|
||||||
return open(dirFile, fileName, O_RDWR);
|
return open(dirFile, fileName, O_RDWR);
|
||||||
}
|
}
|
||||||
/** \deprecated Use:
|
/** \deprecated Use:
|
||||||
* uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag);
|
* uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag);
|
||||||
*/
|
*/
|
||||||
uint8_t open(SdFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT
|
uint8_t open(SdFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT
|
||||||
return open(&dirFile, index, oflag);
|
return open(&dirFile, index, oflag);
|
||||||
}
|
}
|
||||||
/** \deprecated Use: uint8_t SdFile::openRoot(SdVolume* vol); */
|
/** \deprecated Use: uint8_t SdFile::openRoot(SdVolume* vol); */
|
||||||
uint8_t openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT
|
uint8_t openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT
|
||||||
|
|
||||||
/** \deprecated Use: int8_t SdFile::readDir(dir_t* dir); */
|
/** \deprecated Use: int8_t SdFile::readDir(dir_t* dir); */
|
||||||
int8_t readDir(dir_t& dir) {return readDir(&dir);} // NOLINT
|
int8_t readDir(dir_t& dir) {return readDir(&dir);} // NOLINT
|
||||||
/** \deprecated Use:
|
/** \deprecated Use:
|
||||||
* static uint8_t SdFile::remove(SdFile* dirFile, const char* fileName);
|
* static uint8_t SdFile::remove(SdFile* dirFile, const char* fileName);
|
||||||
*/
|
*/
|
||||||
static uint8_t remove(SdFile& dirFile, const char* fileName) { // NOLINT
|
static uint8_t remove(SdFile& dirFile, const char* fileName) { // NOLINT
|
||||||
return remove(&dirFile, fileName);
|
return remove(&dirFile, fileName);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// rest are private
|
// rest are private
|
||||||
private:
|
private:
|
||||||
static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT
|
static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT
|
||||||
static void oldToNew(uint16_t* date, uint16_t* time) {
|
static void oldToNew(uint16_t* date, uint16_t* time) {
|
||||||
uint16_t d;
|
uint16_t d;
|
||||||
uint16_t t;
|
uint16_t t;
|
||||||
oldDateTime_(d, t);
|
oldDateTime_(d, t);
|
||||||
*date = d;
|
*date = d;
|
||||||
*time = t;
|
*time = t;
|
||||||
}
|
}
|
||||||
#endif // ALLOW_DEPRECATED_FUNCTIONS
|
#endif // ALLOW_DEPRECATED_FUNCTIONS
|
||||||
private:
|
private:
|
||||||
// bits defined in flags_
|
// bits defined in flags_
|
||||||
// should be 0XF
|
// should be 0XF
|
||||||
static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC);
|
static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC);
|
||||||
// available bits
|
// available bits
|
||||||
static uint8_t const F_UNUSED = 0X30;
|
static uint8_t const F_UNUSED = 0X30;
|
||||||
// use unbuffered SD read
|
// use unbuffered SD read
|
||||||
static uint8_t const F_FILE_UNBUFFERED_READ = 0X40;
|
static uint8_t const F_FILE_UNBUFFERED_READ = 0X40;
|
||||||
// sync of directory entry required
|
// sync of directory entry required
|
||||||
static uint8_t const F_FILE_DIR_DIRTY = 0X80;
|
static uint8_t const F_FILE_DIR_DIRTY = 0X80;
|
||||||
|
|
||||||
// make sure F_OFLAG is ok
|
// make sure F_OFLAG is ok
|
||||||
#if ((F_UNUSED | F_FILE_UNBUFFERED_READ | F_FILE_DIR_DIRTY) & F_OFLAG)
|
#if ((F_UNUSED | F_FILE_UNBUFFERED_READ | F_FILE_DIR_DIRTY) & F_OFLAG)
|
||||||
#error flags_ bits conflict
|
#error flags_ bits conflict
|
||||||
#endif // flags_ bits
|
#endif // flags_ bits
|
||||||
|
|
||||||
// private data
|
// private data
|
||||||
uint8_t flags_; // See above for definition of flags_ bits
|
uint8_t flags_; // See above for definition of flags_ bits
|
||||||
uint8_t type_; // type of file see above for values
|
uint8_t type_; // type of file see above for values
|
||||||
uint32_t curCluster_; // cluster for current file position
|
uint32_t curCluster_; // cluster for current file position
|
||||||
uint32_t curPosition_; // current file position in bytes from beginning
|
uint32_t curPosition_; // current file position in bytes from beginning
|
||||||
uint32_t dirBlock_; // SD block that contains directory entry for file
|
uint32_t dirBlock_; // SD block that contains directory entry for file
|
||||||
uint8_t dirIndex_; // index of entry in dirBlock 0 <= dirIndex_ <= 0XF
|
uint8_t dirIndex_; // index of entry in dirBlock 0 <= dirIndex_ <= 0XF
|
||||||
uint32_t fileSize_; // file size in bytes
|
uint32_t fileSize_; // file size in bytes
|
||||||
uint32_t firstCluster_; // first cluster of file
|
uint32_t firstCluster_; // first cluster of file
|
||||||
SdVolume* vol_; // volume where file is located
|
SdVolume* vol_; // volume where file is located
|
||||||
|
|
||||||
// private functions
|
// private functions
|
||||||
uint8_t addCluster(void);
|
uint8_t addCluster(void);
|
||||||
uint8_t addDirCluster(void);
|
uint8_t addDirCluster(void);
|
||||||
dir_t* cacheDirEntry(uint8_t action);
|
dir_t* cacheDirEntry(uint8_t action);
|
||||||
static void (*dateTime_)(uint16_t* date, uint16_t* time);
|
static void (*dateTime_)(uint16_t* date, uint16_t* time);
|
||||||
static uint8_t make83Name(const char* str, uint8_t* name);
|
static uint8_t make83Name(const char* str, uint8_t* name);
|
||||||
uint8_t openCachedEntry(uint8_t cacheIndex, uint8_t oflags);
|
uint8_t openCachedEntry(uint8_t cacheIndex, uint8_t oflags);
|
||||||
dir_t* readDirCache(void);
|
dir_t* readDirCache(void);
|
||||||
};
|
};
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// SdVolume class
|
// SdVolume class
|
||||||
/**
|
/**
|
||||||
* \brief Cache for an SD data block
|
* \brief Cache for an SD data block
|
||||||
*/
|
*/
|
||||||
union cache_t {
|
union cache_t {
|
||||||
/** Used to access cached file data blocks. */
|
/** Used to access cached file data blocks. */
|
||||||
uint8_t data[512];
|
uint8_t data[512];
|
||||||
/** Used to access cached FAT16 entries. */
|
/** Used to access cached FAT16 entries. */
|
||||||
uint16_t fat16[256];
|
uint16_t fat16[256];
|
||||||
/** Used to access cached FAT32 entries. */
|
/** Used to access cached FAT32 entries. */
|
||||||
uint32_t fat32[128];
|
uint32_t fat32[128];
|
||||||
/** Used to access cached directory entries. */
|
/** Used to access cached directory entries. */
|
||||||
dir_t dir[16];
|
dir_t dir[16];
|
||||||
/** Used to access a cached MasterBoot Record. */
|
/** Used to access a cached MasterBoot Record. */
|
||||||
mbr_t mbr;
|
mbr_t mbr;
|
||||||
/** Used to access to a cached FAT boot sector. */
|
/** Used to access to a cached FAT boot sector. */
|
||||||
fbs_t fbs;
|
fbs_t fbs;
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* \class SdVolume
|
* \class SdVolume
|
||||||
* \brief Access FAT16 and FAT32 volumes on SD and SDHC cards.
|
* \brief Access FAT16 and FAT32 volumes on SD and SDHC cards.
|
||||||
*/
|
*/
|
||||||
class SdVolume {
|
class SdVolume {
|
||||||
public:
|
public:
|
||||||
/** Create an instance of SdVolume */
|
/** Create an instance of SdVolume */
|
||||||
SdVolume(void) :allocSearchStart_(2), fatType_(0) {}
|
SdVolume(void) :allocSearchStart_(2), fatType_(0) {}
|
||||||
/** Clear the cache and returns a pointer to the cache. Used by the WaveRP
|
/** Clear the cache and returns a pointer to the cache. Used by the WaveRP
|
||||||
* recorder to do raw write to the SD card. Not for normal apps.
|
* recorder to do raw write to the SD card. Not for normal apps.
|
||||||
*/
|
*/
|
||||||
static uint8_t* cacheClear(void) {
|
static uint8_t* cacheClear(void) {
|
||||||
cacheFlush();
|
cacheFlush();
|
||||||
cacheBlockNumber_ = 0XFFFFFFFF;
|
cacheBlockNumber_ = 0XFFFFFFFF;
|
||||||
return cacheBuffer_.data;
|
return cacheBuffer_.data;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Initialize a FAT volume. Try partition one first then try super
|
* Initialize a FAT volume. Try partition one first then try super
|
||||||
* floppy format.
|
* floppy format.
|
||||||
*
|
*
|
||||||
* \param[in] dev The Sd2Card where the volume is located.
|
* \param[in] dev The Sd2Card where the volume is located.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure. Reasons for
|
* the value zero, false, is returned for failure. Reasons for
|
||||||
* failure include not finding a valid partition, not finding a valid
|
* failure include not finding a valid partition, not finding a valid
|
||||||
* FAT file system or an I/O error.
|
* FAT file system or an I/O error.
|
||||||
*/
|
*/
|
||||||
uint8_t init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);}
|
uint8_t init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);}
|
||||||
uint8_t init(Sd2Card* dev, uint8_t part);
|
uint8_t init(Sd2Card* dev, uint8_t part);
|
||||||
|
|
||||||
// inline functions that return volume info
|
// inline functions that return volume info
|
||||||
/** \return The volume's cluster size in blocks. */
|
/** \return The volume's cluster size in blocks. */
|
||||||
uint8_t blocksPerCluster(void) const {return blocksPerCluster_;}
|
uint8_t blocksPerCluster(void) const {return blocksPerCluster_;}
|
||||||
/** \return The number of blocks in one FAT. */
|
/** \return The number of blocks in one FAT. */
|
||||||
uint32_t blocksPerFat(void) const {return blocksPerFat_;}
|
uint32_t blocksPerFat(void) const {return blocksPerFat_;}
|
||||||
/** \return The total number of clusters in the volume. */
|
/** \return The total number of clusters in the volume. */
|
||||||
uint32_t clusterCount(void) const {return clusterCount_;}
|
uint32_t clusterCount(void) const {return clusterCount_;}
|
||||||
/** \return The shift count required to multiply by blocksPerCluster. */
|
/** \return The shift count required to multiply by blocksPerCluster. */
|
||||||
uint8_t clusterSizeShift(void) const {return clusterSizeShift_;}
|
uint8_t clusterSizeShift(void) const {return clusterSizeShift_;}
|
||||||
/** \return The logical block number for the start of file data. */
|
/** \return The logical block number for the start of file data. */
|
||||||
uint32_t dataStartBlock(void) const {return dataStartBlock_;}
|
uint32_t dataStartBlock(void) const {return dataStartBlock_;}
|
||||||
/** \return The number of FAT structures on the volume. */
|
/** \return The number of FAT structures on the volume. */
|
||||||
uint8_t fatCount(void) const {return fatCount_;}
|
uint8_t fatCount(void) const {return fatCount_;}
|
||||||
/** \return The logical block number for the start of the first FAT. */
|
/** \return The logical block number for the start of the first FAT. */
|
||||||
uint32_t fatStartBlock(void) const {return fatStartBlock_;}
|
uint32_t fatStartBlock(void) const {return fatStartBlock_;}
|
||||||
/** \return The FAT type of the volume. Values are 12, 16 or 32. */
|
/** \return The FAT type of the volume. Values are 12, 16 or 32. */
|
||||||
uint8_t fatType(void) const {return fatType_;}
|
uint8_t fatType(void) const {return fatType_;}
|
||||||
/** \return The number of entries in the root directory for FAT16 volumes. */
|
/** \return The number of entries in the root directory for FAT16 volumes. */
|
||||||
uint32_t rootDirEntryCount(void) const {return rootDirEntryCount_;}
|
uint32_t rootDirEntryCount(void) const {return rootDirEntryCount_;}
|
||||||
/** \return The logical block number for the start of the root directory
|
/** \return The logical block number for the start of the root directory
|
||||||
on FAT16 volumes or the first cluster number on FAT32 volumes. */
|
on FAT16 volumes or the first cluster number on FAT32 volumes. */
|
||||||
uint32_t rootDirStart(void) const {return rootDirStart_;}
|
uint32_t rootDirStart(void) const {return rootDirStart_;}
|
||||||
/** return a pointer to the Sd2Card object for this volume */
|
/** return a pointer to the Sd2Card object for this volume */
|
||||||
static Sd2Card* sdCard(void) {return sdCard_;}
|
static Sd2Card* sdCard(void) {return sdCard_;}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
#if ALLOW_DEPRECATED_FUNCTIONS
|
#if ALLOW_DEPRECATED_FUNCTIONS
|
||||||
// Deprecated functions - suppress cpplint warnings with NOLINT comment
|
// Deprecated functions - suppress cpplint warnings with NOLINT comment
|
||||||
/** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev); */
|
/** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev); */
|
||||||
uint8_t init(Sd2Card& dev) {return init(&dev);} // NOLINT
|
uint8_t init(Sd2Card& dev) {return init(&dev);} // NOLINT
|
||||||
|
|
||||||
/** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev, uint8_t vol); */
|
/** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev, uint8_t vol); */
|
||||||
uint8_t init(Sd2Card& dev, uint8_t part) { // NOLINT
|
uint8_t init(Sd2Card& dev, uint8_t part) { // NOLINT
|
||||||
return init(&dev, part);
|
return init(&dev, part);
|
||||||
}
|
}
|
||||||
#endif // ALLOW_DEPRECATED_FUNCTIONS
|
#endif // ALLOW_DEPRECATED_FUNCTIONS
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
private:
|
private:
|
||||||
// Allow SdFile access to SdVolume private data.
|
// Allow SdFile access to SdVolume private data.
|
||||||
friend class SdFile;
|
friend class SdFile;
|
||||||
|
|
||||||
// value for action argument in cacheRawBlock to indicate read from cache
|
// value for action argument in cacheRawBlock to indicate read from cache
|
||||||
static uint8_t const CACHE_FOR_READ = 0;
|
static uint8_t const CACHE_FOR_READ = 0;
|
||||||
// value for action argument in cacheRawBlock to indicate cache dirty
|
// value for action argument in cacheRawBlock to indicate cache dirty
|
||||||
static uint8_t const CACHE_FOR_WRITE = 1;
|
static uint8_t const CACHE_FOR_WRITE = 1;
|
||||||
|
|
||||||
static cache_t cacheBuffer_; // 512 byte cache for device blocks
|
static cache_t cacheBuffer_; // 512 byte cache for device blocks
|
||||||
static uint32_t cacheBlockNumber_; // Logical number of block in the cache
|
static uint32_t cacheBlockNumber_; // Logical number of block in the cache
|
||||||
static Sd2Card* sdCard_; // Sd2Card object for cache
|
static Sd2Card* sdCard_; // Sd2Card object for cache
|
||||||
static uint8_t cacheDirty_; // cacheFlush() will write block if true
|
static uint8_t cacheDirty_; // cacheFlush() will write block if true
|
||||||
static uint32_t cacheMirrorBlock_; // block number for mirror FAT
|
static uint32_t cacheMirrorBlock_; // block number for mirror FAT
|
||||||
//
|
//
|
||||||
uint32_t allocSearchStart_; // start cluster for alloc search
|
uint32_t allocSearchStart_; // start cluster for alloc search
|
||||||
uint8_t blocksPerCluster_; // cluster size in blocks
|
uint8_t blocksPerCluster_; // cluster size in blocks
|
||||||
uint32_t blocksPerFat_; // FAT size in blocks
|
uint32_t blocksPerFat_; // FAT size in blocks
|
||||||
uint32_t clusterCount_; // clusters in one FAT
|
uint32_t clusterCount_; // clusters in one FAT
|
||||||
uint8_t clusterSizeShift_; // shift to convert cluster count to block count
|
uint8_t clusterSizeShift_; // shift to convert cluster count to block count
|
||||||
uint32_t dataStartBlock_; // first data block number
|
uint32_t dataStartBlock_; // first data block number
|
||||||
uint8_t fatCount_; // number of FATs on volume
|
uint8_t fatCount_; // number of FATs on volume
|
||||||
uint32_t fatStartBlock_; // start block for first FAT
|
uint32_t fatStartBlock_; // start block for first FAT
|
||||||
uint8_t fatType_; // volume type (12, 16, OR 32)
|
uint8_t fatType_; // volume type (12, 16, OR 32)
|
||||||
uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir
|
uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir
|
||||||
uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32
|
uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
uint8_t allocContiguous(uint32_t count, uint32_t* curCluster);
|
uint8_t allocContiguous(uint32_t count, uint32_t* curCluster);
|
||||||
uint8_t blockOfCluster(uint32_t position) const {
|
uint8_t blockOfCluster(uint32_t position) const {
|
||||||
return (position >> 9) & (blocksPerCluster_ - 1);}
|
return (position >> 9) & (blocksPerCluster_ - 1);}
|
||||||
uint32_t clusterStartBlock(uint32_t cluster) const {
|
uint32_t clusterStartBlock(uint32_t cluster) const {
|
||||||
return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);}
|
return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);}
|
||||||
uint32_t blockNumber(uint32_t cluster, uint32_t position) const {
|
uint32_t blockNumber(uint32_t cluster, uint32_t position) const {
|
||||||
return clusterStartBlock(cluster) + blockOfCluster(position);}
|
return clusterStartBlock(cluster) + blockOfCluster(position);}
|
||||||
static uint8_t cacheFlush(void);
|
static uint8_t cacheFlush(void);
|
||||||
static uint8_t cacheRawBlock(uint32_t blockNumber, uint8_t action);
|
static uint8_t cacheRawBlock(uint32_t blockNumber, uint8_t action);
|
||||||
static void cacheSetDirty(void) {cacheDirty_ |= CACHE_FOR_WRITE;}
|
static void cacheSetDirty(void) {cacheDirty_ |= CACHE_FOR_WRITE;}
|
||||||
static uint8_t cacheZeroBlock(uint32_t blockNumber);
|
static uint8_t cacheZeroBlock(uint32_t blockNumber);
|
||||||
uint8_t chainSize(uint32_t beginCluster, uint32_t* size) const;
|
uint8_t chainSize(uint32_t beginCluster, uint32_t* size) const;
|
||||||
uint8_t fatGet(uint32_t cluster, uint32_t* value) const;
|
uint8_t fatGet(uint32_t cluster, uint32_t* value) const;
|
||||||
uint8_t fatPut(uint32_t cluster, uint32_t value);
|
uint8_t fatPut(uint32_t cluster, uint32_t value);
|
||||||
uint8_t fatPutEOC(uint32_t cluster) {
|
uint8_t fatPutEOC(uint32_t cluster) {
|
||||||
return fatPut(cluster, 0x0FFFFFFF);
|
return fatPut(cluster, 0x0FFFFFFF);
|
||||||
}
|
}
|
||||||
uint8_t freeChain(uint32_t cluster);
|
uint8_t freeChain(uint32_t cluster);
|
||||||
uint8_t isEOC(uint32_t cluster) const {
|
uint8_t isEOC(uint32_t cluster) const {
|
||||||
return cluster >= (fatType_ == 16 ? FAT16EOC_MIN : FAT32EOC_MIN);
|
return cluster >= (fatType_ == 16 ? FAT16EOC_MIN : FAT32EOC_MIN);
|
||||||
}
|
}
|
||||||
uint8_t readBlock(uint32_t block, uint8_t* dst) {
|
uint8_t readBlock(uint32_t block, uint8_t* dst) {
|
||||||
return sdCard_->readBlock(block, dst);}
|
return sdCard_->readBlock(block, dst);}
|
||||||
uint8_t readData(uint32_t block, uint16_t offset,
|
uint8_t readData(uint32_t block, uint16_t offset,
|
||||||
uint16_t count, uint8_t* dst) {
|
uint16_t count, uint8_t* dst) {
|
||||||
return sdCard_->readData(block, offset, count, dst);
|
return sdCard_->readData(block, offset, count, dst);
|
||||||
}
|
}
|
||||||
uint8_t writeBlock(uint32_t block, const uint8_t* dst) {
|
uint8_t writeBlock(uint32_t block, const uint8_t* dst) {
|
||||||
return sdCard_->writeBlock(block, dst);
|
return sdCard_->writeBlock(block, dst);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif // SdFat_h
|
#endif // SdFat_h
|
||||||
|
|
|
@ -1,70 +1,70 @@
|
||||||
/* Arduino SdFat Library
|
/* Arduino SdFat Library
|
||||||
* Copyright (C) 2008 by William Greiman
|
* Copyright (C) 2008 by William Greiman
|
||||||
*
|
*
|
||||||
* This file is part of the Arduino SdFat Library
|
* This file is part of the Arduino SdFat Library
|
||||||
*
|
*
|
||||||
* This Library is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This Library is distributed in the hope that it will be useful,
|
* This Library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with the Arduino SdFat Library. If not, see
|
* along with the Arduino SdFat Library. If not, see
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#ifndef SdFatUtil_h
|
#ifndef SdFatUtil_h
|
||||||
#define SdFatUtil_h
|
#define SdFatUtil_h
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* Useful utility functions.
|
* Useful utility functions.
|
||||||
*/
|
*/
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
/** Store and print a string in flash memory.*/
|
/** Store and print a string in flash memory.*/
|
||||||
#define PgmPrint(x) SerialPrint_P(PSTR(x))
|
#define PgmPrint(x) SerialPrint_P(PSTR(x))
|
||||||
/** Store and print a string in flash memory followed by a CR/LF.*/
|
/** Store and print a string in flash memory followed by a CR/LF.*/
|
||||||
#define PgmPrintln(x) SerialPrintln_P(PSTR(x))
|
#define PgmPrintln(x) SerialPrintln_P(PSTR(x))
|
||||||
/** Defined so doxygen works for function definitions. */
|
/** Defined so doxygen works for function definitions. */
|
||||||
#define NOINLINE __attribute__((noinline))
|
#define NOINLINE __attribute__((noinline))
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Return the number of bytes currently free in RAM. */
|
/** Return the number of bytes currently free in RAM. */
|
||||||
static int FreeRam(void) {
|
static int FreeRam(void) {
|
||||||
extern int __bss_end;
|
extern int __bss_end;
|
||||||
extern int* __brkval;
|
extern int* __brkval;
|
||||||
int free_memory;
|
int free_memory;
|
||||||
if (reinterpret_cast<int>(__brkval) == 0) {
|
if (reinterpret_cast<int>(__brkval) == 0) {
|
||||||
// if no heap use from end of bss section
|
// if no heap use from end of bss section
|
||||||
free_memory = reinterpret_cast<int>(&free_memory)
|
free_memory = reinterpret_cast<int>(&free_memory)
|
||||||
- reinterpret_cast<int>(&__bss_end);
|
- reinterpret_cast<int>(&__bss_end);
|
||||||
} else {
|
} else {
|
||||||
// use from top of stack to heap
|
// use from top of stack to heap
|
||||||
free_memory = reinterpret_cast<int>(&free_memory)
|
free_memory = reinterpret_cast<int>(&free_memory)
|
||||||
- reinterpret_cast<int>(__brkval);
|
- reinterpret_cast<int>(__brkval);
|
||||||
}
|
}
|
||||||
return free_memory;
|
return free_memory;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* %Print a string in flash memory to the serial port.
|
* %Print a string in flash memory to the serial port.
|
||||||
*
|
*
|
||||||
* \param[in] str Pointer to string stored in flash memory.
|
* \param[in] str Pointer to string stored in flash memory.
|
||||||
*/
|
*/
|
||||||
static NOINLINE void SerialPrint_P(PGM_P str) {
|
static NOINLINE void SerialPrint_P(PGM_P str) {
|
||||||
for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.print(c);
|
for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.print(c);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* %Print a string in flash memory followed by a CR/LF.
|
* %Print a string in flash memory followed by a CR/LF.
|
||||||
*
|
*
|
||||||
* \param[in] str Pointer to string stored in flash memory.
|
* \param[in] str Pointer to string stored in flash memory.
|
||||||
*/
|
*/
|
||||||
static NOINLINE void SerialPrintln_P(PGM_P str) {
|
static NOINLINE void SerialPrintln_P(PGM_P str) {
|
||||||
SerialPrint_P(str);
|
SerialPrint_P(str);
|
||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
}
|
||||||
#endif // #define SdFatUtil_h
|
#endif // #define SdFatUtil_h
|
||||||
|
|
|
@ -1,202 +1,202 @@
|
||||||
/* Arduino SdFat Library
|
/* Arduino SdFat Library
|
||||||
* Copyright (C) 2009 by William Greiman
|
* Copyright (C) 2009 by William Greiman
|
||||||
*
|
*
|
||||||
* This file is part of the Arduino SdFat Library
|
* This file is part of the Arduino SdFat Library
|
||||||
*
|
*
|
||||||
* This Library is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This Library is distributed in the hope that it will be useful,
|
* This Library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with the Arduino SdFat Library. If not, see
|
* along with the Arduino SdFat Library. If not, see
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\mainpage Arduino SdFat Library
|
\mainpage Arduino SdFat Library
|
||||||
<CENTER>Copyright © 2009 by William Greiman
|
<CENTER>Copyright © 2009 by William Greiman
|
||||||
</CENTER>
|
</CENTER>
|
||||||
|
|
||||||
\section Intro Introduction
|
\section Intro Introduction
|
||||||
The Arduino SdFat Library is a minimal implementation of FAT16 and FAT32
|
The Arduino SdFat Library is a minimal implementation of FAT16 and FAT32
|
||||||
file systems on SD flash memory cards. Standard SD and high capacity
|
file systems on SD flash memory cards. Standard SD and high capacity
|
||||||
SDHC cards are supported.
|
SDHC cards are supported.
|
||||||
|
|
||||||
The SdFat only supports short 8.3 names.
|
The SdFat only supports short 8.3 names.
|
||||||
|
|
||||||
The main classes in SdFat are Sd2Card, SdVolume, and SdFile.
|
The main classes in SdFat are Sd2Card, SdVolume, and SdFile.
|
||||||
|
|
||||||
The Sd2Card class supports access to standard SD cards and SDHC cards. Most
|
The Sd2Card class supports access to standard SD cards and SDHC cards. Most
|
||||||
applications will only need to call the Sd2Card::init() member function.
|
applications will only need to call the Sd2Card::init() member function.
|
||||||
|
|
||||||
The SdVolume class supports FAT16 and FAT32 partitions. Most applications
|
The SdVolume class supports FAT16 and FAT32 partitions. Most applications
|
||||||
will only need to call the SdVolume::init() member function.
|
will only need to call the SdVolume::init() member function.
|
||||||
|
|
||||||
The SdFile class provides file access functions such as open(), read(),
|
The SdFile class provides file access functions such as open(), read(),
|
||||||
remove(), write(), close() and sync(). This class supports access to the root
|
remove(), write(), close() and sync(). This class supports access to the root
|
||||||
directory and subdirectories.
|
directory and subdirectories.
|
||||||
|
|
||||||
A number of example are provided in the SdFat/examples folder. These were
|
A number of example are provided in the SdFat/examples folder. These were
|
||||||
developed to test SdFat and illustrate its use.
|
developed to test SdFat and illustrate its use.
|
||||||
|
|
||||||
SdFat was developed for high speed data recording. SdFat was used to implement
|
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
|
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.
|
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
|
These functions reduce write latency so that audio can be recorded with the
|
||||||
small amount of RAM in the Arduino.
|
small amount of RAM in the Arduino.
|
||||||
|
|
||||||
\section SDcard SD\SDHC Cards
|
\section SDcard SD\SDHC Cards
|
||||||
|
|
||||||
Arduinos access SD cards using the cards SPI protocol. PCs, Macs, and
|
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
|
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.
|
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
|
Most cards have good SPI read performance but cards vary widely in SPI
|
||||||
write performance. Write performance is limited by how efficiently the
|
write performance. Write performance is limited by how efficiently the
|
||||||
card manages internal erase/remapping operations. The Arduino cannot
|
card manages internal erase/remapping operations. The Arduino cannot
|
||||||
optimize writes to reduce erase operations because of its limit RAM.
|
optimize writes to reduce erase operations because of its limit RAM.
|
||||||
|
|
||||||
SanDisk cards generally have good write performance. They seem to have
|
SanDisk cards generally have good write performance. They seem to have
|
||||||
more internal RAM buffering than other cards and therefore can limit
|
more internal RAM buffering than other cards and therefore can limit
|
||||||
the number of flash erase operations that the Arduino forces due to its
|
the number of flash erase operations that the Arduino forces due to its
|
||||||
limited RAM.
|
limited RAM.
|
||||||
|
|
||||||
\section Hardware Hardware Configuration
|
\section Hardware Hardware Configuration
|
||||||
|
|
||||||
SdFat was developed using an
|
SdFat was developed using an
|
||||||
<A HREF = "http://www.adafruit.com/"> Adafruit Industries</A>
|
<A HREF = "http://www.adafruit.com/"> Adafruit Industries</A>
|
||||||
<A HREF = "http://www.ladyada.net/make/waveshield/"> Wave Shield</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
|
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
|
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
|
rise times that are too slow for the edge detectors in many newer SD card
|
||||||
controllers when resistor voltage dividers are used.
|
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
|
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
|
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
|
uses a 74AHC125N. Gravitech sells SD and MicroSD Card Adapters based on the
|
||||||
74LCX245.
|
74LCX245.
|
||||||
|
|
||||||
If you are using a resistor based level shifter and are having problems try
|
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
|
setting the SPI bus frequency to 4 MHz. This can be done by using
|
||||||
card.init(SPI_HALF_SPEED) to initialize the SD card.
|
card.init(SPI_HALF_SPEED) to initialize the SD card.
|
||||||
|
|
||||||
\section comment Bugs and Comments
|
\section comment Bugs and Comments
|
||||||
|
|
||||||
If you wish to report bugs or have comments, send email to fat16lib@sbcglobal.net.
|
If you wish to report bugs or have comments, send email to fat16lib@sbcglobal.net.
|
||||||
|
|
||||||
\section SdFatClass SdFat Usage
|
\section SdFatClass SdFat Usage
|
||||||
|
|
||||||
SdFat uses a slightly restricted form of short names.
|
SdFat uses a slightly restricted form of short names.
|
||||||
Only printable ASCII characters are supported. No characters with code point
|
Only printable ASCII characters are supported. No characters with code point
|
||||||
values greater than 127 are allowed. Space is not allowed even though space
|
values greater than 127 are allowed. Space is not allowed even though space
|
||||||
was allowed in the API of early versions of DOS.
|
was allowed in the API of early versions of DOS.
|
||||||
|
|
||||||
Short names are limited to 8 characters followed by an optional period (.)
|
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
|
and extension of up to 3 characters. The characters may be any combination
|
||||||
of letters and digits. The following special characters are also allowed:
|
of letters and digits. The following special characters are also allowed:
|
||||||
|
|
||||||
$ % ' - _ @ ~ ` ! ( ) { } ^ # &
|
$ % ' - _ @ ~ ` ! ( ) { } ^ # &
|
||||||
|
|
||||||
Short names are always converted to upper case and their original case
|
Short names are always converted to upper case and their original case
|
||||||
value is lost.
|
value is lost.
|
||||||
|
|
||||||
\note
|
\note
|
||||||
The Arduino Print class uses character
|
The Arduino Print class uses character
|
||||||
at a time writes so it was necessary to use a \link SdFile::sync() sync() \endlink
|
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.
|
function to control when data is written to the SD card.
|
||||||
|
|
||||||
\par
|
\par
|
||||||
An application which writes to a file using \link Print::print() print()\endlink,
|
An application which writes to a file using \link Print::print() print()\endlink,
|
||||||
\link Print::println() println() \endlink
|
\link Print::println() println() \endlink
|
||||||
or \link SdFile::write write() \endlink must call \link SdFile::sync() sync() \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
|
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
|
to the SD Card. Data and directory information are also written to the SD card
|
||||||
when \link SdFile::close() close() \endlink is called.
|
when \link SdFile::close() close() \endlink is called.
|
||||||
|
|
||||||
\par
|
\par
|
||||||
Applications must use care calling \link SdFile::sync() sync() \endlink
|
Applications must use care calling \link SdFile::sync() sync() \endlink
|
||||||
since 2048 bytes of I/O is required to update file and
|
since 2048 bytes of I/O is required to update file and
|
||||||
directory information. This includes writing the current data block, reading
|
directory information. This includes writing the current data block, reading
|
||||||
the block that contains the directory entry for update, writing the directory
|
the block that contains the directory entry for update, writing the directory
|
||||||
block back and reading back the current data block.
|
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
|
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.
|
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
|
\section HowTo How to format SD Cards as FAT Volumes
|
||||||
|
|
||||||
You should use a freshly formatted SD card for best performance. FAT
|
You should use a freshly formatted SD card for best performance. FAT
|
||||||
file systems become slower if many files have been created and deleted.
|
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,
|
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
|
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
|
before creating the file, a flaw in the FAT design. Also files can become
|
||||||
fragmented which causes reads and writes to be slower.
|
fragmented which causes reads and writes to be slower.
|
||||||
|
|
||||||
Microsoft operating systems support removable media formatted with a
|
Microsoft operating systems support removable media formatted with a
|
||||||
Master Boot Record, MBR, or formatted as a super floppy with a FAT Boot Sector
|
Master Boot Record, MBR, or formatted as a super floppy with a FAT Boot Sector
|
||||||
in block zero.
|
in block zero.
|
||||||
|
|
||||||
Microsoft operating systems expect MBR formatted removable media
|
Microsoft operating systems expect MBR formatted removable media
|
||||||
to have only one partition. The first partition should be used.
|
to have only one partition. The first partition should be used.
|
||||||
|
|
||||||
Microsoft operating systems do not support partitioning SD flash cards.
|
Microsoft operating systems do not support partitioning SD flash cards.
|
||||||
If you erase an SD card with a program like KillDisk, Most versions of
|
If you erase an SD card with a program like KillDisk, Most versions of
|
||||||
Windows will format the card as a super floppy.
|
Windows will format the card as a super floppy.
|
||||||
|
|
||||||
The best way to restore an SD card's format is to use SDFormatter
|
The best way to restore an SD card's format is to use SDFormatter
|
||||||
which can be downloaded from:
|
which can be downloaded from:
|
||||||
|
|
||||||
http://www.sdcard.org/consumers/formatter/
|
http://www.sdcard.org/consumers/formatter/
|
||||||
|
|
||||||
SDFormatter aligns flash erase boundaries with file
|
SDFormatter aligns flash erase boundaries with file
|
||||||
system structures which reduces write latency and file system overhead.
|
system structures which reduces write latency and file system overhead.
|
||||||
|
|
||||||
SDFormatter does not have an option for FAT type so it may format
|
SDFormatter does not have an option for FAT type so it may format
|
||||||
small cards as FAT12.
|
small cards as FAT12.
|
||||||
|
|
||||||
After the MBR is restored by SDFormatter you may need to reformat small
|
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.
|
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
|
If you reformat the SD card with an OS utility, choose a cluster size that
|
||||||
will result in:
|
will result in:
|
||||||
|
|
||||||
4084 < CountOfClusters && CountOfClusters < 65525
|
4084 < CountOfClusters && CountOfClusters < 65525
|
||||||
|
|
||||||
The volume will then be FAT16.
|
The volume will then be FAT16.
|
||||||
|
|
||||||
If you are formatting an SD card on OS X or Linux, be sure to use the first
|
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.
|
partition. Format this partition with a cluster count in above range.
|
||||||
|
|
||||||
\section References References
|
\section References References
|
||||||
|
|
||||||
Adafruit Industries:
|
Adafruit Industries:
|
||||||
|
|
||||||
http://www.adafruit.com/
|
http://www.adafruit.com/
|
||||||
|
|
||||||
http://www.ladyada.net/make/waveshield/
|
http://www.ladyada.net/make/waveshield/
|
||||||
|
|
||||||
The Arduino site:
|
The Arduino site:
|
||||||
|
|
||||||
http://www.arduino.cc/
|
http://www.arduino.cc/
|
||||||
|
|
||||||
For more information about FAT file systems see:
|
For more information about FAT file systems see:
|
||||||
|
|
||||||
http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
||||||
|
|
||||||
For information about using SD cards as SPI devices see:
|
For information about using SD cards as SPI devices see:
|
||||||
|
|
||||||
http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
|
http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
|
||||||
|
|
||||||
The ATmega328 datasheet:
|
The ATmega328 datasheet:
|
||||||
|
|
||||||
http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf
|
http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
2504
Marlin/SdFile.cpp
2504
Marlin/SdFile.cpp
|
@ -1,1252 +1,1252 @@
|
||||||
/* Arduino SdFat Library
|
/* Arduino SdFat Library
|
||||||
* Copyright (C) 2009 by William Greiman
|
* Copyright (C) 2009 by William Greiman
|
||||||
*
|
*
|
||||||
* This file is part of the Arduino SdFat Library
|
* This file is part of the Arduino SdFat Library
|
||||||
*
|
*
|
||||||
* This Library is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This Library is distributed in the hope that it will be useful,
|
* This Library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with the Arduino SdFat Library. If not, see
|
* along with the Arduino SdFat Library. If not, see
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "SdFat.h"
|
#include "SdFat.h"
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// callback function for date/time
|
// callback function for date/time
|
||||||
void (*SdFile::dateTime_)(uint16_t* date, uint16_t* time) = NULL;
|
void (*SdFile::dateTime_)(uint16_t* date, uint16_t* time) = NULL;
|
||||||
|
|
||||||
#if ALLOW_DEPRECATED_FUNCTIONS
|
#if ALLOW_DEPRECATED_FUNCTIONS
|
||||||
// suppress cpplint warnings with NOLINT comment
|
// suppress cpplint warnings with NOLINT comment
|
||||||
void (*SdFile::oldDateTime_)(uint16_t& date, uint16_t& time) = NULL; // NOLINT
|
void (*SdFile::oldDateTime_)(uint16_t& date, uint16_t& time) = NULL; // NOLINT
|
||||||
#endif // ALLOW_DEPRECATED_FUNCTIONS
|
#endif // ALLOW_DEPRECATED_FUNCTIONS
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// add a cluster to a file
|
// add a cluster to a file
|
||||||
uint8_t SdFile::addCluster() {
|
uint8_t SdFile::addCluster() {
|
||||||
if (!vol_->allocContiguous(1, &curCluster_)) return false;
|
if (!vol_->allocContiguous(1, &curCluster_)) return false;
|
||||||
|
|
||||||
// if first cluster of file link to directory entry
|
// if first cluster of file link to directory entry
|
||||||
if (firstCluster_ == 0) {
|
if (firstCluster_ == 0) {
|
||||||
firstCluster_ = curCluster_;
|
firstCluster_ = curCluster_;
|
||||||
flags_ |= F_FILE_DIR_DIRTY;
|
flags_ |= F_FILE_DIR_DIRTY;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Add a cluster to a directory file and zero the cluster.
|
// Add a cluster to a directory file and zero the cluster.
|
||||||
// return with first block of cluster in the cache
|
// return with first block of cluster in the cache
|
||||||
uint8_t SdFile::addDirCluster(void) {
|
uint8_t SdFile::addDirCluster(void) {
|
||||||
if (!addCluster()) return false;
|
if (!addCluster()) return false;
|
||||||
|
|
||||||
// zero data in cluster insure first cluster is in cache
|
// zero data in cluster insure first cluster is in cache
|
||||||
uint32_t block = vol_->clusterStartBlock(curCluster_);
|
uint32_t block = vol_->clusterStartBlock(curCluster_);
|
||||||
for (uint8_t i = vol_->blocksPerCluster_; i != 0; i--) {
|
for (uint8_t i = vol_->blocksPerCluster_; i != 0; i--) {
|
||||||
if (!SdVolume::cacheZeroBlock(block + i - 1)) return false;
|
if (!SdVolume::cacheZeroBlock(block + i - 1)) return false;
|
||||||
}
|
}
|
||||||
// Increase directory file size by cluster size
|
// Increase directory file size by cluster size
|
||||||
fileSize_ += 512UL << vol_->clusterSizeShift_;
|
fileSize_ += 512UL << vol_->clusterSizeShift_;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// cache a file's directory entry
|
// cache a file's directory entry
|
||||||
// return pointer to cached entry or null for failure
|
// return pointer to cached entry or null for failure
|
||||||
dir_t* SdFile::cacheDirEntry(uint8_t action) {
|
dir_t* SdFile::cacheDirEntry(uint8_t action) {
|
||||||
if (!SdVolume::cacheRawBlock(dirBlock_, action)) return NULL;
|
if (!SdVolume::cacheRawBlock(dirBlock_, action)) return NULL;
|
||||||
return SdVolume::cacheBuffer_.dir + dirIndex_;
|
return SdVolume::cacheBuffer_.dir + dirIndex_;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Close a file and force cached data and directory information
|
* Close a file and force cached data and directory information
|
||||||
* to be written to the storage device.
|
* to be written to the storage device.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include no file is open or an I/O error.
|
* Reasons for failure include no file is open or an I/O error.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::close(void) {
|
uint8_t SdFile::close(void) {
|
||||||
if (!sync())return false;
|
if (!sync())return false;
|
||||||
type_ = FAT_FILE_TYPE_CLOSED;
|
type_ = FAT_FILE_TYPE_CLOSED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Check for contiguous file and return its raw block range.
|
* Check for contiguous file and return its raw block range.
|
||||||
*
|
*
|
||||||
* \param[out] bgnBlock the first block address for the file.
|
* \param[out] bgnBlock the first block address for the file.
|
||||||
* \param[out] endBlock the last block address for the file.
|
* \param[out] endBlock the last block address for the file.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include file is not contiguous, file has zero length
|
* Reasons for failure include file is not contiguous, file has zero length
|
||||||
* or an I/O error occurred.
|
* or an I/O error occurred.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
|
uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
|
||||||
// error if no blocks
|
// error if no blocks
|
||||||
if (firstCluster_ == 0) return false;
|
if (firstCluster_ == 0) return false;
|
||||||
|
|
||||||
for (uint32_t c = firstCluster_; ; c++) {
|
for (uint32_t c = firstCluster_; ; c++) {
|
||||||
uint32_t next;
|
uint32_t next;
|
||||||
if (!vol_->fatGet(c, &next)) return false;
|
if (!vol_->fatGet(c, &next)) return false;
|
||||||
|
|
||||||
// check for contiguous
|
// check for contiguous
|
||||||
if (next != (c + 1)) {
|
if (next != (c + 1)) {
|
||||||
// error if not end of chain
|
// error if not end of chain
|
||||||
if (!vol_->isEOC(next)) return false;
|
if (!vol_->isEOC(next)) return false;
|
||||||
*bgnBlock = vol_->clusterStartBlock(firstCluster_);
|
*bgnBlock = vol_->clusterStartBlock(firstCluster_);
|
||||||
*endBlock = vol_->clusterStartBlock(c)
|
*endBlock = vol_->clusterStartBlock(c)
|
||||||
+ vol_->blocksPerCluster_ - 1;
|
+ vol_->blocksPerCluster_ - 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Create and open a new contiguous file of a specified size.
|
* Create and open a new contiguous file of a specified size.
|
||||||
*
|
*
|
||||||
* \note This function only supports short DOS 8.3 names.
|
* \note This function only supports short DOS 8.3 names.
|
||||||
* See open() for more information.
|
* See open() for more information.
|
||||||
*
|
*
|
||||||
* \param[in] dirFile The directory where the file will be created.
|
* \param[in] dirFile The directory where the file will be created.
|
||||||
* \param[in] fileName A valid DOS 8.3 file name.
|
* \param[in] fileName A valid DOS 8.3 file name.
|
||||||
* \param[in] size The desired file size.
|
* \param[in] size The desired file size.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include \a fileName contains
|
* Reasons for failure include \a fileName contains
|
||||||
* an invalid DOS 8.3 file name, the FAT volume has not been initialized,
|
* an invalid DOS 8.3 file name, the FAT volume has not been initialized,
|
||||||
* a file is already open, the file already exists, the root
|
* a file is already open, the file already exists, the root
|
||||||
* directory is full or an I/O error.
|
* directory is full or an I/O error.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::createContiguous(SdFile* dirFile,
|
uint8_t SdFile::createContiguous(SdFile* dirFile,
|
||||||
const char* fileName, uint32_t size) {
|
const char* fileName, uint32_t size) {
|
||||||
// don't allow zero length file
|
// don't allow zero length file
|
||||||
if (size == 0) return false;
|
if (size == 0) return false;
|
||||||
if (!open(dirFile, fileName, O_CREAT | O_EXCL | O_RDWR)) return false;
|
if (!open(dirFile, fileName, O_CREAT | O_EXCL | O_RDWR)) return false;
|
||||||
|
|
||||||
// calculate number of clusters needed
|
// calculate number of clusters needed
|
||||||
uint32_t count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1;
|
uint32_t count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1;
|
||||||
|
|
||||||
// allocate clusters
|
// allocate clusters
|
||||||
if (!vol_->allocContiguous(count, &firstCluster_)) {
|
if (!vol_->allocContiguous(count, &firstCluster_)) {
|
||||||
remove();
|
remove();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fileSize_ = size;
|
fileSize_ = size;
|
||||||
|
|
||||||
// insure sync() will update dir entry
|
// insure sync() will update dir entry
|
||||||
flags_ |= F_FILE_DIR_DIRTY;
|
flags_ |= F_FILE_DIR_DIRTY;
|
||||||
return sync();
|
return sync();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Return a files directory entry
|
* Return a files directory entry
|
||||||
*
|
*
|
||||||
* \param[out] dir Location for return of the files directory entry.
|
* \param[out] dir Location for return of the files directory entry.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::dirEntry(dir_t* dir) {
|
uint8_t SdFile::dirEntry(dir_t* dir) {
|
||||||
// make sure fields on SD are correct
|
// make sure fields on SD are correct
|
||||||
if (!sync()) return false;
|
if (!sync()) return false;
|
||||||
|
|
||||||
// read entry
|
// read entry
|
||||||
dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
|
dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
|
||||||
if (!p) return false;
|
if (!p) return false;
|
||||||
|
|
||||||
// copy to caller's struct
|
// copy to caller's struct
|
||||||
memcpy(dir, p, sizeof(dir_t));
|
memcpy(dir, p, sizeof(dir_t));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Format the name field of \a dir into the 13 byte array
|
* Format the name field of \a dir into the 13 byte array
|
||||||
* \a name in standard 8.3 short name format.
|
* \a name in standard 8.3 short name format.
|
||||||
*
|
*
|
||||||
* \param[in] dir The directory structure containing the name.
|
* \param[in] dir The directory structure containing the name.
|
||||||
* \param[out] name A 13 byte char array for the formatted name.
|
* \param[out] name A 13 byte char array for the formatted name.
|
||||||
*/
|
*/
|
||||||
void SdFile::dirName(const dir_t& dir, char* name) {
|
void SdFile::dirName(const dir_t& dir, char* name) {
|
||||||
uint8_t j = 0;
|
uint8_t j = 0;
|
||||||
for (uint8_t i = 0; i < 11; i++) {
|
for (uint8_t i = 0; i < 11; i++) {
|
||||||
if (dir.name[i] == ' ')continue;
|
if (dir.name[i] == ' ')continue;
|
||||||
if (i == 8) name[j++] = '.';
|
if (i == 8) name[j++] = '.';
|
||||||
name[j++] = dir.name[i];
|
name[j++] = dir.name[i];
|
||||||
}
|
}
|
||||||
name[j] = 0;
|
name[j] = 0;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** List directory contents to Serial.
|
/** List directory contents to Serial.
|
||||||
*
|
*
|
||||||
* \param[in] flags The inclusive OR of
|
* \param[in] flags The inclusive OR of
|
||||||
*
|
*
|
||||||
* LS_DATE - %Print file modification date
|
* LS_DATE - %Print file modification date
|
||||||
*
|
*
|
||||||
* LS_SIZE - %Print file size.
|
* LS_SIZE - %Print file size.
|
||||||
*
|
*
|
||||||
* LS_R - Recursive list of subdirectories.
|
* LS_R - Recursive list of subdirectories.
|
||||||
*
|
*
|
||||||
* \param[in] indent Amount of space before file name. Used for recursive
|
* \param[in] indent Amount of space before file name. Used for recursive
|
||||||
* list to indicate subdirectory level.
|
* list to indicate subdirectory level.
|
||||||
*/
|
*/
|
||||||
void SdFile::ls(uint8_t flags, uint8_t indent) {
|
void SdFile::ls(uint8_t flags, uint8_t indent) {
|
||||||
dir_t* p;
|
dir_t* p;
|
||||||
|
|
||||||
rewind();
|
rewind();
|
||||||
while ((p = readDirCache())) {
|
while ((p = readDirCache())) {
|
||||||
// done if past last used entry
|
// done if past last used entry
|
||||||
if (p->name[0] == DIR_NAME_FREE) break;
|
if (p->name[0] == DIR_NAME_FREE) break;
|
||||||
|
|
||||||
// skip deleted entry and entries for . and ..
|
// skip deleted entry and entries for . and ..
|
||||||
if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
|
if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
|
||||||
|
|
||||||
// only list subdirectories and files
|
// only list subdirectories and files
|
||||||
if (!DIR_IS_FILE_OR_SUBDIR(p)) continue;
|
if (!DIR_IS_FILE_OR_SUBDIR(p)) continue;
|
||||||
|
|
||||||
// print any indent spaces
|
// print any indent spaces
|
||||||
for (int8_t i = 0; i < indent; i++) Serial.print(' ');
|
for (int8_t i = 0; i < indent; i++) Serial.print(' ');
|
||||||
|
|
||||||
// print file name with possible blank fill
|
// print file name with possible blank fill
|
||||||
printDirName(*p, flags & (LS_DATE | LS_SIZE) ? 14 : 0);
|
printDirName(*p, flags & (LS_DATE | LS_SIZE) ? 14 : 0);
|
||||||
|
|
||||||
// print modify date/time if requested
|
// print modify date/time if requested
|
||||||
if (flags & LS_DATE) {
|
if (flags & LS_DATE) {
|
||||||
printFatDate(p->lastWriteDate);
|
printFatDate(p->lastWriteDate);
|
||||||
Serial.print(' ');
|
Serial.print(' ');
|
||||||
printFatTime(p->lastWriteTime);
|
printFatTime(p->lastWriteTime);
|
||||||
}
|
}
|
||||||
// print size if requested
|
// print size if requested
|
||||||
if (!DIR_IS_SUBDIR(p) && (flags & LS_SIZE)) {
|
if (!DIR_IS_SUBDIR(p) && (flags & LS_SIZE)) {
|
||||||
Serial.print(' ');
|
Serial.print(' ');
|
||||||
Serial.print(p->fileSize);
|
Serial.print(p->fileSize);
|
||||||
}
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
|
||||||
// list subdirectory content if requested
|
// list subdirectory content if requested
|
||||||
if ((flags & LS_R) && DIR_IS_SUBDIR(p)) {
|
if ((flags & LS_R) && DIR_IS_SUBDIR(p)) {
|
||||||
uint16_t index = curPosition()/32 - 1;
|
uint16_t index = curPosition()/32 - 1;
|
||||||
SdFile s;
|
SdFile s;
|
||||||
if (s.open(this, index, O_READ)) s.ls(flags, indent + 2);
|
if (s.open(this, index, O_READ)) s.ls(flags, indent + 2);
|
||||||
seekSet(32 * (index + 1));
|
seekSet(32 * (index + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// format directory name field from a 8.3 name string
|
// format directory name field from a 8.3 name string
|
||||||
uint8_t SdFile::make83Name(const char* str, uint8_t* name) {
|
uint8_t SdFile::make83Name(const char* str, uint8_t* name) {
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
uint8_t n = 7; // max index for part before dot
|
uint8_t n = 7; // max index for part before dot
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
// blank fill name and extension
|
// blank fill name and extension
|
||||||
while (i < 11) name[i++] = ' ';
|
while (i < 11) name[i++] = ' ';
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((c = *str++) != '\0') {
|
while ((c = *str++) != '\0') {
|
||||||
if (c == '.') {
|
if (c == '.') {
|
||||||
if (n == 10) return false; // only one dot allowed
|
if (n == 10) return false; // only one dot allowed
|
||||||
n = 10; // max index for full 8.3 name
|
n = 10; // max index for full 8.3 name
|
||||||
i = 8; // place for extension
|
i = 8; // place for extension
|
||||||
} else {
|
} else {
|
||||||
// illegal FAT characters
|
// illegal FAT characters
|
||||||
PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
|
PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
while ((b = pgm_read_byte(p++))) if (b == c) return false;
|
while ((b = pgm_read_byte(p++))) if (b == c) return false;
|
||||||
// check size and only allow ASCII printable characters
|
// check size and only allow ASCII printable characters
|
||||||
if (i > n || c < 0X21 || c > 0X7E)return false;
|
if (i > n || c < 0X21 || c > 0X7E)return false;
|
||||||
// only upper case allowed in 8.3 names - convert lower to upper
|
// only upper case allowed in 8.3 names - convert lower to upper
|
||||||
name[i++] = c < 'a' || c > 'z' ? c : c + ('A' - 'a');
|
name[i++] = c < 'a' || c > 'z' ? c : c + ('A' - 'a');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// must have a file name, extension is optional
|
// must have a file name, extension is optional
|
||||||
return name[0] != ' ';
|
return name[0] != ' ';
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Make a new directory.
|
/** Make a new directory.
|
||||||
*
|
*
|
||||||
* \param[in] dir An open SdFat instance for the directory that will containing
|
* \param[in] dir An open SdFat instance for the directory that will containing
|
||||||
* the new directory.
|
* the new directory.
|
||||||
*
|
*
|
||||||
* \param[in] dirName A valid 8.3 DOS name for the new directory.
|
* \param[in] dirName A valid 8.3 DOS name for the new directory.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include this SdFile is already open, \a dir is not a
|
* Reasons for failure include this SdFile is already open, \a dir is not a
|
||||||
* directory, \a dirName is invalid or already exists in \a dir.
|
* directory, \a dirName is invalid or already exists in \a dir.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::makeDir(SdFile* dir, const char* dirName) {
|
uint8_t SdFile::makeDir(SdFile* dir, const char* dirName) {
|
||||||
dir_t d;
|
dir_t d;
|
||||||
|
|
||||||
// create a normal file
|
// create a normal file
|
||||||
if (!open(dir, dirName, O_CREAT | O_EXCL | O_RDWR)) return false;
|
if (!open(dir, dirName, O_CREAT | O_EXCL | O_RDWR)) return false;
|
||||||
|
|
||||||
// convert SdFile to directory
|
// convert SdFile to directory
|
||||||
flags_ = O_READ;
|
flags_ = O_READ;
|
||||||
type_ = FAT_FILE_TYPE_SUBDIR;
|
type_ = FAT_FILE_TYPE_SUBDIR;
|
||||||
|
|
||||||
// allocate and zero first cluster
|
// allocate and zero first cluster
|
||||||
if (!addDirCluster())return false;
|
if (!addDirCluster())return false;
|
||||||
|
|
||||||
// force entry to SD
|
// force entry to SD
|
||||||
if (!sync()) return false;
|
if (!sync()) return false;
|
||||||
|
|
||||||
// cache entry - should already be in cache due to sync() call
|
// cache entry - should already be in cache due to sync() call
|
||||||
dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||||
if (!p) return false;
|
if (!p) return false;
|
||||||
|
|
||||||
// change directory entry attribute
|
// change directory entry attribute
|
||||||
p->attributes = DIR_ATT_DIRECTORY;
|
p->attributes = DIR_ATT_DIRECTORY;
|
||||||
|
|
||||||
// make entry for '.'
|
// make entry for '.'
|
||||||
memcpy(&d, p, sizeof(d));
|
memcpy(&d, p, sizeof(d));
|
||||||
for (uint8_t i = 1; i < 11; i++) d.name[i] = ' ';
|
for (uint8_t i = 1; i < 11; i++) d.name[i] = ' ';
|
||||||
d.name[0] = '.';
|
d.name[0] = '.';
|
||||||
|
|
||||||
// cache block for '.' and '..'
|
// cache block for '.' and '..'
|
||||||
uint32_t block = vol_->clusterStartBlock(firstCluster_);
|
uint32_t block = vol_->clusterStartBlock(firstCluster_);
|
||||||
if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) return false;
|
if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) return false;
|
||||||
|
|
||||||
// copy '.' to block
|
// copy '.' to block
|
||||||
memcpy(&SdVolume::cacheBuffer_.dir[0], &d, sizeof(d));
|
memcpy(&SdVolume::cacheBuffer_.dir[0], &d, sizeof(d));
|
||||||
|
|
||||||
// make entry for '..'
|
// make entry for '..'
|
||||||
d.name[1] = '.';
|
d.name[1] = '.';
|
||||||
if (dir->isRoot()) {
|
if (dir->isRoot()) {
|
||||||
d.firstClusterLow = 0;
|
d.firstClusterLow = 0;
|
||||||
d.firstClusterHigh = 0;
|
d.firstClusterHigh = 0;
|
||||||
} else {
|
} else {
|
||||||
d.firstClusterLow = dir->firstCluster_ & 0XFFFF;
|
d.firstClusterLow = dir->firstCluster_ & 0XFFFF;
|
||||||
d.firstClusterHigh = dir->firstCluster_ >> 16;
|
d.firstClusterHigh = dir->firstCluster_ >> 16;
|
||||||
}
|
}
|
||||||
// copy '..' to block
|
// copy '..' to block
|
||||||
memcpy(&SdVolume::cacheBuffer_.dir[1], &d, sizeof(d));
|
memcpy(&SdVolume::cacheBuffer_.dir[1], &d, sizeof(d));
|
||||||
|
|
||||||
// set position after '..'
|
// set position after '..'
|
||||||
curPosition_ = 2 * sizeof(d);
|
curPosition_ = 2 * sizeof(d);
|
||||||
|
|
||||||
// write first block
|
// write first block
|
||||||
return SdVolume::cacheFlush();
|
return SdVolume::cacheFlush();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Open a file or directory by name.
|
* Open a file or directory by name.
|
||||||
*
|
*
|
||||||
* \param[in] dirFile An open SdFat instance for the directory containing the
|
* \param[in] dirFile An open SdFat instance for the directory containing the
|
||||||
* file to be opened.
|
* file to be opened.
|
||||||
*
|
*
|
||||||
* \param[in] fileName A valid 8.3 DOS name for a file to be opened.
|
* \param[in] fileName A valid 8.3 DOS name for a file to be opened.
|
||||||
*
|
*
|
||||||
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
|
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
|
||||||
* OR of flags from the following list
|
* OR of flags from the following list
|
||||||
*
|
*
|
||||||
* O_READ - Open for reading.
|
* O_READ - Open for reading.
|
||||||
*
|
*
|
||||||
* O_RDONLY - Same as O_READ.
|
* O_RDONLY - Same as O_READ.
|
||||||
*
|
*
|
||||||
* O_WRITE - Open for writing.
|
* O_WRITE - Open for writing.
|
||||||
*
|
*
|
||||||
* O_WRONLY - Same as O_WRITE.
|
* O_WRONLY - Same as O_WRITE.
|
||||||
*
|
*
|
||||||
* O_RDWR - Open for reading and writing.
|
* O_RDWR - Open for reading and writing.
|
||||||
*
|
*
|
||||||
* O_APPEND - If set, the file offset shall be set to the end of the
|
* O_APPEND - If set, the file offset shall be set to the end of the
|
||||||
* file prior to each write.
|
* file prior to each write.
|
||||||
*
|
*
|
||||||
* O_CREAT - If the file exists, this flag has no effect except as noted
|
* O_CREAT - If the file exists, this flag has no effect except as noted
|
||||||
* under O_EXCL below. Otherwise, the file shall be created
|
* under O_EXCL below. Otherwise, the file shall be created
|
||||||
*
|
*
|
||||||
* O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.
|
* O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.
|
||||||
*
|
*
|
||||||
* O_SYNC - Call sync() after each write. This flag should not be used with
|
* O_SYNC - Call sync() after each write. This flag should not be used with
|
||||||
* write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class.
|
* write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class.
|
||||||
* These functions do character at a time writes so sync() will be called
|
* These functions do character at a time writes so sync() will be called
|
||||||
* after each byte.
|
* after each byte.
|
||||||
*
|
*
|
||||||
* O_TRUNC - If the file exists and is a regular file, and the file is
|
* O_TRUNC - If the file exists and is a regular file, and the file is
|
||||||
* successfully opened and is not read only, its length shall be truncated to 0.
|
* successfully opened and is not read only, its length shall be truncated to 0.
|
||||||
*
|
*
|
||||||
* \note Directory files must be opened read only. Write and truncation is
|
* \note Directory files must be opened read only. Write and truncation is
|
||||||
* not allowed for directory files.
|
* not allowed for directory files.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include this SdFile is already open, \a difFile is not
|
* Reasons for failure include this SdFile is already open, \a difFile is not
|
||||||
* a directory, \a fileName is invalid, the file does not exist
|
* a directory, \a fileName is invalid, the file does not exist
|
||||||
* or can't be opened in the access mode specified by oflag.
|
* or can't be opened in the access mode specified by oflag.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag) {
|
uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag) {
|
||||||
uint8_t dname[11];
|
uint8_t dname[11];
|
||||||
dir_t* p;
|
dir_t* p;
|
||||||
|
|
||||||
// error if already open
|
// error if already open
|
||||||
if (isOpen())return false;
|
if (isOpen())return false;
|
||||||
|
|
||||||
if (!make83Name(fileName, dname)) return false;
|
if (!make83Name(fileName, dname)) return false;
|
||||||
vol_ = dirFile->vol_;
|
vol_ = dirFile->vol_;
|
||||||
dirFile->rewind();
|
dirFile->rewind();
|
||||||
|
|
||||||
// bool for empty entry found
|
// bool for empty entry found
|
||||||
uint8_t emptyFound = false;
|
uint8_t emptyFound = false;
|
||||||
|
|
||||||
// search for file
|
// search for file
|
||||||
while (dirFile->curPosition_ < dirFile->fileSize_) {
|
while (dirFile->curPosition_ < dirFile->fileSize_) {
|
||||||
uint8_t index = 0XF & (dirFile->curPosition_ >> 5);
|
uint8_t index = 0XF & (dirFile->curPosition_ >> 5);
|
||||||
p = dirFile->readDirCache();
|
p = dirFile->readDirCache();
|
||||||
if (p == NULL) return false;
|
if (p == NULL) return false;
|
||||||
|
|
||||||
if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) {
|
if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) {
|
||||||
// remember first empty slot
|
// remember first empty slot
|
||||||
if (!emptyFound) {
|
if (!emptyFound) {
|
||||||
emptyFound = true;
|
emptyFound = true;
|
||||||
dirIndex_ = index;
|
dirIndex_ = index;
|
||||||
dirBlock_ = SdVolume::cacheBlockNumber_;
|
dirBlock_ = SdVolume::cacheBlockNumber_;
|
||||||
}
|
}
|
||||||
// done if no entries follow
|
// done if no entries follow
|
||||||
if (p->name[0] == DIR_NAME_FREE) break;
|
if (p->name[0] == DIR_NAME_FREE) break;
|
||||||
} else if (!memcmp(dname, p->name, 11)) {
|
} else if (!memcmp(dname, p->name, 11)) {
|
||||||
// don't open existing file if O_CREAT and O_EXCL
|
// don't open existing file if O_CREAT and O_EXCL
|
||||||
if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false;
|
if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false;
|
||||||
|
|
||||||
// open found file
|
// open found file
|
||||||
return openCachedEntry(0XF & index, oflag);
|
return openCachedEntry(0XF & index, oflag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// only create file if O_CREAT and O_WRITE
|
// only create file if O_CREAT and O_WRITE
|
||||||
if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false;
|
if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false;
|
||||||
|
|
||||||
// cache found slot or add cluster if end of file
|
// cache found slot or add cluster if end of file
|
||||||
if (emptyFound) {
|
if (emptyFound) {
|
||||||
p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||||
if (!p) return false;
|
if (!p) return false;
|
||||||
} else {
|
} else {
|
||||||
if (dirFile->type_ == FAT_FILE_TYPE_ROOT16) return false;
|
if (dirFile->type_ == FAT_FILE_TYPE_ROOT16) return false;
|
||||||
|
|
||||||
// add and zero cluster for dirFile - first cluster is in cache for write
|
// add and zero cluster for dirFile - first cluster is in cache for write
|
||||||
if (!dirFile->addDirCluster()) return false;
|
if (!dirFile->addDirCluster()) return false;
|
||||||
|
|
||||||
// use first entry in cluster
|
// use first entry in cluster
|
||||||
dirIndex_ = 0;
|
dirIndex_ = 0;
|
||||||
p = SdVolume::cacheBuffer_.dir;
|
p = SdVolume::cacheBuffer_.dir;
|
||||||
}
|
}
|
||||||
// initialize as empty file
|
// initialize as empty file
|
||||||
memset(p, 0, sizeof(dir_t));
|
memset(p, 0, sizeof(dir_t));
|
||||||
memcpy(p->name, dname, 11);
|
memcpy(p->name, dname, 11);
|
||||||
|
|
||||||
// set timestamps
|
// set timestamps
|
||||||
if (dateTime_) {
|
if (dateTime_) {
|
||||||
// call user function
|
// call user function
|
||||||
dateTime_(&p->creationDate, &p->creationTime);
|
dateTime_(&p->creationDate, &p->creationTime);
|
||||||
} else {
|
} else {
|
||||||
// use default date/time
|
// use default date/time
|
||||||
p->creationDate = FAT_DEFAULT_DATE;
|
p->creationDate = FAT_DEFAULT_DATE;
|
||||||
p->creationTime = FAT_DEFAULT_TIME;
|
p->creationTime = FAT_DEFAULT_TIME;
|
||||||
}
|
}
|
||||||
p->lastAccessDate = p->creationDate;
|
p->lastAccessDate = p->creationDate;
|
||||||
p->lastWriteDate = p->creationDate;
|
p->lastWriteDate = p->creationDate;
|
||||||
p->lastWriteTime = p->creationTime;
|
p->lastWriteTime = p->creationTime;
|
||||||
|
|
||||||
// force write of entry to SD
|
// force write of entry to SD
|
||||||
if (!SdVolume::cacheFlush()) return false;
|
if (!SdVolume::cacheFlush()) return false;
|
||||||
|
|
||||||
// open entry in cache
|
// open entry in cache
|
||||||
return openCachedEntry(dirIndex_, oflag);
|
return openCachedEntry(dirIndex_, oflag);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Open a file by index.
|
* Open a file by index.
|
||||||
*
|
*
|
||||||
* \param[in] dirFile An open SdFat instance for the directory.
|
* \param[in] dirFile An open SdFat instance for the directory.
|
||||||
*
|
*
|
||||||
* \param[in] index The \a index of the directory entry for the file to be
|
* \param[in] index The \a index of the directory entry for the file to be
|
||||||
* opened. The value for \a index is (directory file position)/32.
|
* opened. The value for \a index is (directory file position)/32.
|
||||||
*
|
*
|
||||||
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
|
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
|
||||||
* OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
|
* OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
|
||||||
*
|
*
|
||||||
* See open() by fileName for definition of flags and return values.
|
* See open() by fileName for definition of flags and return values.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag) {
|
uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag) {
|
||||||
// error if already open
|
// error if already open
|
||||||
if (isOpen())return false;
|
if (isOpen())return false;
|
||||||
|
|
||||||
// don't open existing file if O_CREAT and O_EXCL - user call error
|
// don't open existing file if O_CREAT and O_EXCL - user call error
|
||||||
if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false;
|
if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false;
|
||||||
|
|
||||||
vol_ = dirFile->vol_;
|
vol_ = dirFile->vol_;
|
||||||
|
|
||||||
// seek to location of entry
|
// seek to location of entry
|
||||||
if (!dirFile->seekSet(32 * index)) return false;
|
if (!dirFile->seekSet(32 * index)) return false;
|
||||||
|
|
||||||
// read entry into cache
|
// read entry into cache
|
||||||
dir_t* p = dirFile->readDirCache();
|
dir_t* p = dirFile->readDirCache();
|
||||||
if (p == NULL) return false;
|
if (p == NULL) return false;
|
||||||
|
|
||||||
// error if empty slot or '.' or '..'
|
// error if empty slot or '.' or '..'
|
||||||
if (p->name[0] == DIR_NAME_FREE ||
|
if (p->name[0] == DIR_NAME_FREE ||
|
||||||
p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') {
|
p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// open cached entry
|
// open cached entry
|
||||||
return openCachedEntry(index & 0XF, oflag);
|
return openCachedEntry(index & 0XF, oflag);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// open a cached directory entry. Assumes vol_ is initializes
|
// open a cached directory entry. Assumes vol_ is initializes
|
||||||
uint8_t SdFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
|
uint8_t SdFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
|
||||||
// location of entry in cache
|
// location of entry in cache
|
||||||
dir_t* p = SdVolume::cacheBuffer_.dir + dirIndex;
|
dir_t* p = SdVolume::cacheBuffer_.dir + dirIndex;
|
||||||
|
|
||||||
// write or truncate is an error for a directory or read-only file
|
// write or truncate is an error for a directory or read-only file
|
||||||
if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) {
|
if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) {
|
||||||
if (oflag & (O_WRITE | O_TRUNC)) return false;
|
if (oflag & (O_WRITE | O_TRUNC)) return false;
|
||||||
}
|
}
|
||||||
// remember location of directory entry on SD
|
// remember location of directory entry on SD
|
||||||
dirIndex_ = dirIndex;
|
dirIndex_ = dirIndex;
|
||||||
dirBlock_ = SdVolume::cacheBlockNumber_;
|
dirBlock_ = SdVolume::cacheBlockNumber_;
|
||||||
|
|
||||||
// copy first cluster number for directory fields
|
// copy first cluster number for directory fields
|
||||||
firstCluster_ = (uint32_t)p->firstClusterHigh << 16;
|
firstCluster_ = (uint32_t)p->firstClusterHigh << 16;
|
||||||
firstCluster_ |= p->firstClusterLow;
|
firstCluster_ |= p->firstClusterLow;
|
||||||
|
|
||||||
// make sure it is a normal file or subdirectory
|
// make sure it is a normal file or subdirectory
|
||||||
if (DIR_IS_FILE(p)) {
|
if (DIR_IS_FILE(p)) {
|
||||||
fileSize_ = p->fileSize;
|
fileSize_ = p->fileSize;
|
||||||
type_ = FAT_FILE_TYPE_NORMAL;
|
type_ = FAT_FILE_TYPE_NORMAL;
|
||||||
} else if (DIR_IS_SUBDIR(p)) {
|
} else if (DIR_IS_SUBDIR(p)) {
|
||||||
if (!vol_->chainSize(firstCluster_, &fileSize_)) return false;
|
if (!vol_->chainSize(firstCluster_, &fileSize_)) return false;
|
||||||
type_ = FAT_FILE_TYPE_SUBDIR;
|
type_ = FAT_FILE_TYPE_SUBDIR;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// save open flags for read/write
|
// save open flags for read/write
|
||||||
flags_ = oflag & (O_ACCMODE | O_SYNC | O_APPEND);
|
flags_ = oflag & (O_ACCMODE | O_SYNC | O_APPEND);
|
||||||
|
|
||||||
// set to start of file
|
// set to start of file
|
||||||
curCluster_ = 0;
|
curCluster_ = 0;
|
||||||
curPosition_ = 0;
|
curPosition_ = 0;
|
||||||
|
|
||||||
// truncate file to zero length if requested
|
// truncate file to zero length if requested
|
||||||
if (oflag & O_TRUNC) return truncate(0);
|
if (oflag & O_TRUNC) return truncate(0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Open a volume's root directory.
|
* Open a volume's root directory.
|
||||||
*
|
*
|
||||||
* \param[in] vol The FAT volume containing the root directory to be opened.
|
* \param[in] vol The FAT volume containing the root directory to be opened.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include the FAT volume has not been initialized
|
* Reasons for failure include the FAT volume has not been initialized
|
||||||
* or it a FAT12 volume.
|
* or it a FAT12 volume.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::openRoot(SdVolume* vol) {
|
uint8_t SdFile::openRoot(SdVolume* vol) {
|
||||||
// error if file is already open
|
// error if file is already open
|
||||||
if (isOpen()) return false;
|
if (isOpen()) return false;
|
||||||
|
|
||||||
if (vol->fatType() == 16) {
|
if (vol->fatType() == 16) {
|
||||||
type_ = FAT_FILE_TYPE_ROOT16;
|
type_ = FAT_FILE_TYPE_ROOT16;
|
||||||
firstCluster_ = 0;
|
firstCluster_ = 0;
|
||||||
fileSize_ = 32 * vol->rootDirEntryCount();
|
fileSize_ = 32 * vol->rootDirEntryCount();
|
||||||
} else if (vol->fatType() == 32) {
|
} else if (vol->fatType() == 32) {
|
||||||
type_ = FAT_FILE_TYPE_ROOT32;
|
type_ = FAT_FILE_TYPE_ROOT32;
|
||||||
firstCluster_ = vol->rootDirStart();
|
firstCluster_ = vol->rootDirStart();
|
||||||
if (!vol->chainSize(firstCluster_, &fileSize_)) return false;
|
if (!vol->chainSize(firstCluster_, &fileSize_)) return false;
|
||||||
} else {
|
} else {
|
||||||
// volume is not initialized or FAT12
|
// volume is not initialized or FAT12
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
vol_ = vol;
|
vol_ = vol;
|
||||||
// read only
|
// read only
|
||||||
flags_ = O_READ;
|
flags_ = O_READ;
|
||||||
|
|
||||||
// set to start of file
|
// set to start of file
|
||||||
curCluster_ = 0;
|
curCluster_ = 0;
|
||||||
curPosition_ = 0;
|
curPosition_ = 0;
|
||||||
|
|
||||||
// root has no directory entry
|
// root has no directory entry
|
||||||
dirBlock_ = 0;
|
dirBlock_ = 0;
|
||||||
dirIndex_ = 0;
|
dirIndex_ = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** %Print the name field of a directory entry in 8.3 format to Serial.
|
/** %Print the name field of a directory entry in 8.3 format to Serial.
|
||||||
*
|
*
|
||||||
* \param[in] dir The directory structure containing the name.
|
* \param[in] dir The directory structure containing the name.
|
||||||
* \param[in] width Blank fill name if length is less than \a width.
|
* \param[in] width Blank fill name if length is less than \a width.
|
||||||
*/
|
*/
|
||||||
void SdFile::printDirName(const dir_t& dir, uint8_t width) {
|
void SdFile::printDirName(const dir_t& dir, uint8_t width) {
|
||||||
uint8_t w = 0;
|
uint8_t w = 0;
|
||||||
for (uint8_t i = 0; i < 11; i++) {
|
for (uint8_t i = 0; i < 11; i++) {
|
||||||
if (dir.name[i] == ' ')continue;
|
if (dir.name[i] == ' ')continue;
|
||||||
if (i == 8) {
|
if (i == 8) {
|
||||||
Serial.print('.');
|
Serial.print('.');
|
||||||
w++;
|
w++;
|
||||||
}
|
}
|
||||||
Serial.print(dir.name[i]);
|
Serial.print(dir.name[i]);
|
||||||
w++;
|
w++;
|
||||||
}
|
}
|
||||||
if (DIR_IS_SUBDIR(&dir)) {
|
if (DIR_IS_SUBDIR(&dir)) {
|
||||||
Serial.print('/');
|
Serial.print('/');
|
||||||
w++;
|
w++;
|
||||||
}
|
}
|
||||||
while (w < width) {
|
while (w < width) {
|
||||||
Serial.print(' ');
|
Serial.print(' ');
|
||||||
w++;
|
w++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** %Print a directory date field to Serial.
|
/** %Print a directory date field to Serial.
|
||||||
*
|
*
|
||||||
* Format is yyyy-mm-dd.
|
* Format is yyyy-mm-dd.
|
||||||
*
|
*
|
||||||
* \param[in] fatDate The date field from a directory entry.
|
* \param[in] fatDate The date field from a directory entry.
|
||||||
*/
|
*/
|
||||||
void SdFile::printFatDate(uint16_t fatDate) {
|
void SdFile::printFatDate(uint16_t fatDate) {
|
||||||
Serial.print(FAT_YEAR(fatDate));
|
Serial.print(FAT_YEAR(fatDate));
|
||||||
Serial.print('-');
|
Serial.print('-');
|
||||||
printTwoDigits(FAT_MONTH(fatDate));
|
printTwoDigits(FAT_MONTH(fatDate));
|
||||||
Serial.print('-');
|
Serial.print('-');
|
||||||
printTwoDigits(FAT_DAY(fatDate));
|
printTwoDigits(FAT_DAY(fatDate));
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** %Print a directory time field to Serial.
|
/** %Print a directory time field to Serial.
|
||||||
*
|
*
|
||||||
* Format is hh:mm:ss.
|
* Format is hh:mm:ss.
|
||||||
*
|
*
|
||||||
* \param[in] fatTime The time field from a directory entry.
|
* \param[in] fatTime The time field from a directory entry.
|
||||||
*/
|
*/
|
||||||
void SdFile::printFatTime(uint16_t fatTime) {
|
void SdFile::printFatTime(uint16_t fatTime) {
|
||||||
printTwoDigits(FAT_HOUR(fatTime));
|
printTwoDigits(FAT_HOUR(fatTime));
|
||||||
Serial.print(':');
|
Serial.print(':');
|
||||||
printTwoDigits(FAT_MINUTE(fatTime));
|
printTwoDigits(FAT_MINUTE(fatTime));
|
||||||
Serial.print(':');
|
Serial.print(':');
|
||||||
printTwoDigits(FAT_SECOND(fatTime));
|
printTwoDigits(FAT_SECOND(fatTime));
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** %Print a value as two digits to Serial.
|
/** %Print a value as two digits to Serial.
|
||||||
*
|
*
|
||||||
* \param[in] v Value to be printed, 0 <= \a v <= 99
|
* \param[in] v Value to be printed, 0 <= \a v <= 99
|
||||||
*/
|
*/
|
||||||
void SdFile::printTwoDigits(uint8_t v) {
|
void SdFile::printTwoDigits(uint8_t v) {
|
||||||
char str[3];
|
char str[3];
|
||||||
str[0] = '0' + v/10;
|
str[0] = '0' + v/10;
|
||||||
str[1] = '0' + v % 10;
|
str[1] = '0' + v % 10;
|
||||||
str[2] = 0;
|
str[2] = 0;
|
||||||
Serial.print(str);
|
Serial.print(str);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Read data from a file starting at the current position.
|
* Read data from a file starting at the current position.
|
||||||
*
|
*
|
||||||
* \param[out] buf Pointer to the location that will receive the data.
|
* \param[out] buf Pointer to the location that will receive the data.
|
||||||
*
|
*
|
||||||
* \param[in] nbyte Maximum number of bytes to read.
|
* \param[in] nbyte Maximum number of bytes to read.
|
||||||
*
|
*
|
||||||
* \return For success read() returns the number of bytes read.
|
* \return For success read() returns the number of bytes read.
|
||||||
* A value less than \a nbyte, including zero, will be returned
|
* A value less than \a nbyte, including zero, will be returned
|
||||||
* if end of file is reached.
|
* if end of file is reached.
|
||||||
* If an error occurs, read() returns -1. Possible errors include
|
* If an error occurs, read() returns -1. Possible errors include
|
||||||
* read() called before a file has been opened, corrupt file system
|
* read() called before a file has been opened, corrupt file system
|
||||||
* or an I/O error occurred.
|
* or an I/O error occurred.
|
||||||
*/
|
*/
|
||||||
int16_t SdFile::read(void* buf, uint16_t nbyte) {
|
int16_t SdFile::read(void* buf, uint16_t nbyte) {
|
||||||
uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
|
uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
|
||||||
|
|
||||||
// error if not open or write only
|
// error if not open or write only
|
||||||
if (!isOpen() || !(flags_ & O_READ)) return -1;
|
if (!isOpen() || !(flags_ & O_READ)) return -1;
|
||||||
|
|
||||||
// max bytes left in file
|
// max bytes left in file
|
||||||
if (nbyte > (fileSize_ - curPosition_)) nbyte = fileSize_ - curPosition_;
|
if (nbyte > (fileSize_ - curPosition_)) nbyte = fileSize_ - curPosition_;
|
||||||
|
|
||||||
// amount left to read
|
// amount left to read
|
||||||
uint16_t toRead = nbyte;
|
uint16_t toRead = nbyte;
|
||||||
while (toRead > 0) {
|
while (toRead > 0) {
|
||||||
uint32_t block; // raw device block number
|
uint32_t block; // raw device block number
|
||||||
uint16_t offset = curPosition_ & 0X1FF; // offset in block
|
uint16_t offset = curPosition_ & 0X1FF; // offset in block
|
||||||
if (type_ == FAT_FILE_TYPE_ROOT16) {
|
if (type_ == FAT_FILE_TYPE_ROOT16) {
|
||||||
block = vol_->rootDirStart() + (curPosition_ >> 9);
|
block = vol_->rootDirStart() + (curPosition_ >> 9);
|
||||||
} else {
|
} else {
|
||||||
uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_);
|
uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_);
|
||||||
if (offset == 0 && blockOfCluster == 0) {
|
if (offset == 0 && blockOfCluster == 0) {
|
||||||
// start of new cluster
|
// start of new cluster
|
||||||
if (curPosition_ == 0) {
|
if (curPosition_ == 0) {
|
||||||
// use first cluster in file
|
// use first cluster in file
|
||||||
curCluster_ = firstCluster_;
|
curCluster_ = firstCluster_;
|
||||||
} else {
|
} else {
|
||||||
// get next cluster from FAT
|
// get next cluster from FAT
|
||||||
if (!vol_->fatGet(curCluster_, &curCluster_)) return -1;
|
if (!vol_->fatGet(curCluster_, &curCluster_)) return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
block = vol_->clusterStartBlock(curCluster_) + blockOfCluster;
|
block = vol_->clusterStartBlock(curCluster_) + blockOfCluster;
|
||||||
}
|
}
|
||||||
uint16_t n = toRead;
|
uint16_t n = toRead;
|
||||||
|
|
||||||
// amount to be read from current block
|
// amount to be read from current block
|
||||||
if (n > (512 - offset)) n = 512 - offset;
|
if (n > (512 - offset)) n = 512 - offset;
|
||||||
|
|
||||||
// no buffering needed if n == 512 or user requests no buffering
|
// no buffering needed if n == 512 or user requests no buffering
|
||||||
if ((unbufferedRead() || n == 512) &&
|
if ((unbufferedRead() || n == 512) &&
|
||||||
block != SdVolume::cacheBlockNumber_) {
|
block != SdVolume::cacheBlockNumber_) {
|
||||||
if (!vol_->readData(block, offset, n, dst)) return -1;
|
if (!vol_->readData(block, offset, n, dst)) return -1;
|
||||||
dst += n;
|
dst += n;
|
||||||
} else {
|
} else {
|
||||||
// read block to cache and copy data to caller
|
// read block to cache and copy data to caller
|
||||||
if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) return -1;
|
if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) return -1;
|
||||||
uint8_t* src = SdVolume::cacheBuffer_.data + offset;
|
uint8_t* src = SdVolume::cacheBuffer_.data + offset;
|
||||||
uint8_t* end = src + n;
|
uint8_t* end = src + n;
|
||||||
while (src != end) *dst++ = *src++;
|
while (src != end) *dst++ = *src++;
|
||||||
}
|
}
|
||||||
curPosition_ += n;
|
curPosition_ += n;
|
||||||
toRead -= n;
|
toRead -= n;
|
||||||
}
|
}
|
||||||
return nbyte;
|
return nbyte;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Read the next directory entry from a directory file.
|
* Read the next directory entry from a directory file.
|
||||||
*
|
*
|
||||||
* \param[out] dir The dir_t struct that will receive the data.
|
* \param[out] dir The dir_t struct that will receive the data.
|
||||||
*
|
*
|
||||||
* \return For success readDir() returns the number of bytes read.
|
* \return For success readDir() returns the number of bytes read.
|
||||||
* A value of zero will be returned if end of file is reached.
|
* A value of zero will be returned if end of file is reached.
|
||||||
* If an error occurs, readDir() returns -1. Possible errors include
|
* If an error occurs, readDir() returns -1. Possible errors include
|
||||||
* readDir() called before a directory has been opened, this is not
|
* readDir() called before a directory has been opened, this is not
|
||||||
* a directory file or an I/O error occurred.
|
* a directory file or an I/O error occurred.
|
||||||
*/
|
*/
|
||||||
int8_t SdFile::readDir(dir_t* dir) {
|
int8_t SdFile::readDir(dir_t* dir) {
|
||||||
int8_t n;
|
int8_t n;
|
||||||
// if not a directory file or miss-positioned return an error
|
// if not a directory file or miss-positioned return an error
|
||||||
if (!isDir() || (0X1F & curPosition_)) return -1;
|
if (!isDir() || (0X1F & curPosition_)) return -1;
|
||||||
|
|
||||||
while ((n = read(dir, sizeof(dir_t))) == sizeof(dir_t)) {
|
while ((n = read(dir, sizeof(dir_t))) == sizeof(dir_t)) {
|
||||||
// last entry if DIR_NAME_FREE
|
// last entry if DIR_NAME_FREE
|
||||||
if (dir->name[0] == DIR_NAME_FREE) break;
|
if (dir->name[0] == DIR_NAME_FREE) break;
|
||||||
// skip empty entries and entry for . and ..
|
// skip empty entries and entry for . and ..
|
||||||
if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') continue;
|
if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') continue;
|
||||||
// return if normal file or subdirectory
|
// return if normal file or subdirectory
|
||||||
if (DIR_IS_FILE_OR_SUBDIR(dir)) return n;
|
if (DIR_IS_FILE_OR_SUBDIR(dir)) return n;
|
||||||
}
|
}
|
||||||
// error, end of file, or past last entry
|
// error, end of file, or past last entry
|
||||||
return n < 0 ? -1 : 0;
|
return n < 0 ? -1 : 0;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Read next directory entry into the cache
|
// Read next directory entry into the cache
|
||||||
// Assumes file is correctly positioned
|
// Assumes file is correctly positioned
|
||||||
dir_t* SdFile::readDirCache(void) {
|
dir_t* SdFile::readDirCache(void) {
|
||||||
// error if not directory
|
// error if not directory
|
||||||
if (!isDir()) return NULL;
|
if (!isDir()) return NULL;
|
||||||
|
|
||||||
// index of entry in cache
|
// index of entry in cache
|
||||||
uint8_t i = (curPosition_ >> 5) & 0XF;
|
uint8_t i = (curPosition_ >> 5) & 0XF;
|
||||||
|
|
||||||
// use read to locate and cache block
|
// use read to locate and cache block
|
||||||
if (read() < 0) return NULL;
|
if (read() < 0) return NULL;
|
||||||
|
|
||||||
// advance to next entry
|
// advance to next entry
|
||||||
curPosition_ += 31;
|
curPosition_ += 31;
|
||||||
|
|
||||||
// return pointer to entry
|
// return pointer to entry
|
||||||
return (SdVolume::cacheBuffer_.dir + i);
|
return (SdVolume::cacheBuffer_.dir + i);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Remove a file.
|
* Remove a file.
|
||||||
*
|
*
|
||||||
* The directory entry and all data for the file are deleted.
|
* The directory entry and all data for the file are deleted.
|
||||||
*
|
*
|
||||||
* \note This function should not be used to delete the 8.3 version of a
|
* \note This function should not be used to delete the 8.3 version of a
|
||||||
* file that has a long name. For example if a file has the long name
|
* file that has a long name. For example if a file has the long name
|
||||||
* "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
|
* "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include the file read-only, is a directory,
|
* Reasons for failure include the file read-only, is a directory,
|
||||||
* or an I/O error occurred.
|
* or an I/O error occurred.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::remove(void) {
|
uint8_t SdFile::remove(void) {
|
||||||
// free any clusters - will fail if read-only or directory
|
// free any clusters - will fail if read-only or directory
|
||||||
if (!truncate(0)) return false;
|
if (!truncate(0)) return false;
|
||||||
|
|
||||||
// cache directory entry
|
// cache directory entry
|
||||||
dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||||
if (!d) return false;
|
if (!d) return false;
|
||||||
|
|
||||||
// mark entry deleted
|
// mark entry deleted
|
||||||
d->name[0] = DIR_NAME_DELETED;
|
d->name[0] = DIR_NAME_DELETED;
|
||||||
|
|
||||||
// set this SdFile closed
|
// set this SdFile closed
|
||||||
type_ = FAT_FILE_TYPE_CLOSED;
|
type_ = FAT_FILE_TYPE_CLOSED;
|
||||||
|
|
||||||
// write entry to SD
|
// write entry to SD
|
||||||
return SdVolume::cacheFlush();
|
return SdVolume::cacheFlush();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Remove a file.
|
* Remove a file.
|
||||||
*
|
*
|
||||||
* The directory entry and all data for the file are deleted.
|
* The directory entry and all data for the file are deleted.
|
||||||
*
|
*
|
||||||
* \param[in] dirFile The directory that contains the file.
|
* \param[in] dirFile The directory that contains the file.
|
||||||
* \param[in] fileName The name of the file to be removed.
|
* \param[in] fileName The name of the file to be removed.
|
||||||
*
|
*
|
||||||
* \note This function should not be used to delete the 8.3 version of a
|
* \note This function should not be used to delete the 8.3 version of a
|
||||||
* file that has a long name. For example if a file has the long name
|
* file that has a long name. For example if a file has the long name
|
||||||
* "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
|
* "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include the file is a directory, is read only,
|
* Reasons for failure include the file is a directory, is read only,
|
||||||
* \a dirFile is not a directory, \a fileName is not found
|
* \a dirFile is not a directory, \a fileName is not found
|
||||||
* or an I/O error occurred.
|
* or an I/O error occurred.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::remove(SdFile* dirFile, const char* fileName) {
|
uint8_t SdFile::remove(SdFile* dirFile, const char* fileName) {
|
||||||
SdFile file;
|
SdFile file;
|
||||||
if (!file.open(dirFile, fileName, O_WRITE)) return false;
|
if (!file.open(dirFile, fileName, O_WRITE)) return false;
|
||||||
return file.remove();
|
return file.remove();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Remove a directory file.
|
/** Remove a directory file.
|
||||||
*
|
*
|
||||||
* The directory file will be removed only if it is empty and is not the
|
* The directory file will be removed only if it is empty and is not the
|
||||||
* root directory. rmDir() follows DOS and Windows and ignores the
|
* root directory. rmDir() follows DOS and Windows and ignores the
|
||||||
* read-only attribute for the directory.
|
* read-only attribute for the directory.
|
||||||
*
|
*
|
||||||
* \note This function should not be used to delete the 8.3 version of a
|
* \note This function should not be used to delete the 8.3 version of a
|
||||||
* directory that has a long name. For example if a directory has the
|
* directory that has a long name. For example if a directory has the
|
||||||
* long name "New folder" you should not delete the 8.3 name "NEWFOL~1".
|
* long name "New folder" you should not delete the 8.3 name "NEWFOL~1".
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include the file is not a directory, is the root
|
* Reasons for failure include the file is not a directory, is the root
|
||||||
* directory, is not empty, or an I/O error occurred.
|
* directory, is not empty, or an I/O error occurred.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::rmDir(void) {
|
uint8_t SdFile::rmDir(void) {
|
||||||
// must be open subdirectory
|
// must be open subdirectory
|
||||||
if (!isSubDir()) return false;
|
if (!isSubDir()) return false;
|
||||||
|
|
||||||
rewind();
|
rewind();
|
||||||
|
|
||||||
// make sure directory is empty
|
// make sure directory is empty
|
||||||
while (curPosition_ < fileSize_) {
|
while (curPosition_ < fileSize_) {
|
||||||
dir_t* p = readDirCache();
|
dir_t* p = readDirCache();
|
||||||
if (p == NULL) return false;
|
if (p == NULL) return false;
|
||||||
// done if past last used entry
|
// done if past last used entry
|
||||||
if (p->name[0] == DIR_NAME_FREE) break;
|
if (p->name[0] == DIR_NAME_FREE) break;
|
||||||
// skip empty slot or '.' or '..'
|
// skip empty slot or '.' or '..'
|
||||||
if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
|
if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
|
||||||
// error not empty
|
// error not empty
|
||||||
if (DIR_IS_FILE_OR_SUBDIR(p)) return false;
|
if (DIR_IS_FILE_OR_SUBDIR(p)) return false;
|
||||||
}
|
}
|
||||||
// convert empty directory to normal file for remove
|
// convert empty directory to normal file for remove
|
||||||
type_ = FAT_FILE_TYPE_NORMAL;
|
type_ = FAT_FILE_TYPE_NORMAL;
|
||||||
flags_ |= O_WRITE;
|
flags_ |= O_WRITE;
|
||||||
return remove();
|
return remove();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** Recursively delete a directory and all contained files.
|
/** Recursively delete a directory and all contained files.
|
||||||
*
|
*
|
||||||
* This is like the Unix/Linux 'rm -rf *' if called with the root directory
|
* This is like the Unix/Linux 'rm -rf *' if called with the root directory
|
||||||
* hence the name.
|
* hence the name.
|
||||||
*
|
*
|
||||||
* Warning - This will remove all contents of the directory including
|
* Warning - This will remove all contents of the directory including
|
||||||
* subdirectories. The directory will then be removed if it is not root.
|
* subdirectories. The directory will then be removed if it is not root.
|
||||||
* The read-only attribute for files will be ignored.
|
* The read-only attribute for files will be ignored.
|
||||||
*
|
*
|
||||||
* \note This function should not be used to delete the 8.3 version of
|
* \note This function should not be used to delete the 8.3 version of
|
||||||
* a directory that has a long name. See remove() and rmDir().
|
* a directory that has a long name. See remove() and rmDir().
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::rmRfStar(void) {
|
uint8_t SdFile::rmRfStar(void) {
|
||||||
rewind();
|
rewind();
|
||||||
while (curPosition_ < fileSize_) {
|
while (curPosition_ < fileSize_) {
|
||||||
SdFile f;
|
SdFile f;
|
||||||
|
|
||||||
// remember position
|
// remember position
|
||||||
uint16_t index = curPosition_/32;
|
uint16_t index = curPosition_/32;
|
||||||
|
|
||||||
dir_t* p = readDirCache();
|
dir_t* p = readDirCache();
|
||||||
if (!p) return false;
|
if (!p) return false;
|
||||||
|
|
||||||
// done if past last entry
|
// done if past last entry
|
||||||
if (p->name[0] == DIR_NAME_FREE) break;
|
if (p->name[0] == DIR_NAME_FREE) break;
|
||||||
|
|
||||||
// skip empty slot or '.' or '..'
|
// skip empty slot or '.' or '..'
|
||||||
if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
|
if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
|
||||||
|
|
||||||
// skip if part of long file name or volume label in root
|
// skip if part of long file name or volume label in root
|
||||||
if (!DIR_IS_FILE_OR_SUBDIR(p)) continue;
|
if (!DIR_IS_FILE_OR_SUBDIR(p)) continue;
|
||||||
|
|
||||||
if (!f.open(this, index, O_READ)) return false;
|
if (!f.open(this, index, O_READ)) return false;
|
||||||
if (f.isSubDir()) {
|
if (f.isSubDir()) {
|
||||||
// recursively delete
|
// recursively delete
|
||||||
if (!f.rmRfStar()) return false;
|
if (!f.rmRfStar()) return false;
|
||||||
} else {
|
} else {
|
||||||
// ignore read-only
|
// ignore read-only
|
||||||
f.flags_ |= O_WRITE;
|
f.flags_ |= O_WRITE;
|
||||||
if (!f.remove()) return false;
|
if (!f.remove()) return false;
|
||||||
}
|
}
|
||||||
// position to next entry if required
|
// position to next entry if required
|
||||||
if (curPosition_ != (32*(index + 1))) {
|
if (curPosition_ != (32*(index + 1))) {
|
||||||
if (!seekSet(32*(index + 1))) return false;
|
if (!seekSet(32*(index + 1))) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// don't try to delete root
|
// don't try to delete root
|
||||||
if (isRoot()) return true;
|
if (isRoot()) return true;
|
||||||
return rmDir();
|
return rmDir();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Sets a file's position.
|
* Sets a file's position.
|
||||||
*
|
*
|
||||||
* \param[in] pos The new position in bytes from the beginning of the file.
|
* \param[in] pos The new position in bytes from the beginning of the file.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::seekSet(uint32_t pos) {
|
uint8_t SdFile::seekSet(uint32_t pos) {
|
||||||
// error if file not open or seek past end of file
|
// error if file not open or seek past end of file
|
||||||
if (!isOpen() || pos > fileSize_) return false;
|
if (!isOpen() || pos > fileSize_) return false;
|
||||||
|
|
||||||
if (type_ == FAT_FILE_TYPE_ROOT16) {
|
if (type_ == FAT_FILE_TYPE_ROOT16) {
|
||||||
curPosition_ = pos;
|
curPosition_ = pos;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (pos == 0) {
|
if (pos == 0) {
|
||||||
// set position to start of file
|
// set position to start of file
|
||||||
curCluster_ = 0;
|
curCluster_ = 0;
|
||||||
curPosition_ = 0;
|
curPosition_ = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// calculate cluster index for cur and new position
|
// calculate cluster index for cur and new position
|
||||||
uint32_t nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9);
|
uint32_t nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9);
|
||||||
uint32_t nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9);
|
uint32_t nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9);
|
||||||
|
|
||||||
if (nNew < nCur || curPosition_ == 0) {
|
if (nNew < nCur || curPosition_ == 0) {
|
||||||
// must follow chain from first cluster
|
// must follow chain from first cluster
|
||||||
curCluster_ = firstCluster_;
|
curCluster_ = firstCluster_;
|
||||||
} else {
|
} else {
|
||||||
// advance from curPosition
|
// advance from curPosition
|
||||||
nNew -= nCur;
|
nNew -= nCur;
|
||||||
}
|
}
|
||||||
while (nNew--) {
|
while (nNew--) {
|
||||||
if (!vol_->fatGet(curCluster_, &curCluster_)) return false;
|
if (!vol_->fatGet(curCluster_, &curCluster_)) return false;
|
||||||
}
|
}
|
||||||
curPosition_ = pos;
|
curPosition_ = pos;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* The sync() call causes all modified data and directory fields
|
* The sync() call causes all modified data and directory fields
|
||||||
* to be written to the storage device.
|
* to be written to the storage device.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include a call to sync() before a file has been
|
* Reasons for failure include a call to sync() before a file has been
|
||||||
* opened or an I/O error.
|
* opened or an I/O error.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::sync(void) {
|
uint8_t SdFile::sync(void) {
|
||||||
// only allow open files and directories
|
// only allow open files and directories
|
||||||
if (!isOpen()) return false;
|
if (!isOpen()) return false;
|
||||||
|
|
||||||
if (flags_ & F_FILE_DIR_DIRTY) {
|
if (flags_ & F_FILE_DIR_DIRTY) {
|
||||||
dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||||
if (!d) return false;
|
if (!d) return false;
|
||||||
|
|
||||||
// do not set filesize for dir files
|
// do not set filesize for dir files
|
||||||
if (!isDir()) d->fileSize = fileSize_;
|
if (!isDir()) d->fileSize = fileSize_;
|
||||||
|
|
||||||
// update first cluster fields
|
// update first cluster fields
|
||||||
d->firstClusterLow = firstCluster_ & 0XFFFF;
|
d->firstClusterLow = firstCluster_ & 0XFFFF;
|
||||||
d->firstClusterHigh = firstCluster_ >> 16;
|
d->firstClusterHigh = firstCluster_ >> 16;
|
||||||
|
|
||||||
// set modify time if user supplied a callback date/time function
|
// set modify time if user supplied a callback date/time function
|
||||||
if (dateTime_) {
|
if (dateTime_) {
|
||||||
dateTime_(&d->lastWriteDate, &d->lastWriteTime);
|
dateTime_(&d->lastWriteDate, &d->lastWriteTime);
|
||||||
d->lastAccessDate = d->lastWriteDate;
|
d->lastAccessDate = d->lastWriteDate;
|
||||||
}
|
}
|
||||||
// clear directory dirty
|
// clear directory dirty
|
||||||
flags_ &= ~F_FILE_DIR_DIRTY;
|
flags_ &= ~F_FILE_DIR_DIRTY;
|
||||||
}
|
}
|
||||||
return SdVolume::cacheFlush();
|
return SdVolume::cacheFlush();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Set a file's timestamps in its directory entry.
|
* Set a file's timestamps in its directory entry.
|
||||||
*
|
*
|
||||||
* \param[in] flags Values for \a flags are constructed by a bitwise-inclusive
|
* \param[in] flags Values for \a flags are constructed by a bitwise-inclusive
|
||||||
* OR of flags from the following list
|
* OR of flags from the following list
|
||||||
*
|
*
|
||||||
* T_ACCESS - Set the file's last access date.
|
* T_ACCESS - Set the file's last access date.
|
||||||
*
|
*
|
||||||
* T_CREATE - Set the file's creation date and time.
|
* T_CREATE - Set the file's creation date and time.
|
||||||
*
|
*
|
||||||
* T_WRITE - Set the file's last write/modification date and time.
|
* T_WRITE - Set the file's last write/modification date and time.
|
||||||
*
|
*
|
||||||
* \param[in] year Valid range 1980 - 2107 inclusive.
|
* \param[in] year Valid range 1980 - 2107 inclusive.
|
||||||
*
|
*
|
||||||
* \param[in] month Valid range 1 - 12 inclusive.
|
* \param[in] month Valid range 1 - 12 inclusive.
|
||||||
*
|
*
|
||||||
* \param[in] day Valid range 1 - 31 inclusive.
|
* \param[in] day Valid range 1 - 31 inclusive.
|
||||||
*
|
*
|
||||||
* \param[in] hour Valid range 0 - 23 inclusive.
|
* \param[in] hour Valid range 0 - 23 inclusive.
|
||||||
*
|
*
|
||||||
* \param[in] minute Valid range 0 - 59 inclusive.
|
* \param[in] minute Valid range 0 - 59 inclusive.
|
||||||
*
|
*
|
||||||
* \param[in] second Valid range 0 - 59 inclusive
|
* \param[in] second Valid range 0 - 59 inclusive
|
||||||
*
|
*
|
||||||
* \note It is possible to set an invalid date since there is no check for
|
* \note It is possible to set an invalid date since there is no check for
|
||||||
* the number of days in a month.
|
* the number of days in a month.
|
||||||
*
|
*
|
||||||
* \note
|
* \note
|
||||||
* Modify and access timestamps may be overwritten if a date time callback
|
* Modify and access timestamps may be overwritten if a date time callback
|
||||||
* function has been set by dateTimeCallback().
|
* function has been set by dateTimeCallback().
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
uint8_t SdFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
||||||
uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
|
uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
|
||||||
if (!isOpen()
|
if (!isOpen()
|
||||||
|| year < 1980
|
|| year < 1980
|
||||||
|| year > 2107
|
|| year > 2107
|
||||||
|| month < 1
|
|| month < 1
|
||||||
|| month > 12
|
|| month > 12
|
||||||
|| day < 1
|
|| day < 1
|
||||||
|| day > 31
|
|| day > 31
|
||||||
|| hour > 23
|
|| hour > 23
|
||||||
|| minute > 59
|
|| minute > 59
|
||||||
|| second > 59) {
|
|| second > 59) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||||
if (!d) return false;
|
if (!d) return false;
|
||||||
|
|
||||||
uint16_t dirDate = FAT_DATE(year, month, day);
|
uint16_t dirDate = FAT_DATE(year, month, day);
|
||||||
uint16_t dirTime = FAT_TIME(hour, minute, second);
|
uint16_t dirTime = FAT_TIME(hour, minute, second);
|
||||||
if (flags & T_ACCESS) {
|
if (flags & T_ACCESS) {
|
||||||
d->lastAccessDate = dirDate;
|
d->lastAccessDate = dirDate;
|
||||||
}
|
}
|
||||||
if (flags & T_CREATE) {
|
if (flags & T_CREATE) {
|
||||||
d->creationDate = dirDate;
|
d->creationDate = dirDate;
|
||||||
d->creationTime = dirTime;
|
d->creationTime = dirTime;
|
||||||
// seems to be units of 1/100 second not 1/10 as Microsoft states
|
// seems to be units of 1/100 second not 1/10 as Microsoft states
|
||||||
d->creationTimeTenths = second & 1 ? 100 : 0;
|
d->creationTimeTenths = second & 1 ? 100 : 0;
|
||||||
}
|
}
|
||||||
if (flags & T_WRITE) {
|
if (flags & T_WRITE) {
|
||||||
d->lastWriteDate = dirDate;
|
d->lastWriteDate = dirDate;
|
||||||
d->lastWriteTime = dirTime;
|
d->lastWriteTime = dirTime;
|
||||||
}
|
}
|
||||||
SdVolume::cacheSetDirty();
|
SdVolume::cacheSetDirty();
|
||||||
return sync();
|
return sync();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Truncate a file to a specified length. The current file position
|
* Truncate a file to a specified length. The current file position
|
||||||
* will be maintained if it is less than or equal to \a length otherwise
|
* will be maintained if it is less than or equal to \a length otherwise
|
||||||
* it will be set to end of file.
|
* it will be set to end of file.
|
||||||
*
|
*
|
||||||
* \param[in] length The desired length for the file.
|
* \param[in] length The desired length for the file.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure.
|
* the value zero, false, is returned for failure.
|
||||||
* Reasons for failure include file is read only, file is a directory,
|
* Reasons for failure include file is read only, file is a directory,
|
||||||
* \a length is greater than the current file size or an I/O error occurs.
|
* \a length is greater than the current file size or an I/O error occurs.
|
||||||
*/
|
*/
|
||||||
uint8_t SdFile::truncate(uint32_t length) {
|
uint8_t SdFile::truncate(uint32_t length) {
|
||||||
// error if not a normal file or read-only
|
// error if not a normal file or read-only
|
||||||
if (!isFile() || !(flags_ & O_WRITE)) return false;
|
if (!isFile() || !(flags_ & O_WRITE)) return false;
|
||||||
|
|
||||||
// error if length is greater than current size
|
// error if length is greater than current size
|
||||||
if (length > fileSize_) return false;
|
if (length > fileSize_) return false;
|
||||||
|
|
||||||
// fileSize and length are zero - nothing to do
|
// fileSize and length are zero - nothing to do
|
||||||
if (fileSize_ == 0) return true;
|
if (fileSize_ == 0) return true;
|
||||||
|
|
||||||
// remember position for seek after truncation
|
// remember position for seek after truncation
|
||||||
uint32_t newPos = curPosition_ > length ? length : curPosition_;
|
uint32_t newPos = curPosition_ > length ? length : curPosition_;
|
||||||
|
|
||||||
// position to last cluster in truncated file
|
// position to last cluster in truncated file
|
||||||
if (!seekSet(length)) return false;
|
if (!seekSet(length)) return false;
|
||||||
|
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
// free all clusters
|
// free all clusters
|
||||||
if (!vol_->freeChain(firstCluster_)) return false;
|
if (!vol_->freeChain(firstCluster_)) return false;
|
||||||
firstCluster_ = 0;
|
firstCluster_ = 0;
|
||||||
} else {
|
} else {
|
||||||
uint32_t toFree;
|
uint32_t toFree;
|
||||||
if (!vol_->fatGet(curCluster_, &toFree)) return false;
|
if (!vol_->fatGet(curCluster_, &toFree)) return false;
|
||||||
|
|
||||||
if (!vol_->isEOC(toFree)) {
|
if (!vol_->isEOC(toFree)) {
|
||||||
// free extra clusters
|
// free extra clusters
|
||||||
if (!vol_->freeChain(toFree)) return false;
|
if (!vol_->freeChain(toFree)) return false;
|
||||||
|
|
||||||
// current cluster is end of chain
|
// current cluster is end of chain
|
||||||
if (!vol_->fatPutEOC(curCluster_)) return false;
|
if (!vol_->fatPutEOC(curCluster_)) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fileSize_ = length;
|
fileSize_ = length;
|
||||||
|
|
||||||
// need to update directory entry
|
// need to update directory entry
|
||||||
flags_ |= F_FILE_DIR_DIRTY;
|
flags_ |= F_FILE_DIR_DIRTY;
|
||||||
|
|
||||||
if (!sync()) return false;
|
if (!sync()) return false;
|
||||||
|
|
||||||
// set file to correct position
|
// set file to correct position
|
||||||
return seekSet(newPos);
|
return seekSet(newPos);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Write data to an open file.
|
* Write data to an open file.
|
||||||
*
|
*
|
||||||
* \note Data is moved to the cache but may not be written to the
|
* \note Data is moved to the cache but may not be written to the
|
||||||
* storage device until sync() is called.
|
* storage device until sync() is called.
|
||||||
*
|
*
|
||||||
* \param[in] buf Pointer to the location of the data to be written.
|
* \param[in] buf Pointer to the location of the data to be written.
|
||||||
*
|
*
|
||||||
* \param[in] nbyte Number of bytes to write.
|
* \param[in] nbyte Number of bytes to write.
|
||||||
*
|
*
|
||||||
* \return For success write() returns the number of bytes written, always
|
* \return For success write() returns the number of bytes written, always
|
||||||
* \a nbyte. If an error occurs, write() returns -1. Possible errors
|
* \a nbyte. If an error occurs, write() returns -1. Possible errors
|
||||||
* include write() is called before a file has been opened, write is called
|
* include write() is called before a file has been opened, write is called
|
||||||
* for a read-only file, device is full, a corrupt file system or an I/O error.
|
* for a read-only file, device is full, a corrupt file system or an I/O error.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int16_t SdFile::write(const void* buf, uint16_t nbyte) {
|
int16_t SdFile::write(const void* buf, uint16_t nbyte) {
|
||||||
// convert void* to uint8_t* - must be before goto statements
|
// convert void* to uint8_t* - must be before goto statements
|
||||||
const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
|
const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
|
||||||
|
|
||||||
// number of bytes left to write - must be before goto statements
|
// number of bytes left to write - must be before goto statements
|
||||||
uint16_t nToWrite = nbyte;
|
uint16_t nToWrite = nbyte;
|
||||||
|
|
||||||
// error if not a normal file or is read-only
|
// error if not a normal file or is read-only
|
||||||
if (!isFile() || !(flags_ & O_WRITE)) goto writeErrorReturn;
|
if (!isFile() || !(flags_ & O_WRITE)) goto writeErrorReturn;
|
||||||
|
|
||||||
// seek to end of file if append flag
|
// seek to end of file if append flag
|
||||||
if ((flags_ & O_APPEND) && curPosition_ != fileSize_) {
|
if ((flags_ & O_APPEND) && curPosition_ != fileSize_) {
|
||||||
if (!seekEnd()) goto writeErrorReturn;
|
if (!seekEnd()) goto writeErrorReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (nToWrite > 0) {
|
while (nToWrite > 0) {
|
||||||
uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_);
|
uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_);
|
||||||
uint16_t blockOffset = curPosition_ & 0X1FF;
|
uint16_t blockOffset = curPosition_ & 0X1FF;
|
||||||
if (blockOfCluster == 0 && blockOffset == 0) {
|
if (blockOfCluster == 0 && blockOffset == 0) {
|
||||||
// start of new cluster
|
// start of new cluster
|
||||||
if (curCluster_ == 0) {
|
if (curCluster_ == 0) {
|
||||||
if (firstCluster_ == 0) {
|
if (firstCluster_ == 0) {
|
||||||
// allocate first cluster of file
|
// allocate first cluster of file
|
||||||
if (!addCluster()) goto writeErrorReturn;
|
if (!addCluster()) goto writeErrorReturn;
|
||||||
} else {
|
} else {
|
||||||
curCluster_ = firstCluster_;
|
curCluster_ = firstCluster_;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint32_t next;
|
uint32_t next;
|
||||||
if (!vol_->fatGet(curCluster_, &next)) return false;
|
if (!vol_->fatGet(curCluster_, &next)) return false;
|
||||||
if (vol_->isEOC(next)) {
|
if (vol_->isEOC(next)) {
|
||||||
// add cluster if at end of chain
|
// add cluster if at end of chain
|
||||||
if (!addCluster()) goto writeErrorReturn;
|
if (!addCluster()) goto writeErrorReturn;
|
||||||
} else {
|
} else {
|
||||||
curCluster_ = next;
|
curCluster_ = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// max space in block
|
// max space in block
|
||||||
uint16_t n = 512 - blockOffset;
|
uint16_t n = 512 - blockOffset;
|
||||||
|
|
||||||
// lesser of space and amount to write
|
// lesser of space and amount to write
|
||||||
if (n > nToWrite) n = nToWrite;
|
if (n > nToWrite) n = nToWrite;
|
||||||
|
|
||||||
// block for data write
|
// block for data write
|
||||||
uint32_t block = vol_->clusterStartBlock(curCluster_) + blockOfCluster;
|
uint32_t block = vol_->clusterStartBlock(curCluster_) + blockOfCluster;
|
||||||
if (n == 512) {
|
if (n == 512) {
|
||||||
// full block - don't need to use cache
|
// full block - don't need to use cache
|
||||||
// invalidate cache if block is in cache
|
// invalidate cache if block is in cache
|
||||||
if (SdVolume::cacheBlockNumber_ == block) {
|
if (SdVolume::cacheBlockNumber_ == block) {
|
||||||
SdVolume::cacheBlockNumber_ = 0XFFFFFFFF;
|
SdVolume::cacheBlockNumber_ = 0XFFFFFFFF;
|
||||||
}
|
}
|
||||||
if (!vol_->writeBlock(block, src)) goto writeErrorReturn;
|
if (!vol_->writeBlock(block, src)) goto writeErrorReturn;
|
||||||
src += 512;
|
src += 512;
|
||||||
} else {
|
} else {
|
||||||
if (blockOffset == 0 && curPosition_ >= fileSize_) {
|
if (blockOffset == 0 && curPosition_ >= fileSize_) {
|
||||||
// start of new block don't need to read into cache
|
// start of new block don't need to read into cache
|
||||||
if (!SdVolume::cacheFlush()) goto writeErrorReturn;
|
if (!SdVolume::cacheFlush()) goto writeErrorReturn;
|
||||||
SdVolume::cacheBlockNumber_ = block;
|
SdVolume::cacheBlockNumber_ = block;
|
||||||
SdVolume::cacheSetDirty();
|
SdVolume::cacheSetDirty();
|
||||||
} else {
|
} else {
|
||||||
// rewrite part of block
|
// rewrite part of block
|
||||||
if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) {
|
if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) {
|
||||||
goto writeErrorReturn;
|
goto writeErrorReturn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint8_t* dst = SdVolume::cacheBuffer_.data + blockOffset;
|
uint8_t* dst = SdVolume::cacheBuffer_.data + blockOffset;
|
||||||
uint8_t* end = dst + n;
|
uint8_t* end = dst + n;
|
||||||
while (dst != end) *dst++ = *src++;
|
while (dst != end) *dst++ = *src++;
|
||||||
}
|
}
|
||||||
nToWrite -= n;
|
nToWrite -= n;
|
||||||
curPosition_ += n;
|
curPosition_ += n;
|
||||||
}
|
}
|
||||||
if (curPosition_ > fileSize_) {
|
if (curPosition_ > fileSize_) {
|
||||||
// update fileSize and insure sync will update dir entry
|
// update fileSize and insure sync will update dir entry
|
||||||
fileSize_ = curPosition_;
|
fileSize_ = curPosition_;
|
||||||
flags_ |= F_FILE_DIR_DIRTY;
|
flags_ |= F_FILE_DIR_DIRTY;
|
||||||
} else if (dateTime_ && nbyte) {
|
} else if (dateTime_ && nbyte) {
|
||||||
// insure sync will update modified date and time
|
// insure sync will update modified date and time
|
||||||
flags_ |= F_FILE_DIR_DIRTY;
|
flags_ |= F_FILE_DIR_DIRTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags_ & O_SYNC) {
|
if (flags_ & O_SYNC) {
|
||||||
if (!sync()) goto writeErrorReturn;
|
if (!sync()) goto writeErrorReturn;
|
||||||
}
|
}
|
||||||
return nbyte;
|
return nbyte;
|
||||||
|
|
||||||
writeErrorReturn:
|
writeErrorReturn:
|
||||||
// return for write error
|
// return for write error
|
||||||
writeError = true;
|
writeError = true;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Write a byte to a file. Required by the Arduino Print class.
|
* Write a byte to a file. Required by the Arduino Print class.
|
||||||
*
|
*
|
||||||
* Use SdFile::writeError to check for errors.
|
* Use SdFile::writeError to check for errors.
|
||||||
*/
|
*/
|
||||||
void SdFile::write(uint8_t b) {
|
void SdFile::write(uint8_t b) {
|
||||||
write(&b, 1);
|
write(&b, 1);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Write a string to a file. Used by the Arduino Print class.
|
* Write a string to a file. Used by the Arduino Print class.
|
||||||
*
|
*
|
||||||
* Use SdFile::writeError to check for errors.
|
* Use SdFile::writeError to check for errors.
|
||||||
*/
|
*/
|
||||||
void SdFile::write(const char* str) {
|
void SdFile::write(const char* str) {
|
||||||
write(str, strlen(str));
|
write(str, strlen(str));
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Write a PROGMEM string to a file.
|
* Write a PROGMEM string to a file.
|
||||||
*
|
*
|
||||||
* Use SdFile::writeError to check for errors.
|
* Use SdFile::writeError to check for errors.
|
||||||
*/
|
*/
|
||||||
void SdFile::write_P(PGM_P str) {
|
void SdFile::write_P(PGM_P str) {
|
||||||
for (uint8_t c; (c = pgm_read_byte(str)); str++) write(c);
|
for (uint8_t c; (c = pgm_read_byte(str)); str++) write(c);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Write a PROGMEM string followed by CR/LF to a file.
|
* Write a PROGMEM string followed by CR/LF to a file.
|
||||||
*
|
*
|
||||||
* Use SdFile::writeError to check for errors.
|
* Use SdFile::writeError to check for errors.
|
||||||
*/
|
*/
|
||||||
void SdFile::writeln_P(PGM_P str) {
|
void SdFile::writeln_P(PGM_P str) {
|
||||||
write_P(str);
|
write_P(str);
|
||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
464
Marlin/SdInfo.h
464
Marlin/SdInfo.h
|
@ -1,232 +1,232 @@
|
||||||
/* Arduino Sd2Card Library
|
/* Arduino Sd2Card Library
|
||||||
* Copyright (C) 2009 by William Greiman
|
* Copyright (C) 2009 by William Greiman
|
||||||
*
|
*
|
||||||
* This file is part of the Arduino Sd2Card Library
|
* This file is part of the Arduino Sd2Card Library
|
||||||
*
|
*
|
||||||
* This Library is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This Library is distributed in the hope that it will be useful,
|
* This Library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with the Arduino Sd2Card Library. If not, see
|
* along with the Arduino Sd2Card Library. If not, see
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#ifndef SdInfo_h
|
#ifndef SdInfo_h
|
||||||
#define SdInfo_h
|
#define SdInfo_h
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
// Based on the document:
|
// Based on the document:
|
||||||
//
|
//
|
||||||
// SD Specifications
|
// SD Specifications
|
||||||
// Part 1
|
// Part 1
|
||||||
// Physical Layer
|
// Physical Layer
|
||||||
// Simplified Specification
|
// Simplified Specification
|
||||||
// Version 2.00
|
// Version 2.00
|
||||||
// September 25, 2006
|
// September 25, 2006
|
||||||
//
|
//
|
||||||
// www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
|
// www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// SD card commands
|
// SD card commands
|
||||||
/** GO_IDLE_STATE - init card in spi mode if CS low */
|
/** GO_IDLE_STATE - init card in spi mode if CS low */
|
||||||
uint8_t const CMD0 = 0X00;
|
uint8_t const CMD0 = 0X00;
|
||||||
/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/
|
/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/
|
||||||
uint8_t const CMD8 = 0X08;
|
uint8_t const CMD8 = 0X08;
|
||||||
/** SEND_CSD - read the Card Specific Data (CSD register) */
|
/** SEND_CSD - read the Card Specific Data (CSD register) */
|
||||||
uint8_t const CMD9 = 0X09;
|
uint8_t const CMD9 = 0X09;
|
||||||
/** SEND_CID - read the card identification information (CID register) */
|
/** SEND_CID - read the card identification information (CID register) */
|
||||||
uint8_t const CMD10 = 0X0A;
|
uint8_t const CMD10 = 0X0A;
|
||||||
/** SEND_STATUS - read the card status register */
|
/** SEND_STATUS - read the card status register */
|
||||||
uint8_t const CMD13 = 0X0D;
|
uint8_t const CMD13 = 0X0D;
|
||||||
/** READ_BLOCK - read a single data block from the card */
|
/** READ_BLOCK - read a single data block from the card */
|
||||||
uint8_t const CMD17 = 0X11;
|
uint8_t const CMD17 = 0X11;
|
||||||
/** WRITE_BLOCK - write a single data block to the card */
|
/** WRITE_BLOCK - write a single data block to the card */
|
||||||
uint8_t const CMD24 = 0X18;
|
uint8_t const CMD24 = 0X18;
|
||||||
/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */
|
/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */
|
||||||
uint8_t const CMD25 = 0X19;
|
uint8_t const CMD25 = 0X19;
|
||||||
/** ERASE_WR_BLK_START - sets the address of the first block to be erased */
|
/** ERASE_WR_BLK_START - sets the address of the first block to be erased */
|
||||||
uint8_t const CMD32 = 0X20;
|
uint8_t const CMD32 = 0X20;
|
||||||
/** ERASE_WR_BLK_END - sets the address of the last block of the continuous
|
/** ERASE_WR_BLK_END - sets the address of the last block of the continuous
|
||||||
range to be erased*/
|
range to be erased*/
|
||||||
uint8_t const CMD33 = 0X21;
|
uint8_t const CMD33 = 0X21;
|
||||||
/** ERASE - erase all previously selected blocks */
|
/** ERASE - erase all previously selected blocks */
|
||||||
uint8_t const CMD38 = 0X26;
|
uint8_t const CMD38 = 0X26;
|
||||||
/** APP_CMD - escape for application specific command */
|
/** APP_CMD - escape for application specific command */
|
||||||
uint8_t const CMD55 = 0X37;
|
uint8_t const CMD55 = 0X37;
|
||||||
/** READ_OCR - read the OCR register of a card */
|
/** READ_OCR - read the OCR register of a card */
|
||||||
uint8_t const CMD58 = 0X3A;
|
uint8_t const CMD58 = 0X3A;
|
||||||
/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be
|
/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be
|
||||||
pre-erased before writing */
|
pre-erased before writing */
|
||||||
uint8_t const ACMD23 = 0X17;
|
uint8_t const ACMD23 = 0X17;
|
||||||
/** SD_SEND_OP_COMD - Sends host capacity support information and
|
/** SD_SEND_OP_COMD - Sends host capacity support information and
|
||||||
activates the card's initialization process */
|
activates the card's initialization process */
|
||||||
uint8_t const ACMD41 = 0X29;
|
uint8_t const ACMD41 = 0X29;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** status for card in the ready state */
|
/** status for card in the ready state */
|
||||||
uint8_t const R1_READY_STATE = 0X00;
|
uint8_t const R1_READY_STATE = 0X00;
|
||||||
/** status for card in the idle state */
|
/** status for card in the idle state */
|
||||||
uint8_t const R1_IDLE_STATE = 0X01;
|
uint8_t const R1_IDLE_STATE = 0X01;
|
||||||
/** status bit for illegal command */
|
/** status bit for illegal command */
|
||||||
uint8_t const R1_ILLEGAL_COMMAND = 0X04;
|
uint8_t const R1_ILLEGAL_COMMAND = 0X04;
|
||||||
/** start data token for read or write single block*/
|
/** start data token for read or write single block*/
|
||||||
uint8_t const DATA_START_BLOCK = 0XFE;
|
uint8_t const DATA_START_BLOCK = 0XFE;
|
||||||
/** stop token for write multiple blocks*/
|
/** stop token for write multiple blocks*/
|
||||||
uint8_t const STOP_TRAN_TOKEN = 0XFD;
|
uint8_t const STOP_TRAN_TOKEN = 0XFD;
|
||||||
/** start data token for write multiple blocks*/
|
/** start data token for write multiple blocks*/
|
||||||
uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC;
|
uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC;
|
||||||
/** mask for data response tokens after a write block operation */
|
/** mask for data response tokens after a write block operation */
|
||||||
uint8_t const DATA_RES_MASK = 0X1F;
|
uint8_t const DATA_RES_MASK = 0X1F;
|
||||||
/** write data accepted token */
|
/** write data accepted token */
|
||||||
uint8_t const DATA_RES_ACCEPTED = 0X05;
|
uint8_t const DATA_RES_ACCEPTED = 0X05;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
typedef struct CID {
|
typedef struct CID {
|
||||||
// byte 0
|
// byte 0
|
||||||
uint8_t mid; // Manufacturer ID
|
uint8_t mid; // Manufacturer ID
|
||||||
// byte 1-2
|
// byte 1-2
|
||||||
char oid[2]; // OEM/Application ID
|
char oid[2]; // OEM/Application ID
|
||||||
// byte 3-7
|
// byte 3-7
|
||||||
char pnm[5]; // Product name
|
char pnm[5]; // Product name
|
||||||
// byte 8
|
// byte 8
|
||||||
unsigned prv_m : 4; // Product revision n.m
|
unsigned prv_m : 4; // Product revision n.m
|
||||||
unsigned prv_n : 4;
|
unsigned prv_n : 4;
|
||||||
// byte 9-12
|
// byte 9-12
|
||||||
uint32_t psn; // Product serial number
|
uint32_t psn; // Product serial number
|
||||||
// byte 13
|
// byte 13
|
||||||
unsigned mdt_year_high : 4; // Manufacturing date
|
unsigned mdt_year_high : 4; // Manufacturing date
|
||||||
unsigned reserved : 4;
|
unsigned reserved : 4;
|
||||||
// byte 14
|
// byte 14
|
||||||
unsigned mdt_month : 4;
|
unsigned mdt_month : 4;
|
||||||
unsigned mdt_year_low :4;
|
unsigned mdt_year_low :4;
|
||||||
// byte 15
|
// byte 15
|
||||||
unsigned always1 : 1;
|
unsigned always1 : 1;
|
||||||
unsigned crc : 7;
|
unsigned crc : 7;
|
||||||
}cid_t;
|
}cid_t;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// CSD for version 1.00 cards
|
// CSD for version 1.00 cards
|
||||||
typedef struct CSDV1 {
|
typedef struct CSDV1 {
|
||||||
// byte 0
|
// byte 0
|
||||||
unsigned reserved1 : 6;
|
unsigned reserved1 : 6;
|
||||||
unsigned csd_ver : 2;
|
unsigned csd_ver : 2;
|
||||||
// byte 1
|
// byte 1
|
||||||
uint8_t taac;
|
uint8_t taac;
|
||||||
// byte 2
|
// byte 2
|
||||||
uint8_t nsac;
|
uint8_t nsac;
|
||||||
// byte 3
|
// byte 3
|
||||||
uint8_t tran_speed;
|
uint8_t tran_speed;
|
||||||
// byte 4
|
// byte 4
|
||||||
uint8_t ccc_high;
|
uint8_t ccc_high;
|
||||||
// byte 5
|
// byte 5
|
||||||
unsigned read_bl_len : 4;
|
unsigned read_bl_len : 4;
|
||||||
unsigned ccc_low : 4;
|
unsigned ccc_low : 4;
|
||||||
// byte 6
|
// byte 6
|
||||||
unsigned c_size_high : 2;
|
unsigned c_size_high : 2;
|
||||||
unsigned reserved2 : 2;
|
unsigned reserved2 : 2;
|
||||||
unsigned dsr_imp : 1;
|
unsigned dsr_imp : 1;
|
||||||
unsigned read_blk_misalign :1;
|
unsigned read_blk_misalign :1;
|
||||||
unsigned write_blk_misalign : 1;
|
unsigned write_blk_misalign : 1;
|
||||||
unsigned read_bl_partial : 1;
|
unsigned read_bl_partial : 1;
|
||||||
// byte 7
|
// byte 7
|
||||||
uint8_t c_size_mid;
|
uint8_t c_size_mid;
|
||||||
// byte 8
|
// byte 8
|
||||||
unsigned vdd_r_curr_max : 3;
|
unsigned vdd_r_curr_max : 3;
|
||||||
unsigned vdd_r_curr_min : 3;
|
unsigned vdd_r_curr_min : 3;
|
||||||
unsigned c_size_low :2;
|
unsigned c_size_low :2;
|
||||||
// byte 9
|
// byte 9
|
||||||
unsigned c_size_mult_high : 2;
|
unsigned c_size_mult_high : 2;
|
||||||
unsigned vdd_w_cur_max : 3;
|
unsigned vdd_w_cur_max : 3;
|
||||||
unsigned vdd_w_curr_min : 3;
|
unsigned vdd_w_curr_min : 3;
|
||||||
// byte 10
|
// byte 10
|
||||||
unsigned sector_size_high : 6;
|
unsigned sector_size_high : 6;
|
||||||
unsigned erase_blk_en : 1;
|
unsigned erase_blk_en : 1;
|
||||||
unsigned c_size_mult_low : 1;
|
unsigned c_size_mult_low : 1;
|
||||||
// byte 11
|
// byte 11
|
||||||
unsigned wp_grp_size : 7;
|
unsigned wp_grp_size : 7;
|
||||||
unsigned sector_size_low : 1;
|
unsigned sector_size_low : 1;
|
||||||
// byte 12
|
// byte 12
|
||||||
unsigned write_bl_len_high : 2;
|
unsigned write_bl_len_high : 2;
|
||||||
unsigned r2w_factor : 3;
|
unsigned r2w_factor : 3;
|
||||||
unsigned reserved3 : 2;
|
unsigned reserved3 : 2;
|
||||||
unsigned wp_grp_enable : 1;
|
unsigned wp_grp_enable : 1;
|
||||||
// byte 13
|
// byte 13
|
||||||
unsigned reserved4 : 5;
|
unsigned reserved4 : 5;
|
||||||
unsigned write_partial : 1;
|
unsigned write_partial : 1;
|
||||||
unsigned write_bl_len_low : 2;
|
unsigned write_bl_len_low : 2;
|
||||||
// byte 14
|
// byte 14
|
||||||
unsigned reserved5: 2;
|
unsigned reserved5: 2;
|
||||||
unsigned file_format : 2;
|
unsigned file_format : 2;
|
||||||
unsigned tmp_write_protect : 1;
|
unsigned tmp_write_protect : 1;
|
||||||
unsigned perm_write_protect : 1;
|
unsigned perm_write_protect : 1;
|
||||||
unsigned copy : 1;
|
unsigned copy : 1;
|
||||||
unsigned file_format_grp : 1;
|
unsigned file_format_grp : 1;
|
||||||
// byte 15
|
// byte 15
|
||||||
unsigned always1 : 1;
|
unsigned always1 : 1;
|
||||||
unsigned crc : 7;
|
unsigned crc : 7;
|
||||||
}csd1_t;
|
}csd1_t;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// CSD for version 2.00 cards
|
// CSD for version 2.00 cards
|
||||||
typedef struct CSDV2 {
|
typedef struct CSDV2 {
|
||||||
// byte 0
|
// byte 0
|
||||||
unsigned reserved1 : 6;
|
unsigned reserved1 : 6;
|
||||||
unsigned csd_ver : 2;
|
unsigned csd_ver : 2;
|
||||||
// byte 1
|
// byte 1
|
||||||
uint8_t taac;
|
uint8_t taac;
|
||||||
// byte 2
|
// byte 2
|
||||||
uint8_t nsac;
|
uint8_t nsac;
|
||||||
// byte 3
|
// byte 3
|
||||||
uint8_t tran_speed;
|
uint8_t tran_speed;
|
||||||
// byte 4
|
// byte 4
|
||||||
uint8_t ccc_high;
|
uint8_t ccc_high;
|
||||||
// byte 5
|
// byte 5
|
||||||
unsigned read_bl_len : 4;
|
unsigned read_bl_len : 4;
|
||||||
unsigned ccc_low : 4;
|
unsigned ccc_low : 4;
|
||||||
// byte 6
|
// byte 6
|
||||||
unsigned reserved2 : 4;
|
unsigned reserved2 : 4;
|
||||||
unsigned dsr_imp : 1;
|
unsigned dsr_imp : 1;
|
||||||
unsigned read_blk_misalign :1;
|
unsigned read_blk_misalign :1;
|
||||||
unsigned write_blk_misalign : 1;
|
unsigned write_blk_misalign : 1;
|
||||||
unsigned read_bl_partial : 1;
|
unsigned read_bl_partial : 1;
|
||||||
// byte 7
|
// byte 7
|
||||||
unsigned reserved3 : 2;
|
unsigned reserved3 : 2;
|
||||||
unsigned c_size_high : 6;
|
unsigned c_size_high : 6;
|
||||||
// byte 8
|
// byte 8
|
||||||
uint8_t c_size_mid;
|
uint8_t c_size_mid;
|
||||||
// byte 9
|
// byte 9
|
||||||
uint8_t c_size_low;
|
uint8_t c_size_low;
|
||||||
// byte 10
|
// byte 10
|
||||||
unsigned sector_size_high : 6;
|
unsigned sector_size_high : 6;
|
||||||
unsigned erase_blk_en : 1;
|
unsigned erase_blk_en : 1;
|
||||||
unsigned reserved4 : 1;
|
unsigned reserved4 : 1;
|
||||||
// byte 11
|
// byte 11
|
||||||
unsigned wp_grp_size : 7;
|
unsigned wp_grp_size : 7;
|
||||||
unsigned sector_size_low : 1;
|
unsigned sector_size_low : 1;
|
||||||
// byte 12
|
// byte 12
|
||||||
unsigned write_bl_len_high : 2;
|
unsigned write_bl_len_high : 2;
|
||||||
unsigned r2w_factor : 3;
|
unsigned r2w_factor : 3;
|
||||||
unsigned reserved5 : 2;
|
unsigned reserved5 : 2;
|
||||||
unsigned wp_grp_enable : 1;
|
unsigned wp_grp_enable : 1;
|
||||||
// byte 13
|
// byte 13
|
||||||
unsigned reserved6 : 5;
|
unsigned reserved6 : 5;
|
||||||
unsigned write_partial : 1;
|
unsigned write_partial : 1;
|
||||||
unsigned write_bl_len_low : 2;
|
unsigned write_bl_len_low : 2;
|
||||||
// byte 14
|
// byte 14
|
||||||
unsigned reserved7: 2;
|
unsigned reserved7: 2;
|
||||||
unsigned file_format : 2;
|
unsigned file_format : 2;
|
||||||
unsigned tmp_write_protect : 1;
|
unsigned tmp_write_protect : 1;
|
||||||
unsigned perm_write_protect : 1;
|
unsigned perm_write_protect : 1;
|
||||||
unsigned copy : 1;
|
unsigned copy : 1;
|
||||||
unsigned file_format_grp : 1;
|
unsigned file_format_grp : 1;
|
||||||
// byte 15
|
// byte 15
|
||||||
unsigned always1 : 1;
|
unsigned always1 : 1;
|
||||||
unsigned crc : 7;
|
unsigned crc : 7;
|
||||||
}csd2_t;
|
}csd2_t;
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// union of old and new style CSD register
|
// union of old and new style CSD register
|
||||||
union csd_t {
|
union csd_t {
|
||||||
csd1_t v1;
|
csd1_t v1;
|
||||||
csd2_t v2;
|
csd2_t v2;
|
||||||
};
|
};
|
||||||
#endif // SdInfo_h
|
#endif // SdInfo_h
|
||||||
|
|
|
@ -1,295 +1,295 @@
|
||||||
/* Arduino SdFat Library
|
/* Arduino SdFat Library
|
||||||
* Copyright (C) 2009 by William Greiman
|
* Copyright (C) 2009 by William Greiman
|
||||||
*
|
*
|
||||||
* This file is part of the Arduino SdFat Library
|
* This file is part of the Arduino SdFat Library
|
||||||
*
|
*
|
||||||
* This Library is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This Library is distributed in the hope that it will be useful,
|
* This Library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with the Arduino SdFat Library. If not, see
|
* along with the Arduino SdFat Library. If not, see
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "SdFat.h"
|
#include "SdFat.h"
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// raw block cache
|
// raw block cache
|
||||||
// init cacheBlockNumber_to invalid SD block number
|
// init cacheBlockNumber_to invalid SD block number
|
||||||
uint32_t SdVolume::cacheBlockNumber_ = 0XFFFFFFFF;
|
uint32_t SdVolume::cacheBlockNumber_ = 0XFFFFFFFF;
|
||||||
cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card
|
cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card
|
||||||
Sd2Card* SdVolume::sdCard_; // pointer to SD card object
|
Sd2Card* SdVolume::sdCard_; // pointer to SD card object
|
||||||
uint8_t SdVolume::cacheDirty_ = 0; // cacheFlush() will write block if true
|
uint8_t SdVolume::cacheDirty_ = 0; // cacheFlush() will write block if true
|
||||||
uint32_t SdVolume::cacheMirrorBlock_ = 0; // mirror block for second FAT
|
uint32_t SdVolume::cacheMirrorBlock_ = 0; // mirror block for second FAT
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// find a contiguous group of clusters
|
// find a contiguous group of clusters
|
||||||
uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
|
uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
|
||||||
// start of group
|
// start of group
|
||||||
uint32_t bgnCluster;
|
uint32_t bgnCluster;
|
||||||
|
|
||||||
// flag to save place to start next search
|
// flag to save place to start next search
|
||||||
uint8_t setStart;
|
uint8_t setStart;
|
||||||
|
|
||||||
// set search start cluster
|
// set search start cluster
|
||||||
if (*curCluster) {
|
if (*curCluster) {
|
||||||
// try to make file contiguous
|
// try to make file contiguous
|
||||||
bgnCluster = *curCluster + 1;
|
bgnCluster = *curCluster + 1;
|
||||||
|
|
||||||
// don't save new start location
|
// don't save new start location
|
||||||
setStart = false;
|
setStart = false;
|
||||||
} else {
|
} else {
|
||||||
// start at likely place for free cluster
|
// start at likely place for free cluster
|
||||||
bgnCluster = allocSearchStart_;
|
bgnCluster = allocSearchStart_;
|
||||||
|
|
||||||
// save next search start if one cluster
|
// save next search start if one cluster
|
||||||
setStart = 1 == count;
|
setStart = 1 == count;
|
||||||
}
|
}
|
||||||
// end of group
|
// end of group
|
||||||
uint32_t endCluster = bgnCluster;
|
uint32_t endCluster = bgnCluster;
|
||||||
|
|
||||||
// last cluster of FAT
|
// last cluster of FAT
|
||||||
uint32_t fatEnd = clusterCount_ + 1;
|
uint32_t fatEnd = clusterCount_ + 1;
|
||||||
|
|
||||||
// search the FAT for free clusters
|
// search the FAT for free clusters
|
||||||
for (uint32_t n = 0;; n++, endCluster++) {
|
for (uint32_t n = 0;; n++, endCluster++) {
|
||||||
// can't find space checked all clusters
|
// can't find space checked all clusters
|
||||||
if (n >= clusterCount_) return false;
|
if (n >= clusterCount_) return false;
|
||||||
|
|
||||||
// past end - start from beginning of FAT
|
// past end - start from beginning of FAT
|
||||||
if (endCluster > fatEnd) {
|
if (endCluster > fatEnd) {
|
||||||
bgnCluster = endCluster = 2;
|
bgnCluster = endCluster = 2;
|
||||||
}
|
}
|
||||||
uint32_t f;
|
uint32_t f;
|
||||||
if (!fatGet(endCluster, &f)) return false;
|
if (!fatGet(endCluster, &f)) return false;
|
||||||
|
|
||||||
if (f != 0) {
|
if (f != 0) {
|
||||||
// cluster in use try next cluster as bgnCluster
|
// cluster in use try next cluster as bgnCluster
|
||||||
bgnCluster = endCluster + 1;
|
bgnCluster = endCluster + 1;
|
||||||
} else if ((endCluster - bgnCluster + 1) == count) {
|
} else if ((endCluster - bgnCluster + 1) == count) {
|
||||||
// done - found space
|
// done - found space
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// mark end of chain
|
// mark end of chain
|
||||||
if (!fatPutEOC(endCluster)) return false;
|
if (!fatPutEOC(endCluster)) return false;
|
||||||
|
|
||||||
// link clusters
|
// link clusters
|
||||||
while (endCluster > bgnCluster) {
|
while (endCluster > bgnCluster) {
|
||||||
if (!fatPut(endCluster - 1, endCluster)) return false;
|
if (!fatPut(endCluster - 1, endCluster)) return false;
|
||||||
endCluster--;
|
endCluster--;
|
||||||
}
|
}
|
||||||
if (*curCluster != 0) {
|
if (*curCluster != 0) {
|
||||||
// connect chains
|
// connect chains
|
||||||
if (!fatPut(*curCluster, bgnCluster)) return false;
|
if (!fatPut(*curCluster, bgnCluster)) return false;
|
||||||
}
|
}
|
||||||
// return first cluster number to caller
|
// return first cluster number to caller
|
||||||
*curCluster = bgnCluster;
|
*curCluster = bgnCluster;
|
||||||
|
|
||||||
// remember possible next free cluster
|
// remember possible next free cluster
|
||||||
if (setStart) allocSearchStart_ = bgnCluster + 1;
|
if (setStart) allocSearchStart_ = bgnCluster + 1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
uint8_t SdVolume::cacheFlush(void) {
|
uint8_t SdVolume::cacheFlush(void) {
|
||||||
if (cacheDirty_) {
|
if (cacheDirty_) {
|
||||||
if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) {
|
if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// mirror FAT tables
|
// mirror FAT tables
|
||||||
if (cacheMirrorBlock_) {
|
if (cacheMirrorBlock_) {
|
||||||
if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) {
|
if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cacheMirrorBlock_ = 0;
|
cacheMirrorBlock_ = 0;
|
||||||
}
|
}
|
||||||
cacheDirty_ = 0;
|
cacheDirty_ = 0;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
uint8_t SdVolume::cacheRawBlock(uint32_t blockNumber, uint8_t action) {
|
uint8_t SdVolume::cacheRawBlock(uint32_t blockNumber, uint8_t action) {
|
||||||
if (cacheBlockNumber_ != blockNumber) {
|
if (cacheBlockNumber_ != blockNumber) {
|
||||||
if (!cacheFlush()) return false;
|
if (!cacheFlush()) return false;
|
||||||
if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) return false;
|
if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) return false;
|
||||||
cacheBlockNumber_ = blockNumber;
|
cacheBlockNumber_ = blockNumber;
|
||||||
}
|
}
|
||||||
cacheDirty_ |= action;
|
cacheDirty_ |= action;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// cache a zero block for blockNumber
|
// cache a zero block for blockNumber
|
||||||
uint8_t SdVolume::cacheZeroBlock(uint32_t blockNumber) {
|
uint8_t SdVolume::cacheZeroBlock(uint32_t blockNumber) {
|
||||||
if (!cacheFlush()) return false;
|
if (!cacheFlush()) return false;
|
||||||
|
|
||||||
// loop take less flash than memset(cacheBuffer_.data, 0, 512);
|
// loop take less flash than memset(cacheBuffer_.data, 0, 512);
|
||||||
for (uint16_t i = 0; i < 512; i++) {
|
for (uint16_t i = 0; i < 512; i++) {
|
||||||
cacheBuffer_.data[i] = 0;
|
cacheBuffer_.data[i] = 0;
|
||||||
}
|
}
|
||||||
cacheBlockNumber_ = blockNumber;
|
cacheBlockNumber_ = blockNumber;
|
||||||
cacheSetDirty();
|
cacheSetDirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// return the size in bytes of a cluster chain
|
// return the size in bytes of a cluster chain
|
||||||
uint8_t SdVolume::chainSize(uint32_t cluster, uint32_t* size) const {
|
uint8_t SdVolume::chainSize(uint32_t cluster, uint32_t* size) const {
|
||||||
uint32_t s = 0;
|
uint32_t s = 0;
|
||||||
do {
|
do {
|
||||||
if (!fatGet(cluster, &cluster)) return false;
|
if (!fatGet(cluster, &cluster)) return false;
|
||||||
s += 512UL << clusterSizeShift_;
|
s += 512UL << clusterSizeShift_;
|
||||||
} while (!isEOC(cluster));
|
} while (!isEOC(cluster));
|
||||||
*size = s;
|
*size = s;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Fetch a FAT entry
|
// Fetch a FAT entry
|
||||||
uint8_t SdVolume::fatGet(uint32_t cluster, uint32_t* value) const {
|
uint8_t SdVolume::fatGet(uint32_t cluster, uint32_t* value) const {
|
||||||
if (cluster > (clusterCount_ + 1)) return false;
|
if (cluster > (clusterCount_ + 1)) return false;
|
||||||
uint32_t lba = fatStartBlock_;
|
uint32_t lba = fatStartBlock_;
|
||||||
lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7;
|
lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7;
|
||||||
if (lba != cacheBlockNumber_) {
|
if (lba != cacheBlockNumber_) {
|
||||||
if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false;
|
if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false;
|
||||||
}
|
}
|
||||||
if (fatType_ == 16) {
|
if (fatType_ == 16) {
|
||||||
*value = cacheBuffer_.fat16[cluster & 0XFF];
|
*value = cacheBuffer_.fat16[cluster & 0XFF];
|
||||||
} else {
|
} else {
|
||||||
*value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK;
|
*value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Store a FAT entry
|
// Store a FAT entry
|
||||||
uint8_t SdVolume::fatPut(uint32_t cluster, uint32_t value) {
|
uint8_t SdVolume::fatPut(uint32_t cluster, uint32_t value) {
|
||||||
// error if reserved cluster
|
// error if reserved cluster
|
||||||
if (cluster < 2) return false;
|
if (cluster < 2) return false;
|
||||||
|
|
||||||
// error if not in FAT
|
// error if not in FAT
|
||||||
if (cluster > (clusterCount_ + 1)) return false;
|
if (cluster > (clusterCount_ + 1)) return false;
|
||||||
|
|
||||||
// calculate block address for entry
|
// calculate block address for entry
|
||||||
uint32_t lba = fatStartBlock_;
|
uint32_t lba = fatStartBlock_;
|
||||||
lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7;
|
lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7;
|
||||||
|
|
||||||
if (lba != cacheBlockNumber_) {
|
if (lba != cacheBlockNumber_) {
|
||||||
if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false;
|
if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false;
|
||||||
}
|
}
|
||||||
// store entry
|
// store entry
|
||||||
if (fatType_ == 16) {
|
if (fatType_ == 16) {
|
||||||
cacheBuffer_.fat16[cluster & 0XFF] = value;
|
cacheBuffer_.fat16[cluster & 0XFF] = value;
|
||||||
} else {
|
} else {
|
||||||
cacheBuffer_.fat32[cluster & 0X7F] = value;
|
cacheBuffer_.fat32[cluster & 0X7F] = value;
|
||||||
}
|
}
|
||||||
cacheSetDirty();
|
cacheSetDirty();
|
||||||
|
|
||||||
// mirror second FAT
|
// mirror second FAT
|
||||||
if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
|
if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// free a cluster chain
|
// free a cluster chain
|
||||||
uint8_t SdVolume::freeChain(uint32_t cluster) {
|
uint8_t SdVolume::freeChain(uint32_t cluster) {
|
||||||
// clear free cluster location
|
// clear free cluster location
|
||||||
allocSearchStart_ = 2;
|
allocSearchStart_ = 2;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
uint32_t next;
|
uint32_t next;
|
||||||
if (!fatGet(cluster, &next)) return false;
|
if (!fatGet(cluster, &next)) return false;
|
||||||
|
|
||||||
// free cluster
|
// free cluster
|
||||||
if (!fatPut(cluster, 0)) return false;
|
if (!fatPut(cluster, 0)) return false;
|
||||||
|
|
||||||
cluster = next;
|
cluster = next;
|
||||||
} while (!isEOC(cluster));
|
} while (!isEOC(cluster));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Initialize a FAT volume.
|
* Initialize a FAT volume.
|
||||||
*
|
*
|
||||||
* \param[in] dev The SD card where the volume is located.
|
* \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
|
* \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
|
* 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 MBR, Master Boot Record, or zero if the device is formatted as
|
||||||
* a super floppy with the FAT boot sector in block zero.
|
* a super floppy with the FAT boot sector in block zero.
|
||||||
*
|
*
|
||||||
* \return The value one, true, is returned for success and
|
* \return The value one, true, is returned for success and
|
||||||
* the value zero, false, is returned for failure. Reasons for
|
* the value zero, false, is returned for failure. Reasons for
|
||||||
* failure include not finding a valid partition, not finding a valid
|
* failure include not finding a valid partition, not finding a valid
|
||||||
* FAT file system in the specified partition or an I/O error.
|
* FAT file system in the specified partition or an I/O error.
|
||||||
*/
|
*/
|
||||||
uint8_t SdVolume::init(Sd2Card* dev, uint8_t part) {
|
uint8_t SdVolume::init(Sd2Card* dev, uint8_t part) {
|
||||||
uint32_t volumeStartBlock = 0;
|
uint32_t volumeStartBlock = 0;
|
||||||
sdCard_ = dev;
|
sdCard_ = dev;
|
||||||
// if part == 0 assume super floppy with FAT boot sector in block zero
|
// if part == 0 assume super floppy with FAT boot sector in block zero
|
||||||
// if part > 0 assume mbr volume with partition table
|
// if part > 0 assume mbr volume with partition table
|
||||||
if (part) {
|
if (part) {
|
||||||
if (part > 4)return false;
|
if (part > 4)return false;
|
||||||
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false;
|
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false;
|
||||||
part_t* p = &cacheBuffer_.mbr.part[part-1];
|
part_t* p = &cacheBuffer_.mbr.part[part-1];
|
||||||
if ((p->boot & 0X7F) !=0 ||
|
if ((p->boot & 0X7F) !=0 ||
|
||||||
p->totalSectors < 100 ||
|
p->totalSectors < 100 ||
|
||||||
p->firstSector == 0) {
|
p->firstSector == 0) {
|
||||||
// not a valid partition
|
// not a valid partition
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
volumeStartBlock = p->firstSector;
|
volumeStartBlock = p->firstSector;
|
||||||
}
|
}
|
||||||
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false;
|
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false;
|
||||||
bpb_t* bpb = &cacheBuffer_.fbs.bpb;
|
bpb_t* bpb = &cacheBuffer_.fbs.bpb;
|
||||||
if (bpb->bytesPerSector != 512 ||
|
if (bpb->bytesPerSector != 512 ||
|
||||||
bpb->fatCount == 0 ||
|
bpb->fatCount == 0 ||
|
||||||
bpb->reservedSectorCount == 0 ||
|
bpb->reservedSectorCount == 0 ||
|
||||||
bpb->sectorsPerCluster == 0) {
|
bpb->sectorsPerCluster == 0) {
|
||||||
// not valid FAT volume
|
// not valid FAT volume
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fatCount_ = bpb->fatCount;
|
fatCount_ = bpb->fatCount;
|
||||||
blocksPerCluster_ = bpb->sectorsPerCluster;
|
blocksPerCluster_ = bpb->sectorsPerCluster;
|
||||||
|
|
||||||
// determine shift that is same as multiply by blocksPerCluster_
|
// determine shift that is same as multiply by blocksPerCluster_
|
||||||
clusterSizeShift_ = 0;
|
clusterSizeShift_ = 0;
|
||||||
while (blocksPerCluster_ != (1 << clusterSizeShift_)) {
|
while (blocksPerCluster_ != (1 << clusterSizeShift_)) {
|
||||||
// error if not power of 2
|
// error if not power of 2
|
||||||
if (clusterSizeShift_++ > 7) return false;
|
if (clusterSizeShift_++ > 7) return false;
|
||||||
}
|
}
|
||||||
blocksPerFat_ = bpb->sectorsPerFat16 ?
|
blocksPerFat_ = bpb->sectorsPerFat16 ?
|
||||||
bpb->sectorsPerFat16 : bpb->sectorsPerFat32;
|
bpb->sectorsPerFat16 : bpb->sectorsPerFat32;
|
||||||
|
|
||||||
fatStartBlock_ = volumeStartBlock + bpb->reservedSectorCount;
|
fatStartBlock_ = volumeStartBlock + bpb->reservedSectorCount;
|
||||||
|
|
||||||
// count for FAT16 zero for FAT32
|
// count for FAT16 zero for FAT32
|
||||||
rootDirEntryCount_ = bpb->rootDirEntryCount;
|
rootDirEntryCount_ = bpb->rootDirEntryCount;
|
||||||
|
|
||||||
// directory start for FAT16 dataStart for FAT32
|
// directory start for FAT16 dataStart for FAT32
|
||||||
rootDirStart_ = fatStartBlock_ + bpb->fatCount * blocksPerFat_;
|
rootDirStart_ = fatStartBlock_ + bpb->fatCount * blocksPerFat_;
|
||||||
|
|
||||||
// data start for FAT16 and FAT32
|
// data start for FAT16 and FAT32
|
||||||
dataStartBlock_ = rootDirStart_ + ((32 * bpb->rootDirEntryCount + 511)/512);
|
dataStartBlock_ = rootDirStart_ + ((32 * bpb->rootDirEntryCount + 511)/512);
|
||||||
|
|
||||||
// total blocks for FAT16 or FAT32
|
// total blocks for FAT16 or FAT32
|
||||||
uint32_t totalBlocks = bpb->totalSectors16 ?
|
uint32_t totalBlocks = bpb->totalSectors16 ?
|
||||||
bpb->totalSectors16 : bpb->totalSectors32;
|
bpb->totalSectors16 : bpb->totalSectors32;
|
||||||
// total data blocks
|
// total data blocks
|
||||||
clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock);
|
clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock);
|
||||||
|
|
||||||
// divide by cluster size to get cluster count
|
// divide by cluster size to get cluster count
|
||||||
clusterCount_ >>= clusterSizeShift_;
|
clusterCount_ >>= clusterSizeShift_;
|
||||||
|
|
||||||
// FAT type is determined by cluster count
|
// FAT type is determined by cluster count
|
||||||
if (clusterCount_ < 4085) {
|
if (clusterCount_ < 4085) {
|
||||||
fatType_ = 12;
|
fatType_ = 12;
|
||||||
} else if (clusterCount_ < 65525) {
|
} else if (clusterCount_ < 65525) {
|
||||||
fatType_ = 16;
|
fatType_ = 16;
|
||||||
} else {
|
} else {
|
||||||
rootDirStart_ = bpb->fat32RootCluster;
|
rootDirStart_ = bpb->fat32RootCluster;
|
||||||
fatType_ = 32;
|
fatType_ = 32;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
5116
Marlin/fastio.h
5116
Marlin/fastio.h
|
@ -1,2559 +1,2559 @@
|
||||||
/*
|
/*
|
||||||
This code contibuted by Triffid_Hunter and modified by Kliment
|
This code contibuted by Triffid_Hunter and modified by Kliment
|
||||||
why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _ARDUINO_H
|
#ifndef _ARDUINO_H
|
||||||
#define _ARDUINO_H
|
#define _ARDUINO_H
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
utility functions
|
utility functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MASK
|
#ifndef MASK
|
||||||
/// MASKING- returns \f$2^PIN\f$
|
/// MASKING- returns \f$2^PIN\f$
|
||||||
#define MASK(PIN) (1 << PIN)
|
#define MASK(PIN) (1 << PIN)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
magic I/O routines
|
magic I/O routines
|
||||||
|
|
||||||
now you can simply SET_OUTPUT(STEP); WRITE(STEP, 1); WRITE(STEP, 0);
|
now you can simply SET_OUTPUT(STEP); WRITE(STEP, 1); WRITE(STEP, 0);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// Read a pin
|
/// Read a pin
|
||||||
#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & MASK(DIO ## IO ## _PIN)))
|
#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & MASK(DIO ## IO ## _PIN)))
|
||||||
/// write to a pin
|
/// write to a pin
|
||||||
#define _WRITE(IO, v) do { if (v) {DIO ## IO ## _WPORT |= MASK(DIO ## IO ## _PIN); } else {DIO ## IO ## _WPORT &= ~MASK(DIO ## IO ## _PIN); }; } while (0)
|
#define _WRITE(IO, v) do { if (v) {DIO ## IO ## _WPORT |= MASK(DIO ## IO ## _PIN); } else {DIO ## IO ## _WPORT &= ~MASK(DIO ## IO ## _PIN); }; } while (0)
|
||||||
//#define _WRITE(IO, v) do { #if (DIO ## IO ## _WPORT >= 0x100) CRITICAL_SECTION_START; if (v) {DIO ## IO ## _WPORT |= MASK(DIO ## IO ## _PIN); } else {DIO ## IO ## _WPORT &= ~MASK(DIO ## IO ## _PIN); };#if (DIO ## IO ## _WPORT >= 0x100) CRITICAL_SECTION_END; } while (0)
|
//#define _WRITE(IO, v) do { #if (DIO ## IO ## _WPORT >= 0x100) CRITICAL_SECTION_START; if (v) {DIO ## IO ## _WPORT |= MASK(DIO ## IO ## _PIN); } else {DIO ## IO ## _WPORT &= ~MASK(DIO ## IO ## _PIN); };#if (DIO ## IO ## _WPORT >= 0x100) CRITICAL_SECTION_END; } while (0)
|
||||||
/// toggle a pin
|
/// toggle a pin
|
||||||
#define _TOGGLE(IO) do {DIO ## IO ## _RPORT = MASK(DIO ## IO ## _PIN); } while (0)
|
#define _TOGGLE(IO) do {DIO ## IO ## _RPORT = MASK(DIO ## IO ## _PIN); } while (0)
|
||||||
|
|
||||||
/// set pin as input
|
/// set pin as input
|
||||||
#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~MASK(DIO ## IO ## _PIN); } while (0)
|
#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~MASK(DIO ## IO ## _PIN); } while (0)
|
||||||
/// set pin as output
|
/// set pin as output
|
||||||
#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= MASK(DIO ## IO ## _PIN); } while (0)
|
#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= MASK(DIO ## IO ## _PIN); } while (0)
|
||||||
|
|
||||||
/// check if pin is an input
|
/// check if pin is an input
|
||||||
#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) == 0)
|
#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) == 0)
|
||||||
/// check if pin is an output
|
/// check if pin is an output
|
||||||
#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) != 0)
|
#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) != 0)
|
||||||
|
|
||||||
// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
||||||
|
|
||||||
/// Read a pin wrapper
|
/// Read a pin wrapper
|
||||||
#define READ(IO) _READ(IO)
|
#define READ(IO) _READ(IO)
|
||||||
/// Write to a pin wrapper
|
/// Write to a pin wrapper
|
||||||
#define WRITE(IO, v) _WRITE(IO, v)
|
#define WRITE(IO, v) _WRITE(IO, v)
|
||||||
/// toggle a pin wrapper
|
/// toggle a pin wrapper
|
||||||
#define TOGGLE(IO) _TOGGLE(IO)
|
#define TOGGLE(IO) _TOGGLE(IO)
|
||||||
|
|
||||||
/// set pin as input wrapper
|
/// set pin as input wrapper
|
||||||
#define SET_INPUT(IO) _SET_INPUT(IO)
|
#define SET_INPUT(IO) _SET_INPUT(IO)
|
||||||
/// set pin as output wrapper
|
/// set pin as output wrapper
|
||||||
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
||||||
|
|
||||||
/// check if pin is an input wrapper
|
/// check if pin is an input wrapper
|
||||||
#define GET_INPUT(IO) _GET_INPUT(IO)
|
#define GET_INPUT(IO) _GET_INPUT(IO)
|
||||||
/// check if pin is an output wrapper
|
/// check if pin is an output wrapper
|
||||||
#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
|
#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ports and functions
|
ports and functions
|
||||||
|
|
||||||
added as necessary or if I feel like it- not a comprehensive list!
|
added as necessary or if I feel like it- not a comprehensive list!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__)
|
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__)
|
||||||
// UART
|
// UART
|
||||||
#define RXD DIO0
|
#define RXD DIO0
|
||||||
#define TXD DIO1
|
#define TXD DIO1
|
||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
#define SCK DIO13
|
#define SCK DIO13
|
||||||
#define MISO DIO12
|
#define MISO DIO12
|
||||||
#define MOSI DIO11
|
#define MOSI DIO11
|
||||||
#define SS DIO10
|
#define SS DIO10
|
||||||
|
|
||||||
// TWI (I2C)
|
// TWI (I2C)
|
||||||
#define SCL AIO5
|
#define SCL AIO5
|
||||||
#define SDA AIO4
|
#define SDA AIO4
|
||||||
|
|
||||||
// timers and PWM
|
// timers and PWM
|
||||||
#define OC0A DIO6
|
#define OC0A DIO6
|
||||||
#define OC0B DIO5
|
#define OC0B DIO5
|
||||||
#define OC1A DIO9
|
#define OC1A DIO9
|
||||||
#define OC1B DIO10
|
#define OC1B DIO10
|
||||||
#define OC2A DIO11
|
#define OC2A DIO11
|
||||||
#define OC2B DIO3
|
#define OC2B DIO3
|
||||||
|
|
||||||
#define DEBUG_LED AIO5
|
#define DEBUG_LED AIO5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pins
|
pins
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DIO0_PIN PIND0
|
#define DIO0_PIN PIND0
|
||||||
#define DIO0_RPORT PIND
|
#define DIO0_RPORT PIND
|
||||||
#define DIO0_WPORT PORTD
|
#define DIO0_WPORT PORTD
|
||||||
#define DIO0_DDR DDRD
|
#define DIO0_DDR DDRD
|
||||||
#define DIO0_PWM NULL
|
#define DIO0_PWM NULL
|
||||||
|
|
||||||
#define DIO1_PIN PIND1
|
#define DIO1_PIN PIND1
|
||||||
#define DIO1_RPORT PIND
|
#define DIO1_RPORT PIND
|
||||||
#define DIO1_WPORT PORTD
|
#define DIO1_WPORT PORTD
|
||||||
#define DIO1_DDR DDRD
|
#define DIO1_DDR DDRD
|
||||||
#define DIO1_PWM NULL
|
#define DIO1_PWM NULL
|
||||||
|
|
||||||
#define DIO2_PIN PIND2
|
#define DIO2_PIN PIND2
|
||||||
#define DIO2_RPORT PIND
|
#define DIO2_RPORT PIND
|
||||||
#define DIO2_WPORT PORTD
|
#define DIO2_WPORT PORTD
|
||||||
#define DIO2_DDR DDRD
|
#define DIO2_DDR DDRD
|
||||||
#define DIO2_PWM NULL
|
#define DIO2_PWM NULL
|
||||||
|
|
||||||
#define DIO3_PIN PIND3
|
#define DIO3_PIN PIND3
|
||||||
#define DIO3_RPORT PIND
|
#define DIO3_RPORT PIND
|
||||||
#define DIO3_WPORT PORTD
|
#define DIO3_WPORT PORTD
|
||||||
#define DIO3_DDR DDRD
|
#define DIO3_DDR DDRD
|
||||||
#define DIO3_PWM &OCR2B
|
#define DIO3_PWM &OCR2B
|
||||||
|
|
||||||
#define DIO4_PIN PIND4
|
#define DIO4_PIN PIND4
|
||||||
#define DIO4_RPORT PIND
|
#define DIO4_RPORT PIND
|
||||||
#define DIO4_WPORT PORTD
|
#define DIO4_WPORT PORTD
|
||||||
#define DIO4_DDR DDRD
|
#define DIO4_DDR DDRD
|
||||||
#define DIO4_PWM NULL
|
#define DIO4_PWM NULL
|
||||||
|
|
||||||
#define DIO5_PIN PIND5
|
#define DIO5_PIN PIND5
|
||||||
#define DIO5_RPORT PIND
|
#define DIO5_RPORT PIND
|
||||||
#define DIO5_WPORT PORTD
|
#define DIO5_WPORT PORTD
|
||||||
#define DIO5_DDR DDRD
|
#define DIO5_DDR DDRD
|
||||||
#define DIO5_PWM &OCR0B
|
#define DIO5_PWM &OCR0B
|
||||||
|
|
||||||
#define DIO6_PIN PIND6
|
#define DIO6_PIN PIND6
|
||||||
#define DIO6_RPORT PIND
|
#define DIO6_RPORT PIND
|
||||||
#define DIO6_WPORT PORTD
|
#define DIO6_WPORT PORTD
|
||||||
#define DIO6_DDR DDRD
|
#define DIO6_DDR DDRD
|
||||||
#define DIO6_PWM &OCR0A
|
#define DIO6_PWM &OCR0A
|
||||||
|
|
||||||
#define DIO7_PIN PIND7
|
#define DIO7_PIN PIND7
|
||||||
#define DIO7_RPORT PIND
|
#define DIO7_RPORT PIND
|
||||||
#define DIO7_WPORT PORTD
|
#define DIO7_WPORT PORTD
|
||||||
#define DIO7_DDR DDRD
|
#define DIO7_DDR DDRD
|
||||||
#define DIO7_PWM NULL
|
#define DIO7_PWM NULL
|
||||||
|
|
||||||
#define DIO8_PIN PINB0
|
#define DIO8_PIN PINB0
|
||||||
#define DIO8_RPORT PINB
|
#define DIO8_RPORT PINB
|
||||||
#define DIO8_WPORT PORTB
|
#define DIO8_WPORT PORTB
|
||||||
#define DIO8_DDR DDRB
|
#define DIO8_DDR DDRB
|
||||||
#define DIO8_PWM NULL
|
#define DIO8_PWM NULL
|
||||||
|
|
||||||
#define DIO9_PIN PINB1
|
#define DIO9_PIN PINB1
|
||||||
#define DIO9_RPORT PINB
|
#define DIO9_RPORT PINB
|
||||||
#define DIO9_WPORT PORTB
|
#define DIO9_WPORT PORTB
|
||||||
#define DIO9_DDR DDRB
|
#define DIO9_DDR DDRB
|
||||||
#define DIO9_PWM NULL
|
#define DIO9_PWM NULL
|
||||||
|
|
||||||
#define DIO10_PIN PINB2
|
#define DIO10_PIN PINB2
|
||||||
#define DIO10_RPORT PINB
|
#define DIO10_RPORT PINB
|
||||||
#define DIO10_WPORT PORTB
|
#define DIO10_WPORT PORTB
|
||||||
#define DIO10_DDR DDRB
|
#define DIO10_DDR DDRB
|
||||||
#define DIO10_PWM NULL
|
#define DIO10_PWM NULL
|
||||||
|
|
||||||
#define DIO11_PIN PINB3
|
#define DIO11_PIN PINB3
|
||||||
#define DIO11_RPORT PINB
|
#define DIO11_RPORT PINB
|
||||||
#define DIO11_WPORT PORTB
|
#define DIO11_WPORT PORTB
|
||||||
#define DIO11_DDR DDRB
|
#define DIO11_DDR DDRB
|
||||||
#define DIO11_PWM &OCR2A
|
#define DIO11_PWM &OCR2A
|
||||||
|
|
||||||
#define DIO12_PIN PINB4
|
#define DIO12_PIN PINB4
|
||||||
#define DIO12_RPORT PINB
|
#define DIO12_RPORT PINB
|
||||||
#define DIO12_WPORT PORTB
|
#define DIO12_WPORT PORTB
|
||||||
#define DIO12_DDR DDRB
|
#define DIO12_DDR DDRB
|
||||||
#define DIO12_PWM NULL
|
#define DIO12_PWM NULL
|
||||||
|
|
||||||
#define DIO13_PIN PINB5
|
#define DIO13_PIN PINB5
|
||||||
#define DIO13_RPORT PINB
|
#define DIO13_RPORT PINB
|
||||||
#define DIO13_WPORT PORTB
|
#define DIO13_WPORT PORTB
|
||||||
#define DIO13_DDR DDRB
|
#define DIO13_DDR DDRB
|
||||||
#define DIO13_PWM NULL
|
#define DIO13_PWM NULL
|
||||||
|
|
||||||
|
|
||||||
#define DIO14_PIN PINC0
|
#define DIO14_PIN PINC0
|
||||||
#define DIO14_RPORT PINC
|
#define DIO14_RPORT PINC
|
||||||
#define DIO14_WPORT PORTC
|
#define DIO14_WPORT PORTC
|
||||||
#define DIO14_DDR DDRC
|
#define DIO14_DDR DDRC
|
||||||
#define DIO14_PWM NULL
|
#define DIO14_PWM NULL
|
||||||
|
|
||||||
#define DIO15_PIN PINC1
|
#define DIO15_PIN PINC1
|
||||||
#define DIO15_RPORT PINC
|
#define DIO15_RPORT PINC
|
||||||
#define DIO15_WPORT PORTC
|
#define DIO15_WPORT PORTC
|
||||||
#define DIO15_DDR DDRC
|
#define DIO15_DDR DDRC
|
||||||
#define DIO15_PWM NULL
|
#define DIO15_PWM NULL
|
||||||
|
|
||||||
#define DIO16_PIN PINC2
|
#define DIO16_PIN PINC2
|
||||||
#define DIO16_RPORT PINC
|
#define DIO16_RPORT PINC
|
||||||
#define DIO16_WPORT PORTC
|
#define DIO16_WPORT PORTC
|
||||||
#define DIO16_DDR DDRC
|
#define DIO16_DDR DDRC
|
||||||
#define DIO16_PWM NULL
|
#define DIO16_PWM NULL
|
||||||
|
|
||||||
#define DIO17_PIN PINC3
|
#define DIO17_PIN PINC3
|
||||||
#define DIO17_RPORT PINC
|
#define DIO17_RPORT PINC
|
||||||
#define DIO17_WPORT PORTC
|
#define DIO17_WPORT PORTC
|
||||||
#define DIO17_DDR DDRC
|
#define DIO17_DDR DDRC
|
||||||
#define DIO17_PWM NULL
|
#define DIO17_PWM NULL
|
||||||
|
|
||||||
#define DIO18_PIN PINC4
|
#define DIO18_PIN PINC4
|
||||||
#define DIO18_RPORT PINC
|
#define DIO18_RPORT PINC
|
||||||
#define DIO18_WPORT PORTC
|
#define DIO18_WPORT PORTC
|
||||||
#define DIO18_DDR DDRC
|
#define DIO18_DDR DDRC
|
||||||
#define DIO18_PWM NULL
|
#define DIO18_PWM NULL
|
||||||
|
|
||||||
#define DIO19_PIN PINC5
|
#define DIO19_PIN PINC5
|
||||||
#define DIO19_RPORT PINC
|
#define DIO19_RPORT PINC
|
||||||
#define DIO19_WPORT PORTC
|
#define DIO19_WPORT PORTC
|
||||||
#define DIO19_DDR DDRC
|
#define DIO19_DDR DDRC
|
||||||
#define DIO19_PWM NULL
|
#define DIO19_PWM NULL
|
||||||
|
|
||||||
#define DIO20_PIN PINC6
|
#define DIO20_PIN PINC6
|
||||||
#define DIO20_RPORT PINC
|
#define DIO20_RPORT PINC
|
||||||
#define DIO20_WPORT PORTC
|
#define DIO20_WPORT PORTC
|
||||||
#define DIO20_DDR DDRC
|
#define DIO20_DDR DDRC
|
||||||
#define DIO20_PWM NULL
|
#define DIO20_PWM NULL
|
||||||
|
|
||||||
#define DIO21_PIN PINC7
|
#define DIO21_PIN PINC7
|
||||||
#define DIO21_RPORT PINC
|
#define DIO21_RPORT PINC
|
||||||
#define DIO21_WPORT PORTC
|
#define DIO21_WPORT PORTC
|
||||||
#define DIO21_DDR DDRC
|
#define DIO21_DDR DDRC
|
||||||
#define DIO21_PWM NULL
|
#define DIO21_PWM NULL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#undef PB0
|
#undef PB0
|
||||||
#define PB0_PIN PINB0
|
#define PB0_PIN PINB0
|
||||||
#define PB0_RPORT PINB
|
#define PB0_RPORT PINB
|
||||||
#define PB0_WPORT PORTB
|
#define PB0_WPORT PORTB
|
||||||
#define PB0_DDR DDRB
|
#define PB0_DDR DDRB
|
||||||
#define PB0_PWM NULL
|
#define PB0_PWM NULL
|
||||||
|
|
||||||
#undef PB1
|
#undef PB1
|
||||||
#define PB1_PIN PINB1
|
#define PB1_PIN PINB1
|
||||||
#define PB1_RPORT PINB
|
#define PB1_RPORT PINB
|
||||||
#define PB1_WPORT PORTB
|
#define PB1_WPORT PORTB
|
||||||
#define PB1_DDR DDRB
|
#define PB1_DDR DDRB
|
||||||
#define PB1_PWM NULL
|
#define PB1_PWM NULL
|
||||||
|
|
||||||
#undef PB2
|
#undef PB2
|
||||||
#define PB2_PIN PINB2
|
#define PB2_PIN PINB2
|
||||||
#define PB2_RPORT PINB
|
#define PB2_RPORT PINB
|
||||||
#define PB2_WPORT PORTB
|
#define PB2_WPORT PORTB
|
||||||
#define PB2_DDR DDRB
|
#define PB2_DDR DDRB
|
||||||
#define PB2_PWM NULL
|
#define PB2_PWM NULL
|
||||||
|
|
||||||
#undef PB3
|
#undef PB3
|
||||||
#define PB3_PIN PINB3
|
#define PB3_PIN PINB3
|
||||||
#define PB3_RPORT PINB
|
#define PB3_RPORT PINB
|
||||||
#define PB3_WPORT PORTB
|
#define PB3_WPORT PORTB
|
||||||
#define PB3_DDR DDRB
|
#define PB3_DDR DDRB
|
||||||
#define PB3_PWM &OCR2A
|
#define PB3_PWM &OCR2A
|
||||||
|
|
||||||
#undef PB4
|
#undef PB4
|
||||||
#define PB4_PIN PINB4
|
#define PB4_PIN PINB4
|
||||||
#define PB4_RPORT PINB
|
#define PB4_RPORT PINB
|
||||||
#define PB4_WPORT PORTB
|
#define PB4_WPORT PORTB
|
||||||
#define PB4_DDR DDRB
|
#define PB4_DDR DDRB
|
||||||
#define PB4_PWM NULL
|
#define PB4_PWM NULL
|
||||||
|
|
||||||
#undef PB5
|
#undef PB5
|
||||||
#define PB5_PIN PINB5
|
#define PB5_PIN PINB5
|
||||||
#define PB5_RPORT PINB
|
#define PB5_RPORT PINB
|
||||||
#define PB5_WPORT PORTB
|
#define PB5_WPORT PORTB
|
||||||
#define PB5_DDR DDRB
|
#define PB5_DDR DDRB
|
||||||
#define PB5_PWM NULL
|
#define PB5_PWM NULL
|
||||||
|
|
||||||
#undef PB6
|
#undef PB6
|
||||||
#define PB6_PIN PINB6
|
#define PB6_PIN PINB6
|
||||||
#define PB6_RPORT PINB
|
#define PB6_RPORT PINB
|
||||||
#define PB6_WPORT PORTB
|
#define PB6_WPORT PORTB
|
||||||
#define PB6_DDR DDRB
|
#define PB6_DDR DDRB
|
||||||
#define PB6_PWM NULL
|
#define PB6_PWM NULL
|
||||||
|
|
||||||
#undef PB7
|
#undef PB7
|
||||||
#define PB7_PIN PINB7
|
#define PB7_PIN PINB7
|
||||||
#define PB7_RPORT PINB
|
#define PB7_RPORT PINB
|
||||||
#define PB7_WPORT PORTB
|
#define PB7_WPORT PORTB
|
||||||
#define PB7_DDR DDRB
|
#define PB7_DDR DDRB
|
||||||
#define PB7_PWM NULL
|
#define PB7_PWM NULL
|
||||||
|
|
||||||
|
|
||||||
#undef PC0
|
#undef PC0
|
||||||
#define PC0_PIN PINC0
|
#define PC0_PIN PINC0
|
||||||
#define PC0_RPORT PINC
|
#define PC0_RPORT PINC
|
||||||
#define PC0_WPORT PORTC
|
#define PC0_WPORT PORTC
|
||||||
#define PC0_DDR DDRC
|
#define PC0_DDR DDRC
|
||||||
#define PC0_PWM NULL
|
#define PC0_PWM NULL
|
||||||
|
|
||||||
#undef PC1
|
#undef PC1
|
||||||
#define PC1_PIN PINC1
|
#define PC1_PIN PINC1
|
||||||
#define PC1_RPORT PINC
|
#define PC1_RPORT PINC
|
||||||
#define PC1_WPORT PORTC
|
#define PC1_WPORT PORTC
|
||||||
#define PC1_DDR DDRC
|
#define PC1_DDR DDRC
|
||||||
#define PC1_PWM NULL
|
#define PC1_PWM NULL
|
||||||
|
|
||||||
#undef PC2
|
#undef PC2
|
||||||
#define PC2_PIN PINC2
|
#define PC2_PIN PINC2
|
||||||
#define PC2_RPORT PINC
|
#define PC2_RPORT PINC
|
||||||
#define PC2_WPORT PORTC
|
#define PC2_WPORT PORTC
|
||||||
#define PC2_DDR DDRC
|
#define PC2_DDR DDRC
|
||||||
#define PC2_PWM NULL
|
#define PC2_PWM NULL
|
||||||
|
|
||||||
#undef PC3
|
#undef PC3
|
||||||
#define PC3_PIN PINC3
|
#define PC3_PIN PINC3
|
||||||
#define PC3_RPORT PINC
|
#define PC3_RPORT PINC
|
||||||
#define PC3_WPORT PORTC
|
#define PC3_WPORT PORTC
|
||||||
#define PC3_DDR DDRC
|
#define PC3_DDR DDRC
|
||||||
#define PC3_PWM NULL
|
#define PC3_PWM NULL
|
||||||
|
|
||||||
#undef PC4
|
#undef PC4
|
||||||
#define PC4_PIN PINC4
|
#define PC4_PIN PINC4
|
||||||
#define PC4_RPORT PINC
|
#define PC4_RPORT PINC
|
||||||
#define PC4_WPORT PORTC
|
#define PC4_WPORT PORTC
|
||||||
#define PC4_DDR DDRC
|
#define PC4_DDR DDRC
|
||||||
#define PC4_PWM NULL
|
#define PC4_PWM NULL
|
||||||
|
|
||||||
#undef PC5
|
#undef PC5
|
||||||
#define PC5_PIN PINC5
|
#define PC5_PIN PINC5
|
||||||
#define PC5_RPORT PINC
|
#define PC5_RPORT PINC
|
||||||
#define PC5_WPORT PORTC
|
#define PC5_WPORT PORTC
|
||||||
#define PC5_DDR DDRC
|
#define PC5_DDR DDRC
|
||||||
#define PC5_PWM NULL
|
#define PC5_PWM NULL
|
||||||
|
|
||||||
#undef PC6
|
#undef PC6
|
||||||
#define PC6_PIN PINC6
|
#define PC6_PIN PINC6
|
||||||
#define PC6_RPORT PINC
|
#define PC6_RPORT PINC
|
||||||
#define PC6_WPORT PORTC
|
#define PC6_WPORT PORTC
|
||||||
#define PC6_DDR DDRC
|
#define PC6_DDR DDRC
|
||||||
#define PC6_PWM NULL
|
#define PC6_PWM NULL
|
||||||
|
|
||||||
#undef PC7
|
#undef PC7
|
||||||
#define PC7_PIN PINC7
|
#define PC7_PIN PINC7
|
||||||
#define PC7_RPORT PINC
|
#define PC7_RPORT PINC
|
||||||
#define PC7_WPORT PORTC
|
#define PC7_WPORT PORTC
|
||||||
#define PC7_DDR DDRC
|
#define PC7_DDR DDRC
|
||||||
#define PC7_PWM NULL
|
#define PC7_PWM NULL
|
||||||
|
|
||||||
|
|
||||||
#undef PD0
|
#undef PD0
|
||||||
#define PD0_PIN PIND0
|
#define PD0_PIN PIND0
|
||||||
#define PD0_RPORT PIND
|
#define PD0_RPORT PIND
|
||||||
#define PD0_WPORT PORTD
|
#define PD0_WPORT PORTD
|
||||||
#define PD0_DDR DDRD
|
#define PD0_DDR DDRD
|
||||||
#define PD0_PWM NULL
|
#define PD0_PWM NULL
|
||||||
|
|
||||||
#undef PD1
|
#undef PD1
|
||||||
#define PD1_PIN PIND1
|
#define PD1_PIN PIND1
|
||||||
#define PD1_RPORT PIND
|
#define PD1_RPORT PIND
|
||||||
#define PD1_WPORT PORTD
|
#define PD1_WPORT PORTD
|
||||||
#define PD1_DDR DDRD
|
#define PD1_DDR DDRD
|
||||||
#define PD1_PWM NULL
|
#define PD1_PWM NULL
|
||||||
|
|
||||||
#undef PD2
|
#undef PD2
|
||||||
#define PD2_PIN PIND2
|
#define PD2_PIN PIND2
|
||||||
#define PD2_RPORT PIND
|
#define PD2_RPORT PIND
|
||||||
#define PD2_WPORT PORTD
|
#define PD2_WPORT PORTD
|
||||||
#define PD2_DDR DDRD
|
#define PD2_DDR DDRD
|
||||||
#define PD2_PWM NULL
|
#define PD2_PWM NULL
|
||||||
|
|
||||||
#undef PD3
|
#undef PD3
|
||||||
#define PD3_PIN PIND3
|
#define PD3_PIN PIND3
|
||||||
#define PD3_RPORT PIND
|
#define PD3_RPORT PIND
|
||||||
#define PD3_WPORT PORTD
|
#define PD3_WPORT PORTD
|
||||||
#define PD3_DDR DDRD
|
#define PD3_DDR DDRD
|
||||||
#define PD3_PWM &OCR2B
|
#define PD3_PWM &OCR2B
|
||||||
|
|
||||||
#undef PD4
|
#undef PD4
|
||||||
#define PD4_PIN PIND4
|
#define PD4_PIN PIND4
|
||||||
#define PD4_RPORT PIND
|
#define PD4_RPORT PIND
|
||||||
#define PD4_WPORT PORTD
|
#define PD4_WPORT PORTD
|
||||||
#define PD4_DDR DDRD
|
#define PD4_DDR DDRD
|
||||||
#define PD4_PWM NULL
|
#define PD4_PWM NULL
|
||||||
|
|
||||||
#undef PD5
|
#undef PD5
|
||||||
#define PD5_PIN PIND5
|
#define PD5_PIN PIND5
|
||||||
#define PD5_RPORT PIND
|
#define PD5_RPORT PIND
|
||||||
#define PD5_WPORT PORTD
|
#define PD5_WPORT PORTD
|
||||||
#define PD5_DDR DDRD
|
#define PD5_DDR DDRD
|
||||||
#define PD5_PWM &OCR0B
|
#define PD5_PWM &OCR0B
|
||||||
|
|
||||||
#undef PD6
|
#undef PD6
|
||||||
#define PD6_PIN PIND6
|
#define PD6_PIN PIND6
|
||||||
#define PD6_RPORT PIND
|
#define PD6_RPORT PIND
|
||||||
#define PD6_WPORT PORTD
|
#define PD6_WPORT PORTD
|
||||||
#define PD6_DDR DDRD
|
#define PD6_DDR DDRD
|
||||||
#define PD6_PWM &OCR0A
|
#define PD6_PWM &OCR0A
|
||||||
|
|
||||||
#undef PD7
|
#undef PD7
|
||||||
#define PD7_PIN PIND7
|
#define PD7_PIN PIND7
|
||||||
#define PD7_RPORT PIND
|
#define PD7_RPORT PIND
|
||||||
#define PD7_WPORT PORTD
|
#define PD7_WPORT PORTD
|
||||||
#define PD7_DDR DDRD
|
#define PD7_DDR DDRD
|
||||||
#define PD7_PWM NULL
|
#define PD7_PWM NULL
|
||||||
#endif /* _AVR_ATmega{168,328,328P}__ */
|
#endif /* _AVR_ATmega{168,328,328P}__ */
|
||||||
|
|
||||||
#if defined (__AVR_ATmega644__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__)
|
#if defined (__AVR_ATmega644__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__)
|
||||||
// UART
|
// UART
|
||||||
#define RXD DIO8
|
#define RXD DIO8
|
||||||
#define TXD DIO9
|
#define TXD DIO9
|
||||||
#define RXD0 DIO8
|
#define RXD0 DIO8
|
||||||
#define TXD0 DIO9
|
#define TXD0 DIO9
|
||||||
|
|
||||||
#define RXD1 DIO10
|
#define RXD1 DIO10
|
||||||
#define TXD1 DIO11
|
#define TXD1 DIO11
|
||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
#define SCK DIO7
|
#define SCK DIO7
|
||||||
#define MISO DIO6
|
#define MISO DIO6
|
||||||
#define MOSI DIO5
|
#define MOSI DIO5
|
||||||
#define SS DIO4
|
#define SS DIO4
|
||||||
|
|
||||||
// TWI (I2C)
|
// TWI (I2C)
|
||||||
#define SCL DIO16
|
#define SCL DIO16
|
||||||
#define SDA DIO17
|
#define SDA DIO17
|
||||||
|
|
||||||
// timers and PWM
|
// timers and PWM
|
||||||
#define OC0A DIO3
|
#define OC0A DIO3
|
||||||
#define OC0B DIO4
|
#define OC0B DIO4
|
||||||
#define OC1A DIO13
|
#define OC1A DIO13
|
||||||
#define OC1B DIO12
|
#define OC1B DIO12
|
||||||
#define OC2A DIO15
|
#define OC2A DIO15
|
||||||
#define OC2B DIO14
|
#define OC2B DIO14
|
||||||
|
|
||||||
#define DEBUG_LED DIO0
|
#define DEBUG_LED DIO0
|
||||||
/*
|
/*
|
||||||
pins
|
pins
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DIO0_PIN PINB0
|
#define DIO0_PIN PINB0
|
||||||
#define DIO0_RPORT PINB
|
#define DIO0_RPORT PINB
|
||||||
#define DIO0_WPORT PORTB
|
#define DIO0_WPORT PORTB
|
||||||
#define DIO0_DDR DDRB
|
#define DIO0_DDR DDRB
|
||||||
#define DIO0_PWM NULL
|
#define DIO0_PWM NULL
|
||||||
|
|
||||||
#define DIO1_PIN PINB1
|
#define DIO1_PIN PINB1
|
||||||
#define DIO1_RPORT PINB
|
#define DIO1_RPORT PINB
|
||||||
#define DIO1_WPORT PORTB
|
#define DIO1_WPORT PORTB
|
||||||
#define DIO1_DDR DDRB
|
#define DIO1_DDR DDRB
|
||||||
#define DIO1_PWM NULL
|
#define DIO1_PWM NULL
|
||||||
|
|
||||||
#define DIO2_PIN PINB2
|
#define DIO2_PIN PINB2
|
||||||
#define DIO2_RPORT PINB
|
#define DIO2_RPORT PINB
|
||||||
#define DIO2_WPORT PORTB
|
#define DIO2_WPORT PORTB
|
||||||
#define DIO2_DDR DDRB
|
#define DIO2_DDR DDRB
|
||||||
#define DIO2_PWM NULL
|
#define DIO2_PWM NULL
|
||||||
|
|
||||||
#define DIO3_PIN PINB3
|
#define DIO3_PIN PINB3
|
||||||
#define DIO3_RPORT PINB
|
#define DIO3_RPORT PINB
|
||||||
#define DIO3_WPORT PORTB
|
#define DIO3_WPORT PORTB
|
||||||
#define DIO3_DDR DDRB
|
#define DIO3_DDR DDRB
|
||||||
#define DIO3_PWM &OCR0A
|
#define DIO3_PWM &OCR0A
|
||||||
|
|
||||||
#define DIO4_PIN PINB4
|
#define DIO4_PIN PINB4
|
||||||
#define DIO4_RPORT PINB
|
#define DIO4_RPORT PINB
|
||||||
#define DIO4_WPORT PORTB
|
#define DIO4_WPORT PORTB
|
||||||
#define DIO4_DDR DDRB
|
#define DIO4_DDR DDRB
|
||||||
#define DIO4_PWM &OCR0B
|
#define DIO4_PWM &OCR0B
|
||||||
|
|
||||||
#define DIO5_PIN PINB5
|
#define DIO5_PIN PINB5
|
||||||
#define DIO5_RPORT PINB
|
#define DIO5_RPORT PINB
|
||||||
#define DIO5_WPORT PORTB
|
#define DIO5_WPORT PORTB
|
||||||
#define DIO5_DDR DDRB
|
#define DIO5_DDR DDRB
|
||||||
#define DIO5_PWM NULL
|
#define DIO5_PWM NULL
|
||||||
|
|
||||||
#define DIO6_PIN PINB6
|
#define DIO6_PIN PINB6
|
||||||
#define DIO6_RPORT PINB
|
#define DIO6_RPORT PINB
|
||||||
#define DIO6_WPORT PORTB
|
#define DIO6_WPORT PORTB
|
||||||
#define DIO6_DDR DDRB
|
#define DIO6_DDR DDRB
|
||||||
#define DIO6_PWM NULL
|
#define DIO6_PWM NULL
|
||||||
|
|
||||||
#define DIO7_PIN PINB7
|
#define DIO7_PIN PINB7
|
||||||
#define DIO7_RPORT PINB
|
#define DIO7_RPORT PINB
|
||||||
#define DIO7_WPORT PORTB
|
#define DIO7_WPORT PORTB
|
||||||
#define DIO7_DDR DDRB
|
#define DIO7_DDR DDRB
|
||||||
#define DIO7_PWM NULL
|
#define DIO7_PWM NULL
|
||||||
|
|
||||||
#define DIO8_PIN PIND0
|
#define DIO8_PIN PIND0
|
||||||
#define DIO8_RPORT PIND
|
#define DIO8_RPORT PIND
|
||||||
#define DIO8_WPORT PORTD
|
#define DIO8_WPORT PORTD
|
||||||
#define DIO8_DDR DDRD
|
#define DIO8_DDR DDRD
|
||||||
#define DIO8_PWM NULL
|
#define DIO8_PWM NULL
|
||||||
|
|
||||||
#define DIO9_PIN PIND1
|
#define DIO9_PIN PIND1
|
||||||
#define DIO9_RPORT PIND
|
#define DIO9_RPORT PIND
|
||||||
#define DIO9_WPORT PORTD
|
#define DIO9_WPORT PORTD
|
||||||
#define DIO9_DDR DDRD
|
#define DIO9_DDR DDRD
|
||||||
#define DIO9_PWM NULL
|
#define DIO9_PWM NULL
|
||||||
|
|
||||||
#define DIO10_PIN PIND2
|
#define DIO10_PIN PIND2
|
||||||
#define DIO10_RPORT PIND
|
#define DIO10_RPORT PIND
|
||||||
#define DIO10_WPORT PORTD
|
#define DIO10_WPORT PORTD
|
||||||
#define DIO10_DDR DDRD
|
#define DIO10_DDR DDRD
|
||||||
#define DIO10_PWM NULL
|
#define DIO10_PWM NULL
|
||||||
|
|
||||||
#define DIO11_PIN PIND3
|
#define DIO11_PIN PIND3
|
||||||
#define DIO11_RPORT PIND
|
#define DIO11_RPORT PIND
|
||||||
#define DIO11_WPORT PORTD
|
#define DIO11_WPORT PORTD
|
||||||
#define DIO11_DDR DDRD
|
#define DIO11_DDR DDRD
|
||||||
#define DIO11_PWM NULL
|
#define DIO11_PWM NULL
|
||||||
|
|
||||||
#define DIO12_PIN PIND4
|
#define DIO12_PIN PIND4
|
||||||
#define DIO12_RPORT PIND
|
#define DIO12_RPORT PIND
|
||||||
#define DIO12_WPORT PORTD
|
#define DIO12_WPORT PORTD
|
||||||
#define DIO12_DDR DDRD
|
#define DIO12_DDR DDRD
|
||||||
#define DIO12_PWM NULL
|
#define DIO12_PWM NULL
|
||||||
|
|
||||||
#define DIO13_PIN PIND5
|
#define DIO13_PIN PIND5
|
||||||
#define DIO13_RPORT PIND
|
#define DIO13_RPORT PIND
|
||||||
#define DIO13_WPORT PORTD
|
#define DIO13_WPORT PORTD
|
||||||
#define DIO13_DDR DDRD
|
#define DIO13_DDR DDRD
|
||||||
#define DIO13_PWM NULL
|
#define DIO13_PWM NULL
|
||||||
|
|
||||||
#define DIO14_PIN PIND6
|
#define DIO14_PIN PIND6
|
||||||
#define DIO14_RPORT PIND
|
#define DIO14_RPORT PIND
|
||||||
#define DIO14_WPORT PORTD
|
#define DIO14_WPORT PORTD
|
||||||
#define DIO14_DDR DDRD
|
#define DIO14_DDR DDRD
|
||||||
#define DIO14_PWM &OCR2B
|
#define DIO14_PWM &OCR2B
|
||||||
|
|
||||||
#define DIO15_PIN PIND7
|
#define DIO15_PIN PIND7
|
||||||
#define DIO15_RPORT PIND
|
#define DIO15_RPORT PIND
|
||||||
#define DIO15_WPORT PORTD
|
#define DIO15_WPORT PORTD
|
||||||
#define DIO15_DDR DDRD
|
#define DIO15_DDR DDRD
|
||||||
#define DIO15_PWM &OCR2A
|
#define DIO15_PWM &OCR2A
|
||||||
|
|
||||||
#define DIO16_PIN PINC0
|
#define DIO16_PIN PINC0
|
||||||
#define DIO16_RPORT PINC
|
#define DIO16_RPORT PINC
|
||||||
#define DIO16_WPORT PORTC
|
#define DIO16_WPORT PORTC
|
||||||
#define DIO16_DDR DDRC
|
#define DIO16_DDR DDRC
|
||||||
#define DIO16_PWM NULL
|
#define DIO16_PWM NULL
|
||||||
|
|
||||||
#define DIO17_PIN PINC1
|
#define DIO17_PIN PINC1
|
||||||
#define DIO17_RPORT PINC
|
#define DIO17_RPORT PINC
|
||||||
#define DIO17_WPORT PORTC
|
#define DIO17_WPORT PORTC
|
||||||
#define DIO17_DDR DDRC
|
#define DIO17_DDR DDRC
|
||||||
#define DIO17_PWM NULL
|
#define DIO17_PWM NULL
|
||||||
|
|
||||||
#define DIO18_PIN PINC2
|
#define DIO18_PIN PINC2
|
||||||
#define DIO18_RPORT PINC
|
#define DIO18_RPORT PINC
|
||||||
#define DIO18_WPORT PORTC
|
#define DIO18_WPORT PORTC
|
||||||
#define DIO18_DDR DDRC
|
#define DIO18_DDR DDRC
|
||||||
#define DIO18_PWM NULL
|
#define DIO18_PWM NULL
|
||||||
|
|
||||||
#define DIO19_PIN PINC3
|
#define DIO19_PIN PINC3
|
||||||
#define DIO19_RPORT PINC
|
#define DIO19_RPORT PINC
|
||||||
#define DIO19_WPORT PORTC
|
#define DIO19_WPORT PORTC
|
||||||
#define DIO19_DDR DDRC
|
#define DIO19_DDR DDRC
|
||||||
#define DIO19_PWM NULL
|
#define DIO19_PWM NULL
|
||||||
|
|
||||||
#define DIO20_PIN PINC4
|
#define DIO20_PIN PINC4
|
||||||
#define DIO20_RPORT PINC
|
#define DIO20_RPORT PINC
|
||||||
#define DIO20_WPORT PORTC
|
#define DIO20_WPORT PORTC
|
||||||
#define DIO20_DDR DDRC
|
#define DIO20_DDR DDRC
|
||||||
#define DIO20_PWM NULL
|
#define DIO20_PWM NULL
|
||||||
|
|
||||||
#define DIO21_PIN PINC5
|
#define DIO21_PIN PINC5
|
||||||
#define DIO21_RPORT PINC
|
#define DIO21_RPORT PINC
|
||||||
#define DIO21_WPORT PORTC
|
#define DIO21_WPORT PORTC
|
||||||
#define DIO21_DDR DDRC
|
#define DIO21_DDR DDRC
|
||||||
#define DIO21_PWM NULL
|
#define DIO21_PWM NULL
|
||||||
|
|
||||||
#define DIO22_PIN PINC6
|
#define DIO22_PIN PINC6
|
||||||
#define DIO22_RPORT PINC
|
#define DIO22_RPORT PINC
|
||||||
#define DIO22_WPORT PORTC
|
#define DIO22_WPORT PORTC
|
||||||
#define DIO22_DDR DDRC
|
#define DIO22_DDR DDRC
|
||||||
#define DIO22_PWM NULL
|
#define DIO22_PWM NULL
|
||||||
|
|
||||||
#define DIO23_PIN PINC7
|
#define DIO23_PIN PINC7
|
||||||
#define DIO23_RPORT PINC
|
#define DIO23_RPORT PINC
|
||||||
#define DIO23_WPORT PORTC
|
#define DIO23_WPORT PORTC
|
||||||
#define DIO23_DDR DDRC
|
#define DIO23_DDR DDRC
|
||||||
#define DIO23_PWM NULL
|
#define DIO23_PWM NULL
|
||||||
|
|
||||||
#define DIO24_PIN PINA7
|
#define DIO24_PIN PINA7
|
||||||
#define DIO24_RPORT PINA
|
#define DIO24_RPORT PINA
|
||||||
#define DIO24_WPORT PORTA
|
#define DIO24_WPORT PORTA
|
||||||
#define DIO24_DDR DDRA
|
#define DIO24_DDR DDRA
|
||||||
#define DIO24_PWM NULL
|
#define DIO24_PWM NULL
|
||||||
|
|
||||||
#define DIO25_PIN PINA6
|
#define DIO25_PIN PINA6
|
||||||
#define DIO25_RPORT PINA
|
#define DIO25_RPORT PINA
|
||||||
#define DIO25_WPORT PORTA
|
#define DIO25_WPORT PORTA
|
||||||
#define DIO25_DDR DDRA
|
#define DIO25_DDR DDRA
|
||||||
#define DIO25_PWM NULL
|
#define DIO25_PWM NULL
|
||||||
|
|
||||||
#define DIO26_PIN PINA5
|
#define DIO26_PIN PINA5
|
||||||
#define DIO26_RPORT PINA
|
#define DIO26_RPORT PINA
|
||||||
#define DIO26_WPORT PORTA
|
#define DIO26_WPORT PORTA
|
||||||
#define DIO26_DDR DDRA
|
#define DIO26_DDR DDRA
|
||||||
#define DIO26_PWM NULL
|
#define DIO26_PWM NULL
|
||||||
|
|
||||||
#define DIO27_PIN PINA4
|
#define DIO27_PIN PINA4
|
||||||
#define DIO27_RPORT PINA
|
#define DIO27_RPORT PINA
|
||||||
#define DIO27_WPORT PORTA
|
#define DIO27_WPORT PORTA
|
||||||
#define DIO27_DDR DDRA
|
#define DIO27_DDR DDRA
|
||||||
#define DIO27_PWM NULL
|
#define DIO27_PWM NULL
|
||||||
|
|
||||||
#define DIO28_PIN PINA3
|
#define DIO28_PIN PINA3
|
||||||
#define DIO28_RPORT PINA
|
#define DIO28_RPORT PINA
|
||||||
#define DIO28_WPORT PORTA
|
#define DIO28_WPORT PORTA
|
||||||
#define DIO28_DDR DDRA
|
#define DIO28_DDR DDRA
|
||||||
#define DIO28_PWM NULL
|
#define DIO28_PWM NULL
|
||||||
|
|
||||||
#define DIO29_PIN PINA2
|
#define DIO29_PIN PINA2
|
||||||
#define DIO29_RPORT PINA
|
#define DIO29_RPORT PINA
|
||||||
#define DIO29_WPORT PORTA
|
#define DIO29_WPORT PORTA
|
||||||
#define DIO29_DDR DDRA
|
#define DIO29_DDR DDRA
|
||||||
#define DIO29_PWM NULL
|
#define DIO29_PWM NULL
|
||||||
|
|
||||||
#define DIO30_PIN PINA1
|
#define DIO30_PIN PINA1
|
||||||
#define DIO30_RPORT PINA
|
#define DIO30_RPORT PINA
|
||||||
#define DIO30_WPORT PORTA
|
#define DIO30_WPORT PORTA
|
||||||
#define DIO30_DDR DDRA
|
#define DIO30_DDR DDRA
|
||||||
#define DIO30_PWM NULL
|
#define DIO30_PWM NULL
|
||||||
|
|
||||||
#define DIO31_PIN PINA0
|
#define DIO31_PIN PINA0
|
||||||
#define DIO31_RPORT PINA
|
#define DIO31_RPORT PINA
|
||||||
#define DIO31_WPORT PORTA
|
#define DIO31_WPORT PORTA
|
||||||
#define DIO31_DDR DDRA
|
#define DIO31_DDR DDRA
|
||||||
#define DIO31_PWM NULL
|
#define DIO31_PWM NULL
|
||||||
|
|
||||||
#define AIO0_PIN PINA0
|
#define AIO0_PIN PINA0
|
||||||
#define AIO0_RPORT PINA
|
#define AIO0_RPORT PINA
|
||||||
#define AIO0_WPORT PORTA
|
#define AIO0_WPORT PORTA
|
||||||
#define AIO0_DDR DDRA
|
#define AIO0_DDR DDRA
|
||||||
#define AIO0_PWM NULL
|
#define AIO0_PWM NULL
|
||||||
|
|
||||||
#define AIO1_PIN PINA1
|
#define AIO1_PIN PINA1
|
||||||
#define AIO1_RPORT PINA
|
#define AIO1_RPORT PINA
|
||||||
#define AIO1_WPORT PORTA
|
#define AIO1_WPORT PORTA
|
||||||
#define AIO1_DDR DDRA
|
#define AIO1_DDR DDRA
|
||||||
#define AIO1_PWM NULL
|
#define AIO1_PWM NULL
|
||||||
|
|
||||||
#define AIO2_PIN PINA2
|
#define AIO2_PIN PINA2
|
||||||
#define AIO2_RPORT PINA
|
#define AIO2_RPORT PINA
|
||||||
#define AIO2_WPORT PORTA
|
#define AIO2_WPORT PORTA
|
||||||
#define AIO2_DDR DDRA
|
#define AIO2_DDR DDRA
|
||||||
#define AIO2_PWM NULL
|
#define AIO2_PWM NULL
|
||||||
|
|
||||||
#define AIO3_PIN PINA3
|
#define AIO3_PIN PINA3
|
||||||
#define AIO3_RPORT PINA
|
#define AIO3_RPORT PINA
|
||||||
#define AIO3_WPORT PORTA
|
#define AIO3_WPORT PORTA
|
||||||
#define AIO3_DDR DDRA
|
#define AIO3_DDR DDRA
|
||||||
#define AIO3_PWM NULL
|
#define AIO3_PWM NULL
|
||||||
|
|
||||||
#define AIO4_PIN PINA4
|
#define AIO4_PIN PINA4
|
||||||
#define AIO4_RPORT PINA
|
#define AIO4_RPORT PINA
|
||||||
#define AIO4_WPORT PORTA
|
#define AIO4_WPORT PORTA
|
||||||
#define AIO4_DDR DDRA
|
#define AIO4_DDR DDRA
|
||||||
#define AIO4_PWM NULL
|
#define AIO4_PWM NULL
|
||||||
|
|
||||||
#define AIO5_PIN PINA5
|
#define AIO5_PIN PINA5
|
||||||
#define AIO5_RPORT PINA
|
#define AIO5_RPORT PINA
|
||||||
#define AIO5_WPORT PORTA
|
#define AIO5_WPORT PORTA
|
||||||
#define AIO5_DDR DDRA
|
#define AIO5_DDR DDRA
|
||||||
#define AIO5_PWM NULL
|
#define AIO5_PWM NULL
|
||||||
|
|
||||||
#define AIO6_PIN PINA6
|
#define AIO6_PIN PINA6
|
||||||
#define AIO6_RPORT PINA
|
#define AIO6_RPORT PINA
|
||||||
#define AIO6_WPORT PORTA
|
#define AIO6_WPORT PORTA
|
||||||
#define AIO6_DDR DDRA
|
#define AIO6_DDR DDRA
|
||||||
#define AIO6_PWM NULL
|
#define AIO6_PWM NULL
|
||||||
|
|
||||||
#define AIO7_PIN PINA7
|
#define AIO7_PIN PINA7
|
||||||
#define AIO7_RPORT PINA
|
#define AIO7_RPORT PINA
|
||||||
#define AIO7_WPORT PORTA
|
#define AIO7_WPORT PORTA
|
||||||
#define AIO7_DDR DDRA
|
#define AIO7_DDR DDRA
|
||||||
#define AIO7_PWM NULL
|
#define AIO7_PWM NULL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#undef PA0
|
#undef PA0
|
||||||
#define PA0_PIN PINA0
|
#define PA0_PIN PINA0
|
||||||
#define PA0_RPORT PINA
|
#define PA0_RPORT PINA
|
||||||
#define PA0_WPORT PORTA
|
#define PA0_WPORT PORTA
|
||||||
#define PA0_DDR DDRA
|
#define PA0_DDR DDRA
|
||||||
#define PA0_PWM NULL
|
#define PA0_PWM NULL
|
||||||
|
|
||||||
#undef PA1
|
#undef PA1
|
||||||
#define PA1_PIN PINA1
|
#define PA1_PIN PINA1
|
||||||
#define PA1_RPORT PINA
|
#define PA1_RPORT PINA
|
||||||
#define PA1_WPORT PORTA
|
#define PA1_WPORT PORTA
|
||||||
#define PA1_DDR DDRA
|
#define PA1_DDR DDRA
|
||||||
#define PA1_PWM NULL
|
#define PA1_PWM NULL
|
||||||
|
|
||||||
#undef PA2
|
#undef PA2
|
||||||
#define PA2_PIN PINA2
|
#define PA2_PIN PINA2
|
||||||
#define PA2_RPORT PINA
|
#define PA2_RPORT PINA
|
||||||
#define PA2_WPORT PORTA
|
#define PA2_WPORT PORTA
|
||||||
#define PA2_DDR DDRA
|
#define PA2_DDR DDRA
|
||||||
#define PA2_PWM NULL
|
#define PA2_PWM NULL
|
||||||
|
|
||||||
#undef PA3
|
#undef PA3
|
||||||
#define PA3_PIN PINA3
|
#define PA3_PIN PINA3
|
||||||
#define PA3_RPORT PINA
|
#define PA3_RPORT PINA
|
||||||
#define PA3_WPORT PORTA
|
#define PA3_WPORT PORTA
|
||||||
#define PA3_DDR DDRA
|
#define PA3_DDR DDRA
|
||||||
#define PA3_PWM NULL
|
#define PA3_PWM NULL
|
||||||
|
|
||||||
#undef PA4
|
#undef PA4
|
||||||
#define PA4_PIN PINA4
|
#define PA4_PIN PINA4
|
||||||
#define PA4_RPORT PINA
|
#define PA4_RPORT PINA
|
||||||
#define PA4_WPORT PORTA
|
#define PA4_WPORT PORTA
|
||||||
#define PA4_DDR DDRA
|
#define PA4_DDR DDRA
|
||||||
#define PA4_PWM NULL
|
#define PA4_PWM NULL
|
||||||
|
|
||||||
#undef PA5
|
#undef PA5
|
||||||
#define PA5_PIN PINA5
|
#define PA5_PIN PINA5
|
||||||
#define PA5_RPORT PINA
|
#define PA5_RPORT PINA
|
||||||
#define PA5_WPORT PORTA
|
#define PA5_WPORT PORTA
|
||||||
#define PA5_DDR DDRA
|
#define PA5_DDR DDRA
|
||||||
#define PA5_PWM NULL
|
#define PA5_PWM NULL
|
||||||
|
|
||||||
#undef PA6
|
#undef PA6
|
||||||
#define PA6_PIN PINA6
|
#define PA6_PIN PINA6
|
||||||
#define PA6_RPORT PINA
|
#define PA6_RPORT PINA
|
||||||
#define PA6_WPORT PORTA
|
#define PA6_WPORT PORTA
|
||||||
#define PA6_DDR DDRA
|
#define PA6_DDR DDRA
|
||||||
#define PA6_PWM NULL
|
#define PA6_PWM NULL
|
||||||
|
|
||||||
#undef PA7
|
#undef PA7
|
||||||
#define PA7_PIN PINA7
|
#define PA7_PIN PINA7
|
||||||
#define PA7_RPORT PINA
|
#define PA7_RPORT PINA
|
||||||
#define PA7_WPORT PORTA
|
#define PA7_WPORT PORTA
|
||||||
#define PA7_DDR DDRA
|
#define PA7_DDR DDRA
|
||||||
#define PA7_PWM NULL
|
#define PA7_PWM NULL
|
||||||
|
|
||||||
|
|
||||||
#undef PB0
|
#undef PB0
|
||||||
#define PB0_PIN PINB0
|
#define PB0_PIN PINB0
|
||||||
#define PB0_RPORT PINB
|
#define PB0_RPORT PINB
|
||||||
#define PB0_WPORT PORTB
|
#define PB0_WPORT PORTB
|
||||||
#define PB0_DDR DDRB
|
#define PB0_DDR DDRB
|
||||||
#define PB0_PWM NULL
|
#define PB0_PWM NULL
|
||||||
|
|
||||||
#undef PB1
|
#undef PB1
|
||||||
#define PB1_PIN PINB1
|
#define PB1_PIN PINB1
|
||||||
#define PB1_RPORT PINB
|
#define PB1_RPORT PINB
|
||||||
#define PB1_WPORT PORTB
|
#define PB1_WPORT PORTB
|
||||||
#define PB1_DDR DDRB
|
#define PB1_DDR DDRB
|
||||||
#define PB1_PWM NULL
|
#define PB1_PWM NULL
|
||||||
|
|
||||||
#undef PB2
|
#undef PB2
|
||||||
#define PB2_PIN PINB2
|
#define PB2_PIN PINB2
|
||||||
#define PB2_RPORT PINB
|
#define PB2_RPORT PINB
|
||||||
#define PB2_WPORT PORTB
|
#define PB2_WPORT PORTB
|
||||||
#define PB2_DDR DDRB
|
#define PB2_DDR DDRB
|
||||||
#define PB2_PWM NULL
|
#define PB2_PWM NULL
|
||||||
|
|
||||||
#undef PB3
|
#undef PB3
|
||||||
#define PB3_PIN PINB3
|
#define PB3_PIN PINB3
|
||||||
#define PB3_RPORT PINB
|
#define PB3_RPORT PINB
|
||||||
#define PB3_WPORT PORTB
|
#define PB3_WPORT PORTB
|
||||||
#define PB3_DDR DDRB
|
#define PB3_DDR DDRB
|
||||||
#define PB3_PWM &OCR0A
|
#define PB3_PWM &OCR0A
|
||||||
|
|
||||||
#undef PB4
|
#undef PB4
|
||||||
#define PB4_PIN PINB4
|
#define PB4_PIN PINB4
|
||||||
#define PB4_RPORT PINB
|
#define PB4_RPORT PINB
|
||||||
#define PB4_WPORT PORTB
|
#define PB4_WPORT PORTB
|
||||||
#define PB4_DDR DDRB
|
#define PB4_DDR DDRB
|
||||||
#define PB4_PWM &OCR0B
|
#define PB4_PWM &OCR0B
|
||||||
|
|
||||||
#undef PB5
|
#undef PB5
|
||||||
#define PB5_PIN PINB5
|
#define PB5_PIN PINB5
|
||||||
#define PB5_RPORT PINB
|
#define PB5_RPORT PINB
|
||||||
#define PB5_WPORT PORTB
|
#define PB5_WPORT PORTB
|
||||||
#define PB5_DDR DDRB
|
#define PB5_DDR DDRB
|
||||||
#define PB5_PWM NULL
|
#define PB5_PWM NULL
|
||||||
|
|
||||||
#undef PB6
|
#undef PB6
|
||||||
#define PB6_PIN PINB6
|
#define PB6_PIN PINB6
|
||||||
#define PB6_RPORT PINB
|
#define PB6_RPORT PINB
|
||||||
#define PB6_WPORT PORTB
|
#define PB6_WPORT PORTB
|
||||||
#define PB6_DDR DDRB
|
#define PB6_DDR DDRB
|
||||||
#define PB6_PWM NULL
|
#define PB6_PWM NULL
|
||||||
|
|
||||||
#undef PB7
|
#undef PB7
|
||||||
#define PB7_PIN PINB7
|
#define PB7_PIN PINB7
|
||||||
#define PB7_RPORT PINB
|
#define PB7_RPORT PINB
|
||||||
#define PB7_WPORT PORTB
|
#define PB7_WPORT PORTB
|
||||||
#define PB7_DDR DDRB
|
#define PB7_DDR DDRB
|
||||||
#define PB7_PWM NULL
|
#define PB7_PWM NULL
|
||||||
|
|
||||||
|
|
||||||
#undef PC0
|
#undef PC0
|
||||||
#define PC0_PIN PINC0
|
#define PC0_PIN PINC0
|
||||||
#define PC0_RPORT PINC
|
#define PC0_RPORT PINC
|
||||||
#define PC0_WPORT PORTC
|
#define PC0_WPORT PORTC
|
||||||
#define PC0_DDR DDRC
|
#define PC0_DDR DDRC
|
||||||
#define PC0_PWM NULL
|
#define PC0_PWM NULL
|
||||||
|
|
||||||
#undef PC1
|
#undef PC1
|
||||||
#define PC1_PIN PINC1
|
#define PC1_PIN PINC1
|
||||||
#define PC1_RPORT PINC
|
#define PC1_RPORT PINC
|
||||||
#define PC1_WPORT PORTC
|
#define PC1_WPORT PORTC
|
||||||
#define PC1_DDR DDRC
|
#define PC1_DDR DDRC
|
||||||
#define PC1_PWM NULL
|
#define PC1_PWM NULL
|
||||||
|
|
||||||
#undef PC2
|
#undef PC2
|
||||||
#define PC2_PIN PINC2
|
#define PC2_PIN PINC2
|
||||||
#define PC2_RPORT PINC
|
#define PC2_RPORT PINC
|
||||||
#define PC2_WPORT PORTC
|
#define PC2_WPORT PORTC
|
||||||
#define PC2_DDR DDRC
|
#define PC2_DDR DDRC
|
||||||
#define PC2_PWM NULL
|
#define PC2_PWM NULL
|
||||||
|
|
||||||
#undef PC3
|
#undef PC3
|
||||||
#define PC3_PIN PINC3
|
#define PC3_PIN PINC3
|
||||||
#define PC3_RPORT PINC
|
#define PC3_RPORT PINC
|
||||||
#define PC3_WPORT PORTC
|
#define PC3_WPORT PORTC
|
||||||
#define PC3_DDR DDRC
|
#define PC3_DDR DDRC
|
||||||
#define PC3_PWM NULL
|
#define PC3_PWM NULL
|
||||||
|
|
||||||
#undef PC4
|
#undef PC4
|
||||||
#define PC4_PIN PINC4
|
#define PC4_PIN PINC4
|
||||||
#define PC4_RPORT PINC
|
#define PC4_RPORT PINC
|
||||||
#define PC4_WPORT PORTC
|
#define PC4_WPORT PORTC
|
||||||
#define PC4_DDR DDRC
|
#define PC4_DDR DDRC
|
||||||
#define PC4_PWM NULL
|
#define PC4_PWM NULL
|
||||||
|
|
||||||
#undef PC5
|
#undef PC5
|
||||||
#define PC5_PIN PINC5
|
#define PC5_PIN PINC5
|
||||||
#define PC5_RPORT PINC
|
#define PC5_RPORT PINC
|
||||||
#define PC5_WPORT PORTC
|
#define PC5_WPORT PORTC
|
||||||
#define PC5_DDR DDRC
|
#define PC5_DDR DDRC
|
||||||
#define PC5_PWM NULL
|
#define PC5_PWM NULL
|
||||||
|
|
||||||
#undef PC6
|
#undef PC6
|
||||||
#define PC6_PIN PINC6
|
#define PC6_PIN PINC6
|
||||||
#define PC6_RPORT PINC
|
#define PC6_RPORT PINC
|
||||||
#define PC6_WPORT PORTC
|
#define PC6_WPORT PORTC
|
||||||
#define PC6_DDR DDRC
|
#define PC6_DDR DDRC
|
||||||
#define PC6_PWM NULL
|
#define PC6_PWM NULL
|
||||||
|
|
||||||
#undef PC7
|
#undef PC7
|
||||||
#define PC7_PIN PINC7
|
#define PC7_PIN PINC7
|
||||||
#define PC7_RPORT PINC
|
#define PC7_RPORT PINC
|
||||||
#define PC7_WPORT PORTC
|
#define PC7_WPORT PORTC
|
||||||
#define PC7_DDR DDRC
|
#define PC7_DDR DDRC
|
||||||
#define PC7_PWM NULL
|
#define PC7_PWM NULL
|
||||||
|
|
||||||
|
|
||||||
#undef PD0
|
#undef PD0
|
||||||
#define PD0_PIN PIND0
|
#define PD0_PIN PIND0
|
||||||
#define PD0_RPORT PIND
|
#define PD0_RPORT PIND
|
||||||
#define PD0_WPORT PORTD
|
#define PD0_WPORT PORTD
|
||||||
#define PD0_DDR DDRD
|
#define PD0_DDR DDRD
|
||||||
#define PD0_PWM NULL
|
#define PD0_PWM NULL
|
||||||
|
|
||||||
#undef PD1
|
#undef PD1
|
||||||
#define PD1_PIN PIND1
|
#define PD1_PIN PIND1
|
||||||
#define PD1_RPORT PIND
|
#define PD1_RPORT PIND
|
||||||
#define PD1_WPORT PORTD
|
#define PD1_WPORT PORTD
|
||||||
#define PD1_DDR DDRD
|
#define PD1_DDR DDRD
|
||||||
#define PD1_PWM NULL
|
#define PD1_PWM NULL
|
||||||
|
|
||||||
#undef PD2
|
#undef PD2
|
||||||
#define PD2_PIN PIND2
|
#define PD2_PIN PIND2
|
||||||
#define PD2_RPORT PIND
|
#define PD2_RPORT PIND
|
||||||
#define PD2_WPORT PORTD
|
#define PD2_WPORT PORTD
|
||||||
#define PD2_DDR DDRD
|
#define PD2_DDR DDRD
|
||||||
#define PD2_PWM NULL
|
#define PD2_PWM NULL
|
||||||
|
|
||||||
#undef PD3
|
#undef PD3
|
||||||
#define PD3_PIN PIND3
|
#define PD3_PIN PIND3
|
||||||
#define PD3_RPORT PIND
|
#define PD3_RPORT PIND
|
||||||
#define PD3_WPORT PORTD
|
#define PD3_WPORT PORTD
|
||||||
#define PD3_DDR DDRD
|
#define PD3_DDR DDRD
|
||||||
#define PD3_PWM NULL
|
#define PD3_PWM NULL
|
||||||
|
|
||||||
#undef PD4
|
#undef PD4
|
||||||
#define PD4_PIN PIND4
|
#define PD4_PIN PIND4
|
||||||
#define PD4_RPORT PIND
|
#define PD4_RPORT PIND
|
||||||
#define PD4_WPORT PORTD
|
#define PD4_WPORT PORTD
|
||||||
#define PD4_DDR DDRD
|
#define PD4_DDR DDRD
|
||||||
#define PD4_PWM NULL
|
#define PD4_PWM NULL
|
||||||
|
|
||||||
#undef PD5
|
#undef PD5
|
||||||
#define PD5_PIN PIND5
|
#define PD5_PIN PIND5
|
||||||
#define PD5_RPORT PIND
|
#define PD5_RPORT PIND
|
||||||
#define PD5_WPORT PORTD
|
#define PD5_WPORT PORTD
|
||||||
#define PD5_DDR DDRD
|
#define PD5_DDR DDRD
|
||||||
#define PD5_PWM NULL
|
#define PD5_PWM NULL
|
||||||
|
|
||||||
#undef PD6
|
#undef PD6
|
||||||
#define PD6_PIN PIND6
|
#define PD6_PIN PIND6
|
||||||
#define PD6_RPORT PIND
|
#define PD6_RPORT PIND
|
||||||
#define PD6_WPORT PORTD
|
#define PD6_WPORT PORTD
|
||||||
#define PD6_DDR DDRD
|
#define PD6_DDR DDRD
|
||||||
#define PD6_PWM &OCR2B
|
#define PD6_PWM &OCR2B
|
||||||
|
|
||||||
#undef PD7
|
#undef PD7
|
||||||
#define PD7_PIN PIND7
|
#define PD7_PIN PIND7
|
||||||
#define PD7_RPORT PIND
|
#define PD7_RPORT PIND
|
||||||
#define PD7_WPORT PORTD
|
#define PD7_WPORT PORTD
|
||||||
#define PD7_DDR DDRD
|
#define PD7_DDR DDRD
|
||||||
#define PD7_PWM &OCR2A
|
#define PD7_PWM &OCR2A
|
||||||
#endif /* _AVR_ATmega{644,644P,644PA}__ */
|
#endif /* _AVR_ATmega{644,644P,644PA}__ */
|
||||||
|
|
||||||
#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
|
#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
|
||||||
// UART
|
// UART
|
||||||
#define RXD DIO0
|
#define RXD DIO0
|
||||||
#define TXD DIO1
|
#define TXD DIO1
|
||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
#define SCK DIO52
|
#define SCK DIO52
|
||||||
#define MISO DIO50
|
#define MISO DIO50
|
||||||
#define MOSI DIO51
|
#define MOSI DIO51
|
||||||
#define SS DIO53
|
#define SS DIO53
|
||||||
|
|
||||||
// TWI (I2C)
|
// TWI (I2C)
|
||||||
#define SCL DIO21
|
#define SCL DIO21
|
||||||
#define SDA DIO20
|
#define SDA DIO20
|
||||||
|
|
||||||
// timers and PWM
|
// timers and PWM
|
||||||
#define OC0A DIO13
|
#define OC0A DIO13
|
||||||
#define OC0B DIO4
|
#define OC0B DIO4
|
||||||
#define OC1A DIO11
|
#define OC1A DIO11
|
||||||
#define OC1B DIO12
|
#define OC1B DIO12
|
||||||
#define OC2A DIO10
|
#define OC2A DIO10
|
||||||
#define OC2B DIO9
|
#define OC2B DIO9
|
||||||
#define OC3A DIO5
|
#define OC3A DIO5
|
||||||
#define OC3B DIO2
|
#define OC3B DIO2
|
||||||
#define OC3C DIO3
|
#define OC3C DIO3
|
||||||
#define OC4A DIO6
|
#define OC4A DIO6
|
||||||
#define OC4B DIO7
|
#define OC4B DIO7
|
||||||
#define OC4C DIO8
|
#define OC4C DIO8
|
||||||
#define OC5A DIO46
|
#define OC5A DIO46
|
||||||
#define OC5B DIO45
|
#define OC5B DIO45
|
||||||
#define OC5C DIO44
|
#define OC5C DIO44
|
||||||
|
|
||||||
// change for your board
|
// change for your board
|
||||||
#define DEBUG_LED DIO21
|
#define DEBUG_LED DIO21
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pins
|
pins
|
||||||
*/
|
*/
|
||||||
#define DIO0_PIN PINE0
|
#define DIO0_PIN PINE0
|
||||||
#define DIO0_RPORT PINE
|
#define DIO0_RPORT PINE
|
||||||
#define DIO0_WPORT PORTE
|
#define DIO0_WPORT PORTE
|
||||||
#define DIO0_DDR DDRE
|
#define DIO0_DDR DDRE
|
||||||
#define DIO0_PWM NULL
|
#define DIO0_PWM NULL
|
||||||
|
|
||||||
#define DIO1_PIN PINE1
|
#define DIO1_PIN PINE1
|
||||||
#define DIO1_RPORT PINE
|
#define DIO1_RPORT PINE
|
||||||
#define DIO1_WPORT PORTE
|
#define DIO1_WPORT PORTE
|
||||||
#define DIO1_DDR DDRE
|
#define DIO1_DDR DDRE
|
||||||
#define DIO1_PWM NULL
|
#define DIO1_PWM NULL
|
||||||
|
|
||||||
#define DIO2_PIN PINE4
|
#define DIO2_PIN PINE4
|
||||||
#define DIO2_RPORT PINE
|
#define DIO2_RPORT PINE
|
||||||
#define DIO2_WPORT PORTE
|
#define DIO2_WPORT PORTE
|
||||||
#define DIO2_DDR DDRE
|
#define DIO2_DDR DDRE
|
||||||
#define DIO2_PWM &OCR3BL
|
#define DIO2_PWM &OCR3BL
|
||||||
|
|
||||||
#define DIO3_PIN PINE5
|
#define DIO3_PIN PINE5
|
||||||
#define DIO3_RPORT PINE
|
#define DIO3_RPORT PINE
|
||||||
#define DIO3_WPORT PORTE
|
#define DIO3_WPORT PORTE
|
||||||
#define DIO3_DDR DDRE
|
#define DIO3_DDR DDRE
|
||||||
#define DIO3_PWM &OCR3CL
|
#define DIO3_PWM &OCR3CL
|
||||||
|
|
||||||
#define DIO4_PIN PING5
|
#define DIO4_PIN PING5
|
||||||
#define DIO4_RPORT PING
|
#define DIO4_RPORT PING
|
||||||
#define DIO4_WPORT PORTG
|
#define DIO4_WPORT PORTG
|
||||||
#define DIO4_DDR DDRG
|
#define DIO4_DDR DDRG
|
||||||
#define DIO4_PWM &OCR0B
|
#define DIO4_PWM &OCR0B
|
||||||
|
|
||||||
#define DIO5_PIN PINE3
|
#define DIO5_PIN PINE3
|
||||||
#define DIO5_RPORT PINE
|
#define DIO5_RPORT PINE
|
||||||
#define DIO5_WPORT PORTE
|
#define DIO5_WPORT PORTE
|
||||||
#define DIO5_DDR DDRE
|
#define DIO5_DDR DDRE
|
||||||
#define DIO5_PWM &OCR3AL
|
#define DIO5_PWM &OCR3AL
|
||||||
|
|
||||||
#define DIO6_PIN PINH3
|
#define DIO6_PIN PINH3
|
||||||
#define DIO6_RPORT PINH
|
#define DIO6_RPORT PINH
|
||||||
#define DIO6_WPORT PORTH
|
#define DIO6_WPORT PORTH
|
||||||
#define DIO6_DDR DDRH
|
#define DIO6_DDR DDRH
|
||||||
#define DIO6_PWM &OCR4AL
|
#define DIO6_PWM &OCR4AL
|
||||||
|
|
||||||
#define DIO7_PIN PINH4
|
#define DIO7_PIN PINH4
|
||||||
#define DIO7_RPORT PINH
|
#define DIO7_RPORT PINH
|
||||||
#define DIO7_WPORT PORTH
|
#define DIO7_WPORT PORTH
|
||||||
#define DIO7_DDR DDRH
|
#define DIO7_DDR DDRH
|
||||||
#define DIO7_PWM &OCR4BL
|
#define DIO7_PWM &OCR4BL
|
||||||
|
|
||||||
#define DIO8_PIN PINH5
|
#define DIO8_PIN PINH5
|
||||||
#define DIO8_RPORT PINH
|
#define DIO8_RPORT PINH
|
||||||
#define DIO8_WPORT PORTH
|
#define DIO8_WPORT PORTH
|
||||||
#define DIO8_DDR DDRH
|
#define DIO8_DDR DDRH
|
||||||
#define DIO8_PWM &OCR4CL
|
#define DIO8_PWM &OCR4CL
|
||||||
|
|
||||||
#define DIO9_PIN PINH6
|
#define DIO9_PIN PINH6
|
||||||
#define DIO9_RPORT PINH
|
#define DIO9_RPORT PINH
|
||||||
#define DIO9_WPORT PORTH
|
#define DIO9_WPORT PORTH
|
||||||
#define DIO9_DDR DDRH
|
#define DIO9_DDR DDRH
|
||||||
#define DIO9_PWM &OCR2B
|
#define DIO9_PWM &OCR2B
|
||||||
|
|
||||||
#define DIO10_PIN PINB4
|
#define DIO10_PIN PINB4
|
||||||
#define DIO10_RPORT PINB
|
#define DIO10_RPORT PINB
|
||||||
#define DIO10_WPORT PORTB
|
#define DIO10_WPORT PORTB
|
||||||
#define DIO10_DDR DDRB
|
#define DIO10_DDR DDRB
|
||||||
#define DIO10_PWM &OCR2A
|
#define DIO10_PWM &OCR2A
|
||||||
|
|
||||||
#define DIO11_PIN PINB5
|
#define DIO11_PIN PINB5
|
||||||
#define DIO11_RPORT PINB
|
#define DIO11_RPORT PINB
|
||||||
#define DIO11_WPORT PORTB
|
#define DIO11_WPORT PORTB
|
||||||
#define DIO11_DDR DDRB
|
#define DIO11_DDR DDRB
|
||||||
#define DIO11_PWM NULL
|
#define DIO11_PWM NULL
|
||||||
|
|
||||||
#define DIO12_PIN PINB6
|
#define DIO12_PIN PINB6
|
||||||
#define DIO12_RPORT PINB
|
#define DIO12_RPORT PINB
|
||||||
#define DIO12_WPORT PORTB
|
#define DIO12_WPORT PORTB
|
||||||
#define DIO12_DDR DDRB
|
#define DIO12_DDR DDRB
|
||||||
#define DIO12_PWM NULL
|
#define DIO12_PWM NULL
|
||||||
|
|
||||||
#define DIO13_PIN PINB7
|
#define DIO13_PIN PINB7
|
||||||
#define DIO13_RPORT PINB
|
#define DIO13_RPORT PINB
|
||||||
#define DIO13_WPORT PORTB
|
#define DIO13_WPORT PORTB
|
||||||
#define DIO13_DDR DDRB
|
#define DIO13_DDR DDRB
|
||||||
#define DIO13_PWM &OCR0A
|
#define DIO13_PWM &OCR0A
|
||||||
|
|
||||||
#define DIO14_PIN PINJ1
|
#define DIO14_PIN PINJ1
|
||||||
#define DIO14_RPORT PINJ
|
#define DIO14_RPORT PINJ
|
||||||
#define DIO14_WPORT PORTJ
|
#define DIO14_WPORT PORTJ
|
||||||
#define DIO14_DDR DDRJ
|
#define DIO14_DDR DDRJ
|
||||||
#define DIO14_PWM NULL
|
#define DIO14_PWM NULL
|
||||||
|
|
||||||
#define DIO15_PIN PINJ0
|
#define DIO15_PIN PINJ0
|
||||||
#define DIO15_RPORT PINJ
|
#define DIO15_RPORT PINJ
|
||||||
#define DIO15_WPORT PORTJ
|
#define DIO15_WPORT PORTJ
|
||||||
#define DIO15_DDR DDRJ
|
#define DIO15_DDR DDRJ
|
||||||
#define DIO15_PWM NULL
|
#define DIO15_PWM NULL
|
||||||
|
|
||||||
#define DIO16_PIN PINH1
|
#define DIO16_PIN PINH1
|
||||||
#define DIO16_RPORT PINH
|
#define DIO16_RPORT PINH
|
||||||
#define DIO16_WPORT PORTH
|
#define DIO16_WPORT PORTH
|
||||||
#define DIO16_DDR DDRH
|
#define DIO16_DDR DDRH
|
||||||
#define DIO16_PWM NULL
|
#define DIO16_PWM NULL
|
||||||
|
|
||||||
#define DIO17_PIN PINH0
|
#define DIO17_PIN PINH0
|
||||||
#define DIO17_RPORT PINH
|
#define DIO17_RPORT PINH
|
||||||
#define DIO17_WPORT PORTH
|
#define DIO17_WPORT PORTH
|
||||||
#define DIO17_DDR DDRH
|
#define DIO17_DDR DDRH
|
||||||
#define DIO17_PWM NULL
|
#define DIO17_PWM NULL
|
||||||
|
|
||||||
#define DIO18_PIN PIND3
|
#define DIO18_PIN PIND3
|
||||||
#define DIO18_RPORT PIND
|
#define DIO18_RPORT PIND
|
||||||
#define DIO18_WPORT PORTD
|
#define DIO18_WPORT PORTD
|
||||||
#define DIO18_DDR DDRD
|
#define DIO18_DDR DDRD
|
||||||
#define DIO18_PWM NULL
|
#define DIO18_PWM NULL
|
||||||
|
|
||||||
#define DIO19_PIN PIND2
|
#define DIO19_PIN PIND2
|
||||||
#define DIO19_RPORT PIND
|
#define DIO19_RPORT PIND
|
||||||
#define DIO19_WPORT PORTD
|
#define DIO19_WPORT PORTD
|
||||||
#define DIO19_DDR DDRD
|
#define DIO19_DDR DDRD
|
||||||
#define DIO19_PWM NULL
|
#define DIO19_PWM NULL
|
||||||
|
|
||||||
#define DIO20_PIN PIND1
|
#define DIO20_PIN PIND1
|
||||||
#define DIO20_RPORT PIND
|
#define DIO20_RPORT PIND
|
||||||
#define DIO20_WPORT PORTD
|
#define DIO20_WPORT PORTD
|
||||||
#define DIO20_DDR DDRD
|
#define DIO20_DDR DDRD
|
||||||
#define DIO20_PWM NULL
|
#define DIO20_PWM NULL
|
||||||
|
|
||||||
#define DIO21_PIN PIND0
|
#define DIO21_PIN PIND0
|
||||||
#define DIO21_RPORT PIND
|
#define DIO21_RPORT PIND
|
||||||
#define DIO21_WPORT PORTD
|
#define DIO21_WPORT PORTD
|
||||||
#define DIO21_DDR DDRD
|
#define DIO21_DDR DDRD
|
||||||
#define DIO21_PWM NULL
|
#define DIO21_PWM NULL
|
||||||
|
|
||||||
#define DIO22_PIN PINA0
|
#define DIO22_PIN PINA0
|
||||||
#define DIO22_RPORT PINA
|
#define DIO22_RPORT PINA
|
||||||
#define DIO22_WPORT PORTA
|
#define DIO22_WPORT PORTA
|
||||||
#define DIO22_DDR DDRA
|
#define DIO22_DDR DDRA
|
||||||
#define DIO22_PWM NULL
|
#define DIO22_PWM NULL
|
||||||
|
|
||||||
#define DIO23_PIN PINA1
|
#define DIO23_PIN PINA1
|
||||||
#define DIO23_RPORT PINA
|
#define DIO23_RPORT PINA
|
||||||
#define DIO23_WPORT PORTA
|
#define DIO23_WPORT PORTA
|
||||||
#define DIO23_DDR DDRA
|
#define DIO23_DDR DDRA
|
||||||
#define DIO23_PWM NULL
|
#define DIO23_PWM NULL
|
||||||
|
|
||||||
#define DIO24_PIN PINA2
|
#define DIO24_PIN PINA2
|
||||||
#define DIO24_RPORT PINA
|
#define DIO24_RPORT PINA
|
||||||
#define DIO24_WPORT PORTA
|
#define DIO24_WPORT PORTA
|
||||||
#define DIO24_DDR DDRA
|
#define DIO24_DDR DDRA
|
||||||
#define DIO24_PWM NULL
|
#define DIO24_PWM NULL
|
||||||
|
|
||||||
#define DIO25_PIN PINA3
|
#define DIO25_PIN PINA3
|
||||||
#define DIO25_RPORT PINA
|
#define DIO25_RPORT PINA
|
||||||
#define DIO25_WPORT PORTA
|
#define DIO25_WPORT PORTA
|
||||||
#define DIO25_DDR DDRA
|
#define DIO25_DDR DDRA
|
||||||
#define DIO25_PWM NULL
|
#define DIO25_PWM NULL
|
||||||
|
|
||||||
#define DIO26_PIN PINA4
|
#define DIO26_PIN PINA4
|
||||||
#define DIO26_RPORT PINA
|
#define DIO26_RPORT PINA
|
||||||
#define DIO26_WPORT PORTA
|
#define DIO26_WPORT PORTA
|
||||||
#define DIO26_DDR DDRA
|
#define DIO26_DDR DDRA
|
||||||
#define DIO26_PWM NULL
|
#define DIO26_PWM NULL
|
||||||
|
|
||||||
#define DIO27_PIN PINA5
|
#define DIO27_PIN PINA5
|
||||||
#define DIO27_RPORT PINA
|
#define DIO27_RPORT PINA
|
||||||
#define DIO27_WPORT PORTA
|
#define DIO27_WPORT PORTA
|
||||||
#define DIO27_DDR DDRA
|
#define DIO27_DDR DDRA
|
||||||
#define DIO27_PWM NULL
|
#define DIO27_PWM NULL
|
||||||
|
|
||||||
#define DIO28_PIN PINA6
|
#define DIO28_PIN PINA6
|
||||||
#define DIO28_RPORT PINA
|
#define DIO28_RPORT PINA
|
||||||
#define DIO28_WPORT PORTA
|
#define DIO28_WPORT PORTA
|
||||||
#define DIO28_DDR DDRA
|
#define DIO28_DDR DDRA
|
||||||
#define DIO28_PWM NULL
|
#define DIO28_PWM NULL
|
||||||
|
|
||||||
#define DIO29_PIN PINA7
|
#define DIO29_PIN PINA7
|
||||||
#define DIO29_RPORT PINA
|
#define DIO29_RPORT PINA
|
||||||
#define DIO29_WPORT PORTA
|
#define DIO29_WPORT PORTA
|
||||||
#define DIO29_DDR DDRA
|
#define DIO29_DDR DDRA
|
||||||
#define DIO29_PWM NULL
|
#define DIO29_PWM NULL
|
||||||
|
|
||||||
#define DIO30_PIN PINC7
|
#define DIO30_PIN PINC7
|
||||||
#define DIO30_RPORT PINC
|
#define DIO30_RPORT PINC
|
||||||
#define DIO30_WPORT PORTC
|
#define DIO30_WPORT PORTC
|
||||||
#define DIO30_DDR DDRC
|
#define DIO30_DDR DDRC
|
||||||
#define DIO30_PWM NULL
|
#define DIO30_PWM NULL
|
||||||
|
|
||||||
#define DIO31_PIN PINC6
|
#define DIO31_PIN PINC6
|
||||||
#define DIO31_RPORT PINC
|
#define DIO31_RPORT PINC
|
||||||
#define DIO31_WPORT PORTC
|
#define DIO31_WPORT PORTC
|
||||||
#define DIO31_DDR DDRC
|
#define DIO31_DDR DDRC
|
||||||
#define DIO31_PWM NULL
|
#define DIO31_PWM NULL
|
||||||
|
|
||||||
#define DIO32_PIN PINC5
|
#define DIO32_PIN PINC5
|
||||||
#define DIO32_RPORT PINC
|
#define DIO32_RPORT PINC
|
||||||
#define DIO32_WPORT PORTC
|
#define DIO32_WPORT PORTC
|
||||||
#define DIO32_DDR DDRC
|
#define DIO32_DDR DDRC
|
||||||
#define DIO32_PWM NULL
|
#define DIO32_PWM NULL
|
||||||
|
|
||||||
#define DIO33_PIN PINC4
|
#define DIO33_PIN PINC4
|
||||||
#define DIO33_RPORT PINC
|
#define DIO33_RPORT PINC
|
||||||
#define DIO33_WPORT PORTC
|
#define DIO33_WPORT PORTC
|
||||||
#define DIO33_DDR DDRC
|
#define DIO33_DDR DDRC
|
||||||
#define DIO33_PWM NULL
|
#define DIO33_PWM NULL
|
||||||
|
|
||||||
#define DIO34_PIN PINC3
|
#define DIO34_PIN PINC3
|
||||||
#define DIO34_RPORT PINC
|
#define DIO34_RPORT PINC
|
||||||
#define DIO34_WPORT PORTC
|
#define DIO34_WPORT PORTC
|
||||||
#define DIO34_DDR DDRC
|
#define DIO34_DDR DDRC
|
||||||
#define DIO34_PWM NULL
|
#define DIO34_PWM NULL
|
||||||
|
|
||||||
#define DIO35_PIN PINC2
|
#define DIO35_PIN PINC2
|
||||||
#define DIO35_RPORT PINC
|
#define DIO35_RPORT PINC
|
||||||
#define DIO35_WPORT PORTC
|
#define DIO35_WPORT PORTC
|
||||||
#define DIO35_DDR DDRC
|
#define DIO35_DDR DDRC
|
||||||
#define DIO35_PWM NULL
|
#define DIO35_PWM NULL
|
||||||
|
|
||||||
#define DIO36_PIN PINC1
|
#define DIO36_PIN PINC1
|
||||||
#define DIO36_RPORT PINC
|
#define DIO36_RPORT PINC
|
||||||
#define DIO36_WPORT PORTC
|
#define DIO36_WPORT PORTC
|
||||||
#define DIO36_DDR DDRC
|
#define DIO36_DDR DDRC
|
||||||
#define DIO36_PWM NULL
|
#define DIO36_PWM NULL
|
||||||
|
|
||||||
#define DIO37_PIN PINC0
|
#define DIO37_PIN PINC0
|
||||||
#define DIO37_RPORT PINC
|
#define DIO37_RPORT PINC
|
||||||
#define DIO37_WPORT PORTC
|
#define DIO37_WPORT PORTC
|
||||||
#define DIO37_DDR DDRC
|
#define DIO37_DDR DDRC
|
||||||
#define DIO37_PWM NULL
|
#define DIO37_PWM NULL
|
||||||
|
|
||||||
#define DIO38_PIN PIND7
|
#define DIO38_PIN PIND7
|
||||||
#define DIO38_RPORT PIND
|
#define DIO38_RPORT PIND
|
||||||
#define DIO38_WPORT PORTD
|
#define DIO38_WPORT PORTD
|
||||||
#define DIO38_DDR DDRD
|
#define DIO38_DDR DDRD
|
||||||
#define DIO38_PWM NULL
|
#define DIO38_PWM NULL
|
||||||
|
|
||||||
#define DIO39_PIN PING2
|
#define DIO39_PIN PING2
|
||||||
#define DIO39_RPORT PING
|
#define DIO39_RPORT PING
|
||||||
#define DIO39_WPORT PORTG
|
#define DIO39_WPORT PORTG
|
||||||
#define DIO39_DDR DDRG
|
#define DIO39_DDR DDRG
|
||||||
#define DIO39_PWM NULL
|
#define DIO39_PWM NULL
|
||||||
|
|
||||||
#define DIO40_PIN PING1
|
#define DIO40_PIN PING1
|
||||||
#define DIO40_RPORT PING
|
#define DIO40_RPORT PING
|
||||||
#define DIO40_WPORT PORTG
|
#define DIO40_WPORT PORTG
|
||||||
#define DIO40_DDR DDRG
|
#define DIO40_DDR DDRG
|
||||||
#define DIO40_PWM NULL
|
#define DIO40_PWM NULL
|
||||||
|
|
||||||
#define DIO41_PIN PING0
|
#define DIO41_PIN PING0
|
||||||
#define DIO41_RPORT PING
|
#define DIO41_RPORT PING
|
||||||
#define DIO41_WPORT PORTG
|
#define DIO41_WPORT PORTG
|
||||||
#define DIO41_DDR DDRG
|
#define DIO41_DDR DDRG
|
||||||
#define DIO41_PWM NULL
|
#define DIO41_PWM NULL
|
||||||
|
|
||||||
#define DIO42_PIN PINL7
|
#define DIO42_PIN PINL7
|
||||||
#define DIO42_RPORT PINL
|
#define DIO42_RPORT PINL
|
||||||
#define DIO42_WPORT PORTL
|
#define DIO42_WPORT PORTL
|
||||||
#define DIO42_DDR DDRL
|
#define DIO42_DDR DDRL
|
||||||
#define DIO42_PWM NULL
|
#define DIO42_PWM NULL
|
||||||
|
|
||||||
#define DIO43_PIN PINL6
|
#define DIO43_PIN PINL6
|
||||||
#define DIO43_RPORT PINL
|
#define DIO43_RPORT PINL
|
||||||
#define DIO43_WPORT PORTL
|
#define DIO43_WPORT PORTL
|
||||||
#define DIO43_DDR DDRL
|
#define DIO43_DDR DDRL
|
||||||
#define DIO43_PWM NULL
|
#define DIO43_PWM NULL
|
||||||
|
|
||||||
#define DIO44_PIN PINL5
|
#define DIO44_PIN PINL5
|
||||||
#define DIO44_RPORT PINL
|
#define DIO44_RPORT PINL
|
||||||
#define DIO44_WPORT PORTL
|
#define DIO44_WPORT PORTL
|
||||||
#define DIO44_DDR DDRL
|
#define DIO44_DDR DDRL
|
||||||
#define DIO44_PWM &OCR5CL
|
#define DIO44_PWM &OCR5CL
|
||||||
|
|
||||||
#define DIO45_PIN PINL4
|
#define DIO45_PIN PINL4
|
||||||
#define DIO45_RPORT PINL
|
#define DIO45_RPORT PINL
|
||||||
#define DIO45_WPORT PORTL
|
#define DIO45_WPORT PORTL
|
||||||
#define DIO45_DDR DDRL
|
#define DIO45_DDR DDRL
|
||||||
#define DIO45_PWM &OCR5BL
|
#define DIO45_PWM &OCR5BL
|
||||||
|
|
||||||
#define DIO46_PIN PINL3
|
#define DIO46_PIN PINL3
|
||||||
#define DIO46_RPORT PINL
|
#define DIO46_RPORT PINL
|
||||||
#define DIO46_WPORT PORTL
|
#define DIO46_WPORT PORTL
|
||||||
#define DIO46_DDR DDRL
|
#define DIO46_DDR DDRL
|
||||||
#define DIO46_PWM &OCR5AL
|
#define DIO46_PWM &OCR5AL
|
||||||
|
|
||||||
#define DIO47_PIN PINL2
|
#define DIO47_PIN PINL2
|
||||||
#define DIO47_RPORT PINL
|
#define DIO47_RPORT PINL
|
||||||
#define DIO47_WPORT PORTL
|
#define DIO47_WPORT PORTL
|
||||||
#define DIO47_DDR DDRL
|
#define DIO47_DDR DDRL
|
||||||
#define DIO47_PWM NULL
|
#define DIO47_PWM NULL
|
||||||
|
|
||||||
#define DIO48_PIN PINL1
|
#define DIO48_PIN PINL1
|
||||||
#define DIO48_RPORT PINL
|
#define DIO48_RPORT PINL
|
||||||
#define DIO48_WPORT PORTL
|
#define DIO48_WPORT PORTL
|
||||||
#define DIO48_DDR DDRL
|
#define DIO48_DDR DDRL
|
||||||
#define DIO48_PWM NULL
|
#define DIO48_PWM NULL
|
||||||
|
|
||||||
#define DIO49_PIN PINL0
|
#define DIO49_PIN PINL0
|
||||||
#define DIO49_RPORT PINL
|
#define DIO49_RPORT PINL
|
||||||
#define DIO49_WPORT PORTL
|
#define DIO49_WPORT PORTL
|
||||||
#define DIO49_DDR DDRL
|
#define DIO49_DDR DDRL
|
||||||
#define DIO49_PWM NULL
|
#define DIO49_PWM NULL
|
||||||
|
|
||||||
#define DIO50_PIN PINB3
|
#define DIO50_PIN PINB3
|
||||||
#define DIO50_RPORT PINB
|
#define DIO50_RPORT PINB
|
||||||
#define DIO50_WPORT PORTB
|
#define DIO50_WPORT PORTB
|
||||||
#define DIO50_DDR DDRB
|
#define DIO50_DDR DDRB
|
||||||
#define DIO50_PWM NULL
|
#define DIO50_PWM NULL
|
||||||
|
|
||||||
#define DIO51_PIN PINB2
|
#define DIO51_PIN PINB2
|
||||||
#define DIO51_RPORT PINB
|
#define DIO51_RPORT PINB
|
||||||
#define DIO51_WPORT PORTB
|
#define DIO51_WPORT PORTB
|
||||||
#define DIO51_DDR DDRB
|
#define DIO51_DDR DDRB
|
||||||
#define DIO51_PWM NULL
|
#define DIO51_PWM NULL
|
||||||
|
|
||||||
#define DIO52_PIN PINB1
|
#define DIO52_PIN PINB1
|
||||||
#define DIO52_RPORT PINB
|
#define DIO52_RPORT PINB
|
||||||
#define DIO52_WPORT PORTB
|
#define DIO52_WPORT PORTB
|
||||||
#define DIO52_DDR DDRB
|
#define DIO52_DDR DDRB
|
||||||
#define DIO52_PWM NULL
|
#define DIO52_PWM NULL
|
||||||
|
|
||||||
#define DIO53_PIN PINB0
|
#define DIO53_PIN PINB0
|
||||||
#define DIO53_RPORT PINB
|
#define DIO53_RPORT PINB
|
||||||
#define DIO53_WPORT PORTB
|
#define DIO53_WPORT PORTB
|
||||||
#define DIO53_DDR DDRB
|
#define DIO53_DDR DDRB
|
||||||
#define DIO53_PWM NULL
|
#define DIO53_PWM NULL
|
||||||
|
|
||||||
#define DIO54_PIN PINF0
|
#define DIO54_PIN PINF0
|
||||||
#define DIO54_RPORT PINF
|
#define DIO54_RPORT PINF
|
||||||
#define DIO54_WPORT PORTF
|
#define DIO54_WPORT PORTF
|
||||||
#define DIO54_DDR DDRF
|
#define DIO54_DDR DDRF
|
||||||
#define DIO54_PWM NULL
|
#define DIO54_PWM NULL
|
||||||
|
|
||||||
#define DIO55_PIN PINF1
|
#define DIO55_PIN PINF1
|
||||||
#define DIO55_RPORT PINF
|
#define DIO55_RPORT PINF
|
||||||
#define DIO55_WPORT PORTF
|
#define DIO55_WPORT PORTF
|
||||||
#define DIO55_DDR DDRF
|
#define DIO55_DDR DDRF
|
||||||
#define DIO55_PWM NULL
|
#define DIO55_PWM NULL
|
||||||
|
|
||||||
#define DIO56_PIN PINF2
|
#define DIO56_PIN PINF2
|
||||||
#define DIO56_RPORT PINF
|
#define DIO56_RPORT PINF
|
||||||
#define DIO56_WPORT PORTF
|
#define DIO56_WPORT PORTF
|
||||||
#define DIO56_DDR DDRF
|
#define DIO56_DDR DDRF
|
||||||
#define DIO56_PWM NULL
|
#define DIO56_PWM NULL
|
||||||
|
|
||||||
#define DIO57_PIN PINF3
|
#define DIO57_PIN PINF3
|
||||||
#define DIO57_RPORT PINF
|
#define DIO57_RPORT PINF
|
||||||
#define DIO57_WPORT PORTF
|
#define DIO57_WPORT PORTF
|
||||||
#define DIO57_DDR DDRF
|
#define DIO57_DDR DDRF
|
||||||
#define DIO57_PWM NULL
|
#define DIO57_PWM NULL
|
||||||
|
|
||||||
#define DIO58_PIN PINF4
|
#define DIO58_PIN PINF4
|
||||||
#define DIO58_RPORT PINF
|
#define DIO58_RPORT PINF
|
||||||
#define DIO58_WPORT PORTF
|
#define DIO58_WPORT PORTF
|
||||||
#define DIO58_DDR DDRF
|
#define DIO58_DDR DDRF
|
||||||
#define DIO58_PWM NULL
|
#define DIO58_PWM NULL
|
||||||
|
|
||||||
#define DIO59_PIN PINF5
|
#define DIO59_PIN PINF5
|
||||||
#define DIO59_RPORT PINF
|
#define DIO59_RPORT PINF
|
||||||
#define DIO59_WPORT PORTF
|
#define DIO59_WPORT PORTF
|
||||||
#define DIO59_DDR DDRF
|
#define DIO59_DDR DDRF
|
||||||
#define DIO59_PWM NULL
|
#define DIO59_PWM NULL
|
||||||
|
|
||||||
#define DIO60_PIN PINF6
|
#define DIO60_PIN PINF6
|
||||||
#define DIO60_RPORT PINF
|
#define DIO60_RPORT PINF
|
||||||
#define DIO60_WPORT PORTF
|
#define DIO60_WPORT PORTF
|
||||||
#define DIO60_DDR DDRF
|
#define DIO60_DDR DDRF
|
||||||
#define DIO60_PWM NULL
|
#define DIO60_PWM NULL
|
||||||
|
|
||||||
#define DIO61_PIN PINF7
|
#define DIO61_PIN PINF7
|
||||||
#define DIO61_RPORT PINF
|
#define DIO61_RPORT PINF
|
||||||
#define DIO61_WPORT PORTF
|
#define DIO61_WPORT PORTF
|
||||||
#define DIO61_DDR DDRF
|
#define DIO61_DDR DDRF
|
||||||
#define DIO61_PWM NULL
|
#define DIO61_PWM NULL
|
||||||
|
|
||||||
#define DIO62_PIN PINK0
|
#define DIO62_PIN PINK0
|
||||||
#define DIO62_RPORT PINK
|
#define DIO62_RPORT PINK
|
||||||
#define DIO62_WPORT PORTK
|
#define DIO62_WPORT PORTK
|
||||||
#define DIO62_DDR DDRK
|
#define DIO62_DDR DDRK
|
||||||
#define DIO62_PWM NULL
|
#define DIO62_PWM NULL
|
||||||
|
|
||||||
#define DIO63_PIN PINK1
|
#define DIO63_PIN PINK1
|
||||||
#define DIO63_RPORT PINK
|
#define DIO63_RPORT PINK
|
||||||
#define DIO63_WPORT PORTK
|
#define DIO63_WPORT PORTK
|
||||||
#define DIO63_DDR DDRK
|
#define DIO63_DDR DDRK
|
||||||
#define DIO63_PWM NULL
|
#define DIO63_PWM NULL
|
||||||
|
|
||||||
#define DIO64_PIN PINK2
|
#define DIO64_PIN PINK2
|
||||||
#define DIO64_RPORT PINK
|
#define DIO64_RPORT PINK
|
||||||
#define DIO64_WPORT PORTK
|
#define DIO64_WPORT PORTK
|
||||||
#define DIO64_DDR DDRK
|
#define DIO64_DDR DDRK
|
||||||
#define DIO64_PWM NULL
|
#define DIO64_PWM NULL
|
||||||
|
|
||||||
#define DIO65_PIN PINK3
|
#define DIO65_PIN PINK3
|
||||||
#define DIO65_RPORT PINK
|
#define DIO65_RPORT PINK
|
||||||
#define DIO65_WPORT PORTK
|
#define DIO65_WPORT PORTK
|
||||||
#define DIO65_DDR DDRK
|
#define DIO65_DDR DDRK
|
||||||
#define DIO65_PWM NULL
|
#define DIO65_PWM NULL
|
||||||
|
|
||||||
#define DIO66_PIN PINK4
|
#define DIO66_PIN PINK4
|
||||||
#define DIO66_RPORT PINK
|
#define DIO66_RPORT PINK
|
||||||
#define DIO66_WPORT PORTK
|
#define DIO66_WPORT PORTK
|
||||||
#define DIO66_DDR DDRK
|
#define DIO66_DDR DDRK
|
||||||
#define DIO66_PWM NULL
|
#define DIO66_PWM NULL
|
||||||
|
|
||||||
#define DIO67_PIN PINK5
|
#define DIO67_PIN PINK5
|
||||||
#define DIO67_RPORT PINK
|
#define DIO67_RPORT PINK
|
||||||
#define DIO67_WPORT PORTK
|
#define DIO67_WPORT PORTK
|
||||||
#define DIO67_DDR DDRK
|
#define DIO67_DDR DDRK
|
||||||
#define DIO67_PWM NULL
|
#define DIO67_PWM NULL
|
||||||
|
|
||||||
#define DIO68_PIN PINK6
|
#define DIO68_PIN PINK6
|
||||||
#define DIO68_RPORT PINK
|
#define DIO68_RPORT PINK
|
||||||
#define DIO68_WPORT PORTK
|
#define DIO68_WPORT PORTK
|
||||||
#define DIO68_DDR DDRK
|
#define DIO68_DDR DDRK
|
||||||
#define DIO68_PWM NULL
|
#define DIO68_PWM NULL
|
||||||
|
|
||||||
#define DIO69_PIN PINK7
|
#define DIO69_PIN PINK7
|
||||||
#define DIO69_RPORT PINK
|
#define DIO69_RPORT PINK
|
||||||
#define DIO69_WPORT PORTK
|
#define DIO69_WPORT PORTK
|
||||||
#define DIO69_DDR DDRK
|
#define DIO69_DDR DDRK
|
||||||
#define DIO69_PWM NULL
|
#define DIO69_PWM NULL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#undef PA0
|
#undef PA0
|
||||||
#define PA0_PIN PINA0
|
#define PA0_PIN PINA0
|
||||||
#define PA0_RPORT PINA
|
#define PA0_RPORT PINA
|
||||||
#define PA0_WPORT PORTA
|
#define PA0_WPORT PORTA
|
||||||
#define PA0_DDR DDRA
|
#define PA0_DDR DDRA
|
||||||
#define PA0_PWM NULL
|
#define PA0_PWM NULL
|
||||||
#undef PA1
|
#undef PA1
|
||||||
#define PA1_PIN PINA1
|
#define PA1_PIN PINA1
|
||||||
#define PA1_RPORT PINA
|
#define PA1_RPORT PINA
|
||||||
#define PA1_WPORT PORTA
|
#define PA1_WPORT PORTA
|
||||||
#define PA1_DDR DDRA
|
#define PA1_DDR DDRA
|
||||||
#define PA1_PWM NULL
|
#define PA1_PWM NULL
|
||||||
#undef PA2
|
#undef PA2
|
||||||
#define PA2_PIN PINA2
|
#define PA2_PIN PINA2
|
||||||
#define PA2_RPORT PINA
|
#define PA2_RPORT PINA
|
||||||
#define PA2_WPORT PORTA
|
#define PA2_WPORT PORTA
|
||||||
#define PA2_DDR DDRA
|
#define PA2_DDR DDRA
|
||||||
#define PA2_PWM NULL
|
#define PA2_PWM NULL
|
||||||
#undef PA3
|
#undef PA3
|
||||||
#define PA3_PIN PINA3
|
#define PA3_PIN PINA3
|
||||||
#define PA3_RPORT PINA
|
#define PA3_RPORT PINA
|
||||||
#define PA3_WPORT PORTA
|
#define PA3_WPORT PORTA
|
||||||
#define PA3_DDR DDRA
|
#define PA3_DDR DDRA
|
||||||
#define PA3_PWM NULL
|
#define PA3_PWM NULL
|
||||||
#undef PA4
|
#undef PA4
|
||||||
#define PA4_PIN PINA4
|
#define PA4_PIN PINA4
|
||||||
#define PA4_RPORT PINA
|
#define PA4_RPORT PINA
|
||||||
#define PA4_WPORT PORTA
|
#define PA4_WPORT PORTA
|
||||||
#define PA4_DDR DDRA
|
#define PA4_DDR DDRA
|
||||||
#define PA4_PWM NULL
|
#define PA4_PWM NULL
|
||||||
#undef PA5
|
#undef PA5
|
||||||
#define PA5_PIN PINA5
|
#define PA5_PIN PINA5
|
||||||
#define PA5_RPORT PINA
|
#define PA5_RPORT PINA
|
||||||
#define PA5_WPORT PORTA
|
#define PA5_WPORT PORTA
|
||||||
#define PA5_DDR DDRA
|
#define PA5_DDR DDRA
|
||||||
#define PA5_PWM NULL
|
#define PA5_PWM NULL
|
||||||
#undef PA6
|
#undef PA6
|
||||||
#define PA6_PIN PINA6
|
#define PA6_PIN PINA6
|
||||||
#define PA6_RPORT PINA
|
#define PA6_RPORT PINA
|
||||||
#define PA6_WPORT PORTA
|
#define PA6_WPORT PORTA
|
||||||
#define PA6_DDR DDRA
|
#define PA6_DDR DDRA
|
||||||
#define PA6_PWM NULL
|
#define PA6_PWM NULL
|
||||||
#undef PA7
|
#undef PA7
|
||||||
#define PA7_PIN PINA7
|
#define PA7_PIN PINA7
|
||||||
#define PA7_RPORT PINA
|
#define PA7_RPORT PINA
|
||||||
#define PA7_WPORT PORTA
|
#define PA7_WPORT PORTA
|
||||||
#define PA7_DDR DDRA
|
#define PA7_DDR DDRA
|
||||||
#define PA7_PWM NULL
|
#define PA7_PWM NULL
|
||||||
|
|
||||||
#undef PB0
|
#undef PB0
|
||||||
#define PB0_PIN PINB0
|
#define PB0_PIN PINB0
|
||||||
#define PB0_RPORT PINB
|
#define PB0_RPORT PINB
|
||||||
#define PB0_WPORT PORTB
|
#define PB0_WPORT PORTB
|
||||||
#define PB0_DDR DDRB
|
#define PB0_DDR DDRB
|
||||||
#define PB0_PWM NULL
|
#define PB0_PWM NULL
|
||||||
#undef PB1
|
#undef PB1
|
||||||
#define PB1_PIN PINB1
|
#define PB1_PIN PINB1
|
||||||
#define PB1_RPORT PINB
|
#define PB1_RPORT PINB
|
||||||
#define PB1_WPORT PORTB
|
#define PB1_WPORT PORTB
|
||||||
#define PB1_DDR DDRB
|
#define PB1_DDR DDRB
|
||||||
#define PB1_PWM NULL
|
#define PB1_PWM NULL
|
||||||
#undef PB2
|
#undef PB2
|
||||||
#define PB2_PIN PINB2
|
#define PB2_PIN PINB2
|
||||||
#define PB2_RPORT PINB
|
#define PB2_RPORT PINB
|
||||||
#define PB2_WPORT PORTB
|
#define PB2_WPORT PORTB
|
||||||
#define PB2_DDR DDRB
|
#define PB2_DDR DDRB
|
||||||
#define PB2_PWM NULL
|
#define PB2_PWM NULL
|
||||||
#undef PB3
|
#undef PB3
|
||||||
#define PB3_PIN PINB3
|
#define PB3_PIN PINB3
|
||||||
#define PB3_RPORT PINB
|
#define PB3_RPORT PINB
|
||||||
#define PB3_WPORT PORTB
|
#define PB3_WPORT PORTB
|
||||||
#define PB3_DDR DDRB
|
#define PB3_DDR DDRB
|
||||||
#define PB3_PWM NULL
|
#define PB3_PWM NULL
|
||||||
#undef PB4
|
#undef PB4
|
||||||
#define PB4_PIN PINB4
|
#define PB4_PIN PINB4
|
||||||
#define PB4_RPORT PINB
|
#define PB4_RPORT PINB
|
||||||
#define PB4_WPORT PORTB
|
#define PB4_WPORT PORTB
|
||||||
#define PB4_DDR DDRB
|
#define PB4_DDR DDRB
|
||||||
#define PB4_PWM &OCR2A
|
#define PB4_PWM &OCR2A
|
||||||
#undef PB5
|
#undef PB5
|
||||||
#define PB5_PIN PINB5
|
#define PB5_PIN PINB5
|
||||||
#define PB5_RPORT PINB
|
#define PB5_RPORT PINB
|
||||||
#define PB5_WPORT PORTB
|
#define PB5_WPORT PORTB
|
||||||
#define PB5_DDR DDRB
|
#define PB5_DDR DDRB
|
||||||
#define PB5_PWM NULL
|
#define PB5_PWM NULL
|
||||||
#undef PB6
|
#undef PB6
|
||||||
#define PB6_PIN PINB6
|
#define PB6_PIN PINB6
|
||||||
#define PB6_RPORT PINB
|
#define PB6_RPORT PINB
|
||||||
#define PB6_WPORT PORTB
|
#define PB6_WPORT PORTB
|
||||||
#define PB6_DDR DDRB
|
#define PB6_DDR DDRB
|
||||||
#define PB6_PWM NULL
|
#define PB6_PWM NULL
|
||||||
#undef PB7
|
#undef PB7
|
||||||
#define PB7_PIN PINB7
|
#define PB7_PIN PINB7
|
||||||
#define PB7_RPORT PINB
|
#define PB7_RPORT PINB
|
||||||
#define PB7_WPORT PORTB
|
#define PB7_WPORT PORTB
|
||||||
#define PB7_DDR DDRB
|
#define PB7_DDR DDRB
|
||||||
#define PB7_PWM &OCR0A
|
#define PB7_PWM &OCR0A
|
||||||
|
|
||||||
#undef PC0
|
#undef PC0
|
||||||
#define PC0_PIN PINC0
|
#define PC0_PIN PINC0
|
||||||
#define PC0_RPORT PINC
|
#define PC0_RPORT PINC
|
||||||
#define PC0_WPORT PORTC
|
#define PC0_WPORT PORTC
|
||||||
#define PC0_DDR DDRC
|
#define PC0_DDR DDRC
|
||||||
#define PC0_PWM NULL
|
#define PC0_PWM NULL
|
||||||
#undef PC1
|
#undef PC1
|
||||||
#define PC1_PIN PINC1
|
#define PC1_PIN PINC1
|
||||||
#define PC1_RPORT PINC
|
#define PC1_RPORT PINC
|
||||||
#define PC1_WPORT PORTC
|
#define PC1_WPORT PORTC
|
||||||
#define PC1_DDR DDRC
|
#define PC1_DDR DDRC
|
||||||
#define PC1_PWM NULL
|
#define PC1_PWM NULL
|
||||||
#undef PC2
|
#undef PC2
|
||||||
#define PC2_PIN PINC2
|
#define PC2_PIN PINC2
|
||||||
#define PC2_RPORT PINC
|
#define PC2_RPORT PINC
|
||||||
#define PC2_WPORT PORTC
|
#define PC2_WPORT PORTC
|
||||||
#define PC2_DDR DDRC
|
#define PC2_DDR DDRC
|
||||||
#define PC2_PWM NULL
|
#define PC2_PWM NULL
|
||||||
#undef PC3
|
#undef PC3
|
||||||
#define PC3_PIN PINC3
|
#define PC3_PIN PINC3
|
||||||
#define PC3_RPORT PINC
|
#define PC3_RPORT PINC
|
||||||
#define PC3_WPORT PORTC
|
#define PC3_WPORT PORTC
|
||||||
#define PC3_DDR DDRC
|
#define PC3_DDR DDRC
|
||||||
#define PC3_PWM NULL
|
#define PC3_PWM NULL
|
||||||
#undef PC4
|
#undef PC4
|
||||||
#define PC4_PIN PINC4
|
#define PC4_PIN PINC4
|
||||||
#define PC4_RPORT PINC
|
#define PC4_RPORT PINC
|
||||||
#define PC4_WPORT PORTC
|
#define PC4_WPORT PORTC
|
||||||
#define PC4_DDR DDRC
|
#define PC4_DDR DDRC
|
||||||
#define PC4_PWM NULL
|
#define PC4_PWM NULL
|
||||||
#undef PC5
|
#undef PC5
|
||||||
#define PC5_PIN PINC5
|
#define PC5_PIN PINC5
|
||||||
#define PC5_RPORT PINC
|
#define PC5_RPORT PINC
|
||||||
#define PC5_WPORT PORTC
|
#define PC5_WPORT PORTC
|
||||||
#define PC5_DDR DDRC
|
#define PC5_DDR DDRC
|
||||||
#define PC5_PWM NULL
|
#define PC5_PWM NULL
|
||||||
#undef PC6
|
#undef PC6
|
||||||
#define PC6_PIN PINC6
|
#define PC6_PIN PINC6
|
||||||
#define PC6_RPORT PINC
|
#define PC6_RPORT PINC
|
||||||
#define PC6_WPORT PORTC
|
#define PC6_WPORT PORTC
|
||||||
#define PC6_DDR DDRC
|
#define PC6_DDR DDRC
|
||||||
#define PC6_PWM NULL
|
#define PC6_PWM NULL
|
||||||
#undef PC7
|
#undef PC7
|
||||||
#define PC7_PIN PINC7
|
#define PC7_PIN PINC7
|
||||||
#define PC7_RPORT PINC
|
#define PC7_RPORT PINC
|
||||||
#define PC7_WPORT PORTC
|
#define PC7_WPORT PORTC
|
||||||
#define PC7_DDR DDRC
|
#define PC7_DDR DDRC
|
||||||
#define PC7_PWM NULL
|
#define PC7_PWM NULL
|
||||||
|
|
||||||
#undef PD0
|
#undef PD0
|
||||||
#define PD0_PIN PIND0
|
#define PD0_PIN PIND0
|
||||||
#define PD0_RPORT PIND
|
#define PD0_RPORT PIND
|
||||||
#define PD0_WPORT PORTD
|
#define PD0_WPORT PORTD
|
||||||
#define PD0_DDR DDRD
|
#define PD0_DDR DDRD
|
||||||
#define PD0_PWM NULL
|
#define PD0_PWM NULL
|
||||||
#undef PD1
|
#undef PD1
|
||||||
#define PD1_PIN PIND1
|
#define PD1_PIN PIND1
|
||||||
#define PD1_RPORT PIND
|
#define PD1_RPORT PIND
|
||||||
#define PD1_WPORT PORTD
|
#define PD1_WPORT PORTD
|
||||||
#define PD1_DDR DDRD
|
#define PD1_DDR DDRD
|
||||||
#define PD1_PWM NULL
|
#define PD1_PWM NULL
|
||||||
#undef PD2
|
#undef PD2
|
||||||
#define PD2_PIN PIND2
|
#define PD2_PIN PIND2
|
||||||
#define PD2_RPORT PIND
|
#define PD2_RPORT PIND
|
||||||
#define PD2_WPORT PORTD
|
#define PD2_WPORT PORTD
|
||||||
#define PD2_DDR DDRD
|
#define PD2_DDR DDRD
|
||||||
#define PD2_PWM NULL
|
#define PD2_PWM NULL
|
||||||
#undef PD3
|
#undef PD3
|
||||||
#define PD3_PIN PIND3
|
#define PD3_PIN PIND3
|
||||||
#define PD3_RPORT PIND
|
#define PD3_RPORT PIND
|
||||||
#define PD3_WPORT PORTD
|
#define PD3_WPORT PORTD
|
||||||
#define PD3_DDR DDRD
|
#define PD3_DDR DDRD
|
||||||
#define PD3_PWM NULL
|
#define PD3_PWM NULL
|
||||||
#undef PD4
|
#undef PD4
|
||||||
#define PD4_PIN PIND4
|
#define PD4_PIN PIND4
|
||||||
#define PD4_RPORT PIND
|
#define PD4_RPORT PIND
|
||||||
#define PD4_WPORT PORTD
|
#define PD4_WPORT PORTD
|
||||||
#define PD4_DDR DDRD
|
#define PD4_DDR DDRD
|
||||||
#define PD4_PWM NULL
|
#define PD4_PWM NULL
|
||||||
#undef PD5
|
#undef PD5
|
||||||
#define PD5_PIN PIND5
|
#define PD5_PIN PIND5
|
||||||
#define PD5_RPORT PIND
|
#define PD5_RPORT PIND
|
||||||
#define PD5_WPORT PORTD
|
#define PD5_WPORT PORTD
|
||||||
#define PD5_DDR DDRD
|
#define PD5_DDR DDRD
|
||||||
#define PD5_PWM NULL
|
#define PD5_PWM NULL
|
||||||
#undef PD6
|
#undef PD6
|
||||||
#define PD6_PIN PIND6
|
#define PD6_PIN PIND6
|
||||||
#define PD6_RPORT PIND
|
#define PD6_RPORT PIND
|
||||||
#define PD6_WPORT PORTD
|
#define PD6_WPORT PORTD
|
||||||
#define PD6_DDR DDRD
|
#define PD6_DDR DDRD
|
||||||
#define PD6_PWM NULL
|
#define PD6_PWM NULL
|
||||||
#undef PD7
|
#undef PD7
|
||||||
#define PD7_PIN PIND7
|
#define PD7_PIN PIND7
|
||||||
#define PD7_RPORT PIND
|
#define PD7_RPORT PIND
|
||||||
#define PD7_WPORT PORTD
|
#define PD7_WPORT PORTD
|
||||||
#define PD7_DDR DDRD
|
#define PD7_DDR DDRD
|
||||||
#define PD7_PWM NULL
|
#define PD7_PWM NULL
|
||||||
|
|
||||||
#undef PE0
|
#undef PE0
|
||||||
#define PE0_PIN PINE0
|
#define PE0_PIN PINE0
|
||||||
#define PE0_RPORT PINE
|
#define PE0_RPORT PINE
|
||||||
#define PE0_WPORT PORTE
|
#define PE0_WPORT PORTE
|
||||||
#define PE0_DDR DDRE
|
#define PE0_DDR DDRE
|
||||||
#define PE0_PWM NULL
|
#define PE0_PWM NULL
|
||||||
#undef PE1
|
#undef PE1
|
||||||
#define PE1_PIN PINE1
|
#define PE1_PIN PINE1
|
||||||
#define PE1_RPORT PINE
|
#define PE1_RPORT PINE
|
||||||
#define PE1_WPORT PORTE
|
#define PE1_WPORT PORTE
|
||||||
#define PE1_DDR DDRE
|
#define PE1_DDR DDRE
|
||||||
#define PE1_PWM NULL
|
#define PE1_PWM NULL
|
||||||
#undef PE2
|
#undef PE2
|
||||||
#define PE2_PIN PINE2
|
#define PE2_PIN PINE2
|
||||||
#define PE2_RPORT PINE
|
#define PE2_RPORT PINE
|
||||||
#define PE2_WPORT PORTE
|
#define PE2_WPORT PORTE
|
||||||
#define PE2_DDR DDRE
|
#define PE2_DDR DDRE
|
||||||
#define PE2_PWM NULL
|
#define PE2_PWM NULL
|
||||||
#undef PE3
|
#undef PE3
|
||||||
#define PE3_PIN PINE3
|
#define PE3_PIN PINE3
|
||||||
#define PE3_RPORT PINE
|
#define PE3_RPORT PINE
|
||||||
#define PE3_WPORT PORTE
|
#define PE3_WPORT PORTE
|
||||||
#define PE3_DDR DDRE
|
#define PE3_DDR DDRE
|
||||||
#define PE3_PWM &OCR3AL
|
#define PE3_PWM &OCR3AL
|
||||||
#undef PE4
|
#undef PE4
|
||||||
#define PE4_PIN PINE4
|
#define PE4_PIN PINE4
|
||||||
#define PE4_RPORT PINE
|
#define PE4_RPORT PINE
|
||||||
#define PE4_WPORT PORTE
|
#define PE4_WPORT PORTE
|
||||||
#define PE4_DDR DDRE
|
#define PE4_DDR DDRE
|
||||||
#define PE4_PWM &OCR3BL
|
#define PE4_PWM &OCR3BL
|
||||||
#undef PE5
|
#undef PE5
|
||||||
#define PE5_PIN PINE5
|
#define PE5_PIN PINE5
|
||||||
#define PE5_RPORT PINE
|
#define PE5_RPORT PINE
|
||||||
#define PE5_WPORT PORTE
|
#define PE5_WPORT PORTE
|
||||||
#define PE5_DDR DDRE
|
#define PE5_DDR DDRE
|
||||||
#define PE5_PWM &OCR3CL
|
#define PE5_PWM &OCR3CL
|
||||||
#undef PE6
|
#undef PE6
|
||||||
#define PE6_PIN PINE6
|
#define PE6_PIN PINE6
|
||||||
#define PE6_RPORT PINE
|
#define PE6_RPORT PINE
|
||||||
#define PE6_WPORT PORTE
|
#define PE6_WPORT PORTE
|
||||||
#define PE6_DDR DDRE
|
#define PE6_DDR DDRE
|
||||||
#define PE6_PWM NULL
|
#define PE6_PWM NULL
|
||||||
#undef PE7
|
#undef PE7
|
||||||
#define PE7_PIN PINE7
|
#define PE7_PIN PINE7
|
||||||
#define PE7_RPORT PINE
|
#define PE7_RPORT PINE
|
||||||
#define PE7_WPORT PORTE
|
#define PE7_WPORT PORTE
|
||||||
#define PE7_DDR DDRE
|
#define PE7_DDR DDRE
|
||||||
#define PE7_PWM NULL
|
#define PE7_PWM NULL
|
||||||
|
|
||||||
#undef PF0
|
#undef PF0
|
||||||
#define PF0_PIN PINF0
|
#define PF0_PIN PINF0
|
||||||
#define PF0_RPORT PINF
|
#define PF0_RPORT PINF
|
||||||
#define PF0_WPORT PORTF
|
#define PF0_WPORT PORTF
|
||||||
#define PF0_DDR DDRF
|
#define PF0_DDR DDRF
|
||||||
#define PF0_PWM NULL
|
#define PF0_PWM NULL
|
||||||
#undef PF1
|
#undef PF1
|
||||||
#define PF1_PIN PINF1
|
#define PF1_PIN PINF1
|
||||||
#define PF1_RPORT PINF
|
#define PF1_RPORT PINF
|
||||||
#define PF1_WPORT PORTF
|
#define PF1_WPORT PORTF
|
||||||
#define PF1_DDR DDRF
|
#define PF1_DDR DDRF
|
||||||
#define PF1_PWM NULL
|
#define PF1_PWM NULL
|
||||||
#undef PF2
|
#undef PF2
|
||||||
#define PF2_PIN PINF2
|
#define PF2_PIN PINF2
|
||||||
#define PF2_RPORT PINF
|
#define PF2_RPORT PINF
|
||||||
#define PF2_WPORT PORTF
|
#define PF2_WPORT PORTF
|
||||||
#define PF2_DDR DDRF
|
#define PF2_DDR DDRF
|
||||||
#define PF2_PWM NULL
|
#define PF2_PWM NULL
|
||||||
#undef PF3
|
#undef PF3
|
||||||
#define PF3_PIN PINF3
|
#define PF3_PIN PINF3
|
||||||
#define PF3_RPORT PINF
|
#define PF3_RPORT PINF
|
||||||
#define PF3_WPORT PORTF
|
#define PF3_WPORT PORTF
|
||||||
#define PF3_DDR DDRF
|
#define PF3_DDR DDRF
|
||||||
#define PF3_PWM NULL
|
#define PF3_PWM NULL
|
||||||
#undef PF4
|
#undef PF4
|
||||||
#define PF4_PIN PINF4
|
#define PF4_PIN PINF4
|
||||||
#define PF4_RPORT PINF
|
#define PF4_RPORT PINF
|
||||||
#define PF4_WPORT PORTF
|
#define PF4_WPORT PORTF
|
||||||
#define PF4_DDR DDRF
|
#define PF4_DDR DDRF
|
||||||
#define PF4_PWM NULL
|
#define PF4_PWM NULL
|
||||||
#undef PF5
|
#undef PF5
|
||||||
#define PF5_PIN PINF5
|
#define PF5_PIN PINF5
|
||||||
#define PF5_RPORT PINF
|
#define PF5_RPORT PINF
|
||||||
#define PF5_WPORT PORTF
|
#define PF5_WPORT PORTF
|
||||||
#define PF5_DDR DDRF
|
#define PF5_DDR DDRF
|
||||||
#define PF5_PWM NULL
|
#define PF5_PWM NULL
|
||||||
#undef PF6
|
#undef PF6
|
||||||
#define PF6_PIN PINF6
|
#define PF6_PIN PINF6
|
||||||
#define PF6_RPORT PINF
|
#define PF6_RPORT PINF
|
||||||
#define PF6_WPORT PORTF
|
#define PF6_WPORT PORTF
|
||||||
#define PF6_DDR DDRF
|
#define PF6_DDR DDRF
|
||||||
#define PF6_PWM NULL
|
#define PF6_PWM NULL
|
||||||
#undef PF7
|
#undef PF7
|
||||||
#define PF7_PIN PINF7
|
#define PF7_PIN PINF7
|
||||||
#define PF7_RPORT PINF
|
#define PF7_RPORT PINF
|
||||||
#define PF7_WPORT PORTF
|
#define PF7_WPORT PORTF
|
||||||
#define PF7_DDR DDRF
|
#define PF7_DDR DDRF
|
||||||
#define PF7_PWM NULL
|
#define PF7_PWM NULL
|
||||||
|
|
||||||
#undef PG0
|
#undef PG0
|
||||||
#define PG0_PIN PING0
|
#define PG0_PIN PING0
|
||||||
#define PG0_RPORT PING
|
#define PG0_RPORT PING
|
||||||
#define PG0_WPORT PORTG
|
#define PG0_WPORT PORTG
|
||||||
#define PG0_DDR DDRG
|
#define PG0_DDR DDRG
|
||||||
#define PG0_PWM NULL
|
#define PG0_PWM NULL
|
||||||
#undef PG1
|
#undef PG1
|
||||||
#define PG1_PIN PING1
|
#define PG1_PIN PING1
|
||||||
#define PG1_RPORT PING
|
#define PG1_RPORT PING
|
||||||
#define PG1_WPORT PORTG
|
#define PG1_WPORT PORTG
|
||||||
#define PG1_DDR DDRG
|
#define PG1_DDR DDRG
|
||||||
#define PG1_PWM NULL
|
#define PG1_PWM NULL
|
||||||
#undef PG2
|
#undef PG2
|
||||||
#define PG2_PIN PING2
|
#define PG2_PIN PING2
|
||||||
#define PG2_RPORT PING
|
#define PG2_RPORT PING
|
||||||
#define PG2_WPORT PORTG
|
#define PG2_WPORT PORTG
|
||||||
#define PG2_DDR DDRG
|
#define PG2_DDR DDRG
|
||||||
#define PG2_PWM NULL
|
#define PG2_PWM NULL
|
||||||
#undef PG3
|
#undef PG3
|
||||||
#define PG3_PIN PING3
|
#define PG3_PIN PING3
|
||||||
#define PG3_RPORT PING
|
#define PG3_RPORT PING
|
||||||
#define PG3_WPORT PORTG
|
#define PG3_WPORT PORTG
|
||||||
#define PG3_DDR DDRG
|
#define PG3_DDR DDRG
|
||||||
#define PG3_PWM NULL
|
#define PG3_PWM NULL
|
||||||
#undef PG4
|
#undef PG4
|
||||||
#define PG4_PIN PING4
|
#define PG4_PIN PING4
|
||||||
#define PG4_RPORT PING
|
#define PG4_RPORT PING
|
||||||
#define PG4_WPORT PORTG
|
#define PG4_WPORT PORTG
|
||||||
#define PG4_DDR DDRG
|
#define PG4_DDR DDRG
|
||||||
#define PG4_PWM NULL
|
#define PG4_PWM NULL
|
||||||
#undef PG5
|
#undef PG5
|
||||||
#define PG5_PIN PING5
|
#define PG5_PIN PING5
|
||||||
#define PG5_RPORT PING
|
#define PG5_RPORT PING
|
||||||
#define PG5_WPORT PORTG
|
#define PG5_WPORT PORTG
|
||||||
#define PG5_DDR DDRG
|
#define PG5_DDR DDRG
|
||||||
#define PG5_PWM &OCR0B
|
#define PG5_PWM &OCR0B
|
||||||
#undef PG6
|
#undef PG6
|
||||||
#define PG6_PIN PING6
|
#define PG6_PIN PING6
|
||||||
#define PG6_RPORT PING
|
#define PG6_RPORT PING
|
||||||
#define PG6_WPORT PORTG
|
#define PG6_WPORT PORTG
|
||||||
#define PG6_DDR DDRG
|
#define PG6_DDR DDRG
|
||||||
#define PG6_PWM NULL
|
#define PG6_PWM NULL
|
||||||
#undef PG7
|
#undef PG7
|
||||||
#define PG7_PIN PING7
|
#define PG7_PIN PING7
|
||||||
#define PG7_RPORT PING
|
#define PG7_RPORT PING
|
||||||
#define PG7_WPORT PORTG
|
#define PG7_WPORT PORTG
|
||||||
#define PG7_DDR DDRG
|
#define PG7_DDR DDRG
|
||||||
#define PG7_PWM NULL
|
#define PG7_PWM NULL
|
||||||
|
|
||||||
#undef PH0
|
#undef PH0
|
||||||
#define PH0_PIN PINH0
|
#define PH0_PIN PINH0
|
||||||
#define PH0_RPORT PINH
|
#define PH0_RPORT PINH
|
||||||
#define PH0_WPORT PORTH
|
#define PH0_WPORT PORTH
|
||||||
#define PH0_DDR DDRH
|
#define PH0_DDR DDRH
|
||||||
#define PH0_PWM NULL
|
#define PH0_PWM NULL
|
||||||
#undef PH1
|
#undef PH1
|
||||||
#define PH1_PIN PINH1
|
#define PH1_PIN PINH1
|
||||||
#define PH1_RPORT PINH
|
#define PH1_RPORT PINH
|
||||||
#define PH1_WPORT PORTH
|
#define PH1_WPORT PORTH
|
||||||
#define PH1_DDR DDRH
|
#define PH1_DDR DDRH
|
||||||
#define PH1_PWM NULL
|
#define PH1_PWM NULL
|
||||||
#undef PH2
|
#undef PH2
|
||||||
#define PH2_PIN PINH2
|
#define PH2_PIN PINH2
|
||||||
#define PH2_RPORT PINH
|
#define PH2_RPORT PINH
|
||||||
#define PH2_WPORT PORTH
|
#define PH2_WPORT PORTH
|
||||||
#define PH2_DDR DDRH
|
#define PH2_DDR DDRH
|
||||||
#define PH2_PWM NULL
|
#define PH2_PWM NULL
|
||||||
#undef PH3
|
#undef PH3
|
||||||
#define PH3_PIN PINH3
|
#define PH3_PIN PINH3
|
||||||
#define PH3_RPORT PINH
|
#define PH3_RPORT PINH
|
||||||
#define PH3_WPORT PORTH
|
#define PH3_WPORT PORTH
|
||||||
#define PH3_DDR DDRH
|
#define PH3_DDR DDRH
|
||||||
#define PH3_PWM &OCR4AL
|
#define PH3_PWM &OCR4AL
|
||||||
#undef PH4
|
#undef PH4
|
||||||
#define PH4_PIN PINH4
|
#define PH4_PIN PINH4
|
||||||
#define PH4_RPORT PINH
|
#define PH4_RPORT PINH
|
||||||
#define PH4_WPORT PORTH
|
#define PH4_WPORT PORTH
|
||||||
#define PH4_DDR DDRH
|
#define PH4_DDR DDRH
|
||||||
#define PH4_PWM &OCR4BL
|
#define PH4_PWM &OCR4BL
|
||||||
#undef PH5
|
#undef PH5
|
||||||
#define PH5_PIN PINH5
|
#define PH5_PIN PINH5
|
||||||
#define PH5_RPORT PINH
|
#define PH5_RPORT PINH
|
||||||
#define PH5_WPORT PORTH
|
#define PH5_WPORT PORTH
|
||||||
#define PH5_DDR DDRH
|
#define PH5_DDR DDRH
|
||||||
#define PH5_PWM &OCR4CL
|
#define PH5_PWM &OCR4CL
|
||||||
#undef PH6
|
#undef PH6
|
||||||
#define PH6_PIN PINH6
|
#define PH6_PIN PINH6
|
||||||
#define PH6_RPORT PINH
|
#define PH6_RPORT PINH
|
||||||
#define PH6_WPORT PORTH
|
#define PH6_WPORT PORTH
|
||||||
#define PH6_DDR DDRH
|
#define PH6_DDR DDRH
|
||||||
#define PH6_PWM &OCR2B
|
#define PH6_PWM &OCR2B
|
||||||
#undef PH7
|
#undef PH7
|
||||||
#define PH7_PIN PINH7
|
#define PH7_PIN PINH7
|
||||||
#define PH7_RPORT PINH
|
#define PH7_RPORT PINH
|
||||||
#define PH7_WPORT PORTH
|
#define PH7_WPORT PORTH
|
||||||
#define PH7_DDR DDRH
|
#define PH7_DDR DDRH
|
||||||
#define PH7_PWM NULL
|
#define PH7_PWM NULL
|
||||||
|
|
||||||
#undef PJ0
|
#undef PJ0
|
||||||
#define PJ0_PIN PINJ0
|
#define PJ0_PIN PINJ0
|
||||||
#define PJ0_RPORT PINJ
|
#define PJ0_RPORT PINJ
|
||||||
#define PJ0_WPORT PORTJ
|
#define PJ0_WPORT PORTJ
|
||||||
#define PJ0_DDR DDRJ
|
#define PJ0_DDR DDRJ
|
||||||
#define PJ0_PWM NULL
|
#define PJ0_PWM NULL
|
||||||
#undef PJ1
|
#undef PJ1
|
||||||
#define PJ1_PIN PINJ1
|
#define PJ1_PIN PINJ1
|
||||||
#define PJ1_RPORT PINJ
|
#define PJ1_RPORT PINJ
|
||||||
#define PJ1_WPORT PORTJ
|
#define PJ1_WPORT PORTJ
|
||||||
#define PJ1_DDR DDRJ
|
#define PJ1_DDR DDRJ
|
||||||
#define PJ1_PWM NULL
|
#define PJ1_PWM NULL
|
||||||
#undef PJ2
|
#undef PJ2
|
||||||
#define PJ2_PIN PINJ2
|
#define PJ2_PIN PINJ2
|
||||||
#define PJ2_RPORT PINJ
|
#define PJ2_RPORT PINJ
|
||||||
#define PJ2_WPORT PORTJ
|
#define PJ2_WPORT PORTJ
|
||||||
#define PJ2_DDR DDRJ
|
#define PJ2_DDR DDRJ
|
||||||
#define PJ2_PWM NULL
|
#define PJ2_PWM NULL
|
||||||
#undef PJ3
|
#undef PJ3
|
||||||
#define PJ3_PIN PINJ3
|
#define PJ3_PIN PINJ3
|
||||||
#define PJ3_RPORT PINJ
|
#define PJ3_RPORT PINJ
|
||||||
#define PJ3_WPORT PORTJ
|
#define PJ3_WPORT PORTJ
|
||||||
#define PJ3_DDR DDRJ
|
#define PJ3_DDR DDRJ
|
||||||
#define PJ3_PWM NULL
|
#define PJ3_PWM NULL
|
||||||
#undef PJ4
|
#undef PJ4
|
||||||
#define PJ4_PIN PINJ4
|
#define PJ4_PIN PINJ4
|
||||||
#define PJ4_RPORT PINJ
|
#define PJ4_RPORT PINJ
|
||||||
#define PJ4_WPORT PORTJ
|
#define PJ4_WPORT PORTJ
|
||||||
#define PJ4_DDR DDRJ
|
#define PJ4_DDR DDRJ
|
||||||
#define PJ4_PWM NULL
|
#define PJ4_PWM NULL
|
||||||
#undef PJ5
|
#undef PJ5
|
||||||
#define PJ5_PIN PINJ5
|
#define PJ5_PIN PINJ5
|
||||||
#define PJ5_RPORT PINJ
|
#define PJ5_RPORT PINJ
|
||||||
#define PJ5_WPORT PORTJ
|
#define PJ5_WPORT PORTJ
|
||||||
#define PJ5_DDR DDRJ
|
#define PJ5_DDR DDRJ
|
||||||
#define PJ5_PWM NULL
|
#define PJ5_PWM NULL
|
||||||
#undef PJ6
|
#undef PJ6
|
||||||
#define PJ6_PIN PINJ6
|
#define PJ6_PIN PINJ6
|
||||||
#define PJ6_RPORT PINJ
|
#define PJ6_RPORT PINJ
|
||||||
#define PJ6_WPORT PORTJ
|
#define PJ6_WPORT PORTJ
|
||||||
#define PJ6_DDR DDRJ
|
#define PJ6_DDR DDRJ
|
||||||
#define PJ6_PWM NULL
|
#define PJ6_PWM NULL
|
||||||
#undef PJ7
|
#undef PJ7
|
||||||
#define PJ7_PIN PINJ7
|
#define PJ7_PIN PINJ7
|
||||||
#define PJ7_RPORT PINJ
|
#define PJ7_RPORT PINJ
|
||||||
#define PJ7_WPORT PORTJ
|
#define PJ7_WPORT PORTJ
|
||||||
#define PJ7_DDR DDRJ
|
#define PJ7_DDR DDRJ
|
||||||
#define PJ7_PWM NULL
|
#define PJ7_PWM NULL
|
||||||
|
|
||||||
#undef PK0
|
#undef PK0
|
||||||
#define PK0_PIN PINK0
|
#define PK0_PIN PINK0
|
||||||
#define PK0_RPORT PINK
|
#define PK0_RPORT PINK
|
||||||
#define PK0_WPORT PORTK
|
#define PK0_WPORT PORTK
|
||||||
#define PK0_DDR DDRK
|
#define PK0_DDR DDRK
|
||||||
#define PK0_PWM NULL
|
#define PK0_PWM NULL
|
||||||
#undef PK1
|
#undef PK1
|
||||||
#define PK1_PIN PINK1
|
#define PK1_PIN PINK1
|
||||||
#define PK1_RPORT PINK
|
#define PK1_RPORT PINK
|
||||||
#define PK1_WPORT PORTK
|
#define PK1_WPORT PORTK
|
||||||
#define PK1_DDR DDRK
|
#define PK1_DDR DDRK
|
||||||
#define PK1_PWM NULL
|
#define PK1_PWM NULL
|
||||||
#undef PK2
|
#undef PK2
|
||||||
#define PK2_PIN PINK2
|
#define PK2_PIN PINK2
|
||||||
#define PK2_RPORT PINK
|
#define PK2_RPORT PINK
|
||||||
#define PK2_WPORT PORTK
|
#define PK2_WPORT PORTK
|
||||||
#define PK2_DDR DDRK
|
#define PK2_DDR DDRK
|
||||||
#define PK2_PWM NULL
|
#define PK2_PWM NULL
|
||||||
#undef PK3
|
#undef PK3
|
||||||
#define PK3_PIN PINK3
|
#define PK3_PIN PINK3
|
||||||
#define PK3_RPORT PINK
|
#define PK3_RPORT PINK
|
||||||
#define PK3_WPORT PORTK
|
#define PK3_WPORT PORTK
|
||||||
#define PK3_DDR DDRK
|
#define PK3_DDR DDRK
|
||||||
#define PK3_PWM NULL
|
#define PK3_PWM NULL
|
||||||
#undef PK4
|
#undef PK4
|
||||||
#define PK4_PIN PINK4
|
#define PK4_PIN PINK4
|
||||||
#define PK4_RPORT PINK
|
#define PK4_RPORT PINK
|
||||||
#define PK4_WPORT PORTK
|
#define PK4_WPORT PORTK
|
||||||
#define PK4_DDR DDRK
|
#define PK4_DDR DDRK
|
||||||
#define PK4_PWM NULL
|
#define PK4_PWM NULL
|
||||||
#undef PK5
|
#undef PK5
|
||||||
#define PK5_PIN PINK5
|
#define PK5_PIN PINK5
|
||||||
#define PK5_RPORT PINK
|
#define PK5_RPORT PINK
|
||||||
#define PK5_WPORT PORTK
|
#define PK5_WPORT PORTK
|
||||||
#define PK5_DDR DDRK
|
#define PK5_DDR DDRK
|
||||||
#define PK5_PWM NULL
|
#define PK5_PWM NULL
|
||||||
#undef PK6
|
#undef PK6
|
||||||
#define PK6_PIN PINK6
|
#define PK6_PIN PINK6
|
||||||
#define PK6_RPORT PINK
|
#define PK6_RPORT PINK
|
||||||
#define PK6_WPORT PORTK
|
#define PK6_WPORT PORTK
|
||||||
#define PK6_DDR DDRK
|
#define PK6_DDR DDRK
|
||||||
#define PK6_PWM NULL
|
#define PK6_PWM NULL
|
||||||
#undef PK7
|
#undef PK7
|
||||||
#define PK7_PIN PINK7
|
#define PK7_PIN PINK7
|
||||||
#define PK7_RPORT PINK
|
#define PK7_RPORT PINK
|
||||||
#define PK7_WPORT PORTK
|
#define PK7_WPORT PORTK
|
||||||
#define PK7_DDR DDRK
|
#define PK7_DDR DDRK
|
||||||
#define PK7_PWM NULL
|
#define PK7_PWM NULL
|
||||||
|
|
||||||
#undef PL0
|
#undef PL0
|
||||||
#define PL0_PIN PINL0
|
#define PL0_PIN PINL0
|
||||||
#define PL0_RPORT PINL
|
#define PL0_RPORT PINL
|
||||||
#define PL0_WPORT PORTL
|
#define PL0_WPORT PORTL
|
||||||
#define PL0_DDR DDRL
|
#define PL0_DDR DDRL
|
||||||
#define PL0_PWM NULL
|
#define PL0_PWM NULL
|
||||||
#undef PL1
|
#undef PL1
|
||||||
#define PL1_PIN PINL1
|
#define PL1_PIN PINL1
|
||||||
#define PL1_RPORT PINL
|
#define PL1_RPORT PINL
|
||||||
#define PL1_WPORT PORTL
|
#define PL1_WPORT PORTL
|
||||||
#define PL1_DDR DDRL
|
#define PL1_DDR DDRL
|
||||||
#define PL1_PWM NULL
|
#define PL1_PWM NULL
|
||||||
#undef PL2
|
#undef PL2
|
||||||
#define PL2_PIN PINL2
|
#define PL2_PIN PINL2
|
||||||
#define PL2_RPORT PINL
|
#define PL2_RPORT PINL
|
||||||
#define PL2_WPORT PORTL
|
#define PL2_WPORT PORTL
|
||||||
#define PL2_DDR DDRL
|
#define PL2_DDR DDRL
|
||||||
#define PL2_PWM NULL
|
#define PL2_PWM NULL
|
||||||
#undef PL3
|
#undef PL3
|
||||||
#define PL3_PIN PINL3
|
#define PL3_PIN PINL3
|
||||||
#define PL3_RPORT PINL
|
#define PL3_RPORT PINL
|
||||||
#define PL3_WPORT PORTL
|
#define PL3_WPORT PORTL
|
||||||
#define PL3_DDR DDRL
|
#define PL3_DDR DDRL
|
||||||
#define PL3_PWM &OCR5AL
|
#define PL3_PWM &OCR5AL
|
||||||
#undef PL4
|
#undef PL4
|
||||||
#define PL4_PIN PINL4
|
#define PL4_PIN PINL4
|
||||||
#define PL4_RPORT PINL
|
#define PL4_RPORT PINL
|
||||||
#define PL4_WPORT PORTL
|
#define PL4_WPORT PORTL
|
||||||
#define PL4_DDR DDRL
|
#define PL4_DDR DDRL
|
||||||
#define PL4_PWM &OCR5BL
|
#define PL4_PWM &OCR5BL
|
||||||
#undef PL5
|
#undef PL5
|
||||||
#define PL5_PIN PINL5
|
#define PL5_PIN PINL5
|
||||||
#define PL5_RPORT PINL
|
#define PL5_RPORT PINL
|
||||||
#define PL5_WPORT PORTL
|
#define PL5_WPORT PORTL
|
||||||
#define PL5_DDR DDRL
|
#define PL5_DDR DDRL
|
||||||
#define PL5_PWM &OCR5CL
|
#define PL5_PWM &OCR5CL
|
||||||
#undef PL6
|
#undef PL6
|
||||||
#define PL6_PIN PINL6
|
#define PL6_PIN PINL6
|
||||||
#define PL6_RPORT PINL
|
#define PL6_RPORT PINL
|
||||||
#define PL6_WPORT PORTL
|
#define PL6_WPORT PORTL
|
||||||
#define PL6_DDR DDRL
|
#define PL6_DDR DDRL
|
||||||
#define PL6_PWM NULL
|
#define PL6_PWM NULL
|
||||||
#undef PL7
|
#undef PL7
|
||||||
#define PL7_PIN PINL7
|
#define PL7_PIN PINL7
|
||||||
#define PL7_RPORT PINL
|
#define PL7_RPORT PINL
|
||||||
#define PL7_WPORT PORTL
|
#define PL7_WPORT PORTL
|
||||||
#define PL7_DDR DDRL
|
#define PL7_DDR DDRL
|
||||||
#define PL7_PWM NULL
|
#define PL7_PWM NULL
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (__AVR_AT90USB1287__)
|
#if defined (__AVR_AT90USB1287__)
|
||||||
// SPI
|
// SPI
|
||||||
#define SCK DIO9
|
#define SCK DIO9
|
||||||
#define MISO DIO11
|
#define MISO DIO11
|
||||||
#define MOSI DIO10
|
#define MOSI DIO10
|
||||||
#define SS DIO8
|
#define SS DIO8
|
||||||
|
|
||||||
// change for your board
|
// change for your board
|
||||||
#define DEBUG_LED DIO31 /* led D5 red */
|
#define DEBUG_LED DIO31 /* led D5 red */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pins
|
pins
|
||||||
*/
|
*/
|
||||||
#define DIO0_PIN PINA0
|
#define DIO0_PIN PINA0
|
||||||
#define DIO0_RPORT PINA
|
#define DIO0_RPORT PINA
|
||||||
#define DIO0_WPORT PORTA
|
#define DIO0_WPORT PORTA
|
||||||
#define DIO0_PWM NULL
|
#define DIO0_PWM NULL
|
||||||
#define DIO0_DDR DDRA
|
#define DIO0_DDR DDRA
|
||||||
|
|
||||||
#define DIO1_PIN PINA1
|
#define DIO1_PIN PINA1
|
||||||
#define DIO1_RPORT PINA
|
#define DIO1_RPORT PINA
|
||||||
#define DIO1_WPORT PORTA
|
#define DIO1_WPORT PORTA
|
||||||
#define DIO1_PWM NULL
|
#define DIO1_PWM NULL
|
||||||
#define DIO1_DDR DDRA
|
#define DIO1_DDR DDRA
|
||||||
|
|
||||||
#define DIO2_PIN PINA2
|
#define DIO2_PIN PINA2
|
||||||
#define DIO2_RPORT PINA
|
#define DIO2_RPORT PINA
|
||||||
#define DIO2_WPORT PORTA
|
#define DIO2_WPORT PORTA
|
||||||
#define DIO2_PWM NULL
|
#define DIO2_PWM NULL
|
||||||
#define DIO2_DDR DDRA
|
#define DIO2_DDR DDRA
|
||||||
|
|
||||||
#define DIO3_PIN PINA3
|
#define DIO3_PIN PINA3
|
||||||
#define DIO3_RPORT PINA
|
#define DIO3_RPORT PINA
|
||||||
#define DIO3_WPORT PORTA
|
#define DIO3_WPORT PORTA
|
||||||
#define DIO3_PWM NULL
|
#define DIO3_PWM NULL
|
||||||
#define DIO3_DDR DDRA
|
#define DIO3_DDR DDRA
|
||||||
|
|
||||||
#define DIO4_PIN PINA4
|
#define DIO4_PIN PINA4
|
||||||
#define DIO4_RPORT PINA
|
#define DIO4_RPORT PINA
|
||||||
#define DIO4_WPORT PORTA
|
#define DIO4_WPORT PORTA
|
||||||
#define DIO4_PWM NULL
|
#define DIO4_PWM NULL
|
||||||
#define DIO4_DDR DDRA
|
#define DIO4_DDR DDRA
|
||||||
|
|
||||||
#define DIO5_PIN PINA5
|
#define DIO5_PIN PINA5
|
||||||
#define DIO5_RPORT PINA
|
#define DIO5_RPORT PINA
|
||||||
#define DIO5_WPORT PORTA
|
#define DIO5_WPORT PORTA
|
||||||
#define DIO5_PWM NULL
|
#define DIO5_PWM NULL
|
||||||
#define DIO5_DDR DDRA
|
#define DIO5_DDR DDRA
|
||||||
|
|
||||||
#define DIO6_PIN PINA6
|
#define DIO6_PIN PINA6
|
||||||
#define DIO6_RPORT PINA
|
#define DIO6_RPORT PINA
|
||||||
#define DIO6_WPORT PORTA
|
#define DIO6_WPORT PORTA
|
||||||
#define DIO6_PWM NULL
|
#define DIO6_PWM NULL
|
||||||
#define DIO6_DDR DDRA
|
#define DIO6_DDR DDRA
|
||||||
|
|
||||||
#define DIO7_PIN PINA7
|
#define DIO7_PIN PINA7
|
||||||
#define DIO7_RPORT PINA
|
#define DIO7_RPORT PINA
|
||||||
#define DIO7_WPORT PORTA
|
#define DIO7_WPORT PORTA
|
||||||
#define DIO7_PWM NULL
|
#define DIO7_PWM NULL
|
||||||
#define DIO7_DDR DDRA
|
#define DIO7_DDR DDRA
|
||||||
|
|
||||||
#define DIO8_PIN PINB0
|
#define DIO8_PIN PINB0
|
||||||
#define DIO8_RPORT PINB
|
#define DIO8_RPORT PINB
|
||||||
#define DIO8_WPORT PORTB
|
#define DIO8_WPORT PORTB
|
||||||
#define DIO8_PWM NULL
|
#define DIO8_PWM NULL
|
||||||
#define DIO8_DDR DDRB
|
#define DIO8_DDR DDRB
|
||||||
|
|
||||||
#define DIO9_PIN PINB1
|
#define DIO9_PIN PINB1
|
||||||
#define DIO9_RPORT PINB
|
#define DIO9_RPORT PINB
|
||||||
#define DIO9_WPORT PORTB
|
#define DIO9_WPORT PORTB
|
||||||
#define DIO9_PWM NULL
|
#define DIO9_PWM NULL
|
||||||
#define DIO9_DDR DDRB
|
#define DIO9_DDR DDRB
|
||||||
|
|
||||||
#define DIO10_PIN PINB2
|
#define DIO10_PIN PINB2
|
||||||
#define DIO10_RPORT PINB
|
#define DIO10_RPORT PINB
|
||||||
#define DIO10_WPORT PORTB
|
#define DIO10_WPORT PORTB
|
||||||
#define DIO10_PWM NULL
|
#define DIO10_PWM NULL
|
||||||
#define DIO10_DDR DDRB
|
#define DIO10_DDR DDRB
|
||||||
|
|
||||||
#define DIO11_PIN PINB3
|
#define DIO11_PIN PINB3
|
||||||
#define DIO11_RPORT PINB
|
#define DIO11_RPORT PINB
|
||||||
#define DIO11_WPORT PORTB
|
#define DIO11_WPORT PORTB
|
||||||
#define DIO11_PWM NULL
|
#define DIO11_PWM NULL
|
||||||
#define DIO11_DDR DDRB
|
#define DIO11_DDR DDRB
|
||||||
|
|
||||||
#define DIO12_PIN PINB4
|
#define DIO12_PIN PINB4
|
||||||
#define DIO12_RPORT PINB
|
#define DIO12_RPORT PINB
|
||||||
#define DIO12_WPORT PORTB
|
#define DIO12_WPORT PORTB
|
||||||
#define DIO12_PWM NULL
|
#define DIO12_PWM NULL
|
||||||
#define DIO12_DDR DDRB
|
#define DIO12_DDR DDRB
|
||||||
|
|
||||||
#define DIO13_PIN PINB5
|
#define DIO13_PIN PINB5
|
||||||
#define DIO13_RPORT PINB
|
#define DIO13_RPORT PINB
|
||||||
#define DIO13_WPORT PORTB
|
#define DIO13_WPORT PORTB
|
||||||
#define DIO13_PWM NULL
|
#define DIO13_PWM NULL
|
||||||
#define DIO13_DDR DDRB
|
#define DIO13_DDR DDRB
|
||||||
|
|
||||||
#define DIO14_PIN PINB6
|
#define DIO14_PIN PINB6
|
||||||
#define DIO14_RPORT PINB
|
#define DIO14_RPORT PINB
|
||||||
#define DIO14_WPORT PORTB
|
#define DIO14_WPORT PORTB
|
||||||
#define DIO14_PWM NULL
|
#define DIO14_PWM NULL
|
||||||
#define DIO14_DDR DDRB
|
#define DIO14_DDR DDRB
|
||||||
|
|
||||||
#define DIO15_PIN PINB7
|
#define DIO15_PIN PINB7
|
||||||
#define DIO15_RPORT PINB
|
#define DIO15_RPORT PINB
|
||||||
#define DIO15_WPORT PORTB
|
#define DIO15_WPORT PORTB
|
||||||
#define DIO15_PWM NULL
|
#define DIO15_PWM NULL
|
||||||
#define DIO15_DDR DDRB
|
#define DIO15_DDR DDRB
|
||||||
|
|
||||||
#define DIO16_PIN PINC0
|
#define DIO16_PIN PINC0
|
||||||
#define DIO16_RPORT PINC
|
#define DIO16_RPORT PINC
|
||||||
#define DIO16_WPORT PORTC
|
#define DIO16_WPORT PORTC
|
||||||
#define DIO16_PWM NULL
|
#define DIO16_PWM NULL
|
||||||
#define DIO16_DDR DDRC
|
#define DIO16_DDR DDRC
|
||||||
|
|
||||||
#define DIO17_PIN PINC1
|
#define DIO17_PIN PINC1
|
||||||
#define DIO17_RPORT PINC
|
#define DIO17_RPORT PINC
|
||||||
#define DIO17_WPORT PORTC
|
#define DIO17_WPORT PORTC
|
||||||
#define DIO17_PWM NULL
|
#define DIO17_PWM NULL
|
||||||
#define DIO17_DDR DDRC
|
#define DIO17_DDR DDRC
|
||||||
|
|
||||||
#define DIO18_PIN PINC2
|
#define DIO18_PIN PINC2
|
||||||
#define DIO18_RPORT PINC
|
#define DIO18_RPORT PINC
|
||||||
#define DIO18_WPORT PORTC
|
#define DIO18_WPORT PORTC
|
||||||
#define DIO18_PWM NULL
|
#define DIO18_PWM NULL
|
||||||
#define DIO18_DDR DDRC
|
#define DIO18_DDR DDRC
|
||||||
|
|
||||||
#define DIO19_PIN PINC3
|
#define DIO19_PIN PINC3
|
||||||
#define DIO19_RPORT PINC
|
#define DIO19_RPORT PINC
|
||||||
#define DIO19_WPORT PORTC
|
#define DIO19_WPORT PORTC
|
||||||
#define DIO19_PWM NULL
|
#define DIO19_PWM NULL
|
||||||
#define DIO19_DDR DDRC
|
#define DIO19_DDR DDRC
|
||||||
|
|
||||||
#define DIO20_PIN PINC4
|
#define DIO20_PIN PINC4
|
||||||
#define DIO20_RPORT PINC
|
#define DIO20_RPORT PINC
|
||||||
#define DIO20_WPORT PORTC
|
#define DIO20_WPORT PORTC
|
||||||
#define DIO20_PWM NULL
|
#define DIO20_PWM NULL
|
||||||
#define DIO20_DDR DDRC
|
#define DIO20_DDR DDRC
|
||||||
|
|
||||||
#define DIO21_PIN PINC5
|
#define DIO21_PIN PINC5
|
||||||
#define DIO21_RPORT PINC
|
#define DIO21_RPORT PINC
|
||||||
#define DIO21_WPORT PORTC
|
#define DIO21_WPORT PORTC
|
||||||
#define DIO21_PWM NULL
|
#define DIO21_PWM NULL
|
||||||
#define DIO21_DDR DDRC
|
#define DIO21_DDR DDRC
|
||||||
|
|
||||||
#define DIO22_PIN PINC6
|
#define DIO22_PIN PINC6
|
||||||
#define DIO22_RPORT PINC
|
#define DIO22_RPORT PINC
|
||||||
#define DIO22_WPORT PORTC
|
#define DIO22_WPORT PORTC
|
||||||
#define DIO22_PWM NULL
|
#define DIO22_PWM NULL
|
||||||
#define DIO22_DDR DDRC
|
#define DIO22_DDR DDRC
|
||||||
|
|
||||||
#define DIO23_PIN PINC7
|
#define DIO23_PIN PINC7
|
||||||
#define DIO23_RPORT PINC
|
#define DIO23_RPORT PINC
|
||||||
#define DIO23_WPORT PORTC
|
#define DIO23_WPORT PORTC
|
||||||
#define DIO23_PWM NULL
|
#define DIO23_PWM NULL
|
||||||
#define DIO23_DDR DDRC
|
#define DIO23_DDR DDRC
|
||||||
|
|
||||||
#define DIO24_PIN PIND0
|
#define DIO24_PIN PIND0
|
||||||
#define DIO24_RPORT PIND
|
#define DIO24_RPORT PIND
|
||||||
#define DIO24_WPORT PORTD
|
#define DIO24_WPORT PORTD
|
||||||
#define DIO24_PWM NULL
|
#define DIO24_PWM NULL
|
||||||
#define DIO24_DDR DDRD
|
#define DIO24_DDR DDRD
|
||||||
|
|
||||||
#define DIO25_PIN PIND1
|
#define DIO25_PIN PIND1
|
||||||
#define DIO25_RPORT PIND
|
#define DIO25_RPORT PIND
|
||||||
#define DIO25_WPORT PORTD
|
#define DIO25_WPORT PORTD
|
||||||
#define DIO25_PWM NULL
|
#define DIO25_PWM NULL
|
||||||
#define DIO25_DDR DDRD
|
#define DIO25_DDR DDRD
|
||||||
|
|
||||||
#define DIO26_PIN PIND2
|
#define DIO26_PIN PIND2
|
||||||
#define DIO26_RPORT PIND
|
#define DIO26_RPORT PIND
|
||||||
#define DIO26_WPORT PORTD
|
#define DIO26_WPORT PORTD
|
||||||
#define DIO26_PWM NULL
|
#define DIO26_PWM NULL
|
||||||
#define DIO26_DDR DDRD
|
#define DIO26_DDR DDRD
|
||||||
|
|
||||||
#define DIO27_PIN PIND3
|
#define DIO27_PIN PIND3
|
||||||
#define DIO27_RPORT PIND
|
#define DIO27_RPORT PIND
|
||||||
#define DIO27_WPORT PORTD
|
#define DIO27_WPORT PORTD
|
||||||
#define DIO27_PWM NULL
|
#define DIO27_PWM NULL
|
||||||
#define DIO27_DDR DDRD
|
#define DIO27_DDR DDRD
|
||||||
|
|
||||||
#define DIO28_PIN PIND4
|
#define DIO28_PIN PIND4
|
||||||
#define DIO28_RPORT PIND
|
#define DIO28_RPORT PIND
|
||||||
#define DIO28_WPORT PORTD
|
#define DIO28_WPORT PORTD
|
||||||
#define DIO28_PWM NULL
|
#define DIO28_PWM NULL
|
||||||
#define DIO28_DDR DDRD
|
#define DIO28_DDR DDRD
|
||||||
|
|
||||||
#define DIO29_PIN PIND5
|
#define DIO29_PIN PIND5
|
||||||
#define DIO29_RPORT PIND
|
#define DIO29_RPORT PIND
|
||||||
#define DIO29_WPORT PORTD
|
#define DIO29_WPORT PORTD
|
||||||
#define DIO29_PWM NULL
|
#define DIO29_PWM NULL
|
||||||
#define DIO29_DDR DDRD
|
#define DIO29_DDR DDRD
|
||||||
|
|
||||||
#define DIO30_PIN PIND6
|
#define DIO30_PIN PIND6
|
||||||
#define DIO30_RPORT PIND
|
#define DIO30_RPORT PIND
|
||||||
#define DIO30_WPORT PORTD
|
#define DIO30_WPORT PORTD
|
||||||
#define DIO30_PWM NULL
|
#define DIO30_PWM NULL
|
||||||
#define DIO30_DDR DDRD
|
#define DIO30_DDR DDRD
|
||||||
|
|
||||||
#define DIO31_PIN PIND7
|
#define DIO31_PIN PIND7
|
||||||
#define DIO31_RPORT PIND
|
#define DIO31_RPORT PIND
|
||||||
#define DIO31_WPORT PORTD
|
#define DIO31_WPORT PORTD
|
||||||
#define DIO31_PWM NULL
|
#define DIO31_PWM NULL
|
||||||
#define DIO31_DDR DDRD
|
#define DIO31_DDR DDRD
|
||||||
|
|
||||||
|
|
||||||
#define DIO32_PIN PINE0
|
#define DIO32_PIN PINE0
|
||||||
#define DIO32_RPORT PINE
|
#define DIO32_RPORT PINE
|
||||||
#define DIO32_WPORT PORTE
|
#define DIO32_WPORT PORTE
|
||||||
#define DIO32_PWM NULL
|
#define DIO32_PWM NULL
|
||||||
#define DIO32_DDR DDRE
|
#define DIO32_DDR DDRE
|
||||||
|
|
||||||
#define DIO33_PIN PINE1
|
#define DIO33_PIN PINE1
|
||||||
#define DIO33_RPORT PINE
|
#define DIO33_RPORT PINE
|
||||||
#define DIO33_WPORT PORTE
|
#define DIO33_WPORT PORTE
|
||||||
#define DIO33_PWM NULL
|
#define DIO33_PWM NULL
|
||||||
#define DIO33_DDR DDRE
|
#define DIO33_DDR DDRE
|
||||||
|
|
||||||
#define DIO34_PIN PINE2
|
#define DIO34_PIN PINE2
|
||||||
#define DIO34_RPORT PINE
|
#define DIO34_RPORT PINE
|
||||||
#define DIO34_WPORT PORTE
|
#define DIO34_WPORT PORTE
|
||||||
#define DIO34_PWM NULL
|
#define DIO34_PWM NULL
|
||||||
#define DIO34_DDR DDRE
|
#define DIO34_DDR DDRE
|
||||||
|
|
||||||
#define DIO35_PIN PINE3
|
#define DIO35_PIN PINE3
|
||||||
#define DIO35_RPORT PINE
|
#define DIO35_RPORT PINE
|
||||||
#define DIO35_WPORT PORTE
|
#define DIO35_WPORT PORTE
|
||||||
#define DIO35_PWM NULL
|
#define DIO35_PWM NULL
|
||||||
#define DIO35_DDR DDRE
|
#define DIO35_DDR DDRE
|
||||||
|
|
||||||
#define DIO36_PIN PINE4
|
#define DIO36_PIN PINE4
|
||||||
#define DIO36_RPORT PINE
|
#define DIO36_RPORT PINE
|
||||||
#define DIO36_WPORT PORTE
|
#define DIO36_WPORT PORTE
|
||||||
#define DIO36_PWM NULL
|
#define DIO36_PWM NULL
|
||||||
#define DIO36_DDR DDRE
|
#define DIO36_DDR DDRE
|
||||||
|
|
||||||
#define DIO37_PIN PINE5
|
#define DIO37_PIN PINE5
|
||||||
#define DIO37_RPORT PINE
|
#define DIO37_RPORT PINE
|
||||||
#define DIO37_WPORT PORTE
|
#define DIO37_WPORT PORTE
|
||||||
#define DIO37_PWM NULL
|
#define DIO37_PWM NULL
|
||||||
#define DIO37_DDR DDRE
|
#define DIO37_DDR DDRE
|
||||||
|
|
||||||
#define DIO38_PIN PINE6
|
#define DIO38_PIN PINE6
|
||||||
#define DIO38_RPORT PINE
|
#define DIO38_RPORT PINE
|
||||||
#define DIO38_WPORT PORTE
|
#define DIO38_WPORT PORTE
|
||||||
#define DIO38_PWM NULL
|
#define DIO38_PWM NULL
|
||||||
#define DIO38_DDR DDRE
|
#define DIO38_DDR DDRE
|
||||||
|
|
||||||
#define DIO39_PIN PINE7
|
#define DIO39_PIN PINE7
|
||||||
#define DIO39_RPORT PINE
|
#define DIO39_RPORT PINE
|
||||||
#define DIO39_WPORT PORTE
|
#define DIO39_WPORT PORTE
|
||||||
#define DIO39_PWM NULL
|
#define DIO39_PWM NULL
|
||||||
#define DIO39_DDR DDRE
|
#define DIO39_DDR DDRE
|
||||||
|
|
||||||
#define AIO0_PIN PINF0
|
#define AIO0_PIN PINF0
|
||||||
#define AIO0_RPORT PINF
|
#define AIO0_RPORT PINF
|
||||||
#define AIO0_WPORT PORTF
|
#define AIO0_WPORT PORTF
|
||||||
#define AIO0_PWM NULL
|
#define AIO0_PWM NULL
|
||||||
#define AIO0_DDR DDRF
|
#define AIO0_DDR DDRF
|
||||||
|
|
||||||
#define AIO1_PIN PINF1
|
#define AIO1_PIN PINF1
|
||||||
#define AIO1_RPORT PINF
|
#define AIO1_RPORT PINF
|
||||||
#define AIO1_WPORT PORTF
|
#define AIO1_WPORT PORTF
|
||||||
#define AIO1_PWM NULL
|
#define AIO1_PWM NULL
|
||||||
#define AIO1_DDR DDRF
|
#define AIO1_DDR DDRF
|
||||||
|
|
||||||
#define AIO2_PIN PINF2
|
#define AIO2_PIN PINF2
|
||||||
#define AIO2_RPORT PINF
|
#define AIO2_RPORT PINF
|
||||||
#define AIO2_WPORT PORTF
|
#define AIO2_WPORT PORTF
|
||||||
#define AIO2_PWM NULL
|
#define AIO2_PWM NULL
|
||||||
#define AIO2_DDR DDRF
|
#define AIO2_DDR DDRF
|
||||||
|
|
||||||
#define AIO3_PIN PINF3
|
#define AIO3_PIN PINF3
|
||||||
#define AIO3_RPORT PINF
|
#define AIO3_RPORT PINF
|
||||||
#define AIO3_WPORT PORTF
|
#define AIO3_WPORT PORTF
|
||||||
#define AIO3_PWM NULL
|
#define AIO3_PWM NULL
|
||||||
#define AIO3_DDR DDRF
|
#define AIO3_DDR DDRF
|
||||||
|
|
||||||
#define AIO4_PIN PINF4
|
#define AIO4_PIN PINF4
|
||||||
#define AIO4_RPORT PINF
|
#define AIO4_RPORT PINF
|
||||||
#define AIO4_WPORT PORTF
|
#define AIO4_WPORT PORTF
|
||||||
#define AIO4_PWM NULL
|
#define AIO4_PWM NULL
|
||||||
#define AIO4_DDR DDRF
|
#define AIO4_DDR DDRF
|
||||||
|
|
||||||
#define AIO5_PIN PINF5
|
#define AIO5_PIN PINF5
|
||||||
#define AIO5_RPORT PINF
|
#define AIO5_RPORT PINF
|
||||||
#define AIO5_WPORT PORTF
|
#define AIO5_WPORT PORTF
|
||||||
#define AIO5_PWM NULL
|
#define AIO5_PWM NULL
|
||||||
#define AIO5_DDR DDRF
|
#define AIO5_DDR DDRF
|
||||||
|
|
||||||
#define AIO6_PIN PINF6
|
#define AIO6_PIN PINF6
|
||||||
#define AIO6_RPORT PINF
|
#define AIO6_RPORT PINF
|
||||||
#define AIO6_WPORT PORTF
|
#define AIO6_WPORT PORTF
|
||||||
#define AIO6_PWM NULL
|
#define AIO6_PWM NULL
|
||||||
#define AIO6_DDR DDRF
|
#define AIO6_DDR DDRF
|
||||||
|
|
||||||
#define AIO7_PIN PINF7
|
#define AIO7_PIN PINF7
|
||||||
#define AIO7_RPORT PINF
|
#define AIO7_RPORT PINF
|
||||||
#define AIO7_WPORT PORTF
|
#define AIO7_WPORT PORTF
|
||||||
#define AIO7_PWM NULL
|
#define AIO7_PWM NULL
|
||||||
#define AIO7_DDR DDRF
|
#define AIO7_DDR DDRF
|
||||||
|
|
||||||
#define DIO40_PIN PINF0
|
#define DIO40_PIN PINF0
|
||||||
#define DIO40_RPORT PINF
|
#define DIO40_RPORT PINF
|
||||||
#define DIO40_WPORT PORTF
|
#define DIO40_WPORT PORTF
|
||||||
#define DIO40_PWM NULL
|
#define DIO40_PWM NULL
|
||||||
#define DIO40_DDR DDRF
|
#define DIO40_DDR DDRF
|
||||||
|
|
||||||
#define DIO41_PIN PINF1
|
#define DIO41_PIN PINF1
|
||||||
#define DIO41_RPORT PINF
|
#define DIO41_RPORT PINF
|
||||||
#define DIO41_WPORT PORTF
|
#define DIO41_WPORT PORTF
|
||||||
#define DIO41_PWM NULL
|
#define DIO41_PWM NULL
|
||||||
#define DIO41_DDR DDRF
|
#define DIO41_DDR DDRF
|
||||||
|
|
||||||
#define DIO42_PIN PINF2
|
#define DIO42_PIN PINF2
|
||||||
#define DIO42_RPORT PINF
|
#define DIO42_RPORT PINF
|
||||||
#define DIO42_WPORT PORTF
|
#define DIO42_WPORT PORTF
|
||||||
#define DIO42_PWM NULL
|
#define DIO42_PWM NULL
|
||||||
#define DIO42_DDR DDRF
|
#define DIO42_DDR DDRF
|
||||||
|
|
||||||
#define DIO43_PIN PINF3
|
#define DIO43_PIN PINF3
|
||||||
#define DIO43_RPORT PINF
|
#define DIO43_RPORT PINF
|
||||||
#define DIO43_WPORT PORTF
|
#define DIO43_WPORT PORTF
|
||||||
#define DIO43_PWM NULL
|
#define DIO43_PWM NULL
|
||||||
#define DIO43_DDR DDRF
|
#define DIO43_DDR DDRF
|
||||||
|
|
||||||
#define DIO44_PIN PINF4
|
#define DIO44_PIN PINF4
|
||||||
#define DIO44_RPORT PINF
|
#define DIO44_RPORT PINF
|
||||||
#define DIO44_WPORT PORTF
|
#define DIO44_WPORT PORTF
|
||||||
#define DIO44_PWM NULL
|
#define DIO44_PWM NULL
|
||||||
#define DIO44_DDR DDRF
|
#define DIO44_DDR DDRF
|
||||||
|
|
||||||
#define DIO45_PIN PINF5
|
#define DIO45_PIN PINF5
|
||||||
#define DIO45_RPORT PINF
|
#define DIO45_RPORT PINF
|
||||||
#define DIO45_WPORT PORTF
|
#define DIO45_WPORT PORTF
|
||||||
#define DIO45_PWM NULL
|
#define DIO45_PWM NULL
|
||||||
#define DIO45_DDR DDRF
|
#define DIO45_DDR DDRF
|
||||||
|
|
||||||
#define DIO46_PIN PINF6
|
#define DIO46_PIN PINF6
|
||||||
#define DIO46_RPORT PINF
|
#define DIO46_RPORT PINF
|
||||||
#define DIO46_WPORT PORTF
|
#define DIO46_WPORT PORTF
|
||||||
#define DIO46_PWM NULL
|
#define DIO46_PWM NULL
|
||||||
#define DIO46_DDR DDRF
|
#define DIO46_DDR DDRF
|
||||||
|
|
||||||
#define DIO47_PIN PINF7
|
#define DIO47_PIN PINF7
|
||||||
#define DIO47_RPORT PINF
|
#define DIO47_RPORT PINF
|
||||||
#define DIO47_WPORT PORTF
|
#define DIO47_WPORT PORTF
|
||||||
#define DIO47_PWM NULL
|
#define DIO47_PWM NULL
|
||||||
#define DIO47_DDR DDRF
|
#define DIO47_DDR DDRF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#undef PA0
|
#undef PA0
|
||||||
#define PA0_PIN PINA0
|
#define PA0_PIN PINA0
|
||||||
#define PA0_RPORT PINA
|
#define PA0_RPORT PINA
|
||||||
#define PA0_WPORT PORTA
|
#define PA0_WPORT PORTA
|
||||||
#define PA0_PWM NULL
|
#define PA0_PWM NULL
|
||||||
#define PA0_DDR DDRA
|
#define PA0_DDR DDRA
|
||||||
#undef PA1
|
#undef PA1
|
||||||
#define PA1_PIN PINA1
|
#define PA1_PIN PINA1
|
||||||
#define PA1_RPORT PINA
|
#define PA1_RPORT PINA
|
||||||
#define PA1_WPORT PORTA
|
#define PA1_WPORT PORTA
|
||||||
#define PA1_PWM NULL
|
#define PA1_PWM NULL
|
||||||
#define PA1_DDR DDRA
|
#define PA1_DDR DDRA
|
||||||
#undef PA2
|
#undef PA2
|
||||||
#define PA2_PIN PINA2
|
#define PA2_PIN PINA2
|
||||||
#define PA2_RPORT PINA
|
#define PA2_RPORT PINA
|
||||||
#define PA2_WPORT PORTA
|
#define PA2_WPORT PORTA
|
||||||
#define PA2_PWM NULL
|
#define PA2_PWM NULL
|
||||||
#define PA2_DDR DDRA
|
#define PA2_DDR DDRA
|
||||||
#undef PA3
|
#undef PA3
|
||||||
#define PA3_PIN PINA3
|
#define PA3_PIN PINA3
|
||||||
#define PA3_RPORT PINA
|
#define PA3_RPORT PINA
|
||||||
#define PA3_WPORT PORTA
|
#define PA3_WPORT PORTA
|
||||||
#define PA3_PWM NULL
|
#define PA3_PWM NULL
|
||||||
#define PA3_DDR DDRA
|
#define PA3_DDR DDRA
|
||||||
#undef PA4
|
#undef PA4
|
||||||
#define PA4_PIN PINA4
|
#define PA4_PIN PINA4
|
||||||
#define PA4_RPORT PINA
|
#define PA4_RPORT PINA
|
||||||
#define PA4_WPORT PORTA
|
#define PA4_WPORT PORTA
|
||||||
#define PA4_PWM NULL
|
#define PA4_PWM NULL
|
||||||
#define PA4_DDR DDRA
|
#define PA4_DDR DDRA
|
||||||
#undef PA5
|
#undef PA5
|
||||||
#define PA5_PIN PINA5
|
#define PA5_PIN PINA5
|
||||||
#define PA5_RPORT PINA
|
#define PA5_RPORT PINA
|
||||||
#define PA5_WPORT PORTA
|
#define PA5_WPORT PORTA
|
||||||
#define PA5_PWM NULL
|
#define PA5_PWM NULL
|
||||||
#define PA5_DDR DDRA
|
#define PA5_DDR DDRA
|
||||||
#undef PA6
|
#undef PA6
|
||||||
#define PA6_PIN PINA6
|
#define PA6_PIN PINA6
|
||||||
#define PA6_RPORT PINA
|
#define PA6_RPORT PINA
|
||||||
#define PA6_WPORT PORTA
|
#define PA6_WPORT PORTA
|
||||||
#define PA6_PWM NULL
|
#define PA6_PWM NULL
|
||||||
#define PA6_DDR DDRA
|
#define PA6_DDR DDRA
|
||||||
#undef PA7
|
#undef PA7
|
||||||
#define PA7_PIN PINA7
|
#define PA7_PIN PINA7
|
||||||
#define PA7_RPORT PINA
|
#define PA7_RPORT PINA
|
||||||
#define PA7_WPORT PORTA
|
#define PA7_WPORT PORTA
|
||||||
#define PA7_PWM NULL
|
#define PA7_PWM NULL
|
||||||
#define PA7_DDR DDRA
|
#define PA7_DDR DDRA
|
||||||
|
|
||||||
#undef PB0
|
#undef PB0
|
||||||
#define PB0_PIN PINB0
|
#define PB0_PIN PINB0
|
||||||
#define PB0_RPORT PINB
|
#define PB0_RPORT PINB
|
||||||
#define PB0_WPORT PORTB
|
#define PB0_WPORT PORTB
|
||||||
#define PB0_PWM NULL
|
#define PB0_PWM NULL
|
||||||
#define PB0_DDR DDRB
|
#define PB0_DDR DDRB
|
||||||
#undef PB1
|
#undef PB1
|
||||||
#define PB1_PIN PINB1
|
#define PB1_PIN PINB1
|
||||||
#define PB1_RPORT PINB
|
#define PB1_RPORT PINB
|
||||||
#define PB1_WPORT PORTB
|
#define PB1_WPORT PORTB
|
||||||
#define PB1_PWM NULL
|
#define PB1_PWM NULL
|
||||||
#define PB1_DDR DDRB
|
#define PB1_DDR DDRB
|
||||||
#undef PB2
|
#undef PB2
|
||||||
#define PB2_PIN PINB2
|
#define PB2_PIN PINB2
|
||||||
#define PB2_RPORT PINB
|
#define PB2_RPORT PINB
|
||||||
#define PB2_WPORT PORTB
|
#define PB2_WPORT PORTB
|
||||||
#define PB2_PWM NULL
|
#define PB2_PWM NULL
|
||||||
#define PB2_DDR DDRB
|
#define PB2_DDR DDRB
|
||||||
#undef PB3
|
#undef PB3
|
||||||
#define PB3_PIN PINB3
|
#define PB3_PIN PINB3
|
||||||
#define PB3_RPORT PINB
|
#define PB3_RPORT PINB
|
||||||
#define PB3_WPORT PORTB
|
#define PB3_WPORT PORTB
|
||||||
#define PB3_PWM NULL
|
#define PB3_PWM NULL
|
||||||
#define PB3_DDR DDRB
|
#define PB3_DDR DDRB
|
||||||
#undef PB4
|
#undef PB4
|
||||||
#define PB4_PIN PINB4
|
#define PB4_PIN PINB4
|
||||||
#define PB4_RPORT PINB
|
#define PB4_RPORT PINB
|
||||||
#define PB4_WPORT PORTB
|
#define PB4_WPORT PORTB
|
||||||
#define PB4_PWM NULL
|
#define PB4_PWM NULL
|
||||||
#define PB4_DDR DDRB
|
#define PB4_DDR DDRB
|
||||||
#undef PB5
|
#undef PB5
|
||||||
#define PB5_PIN PINB5
|
#define PB5_PIN PINB5
|
||||||
#define PB5_RPORT PINB
|
#define PB5_RPORT PINB
|
||||||
#define PB5_WPORT PORTB
|
#define PB5_WPORT PORTB
|
||||||
#define PB5_PWM NULL
|
#define PB5_PWM NULL
|
||||||
#define PB5_DDR DDRB
|
#define PB5_DDR DDRB
|
||||||
#undef PB6
|
#undef PB6
|
||||||
#define PB6_PIN PINB6
|
#define PB6_PIN PINB6
|
||||||
#define PB6_RPORT PINB
|
#define PB6_RPORT PINB
|
||||||
#define PB6_WPORT PORTB
|
#define PB6_WPORT PORTB
|
||||||
#define PB6_PWM NULL
|
#define PB6_PWM NULL
|
||||||
#define PB6_DDR DDRB
|
#define PB6_DDR DDRB
|
||||||
#undef PB7
|
#undef PB7
|
||||||
#define PB7_PIN PINB7
|
#define PB7_PIN PINB7
|
||||||
#define PB7_RPORT PINB
|
#define PB7_RPORT PINB
|
||||||
#define PB7_WPORT PORTB
|
#define PB7_WPORT PORTB
|
||||||
#define PB7_PWM NULL
|
#define PB7_PWM NULL
|
||||||
#define PB7_DDR DDRB
|
#define PB7_DDR DDRB
|
||||||
|
|
||||||
#undef PC0
|
#undef PC0
|
||||||
#define PC0_PIN PINC0
|
#define PC0_PIN PINC0
|
||||||
#define PC0_RPORT PINC
|
#define PC0_RPORT PINC
|
||||||
#define PC0_WPORT PORTC
|
#define PC0_WPORT PORTC
|
||||||
#define PC0_PWM NULL
|
#define PC0_PWM NULL
|
||||||
#define PC0_DDR DDRC
|
#define PC0_DDR DDRC
|
||||||
#undef PC1
|
#undef PC1
|
||||||
#define PC1_PIN PINC1
|
#define PC1_PIN PINC1
|
||||||
#define PC1_RPORT PINC
|
#define PC1_RPORT PINC
|
||||||
#define PC1_WPORT PORTC
|
#define PC1_WPORT PORTC
|
||||||
#define PC1_PWM NULL
|
#define PC1_PWM NULL
|
||||||
#define PC1_DDR DDRC
|
#define PC1_DDR DDRC
|
||||||
#undef PC2
|
#undef PC2
|
||||||
#define PC2_PIN PINC2
|
#define PC2_PIN PINC2
|
||||||
#define PC2_RPORT PINC
|
#define PC2_RPORT PINC
|
||||||
#define PC2_WPORT PORTC
|
#define PC2_WPORT PORTC
|
||||||
#define PC2_PWM NULL
|
#define PC2_PWM NULL
|
||||||
#define PC2_DDR DDRC
|
#define PC2_DDR DDRC
|
||||||
#undef PC3
|
#undef PC3
|
||||||
#define PC3_PIN PINC3
|
#define PC3_PIN PINC3
|
||||||
#define PC3_RPORT PINC
|
#define PC3_RPORT PINC
|
||||||
#define PC3_WPORT PORTC
|
#define PC3_WPORT PORTC
|
||||||
#define PC3_PWM NULL
|
#define PC3_PWM NULL
|
||||||
#define PC3_DDR DDRC
|
#define PC3_DDR DDRC
|
||||||
#undef PC4
|
#undef PC4
|
||||||
#define PC4_PIN PINC4
|
#define PC4_PIN PINC4
|
||||||
#define PC4_RPORT PINC
|
#define PC4_RPORT PINC
|
||||||
#define PC4_WPORT PORTC
|
#define PC4_WPORT PORTC
|
||||||
#define PC4_PWM NULL
|
#define PC4_PWM NULL
|
||||||
#define PC4_DDR DDRC
|
#define PC4_DDR DDRC
|
||||||
#undef PC5
|
#undef PC5
|
||||||
#define PC5_PIN PINC5
|
#define PC5_PIN PINC5
|
||||||
#define PC5_RPORT PINC
|
#define PC5_RPORT PINC
|
||||||
#define PC5_WPORT PORTC
|
#define PC5_WPORT PORTC
|
||||||
#define PC5_PWM NULL
|
#define PC5_PWM NULL
|
||||||
#define PC5_DDR DDRC
|
#define PC5_DDR DDRC
|
||||||
#undef PC6
|
#undef PC6
|
||||||
#define PC6_PIN PINC6
|
#define PC6_PIN PINC6
|
||||||
#define PC6_RPORT PINC
|
#define PC6_RPORT PINC
|
||||||
#define PC6_WPORT PORTC
|
#define PC6_WPORT PORTC
|
||||||
#define PC6_PWM NULL
|
#define PC6_PWM NULL
|
||||||
#define PC6_DDR DDRC
|
#define PC6_DDR DDRC
|
||||||
#undef PC7
|
#undef PC7
|
||||||
#define PC7_PIN PINC7
|
#define PC7_PIN PINC7
|
||||||
#define PC7_RPORT PINC
|
#define PC7_RPORT PINC
|
||||||
#define PC7_WPORT PORTC
|
#define PC7_WPORT PORTC
|
||||||
#define PC7_PWM NULL
|
#define PC7_PWM NULL
|
||||||
#define PC7_DDR DDRC
|
#define PC7_DDR DDRC
|
||||||
|
|
||||||
#undef PD0
|
#undef PD0
|
||||||
#define PD0_PIN PIND0
|
#define PD0_PIN PIND0
|
||||||
#define PD0_RPORT PIND
|
#define PD0_RPORT PIND
|
||||||
#define PD0_WPORT PORTD
|
#define PD0_WPORT PORTD
|
||||||
#define PD0_PWM NULL
|
#define PD0_PWM NULL
|
||||||
#define PD0_DDR DDRD
|
#define PD0_DDR DDRD
|
||||||
#undef PD1
|
#undef PD1
|
||||||
#define PD1_PIN PIND1
|
#define PD1_PIN PIND1
|
||||||
#define PD1_RPORT PIND
|
#define PD1_RPORT PIND
|
||||||
#define PD1_WPORT PORTD
|
#define PD1_WPORT PORTD
|
||||||
#define PD1_PWM NULL
|
#define PD1_PWM NULL
|
||||||
#define PD1_DDR DDRD
|
#define PD1_DDR DDRD
|
||||||
#undef PD2
|
#undef PD2
|
||||||
#define PD2_PIN PIND2
|
#define PD2_PIN PIND2
|
||||||
#define PD2_RPORT PIND
|
#define PD2_RPORT PIND
|
||||||
#define PD2_WPORT PORTD
|
#define PD2_WPORT PORTD
|
||||||
#define PD2_PWM NULL
|
#define PD2_PWM NULL
|
||||||
#define PD2_DDR DDRD
|
#define PD2_DDR DDRD
|
||||||
#undef PD3
|
#undef PD3
|
||||||
#define PD3_PIN PIND3
|
#define PD3_PIN PIND3
|
||||||
#define PD3_RPORT PIND
|
#define PD3_RPORT PIND
|
||||||
#define PD3_WPORT PORTD
|
#define PD3_WPORT PORTD
|
||||||
#define PD3_PWM NULL
|
#define PD3_PWM NULL
|
||||||
#define PD3_DDR DDRD
|
#define PD3_DDR DDRD
|
||||||
#undef PD4
|
#undef PD4
|
||||||
#define PD4_PIN PIND4
|
#define PD4_PIN PIND4
|
||||||
#define PD4_RPORT PIND
|
#define PD4_RPORT PIND
|
||||||
#define PD4_WPORT PORTD
|
#define PD4_WPORT PORTD
|
||||||
#define PD4_PWM NULL
|
#define PD4_PWM NULL
|
||||||
#define PD4_DDR DDRD
|
#define PD4_DDR DDRD
|
||||||
#undef PD5
|
#undef PD5
|
||||||
#define PD5_PIN PIND5
|
#define PD5_PIN PIND5
|
||||||
#define PD5_RPORT PIND
|
#define PD5_RPORT PIND
|
||||||
#define PD5_WPORT PORTD
|
#define PD5_WPORT PORTD
|
||||||
#define PD5_PWM NULL
|
#define PD5_PWM NULL
|
||||||
#define PD5_DDR DDRD
|
#define PD5_DDR DDRD
|
||||||
#undef PD6
|
#undef PD6
|
||||||
#define PD6_PIN PIND6
|
#define PD6_PIN PIND6
|
||||||
#define PD6_RPORT PIND
|
#define PD6_RPORT PIND
|
||||||
#define PD6_WPORT PORTD
|
#define PD6_WPORT PORTD
|
||||||
#define PD6_PWM NULL
|
#define PD6_PWM NULL
|
||||||
#define PD6_DDR DDRD
|
#define PD6_DDR DDRD
|
||||||
#undef PD7
|
#undef PD7
|
||||||
#define PD7_PIN PIND7
|
#define PD7_PIN PIND7
|
||||||
#define PD7_RPORT PIND
|
#define PD7_RPORT PIND
|
||||||
#define PD7_WPORT PORTD
|
#define PD7_WPORT PORTD
|
||||||
#define PD7_PWM NULL
|
#define PD7_PWM NULL
|
||||||
#define PD7_DDR DDRD
|
#define PD7_DDR DDRD
|
||||||
|
|
||||||
#undef PE0
|
#undef PE0
|
||||||
#define PE0_PIN PINE0
|
#define PE0_PIN PINE0
|
||||||
#define PE0_RPORT PINE
|
#define PE0_RPORT PINE
|
||||||
#define PE0_WPORT PORTE
|
#define PE0_WPORT PORTE
|
||||||
#define PE0_PWM NULL
|
#define PE0_PWM NULL
|
||||||
#define PE0_DDR DDRE
|
#define PE0_DDR DDRE
|
||||||
#undef PE1
|
#undef PE1
|
||||||
#define PE1_PIN PINE1
|
#define PE1_PIN PINE1
|
||||||
#define PE1_RPORT PINE
|
#define PE1_RPORT PINE
|
||||||
#define PE1_WPORT PORTE
|
#define PE1_WPORT PORTE
|
||||||
#define PE1_PWM NULL
|
#define PE1_PWM NULL
|
||||||
#define PE1_DDR DDRE
|
#define PE1_DDR DDRE
|
||||||
#undef PE2
|
#undef PE2
|
||||||
#define PE2_PIN PINE2
|
#define PE2_PIN PINE2
|
||||||
#define PE2_RPORT PINE
|
#define PE2_RPORT PINE
|
||||||
#define PE2_WPORT PORTE
|
#define PE2_WPORT PORTE
|
||||||
#define PE2_PWM NULL
|
#define PE2_PWM NULL
|
||||||
#define PE2_DDR DDRE
|
#define PE2_DDR DDRE
|
||||||
#undef PE3
|
#undef PE3
|
||||||
#define PE3_PIN PINE3
|
#define PE3_PIN PINE3
|
||||||
#define PE3_RPORT PINE
|
#define PE3_RPORT PINE
|
||||||
#define PE3_WPORT PORTE
|
#define PE3_WPORT PORTE
|
||||||
#define PE3_PWM NULL
|
#define PE3_PWM NULL
|
||||||
#define PE3_DDR DDRE
|
#define PE3_DDR DDRE
|
||||||
#undef PE4
|
#undef PE4
|
||||||
#define PE4_PIN PINE4
|
#define PE4_PIN PINE4
|
||||||
#define PE4_RPORT PINE
|
#define PE4_RPORT PINE
|
||||||
#define PE4_WPORT PORTE
|
#define PE4_WPORT PORTE
|
||||||
#define PE4_PWM NULL
|
#define PE4_PWM NULL
|
||||||
#define PE4_DDR DDRE
|
#define PE4_DDR DDRE
|
||||||
#undef PE5
|
#undef PE5
|
||||||
#define PE5_PIN PINE5
|
#define PE5_PIN PINE5
|
||||||
#define PE5_RPORT PINE
|
#define PE5_RPORT PINE
|
||||||
#define PE5_WPORT PORTE
|
#define PE5_WPORT PORTE
|
||||||
#define PE5_PWM NULL
|
#define PE5_PWM NULL
|
||||||
#define PE5_DDR DDRE
|
#define PE5_DDR DDRE
|
||||||
#undef PE6
|
#undef PE6
|
||||||
#define PE6_PIN PINE6
|
#define PE6_PIN PINE6
|
||||||
#define PE6_RPORT PINE
|
#define PE6_RPORT PINE
|
||||||
#define PE6_WPORT PORTE
|
#define PE6_WPORT PORTE
|
||||||
#define PE6_PWM NULL
|
#define PE6_PWM NULL
|
||||||
#define PE6_DDR DDRE
|
#define PE6_DDR DDRE
|
||||||
#undef PE7
|
#undef PE7
|
||||||
#define PE7_PIN PINE7
|
#define PE7_PIN PINE7
|
||||||
#define PE7_RPORT PINE
|
#define PE7_RPORT PINE
|
||||||
#define PE7_WPORT PORTE
|
#define PE7_WPORT PORTE
|
||||||
#define PE7_PWM NULL
|
#define PE7_PWM NULL
|
||||||
#define PE7_DDR DDRE
|
#define PE7_DDR DDRE
|
||||||
|
|
||||||
#undef PF0
|
#undef PF0
|
||||||
#define PF0_PIN PINF0
|
#define PF0_PIN PINF0
|
||||||
#define PF0_RPORT PINF
|
#define PF0_RPORT PINF
|
||||||
#define PF0_WPORT PORTF
|
#define PF0_WPORT PORTF
|
||||||
#define PF0_PWM NULL
|
#define PF0_PWM NULL
|
||||||
#define PF0_DDR DDRF
|
#define PF0_DDR DDRF
|
||||||
#undef PF1
|
#undef PF1
|
||||||
#define PF1_PIN PINF1
|
#define PF1_PIN PINF1
|
||||||
#define PF1_RPORT PINF
|
#define PF1_RPORT PINF
|
||||||
#define PF1_WPORT PORTF
|
#define PF1_WPORT PORTF
|
||||||
#define PF1_PWM NULL
|
#define PF1_PWM NULL
|
||||||
#define PF1_DDR DDRF
|
#define PF1_DDR DDRF
|
||||||
#undef PF2
|
#undef PF2
|
||||||
#define PF2_PIN PINF2
|
#define PF2_PIN PINF2
|
||||||
#define PF2_RPORT PINF
|
#define PF2_RPORT PINF
|
||||||
#define PF2_WPORT PORTF
|
#define PF2_WPORT PORTF
|
||||||
#define PF2_PWM NULL
|
#define PF2_PWM NULL
|
||||||
#define PF2_DDR DDRF
|
#define PF2_DDR DDRF
|
||||||
#undef PF3
|
#undef PF3
|
||||||
#define PF3_PIN PINF3
|
#define PF3_PIN PINF3
|
||||||
#define PF3_RPORT PINF
|
#define PF3_RPORT PINF
|
||||||
#define PF3_WPORT PORTF
|
#define PF3_WPORT PORTF
|
||||||
#define PF3_PWM NULL
|
#define PF3_PWM NULL
|
||||||
#define PF3_DDR DDRF
|
#define PF3_DDR DDRF
|
||||||
#undef PF4
|
#undef PF4
|
||||||
#define PF4_PIN PINF4
|
#define PF4_PIN PINF4
|
||||||
#define PF4_RPORT PINF
|
#define PF4_RPORT PINF
|
||||||
#define PF4_WPORT PORTF
|
#define PF4_WPORT PORTF
|
||||||
#define PF4_PWM NULL
|
#define PF4_PWM NULL
|
||||||
#define PF4_DDR DDRF
|
#define PF4_DDR DDRF
|
||||||
#undef PF5
|
#undef PF5
|
||||||
#define PF5_PIN PINF5
|
#define PF5_PIN PINF5
|
||||||
#define PF5_RPORT PINF
|
#define PF5_RPORT PINF
|
||||||
#define PF5_WPORT PORTF
|
#define PF5_WPORT PORTF
|
||||||
#define PF5_PWM NULL
|
#define PF5_PWM NULL
|
||||||
#define PF5_DDR DDRF
|
#define PF5_DDR DDRF
|
||||||
#undef PF6
|
#undef PF6
|
||||||
#define PF6_PIN PINF6
|
#define PF6_PIN PINF6
|
||||||
#define PF6_RPORT PINF
|
#define PF6_RPORT PINF
|
||||||
#define PF6_WPORT PORTF
|
#define PF6_WPORT PORTF
|
||||||
#define PF6_PWM NULL
|
#define PF6_PWM NULL
|
||||||
#define PF6_DDR DDRF
|
#define PF6_DDR DDRF
|
||||||
#undef PF7
|
#undef PF7
|
||||||
#define PF7_PIN PINF7
|
#define PF7_PIN PINF7
|
||||||
#define PF7_RPORT PINF
|
#define PF7_RPORT PINF
|
||||||
#define PF7_WPORT PORTF
|
#define PF7_WPORT PORTF
|
||||||
#define PF7_PWM NULL
|
#define PF7_PWM NULL
|
||||||
#define PF7_DDR DDRF
|
#define PF7_DDR DDRF
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DIO0_PIN
|
#ifndef DIO0_PIN
|
||||||
#error pins for this chip not defined in arduino.h! If you write an appropriate pin definition and have this firmware work on your chip, please submit a pull request
|
#error pins for this chip not defined in arduino.h! If you write an appropriate pin definition and have this firmware work on your chip, please submit a pull request
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _ARDUINO_H */
|
#endif /* _ARDUINO_H */
|
||||||
|
|
1140
Marlin/pins.h
1140
Marlin/pins.h
|
@ -1,570 +1,570 @@
|
||||||
#ifndef PINS_H
|
#ifndef PINS_H
|
||||||
#define PINS_H
|
#define PINS_H
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Arduino pin assignment
|
* Arduino pin assignment
|
||||||
*
|
*
|
||||||
* ATMega168
|
* ATMega168
|
||||||
* +-\/-+
|
* +-\/-+
|
||||||
* PC6 1| |28 PC5 (AI 5 / D19)
|
* PC6 1| |28 PC5 (AI 5 / D19)
|
||||||
* (D 0) PD0 2| |27 PC4 (AI 4 / D18)
|
* (D 0) PD0 2| |27 PC4 (AI 4 / D18)
|
||||||
* (D 1) PD1 3| |26 PC3 (AI 3 / D17)
|
* (D 1) PD1 3| |26 PC3 (AI 3 / D17)
|
||||||
* (D 2) PD2 4| |25 PC2 (AI 2 / D16)
|
* (D 2) PD2 4| |25 PC2 (AI 2 / D16)
|
||||||
* PWM+ (D 3) PD3 5| |24 PC1 (AI 1 / D15)
|
* PWM+ (D 3) PD3 5| |24 PC1 (AI 1 / D15)
|
||||||
* (D 4) PD4 6| |23 PC0 (AI 0 / D14)
|
* (D 4) PD4 6| |23 PC0 (AI 0 / D14)
|
||||||
* VCC 7| |22 GND
|
* VCC 7| |22 GND
|
||||||
* GND 8| |21 AREF
|
* GND 8| |21 AREF
|
||||||
* PB6 9| |20 AVCC
|
* PB6 9| |20 AVCC
|
||||||
* PB7 10| |19 PB5 (D 13)
|
* PB7 10| |19 PB5 (D 13)
|
||||||
* PWM+ (D 5) PD5 11| |18 PB4 (D 12)
|
* PWM+ (D 5) PD5 11| |18 PB4 (D 12)
|
||||||
* PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM
|
* PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM
|
||||||
* (D 7) PD7 13| |16 PB2 (D 10) PWM
|
* (D 7) PD7 13| |16 PB2 (D 10) PWM
|
||||||
* (D 8) PB0 14| |15 PB1 (D 9) PWM
|
* (D 8) PB0 14| |15 PB1 (D 9) PWM
|
||||||
* +----+
|
* +----+
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
#if MOTHERBOARD == 0
|
#if MOTHERBOARD == 0
|
||||||
#define KNOWN_BOARD 1
|
#define KNOWN_BOARD 1
|
||||||
|
|
||||||
#ifndef __AVR_ATmega168__
|
#ifndef __AVR_ATmega168__
|
||||||
#error Oops! Make sure you have 'Arduino Diecimila' selected from the boards menu.
|
#error Oops! Make sure you have 'Arduino Diecimila' selected from the boards menu.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define X_STEP_PIN 2
|
#define X_STEP_PIN 2
|
||||||
#define X_DIR_PIN 3
|
#define X_DIR_PIN 3
|
||||||
#define X_ENABLE_PIN -1
|
#define X_ENABLE_PIN -1
|
||||||
#define X_MIN_PIN 4
|
#define X_MIN_PIN 4
|
||||||
#define X_MAX_PIN 9
|
#define X_MAX_PIN 9
|
||||||
|
|
||||||
#define Y_STEP_PIN 10
|
#define Y_STEP_PIN 10
|
||||||
#define Y_DIR_PIN 7
|
#define Y_DIR_PIN 7
|
||||||
#define Y_ENABLE_PIN -1
|
#define Y_ENABLE_PIN -1
|
||||||
#define Y_MIN_PIN 8
|
#define Y_MIN_PIN 8
|
||||||
#define Y_MAX_PIN 13
|
#define Y_MAX_PIN 13
|
||||||
|
|
||||||
#define Z_STEP_PIN 19
|
#define Z_STEP_PIN 19
|
||||||
#define Z_DIR_PIN 18
|
#define Z_DIR_PIN 18
|
||||||
#define Z_ENABLE_PIN 5
|
#define Z_ENABLE_PIN 5
|
||||||
#define Z_MIN_PIN 17
|
#define Z_MIN_PIN 17
|
||||||
#define Z_MAX_PIN 16
|
#define Z_MAX_PIN 16
|
||||||
|
|
||||||
#define E_STEP_PIN 11
|
#define E_STEP_PIN 11
|
||||||
#define E_DIR_PIN 12
|
#define E_DIR_PIN 12
|
||||||
#define E_ENABLE_PIN -1
|
#define E_ENABLE_PIN -1
|
||||||
|
|
||||||
#define SDPOWER -1
|
#define SDPOWER -1
|
||||||
#define SDSS -1
|
#define SDSS -1
|
||||||
#define LED_PIN -1
|
#define LED_PIN -1
|
||||||
#define FAN_PIN -1
|
#define FAN_PIN -1
|
||||||
#define PS_ON_PIN 15
|
#define PS_ON_PIN 15
|
||||||
#define KILL_PIN -1
|
#define KILL_PIN -1
|
||||||
|
|
||||||
#define HEATER_0_PIN 6
|
#define HEATER_0_PIN 6
|
||||||
#define TEMP_0_PIN 0 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
#define TEMP_0_PIN 0 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
||||||
#define HEATER_1_PIN -1
|
#define HEATER_1_PIN -1
|
||||||
#define HEATER_2_PIN -1
|
#define HEATER_2_PIN -1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Sanguino/RepRap Motherboard with direct-drive extruders
|
* Sanguino/RepRap Motherboard with direct-drive extruders
|
||||||
*
|
*
|
||||||
* ATMega644P
|
* ATMega644P
|
||||||
*
|
*
|
||||||
* +---\/---+
|
* +---\/---+
|
||||||
* (D 0) PB0 1| |40 PA0 (AI 0 / D31)
|
* (D 0) PB0 1| |40 PA0 (AI 0 / D31)
|
||||||
* (D 1) PB1 2| |39 PA1 (AI 1 / D30)
|
* (D 1) PB1 2| |39 PA1 (AI 1 / D30)
|
||||||
* INT2 (D 2) PB2 3| |38 PA2 (AI 2 / D29)
|
* INT2 (D 2) PB2 3| |38 PA2 (AI 2 / D29)
|
||||||
* PWM (D 3) PB3 4| |37 PA3 (AI 3 / D28)
|
* PWM (D 3) PB3 4| |37 PA3 (AI 3 / D28)
|
||||||
* PWM (D 4) PB4 5| |36 PA4 (AI 4 / D27)
|
* PWM (D 4) PB4 5| |36 PA4 (AI 4 / D27)
|
||||||
* MOSI (D 5) PB5 6| |35 PA5 (AI 5 / D26)
|
* MOSI (D 5) PB5 6| |35 PA5 (AI 5 / D26)
|
||||||
* MISO (D 6) PB6 7| |34 PA6 (AI 6 / D25)
|
* MISO (D 6) PB6 7| |34 PA6 (AI 6 / D25)
|
||||||
* SCK (D 7) PB7 8| |33 PA7 (AI 7 / D24)
|
* SCK (D 7) PB7 8| |33 PA7 (AI 7 / D24)
|
||||||
* RST 9| |32 AREF
|
* RST 9| |32 AREF
|
||||||
* VCC 10| |31 GND
|
* VCC 10| |31 GND
|
||||||
* GND 11| |30 AVCC
|
* GND 11| |30 AVCC
|
||||||
* XTAL2 12| |29 PC7 (D 23)
|
* XTAL2 12| |29 PC7 (D 23)
|
||||||
* XTAL1 13| |28 PC6 (D 22)
|
* XTAL1 13| |28 PC6 (D 22)
|
||||||
* RX0 (D 8) PD0 14| |27 PC5 (D 21) TDI
|
* RX0 (D 8) PD0 14| |27 PC5 (D 21) TDI
|
||||||
* TX0 (D 9) PD1 15| |26 PC4 (D 20) TDO
|
* TX0 (D 9) PD1 15| |26 PC4 (D 20) TDO
|
||||||
* INT0 RX1 (D 10) PD2 16| |25 PC3 (D 19) TMS
|
* INT0 RX1 (D 10) PD2 16| |25 PC3 (D 19) TMS
|
||||||
* INT1 TX1 (D 11) PD3 17| |24 PC2 (D 18) TCK
|
* INT1 TX1 (D 11) PD3 17| |24 PC2 (D 18) TCK
|
||||||
* PWM (D 12) PD4 18| |23 PC1 (D 17) SDA
|
* PWM (D 12) PD4 18| |23 PC1 (D 17) SDA
|
||||||
* PWM (D 13) PD5 19| |22 PC0 (D 16) SCL
|
* PWM (D 13) PD5 19| |22 PC0 (D 16) SCL
|
||||||
* PWM (D 14) PD6 20| |21 PD7 (D 15) PWM
|
* PWM (D 14) PD6 20| |21 PD7 (D 15) PWM
|
||||||
* +--------+
|
* +--------+
|
||||||
*
|
*
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
#if MOTHERBOARD == 1
|
#if MOTHERBOARD == 1
|
||||||
#define KNOWN_BOARD 1
|
#define KNOWN_BOARD 1
|
||||||
|
|
||||||
#ifndef __AVR_ATmega644P__
|
#ifndef __AVR_ATmega644P__
|
||||||
#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu.
|
#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define X_STEP_PIN 15
|
#define X_STEP_PIN 15
|
||||||
#define X_DIR_PIN 18
|
#define X_DIR_PIN 18
|
||||||
#define X_ENABLE_PIN 19
|
#define X_ENABLE_PIN 19
|
||||||
#define X_MIN_PIN 20
|
#define X_MIN_PIN 20
|
||||||
#define X_MAX_PIN 21
|
#define X_MAX_PIN 21
|
||||||
|
|
||||||
#define Y_STEP_PIN 23
|
#define Y_STEP_PIN 23
|
||||||
#define Y_DIR_PIN 22
|
#define Y_DIR_PIN 22
|
||||||
#define Y_ENABLE_PIN 19
|
#define Y_ENABLE_PIN 19
|
||||||
#define Y_MIN_PIN 25
|
#define Y_MIN_PIN 25
|
||||||
#define Y_MAX_PIN 26
|
#define Y_MAX_PIN 26
|
||||||
|
|
||||||
#define Z_STEP_PIN 29
|
#define Z_STEP_PIN 29
|
||||||
#define Z_DIR_PIN 30
|
#define Z_DIR_PIN 30
|
||||||
#define Z_ENABLE_PIN 31
|
#define Z_ENABLE_PIN 31
|
||||||
#define Z_MIN_PIN 2
|
#define Z_MIN_PIN 2
|
||||||
#define Z_MAX_PIN 1
|
#define Z_MAX_PIN 1
|
||||||
|
|
||||||
#define E_STEP_PIN 12
|
#define E_STEP_PIN 12
|
||||||
#define E_DIR_PIN 16
|
#define E_DIR_PIN 16
|
||||||
#define E_ENABLE_PIN 3
|
#define E_ENABLE_PIN 3
|
||||||
|
|
||||||
#define SDPOWER -1
|
#define SDPOWER -1
|
||||||
#define SDSS -1
|
#define SDSS -1
|
||||||
#define LED_PIN 0
|
#define LED_PIN 0
|
||||||
#define FAN_PIN -1
|
#define FAN_PIN -1
|
||||||
#define PS_ON_PIN -1
|
#define PS_ON_PIN -1
|
||||||
#define KILL_PIN -1
|
#define KILL_PIN -1
|
||||||
|
|
||||||
#define HEATER_0_PIN 14
|
#define HEATER_0_PIN 14
|
||||||
#define TEMP_0_PIN 4 //D27 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
#define TEMP_0_PIN 4 //D27 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
||||||
#define HEATER_1_PIN -1
|
#define HEATER_1_PIN -1
|
||||||
#define HEATER_2_PIN -1
|
#define HEATER_2_PIN -1
|
||||||
/* Unused (1) (2) (3) 4 5 6 7 8 9 10 11 12 13 (14) (15) (16) 17 (18) (19) (20) (21) (22) (23) 24 (25) (26) (27) 28 (29) (30) (31) */
|
/* Unused (1) (2) (3) 4 5 6 7 8 9 10 11 12 13 (14) (15) (16) 17 (18) (19) (20) (21) (22) (23) 24 (25) (26) (27) 28 (29) (30) (31) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* RepRap Motherboard ****---NOOOOOO RS485/EXTRUDER CONTROLLER!!!!!!!!!!!!!!!!!---*******
|
* RepRap Motherboard ****---NOOOOOO RS485/EXTRUDER CONTROLLER!!!!!!!!!!!!!!!!!---*******
|
||||||
*
|
*
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
#if MOTHERBOARD == 2
|
#if MOTHERBOARD == 2
|
||||||
#define KNOWN_BOARD 1
|
#define KNOWN_BOARD 1
|
||||||
|
|
||||||
#ifndef __AVR_ATmega644P__
|
#ifndef __AVR_ATmega644P__
|
||||||
#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu.
|
#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define X_STEP_PIN 15
|
#define X_STEP_PIN 15
|
||||||
#define X_DIR_PIN 18
|
#define X_DIR_PIN 18
|
||||||
#define X_ENABLE_PIN 19
|
#define X_ENABLE_PIN 19
|
||||||
#define X_MIN_PIN 20
|
#define X_MIN_PIN 20
|
||||||
#define X_MAX_PIN 21
|
#define X_MAX_PIN 21
|
||||||
|
|
||||||
#define Y_STEP_PIN 23
|
#define Y_STEP_PIN 23
|
||||||
#define Y_DIR_PIN 22
|
#define Y_DIR_PIN 22
|
||||||
#define Y_ENABLE_PIN 24
|
#define Y_ENABLE_PIN 24
|
||||||
#define Y_MIN_PIN 25
|
#define Y_MIN_PIN 25
|
||||||
#define Y_MAX_PIN 26
|
#define Y_MAX_PIN 26
|
||||||
|
|
||||||
#define Z_STEP_PINN 27
|
#define Z_STEP_PINN 27
|
||||||
#define Z_DIR_PINN 28
|
#define Z_DIR_PINN 28
|
||||||
#define Z_ENABLE_PIN 29
|
#define Z_ENABLE_PIN 29
|
||||||
#define Z_MIN_PIN 30
|
#define Z_MIN_PIN 30
|
||||||
#define Z_MAX_PIN 31
|
#define Z_MAX_PIN 31
|
||||||
|
|
||||||
#define E_STEP_PIN 17
|
#define E_STEP_PIN 17
|
||||||
#define E_DIR_PIN 16
|
#define E_DIR_PIN 16
|
||||||
#define E_ENABLE_PIN -1
|
#define E_ENABLE_PIN -1
|
||||||
|
|
||||||
#define SDPOWER -1
|
#define SDPOWER -1
|
||||||
#define SDSS 4
|
#define SDSS 4
|
||||||
#define LED_PIN 0
|
#define LED_PIN 0
|
||||||
|
|
||||||
#define SD_CARD_WRITE 2
|
#define SD_CARD_WRITE 2
|
||||||
#define SD_CARD_DETECT 3
|
#define SD_CARD_DETECT 3
|
||||||
#define SD_CARD_SELECT 4
|
#define SD_CARD_SELECT 4
|
||||||
|
|
||||||
//our RS485 pins
|
//our RS485 pins
|
||||||
#define TX_ENABLE_PIN 12
|
#define TX_ENABLE_PIN 12
|
||||||
#define RX_ENABLE_PIN 13
|
#define RX_ENABLE_PIN 13
|
||||||
|
|
||||||
//pin for controlling the PSU.
|
//pin for controlling the PSU.
|
||||||
#define PS_ON_PIN 14
|
#define PS_ON_PIN 14
|
||||||
|
|
||||||
#define FAN_PIN -1
|
#define FAN_PIN -1
|
||||||
#define KILL_PIN -1
|
#define KILL_PIN -1
|
||||||
|
|
||||||
#define HEATER_0_PIN -1
|
#define HEATER_0_PIN -1
|
||||||
#define TEMP_0_PIN -1 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
#define TEMP_0_PIN -1 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
||||||
#define HEATER_1_PIN -1
|
#define HEATER_1_PIN -1
|
||||||
#define HEATER_2_PIN -1
|
#define HEATER_2_PIN -1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Arduino Mega pin assignment
|
* Arduino Mega pin assignment
|
||||||
*
|
*
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
#if MOTHERBOARD == 33
|
#if MOTHERBOARD == 33
|
||||||
#define MOTHERBOARD 3
|
#define MOTHERBOARD 3
|
||||||
#define RAMPS_V_1_3
|
#define RAMPS_V_1_3
|
||||||
#endif
|
#endif
|
||||||
#if MOTHERBOARD == 3
|
#if MOTHERBOARD == 3
|
||||||
#define KNOWN_BOARD 1
|
#define KNOWN_BOARD 1
|
||||||
|
|
||||||
//////////////////FIX THIS//////////////
|
//////////////////FIX THIS//////////////
|
||||||
#ifndef __AVR_ATmega1280__
|
#ifndef __AVR_ATmega1280__
|
||||||
#ifndef __AVR_ATmega2560__
|
#ifndef __AVR_ATmega2560__
|
||||||
#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu.
|
#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu.
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// uncomment one of the following lines for RAMPS v1.3 or v1.0, comment both for v1.2 or 1.1
|
// uncomment one of the following lines for RAMPS v1.3 or v1.0, comment both for v1.2 or 1.1
|
||||||
// #define RAMPS_V_1_3
|
// #define RAMPS_V_1_3
|
||||||
// #define RAMPS_V_1_0
|
// #define RAMPS_V_1_0
|
||||||
|
|
||||||
#ifdef RAMPS_V_1_3
|
#ifdef RAMPS_V_1_3
|
||||||
|
|
||||||
#define X_STEP_PIN 54
|
#define X_STEP_PIN 54
|
||||||
#define X_DIR_PIN 55
|
#define X_DIR_PIN 55
|
||||||
#define X_ENABLE_PIN 38
|
#define X_ENABLE_PIN 38
|
||||||
#define X_MIN_PIN 3
|
#define X_MIN_PIN 3
|
||||||
#define X_MAX_PIN -1 //2 //Max endstops default to disabled "-1", set to commented value to enable.
|
#define X_MAX_PIN -1 //2 //Max endstops default to disabled "-1", set to commented value to enable.
|
||||||
|
|
||||||
#define Y_STEP_PIN 60
|
#define Y_STEP_PIN 60
|
||||||
#define Y_DIR_PIN 61
|
#define Y_DIR_PIN 61
|
||||||
#define Y_ENABLE_PIN 56
|
#define Y_ENABLE_PIN 56
|
||||||
#define Y_MIN_PIN 14
|
#define Y_MIN_PIN 14
|
||||||
#define Y_MAX_PIN -1 //15
|
#define Y_MAX_PIN -1 //15
|
||||||
|
|
||||||
#define Z_STEP_PIN 46
|
#define Z_STEP_PIN 46
|
||||||
#define Z_DIR_PIN 48
|
#define Z_DIR_PIN 48
|
||||||
#define Z_ENABLE_PIN 62
|
#define Z_ENABLE_PIN 62
|
||||||
#define Z_MIN_PIN 18
|
#define Z_MIN_PIN 18
|
||||||
#define Z_MAX_PIN -1 //19
|
#define Z_MAX_PIN -1 //19
|
||||||
|
|
||||||
#define E_STEP_PIN 26
|
#define E_STEP_PIN 26
|
||||||
#define E_DIR_PIN 28
|
#define E_DIR_PIN 28
|
||||||
#define E_ENABLE_PIN 24
|
#define E_ENABLE_PIN 24
|
||||||
|
|
||||||
#define SDPOWER -1
|
#define SDPOWER -1
|
||||||
#define SDSS 53
|
#define SDSS 53
|
||||||
#define LED_PIN 13
|
#define LED_PIN 13
|
||||||
#define FAN_PIN 9
|
#define FAN_PIN 9
|
||||||
#define PS_ON_PIN 12
|
#define PS_ON_PIN 12
|
||||||
#define KILL_PIN -1
|
#define KILL_PIN -1
|
||||||
|
|
||||||
#define HEATER_0_PIN 10
|
#define HEATER_0_PIN 10
|
||||||
#define HEATER_1_PIN 8
|
#define HEATER_1_PIN 8
|
||||||
#define HEATER_2_PIN -1
|
#define HEATER_2_PIN -1
|
||||||
#define TEMP_0_PIN 13 // ANALOG NUMBERING
|
#define TEMP_0_PIN 13 // ANALOG NUMBERING
|
||||||
#define TEMP_1_PIN 14 // ANALOG NUMBERING
|
#define TEMP_1_PIN 14 // ANALOG NUMBERING
|
||||||
#define TEMP_2_PIN -1 // ANALOG NUMBERING
|
#define TEMP_2_PIN -1 // ANALOG NUMBERING
|
||||||
|
|
||||||
|
|
||||||
#else // RAMPS_V_1_1 or RAMPS_V_1_2 as default
|
#else // RAMPS_V_1_1 or RAMPS_V_1_2 as default
|
||||||
|
|
||||||
#define X_STEP_PIN 26
|
#define X_STEP_PIN 26
|
||||||
#define X_DIR_PIN 28
|
#define X_DIR_PIN 28
|
||||||
#define X_ENABLE_PIN 24
|
#define X_ENABLE_PIN 24
|
||||||
#define X_MIN_PIN 3
|
#define X_MIN_PIN 3
|
||||||
#define X_MAX_PIN -1 //2
|
#define X_MAX_PIN -1 //2
|
||||||
|
|
||||||
#define Y_STEP_PIN 38
|
#define Y_STEP_PIN 38
|
||||||
#define Y_DIR_PIN 40
|
#define Y_DIR_PIN 40
|
||||||
#define Y_ENABLE_PIN 36
|
#define Y_ENABLE_PIN 36
|
||||||
#define Y_MIN_PIN 16
|
#define Y_MIN_PIN 16
|
||||||
#define Y_MAX_PIN -1 //17
|
#define Y_MAX_PIN -1 //17
|
||||||
|
|
||||||
#define Z_STEP_PIN 44
|
#define Z_STEP_PIN 44
|
||||||
#define Z_DIR_PIN 46
|
#define Z_DIR_PIN 46
|
||||||
#define Z_ENABLE_PIN 42
|
#define Z_ENABLE_PIN 42
|
||||||
#define Z_MIN_PIN 18
|
#define Z_MIN_PIN 18
|
||||||
#define Z_MAX_PIN -1 //19
|
#define Z_MAX_PIN -1 //19
|
||||||
|
|
||||||
#define E_STEP_PIN 32
|
#define E_STEP_PIN 32
|
||||||
#define E_DIR_PIN 34
|
#define E_DIR_PIN 34
|
||||||
#define E_ENABLE_PIN 30
|
#define E_ENABLE_PIN 30
|
||||||
|
|
||||||
#define SDPOWER 48
|
#define SDPOWER 48
|
||||||
#define SDSS 53
|
#define SDSS 53
|
||||||
#define LED_PIN 13
|
#define LED_PIN 13
|
||||||
#define PS_ON_PIN -1
|
#define PS_ON_PIN -1
|
||||||
#define KILL_PIN -1
|
#define KILL_PIN -1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef RAMPS_V_1_0 // RAMPS_V_1_0
|
#ifdef RAMPS_V_1_0 // RAMPS_V_1_0
|
||||||
#define HEATER_0_PIN 12 // RAMPS 1.0
|
#define HEATER_0_PIN 12 // RAMPS 1.0
|
||||||
#define HEATER_1_PIN -1 // RAMPS 1.0
|
#define HEATER_1_PIN -1 // RAMPS 1.0
|
||||||
#define FAN_PIN 11 // RAMPS 1.0
|
#define FAN_PIN 11 // RAMPS 1.0
|
||||||
|
|
||||||
#else // RAMPS_V_1_1 or RAMPS_V_1_2
|
#else // RAMPS_V_1_1 or RAMPS_V_1_2
|
||||||
#define HEATER_0_PIN 10 // RAMPS 1.1
|
#define HEATER_0_PIN 10 // RAMPS 1.1
|
||||||
#define HEATER_1_PIN 8 // RAMPS 1.1
|
#define HEATER_1_PIN 8 // RAMPS 1.1
|
||||||
#define FAN_PIN 9 // RAMPS 1.1
|
#define FAN_PIN 9 // RAMPS 1.1
|
||||||
#endif
|
#endif
|
||||||
#define HEATER_2_PIN -1
|
#define HEATER_2_PIN -1
|
||||||
#define TEMP_0_PIN 2 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
#define TEMP_0_PIN 2 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
||||||
#define TEMP_1_PIN 1 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
#define TEMP_1_PIN 1 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
||||||
#define TEMP_2_PIN -1 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
#define TEMP_2_PIN -1 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SPI for Max6675 Thermocouple
|
// SPI for Max6675 Thermocouple
|
||||||
|
|
||||||
#ifndef SDSUPPORT
|
#ifndef SDSUPPORT
|
||||||
// these pins are defined in the SD library if building with SD support #define SCK_PIN 52
|
// these pins are defined in the SD library if building with SD support #define SCK_PIN 52
|
||||||
#define MISO_PIN 50
|
#define MISO_PIN 50
|
||||||
#define MOSI_PIN 51
|
#define MOSI_PIN 51
|
||||||
#define MAX6675_SS 53
|
#define MAX6675_SS 53
|
||||||
#else
|
#else
|
||||||
#define MAX6675_SS 49
|
#define MAX6675_SS 49
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Duemilanove w/ ATMega328P pin assignment
|
* Duemilanove w/ ATMega328P pin assignment
|
||||||
*
|
*
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
#if MOTHERBOARD == 4
|
#if MOTHERBOARD == 4
|
||||||
#define KNOWN_BOARD 1
|
#define KNOWN_BOARD 1
|
||||||
|
|
||||||
#ifndef __AVR_ATmega328P__
|
#ifndef __AVR_ATmega328P__
|
||||||
#error Oops! Make sure you have 'Arduino Duemilanove w/ ATMega328' selected from the 'Tools -> Boards' menu.
|
#error Oops! Make sure you have 'Arduino Duemilanove w/ ATMega328' selected from the 'Tools -> Boards' menu.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define X_STEP_PIN 19
|
#define X_STEP_PIN 19
|
||||||
#define X_DIR_PIN 18
|
#define X_DIR_PIN 18
|
||||||
#define X_ENABLE_PIN -1
|
#define X_ENABLE_PIN -1
|
||||||
#define X_MIN_PIN 17
|
#define X_MIN_PIN 17
|
||||||
#define X_MAX_PIN -1
|
#define X_MAX_PIN -1
|
||||||
|
|
||||||
#define Y_STEP_PIN 10
|
#define Y_STEP_PIN 10
|
||||||
#define Y_DIR_PIN 7
|
#define Y_DIR_PIN 7
|
||||||
#define Y_ENABLE_PIN -1
|
#define Y_ENABLE_PIN -1
|
||||||
#define Y_MIN_PIN 8
|
#define Y_MIN_PIN 8
|
||||||
#define Y_MAX_PIN -1
|
#define Y_MAX_PIN -1
|
||||||
|
|
||||||
#define Z_STEP_PIN 13
|
#define Z_STEP_PIN 13
|
||||||
#define Z_DIR_PIN 3
|
#define Z_DIR_PIN 3
|
||||||
#define Z_ENABLE_PIN 2
|
#define Z_ENABLE_PIN 2
|
||||||
#define Z_MIN_PIN 4
|
#define Z_MIN_PIN 4
|
||||||
#define Z_MAX_PIN -1
|
#define Z_MAX_PIN -1
|
||||||
|
|
||||||
#define E_STEP_PIN 11
|
#define E_STEP_PIN 11
|
||||||
#define E_DIR_PIN 12
|
#define E_DIR_PIN 12
|
||||||
#define E_ENABLE_PIN -1
|
#define E_ENABLE_PIN -1
|
||||||
|
|
||||||
#define SDPOWER -1
|
#define SDPOWER -1
|
||||||
#define SDSS -1
|
#define SDSS -1
|
||||||
#define LED_PIN -1
|
#define LED_PIN -1
|
||||||
#define FAN_PIN 5
|
#define FAN_PIN 5
|
||||||
#define PS_ON_PIN -1
|
#define PS_ON_PIN -1
|
||||||
#define KILL_PIN -1
|
#define KILL_PIN -1
|
||||||
|
|
||||||
#define HEATER_0_PIN 6
|
#define HEATER_0_PIN 6
|
||||||
#define TEMP_0_PIN 0 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
#define TEMP_0_PIN 0 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!!
|
||||||
#define HEATER_1_PIN -1
|
#define HEATER_1_PIN -1
|
||||||
#define HEATER_2_PIN -1
|
#define HEATER_2_PIN -1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Gen6 pin assignment
|
* Gen6 pin assignment
|
||||||
*
|
*
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
#if MOTHERBOARD == 5
|
#if MOTHERBOARD == 5
|
||||||
#define KNOWN_BOARD 1
|
#define KNOWN_BOARD 1
|
||||||
|
|
||||||
#ifndef __AVR_ATmega644P__
|
#ifndef __AVR_ATmega644P__
|
||||||
#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu.
|
#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//x axis pins
|
//x axis pins
|
||||||
#define X_STEP_PIN 15
|
#define X_STEP_PIN 15
|
||||||
#define X_DIR_PIN 18
|
#define X_DIR_PIN 18
|
||||||
#define X_ENABLE_PIN 19
|
#define X_ENABLE_PIN 19
|
||||||
#define X_MIN_PIN 20
|
#define X_MIN_PIN 20
|
||||||
#define X_MAX_PIN -1
|
#define X_MAX_PIN -1
|
||||||
|
|
||||||
//y axis pins
|
//y axis pins
|
||||||
#define Y_STEP_PIN 23
|
#define Y_STEP_PIN 23
|
||||||
#define Y_DIR_PIN 22
|
#define Y_DIR_PIN 22
|
||||||
#define Y_ENABLE_PIN 24
|
#define Y_ENABLE_PIN 24
|
||||||
#define Y_MIN_PIN 25
|
#define Y_MIN_PIN 25
|
||||||
#define Y_MAX_PIN -1
|
#define Y_MAX_PIN -1
|
||||||
|
|
||||||
//z axis pins
|
//z axis pins
|
||||||
#define Z_STEP_PIN 27
|
#define Z_STEP_PIN 27
|
||||||
#define Z_DIR_PIN 28
|
#define Z_DIR_PIN 28
|
||||||
#define Z_ENABLE_PIN 29
|
#define Z_ENABLE_PIN 29
|
||||||
#define Z_MIN_PIN 30
|
#define Z_MIN_PIN 30
|
||||||
#define Z_MAX_PIN -1
|
#define Z_MAX_PIN -1
|
||||||
|
|
||||||
//extruder pins
|
//extruder pins
|
||||||
#define E_STEP_PIN 4 //Edited @ EJE Electronics 20100715
|
#define E_STEP_PIN 4 //Edited @ EJE Electronics 20100715
|
||||||
#define E_DIR_PIN 2 //Edited @ EJE Electronics 20100715
|
#define E_DIR_PIN 2 //Edited @ EJE Electronics 20100715
|
||||||
#define E_ENABLE_PIN 3 //Added @ EJE Electronics 20100715
|
#define E_ENABLE_PIN 3 //Added @ EJE Electronics 20100715
|
||||||
#define TEMP_0_PIN 5 //changed @ rkoeppl 20110410
|
#define TEMP_0_PIN 5 //changed @ rkoeppl 20110410
|
||||||
#define HEATER_0_PIN 14 //changed @ rkoeppl 20110410
|
#define HEATER_0_PIN 14 //changed @ rkoeppl 20110410
|
||||||
#define HEATER_1_PIN -1 //changed @ rkoeppl 20110410
|
#define HEATER_1_PIN -1 //changed @ rkoeppl 20110410
|
||||||
#define HEATER_2_PIN -1
|
#define HEATER_2_PIN -1
|
||||||
|
|
||||||
#define SDPOWER -1
|
#define SDPOWER -1
|
||||||
#define SDSS 17
|
#define SDSS 17
|
||||||
#define LED_PIN -1 //changed @ rkoeppl 20110410
|
#define LED_PIN -1 //changed @ rkoeppl 20110410
|
||||||
#define TEMP_1_PIN -1 //changed @ rkoeppl 20110410
|
#define TEMP_1_PIN -1 //changed @ rkoeppl 20110410
|
||||||
#define TEMP_2_PIN -1
|
#define TEMP_2_PIN -1
|
||||||
#define FAN_PIN -1 //changed @ rkoeppl 20110410
|
#define FAN_PIN -1 //changed @ rkoeppl 20110410
|
||||||
#define PS_ON_PIN -1 //changed @ rkoeppl 20110410
|
#define PS_ON_PIN -1 //changed @ rkoeppl 20110410
|
||||||
//our pin for debugging.
|
//our pin for debugging.
|
||||||
|
|
||||||
#define DEBUG_PIN 0
|
#define DEBUG_PIN 0
|
||||||
|
|
||||||
//our RS485 pins
|
//our RS485 pins
|
||||||
#define TX_ENABLE_PIN 12
|
#define TX_ENABLE_PIN 12
|
||||||
#define RX_ENABLE_PIN 13
|
#define RX_ENABLE_PIN 13
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* Sanguinololu pin assignment
|
* Sanguinololu pin assignment
|
||||||
*
|
*
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
#if MOTHERBOARD == 62
|
#if MOTHERBOARD == 62
|
||||||
#define MOTHERBOARD 6
|
#define MOTHERBOARD 6
|
||||||
#define SANGUINOLOLU_V_1_2
|
#define SANGUINOLOLU_V_1_2
|
||||||
#endif
|
#endif
|
||||||
#if MOTHERBOARD == 6
|
#if MOTHERBOARD == 6
|
||||||
#define KNOWN_BOARD 1
|
#define KNOWN_BOARD 1
|
||||||
#ifndef __AVR_ATmega644P__
|
#ifndef __AVR_ATmega644P__
|
||||||
#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu.
|
#error Oops! Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define X_STEP_PIN 15
|
#define X_STEP_PIN 15
|
||||||
#define X_DIR_PIN 21
|
#define X_DIR_PIN 21
|
||||||
#define X_MIN_PIN 18
|
#define X_MIN_PIN 18
|
||||||
#define X_MAX_PIN -2
|
#define X_MAX_PIN -2
|
||||||
|
|
||||||
#define Y_STEP_PIN 22
|
#define Y_STEP_PIN 22
|
||||||
#define Y_DIR_PIN 23
|
#define Y_DIR_PIN 23
|
||||||
#define Y_MIN_PIN 19
|
#define Y_MIN_PIN 19
|
||||||
#define Y_MAX_PIN -1
|
#define Y_MAX_PIN -1
|
||||||
|
|
||||||
#define Z_STEP_PIN 3
|
#define Z_STEP_PIN 3
|
||||||
#define Z_DIR_PIN 2
|
#define Z_DIR_PIN 2
|
||||||
#define Z_MIN_PIN 20
|
#define Z_MIN_PIN 20
|
||||||
#define Z_MAX_PIN -1
|
#define Z_MAX_PIN -1
|
||||||
|
|
||||||
#define E_STEP_PIN 1
|
#define E_STEP_PIN 1
|
||||||
#define E_DIR_PIN 0
|
#define E_DIR_PIN 0
|
||||||
|
|
||||||
#define LED_PIN -1
|
#define LED_PIN -1
|
||||||
|
|
||||||
#define FAN_PIN -1
|
#define FAN_PIN -1
|
||||||
|
|
||||||
#define PS_ON_PIN -1
|
#define PS_ON_PIN -1
|
||||||
#define KILL_PIN -1
|
#define KILL_PIN -1
|
||||||
|
|
||||||
#define HEATER_0_PIN 13 // (extruder)
|
#define HEATER_0_PIN 13 // (extruder)
|
||||||
|
|
||||||
#ifdef SANGUINOLOLU_V_1_2
|
#ifdef SANGUINOLOLU_V_1_2
|
||||||
|
|
||||||
#define HEATER_1_PIN 12 // (bed)
|
#define HEATER_1_PIN 12 // (bed)
|
||||||
#define X_ENABLE_PIN 14
|
#define X_ENABLE_PIN 14
|
||||||
#define Y_ENABLE_PIN 14
|
#define Y_ENABLE_PIN 14
|
||||||
#define Z_ENABLE_PIN 26
|
#define Z_ENABLE_PIN 26
|
||||||
#define E_ENABLE_PIN 14
|
#define E_ENABLE_PIN 14
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define HEATER_1_PIN 14 // (bed)
|
#define HEATER_1_PIN 14 // (bed)
|
||||||
#define X_ENABLE_PIN -1
|
#define X_ENABLE_PIN -1
|
||||||
#define Y_ENABLE_PIN -1
|
#define Y_ENABLE_PIN -1
|
||||||
#define Z_ENABLE_PIN -1
|
#define Z_ENABLE_PIN -1
|
||||||
#define E_ENABLE_PIN -1
|
#define E_ENABLE_PIN -1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TEMP_0_PIN 7 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 33 extruder)
|
#define TEMP_0_PIN 7 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 33 extruder)
|
||||||
#define TEMP_1_PIN 6 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 34 bed)
|
#define TEMP_1_PIN 6 // MUST USE ANALOG INPUT NUMBERING NOT DIGITAL OUTPUT NUMBERING!!!!!!!!! (pin 34 bed)
|
||||||
#define TEMP_2_PIN -1
|
#define TEMP_2_PIN -1
|
||||||
#define SDPOWER -1
|
#define SDPOWER -1
|
||||||
#define SDSS 31
|
#define SDSS 31
|
||||||
#define HEATER_2_PIN -1
|
#define HEATER_2_PIN -1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if MOTHERBOARD == 7
|
#if MOTHERBOARD == 7
|
||||||
#define KNOWN_BOARD
|
#define KNOWN_BOARD
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
* Ultimaker pin assignment
|
* Ultimaker pin assignment
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
||||||
#ifndef __AVR_ATmega1280__
|
#ifndef __AVR_ATmega1280__
|
||||||
#ifndef __AVR_ATmega2560__
|
#ifndef __AVR_ATmega2560__
|
||||||
#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu.
|
#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu.
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define X_STEP_PIN 25
|
#define X_STEP_PIN 25
|
||||||
#define X_DIR_PIN 23
|
#define X_DIR_PIN 23
|
||||||
#define X_MIN_PIN 22
|
#define X_MIN_PIN 22
|
||||||
#define X_MAX_PIN 24
|
#define X_MAX_PIN 24
|
||||||
#define X_ENABLE_PIN 27
|
#define X_ENABLE_PIN 27
|
||||||
|
|
||||||
#define Y_STEP_PIN 31
|
#define Y_STEP_PIN 31
|
||||||
#define Y_DIR_PIN 33
|
#define Y_DIR_PIN 33
|
||||||
#define Y_MIN_PIN 26
|
#define Y_MIN_PIN 26
|
||||||
#define Y_MAX_PIN 28
|
#define Y_MAX_PIN 28
|
||||||
#define Y_ENABLE_PIN 29
|
#define Y_ENABLE_PIN 29
|
||||||
|
|
||||||
#define Z_STEP_PIN 37
|
#define Z_STEP_PIN 37
|
||||||
#define Z_DIR_PIN 39
|
#define Z_DIR_PIN 39
|
||||||
#define Z_MIN_PIN 30
|
#define Z_MIN_PIN 30
|
||||||
#define Z_MAX_PIN 32
|
#define Z_MAX_PIN 32
|
||||||
#define Z_ENABLE_PIN 35
|
#define Z_ENABLE_PIN 35
|
||||||
|
|
||||||
#define HEATER_1_PIN 4
|
#define HEATER_1_PIN 4
|
||||||
#define TEMP_1_PIN 11
|
#define TEMP_1_PIN 11
|
||||||
|
|
||||||
#define EXTRUDER_0_STEP_PIN 43
|
#define EXTRUDER_0_STEP_PIN 43
|
||||||
#define EXTRUDER_0_DIR_PIN 45
|
#define EXTRUDER_0_DIR_PIN 45
|
||||||
#define EXTRUDER_0_ENABLE_PIN 41
|
#define EXTRUDER_0_ENABLE_PIN 41
|
||||||
#define HEATER_0_PIN 2
|
#define HEATER_0_PIN 2
|
||||||
#define TEMP_0_PIN 8
|
#define TEMP_0_PIN 8
|
||||||
|
|
||||||
#define EXTRUDER_1_STEP_PIN 49
|
#define EXTRUDER_1_STEP_PIN 49
|
||||||
#define EXTRUDER_1_DIR_PIN 47
|
#define EXTRUDER_1_DIR_PIN 47
|
||||||
#define EXTRUDER_1_ENABLE_PIN 51
|
#define EXTRUDER_1_ENABLE_PIN 51
|
||||||
#define EXTRUDER_1_HEATER_PIN 3
|
#define EXTRUDER_1_HEATER_PIN 3
|
||||||
#define EXTRUDER_1_TEMPERATURE_PIN 10
|
#define EXTRUDER_1_TEMPERATURE_PIN 10
|
||||||
#define HEATER_2_PIN 51
|
#define HEATER_2_PIN 51
|
||||||
#define TEMP_2_PIN 3
|
#define TEMP_2_PIN 3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define E_STEP_PIN EXTRUDER_0_STEP_PIN
|
#define E_STEP_PIN EXTRUDER_0_STEP_PIN
|
||||||
#define E_DIR_PIN EXTRUDER_0_DIR_PIN
|
#define E_DIR_PIN EXTRUDER_0_DIR_PIN
|
||||||
#define E_ENABLE_PIN EXTRUDER_0_ENABLE_PIN
|
#define E_ENABLE_PIN EXTRUDER_0_ENABLE_PIN
|
||||||
|
|
||||||
#define SDPOWER -1
|
#define SDPOWER -1
|
||||||
#define SDSS 53
|
#define SDSS 53
|
||||||
#define LED_PIN 13
|
#define LED_PIN 13
|
||||||
#define FAN_PIN 7
|
#define FAN_PIN 7
|
||||||
#define PS_ON_PIN 12
|
#define PS_ON_PIN 12
|
||||||
#define KILL_PIN -1
|
#define KILL_PIN -1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef KNOWN_BOARD
|
#ifndef KNOWN_BOARD
|
||||||
#error Unknown MOTHERBOARD value in configuration.h
|
#error Unknown MOTHERBOARD value in configuration.h
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//List of pins which to ignore when asked to change by gcode, 0 and 1 are RX and TX, do not mess with those!
|
//List of pins which to ignore when asked to change by gcode, 0 and 1 are RX and TX, do not mess with those!
|
||||||
#define SENSITIVE_PINS {0, 1, X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, E_STEP_PIN, E_DIR_PIN, E_ENABLE_PIN, LED_PIN, PS_ON_PIN, HEATER_0_PIN, HEATER_1_PIN, HEATER_2_PIN, FAN_PIN, TEMP_0_PIN, TEMP_1_PIN, TEMP_2_PIN}
|
#define SENSITIVE_PINS {0, 1, X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, E_STEP_PIN, E_DIR_PIN, E_ENABLE_PIN, LED_PIN, PS_ON_PIN, HEATER_0_PIN, HEATER_1_PIN, HEATER_2_PIN, FAN_PIN, TEMP_0_PIN, TEMP_1_PIN, TEMP_2_PIN}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1154
Marlin/planner.cpp
1154
Marlin/planner.cpp
|
@ -1,398 +1,398 @@
|
||||||
/*
|
/*
|
||||||
planner.c - buffers movement commands and manages the acceleration profile plan
|
planner.c - buffers movement commands and manages the acceleration profile plan
|
||||||
Part of Grbl
|
Part of Grbl
|
||||||
|
|
||||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||||
|
|
||||||
Grbl is free software: you can redistribute it and/or modify
|
Grbl is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
Grbl is distributed in the hope that it will be useful,
|
Grbl is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The ring buffer implementation gleaned from the wiring_serial library by David A. Mellis. */
|
/* The ring buffer implementation gleaned from the wiring_serial library by David A. Mellis. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Reasoning behind the mathematics in this module (in the key of 'Mathematica'):
|
Reasoning behind the mathematics in this module (in the key of 'Mathematica'):
|
||||||
|
|
||||||
s == speed, a == acceleration, t == time, d == distance
|
s == speed, a == acceleration, t == time, d == distance
|
||||||
|
|
||||||
Basic definitions:
|
Basic definitions:
|
||||||
|
|
||||||
Speed[s_, a_, t_] := s + (a*t)
|
Speed[s_, a_, t_] := s + (a*t)
|
||||||
Travel[s_, a_, t_] := Integrate[Speed[s, a, t], t]
|
Travel[s_, a_, t_] := Integrate[Speed[s, a, t], t]
|
||||||
|
|
||||||
Distance to reach a specific speed with a constant acceleration:
|
Distance to reach a specific speed with a constant acceleration:
|
||||||
|
|
||||||
Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, d, t]
|
Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, d, t]
|
||||||
d -> (m^2 - s^2)/(2 a) --> estimate_acceleration_distance()
|
d -> (m^2 - s^2)/(2 a) --> estimate_acceleration_distance()
|
||||||
|
|
||||||
Speed after a given distance of travel with constant acceleration:
|
Speed after a given distance of travel with constant acceleration:
|
||||||
|
|
||||||
Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, m, t]
|
Solve[{Speed[s, a, t] == m, Travel[s, a, t] == d}, m, t]
|
||||||
m -> Sqrt[2 a d + s^2]
|
m -> Sqrt[2 a d + s^2]
|
||||||
|
|
||||||
DestinationSpeed[s_, a_, d_] := Sqrt[2 a d + s^2]
|
DestinationSpeed[s_, a_, d_] := Sqrt[2 a d + s^2]
|
||||||
|
|
||||||
When to start braking (di) to reach a specified destionation speed (s2) after accelerating
|
When to start braking (di) to reach a specified destionation speed (s2) after accelerating
|
||||||
from initial speed s1 without ever stopping at a plateau:
|
from initial speed s1 without ever stopping at a plateau:
|
||||||
|
|
||||||
Solve[{DestinationSpeed[s1, a, di] == DestinationSpeed[s2, a, d - di]}, di]
|
Solve[{DestinationSpeed[s1, a, di] == DestinationSpeed[s2, a, d - di]}, di]
|
||||||
di -> (2 a d - s1^2 + s2^2)/(4 a) --> intersection_distance()
|
di -> (2 a d - s1^2 + s2^2)/(4 a) --> intersection_distance()
|
||||||
|
|
||||||
IntersectionDistance[s1_, s2_, a_, d_] := (2 a d - s1^2 + s2^2)/(4 a)
|
IntersectionDistance[s1_, s2_, a_, d_] := (2 a d - s1^2 + s2^2)/(4 a)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//#include <inttypes.h>
|
//#include <inttypes.h>
|
||||||
//#include <math.h>
|
//#include <math.h>
|
||||||
//#include <stdlib.h>
|
//#include <stdlib.h>
|
||||||
|
|
||||||
#include "Marlin.h"
|
#include "Marlin.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "pins.h"
|
#include "pins.h"
|
||||||
#include "fastio.h"
|
#include "fastio.h"
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
#include "temperature.h"
|
#include "temperature.h"
|
||||||
#include "ultralcd.h"
|
#include "ultralcd.h"
|
||||||
|
|
||||||
unsigned long minsegmenttime;
|
unsigned long minsegmenttime;
|
||||||
float max_feedrate[4]; // set the max speeds
|
float max_feedrate[4]; // set the max speeds
|
||||||
float axis_steps_per_unit[4];
|
float axis_steps_per_unit[4];
|
||||||
long max_acceleration_units_per_sq_second[4]; // Use M201 to override by software
|
long max_acceleration_units_per_sq_second[4]; // Use M201 to override by software
|
||||||
float minimumfeedrate;
|
float minimumfeedrate;
|
||||||
float acceleration; // Normal acceleration mm/s^2 THIS IS THE DEFAULT ACCELERATION for all moves. M204 SXXXX
|
float acceleration; // Normal acceleration mm/s^2 THIS IS THE DEFAULT ACCELERATION for all moves. M204 SXXXX
|
||||||
float retract_acceleration; // mm/s^2 filament pull-pack and push-forward while standing still in the other axis M204 TXXXX
|
float retract_acceleration; // mm/s^2 filament pull-pack and push-forward while standing still in the other axis M204 TXXXX
|
||||||
float max_xy_jerk; //speed than can be stopped at once, if i understand correctly.
|
float max_xy_jerk; //speed than can be stopped at once, if i understand correctly.
|
||||||
float max_z_jerk;
|
float max_z_jerk;
|
||||||
float mintravelfeedrate;
|
float mintravelfeedrate;
|
||||||
unsigned long axis_steps_per_sqr_second[NUM_AXIS];
|
unsigned long axis_steps_per_sqr_second[NUM_AXIS];
|
||||||
// Manage heater variables.
|
// Manage heater variables.
|
||||||
|
|
||||||
static block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion instfructions
|
static block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion instfructions
|
||||||
static volatile unsigned char block_buffer_head; // Index of the next block to be pushed
|
static volatile unsigned char block_buffer_head; // Index of the next block to be pushed
|
||||||
static volatile unsigned char block_buffer_tail; // Index of the block to process now
|
static volatile unsigned char block_buffer_tail; // Index of the block to process now
|
||||||
|
|
||||||
// The current position of the tool in absolute steps
|
// The current position of the tool in absolute steps
|
||||||
long position[4];
|
long position[4];
|
||||||
|
|
||||||
#define ONE_MINUTE_OF_MICROSECONDS 60000000.0
|
#define ONE_MINUTE_OF_MICROSECONDS 60000000.0
|
||||||
|
|
||||||
// Calculates the distance (not time) it takes to accelerate from initial_rate to target_rate using the
|
// Calculates the distance (not time) it takes to accelerate from initial_rate to target_rate using the
|
||||||
// given acceleration:
|
// given acceleration:
|
||||||
inline float estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) {
|
inline float estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) {
|
||||||
if (acceleration!=0) {
|
if (acceleration!=0) {
|
||||||
return((target_rate*target_rate-initial_rate*initial_rate)/
|
return((target_rate*target_rate-initial_rate*initial_rate)/
|
||||||
(2.0*acceleration));
|
(2.0*acceleration));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0.0; // acceleration was 0, set acceleration distance to 0
|
return 0.0; // acceleration was 0, set acceleration distance to 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function gives you the point at which you must start braking (at the rate of -acceleration) if
|
// This function gives you the point at which you must start braking (at the rate of -acceleration) if
|
||||||
// you started at speed initial_rate and accelerated until this point and want to end at the final_rate after
|
// you started at speed initial_rate and accelerated until this point and want to end at the final_rate after
|
||||||
// a total travel of distance. This can be used to compute the intersection point between acceleration and
|
// a total travel of distance. This can be used to compute the intersection point between acceleration and
|
||||||
// deceleration in the cases where the trapezoid has no plateau (i.e. never reaches maximum speed)
|
// deceleration in the cases where the trapezoid has no plateau (i.e. never reaches maximum speed)
|
||||||
|
|
||||||
inline float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) {
|
inline float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) {
|
||||||
if (acceleration!=0) {
|
if (acceleration!=0) {
|
||||||
return((2.0*acceleration*distance-initial_rate*initial_rate+final_rate*final_rate)/
|
return((2.0*acceleration*distance-initial_rate*initial_rate+final_rate*final_rate)/
|
||||||
(4.0*acceleration) );
|
(4.0*acceleration) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0.0; // acceleration was 0, set intersection distance to 0
|
return 0.0; // acceleration was 0, set intersection distance to 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates trapezoid parameters so that the entry- and exit-speed is compensated by the provided factors.
|
// Calculates trapezoid parameters so that the entry- and exit-speed is compensated by the provided factors.
|
||||||
|
|
||||||
void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit_speed) {
|
void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit_speed) {
|
||||||
if(block->busy == true) return; // If block is busy then bail out.
|
if(block->busy == true) return; // If block is busy then bail out.
|
||||||
float entry_factor = entry_speed / block->nominal_speed;
|
float entry_factor = entry_speed / block->nominal_speed;
|
||||||
float exit_factor = exit_speed / block->nominal_speed;
|
float exit_factor = exit_speed / block->nominal_speed;
|
||||||
long initial_rate = ceil(block->nominal_rate*entry_factor);
|
long initial_rate = ceil(block->nominal_rate*entry_factor);
|
||||||
long final_rate = ceil(block->nominal_rate*exit_factor);
|
long final_rate = ceil(block->nominal_rate*exit_factor);
|
||||||
|
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
long initial_advance = block->advance*entry_factor*entry_factor;
|
long initial_advance = block->advance*entry_factor*entry_factor;
|
||||||
long final_advance = block->advance*exit_factor*exit_factor;
|
long final_advance = block->advance*exit_factor*exit_factor;
|
||||||
#endif // ADVANCE
|
#endif // ADVANCE
|
||||||
|
|
||||||
// Limit minimal step rate (Otherwise the timer will overflow.)
|
// Limit minimal step rate (Otherwise the timer will overflow.)
|
||||||
if(initial_rate <120) initial_rate=120;
|
if(initial_rate <120) initial_rate=120;
|
||||||
if(final_rate < 120) final_rate=120;
|
if(final_rate < 120) final_rate=120;
|
||||||
|
|
||||||
// Calculate the acceleration steps
|
// Calculate the acceleration steps
|
||||||
long acceleration = block->acceleration_st;
|
long acceleration = block->acceleration_st;
|
||||||
long accelerate_steps = estimate_acceleration_distance(initial_rate, block->nominal_rate, acceleration);
|
long accelerate_steps = estimate_acceleration_distance(initial_rate, block->nominal_rate, acceleration);
|
||||||
long decelerate_steps = estimate_acceleration_distance(final_rate, block->nominal_rate, acceleration);
|
long decelerate_steps = estimate_acceleration_distance(final_rate, block->nominal_rate, acceleration);
|
||||||
// Calculate the size of Plateau of Nominal Rate.
|
// Calculate the size of Plateau of Nominal Rate.
|
||||||
long plateau_steps = block->step_event_count-accelerate_steps-decelerate_steps;
|
long plateau_steps = block->step_event_count-accelerate_steps-decelerate_steps;
|
||||||
|
|
||||||
// Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will
|
// Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will
|
||||||
// have to use intersection_distance() to calculate when to abort acceleration and start braking
|
// have to use intersection_distance() to calculate when to abort acceleration and start braking
|
||||||
// in order to reach the final_rate exactly at the end of this block.
|
// in order to reach the final_rate exactly at the end of this block.
|
||||||
if (plateau_steps < 0) {
|
if (plateau_steps < 0) {
|
||||||
accelerate_steps = intersection_distance(initial_rate, final_rate, acceleration, block->step_event_count);
|
accelerate_steps = intersection_distance(initial_rate, final_rate, acceleration, block->step_event_count);
|
||||||
plateau_steps = 0;
|
plateau_steps = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long decelerate_after = accelerate_steps+plateau_steps;
|
long decelerate_after = accelerate_steps+plateau_steps;
|
||||||
|
|
||||||
CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section
|
CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section
|
||||||
if(block->busy == false) { // Don't update variables if block is busy.
|
if(block->busy == false) { // Don't update variables if block is busy.
|
||||||
block->accelerate_until = accelerate_steps;
|
block->accelerate_until = accelerate_steps;
|
||||||
block->decelerate_after = decelerate_after;
|
block->decelerate_after = decelerate_after;
|
||||||
block->initial_rate = initial_rate;
|
block->initial_rate = initial_rate;
|
||||||
block->final_rate = final_rate;
|
block->final_rate = final_rate;
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
block->initial_advance = initial_advance;
|
block->initial_advance = initial_advance;
|
||||||
block->final_advance = final_advance;
|
block->final_advance = final_advance;
|
||||||
#endif //ADVANCE
|
#endif //ADVANCE
|
||||||
}
|
}
|
||||||
CRITICAL_SECTION_END;
|
CRITICAL_SECTION_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the
|
// Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the
|
||||||
// acceleration within the allotted distance.
|
// acceleration within the allotted distance.
|
||||||
inline float max_allowable_speed(float acceleration, float target_velocity, float distance) {
|
inline float max_allowable_speed(float acceleration, float target_velocity, float distance) {
|
||||||
return(
|
return(
|
||||||
sqrt(target_velocity*target_velocity-2*acceleration*60*60*distance)
|
sqrt(target_velocity*target_velocity-2*acceleration*60*60*distance)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Junction jerk" in this context is the immediate change in speed at the junction of two blocks.
|
// "Junction jerk" in this context is the immediate change in speed at the junction of two blocks.
|
||||||
// This method will calculate the junction jerk as the euclidean distance between the nominal
|
// This method will calculate the junction jerk as the euclidean distance between the nominal
|
||||||
// velocities of the respective blocks.
|
// velocities of the respective blocks.
|
||||||
inline float junction_jerk(block_t *before, block_t *after) {
|
inline float junction_jerk(block_t *before, block_t *after) {
|
||||||
return(sqrt(
|
return(sqrt(
|
||||||
pow((before->speed_x-after->speed_x), 2)+
|
pow((before->speed_x-after->speed_x), 2)+
|
||||||
pow((before->speed_y-after->speed_y), 2)));
|
pow((before->speed_y-after->speed_y), 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the safe speed which is max_jerk/2, e.g. the
|
// Return the safe speed which is max_jerk/2, e.g. the
|
||||||
// speed under which you cannot exceed max_jerk no matter what you do.
|
// speed under which you cannot exceed max_jerk no matter what you do.
|
||||||
float safe_speed(block_t *block) {
|
float safe_speed(block_t *block) {
|
||||||
float safe_speed;
|
float safe_speed;
|
||||||
safe_speed = max_xy_jerk/2;
|
safe_speed = max_xy_jerk/2;
|
||||||
if(abs(block->speed_z) > max_z_jerk/2) safe_speed = max_z_jerk/2;
|
if(abs(block->speed_z) > max_z_jerk/2) safe_speed = max_z_jerk/2;
|
||||||
if (safe_speed > block->nominal_speed) safe_speed = block->nominal_speed;
|
if (safe_speed > block->nominal_speed) safe_speed = block->nominal_speed;
|
||||||
return safe_speed;
|
return safe_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The kernel called by planner_recalculate() when scanning the plan from last to first entry.
|
// The kernel called by planner_recalculate() when scanning the plan from last to first entry.
|
||||||
void planner_reverse_pass_kernel(block_t *previous, block_t *current, block_t *next) {
|
void planner_reverse_pass_kernel(block_t *previous, block_t *current, block_t *next) {
|
||||||
if(!current) {
|
if(!current) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float entry_speed = current->nominal_speed;
|
float entry_speed = current->nominal_speed;
|
||||||
float exit_factor;
|
float exit_factor;
|
||||||
float exit_speed;
|
float exit_speed;
|
||||||
if (next) {
|
if (next) {
|
||||||
exit_speed = next->entry_speed;
|
exit_speed = next->entry_speed;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exit_speed = safe_speed(current);
|
exit_speed = safe_speed(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the entry_factor for the current block.
|
// Calculate the entry_factor for the current block.
|
||||||
if (previous) {
|
if (previous) {
|
||||||
// Reduce speed so that junction_jerk is within the maximum allowed
|
// Reduce speed so that junction_jerk is within the maximum allowed
|
||||||
float jerk = junction_jerk(previous, current);
|
float jerk = junction_jerk(previous, current);
|
||||||
if((previous->steps_x == 0) && (previous->steps_y == 0)) {
|
if((previous->steps_x == 0) && (previous->steps_y == 0)) {
|
||||||
entry_speed = safe_speed(current);
|
entry_speed = safe_speed(current);
|
||||||
}
|
}
|
||||||
else if (jerk > max_xy_jerk) {
|
else if (jerk > max_xy_jerk) {
|
||||||
entry_speed = (max_xy_jerk/jerk) * entry_speed;
|
entry_speed = (max_xy_jerk/jerk) * entry_speed;
|
||||||
}
|
}
|
||||||
if(abs(previous->speed_z - current->speed_z) > max_z_jerk) {
|
if(abs(previous->speed_z - current->speed_z) > max_z_jerk) {
|
||||||
entry_speed = (max_z_jerk/abs(previous->speed_z - current->speed_z)) * entry_speed;
|
entry_speed = (max_z_jerk/abs(previous->speed_z - current->speed_z)) * entry_speed;
|
||||||
}
|
}
|
||||||
// If the required deceleration across the block is too rapid, reduce the entry_factor accordingly.
|
// If the required deceleration across the block is too rapid, reduce the entry_factor accordingly.
|
||||||
if (entry_speed > exit_speed) {
|
if (entry_speed > exit_speed) {
|
||||||
float max_entry_speed = max_allowable_speed(-current->acceleration,exit_speed, current->millimeters);
|
float max_entry_speed = max_allowable_speed(-current->acceleration,exit_speed, current->millimeters);
|
||||||
if (max_entry_speed < entry_speed) {
|
if (max_entry_speed < entry_speed) {
|
||||||
entry_speed = max_entry_speed;
|
entry_speed = max_entry_speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
entry_speed = safe_speed(current);
|
entry_speed = safe_speed(current);
|
||||||
}
|
}
|
||||||
// Store result
|
// Store result
|
||||||
current->entry_speed = entry_speed;
|
current->entry_speed = entry_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// planner_recalculate() needs to go over the current plan twice. Once in reverse and once forward. This
|
// planner_recalculate() needs to go over the current plan twice. Once in reverse and once forward. This
|
||||||
// implements the reverse pass.
|
// implements the reverse pass.
|
||||||
void planner_reverse_pass() {
|
void planner_reverse_pass() {
|
||||||
char block_index = block_buffer_head;
|
char block_index = block_buffer_head;
|
||||||
if(((block_buffer_head-block_buffer_tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1)) > 3) {
|
if(((block_buffer_head-block_buffer_tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1)) > 3) {
|
||||||
block_index = (block_buffer_head - 3) & (BLOCK_BUFFER_SIZE - 1);
|
block_index = (block_buffer_head - 3) & (BLOCK_BUFFER_SIZE - 1);
|
||||||
block_t *block[5] = {
|
block_t *block[5] = {
|
||||||
NULL, NULL, NULL, NULL, NULL };
|
NULL, NULL, NULL, NULL, NULL };
|
||||||
while(block_index != block_buffer_tail) {
|
while(block_index != block_buffer_tail) {
|
||||||
block_index = (block_index-1) & (BLOCK_BUFFER_SIZE -1);
|
block_index = (block_index-1) & (BLOCK_BUFFER_SIZE -1);
|
||||||
block[2]= block[1];
|
block[2]= block[1];
|
||||||
block[1]= block[0];
|
block[1]= block[0];
|
||||||
block[0] = &block_buffer[block_index];
|
block[0] = &block_buffer[block_index];
|
||||||
planner_reverse_pass_kernel(block[0], block[1], block[2]);
|
planner_reverse_pass_kernel(block[0], block[1], block[2]);
|
||||||
}
|
}
|
||||||
planner_reverse_pass_kernel(NULL, block[0], block[1]);
|
planner_reverse_pass_kernel(NULL, block[0], block[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The kernel called by planner_recalculate() when scanning the plan from first to last entry.
|
// The kernel called by planner_recalculate() when scanning the plan from first to last entry.
|
||||||
void planner_forward_pass_kernel(block_t *previous, block_t *current, block_t *next) {
|
void planner_forward_pass_kernel(block_t *previous, block_t *current, block_t *next) {
|
||||||
if(!current) {
|
if(!current) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(previous) {
|
if(previous) {
|
||||||
// If the previous block is an acceleration block, but it is not long enough to
|
// If the previous block is an acceleration block, but it is not long enough to
|
||||||
// complete the full speed change within the block, we need to adjust out entry
|
// complete the full speed change within the block, we need to adjust out entry
|
||||||
// speed accordingly. Remember current->entry_factor equals the exit factor of
|
// speed accordingly. Remember current->entry_factor equals the exit factor of
|
||||||
// the previous block.
|
// the previous block.
|
||||||
if(previous->entry_speed < current->entry_speed) {
|
if(previous->entry_speed < current->entry_speed) {
|
||||||
float max_entry_speed = max_allowable_speed(-previous->acceleration, previous->entry_speed, previous->millimeters);
|
float max_entry_speed = max_allowable_speed(-previous->acceleration, previous->entry_speed, previous->millimeters);
|
||||||
if (max_entry_speed < current->entry_speed) {
|
if (max_entry_speed < current->entry_speed) {
|
||||||
current->entry_speed = max_entry_speed;
|
current->entry_speed = max_entry_speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// planner_recalculate() needs to go over the current plan twice. Once in reverse and once forward. This
|
// planner_recalculate() needs to go over the current plan twice. Once in reverse and once forward. This
|
||||||
// implements the forward pass.
|
// implements the forward pass.
|
||||||
void planner_forward_pass() {
|
void planner_forward_pass() {
|
||||||
char block_index = block_buffer_tail;
|
char block_index = block_buffer_tail;
|
||||||
block_t *block[3] = {
|
block_t *block[3] = {
|
||||||
NULL, NULL, NULL };
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
while(block_index != block_buffer_head) {
|
while(block_index != block_buffer_head) {
|
||||||
block[0] = block[1];
|
block[0] = block[1];
|
||||||
block[1] = block[2];
|
block[1] = block[2];
|
||||||
block[2] = &block_buffer[block_index];
|
block[2] = &block_buffer[block_index];
|
||||||
planner_forward_pass_kernel(block[0],block[1],block[2]);
|
planner_forward_pass_kernel(block[0],block[1],block[2]);
|
||||||
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
|
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
|
||||||
}
|
}
|
||||||
planner_forward_pass_kernel(block[1], block[2], NULL);
|
planner_forward_pass_kernel(block[1], block[2], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recalculates the trapezoid speed profiles for all blocks in the plan according to the
|
// Recalculates the trapezoid speed profiles for all blocks in the plan according to the
|
||||||
// entry_factor for each junction. Must be called by planner_recalculate() after
|
// entry_factor for each junction. Must be called by planner_recalculate() after
|
||||||
// updating the blocks.
|
// updating the blocks.
|
||||||
void planner_recalculate_trapezoids() {
|
void planner_recalculate_trapezoids() {
|
||||||
char block_index = block_buffer_tail;
|
char block_index = block_buffer_tail;
|
||||||
block_t *current;
|
block_t *current;
|
||||||
block_t *next = NULL;
|
block_t *next = NULL;
|
||||||
while(block_index != block_buffer_head) {
|
while(block_index != block_buffer_head) {
|
||||||
current = next;
|
current = next;
|
||||||
next = &block_buffer[block_index];
|
next = &block_buffer[block_index];
|
||||||
if (current) {
|
if (current) {
|
||||||
calculate_trapezoid_for_block(current, current->entry_speed, next->entry_speed);
|
calculate_trapezoid_for_block(current, current->entry_speed, next->entry_speed);
|
||||||
}
|
}
|
||||||
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
|
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
|
||||||
}
|
}
|
||||||
calculate_trapezoid_for_block(next, next->entry_speed, safe_speed(next));
|
calculate_trapezoid_for_block(next, next->entry_speed, safe_speed(next));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recalculates the motion plan according to the following algorithm:
|
// Recalculates the motion plan according to the following algorithm:
|
||||||
//
|
//
|
||||||
// 1. Go over every block in reverse order and calculate a junction speed reduction (i.e. block_t.entry_factor)
|
// 1. Go over every block in reverse order and calculate a junction speed reduction (i.e. block_t.entry_factor)
|
||||||
// so that:
|
// so that:
|
||||||
// a. The junction jerk is within the set limit
|
// a. The junction jerk is within the set limit
|
||||||
// b. No speed reduction within one block requires faster deceleration than the one, true constant
|
// b. No speed reduction within one block requires faster deceleration than the one, true constant
|
||||||
// acceleration.
|
// acceleration.
|
||||||
// 2. Go over every block in chronological order and dial down junction speed reduction values if
|
// 2. Go over every block in chronological order and dial down junction speed reduction values if
|
||||||
// a. The speed increase within one block would require faster accelleration than the one, true
|
// a. The speed increase within one block would require faster accelleration than the one, true
|
||||||
// constant acceleration.
|
// constant acceleration.
|
||||||
//
|
//
|
||||||
// When these stages are complete all blocks have an entry_factor that will allow all speed changes to
|
// When these stages are complete all blocks have an entry_factor that will allow all speed changes to
|
||||||
// be performed using only the one, true constant acceleration, and where no junction jerk is jerkier than
|
// be performed using only the one, true constant acceleration, and where no junction jerk is jerkier than
|
||||||
// the set limit. Finally it will:
|
// the set limit. Finally it will:
|
||||||
//
|
//
|
||||||
// 3. Recalculate trapezoids for all blocks.
|
// 3. Recalculate trapezoids for all blocks.
|
||||||
|
|
||||||
void planner_recalculate() {
|
void planner_recalculate() {
|
||||||
planner_reverse_pass();
|
planner_reverse_pass();
|
||||||
planner_forward_pass();
|
planner_forward_pass();
|
||||||
planner_recalculate_trapezoids();
|
planner_recalculate_trapezoids();
|
||||||
}
|
}
|
||||||
|
|
||||||
void plan_init() {
|
void plan_init() {
|
||||||
block_buffer_head = 0;
|
block_buffer_head = 0;
|
||||||
block_buffer_tail = 0;
|
block_buffer_tail = 0;
|
||||||
memset(position, 0, sizeof(position)); // clear position
|
memset(position, 0, sizeof(position)); // clear position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void plan_discard_current_block() {
|
void plan_discard_current_block() {
|
||||||
if (block_buffer_head != block_buffer_tail) {
|
if (block_buffer_head != block_buffer_tail) {
|
||||||
block_buffer_tail = (block_buffer_tail + 1) & (BLOCK_BUFFER_SIZE - 1);
|
block_buffer_tail = (block_buffer_tail + 1) & (BLOCK_BUFFER_SIZE - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block_t *plan_get_current_block() {
|
block_t *plan_get_current_block() {
|
||||||
if (block_buffer_head == block_buffer_tail) {
|
if (block_buffer_head == block_buffer_tail) {
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
block_t *block = &block_buffer[block_buffer_tail];
|
block_t *block = &block_buffer[block_buffer_tail];
|
||||||
block->busy = true;
|
block->busy = true;
|
||||||
return(block);
|
return(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_axes_activity() {
|
void check_axes_activity() {
|
||||||
unsigned char x_active = 0;
|
unsigned char x_active = 0;
|
||||||
unsigned char y_active = 0;
|
unsigned char y_active = 0;
|
||||||
unsigned char z_active = 0;
|
unsigned char z_active = 0;
|
||||||
unsigned char e_active = 0;
|
unsigned char e_active = 0;
|
||||||
block_t *block;
|
block_t *block;
|
||||||
|
|
||||||
if(block_buffer_tail != block_buffer_head) {
|
if(block_buffer_tail != block_buffer_head) {
|
||||||
char block_index = block_buffer_tail;
|
char block_index = block_buffer_tail;
|
||||||
while(block_index != block_buffer_head) {
|
while(block_index != block_buffer_head) {
|
||||||
block = &block_buffer[block_index];
|
block = &block_buffer[block_index];
|
||||||
if(block->steps_x != 0) x_active++;
|
if(block->steps_x != 0) x_active++;
|
||||||
if(block->steps_y != 0) y_active++;
|
if(block->steps_y != 0) y_active++;
|
||||||
if(block->steps_z != 0) z_active++;
|
if(block->steps_z != 0) z_active++;
|
||||||
if(block->steps_e != 0) e_active++;
|
if(block->steps_e != 0) e_active++;
|
||||||
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
|
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((DISABLE_X) && (x_active == 0)) disable_x();
|
if((DISABLE_X) && (x_active == 0)) disable_x();
|
||||||
if((DISABLE_Y) && (y_active == 0)) disable_y();
|
if((DISABLE_Y) && (y_active == 0)) disable_y();
|
||||||
if((DISABLE_Z) && (z_active == 0)) disable_z();
|
if((DISABLE_Z) && (z_active == 0)) disable_z();
|
||||||
if((DISABLE_E) && (e_active == 0)) disable_e();
|
if((DISABLE_E) && (e_active == 0)) disable_e();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new linear movement to the buffer. steps_x, _y and _z is the absolute position in
|
// Add a new linear movement to the buffer. steps_x, _y and _z is the absolute position in
|
||||||
// mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration
|
// mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration
|
||||||
// calculation the caller must also provide the physical length of the line in millimeters.
|
// calculation the caller must also provide the physical length of the line in millimeters.
|
||||||
void plan_buffer_line(float x, float y, float z, float e, float feed_rate) {
|
void plan_buffer_line(float x, float y, float z, float e, float feed_rate) {
|
||||||
|
|
||||||
|
|
||||||
// Calculate the buffer head after we push this byte
|
// Calculate the buffer head after we push this byte
|
||||||
int next_buffer_head = (block_buffer_head + 1) & (BLOCK_BUFFER_SIZE - 1);
|
int next_buffer_head = (block_buffer_head + 1) & (BLOCK_BUFFER_SIZE - 1);
|
||||||
|
|
||||||
// If the buffer is full: good! That means we are well ahead of the robot.
|
// If the buffer is full: good! That means we are well ahead of the robot.
|
||||||
// Rest here until there is room in the buffer.
|
// Rest here until there is room in the buffer.
|
||||||
while(block_buffer_tail == next_buffer_head) {
|
while(block_buffer_tail == next_buffer_head) {
|
||||||
manage_heater();
|
manage_heater();
|
||||||
manage_inactivity(1);
|
manage_inactivity(1);
|
||||||
LCD_STATUS;
|
LCD_STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The target position of the tool in absolute steps
|
// The target position of the tool in absolute steps
|
||||||
// Calculate target position in absolute steps
|
// Calculate target position in absolute steps
|
||||||
//this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow
|
//this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow
|
||||||
|
@ -402,185 +402,185 @@ void plan_buffer_line(float x, float y, float z, float e, float feed_rate) {
|
||||||
target[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
|
target[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
|
||||||
target[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS]);
|
target[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS]);
|
||||||
|
|
||||||
// Prepare to set up new block
|
// Prepare to set up new block
|
||||||
block_t *block = &block_buffer[block_buffer_head];
|
block_t *block = &block_buffer[block_buffer_head];
|
||||||
|
|
||||||
// Mark block as not busy (Not executed by the stepper interrupt)
|
// Mark block as not busy (Not executed by the stepper interrupt)
|
||||||
block->busy = false;
|
block->busy = false;
|
||||||
|
|
||||||
// Number of steps for each axis
|
// Number of steps for each axis
|
||||||
block->steps_x = labs(target[X_AXIS]-position[X_AXIS]);
|
block->steps_x = labs(target[X_AXIS]-position[X_AXIS]);
|
||||||
block->steps_y = labs(target[Y_AXIS]-position[Y_AXIS]);
|
block->steps_y = labs(target[Y_AXIS]-position[Y_AXIS]);
|
||||||
block->steps_z = labs(target[Z_AXIS]-position[Z_AXIS]);
|
block->steps_z = labs(target[Z_AXIS]-position[Z_AXIS]);
|
||||||
block->steps_e = labs(target[E_AXIS]-position[E_AXIS]);
|
block->steps_e = labs(target[E_AXIS]-position[E_AXIS]);
|
||||||
block->step_event_count = max(block->steps_x, max(block->steps_y, max(block->steps_z, block->steps_e)));
|
block->step_event_count = max(block->steps_x, max(block->steps_y, max(block->steps_z, block->steps_e)));
|
||||||
|
|
||||||
// Bail if this is a zero-length block
|
// Bail if this is a zero-length block
|
||||||
if (block->step_event_count <=dropsegments) {
|
if (block->step_event_count <=dropsegments) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
//enable active axes
|
//enable active axes
|
||||||
if(block->steps_x != 0) enable_x();
|
if(block->steps_x != 0) enable_x();
|
||||||
if(block->steps_y != 0) enable_y();
|
if(block->steps_y != 0) enable_y();
|
||||||
if(block->steps_z != 0) enable_z();
|
if(block->steps_z != 0) enable_z();
|
||||||
if(block->steps_e != 0) enable_e();
|
if(block->steps_e != 0) enable_e();
|
||||||
|
|
||||||
float delta_x_mm = (target[X_AXIS]-position[X_AXIS])/axis_steps_per_unit[X_AXIS];
|
float delta_x_mm = (target[X_AXIS]-position[X_AXIS])/axis_steps_per_unit[X_AXIS];
|
||||||
float delta_y_mm = (target[Y_AXIS]-position[Y_AXIS])/axis_steps_per_unit[Y_AXIS];
|
float delta_y_mm = (target[Y_AXIS]-position[Y_AXIS])/axis_steps_per_unit[Y_AXIS];
|
||||||
float delta_z_mm = (target[Z_AXIS]-position[Z_AXIS])/axis_steps_per_unit[Z_AXIS];
|
float delta_z_mm = (target[Z_AXIS]-position[Z_AXIS])/axis_steps_per_unit[Z_AXIS];
|
||||||
float delta_e_mm = (target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[E_AXIS];
|
float delta_e_mm = (target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[E_AXIS];
|
||||||
block->millimeters = sqrt(square(delta_x_mm) + square(delta_y_mm) + square(delta_z_mm) + square(delta_e_mm));
|
block->millimeters = sqrt(square(delta_x_mm) + square(delta_y_mm) + square(delta_z_mm) + square(delta_e_mm));
|
||||||
|
|
||||||
unsigned long microseconds;
|
unsigned long microseconds;
|
||||||
|
|
||||||
if (block->steps_e == 0) {
|
if (block->steps_e == 0) {
|
||||||
if(feed_rate<mintravelfeedrate) feed_rate=mintravelfeedrate;
|
if(feed_rate<mintravelfeedrate) feed_rate=mintravelfeedrate;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(feed_rate<minimumfeedrate) feed_rate=minimumfeedrate;
|
if(feed_rate<minimumfeedrate) feed_rate=minimumfeedrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
microseconds = lround((block->millimeters/feed_rate)*1000000);
|
microseconds = lround((block->millimeters/feed_rate)*1000000);
|
||||||
|
|
||||||
// slow down when de buffer starts to empty, rather than wait at the corner for a buffer refill
|
// slow down when de buffer starts to empty, rather than wait at the corner for a buffer refill
|
||||||
// reduces/removes corner blobs as the machine won't come to a full stop.
|
// reduces/removes corner blobs as the machine won't come to a full stop.
|
||||||
int blockcount=(block_buffer_head-block_buffer_tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1);
|
int blockcount=(block_buffer_head-block_buffer_tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1);
|
||||||
|
|
||||||
if ((blockcount>0) && (blockcount < (BLOCK_BUFFER_SIZE - 4))) {
|
if ((blockcount>0) && (blockcount < (BLOCK_BUFFER_SIZE - 4))) {
|
||||||
if (microseconds<minsegmenttime) { // buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more.
|
if (microseconds<minsegmenttime) { // buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more.
|
||||||
microseconds=microseconds+lround(2*(minsegmenttime-microseconds)/blockcount);
|
microseconds=microseconds+lround(2*(minsegmenttime-microseconds)/blockcount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (microseconds<minsegmenttime) microseconds=minsegmenttime;
|
if (microseconds<minsegmenttime) microseconds=minsegmenttime;
|
||||||
}
|
}
|
||||||
// END OF SLOW DOWN SECTION
|
// END OF SLOW DOWN SECTION
|
||||||
|
|
||||||
|
|
||||||
// Calculate speed in mm/minute for each axis
|
// Calculate speed in mm/minute for each axis
|
||||||
float multiplier = 60.0*1000000.0/microseconds;
|
float multiplier = 60.0*1000000.0/microseconds;
|
||||||
block->speed_z = delta_z_mm * multiplier;
|
block->speed_z = delta_z_mm * multiplier;
|
||||||
block->speed_x = delta_x_mm * multiplier;
|
block->speed_x = delta_x_mm * multiplier;
|
||||||
block->speed_y = delta_y_mm * multiplier;
|
block->speed_y = delta_y_mm * multiplier;
|
||||||
block->speed_e = delta_e_mm * multiplier;
|
block->speed_e = delta_e_mm * multiplier;
|
||||||
|
|
||||||
|
|
||||||
// Limit speed per axis
|
// Limit speed per axis
|
||||||
float speed_factor = 1; //factor <=1 do decrease speed
|
float speed_factor = 1; //factor <=1 do decrease speed
|
||||||
if(abs(block->speed_x) > max_feedrate[X_AXIS]) {
|
if(abs(block->speed_x) > max_feedrate[X_AXIS]) {
|
||||||
//// [ErikDeBruijn] IS THIS THE BUG WE'RE LOOING FOR????
|
//// [ErikDeBruijn] IS THIS THE BUG WE'RE LOOING FOR????
|
||||||
//// [bernhard] No its not, according to Zalm.
|
//// [bernhard] No its not, according to Zalm.
|
||||||
//// the if would always be true, since tmp_speedfactor <=0 due the inial if, so its safe to set. the next lines actually compare.
|
//// the if would always be true, since tmp_speedfactor <=0 due the inial if, so its safe to set. the next lines actually compare.
|
||||||
speed_factor = max_feedrate[X_AXIS] / abs(block->speed_x);
|
speed_factor = max_feedrate[X_AXIS] / abs(block->speed_x);
|
||||||
//if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
|
//if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
|
||||||
}
|
}
|
||||||
if(abs(block->speed_y) > max_feedrate[Y_AXIS]){
|
if(abs(block->speed_y) > max_feedrate[Y_AXIS]){
|
||||||
float tmp_speed_factor = max_feedrate[Y_AXIS] / abs(block->speed_y);
|
float tmp_speed_factor = max_feedrate[Y_AXIS] / abs(block->speed_y);
|
||||||
if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
|
if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
|
||||||
}
|
}
|
||||||
if(abs(block->speed_z) > max_feedrate[Z_AXIS]){
|
if(abs(block->speed_z) > max_feedrate[Z_AXIS]){
|
||||||
float tmp_speed_factor = max_feedrate[Z_AXIS] / abs(block->speed_z);
|
float tmp_speed_factor = max_feedrate[Z_AXIS] / abs(block->speed_z);
|
||||||
if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
|
if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
|
||||||
}
|
}
|
||||||
if(abs(block->speed_e) > max_feedrate[E_AXIS]){
|
if(abs(block->speed_e) > max_feedrate[E_AXIS]){
|
||||||
float tmp_speed_factor = max_feedrate[E_AXIS] / abs(block->speed_e);
|
float tmp_speed_factor = max_feedrate[E_AXIS] / abs(block->speed_e);
|
||||||
if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
|
if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
|
||||||
}
|
}
|
||||||
multiplier = multiplier * speed_factor;
|
multiplier = multiplier * speed_factor;
|
||||||
block->speed_z = delta_z_mm * multiplier;
|
block->speed_z = delta_z_mm * multiplier;
|
||||||
block->speed_x = delta_x_mm * multiplier;
|
block->speed_x = delta_x_mm * multiplier;
|
||||||
block->speed_y = delta_y_mm * multiplier;
|
block->speed_y = delta_y_mm * multiplier;
|
||||||
block->speed_e = delta_e_mm * multiplier;
|
block->speed_e = delta_e_mm * multiplier;
|
||||||
block->nominal_speed = block->millimeters * multiplier;
|
block->nominal_speed = block->millimeters * multiplier;
|
||||||
block->nominal_rate = ceil(block->step_event_count * multiplier / 60);
|
block->nominal_rate = ceil(block->step_event_count * multiplier / 60);
|
||||||
|
|
||||||
if(block->nominal_rate < 120) block->nominal_rate = 120;
|
if(block->nominal_rate < 120) block->nominal_rate = 120;
|
||||||
block->entry_speed = safe_speed(block);
|
block->entry_speed = safe_speed(block);
|
||||||
|
|
||||||
// Compute the acceleration rate for the trapezoid generator.
|
// Compute the acceleration rate for the trapezoid generator.
|
||||||
float travel_per_step = block->millimeters/block->step_event_count;
|
float travel_per_step = block->millimeters/block->step_event_count;
|
||||||
if(block->steps_x == 0 && block->steps_y == 0 && block->steps_z == 0) {
|
if(block->steps_x == 0 && block->steps_y == 0 && block->steps_z == 0) {
|
||||||
block->acceleration_st = ceil( (retract_acceleration)/travel_per_step); // convert to: acceleration steps/sec^2
|
block->acceleration_st = ceil( (retract_acceleration)/travel_per_step); // convert to: acceleration steps/sec^2
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
block->acceleration_st = ceil( (acceleration)/travel_per_step); // convert to: acceleration steps/sec^2
|
block->acceleration_st = ceil( (acceleration)/travel_per_step); // convert to: acceleration steps/sec^2
|
||||||
float tmp_acceleration = (float)block->acceleration_st / (float)block->step_event_count;
|
float tmp_acceleration = (float)block->acceleration_st / (float)block->step_event_count;
|
||||||
// Limit acceleration per axis
|
// Limit acceleration per axis
|
||||||
if((tmp_acceleration * block->steps_x) > axis_steps_per_sqr_second[X_AXIS]) {
|
if((tmp_acceleration * block->steps_x) > axis_steps_per_sqr_second[X_AXIS]) {
|
||||||
block->acceleration_st = axis_steps_per_sqr_second[X_AXIS];
|
block->acceleration_st = axis_steps_per_sqr_second[X_AXIS];
|
||||||
tmp_acceleration = (float)block->acceleration_st / (float)block->step_event_count;
|
tmp_acceleration = (float)block->acceleration_st / (float)block->step_event_count;
|
||||||
}
|
}
|
||||||
if((tmp_acceleration * block->steps_y) > axis_steps_per_sqr_second[Y_AXIS]) {
|
if((tmp_acceleration * block->steps_y) > axis_steps_per_sqr_second[Y_AXIS]) {
|
||||||
block->acceleration_st = axis_steps_per_sqr_second[Y_AXIS];
|
block->acceleration_st = axis_steps_per_sqr_second[Y_AXIS];
|
||||||
tmp_acceleration = (float)block->acceleration_st / (float)block->step_event_count;
|
tmp_acceleration = (float)block->acceleration_st / (float)block->step_event_count;
|
||||||
}
|
}
|
||||||
if((tmp_acceleration * block->steps_e) > axis_steps_per_sqr_second[E_AXIS]) {
|
if((tmp_acceleration * block->steps_e) > axis_steps_per_sqr_second[E_AXIS]) {
|
||||||
block->acceleration_st = axis_steps_per_sqr_second[E_AXIS];
|
block->acceleration_st = axis_steps_per_sqr_second[E_AXIS];
|
||||||
tmp_acceleration = (float)block->acceleration_st / (float)block->step_event_count;
|
tmp_acceleration = (float)block->acceleration_st / (float)block->step_event_count;
|
||||||
}
|
}
|
||||||
if((tmp_acceleration * block->steps_z) > axis_steps_per_sqr_second[Z_AXIS]) {
|
if((tmp_acceleration * block->steps_z) > axis_steps_per_sqr_second[Z_AXIS]) {
|
||||||
block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS];
|
block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS];
|
||||||
tmp_acceleration = (float)block->acceleration_st / (float)block->step_event_count;
|
tmp_acceleration = (float)block->acceleration_st / (float)block->step_event_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
block->acceleration = block->acceleration_st * travel_per_step;
|
block->acceleration = block->acceleration_st * travel_per_step;
|
||||||
block->acceleration_rate = (long)((float)block->acceleration_st * 8.388608);
|
block->acceleration_rate = (long)((float)block->acceleration_st * 8.388608);
|
||||||
|
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
// Calculate advance rate
|
// Calculate advance rate
|
||||||
if((block->steps_e == 0) || (block->steps_x == 0 && block->steps_y == 0 && block->steps_z == 0)) {
|
if((block->steps_e == 0) || (block->steps_x == 0 && block->steps_y == 0 && block->steps_z == 0)) {
|
||||||
block->advance_rate = 0;
|
block->advance_rate = 0;
|
||||||
block->advance = 0;
|
block->advance = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_st);
|
long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_st);
|
||||||
float advance = (STEPS_PER_CUBIC_MM_E * EXTRUDER_ADVANCE_K) *
|
float advance = (STEPS_PER_CUBIC_MM_E * EXTRUDER_ADVANCE_K) *
|
||||||
(block->speed_e * block->speed_e * EXTRUTION_AREA * EXTRUTION_AREA / 3600.0)*65536;
|
(block->speed_e * block->speed_e * EXTRUTION_AREA * EXTRUTION_AREA / 3600.0)*65536;
|
||||||
block->advance = advance;
|
block->advance = advance;
|
||||||
if(acc_dist == 0) {
|
if(acc_dist == 0) {
|
||||||
block->advance_rate = 0;
|
block->advance_rate = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
block->advance_rate = advance / (float)acc_dist;
|
block->advance_rate = advance / (float)acc_dist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // ADVANCE
|
#endif // ADVANCE
|
||||||
|
|
||||||
// compute a preliminary conservative acceleration trapezoid
|
// compute a preliminary conservative acceleration trapezoid
|
||||||
float safespeed = safe_speed(block);
|
float safespeed = safe_speed(block);
|
||||||
calculate_trapezoid_for_block(block, safespeed, safespeed);
|
calculate_trapezoid_for_block(block, safespeed, safespeed);
|
||||||
|
|
||||||
// Compute direction bits for this block
|
// Compute direction bits for this block
|
||||||
block->direction_bits = 0;
|
block->direction_bits = 0;
|
||||||
if (target[X_AXIS] < position[X_AXIS]) {
|
if (target[X_AXIS] < position[X_AXIS]) {
|
||||||
block->direction_bits |= (1<<X_AXIS);
|
block->direction_bits |= (1<<X_AXIS);
|
||||||
}
|
}
|
||||||
if (target[Y_AXIS] < position[Y_AXIS]) {
|
if (target[Y_AXIS] < position[Y_AXIS]) {
|
||||||
block->direction_bits |= (1<<Y_AXIS);
|
block->direction_bits |= (1<<Y_AXIS);
|
||||||
}
|
}
|
||||||
if (target[Z_AXIS] < position[Z_AXIS]) {
|
if (target[Z_AXIS] < position[Z_AXIS]) {
|
||||||
block->direction_bits |= (1<<Z_AXIS);
|
block->direction_bits |= (1<<Z_AXIS);
|
||||||
}
|
}
|
||||||
if (target[E_AXIS] < position[E_AXIS]) {
|
if (target[E_AXIS] < position[E_AXIS]) {
|
||||||
block->direction_bits |= (1<<E_AXIS);
|
block->direction_bits |= (1<<E_AXIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move buffer head
|
// Move buffer head
|
||||||
block_buffer_head = next_buffer_head;
|
block_buffer_head = next_buffer_head;
|
||||||
|
|
||||||
// Update position
|
// Update position
|
||||||
memcpy(position, target, sizeof(target)); // position[] = target[]
|
memcpy(position, target, sizeof(target)); // position[] = target[]
|
||||||
|
|
||||||
planner_recalculate();
|
planner_recalculate();
|
||||||
st_wake_up();
|
st_wake_up();
|
||||||
}
|
}
|
||||||
|
|
||||||
void plan_set_position(float x, float y, float z, float e)
|
void plan_set_position(float x, float y, float z, float e)
|
||||||
{
|
{
|
||||||
position[X_AXIS] = lround(x*axis_steps_per_unit[X_AXIS]);
|
position[X_AXIS] = lround(x*axis_steps_per_unit[X_AXIS]);
|
||||||
position[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]);
|
position[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]);
|
||||||
position[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
|
position[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]);
|
||||||
position[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS]);
|
position[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,75 +1,75 @@
|
||||||
#ifndef SPEED_LOOKUPTABLE_H
|
#ifndef SPEED_LOOKUPTABLE_H
|
||||||
#define SPEED_LOOKUPTABLE_H
|
#define SPEED_LOOKUPTABLE_H
|
||||||
|
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
uint16_t speed_lookuptable_fast[256][2] PROGMEM = {\
|
uint16_t speed_lookuptable_fast[256][2] PROGMEM = {\
|
||||||
{ 62500, 55556}, { 6944, 3268}, { 3676, 1176}, { 2500, 607}, { 1893, 369}, { 1524, 249}, { 1275, 179}, { 1096, 135},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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}
|
{ 31, 0}, { 31, 0}, { 31, 0}, { 31, 1}, { 30, 0}, { 30, 0}, { 30, 0}, { 30, 0}
|
||||||
};
|
};
|
||||||
uint16_t speed_lookuptable_slow[256][2] PROGMEM = {\
|
uint16_t speed_lookuptable_slow[256][2] PROGMEM = {\
|
||||||
{ 62500, 12500}, { 50000, 8334}, { 41666, 5952}, { 35714, 4464}, { 31250, 3473}, { 27777, 2777}, { 25000, 2273}, { 22727, 1894},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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},
|
{ 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}
|
{ 992, 4}, { 988, 4}, { 984, 4}, { 980, 4}, { 976, 4}, { 972, 4}, { 968, 3}, { 965, 3}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1184
Marlin/stepper.cpp
1184
Marlin/stepper.cpp
|
@ -1,592 +1,592 @@
|
||||||
/*
|
/*
|
||||||
stepper.c - stepper motor driver: executes motion plans using stepper motors
|
stepper.c - stepper motor driver: executes motion plans using stepper motors
|
||||||
Part of Grbl
|
Part of Grbl
|
||||||
|
|
||||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||||
|
|
||||||
Grbl is free software: you can redistribute it and/or modify
|
Grbl is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
Grbl is distributed in the hope that it will be useful,
|
Grbl is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith
|
/* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith
|
||||||
and Philipp Tiefenbacher. */
|
and Philipp Tiefenbacher. */
|
||||||
|
|
||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "Marlin.h"
|
#include "Marlin.h"
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
#include "pins.h"
|
#include "pins.h"
|
||||||
#include "fastio.h"
|
#include "fastio.h"
|
||||||
#include "temperature.h"
|
#include "temperature.h"
|
||||||
#include "ultralcd.h"
|
#include "ultralcd.h"
|
||||||
|
|
||||||
#include "speed_lookuptable.h"
|
#include "speed_lookuptable.h"
|
||||||
|
|
||||||
// if DEBUG_STEPS is enabled, M114 can be used to compare two methods of determining the X,Y,Z position of the printer.
|
// if DEBUG_STEPS is enabled, M114 can be used to compare two methods of determining the X,Y,Z position of the printer.
|
||||||
// for debugging purposes only, should be disabled by default
|
// for debugging purposes only, should be disabled by default
|
||||||
#ifdef DEBUG_STEPS
|
#ifdef DEBUG_STEPS
|
||||||
volatile long count_position[NUM_AXIS] = { 0, 0, 0, 0};
|
volatile long count_position[NUM_AXIS] = { 0, 0, 0, 0};
|
||||||
volatile int count_direction[NUM_AXIS] = { 1, 1, 1, 1};
|
volatile int count_direction[NUM_AXIS] = { 1, 1, 1, 1};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// intRes = intIn1 * intIn2 >> 16
|
// intRes = intIn1 * intIn2 >> 16
|
||||||
// uses:
|
// uses:
|
||||||
// r26 to store 0
|
// r26 to store 0
|
||||||
// r27 to store the byte 1 of the 24 bit result
|
// r27 to store the byte 1 of the 24 bit result
|
||||||
#define MultiU16X8toH16(intRes, charIn1, intIn2) \
|
#define MultiU16X8toH16(intRes, charIn1, intIn2) \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"clr r26 \n\t" \
|
"clr r26 \n\t" \
|
||||||
"mul %A1, %B2 \n\t" \
|
"mul %A1, %B2 \n\t" \
|
||||||
"movw %A0, r0 \n\t" \
|
"movw %A0, r0 \n\t" \
|
||||||
"mul %A1, %A2 \n\t" \
|
"mul %A1, %A2 \n\t" \
|
||||||
"add %A0, r1 \n\t" \
|
"add %A0, r1 \n\t" \
|
||||||
"adc %B0, r26 \n\t" \
|
"adc %B0, r26 \n\t" \
|
||||||
"lsr r0 \n\t" \
|
"lsr r0 \n\t" \
|
||||||
"adc %A0, r26 \n\t" \
|
"adc %A0, r26 \n\t" \
|
||||||
"adc %B0, r26 \n\t" \
|
"adc %B0, r26 \n\t" \
|
||||||
"clr r1 \n\t" \
|
"clr r1 \n\t" \
|
||||||
: \
|
: \
|
||||||
"=&r" (intRes) \
|
"=&r" (intRes) \
|
||||||
: \
|
: \
|
||||||
"d" (charIn1), \
|
"d" (charIn1), \
|
||||||
"d" (intIn2) \
|
"d" (intIn2) \
|
||||||
: \
|
: \
|
||||||
"r26" \
|
"r26" \
|
||||||
)
|
)
|
||||||
|
|
||||||
// intRes = longIn1 * longIn2 >> 24
|
// intRes = longIn1 * longIn2 >> 24
|
||||||
// uses:
|
// uses:
|
||||||
// r26 to store 0
|
// r26 to store 0
|
||||||
// r27 to store the byte 1 of the 48bit result
|
// r27 to store the byte 1 of the 48bit result
|
||||||
#define MultiU24X24toH16(intRes, longIn1, longIn2) \
|
#define MultiU24X24toH16(intRes, longIn1, longIn2) \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"clr r26 \n\t" \
|
"clr r26 \n\t" \
|
||||||
"mul %A1, %B2 \n\t" \
|
"mul %A1, %B2 \n\t" \
|
||||||
"mov r27, r1 \n\t" \
|
"mov r27, r1 \n\t" \
|
||||||
"mul %B1, %C2 \n\t" \
|
"mul %B1, %C2 \n\t" \
|
||||||
"movw %A0, r0 \n\t" \
|
"movw %A0, r0 \n\t" \
|
||||||
"mul %C1, %C2 \n\t" \
|
"mul %C1, %C2 \n\t" \
|
||||||
"add %B0, r0 \n\t" \
|
"add %B0, r0 \n\t" \
|
||||||
"mul %C1, %B2 \n\t" \
|
"mul %C1, %B2 \n\t" \
|
||||||
"add %A0, r0 \n\t" \
|
"add %A0, r0 \n\t" \
|
||||||
"adc %B0, r1 \n\t" \
|
"adc %B0, r1 \n\t" \
|
||||||
"mul %A1, %C2 \n\t" \
|
"mul %A1, %C2 \n\t" \
|
||||||
"add r27, r0 \n\t" \
|
"add r27, r0 \n\t" \
|
||||||
"adc %A0, r1 \n\t" \
|
"adc %A0, r1 \n\t" \
|
||||||
"adc %B0, r26 \n\t" \
|
"adc %B0, r26 \n\t" \
|
||||||
"mul %B1, %B2 \n\t" \
|
"mul %B1, %B2 \n\t" \
|
||||||
"add r27, r0 \n\t" \
|
"add r27, r0 \n\t" \
|
||||||
"adc %A0, r1 \n\t" \
|
"adc %A0, r1 \n\t" \
|
||||||
"adc %B0, r26 \n\t" \
|
"adc %B0, r26 \n\t" \
|
||||||
"mul %C1, %A2 \n\t" \
|
"mul %C1, %A2 \n\t" \
|
||||||
"add r27, r0 \n\t" \
|
"add r27, r0 \n\t" \
|
||||||
"adc %A0, r1 \n\t" \
|
"adc %A0, r1 \n\t" \
|
||||||
"adc %B0, r26 \n\t" \
|
"adc %B0, r26 \n\t" \
|
||||||
"mul %B1, %A2 \n\t" \
|
"mul %B1, %A2 \n\t" \
|
||||||
"add r27, r1 \n\t" \
|
"add r27, r1 \n\t" \
|
||||||
"adc %A0, r26 \n\t" \
|
"adc %A0, r26 \n\t" \
|
||||||
"adc %B0, r26 \n\t" \
|
"adc %B0, r26 \n\t" \
|
||||||
"lsr r27 \n\t" \
|
"lsr r27 \n\t" \
|
||||||
"adc %A0, r26 \n\t" \
|
"adc %A0, r26 \n\t" \
|
||||||
"adc %B0, r26 \n\t" \
|
"adc %B0, r26 \n\t" \
|
||||||
"clr r1 \n\t" \
|
"clr r1 \n\t" \
|
||||||
: \
|
: \
|
||||||
"=&r" (intRes) \
|
"=&r" (intRes) \
|
||||||
: \
|
: \
|
||||||
"d" (longIn1), \
|
"d" (longIn1), \
|
||||||
"d" (longIn2) \
|
"d" (longIn2) \
|
||||||
: \
|
: \
|
||||||
"r26" , "r27" \
|
"r26" , "r27" \
|
||||||
)
|
)
|
||||||
|
|
||||||
// Some useful constants
|
// Some useful constants
|
||||||
|
|
||||||
#define ENABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 |= (1<<OCIE1A)
|
#define ENABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 |= (1<<OCIE1A)
|
||||||
#define DISABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 &= ~(1<<OCIE1A)
|
#define DISABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 &= ~(1<<OCIE1A)
|
||||||
|
|
||||||
block_t *current_block; // A pointer to the block currently being traced
|
block_t *current_block; // A pointer to the block currently being traced
|
||||||
|
|
||||||
// Variables used by The Stepper Driver Interrupt
|
// Variables used by The Stepper Driver Interrupt
|
||||||
static unsigned char out_bits; // The next stepping-bits to be output
|
static unsigned char out_bits; // The next stepping-bits to be output
|
||||||
static long counter_x, // Counter variables for the bresenham line tracer
|
static long counter_x, // Counter variables for the bresenham line tracer
|
||||||
counter_y,
|
counter_y,
|
||||||
counter_z,
|
counter_z,
|
||||||
counter_e;
|
counter_e;
|
||||||
static unsigned long step_events_completed; // The number of step events executed in the current block
|
static unsigned long step_events_completed; // The number of step events executed in the current block
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
static long advance_rate, advance, final_advance = 0;
|
static long advance_rate, advance, final_advance = 0;
|
||||||
static short old_advance = 0;
|
static short old_advance = 0;
|
||||||
static short e_steps;
|
static short e_steps;
|
||||||
#endif
|
#endif
|
||||||
static unsigned char busy = false; // TRUE when SIG_OUTPUT_COMPARE1A is being serviced. Used to avoid retriggering that handler.
|
static unsigned char busy = false; // TRUE when SIG_OUTPUT_COMPARE1A is being serviced. Used to avoid retriggering that handler.
|
||||||
static long acceleration_time, deceleration_time;
|
static long acceleration_time, deceleration_time;
|
||||||
//static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
|
//static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
|
||||||
static unsigned short acc_step_rate; // needed for deccelaration start point
|
static unsigned short acc_step_rate; // needed for deccelaration start point
|
||||||
static char step_loops;
|
static char step_loops;
|
||||||
|
|
||||||
|
|
||||||
// __________________________
|
// __________________________
|
||||||
// /| |\ _________________ ^
|
// /| |\ _________________ ^
|
||||||
// / | | \ /| |\ |
|
// / | | \ /| |\ |
|
||||||
// / | | \ / | | \ s
|
// / | | \ / | | \ s
|
||||||
// / | | | | | \ p
|
// / | | | | | \ p
|
||||||
// / | | | | | \ e
|
// / | | | | | \ e
|
||||||
// +-----+------------------------+---+--+---------------+----+ e
|
// +-----+------------------------+---+--+---------------+----+ e
|
||||||
// | BLOCK 1 | BLOCK 2 | d
|
// | BLOCK 1 | BLOCK 2 | d
|
||||||
//
|
//
|
||||||
// time ----->
|
// time ----->
|
||||||
//
|
//
|
||||||
// The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
|
// The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
|
||||||
// first block->accelerate_until step_events_completed, then keeps going at constant speed until
|
// first block->accelerate_until step_events_completed, then keeps going at constant speed until
|
||||||
// step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
|
// step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
|
||||||
// The slope of acceleration is calculated with the leib ramp alghorithm.
|
// The slope of acceleration is calculated with the leib ramp alghorithm.
|
||||||
|
|
||||||
void st_wake_up() {
|
void st_wake_up() {
|
||||||
// TCNT1 = 0;
|
// TCNT1 = 0;
|
||||||
ENABLE_STEPPER_DRIVER_INTERRUPT();
|
ENABLE_STEPPER_DRIVER_INTERRUPT();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned short calc_timer(unsigned short step_rate) {
|
inline unsigned short calc_timer(unsigned short step_rate) {
|
||||||
unsigned short timer;
|
unsigned short timer;
|
||||||
if(step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY;
|
if(step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY;
|
||||||
|
|
||||||
if(step_rate > 20000) { // If steprate > 20kHz >> step 4 times
|
if(step_rate > 20000) { // If steprate > 20kHz >> step 4 times
|
||||||
step_rate = step_rate >> 2;
|
step_rate = step_rate >> 2;
|
||||||
step_loops = 4;
|
step_loops = 4;
|
||||||
}
|
}
|
||||||
else if(step_rate > 10000) { // If steprate > 10kHz >> step 2 times
|
else if(step_rate > 10000) { // If steprate > 10kHz >> step 2 times
|
||||||
step_rate = step_rate >> 1;
|
step_rate = step_rate >> 1;
|
||||||
step_loops = 2;
|
step_loops = 2;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
step_loops = 1;
|
step_loops = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(step_rate < 32) step_rate = 32;
|
if(step_rate < 32) step_rate = 32;
|
||||||
step_rate -= 32; // Correct for minimal speed
|
step_rate -= 32; // Correct for minimal speed
|
||||||
if(step_rate >= (8*256)){ // higher step rate
|
if(step_rate >= (8*256)){ // higher step rate
|
||||||
unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0];
|
unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0];
|
||||||
unsigned char tmp_step_rate = (step_rate & 0x00ff);
|
unsigned char tmp_step_rate = (step_rate & 0x00ff);
|
||||||
unsigned short gain = (unsigned short)pgm_read_word_near(table_address+2);
|
unsigned short gain = (unsigned short)pgm_read_word_near(table_address+2);
|
||||||
MultiU16X8toH16(timer, tmp_step_rate, gain);
|
MultiU16X8toH16(timer, tmp_step_rate, gain);
|
||||||
timer = (unsigned short)pgm_read_word_near(table_address) - timer;
|
timer = (unsigned short)pgm_read_word_near(table_address) - timer;
|
||||||
}
|
}
|
||||||
else { // lower step rates
|
else { // lower step rates
|
||||||
unsigned short table_address = (unsigned short)&speed_lookuptable_slow[0][0];
|
unsigned short table_address = (unsigned short)&speed_lookuptable_slow[0][0];
|
||||||
table_address += ((step_rate)>>1) & 0xfffc;
|
table_address += ((step_rate)>>1) & 0xfffc;
|
||||||
timer = (unsigned short)pgm_read_word_near(table_address);
|
timer = (unsigned short)pgm_read_word_near(table_address);
|
||||||
timer -= (((unsigned short)pgm_read_word_near(table_address+2) * (unsigned char)(step_rate & 0x0007))>>3);
|
timer -= (((unsigned short)pgm_read_word_near(table_address+2) * (unsigned char)(step_rate & 0x0007))>>3);
|
||||||
}
|
}
|
||||||
if(timer < 100) timer = 100;
|
if(timer < 100) timer = 100;
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes the trapezoid generator from the current block. Called whenever a new
|
// Initializes the trapezoid generator from the current block. Called whenever a new
|
||||||
// block begins.
|
// block begins.
|
||||||
inline void trapezoid_generator_reset() {
|
inline void trapezoid_generator_reset() {
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
advance = current_block->initial_advance;
|
advance = current_block->initial_advance;
|
||||||
final_advance = current_block->final_advance;
|
final_advance = current_block->final_advance;
|
||||||
#endif
|
#endif
|
||||||
deceleration_time = 0;
|
deceleration_time = 0;
|
||||||
// advance_rate = current_block->advance_rate;
|
// advance_rate = current_block->advance_rate;
|
||||||
// step_rate to timer interval
|
// step_rate to timer interval
|
||||||
acc_step_rate = current_block->initial_rate;
|
acc_step_rate = current_block->initial_rate;
|
||||||
acceleration_time = calc_timer(acc_step_rate);
|
acceleration_time = calc_timer(acc_step_rate);
|
||||||
OCR1A = acceleration_time;
|
OCR1A = acceleration_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "The Stepper Driver Interrupt" - This timer interrupt is the workhorse.
|
// "The Stepper Driver Interrupt" - This timer interrupt is the workhorse.
|
||||||
// It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately.
|
// It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately.
|
||||||
ISR(TIMER1_COMPA_vect)
|
ISR(TIMER1_COMPA_vect)
|
||||||
{
|
{
|
||||||
if(busy){ Serial.print(*(unsigned short *)OCR1A); Serial.println(" BUSY");
|
if(busy){ Serial.print(*(unsigned short *)OCR1A); Serial.println(" BUSY");
|
||||||
return;
|
return;
|
||||||
} // The busy-flag is used to avoid reentering this interrupt
|
} // The busy-flag is used to avoid reentering this interrupt
|
||||||
|
|
||||||
busy = true;
|
busy = true;
|
||||||
sei(); // Re enable interrupts (normally disabled while inside an interrupt handler)
|
sei(); // Re enable interrupts (normally disabled while inside an interrupt handler)
|
||||||
|
|
||||||
// If there is no current block, attempt to pop one from the buffer
|
// If there is no current block, attempt to pop one from the buffer
|
||||||
if (current_block == NULL) {
|
if (current_block == NULL) {
|
||||||
// Anything in the buffer?
|
// Anything in the buffer?
|
||||||
current_block = plan_get_current_block();
|
current_block = plan_get_current_block();
|
||||||
if (current_block != NULL) {
|
if (current_block != NULL) {
|
||||||
trapezoid_generator_reset();
|
trapezoid_generator_reset();
|
||||||
counter_x = -(current_block->step_event_count >> 1);
|
counter_x = -(current_block->step_event_count >> 1);
|
||||||
counter_y = counter_x;
|
counter_y = counter_x;
|
||||||
counter_z = counter_x;
|
counter_z = counter_x;
|
||||||
counter_e = counter_x;
|
counter_e = counter_x;
|
||||||
step_events_completed = 0;
|
step_events_completed = 0;
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
e_steps = 0;
|
e_steps = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// DISABLE_STEPPER_DRIVER_INTERRUPT();
|
// DISABLE_STEPPER_DRIVER_INTERRUPT();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_block != NULL) {
|
if (current_block != NULL) {
|
||||||
// Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt
|
// Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt
|
||||||
out_bits = current_block->direction_bits;
|
out_bits = current_block->direction_bits;
|
||||||
|
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
// Calculate E early.
|
// Calculate E early.
|
||||||
counter_e += current_block->steps_e;
|
counter_e += current_block->steps_e;
|
||||||
if (counter_e > 0) {
|
if (counter_e > 0) {
|
||||||
counter_e -= current_block->step_event_count;
|
counter_e -= current_block->step_event_count;
|
||||||
if ((out_bits & (1<<E_AXIS)) != 0) { // - direction
|
if ((out_bits & (1<<E_AXIS)) != 0) { // - direction
|
||||||
CRITICAL_SECTION_START;
|
CRITICAL_SECTION_START;
|
||||||
e_steps--;
|
e_steps--;
|
||||||
CRITICAL_SECTION_END;
|
CRITICAL_SECTION_END;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CRITICAL_SECTION_START;
|
CRITICAL_SECTION_START;
|
||||||
e_steps++;
|
e_steps++;
|
||||||
CRITICAL_SECTION_END;
|
CRITICAL_SECTION_END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Do E steps + advance steps
|
// Do E steps + advance steps
|
||||||
CRITICAL_SECTION_START;
|
CRITICAL_SECTION_START;
|
||||||
e_steps += ((advance >> 16) - old_advance);
|
e_steps += ((advance >> 16) - old_advance);
|
||||||
CRITICAL_SECTION_END;
|
CRITICAL_SECTION_END;
|
||||||
old_advance = advance >> 16;
|
old_advance = advance >> 16;
|
||||||
#endif //ADVANCE
|
#endif //ADVANCE
|
||||||
|
|
||||||
// Set direction en check limit switches
|
// Set direction en check limit switches
|
||||||
if ((out_bits & (1<<X_AXIS)) != 0) { // -direction
|
if ((out_bits & (1<<X_AXIS)) != 0) { // -direction
|
||||||
WRITE(X_DIR_PIN, INVERT_X_DIR);
|
WRITE(X_DIR_PIN, INVERT_X_DIR);
|
||||||
#ifdef DEBUG_STEPS
|
#ifdef DEBUG_STEPS
|
||||||
count_direction[X_AXIS]=-1;
|
count_direction[X_AXIS]=-1;
|
||||||
#endif
|
#endif
|
||||||
#if X_MIN_PIN > -1
|
#if X_MIN_PIN > -1
|
||||||
if(READ(X_MIN_PIN) != ENDSTOPS_INVERTING) {
|
if(READ(X_MIN_PIN) != ENDSTOPS_INVERTING) {
|
||||||
step_events_completed = current_block->step_event_count;
|
step_events_completed = current_block->step_event_count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else { // +direction
|
else { // +direction
|
||||||
WRITE(X_DIR_PIN,!INVERT_X_DIR);
|
WRITE(X_DIR_PIN,!INVERT_X_DIR);
|
||||||
#ifdef DEBUG_STEPS
|
#ifdef DEBUG_STEPS
|
||||||
count_direction[X_AXIS]=1;
|
count_direction[X_AXIS]=1;
|
||||||
#endif
|
#endif
|
||||||
#if X_MAX_PIN > -1
|
#if X_MAX_PIN > -1
|
||||||
if((READ(X_MAX_PIN) != ENDSTOPS_INVERTING) && (current_block->steps_x >0)){
|
if((READ(X_MAX_PIN) != ENDSTOPS_INVERTING) && (current_block->steps_x >0)){
|
||||||
step_events_completed = current_block->step_event_count;
|
step_events_completed = current_block->step_event_count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((out_bits & (1<<Y_AXIS)) != 0) { // -direction
|
if ((out_bits & (1<<Y_AXIS)) != 0) { // -direction
|
||||||
WRITE(Y_DIR_PIN,INVERT_Y_DIR);
|
WRITE(Y_DIR_PIN,INVERT_Y_DIR);
|
||||||
#ifdef DEBUG_STEPS
|
#ifdef DEBUG_STEPS
|
||||||
count_direction[Y_AXIS]=-1;
|
count_direction[Y_AXIS]=-1;
|
||||||
#endif
|
#endif
|
||||||
#if Y_MIN_PIN > -1
|
#if Y_MIN_PIN > -1
|
||||||
if(READ(Y_MIN_PIN) != ENDSTOPS_INVERTING) {
|
if(READ(Y_MIN_PIN) != ENDSTOPS_INVERTING) {
|
||||||
step_events_completed = current_block->step_event_count;
|
step_events_completed = current_block->step_event_count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else { // +direction
|
else { // +direction
|
||||||
WRITE(Y_DIR_PIN,!INVERT_Y_DIR);
|
WRITE(Y_DIR_PIN,!INVERT_Y_DIR);
|
||||||
#ifdef DEBUG_STEPS
|
#ifdef DEBUG_STEPS
|
||||||
count_direction[Y_AXIS]=1;
|
count_direction[Y_AXIS]=1;
|
||||||
#endif
|
#endif
|
||||||
#if Y_MAX_PIN > -1
|
#if Y_MAX_PIN > -1
|
||||||
if((READ(Y_MAX_PIN) != ENDSTOPS_INVERTING) && (current_block->steps_y >0)){
|
if((READ(Y_MAX_PIN) != ENDSTOPS_INVERTING) && (current_block->steps_y >0)){
|
||||||
step_events_completed = current_block->step_event_count;
|
step_events_completed = current_block->step_event_count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((out_bits & (1<<Z_AXIS)) != 0) { // -direction
|
if ((out_bits & (1<<Z_AXIS)) != 0) { // -direction
|
||||||
WRITE(Z_DIR_PIN,INVERT_Z_DIR);
|
WRITE(Z_DIR_PIN,INVERT_Z_DIR);
|
||||||
#ifdef DEBUG_STEPS
|
#ifdef DEBUG_STEPS
|
||||||
count_direction[Z_AXIS]=-1;
|
count_direction[Z_AXIS]=-1;
|
||||||
#endif
|
#endif
|
||||||
#if Z_MIN_PIN > -1
|
#if Z_MIN_PIN > -1
|
||||||
if(READ(Z_MIN_PIN) != ENDSTOPS_INVERTING) {
|
if(READ(Z_MIN_PIN) != ENDSTOPS_INVERTING) {
|
||||||
step_events_completed = current_block->step_event_count;
|
step_events_completed = current_block->step_event_count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else { // +direction
|
else { // +direction
|
||||||
WRITE(Z_DIR_PIN,!INVERT_Z_DIR);
|
WRITE(Z_DIR_PIN,!INVERT_Z_DIR);
|
||||||
#ifdef DEBUG_STEPS
|
#ifdef DEBUG_STEPS
|
||||||
count_direction[Z_AXIS]=1;
|
count_direction[Z_AXIS]=1;
|
||||||
#endif
|
#endif
|
||||||
#if Z_MAX_PIN > -1
|
#if Z_MAX_PIN > -1
|
||||||
if((READ(Z_MAX_PIN) != ENDSTOPS_INVERTING) && (current_block->steps_z >0)){
|
if((READ(Z_MAX_PIN) != ENDSTOPS_INVERTING) && (current_block->steps_z >0)){
|
||||||
step_events_completed = current_block->step_event_count;
|
step_events_completed = current_block->step_event_count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ADVANCE
|
#ifndef ADVANCE
|
||||||
if ((out_bits & (1<<E_AXIS)) != 0) // -direction
|
if ((out_bits & (1<<E_AXIS)) != 0) // -direction
|
||||||
WRITE(E_DIR_PIN,INVERT_E_DIR);
|
WRITE(E_DIR_PIN,INVERT_E_DIR);
|
||||||
else // +direction
|
else // +direction
|
||||||
WRITE(E_DIR_PIN,!INVERT_E_DIR);
|
WRITE(E_DIR_PIN,!INVERT_E_DIR);
|
||||||
#endif //!ADVANCE
|
#endif //!ADVANCE
|
||||||
|
|
||||||
for(char i=0; i < step_loops; i++) { // Take multiple steps per interrupt (For high speed moves)
|
for(char i=0; i < step_loops; i++) { // Take multiple steps per interrupt (For high speed moves)
|
||||||
counter_x += current_block->steps_x;
|
counter_x += current_block->steps_x;
|
||||||
if (counter_x > 0) {
|
if (counter_x > 0) {
|
||||||
WRITE(X_STEP_PIN, HIGH);
|
WRITE(X_STEP_PIN, HIGH);
|
||||||
counter_x -= current_block->step_event_count;
|
counter_x -= current_block->step_event_count;
|
||||||
WRITE(X_STEP_PIN, LOW);
|
WRITE(X_STEP_PIN, LOW);
|
||||||
#ifdef DEBUG_STEPS
|
#ifdef DEBUG_STEPS
|
||||||
count_position[X_AXIS]+=count_direction[X_AXIS];
|
count_position[X_AXIS]+=count_direction[X_AXIS];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
counter_y += current_block->steps_y;
|
counter_y += current_block->steps_y;
|
||||||
if (counter_y > 0) {
|
if (counter_y > 0) {
|
||||||
WRITE(Y_STEP_PIN, HIGH);
|
WRITE(Y_STEP_PIN, HIGH);
|
||||||
counter_y -= current_block->step_event_count;
|
counter_y -= current_block->step_event_count;
|
||||||
WRITE(Y_STEP_PIN, LOW);
|
WRITE(Y_STEP_PIN, LOW);
|
||||||
#ifdef DEBUG_STEPS
|
#ifdef DEBUG_STEPS
|
||||||
count_position[Y_AXIS]+=count_direction[Y_AXIS];
|
count_position[Y_AXIS]+=count_direction[Y_AXIS];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
counter_z += current_block->steps_z;
|
counter_z += current_block->steps_z;
|
||||||
if (counter_z > 0) {
|
if (counter_z > 0) {
|
||||||
WRITE(Z_STEP_PIN, HIGH);
|
WRITE(Z_STEP_PIN, HIGH);
|
||||||
counter_z -= current_block->step_event_count;
|
counter_z -= current_block->step_event_count;
|
||||||
WRITE(Z_STEP_PIN, LOW);
|
WRITE(Z_STEP_PIN, LOW);
|
||||||
#ifdef DEBUG_STEPS
|
#ifdef DEBUG_STEPS
|
||||||
count_position[Z_AXIS]+=count_direction[Z_AXIS];
|
count_position[Z_AXIS]+=count_direction[Z_AXIS];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ADVANCE
|
#ifndef ADVANCE
|
||||||
counter_e += current_block->steps_e;
|
counter_e += current_block->steps_e;
|
||||||
if (counter_e > 0) {
|
if (counter_e > 0) {
|
||||||
WRITE(E_STEP_PIN, HIGH);
|
WRITE(E_STEP_PIN, HIGH);
|
||||||
counter_e -= current_block->step_event_count;
|
counter_e -= current_block->step_event_count;
|
||||||
WRITE(E_STEP_PIN, LOW);
|
WRITE(E_STEP_PIN, LOW);
|
||||||
}
|
}
|
||||||
#endif //!ADVANCE
|
#endif //!ADVANCE
|
||||||
step_events_completed += 1;
|
step_events_completed += 1;
|
||||||
if(step_events_completed >= current_block->step_event_count) break;
|
if(step_events_completed >= current_block->step_event_count) break;
|
||||||
}
|
}
|
||||||
// Calculare new timer value
|
// Calculare new timer value
|
||||||
unsigned short timer;
|
unsigned short timer;
|
||||||
unsigned short step_rate;
|
unsigned short step_rate;
|
||||||
if (step_events_completed <= current_block->accelerate_until) {
|
if (step_events_completed <= current_block->accelerate_until) {
|
||||||
MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate);
|
MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate);
|
||||||
acc_step_rate += current_block->initial_rate;
|
acc_step_rate += current_block->initial_rate;
|
||||||
|
|
||||||
// upper limit
|
// upper limit
|
||||||
if(acc_step_rate > current_block->nominal_rate)
|
if(acc_step_rate > current_block->nominal_rate)
|
||||||
acc_step_rate = current_block->nominal_rate;
|
acc_step_rate = current_block->nominal_rate;
|
||||||
|
|
||||||
// step_rate to timer interval
|
// step_rate to timer interval
|
||||||
timer = calc_timer(acc_step_rate);
|
timer = calc_timer(acc_step_rate);
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
advance += advance_rate;
|
advance += advance_rate;
|
||||||
#endif
|
#endif
|
||||||
acceleration_time += timer;
|
acceleration_time += timer;
|
||||||
OCR1A = timer;
|
OCR1A = timer;
|
||||||
}
|
}
|
||||||
else if (step_events_completed > current_block->decelerate_after) {
|
else if (step_events_completed > current_block->decelerate_after) {
|
||||||
MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate);
|
MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate);
|
||||||
|
|
||||||
if(step_rate > acc_step_rate) { // Check step_rate stays positive
|
if(step_rate > acc_step_rate) { // Check step_rate stays positive
|
||||||
step_rate = current_block->final_rate;
|
step_rate = current_block->final_rate;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
step_rate = acc_step_rate - step_rate; // Decelerate from aceleration end point.
|
step_rate = acc_step_rate - step_rate; // Decelerate from aceleration end point.
|
||||||
}
|
}
|
||||||
|
|
||||||
// lower limit
|
// lower limit
|
||||||
if(step_rate < current_block->final_rate)
|
if(step_rate < current_block->final_rate)
|
||||||
step_rate = current_block->final_rate;
|
step_rate = current_block->final_rate;
|
||||||
|
|
||||||
// step_rate to timer interval
|
// step_rate to timer interval
|
||||||
timer = calc_timer(step_rate);
|
timer = calc_timer(step_rate);
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
advance -= advance_rate;
|
advance -= advance_rate;
|
||||||
if(advance < final_advance)
|
if(advance < final_advance)
|
||||||
advance = final_advance;
|
advance = final_advance;
|
||||||
#endif //ADVANCE
|
#endif //ADVANCE
|
||||||
deceleration_time += timer;
|
deceleration_time += timer;
|
||||||
OCR1A = timer;
|
OCR1A = timer;
|
||||||
}
|
}
|
||||||
// If current block is finished, reset pointer
|
// If current block is finished, reset pointer
|
||||||
if (step_events_completed >= current_block->step_event_count) {
|
if (step_events_completed >= current_block->step_event_count) {
|
||||||
current_block = NULL;
|
current_block = NULL;
|
||||||
plan_discard_current_block();
|
plan_discard_current_block();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cli(); // disable interrupts
|
cli(); // disable interrupts
|
||||||
busy=false;
|
busy=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
|
|
||||||
unsigned char old_OCR0A;
|
unsigned char old_OCR0A;
|
||||||
// Timer interrupt for E. e_steps is set in the main routine;
|
// Timer interrupt for E. e_steps is set in the main routine;
|
||||||
// Timer 0 is shared with millies
|
// Timer 0 is shared with millies
|
||||||
ISR(TIMER0_COMPA_vect)
|
ISR(TIMER0_COMPA_vect)
|
||||||
{
|
{
|
||||||
// Critical section needed because Timer 1 interrupt has higher priority.
|
// Critical section needed because Timer 1 interrupt has higher priority.
|
||||||
// The pin set functions are placed on trategic position to comply with the stepper driver timing.
|
// The pin set functions are placed on trategic position to comply with the stepper driver timing.
|
||||||
WRITE(E_STEP_PIN, LOW);
|
WRITE(E_STEP_PIN, LOW);
|
||||||
// Set E direction (Depends on E direction + advance)
|
// Set E direction (Depends on E direction + advance)
|
||||||
if (e_steps < 0) {
|
if (e_steps < 0) {
|
||||||
WRITE(E_DIR_PIN,INVERT_E_DIR);
|
WRITE(E_DIR_PIN,INVERT_E_DIR);
|
||||||
e_steps++;
|
e_steps++;
|
||||||
WRITE(E_STEP_PIN, HIGH);
|
WRITE(E_STEP_PIN, HIGH);
|
||||||
}
|
}
|
||||||
if (e_steps > 0) {
|
if (e_steps > 0) {
|
||||||
WRITE(E_DIR_PIN,!INVERT_E_DIR);
|
WRITE(E_DIR_PIN,!INVERT_E_DIR);
|
||||||
e_steps--;
|
e_steps--;
|
||||||
WRITE(E_STEP_PIN, HIGH);
|
WRITE(E_STEP_PIN, HIGH);
|
||||||
}
|
}
|
||||||
old_OCR0A += 25; // 10kHz interrupt
|
old_OCR0A += 25; // 10kHz interrupt
|
||||||
OCR0A = old_OCR0A;
|
OCR0A = old_OCR0A;
|
||||||
}
|
}
|
||||||
#endif // ADVANCE
|
#endif // ADVANCE
|
||||||
|
|
||||||
void st_init()
|
void st_init()
|
||||||
{
|
{
|
||||||
//Initialize Dir Pins
|
//Initialize Dir Pins
|
||||||
#if X_DIR_PIN > -1
|
#if X_DIR_PIN > -1
|
||||||
SET_OUTPUT(X_DIR_PIN);
|
SET_OUTPUT(X_DIR_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if Y_DIR_PIN > -1
|
#if Y_DIR_PIN > -1
|
||||||
SET_OUTPUT(Y_DIR_PIN);
|
SET_OUTPUT(Y_DIR_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if Z_DIR_PIN > -1
|
#if Z_DIR_PIN > -1
|
||||||
SET_OUTPUT(Z_DIR_PIN);
|
SET_OUTPUT(Z_DIR_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if E_DIR_PIN > -1
|
#if E_DIR_PIN > -1
|
||||||
SET_OUTPUT(E_DIR_PIN);
|
SET_OUTPUT(E_DIR_PIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Initialize Enable Pins - steppers default to disabled.
|
//Initialize Enable Pins - steppers default to disabled.
|
||||||
|
|
||||||
#if (X_ENABLE_PIN > -1)
|
#if (X_ENABLE_PIN > -1)
|
||||||
SET_OUTPUT(X_ENABLE_PIN);
|
SET_OUTPUT(X_ENABLE_PIN);
|
||||||
if(!X_ENABLE_ON) WRITE(X_ENABLE_PIN,HIGH);
|
if(!X_ENABLE_ON) WRITE(X_ENABLE_PIN,HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if (Y_ENABLE_PIN > -1)
|
#if (Y_ENABLE_PIN > -1)
|
||||||
SET_OUTPUT(Y_ENABLE_PIN);
|
SET_OUTPUT(Y_ENABLE_PIN);
|
||||||
if(!Y_ENABLE_ON) WRITE(Y_ENABLE_PIN,HIGH);
|
if(!Y_ENABLE_ON) WRITE(Y_ENABLE_PIN,HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if (Z_ENABLE_PIN > -1)
|
#if (Z_ENABLE_PIN > -1)
|
||||||
SET_OUTPUT(Z_ENABLE_PIN);
|
SET_OUTPUT(Z_ENABLE_PIN);
|
||||||
if(!Z_ENABLE_ON) WRITE(Z_ENABLE_PIN,HIGH);
|
if(!Z_ENABLE_ON) WRITE(Z_ENABLE_PIN,HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if (E_ENABLE_PIN > -1)
|
#if (E_ENABLE_PIN > -1)
|
||||||
SET_OUTPUT(E_ENABLE_PIN);
|
SET_OUTPUT(E_ENABLE_PIN);
|
||||||
if(!E_ENABLE_ON) WRITE(E_ENABLE_PIN,HIGH);
|
if(!E_ENABLE_ON) WRITE(E_ENABLE_PIN,HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//endstops and pullups
|
//endstops and pullups
|
||||||
#ifdef ENDSTOPPULLUPS
|
#ifdef ENDSTOPPULLUPS
|
||||||
#if X_MIN_PIN > -1
|
#if X_MIN_PIN > -1
|
||||||
SET_INPUT(X_MIN_PIN);
|
SET_INPUT(X_MIN_PIN);
|
||||||
WRITE(X_MIN_PIN,HIGH);
|
WRITE(X_MIN_PIN,HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if X_MAX_PIN > -1
|
#if X_MAX_PIN > -1
|
||||||
SET_INPUT(X_MAX_PIN);
|
SET_INPUT(X_MAX_PIN);
|
||||||
WRITE(X_MAX_PIN,HIGH);
|
WRITE(X_MAX_PIN,HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if Y_MIN_PIN > -1
|
#if Y_MIN_PIN > -1
|
||||||
SET_INPUT(Y_MIN_PIN);
|
SET_INPUT(Y_MIN_PIN);
|
||||||
WRITE(Y_MIN_PIN,HIGH);
|
WRITE(Y_MIN_PIN,HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if Y_MAX_PIN > -1
|
#if Y_MAX_PIN > -1
|
||||||
SET_INPUT(Y_MAX_PIN);
|
SET_INPUT(Y_MAX_PIN);
|
||||||
WRITE(Y_MAX_PIN,HIGH);
|
WRITE(Y_MAX_PIN,HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if Z_MIN_PIN > -1
|
#if Z_MIN_PIN > -1
|
||||||
SET_INPUT(Z_MIN_PIN);
|
SET_INPUT(Z_MIN_PIN);
|
||||||
WRITE(Z_MIN_PIN,HIGH);
|
WRITE(Z_MIN_PIN,HIGH);
|
||||||
#endif
|
#endif
|
||||||
#if Z_MAX_PIN > -1
|
#if Z_MAX_PIN > -1
|
||||||
SET_INPUT(Z_MAX_PIN);
|
SET_INPUT(Z_MAX_PIN);
|
||||||
WRITE(Z_MAX_PIN,HIGH);
|
WRITE(Z_MAX_PIN,HIGH);
|
||||||
#endif
|
#endif
|
||||||
#else //ENDSTOPPULLUPS
|
#else //ENDSTOPPULLUPS
|
||||||
#if X_MIN_PIN > -1
|
#if X_MIN_PIN > -1
|
||||||
SET_INPUT(X_MIN_PIN);
|
SET_INPUT(X_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if X_MAX_PIN > -1
|
#if X_MAX_PIN > -1
|
||||||
SET_INPUT(X_MAX_PIN);
|
SET_INPUT(X_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if Y_MIN_PIN > -1
|
#if Y_MIN_PIN > -1
|
||||||
SET_INPUT(Y_MIN_PIN);
|
SET_INPUT(Y_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if Y_MAX_PIN > -1
|
#if Y_MAX_PIN > -1
|
||||||
SET_INPUT(Y_MAX_PIN);
|
SET_INPUT(Y_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if Z_MIN_PIN > -1
|
#if Z_MIN_PIN > -1
|
||||||
SET_INPUT(Z_MIN_PIN);
|
SET_INPUT(Z_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if Z_MAX_PIN > -1
|
#if Z_MAX_PIN > -1
|
||||||
SET_INPUT(Z_MAX_PIN);
|
SET_INPUT(Z_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif //ENDSTOPPULLUPS
|
#endif //ENDSTOPPULLUPS
|
||||||
|
|
||||||
|
|
||||||
//Initialize Step Pins
|
//Initialize Step Pins
|
||||||
#if (X_STEP_PIN > -1)
|
#if (X_STEP_PIN > -1)
|
||||||
SET_OUTPUT(X_STEP_PIN);
|
SET_OUTPUT(X_STEP_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if (Y_STEP_PIN > -1)
|
#if (Y_STEP_PIN > -1)
|
||||||
SET_OUTPUT(Y_STEP_PIN);
|
SET_OUTPUT(Y_STEP_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if (Z_STEP_PIN > -1)
|
#if (Z_STEP_PIN > -1)
|
||||||
SET_OUTPUT(Z_STEP_PIN);
|
SET_OUTPUT(Z_STEP_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if (E_STEP_PIN > -1)
|
#if (E_STEP_PIN > -1)
|
||||||
SET_OUTPUT(E_STEP_PIN);
|
SET_OUTPUT(E_STEP_PIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// waveform generation = 0100 = CTC
|
// waveform generation = 0100 = CTC
|
||||||
TCCR1B &= ~(1<<WGM13);
|
TCCR1B &= ~(1<<WGM13);
|
||||||
TCCR1B |= (1<<WGM12);
|
TCCR1B |= (1<<WGM12);
|
||||||
TCCR1A &= ~(1<<WGM11);
|
TCCR1A &= ~(1<<WGM11);
|
||||||
TCCR1A &= ~(1<<WGM10);
|
TCCR1A &= ~(1<<WGM10);
|
||||||
|
|
||||||
// output mode = 00 (disconnected)
|
// output mode = 00 (disconnected)
|
||||||
TCCR1A &= ~(3<<COM1A0);
|
TCCR1A &= ~(3<<COM1A0);
|
||||||
TCCR1A &= ~(3<<COM1B0);
|
TCCR1A &= ~(3<<COM1B0);
|
||||||
TCCR1B = (TCCR1B & ~(0x07<<CS10)) | (2<<CS10); // 2MHz timer
|
TCCR1B = (TCCR1B & ~(0x07<<CS10)) | (2<<CS10); // 2MHz timer
|
||||||
|
|
||||||
OCR1A = 0x4000;
|
OCR1A = 0x4000;
|
||||||
DISABLE_STEPPER_DRIVER_INTERRUPT();
|
DISABLE_STEPPER_DRIVER_INTERRUPT();
|
||||||
|
|
||||||
#ifdef ADVANCE
|
#ifdef ADVANCE
|
||||||
e_steps = 0;
|
e_steps = 0;
|
||||||
TIMSK0 |= (1<<OCIE0A);
|
TIMSK0 |= (1<<OCIE0A);
|
||||||
#endif //ADVANCE
|
#endif //ADVANCE
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block until all buffered steps are executed
|
// Block until all buffered steps are executed
|
||||||
void st_synchronize()
|
void st_synchronize()
|
||||||
{
|
{
|
||||||
while(plan_get_current_block()) {
|
while(plan_get_current_block()) {
|
||||||
manage_heater();
|
manage_heater();
|
||||||
manage_inactivity(1);
|
manage_inactivity(1);
|
||||||
LCD_STATUS;
|
LCD_STATUS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,84 +1,84 @@
|
||||||
/*
|
/*
|
||||||
Streaming.h - Arduino library for supporting the << streaming operator
|
Streaming.h - Arduino library for supporting the << streaming operator
|
||||||
Copyright (c) 2010 Mikal Hart. All rights reserved.
|
Copyright (c) 2010 Mikal Hart. All rights reserved.
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
License as published by the Free Software Foundation; either
|
License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
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,
|
This library is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
Lesser General Public License for more details.
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this library; if not, write to the Free Software
|
License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ARDUINO_STREAMING
|
#ifndef ARDUINO_STREAMING
|
||||||
#define ARDUINO_STREAMING
|
#define ARDUINO_STREAMING
|
||||||
|
|
||||||
//#include <WProgram.h>
|
//#include <WProgram.h>
|
||||||
|
|
||||||
#define STREAMING_LIBRARY_VERSION 4
|
#define STREAMING_LIBRARY_VERSION 4
|
||||||
|
|
||||||
// Generic template
|
// Generic template
|
||||||
template<class T>
|
template<class T>
|
||||||
inline Print &operator <<(Print &stream, T arg)
|
inline Print &operator <<(Print &stream, T arg)
|
||||||
{ stream.print(arg); return stream; }
|
{ stream.print(arg); return stream; }
|
||||||
|
|
||||||
struct _BASED
|
struct _BASED
|
||||||
{
|
{
|
||||||
long val;
|
long val;
|
||||||
int base;
|
int base;
|
||||||
_BASED(long v, int b): val(v), base(b)
|
_BASED(long v, int b): val(v), base(b)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define _HEX(a) _BASED(a, HEX)
|
#define _HEX(a) _BASED(a, HEX)
|
||||||
#define _DEC(a) _BASED(a, DEC)
|
#define _DEC(a) _BASED(a, DEC)
|
||||||
#define _OCT(a) _BASED(a, OCT)
|
#define _OCT(a) _BASED(a, OCT)
|
||||||
#define _BIN(a) _BASED(a, BIN)
|
#define _BIN(a) _BASED(a, BIN)
|
||||||
#define _BYTE(a) _BASED(a, BYTE)
|
#define _BYTE(a) _BASED(a, BYTE)
|
||||||
|
|
||||||
// Specialization for class _BASED
|
// Specialization for class _BASED
|
||||||
// Thanks to Arduino forum user Ben Combee who suggested this
|
// Thanks to Arduino forum user Ben Combee who suggested this
|
||||||
// clever technique to allow for expressions like
|
// clever technique to allow for expressions like
|
||||||
// Serial << _HEX(a);
|
// Serial << _HEX(a);
|
||||||
|
|
||||||
inline Print &operator <<(Print &obj, const _BASED &arg)
|
inline Print &operator <<(Print &obj, const _BASED &arg)
|
||||||
{ obj.print(arg.val, arg.base); return obj; }
|
{ obj.print(arg.val, arg.base); return obj; }
|
||||||
|
|
||||||
#if ARDUINO >= 18
|
#if ARDUINO >= 18
|
||||||
// Specialization for class _FLOAT
|
// Specialization for class _FLOAT
|
||||||
// Thanks to Michael Margolis for suggesting a way
|
// Thanks to Michael Margolis for suggesting a way
|
||||||
// to accommodate Arduino 0018's floating point precision
|
// to accommodate Arduino 0018's floating point precision
|
||||||
// feature like this:
|
// feature like this:
|
||||||
// Serial << _FLOAT(gps_latitude, 6); // 6 digits of precision
|
// Serial << _FLOAT(gps_latitude, 6); // 6 digits of precision
|
||||||
|
|
||||||
struct _FLOAT
|
struct _FLOAT
|
||||||
{
|
{
|
||||||
float val;
|
float val;
|
||||||
int digits;
|
int digits;
|
||||||
_FLOAT(double v, int d): val(v), digits(d)
|
_FLOAT(double v, int d): val(v), digits(d)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Print &operator <<(Print &obj, const _FLOAT &arg)
|
inline Print &operator <<(Print &obj, const _FLOAT &arg)
|
||||||
{ obj.print(arg.val, arg.digits); return obj; }
|
{ obj.print(arg.val, arg.digits); return obj; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Specialization for enum _EndLineCode
|
// Specialization for enum _EndLineCode
|
||||||
// Thanks to Arduino forum user Paul V. who suggested this
|
// Thanks to Arduino forum user Paul V. who suggested this
|
||||||
// clever technique to allow for expressions like
|
// clever technique to allow for expressions like
|
||||||
// Serial << "Hello!" << endl;
|
// Serial << "Hello!" << endl;
|
||||||
|
|
||||||
enum _EndLineCode { endl };
|
enum _EndLineCode { endl };
|
||||||
|
|
||||||
inline Print &operator <<(Print &obj, _EndLineCode arg)
|
inline Print &operator <<(Print &obj, _EndLineCode arg)
|
||||||
{ obj.println(); return obj; }
|
{ obj.println(); return obj; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,483 +1,483 @@
|
||||||
/*
|
/*
|
||||||
temperature.c - temperature control
|
temperature.c - temperature control
|
||||||
Part of Marlin
|
Part of Marlin
|
||||||
|
|
||||||
Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
|
Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This firmware is a mashup between Sprinter and grbl.
|
This firmware is a mashup between Sprinter and grbl.
|
||||||
(https://github.com/kliment/Sprinter)
|
(https://github.com/kliment/Sprinter)
|
||||||
(https://github.com/simen/grbl/tree)
|
(https://github.com/simen/grbl/tree)
|
||||||
|
|
||||||
It has preliminary support for Matthew Roberts advance algorithm
|
It has preliminary support for Matthew Roberts advance algorithm
|
||||||
http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
|
http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
|
||||||
|
|
||||||
This firmware is optimized for gen6 electronics.
|
This firmware is optimized for gen6 electronics.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fastio.h"
|
#include "fastio.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "pins.h"
|
#include "pins.h"
|
||||||
#include "Marlin.h"
|
#include "Marlin.h"
|
||||||
#include "ultralcd.h"
|
#include "ultralcd.h"
|
||||||
#include "streaming.h"
|
#include "streaming.h"
|
||||||
#include "temperature.h"
|
#include "temperature.h"
|
||||||
|
|
||||||
int target_bed_raw = 0;
|
int target_bed_raw = 0;
|
||||||
int current_bed_raw = 0;
|
int current_bed_raw = 0;
|
||||||
|
|
||||||
int target_raw[3] = {0, 0, 0};
|
int target_raw[3] = {0, 0, 0};
|
||||||
int current_raw[3] = {0, 0, 0};
|
int current_raw[3] = {0, 0, 0};
|
||||||
unsigned char temp_meas_ready = false;
|
unsigned char temp_meas_ready = false;
|
||||||
|
|
||||||
unsigned long previous_millis_heater, previous_millis_bed_heater;
|
unsigned long previous_millis_heater, previous_millis_bed_heater;
|
||||||
|
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
double temp_iState = 0;
|
double temp_iState = 0;
|
||||||
double temp_dState = 0;
|
double temp_dState = 0;
|
||||||
double pTerm;
|
double pTerm;
|
||||||
double iTerm;
|
double iTerm;
|
||||||
double dTerm;
|
double dTerm;
|
||||||
//int output;
|
//int output;
|
||||||
double pid_error;
|
double pid_error;
|
||||||
double temp_iState_min;
|
double temp_iState_min;
|
||||||
double temp_iState_max;
|
double temp_iState_max;
|
||||||
double pid_setpoint = 0.0;
|
double pid_setpoint = 0.0;
|
||||||
double pid_input;
|
double pid_input;
|
||||||
double pid_output;
|
double pid_output;
|
||||||
bool pid_reset;
|
bool pid_reset;
|
||||||
float HeaterPower;
|
float HeaterPower;
|
||||||
|
|
||||||
float Kp=DEFAULT_Kp;
|
float Kp=DEFAULT_Kp;
|
||||||
float Ki=DEFAULT_Ki;
|
float Ki=DEFAULT_Ki;
|
||||||
float Kd=DEFAULT_Kd;
|
float Kd=DEFAULT_Kd;
|
||||||
float Kc=DEFAULT_Kc;
|
float Kc=DEFAULT_Kc;
|
||||||
#endif //PIDTEMP
|
#endif //PIDTEMP
|
||||||
|
|
||||||
#ifdef MINTEMP
|
#ifdef MINTEMP
|
||||||
int minttemp = temp2analog(MINTEMP);
|
int minttemp = temp2analog(MINTEMP);
|
||||||
#endif //MINTEMP
|
#endif //MINTEMP
|
||||||
#ifdef MAXTEMP
|
#ifdef MAXTEMP
|
||||||
int maxttemp = temp2analog(MAXTEMP);
|
int maxttemp = temp2analog(MAXTEMP);
|
||||||
#endif //MAXTEMP
|
#endif //MAXTEMP
|
||||||
|
|
||||||
#ifdef BED_MINTEMP
|
#ifdef BED_MINTEMP
|
||||||
int bed_minttemp = temp2analog(BED_MINTEMP);
|
int bed_minttemp = temp2analog(BED_MINTEMP);
|
||||||
#endif //BED_MINTEMP
|
#endif //BED_MINTEMP
|
||||||
#ifdef BED_MAXTEMP
|
#ifdef BED_MAXTEMP
|
||||||
int bed_maxttemp = temp2analog(BED_MAXTEMP);
|
int bed_maxttemp = temp2analog(BED_MAXTEMP);
|
||||||
#endif //BED_MAXTEMP
|
#endif //BED_MAXTEMP
|
||||||
|
|
||||||
void manage_heater()
|
void manage_heater()
|
||||||
{
|
{
|
||||||
#ifdef USE_WATCHDOG
|
#ifdef USE_WATCHDOG
|
||||||
wd_reset();
|
wd_reset();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float pid_input;
|
float pid_input;
|
||||||
float pid_output;
|
float pid_output;
|
||||||
if(temp_meas_ready != true) //better readability
|
if(temp_meas_ready != true) //better readability
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CRITICAL_SECTION_START;
|
CRITICAL_SECTION_START;
|
||||||
temp_meas_ready = false;
|
temp_meas_ready = false;
|
||||||
CRITICAL_SECTION_END;
|
CRITICAL_SECTION_END;
|
||||||
|
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
pid_input = analog2temp(current_raw[TEMPSENSOR_HOTEND]);
|
pid_input = analog2temp(current_raw[TEMPSENSOR_HOTEND]);
|
||||||
|
|
||||||
#ifndef PID_OPENLOOP
|
#ifndef PID_OPENLOOP
|
||||||
pid_error = pid_setpoint - pid_input;
|
pid_error = pid_setpoint - pid_input;
|
||||||
if(pid_error > 10){
|
if(pid_error > 10){
|
||||||
pid_output = PID_MAX;
|
pid_output = PID_MAX;
|
||||||
pid_reset = true;
|
pid_reset = true;
|
||||||
}
|
}
|
||||||
else if(pid_error < -10) {
|
else if(pid_error < -10) {
|
||||||
pid_output = 0;
|
pid_output = 0;
|
||||||
pid_reset = true;
|
pid_reset = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(pid_reset == true) {
|
if(pid_reset == true) {
|
||||||
temp_iState = 0.0;
|
temp_iState = 0.0;
|
||||||
pid_reset = false;
|
pid_reset = false;
|
||||||
}
|
}
|
||||||
pTerm = Kp * pid_error;
|
pTerm = Kp * pid_error;
|
||||||
temp_iState += pid_error;
|
temp_iState += pid_error;
|
||||||
temp_iState = constrain(temp_iState, temp_iState_min, temp_iState_max);
|
temp_iState = constrain(temp_iState, temp_iState_min, temp_iState_max);
|
||||||
iTerm = Ki * temp_iState;
|
iTerm = Ki * temp_iState;
|
||||||
//K1 defined in Configuration.h in the PID settings
|
//K1 defined in Configuration.h in the PID settings
|
||||||
#define K2 (1.0-K1)
|
#define K2 (1.0-K1)
|
||||||
dTerm = (Kd * (pid_input - temp_dState))*K2 + (K1 * dTerm);
|
dTerm = (Kd * (pid_input - temp_dState))*K2 + (K1 * dTerm);
|
||||||
temp_dState = pid_input;
|
temp_dState = pid_input;
|
||||||
#ifdef PID_ADD_EXTRUSION_RATE
|
#ifdef PID_ADD_EXTRUSION_RATE
|
||||||
pTerm+=Kc*current_block->speed_e; //additional heating if extrusion speed is high
|
pTerm+=Kc*current_block->speed_e; //additional heating if extrusion speed is high
|
||||||
#endif
|
#endif
|
||||||
pid_output = constrain(pTerm + iTerm - dTerm, 0, PID_MAX);
|
pid_output = constrain(pTerm + iTerm - dTerm, 0, PID_MAX);
|
||||||
}
|
}
|
||||||
#endif //PID_OPENLOOP
|
#endif //PID_OPENLOOP
|
||||||
#ifdef PID_DEBUG
|
#ifdef PID_DEBUG
|
||||||
Serial.print(" Input ");
|
Serial.print(" Input ");
|
||||||
Serial.print(pid_input);
|
Serial.print(pid_input);
|
||||||
Serial.print(" Output ");
|
Serial.print(" Output ");
|
||||||
Serial.print(pid_output);
|
Serial.print(pid_output);
|
||||||
Serial.print(" pTerm ");
|
Serial.print(" pTerm ");
|
||||||
Serial.print(pTerm);
|
Serial.print(pTerm);
|
||||||
Serial.print(" iTerm ");
|
Serial.print(" iTerm ");
|
||||||
Serial.print(iTerm);
|
Serial.print(iTerm);
|
||||||
Serial.print(" dTerm ");
|
Serial.print(" dTerm ");
|
||||||
Serial.print(dTerm);
|
Serial.print(dTerm);
|
||||||
Serial.println();
|
Serial.println();
|
||||||
#endif //PID_DEBUG
|
#endif //PID_DEBUG
|
||||||
analogWrite(HEATER_0_PIN, pid_output);
|
analogWrite(HEATER_0_PIN, pid_output);
|
||||||
#endif //PIDTEMP
|
#endif //PIDTEMP
|
||||||
|
|
||||||
#ifndef PIDTEMP
|
#ifndef PIDTEMP
|
||||||
if(current_raw[0] >= target_raw[0])
|
if(current_raw[0] >= target_raw[0])
|
||||||
{
|
{
|
||||||
WRITE(HEATER_0_PIN,LOW);
|
WRITE(HEATER_0_PIN,LOW);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WRITE(HEATER_0_PIN,HIGH);
|
WRITE(HEATER_0_PIN,HIGH);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
|
if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
|
||||||
return;
|
return;
|
||||||
previous_millis_bed_heater = millis();
|
previous_millis_bed_heater = millis();
|
||||||
|
|
||||||
#if TEMP_1_PIN > -1
|
#if TEMP_1_PIN > -1
|
||||||
if(current_raw[TEMPSENSOR_BED] >= target_raw[TEMPSENSOR_BED])
|
if(current_raw[TEMPSENSOR_BED] >= target_raw[TEMPSENSOR_BED])
|
||||||
{
|
{
|
||||||
WRITE(HEATER_1_PIN,LOW);
|
WRITE(HEATER_1_PIN,LOW);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WRITE(HEATER_1_PIN,HIGH);
|
WRITE(HEATER_1_PIN,HIGH);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes hot end temperature value as input and returns corresponding raw value.
|
// Takes hot end temperature value as input and returns corresponding raw value.
|
||||||
// For a thermistor, it uses the RepRap thermistor temp table.
|
// 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 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.
|
// This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware.
|
||||||
float temp2analog(int celsius) {
|
float temp2analog(int celsius) {
|
||||||
#ifdef HEATER_USES_THERMISTOR_1
|
#ifdef HEATER_USES_THERMISTOR_1
|
||||||
int raw = 0;
|
int raw = 0;
|
||||||
byte i;
|
byte i;
|
||||||
|
|
||||||
for (i=1; i<NUMTEMPS_HEATER_1; i++)
|
for (i=1; i<NUMTEMPS_HEATER_1; i++)
|
||||||
{
|
{
|
||||||
if (temptable_1[i][1] < celsius)
|
if (temptable_1[i][1] < celsius)
|
||||||
{
|
{
|
||||||
raw = temptable_1[i-1][0] +
|
raw = temptable_1[i-1][0] +
|
||||||
(celsius - temptable_1[i-1][1]) *
|
(celsius - temptable_1[i-1][1]) *
|
||||||
(temptable_1[i][0] - temptable_1[i-1][0]) /
|
(temptable_1[i][0] - temptable_1[i-1][0]) /
|
||||||
(temptable_1[i][1] - temptable_1[i-1][1]);
|
(temptable_1[i][1] - temptable_1[i-1][1]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overflow: Set to last value in the table
|
// Overflow: Set to last value in the table
|
||||||
if (i == NUMTEMPS_1) raw = temptable_1[i-1][0];
|
if (i == NUMTEMPS_1) raw = temptable_1[i-1][0];
|
||||||
|
|
||||||
return (1023 * OVERSAMPLENR) - raw;
|
return (1023 * OVERSAMPLENR) - raw;
|
||||||
#elif defined HEATER_1_USES_AD595
|
#elif defined HEATER_1_USES_AD595
|
||||||
return celsius * (1024.0 / (5.0 * 100.0) ) * OVERSAMPLENR;
|
return celsius * (1024.0 / (5.0 * 100.0) ) * OVERSAMPLENR;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes bed temperature value as input and returns corresponding raw value.
|
// Takes bed temperature value as input and returns corresponding raw value.
|
||||||
// For a thermistor, it uses the RepRap thermistor temp table.
|
// 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 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.
|
// This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware.
|
||||||
float temp2analogBed(int celsius) {
|
float temp2analogBed(int celsius) {
|
||||||
#ifdef BED_USES_THERMISTOR
|
#ifdef BED_USES_THERMISTOR
|
||||||
|
|
||||||
int raw = 0;
|
int raw = 0;
|
||||||
byte i;
|
byte i;
|
||||||
|
|
||||||
for (i=1; i<BNUMTEMPS; i++)
|
for (i=1; i<BNUMTEMPS; i++)
|
||||||
{
|
{
|
||||||
if (bedtemptable[i][1] < celsius)
|
if (bedtemptable[i][1] < celsius)
|
||||||
{
|
{
|
||||||
raw = bedtemptable[i-1][0] +
|
raw = bedtemptable[i-1][0] +
|
||||||
(celsius - bedtemptable[i-1][1]) *
|
(celsius - bedtemptable[i-1][1]) *
|
||||||
(bedtemptable[i][0] - bedtemptable[i-1][0]) /
|
(bedtemptable[i][0] - bedtemptable[i-1][0]) /
|
||||||
(bedtemptable[i][1] - bedtemptable[i-1][1]);
|
(bedtemptable[i][1] - bedtemptable[i-1][1]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overflow: Set to last value in the table
|
// Overflow: Set to last value in the table
|
||||||
if (i == BNUMTEMPS) raw = bedtemptable[i-1][0];
|
if (i == BNUMTEMPS) raw = bedtemptable[i-1][0];
|
||||||
|
|
||||||
return (1023 * OVERSAMPLENR) - raw;
|
return (1023 * OVERSAMPLENR) - raw;
|
||||||
#elif defined BED_USES_AD595
|
#elif defined BED_USES_AD595
|
||||||
return celsius * (1024.0 / (5.0 * 100.0) ) * OVERSAMPLENR;
|
return celsius * (1024.0 / (5.0 * 100.0) ) * OVERSAMPLENR;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Derived from RepRap FiveD extruder::getTemperature()
|
// Derived from RepRap FiveD extruder::getTemperature()
|
||||||
// For hot end temperature measurement.
|
// For hot end temperature measurement.
|
||||||
float analog2temp(int raw) {
|
float analog2temp(int raw) {
|
||||||
#ifdef HEATER_1_USES_THERMISTOR
|
#ifdef HEATER_1_USES_THERMISTOR
|
||||||
int celsius = 0;
|
int celsius = 0;
|
||||||
byte i;
|
byte i;
|
||||||
raw = (1023 * OVERSAMPLENR) - raw;
|
raw = (1023 * OVERSAMPLENR) - raw;
|
||||||
for (i=1; i<NUMTEMPS_HEATER_1; i++)
|
for (i=1; i<NUMTEMPS_HEATER_1; i++)
|
||||||
{
|
{
|
||||||
if (temptable_1[i][0] > raw)
|
if (temptable_1[i][0] > raw)
|
||||||
{
|
{
|
||||||
celsius = temptable_1[i-1][1] +
|
celsius = temptable_1[i-1][1] +
|
||||||
(raw - temptable_1[i-1][0]) *
|
(raw - temptable_1[i-1][0]) *
|
||||||
(temptable_1[i][1] - temptable_1[i-1][1]) /
|
(temptable_1[i][1] - temptable_1[i-1][1]) /
|
||||||
(temptable_1[i][0] - temptable_1[i-1][0]);
|
(temptable_1[i][0] - temptable_1[i-1][0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overflow: Set to last value in the table
|
// Overflow: Set to last value in the table
|
||||||
if (i == NUMTEMPS_HEATER_1) celsius = temptable_1[i-1][1];
|
if (i == NUMTEMPS_HEATER_1) celsius = temptable_1[i-1][1];
|
||||||
|
|
||||||
return celsius;
|
return celsius;
|
||||||
#elif defined HEATER_1_USES_AD595
|
#elif defined HEATER_1_USES_AD595
|
||||||
return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR;
|
return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Derived from RepRap FiveD extruder::getTemperature()
|
// Derived from RepRap FiveD extruder::getTemperature()
|
||||||
// For bed temperature measurement.
|
// For bed temperature measurement.
|
||||||
float analog2tempBed(int raw) {
|
float analog2tempBed(int raw) {
|
||||||
#ifdef BED_USES_THERMISTOR
|
#ifdef BED_USES_THERMISTOR
|
||||||
int celsius = 0;
|
int celsius = 0;
|
||||||
byte i;
|
byte i;
|
||||||
|
|
||||||
raw = (1023 * OVERSAMPLENR) - raw;
|
raw = (1023 * OVERSAMPLENR) - raw;
|
||||||
|
|
||||||
for (i=1; i<BNUMTEMPS; i++)
|
for (i=1; i<BNUMTEMPS; i++)
|
||||||
{
|
{
|
||||||
if (bedtemptable[i][0] > raw)
|
if (bedtemptable[i][0] > raw)
|
||||||
{
|
{
|
||||||
celsius = bedtemptable[i-1][1] +
|
celsius = bedtemptable[i-1][1] +
|
||||||
(raw - bedtemptable[i-1][0]) *
|
(raw - bedtemptable[i-1][0]) *
|
||||||
(bedtemptable[i][1] - bedtemptable[i-1][1]) /
|
(bedtemptable[i][1] - bedtemptable[i-1][1]) /
|
||||||
(bedtemptable[i][0] - bedtemptable[i-1][0]);
|
(bedtemptable[i][0] - bedtemptable[i-1][0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overflow: Set to last value in the table
|
// Overflow: Set to last value in the table
|
||||||
if (i == BNUMTEMPS) celsius = bedtemptable[i-1][1];
|
if (i == BNUMTEMPS) celsius = bedtemptable[i-1][1];
|
||||||
|
|
||||||
return celsius;
|
return celsius;
|
||||||
|
|
||||||
#elif defined BED_USES_AD595
|
#elif defined BED_USES_AD595
|
||||||
return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR;
|
return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void tp_init()
|
void tp_init()
|
||||||
{
|
{
|
||||||
#if (HEATER_0_PIN > -1)
|
#if (HEATER_0_PIN > -1)
|
||||||
SET_OUTPUT(HEATER_0_PIN);
|
SET_OUTPUT(HEATER_0_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if (HEATER_1_PIN > -1)
|
#if (HEATER_1_PIN > -1)
|
||||||
SET_OUTPUT(HEATER_1_PIN);
|
SET_OUTPUT(HEATER_1_PIN);
|
||||||
#endif
|
#endif
|
||||||
#if (HEATER_2_PIN > -1)
|
#if (HEATER_2_PIN > -1)
|
||||||
SET_OUTPUT(HEATER_2_PIN);
|
SET_OUTPUT(HEATER_2_PIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
temp_iState_min = 0.0;
|
temp_iState_min = 0.0;
|
||||||
temp_iState_max = PID_INTEGRAL_DRIVE_MAX / Ki;
|
temp_iState_max = PID_INTEGRAL_DRIVE_MAX / Ki;
|
||||||
#endif //PIDTEMP
|
#endif //PIDTEMP
|
||||||
|
|
||||||
// Set analog inputs
|
// Set analog inputs
|
||||||
ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07;
|
ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07;
|
||||||
|
|
||||||
// Use timer0 for temperature measurement
|
// Use timer0 for temperature measurement
|
||||||
// Interleave temperature interrupt with millies interrupt
|
// Interleave temperature interrupt with millies interrupt
|
||||||
OCR0B = 128;
|
OCR0B = 128;
|
||||||
TIMSK0 |= (1<<OCIE0B);
|
TIMSK0 |= (1<<OCIE0B);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char temp_count = 0;
|
static unsigned char temp_count = 0;
|
||||||
static unsigned long raw_temp_0_value = 0;
|
static unsigned long raw_temp_0_value = 0;
|
||||||
static unsigned long raw_temp_1_value = 0;
|
static unsigned long raw_temp_1_value = 0;
|
||||||
static unsigned long raw_temp_2_value = 0;
|
static unsigned long raw_temp_2_value = 0;
|
||||||
static unsigned char temp_state = 0;
|
static unsigned char temp_state = 0;
|
||||||
|
|
||||||
// Timer 0 is shared with millies
|
// Timer 0 is shared with millies
|
||||||
ISR(TIMER0_COMPB_vect)
|
ISR(TIMER0_COMPB_vect)
|
||||||
{
|
{
|
||||||
switch(temp_state) {
|
switch(temp_state) {
|
||||||
case 0: // Prepare TEMP_0
|
case 0: // Prepare TEMP_0
|
||||||
#if (TEMP_0_PIN > -1)
|
#if (TEMP_0_PIN > -1)
|
||||||
#if TEMP_0_PIN < 8
|
#if TEMP_0_PIN < 8
|
||||||
DIDR0 = 1 << TEMP_0_PIN;
|
DIDR0 = 1 << TEMP_0_PIN;
|
||||||
#else
|
#else
|
||||||
DIDR2 = 1<<(TEMP_0_PIN - 8);
|
DIDR2 = 1<<(TEMP_0_PIN - 8);
|
||||||
ADCSRB = 1<<MUX5;
|
ADCSRB = 1<<MUX5;
|
||||||
#endif
|
#endif
|
||||||
ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07));
|
ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07));
|
||||||
ADCSRA |= 1<<ADSC; // Start conversion
|
ADCSRA |= 1<<ADSC; // Start conversion
|
||||||
#endif
|
#endif
|
||||||
#ifdef ULTIPANEL
|
#ifdef ULTIPANEL
|
||||||
buttons_check();
|
buttons_check();
|
||||||
#endif
|
#endif
|
||||||
temp_state = 1;
|
temp_state = 1;
|
||||||
break;
|
break;
|
||||||
case 1: // Measure TEMP_0
|
case 1: // Measure TEMP_0
|
||||||
#if (TEMP_0_PIN > -1)
|
#if (TEMP_0_PIN > -1)
|
||||||
raw_temp_0_value += ADC;
|
raw_temp_0_value += ADC;
|
||||||
#endif
|
#endif
|
||||||
temp_state = 2;
|
temp_state = 2;
|
||||||
break;
|
break;
|
||||||
case 2: // Prepare TEMP_1
|
case 2: // Prepare TEMP_1
|
||||||
#if (TEMP_1_PIN > -1)
|
#if (TEMP_1_PIN > -1)
|
||||||
#if TEMP_1_PIN < 7
|
#if TEMP_1_PIN < 7
|
||||||
DIDR0 = 1<<TEMP_1_PIN;
|
DIDR0 = 1<<TEMP_1_PIN;
|
||||||
#else
|
#else
|
||||||
DIDR2 = 1<<(TEMP_1_PIN - 8);
|
DIDR2 = 1<<(TEMP_1_PIN - 8);
|
||||||
ADCSRB = 1<<MUX5;
|
ADCSRB = 1<<MUX5;
|
||||||
#endif
|
#endif
|
||||||
ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07));
|
ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07));
|
||||||
ADCSRA |= 1<<ADSC; // Start conversion
|
ADCSRA |= 1<<ADSC; // Start conversion
|
||||||
#endif
|
#endif
|
||||||
#ifdef ULTIPANEL
|
#ifdef ULTIPANEL
|
||||||
buttons_check();
|
buttons_check();
|
||||||
#endif
|
#endif
|
||||||
temp_state = 3;
|
temp_state = 3;
|
||||||
break;
|
break;
|
||||||
case 3: // Measure TEMP_1
|
case 3: // Measure TEMP_1
|
||||||
#if (TEMP_1_PIN > -1)
|
#if (TEMP_1_PIN > -1)
|
||||||
raw_temp_1_value += ADC;
|
raw_temp_1_value += ADC;
|
||||||
#endif
|
#endif
|
||||||
temp_state = 4;
|
temp_state = 4;
|
||||||
break;
|
break;
|
||||||
case 4: // Prepare TEMP_2
|
case 4: // Prepare TEMP_2
|
||||||
#if (TEMP_2_PIN > -1)
|
#if (TEMP_2_PIN > -1)
|
||||||
#if TEMP_2_PIN < 7
|
#if TEMP_2_PIN < 7
|
||||||
DIDR0 = 1 << TEMP_2_PIN;
|
DIDR0 = 1 << TEMP_2_PIN;
|
||||||
#else
|
#else
|
||||||
DIDR2 = 1<<(TEMP_2_PIN - 8);
|
DIDR2 = 1<<(TEMP_2_PIN - 8);
|
||||||
ADCSRB = 1<<MUX5;
|
ADCSRB = 1<<MUX5;
|
||||||
#endif
|
#endif
|
||||||
ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07));
|
ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07));
|
||||||
ADCSRA |= 1<<ADSC; // Start conversion
|
ADCSRA |= 1<<ADSC; // Start conversion
|
||||||
#endif
|
#endif
|
||||||
#ifdef ULTIPANEL
|
#ifdef ULTIPANEL
|
||||||
buttons_check();
|
buttons_check();
|
||||||
#endif
|
#endif
|
||||||
temp_state = 5;
|
temp_state = 5;
|
||||||
break;
|
break;
|
||||||
case 5: // Measure TEMP_2
|
case 5: // Measure TEMP_2
|
||||||
#if (TEMP_2_PIN > -1)
|
#if (TEMP_2_PIN > -1)
|
||||||
raw_temp_2_value += ADC;
|
raw_temp_2_value += ADC;
|
||||||
#endif
|
#endif
|
||||||
temp_state = 0;
|
temp_state = 0;
|
||||||
temp_count++;
|
temp_count++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Serial.println("!! Temp measurement error !!");
|
Serial.println("!! Temp measurement error !!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(temp_count >= 16) // 6 ms * 16 = 96ms.
|
if(temp_count >= 16) // 6 ms * 16 = 96ms.
|
||||||
{
|
{
|
||||||
#ifdef HEATER_1_USES_AD595
|
#ifdef HEATER_1_USES_AD595
|
||||||
current_raw[0] = raw_temp_0_value;
|
current_raw[0] = raw_temp_0_value;
|
||||||
#else
|
#else
|
||||||
current_raw[0] = 16383 - raw_temp_0_value;
|
current_raw[0] = 16383 - raw_temp_0_value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HEATER_2_USES_AD595
|
#ifdef HEATER_2_USES_AD595
|
||||||
current_raw[2] = raw_temp_2_value;
|
current_raw[2] = raw_temp_2_value;
|
||||||
#else
|
#else
|
||||||
current_raw[2] = 16383 - raw_temp_2_value;
|
current_raw[2] = 16383 - raw_temp_2_value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BED_USES_AD595
|
#ifdef BED_USES_AD595
|
||||||
current_raw[1] = raw_temp_1_value;
|
current_raw[1] = raw_temp_1_value;
|
||||||
#else
|
#else
|
||||||
current_raw[1] = 16383 - raw_temp_1_value;
|
current_raw[1] = 16383 - raw_temp_1_value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
temp_meas_ready = true;
|
temp_meas_ready = true;
|
||||||
temp_count = 0;
|
temp_count = 0;
|
||||||
raw_temp_0_value = 0;
|
raw_temp_0_value = 0;
|
||||||
raw_temp_1_value = 0;
|
raw_temp_1_value = 0;
|
||||||
raw_temp_2_value = 0;
|
raw_temp_2_value = 0;
|
||||||
#ifdef MAXTEMP
|
#ifdef MAXTEMP
|
||||||
#if (HEATER_0_PIN > -1)
|
#if (HEATER_0_PIN > -1)
|
||||||
if(current_raw[TEMPSENSOR_HOTEND] >= maxttemp) {
|
if(current_raw[TEMPSENSOR_HOTEND] >= maxttemp) {
|
||||||
target_raw[TEMPSENSOR_HOTEND] = 0;
|
target_raw[TEMPSENSOR_HOTEND] = 0;
|
||||||
analogWrite(HEATER_0_PIN, 0);
|
analogWrite(HEATER_0_PIN, 0);
|
||||||
Serial.println("!! Temperature extruder 0 switched off. MAXTEMP triggered !!");
|
Serial.println("!! Temperature extruder 0 switched off. MAXTEMP triggered !!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if (HEATER_2_PIN > -1)
|
#if (HEATER_2_PIN > -1)
|
||||||
if(current_raw[TEMPSENSOR_AUX] >= maxttemp) {
|
if(current_raw[TEMPSENSOR_AUX] >= maxttemp) {
|
||||||
target_raw[TEMPSENSOR_AUX] = 0;
|
target_raw[TEMPSENSOR_AUX] = 0;
|
||||||
analogWrite(HEATER_2_PIN, 0);
|
analogWrite(HEATER_2_PIN, 0);
|
||||||
Serial.println("!! Temperature extruder 1 switched off. MAXTEMP triggered !!");
|
Serial.println("!! Temperature extruder 1 switched off. MAXTEMP triggered !!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif //MAXTEMP
|
#endif //MAXTEMP
|
||||||
#ifdef MINTEMP
|
#ifdef MINTEMP
|
||||||
#if (HEATER_0_PIN > -1)
|
#if (HEATER_0_PIN > -1)
|
||||||
if(current_raw[TEMPSENSOR_HOTEND] <= minttemp) {
|
if(current_raw[TEMPSENSOR_HOTEND] <= minttemp) {
|
||||||
target_raw[TEMPSENSOR_HOTEND] = 0;
|
target_raw[TEMPSENSOR_HOTEND] = 0;
|
||||||
analogWrite(HEATER_0_PIN, 0);
|
analogWrite(HEATER_0_PIN, 0);
|
||||||
Serial.println("!! Temperature extruder 0 switched off. MINTEMP triggered !!");
|
Serial.println("!! Temperature extruder 0 switched off. MINTEMP triggered !!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if (HEATER_2_PIN > -1)
|
#if (HEATER_2_PIN > -1)
|
||||||
if(current_raw[TEMPSENSOR_AUX] <= minttemp) {
|
if(current_raw[TEMPSENSOR_AUX] <= minttemp) {
|
||||||
target_raw[TEMPSENSOR_AUX] = 0;
|
target_raw[TEMPSENSOR_AUX] = 0;
|
||||||
analogWrite(HEATER_2_PIN, 0);
|
analogWrite(HEATER_2_PIN, 0);
|
||||||
Serial.println("!! Temperature extruder 1 switched off. MINTEMP triggered !!");
|
Serial.println("!! Temperature extruder 1 switched off. MINTEMP triggered !!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif //MAXTEMP
|
#endif //MAXTEMP
|
||||||
#ifdef BED_MINTEMP
|
#ifdef BED_MINTEMP
|
||||||
#if (HEATER_1_PIN > -1)
|
#if (HEATER_1_PIN > -1)
|
||||||
if(current_raw[1] <= bed_minttemp) {
|
if(current_raw[1] <= bed_minttemp) {
|
||||||
target_raw[1] = 0;
|
target_raw[1] = 0;
|
||||||
WRITE(HEATER_1_PIN, 0);
|
WRITE(HEATER_1_PIN, 0);
|
||||||
Serial.println("!! Temperatur heated bed switched off. MINTEMP triggered !!");
|
Serial.println("!! Temperatur heated bed switched off. MINTEMP triggered !!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef BED_MAXTEMP
|
#ifdef BED_MAXTEMP
|
||||||
#if (HEATER_1_PIN > -1)
|
#if (HEATER_1_PIN > -1)
|
||||||
if(current_raw[1] >= bed_maxttemp) {
|
if(current_raw[1] >= bed_maxttemp) {
|
||||||
target_raw[1] = 0;
|
target_raw[1] = 0;
|
||||||
WRITE(HEATER_1_PIN, 0);
|
WRITE(HEATER_1_PIN, 0);
|
||||||
Serial.println("!! Temperature heated bed switched off. MAXTEMP triggered !!");
|
Serial.println("!! Temperature heated bed switched off. MAXTEMP triggered !!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,410 +1,410 @@
|
||||||
#ifndef THERMISTORTABLES_H_
|
#ifndef THERMISTORTABLES_H_
|
||||||
#define THERMISTORTABLES_H_
|
#define THERMISTORTABLES_H_
|
||||||
|
|
||||||
#define OVERSAMPLENR 16
|
#define OVERSAMPLENR 16
|
||||||
|
|
||||||
#if (THERMISTORHEATER_1 == 1) || (THERMISTORHEATER_2 == 1) || (THERMISTORBED == 1) //100k bed thermistor
|
#if (THERMISTORHEATER_1 == 1) || (THERMISTORHEATER_2 == 1) || (THERMISTORBED == 1) //100k bed thermistor
|
||||||
|
|
||||||
#define NUMTEMPS_1 61
|
#define NUMTEMPS_1 61
|
||||||
const short temptable_1[NUMTEMPS_1][2] = {
|
const short temptable_1[NUMTEMPS_1][2] = {
|
||||||
{ 23*OVERSAMPLENR , 300 },
|
{ 23*OVERSAMPLENR , 300 },
|
||||||
{ 25*OVERSAMPLENR , 295 },
|
{ 25*OVERSAMPLENR , 295 },
|
||||||
{ 27*OVERSAMPLENR , 290 },
|
{ 27*OVERSAMPLENR , 290 },
|
||||||
{ 28*OVERSAMPLENR , 285 },
|
{ 28*OVERSAMPLENR , 285 },
|
||||||
{ 31*OVERSAMPLENR , 280 },
|
{ 31*OVERSAMPLENR , 280 },
|
||||||
{ 33*OVERSAMPLENR , 275 },
|
{ 33*OVERSAMPLENR , 275 },
|
||||||
{ 35*OVERSAMPLENR , 270 },
|
{ 35*OVERSAMPLENR , 270 },
|
||||||
{ 38*OVERSAMPLENR , 265 },
|
{ 38*OVERSAMPLENR , 265 },
|
||||||
{ 41*OVERSAMPLENR , 260 },
|
{ 41*OVERSAMPLENR , 260 },
|
||||||
{ 44*OVERSAMPLENR , 255 },
|
{ 44*OVERSAMPLENR , 255 },
|
||||||
{ 48*OVERSAMPLENR , 250 },
|
{ 48*OVERSAMPLENR , 250 },
|
||||||
{ 52*OVERSAMPLENR , 245 },
|
{ 52*OVERSAMPLENR , 245 },
|
||||||
{ 56*OVERSAMPLENR , 240 },
|
{ 56*OVERSAMPLENR , 240 },
|
||||||
{ 61*OVERSAMPLENR , 235 },
|
{ 61*OVERSAMPLENR , 235 },
|
||||||
{ 66*OVERSAMPLENR , 230 },
|
{ 66*OVERSAMPLENR , 230 },
|
||||||
{ 71*OVERSAMPLENR , 225 },
|
{ 71*OVERSAMPLENR , 225 },
|
||||||
{ 78*OVERSAMPLENR , 220 },
|
{ 78*OVERSAMPLENR , 220 },
|
||||||
{ 84*OVERSAMPLENR , 215 },
|
{ 84*OVERSAMPLENR , 215 },
|
||||||
{ 92*OVERSAMPLENR , 210 },
|
{ 92*OVERSAMPLENR , 210 },
|
||||||
{ 100*OVERSAMPLENR , 205 },
|
{ 100*OVERSAMPLENR , 205 },
|
||||||
{ 109*OVERSAMPLENR , 200 },
|
{ 109*OVERSAMPLENR , 200 },
|
||||||
{ 120*OVERSAMPLENR , 195 },
|
{ 120*OVERSAMPLENR , 195 },
|
||||||
{ 131*OVERSAMPLENR , 190 },
|
{ 131*OVERSAMPLENR , 190 },
|
||||||
{ 143*OVERSAMPLENR , 185 },
|
{ 143*OVERSAMPLENR , 185 },
|
||||||
{ 156*OVERSAMPLENR , 180 },
|
{ 156*OVERSAMPLENR , 180 },
|
||||||
{ 171*OVERSAMPLENR , 175 },
|
{ 171*OVERSAMPLENR , 175 },
|
||||||
{ 187*OVERSAMPLENR , 170 },
|
{ 187*OVERSAMPLENR , 170 },
|
||||||
{ 205*OVERSAMPLENR , 165 },
|
{ 205*OVERSAMPLENR , 165 },
|
||||||
{ 224*OVERSAMPLENR , 160 },
|
{ 224*OVERSAMPLENR , 160 },
|
||||||
{ 245*OVERSAMPLENR , 155 },
|
{ 245*OVERSAMPLENR , 155 },
|
||||||
{ 268*OVERSAMPLENR , 150 },
|
{ 268*OVERSAMPLENR , 150 },
|
||||||
{ 293*OVERSAMPLENR , 145 },
|
{ 293*OVERSAMPLENR , 145 },
|
||||||
{ 320*OVERSAMPLENR , 140 },
|
{ 320*OVERSAMPLENR , 140 },
|
||||||
{ 348*OVERSAMPLENR , 135 },
|
{ 348*OVERSAMPLENR , 135 },
|
||||||
{ 379*OVERSAMPLENR , 130 },
|
{ 379*OVERSAMPLENR , 130 },
|
||||||
{ 411*OVERSAMPLENR , 125 },
|
{ 411*OVERSAMPLENR , 125 },
|
||||||
{ 445*OVERSAMPLENR , 120 },
|
{ 445*OVERSAMPLENR , 120 },
|
||||||
{ 480*OVERSAMPLENR , 115 },
|
{ 480*OVERSAMPLENR , 115 },
|
||||||
{ 516*OVERSAMPLENR , 110 },
|
{ 516*OVERSAMPLENR , 110 },
|
||||||
{ 553*OVERSAMPLENR , 105 },
|
{ 553*OVERSAMPLENR , 105 },
|
||||||
{ 591*OVERSAMPLENR , 100 },
|
{ 591*OVERSAMPLENR , 100 },
|
||||||
{ 628*OVERSAMPLENR , 95 },
|
{ 628*OVERSAMPLENR , 95 },
|
||||||
{ 665*OVERSAMPLENR , 90 },
|
{ 665*OVERSAMPLENR , 90 },
|
||||||
{ 702*OVERSAMPLENR , 85 },
|
{ 702*OVERSAMPLENR , 85 },
|
||||||
{ 737*OVERSAMPLENR , 80 },
|
{ 737*OVERSAMPLENR , 80 },
|
||||||
{ 770*OVERSAMPLENR , 75 },
|
{ 770*OVERSAMPLENR , 75 },
|
||||||
{ 801*OVERSAMPLENR , 70 },
|
{ 801*OVERSAMPLENR , 70 },
|
||||||
{ 830*OVERSAMPLENR , 65 },
|
{ 830*OVERSAMPLENR , 65 },
|
||||||
{ 857*OVERSAMPLENR , 60 },
|
{ 857*OVERSAMPLENR , 60 },
|
||||||
{ 881*OVERSAMPLENR , 55 },
|
{ 881*OVERSAMPLENR , 55 },
|
||||||
{ 903*OVERSAMPLENR , 50 },
|
{ 903*OVERSAMPLENR , 50 },
|
||||||
{ 922*OVERSAMPLENR , 45 },
|
{ 922*OVERSAMPLENR , 45 },
|
||||||
{ 939*OVERSAMPLENR , 40 },
|
{ 939*OVERSAMPLENR , 40 },
|
||||||
{ 954*OVERSAMPLENR , 35 },
|
{ 954*OVERSAMPLENR , 35 },
|
||||||
{ 966*OVERSAMPLENR , 30 },
|
{ 966*OVERSAMPLENR , 30 },
|
||||||
{ 977*OVERSAMPLENR , 25 },
|
{ 977*OVERSAMPLENR , 25 },
|
||||||
{ 985*OVERSAMPLENR , 20 },
|
{ 985*OVERSAMPLENR , 20 },
|
||||||
{ 993*OVERSAMPLENR , 15 },
|
{ 993*OVERSAMPLENR , 15 },
|
||||||
{ 999*OVERSAMPLENR , 10 },
|
{ 999*OVERSAMPLENR , 10 },
|
||||||
{ 1004*OVERSAMPLENR , 5 },
|
{ 1004*OVERSAMPLENR , 5 },
|
||||||
{ 1008*OVERSAMPLENR , 0 } //safety
|
{ 1008*OVERSAMPLENR , 0 } //safety
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#if (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORBED == 2) //200k bed thermistor
|
#if (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORBED == 2) //200k bed thermistor
|
||||||
#define NUMTEMPS_2 21
|
#define NUMTEMPS_2 21
|
||||||
const short temptable_2[NUMTEMPS_2][2] = {
|
const short temptable_2[NUMTEMPS_2][2] = {
|
||||||
{1*OVERSAMPLENR, 848},
|
{1*OVERSAMPLENR, 848},
|
||||||
{54*OVERSAMPLENR, 275},
|
{54*OVERSAMPLENR, 275},
|
||||||
{107*OVERSAMPLENR, 228},
|
{107*OVERSAMPLENR, 228},
|
||||||
{160*OVERSAMPLENR, 202},
|
{160*OVERSAMPLENR, 202},
|
||||||
{213*OVERSAMPLENR, 185},
|
{213*OVERSAMPLENR, 185},
|
||||||
{266*OVERSAMPLENR, 171},
|
{266*OVERSAMPLENR, 171},
|
||||||
{319*OVERSAMPLENR, 160},
|
{319*OVERSAMPLENR, 160},
|
||||||
{372*OVERSAMPLENR, 150},
|
{372*OVERSAMPLENR, 150},
|
||||||
{425*OVERSAMPLENR, 141},
|
{425*OVERSAMPLENR, 141},
|
||||||
{478*OVERSAMPLENR, 133},
|
{478*OVERSAMPLENR, 133},
|
||||||
{531*OVERSAMPLENR, 125},
|
{531*OVERSAMPLENR, 125},
|
||||||
{584*OVERSAMPLENR, 118},
|
{584*OVERSAMPLENR, 118},
|
||||||
{637*OVERSAMPLENR, 110},
|
{637*OVERSAMPLENR, 110},
|
||||||
{690*OVERSAMPLENR, 103},
|
{690*OVERSAMPLENR, 103},
|
||||||
{743*OVERSAMPLENR, 95},
|
{743*OVERSAMPLENR, 95},
|
||||||
{796*OVERSAMPLENR, 86},
|
{796*OVERSAMPLENR, 86},
|
||||||
{849*OVERSAMPLENR, 77},
|
{849*OVERSAMPLENR, 77},
|
||||||
{902*OVERSAMPLENR, 65},
|
{902*OVERSAMPLENR, 65},
|
||||||
{955*OVERSAMPLENR, 49},
|
{955*OVERSAMPLENR, 49},
|
||||||
{1008*OVERSAMPLENR, 17},
|
{1008*OVERSAMPLENR, 17},
|
||||||
{1020*OVERSAMPLENR, 0} //safety
|
{1020*OVERSAMPLENR, 0} //safety
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 3) || (THERMISTORBED == 3) //mendel-parts
|
#if (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 3) || (THERMISTORBED == 3) //mendel-parts
|
||||||
#define NUMTEMPS_3 28
|
#define NUMTEMPS_3 28
|
||||||
const short temptable_3[NUMTEMPS_3][2] = {
|
const short temptable_3[NUMTEMPS_3][2] = {
|
||||||
{1*OVERSAMPLENR,864},
|
{1*OVERSAMPLENR,864},
|
||||||
{21*OVERSAMPLENR,300},
|
{21*OVERSAMPLENR,300},
|
||||||
{25*OVERSAMPLENR,290},
|
{25*OVERSAMPLENR,290},
|
||||||
{29*OVERSAMPLENR,280},
|
{29*OVERSAMPLENR,280},
|
||||||
{33*OVERSAMPLENR,270},
|
{33*OVERSAMPLENR,270},
|
||||||
{39*OVERSAMPLENR,260},
|
{39*OVERSAMPLENR,260},
|
||||||
{46*OVERSAMPLENR,250},
|
{46*OVERSAMPLENR,250},
|
||||||
{54*OVERSAMPLENR,240},
|
{54*OVERSAMPLENR,240},
|
||||||
{64*OVERSAMPLENR,230},
|
{64*OVERSAMPLENR,230},
|
||||||
{75*OVERSAMPLENR,220},
|
{75*OVERSAMPLENR,220},
|
||||||
{90*OVERSAMPLENR,210},
|
{90*OVERSAMPLENR,210},
|
||||||
{107*OVERSAMPLENR,200},
|
{107*OVERSAMPLENR,200},
|
||||||
{128*OVERSAMPLENR,190},
|
{128*OVERSAMPLENR,190},
|
||||||
{154*OVERSAMPLENR,180},
|
{154*OVERSAMPLENR,180},
|
||||||
{184*OVERSAMPLENR,170},
|
{184*OVERSAMPLENR,170},
|
||||||
{221*OVERSAMPLENR,160},
|
{221*OVERSAMPLENR,160},
|
||||||
{265*OVERSAMPLENR,150},
|
{265*OVERSAMPLENR,150},
|
||||||
{316*OVERSAMPLENR,140},
|
{316*OVERSAMPLENR,140},
|
||||||
{375*OVERSAMPLENR,130},
|
{375*OVERSAMPLENR,130},
|
||||||
{441*OVERSAMPLENR,120},
|
{441*OVERSAMPLENR,120},
|
||||||
{513*OVERSAMPLENR,110},
|
{513*OVERSAMPLENR,110},
|
||||||
{588*OVERSAMPLENR,100},
|
{588*OVERSAMPLENR,100},
|
||||||
{734*OVERSAMPLENR,80},
|
{734*OVERSAMPLENR,80},
|
||||||
{856*OVERSAMPLENR,60},
|
{856*OVERSAMPLENR,60},
|
||||||
{938*OVERSAMPLENR,40},
|
{938*OVERSAMPLENR,40},
|
||||||
{986*OVERSAMPLENR,20},
|
{986*OVERSAMPLENR,20},
|
||||||
{1008*OVERSAMPLENR,0},
|
{1008*OVERSAMPLENR,0},
|
||||||
{1018*OVERSAMPLENR,-20}
|
{1018*OVERSAMPLENR,-20}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORBED == 4) //10k thermistor
|
#if (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORBED == 4) //10k thermistor
|
||||||
|
|
||||||
#define NUMTEMPS_4 20
|
#define NUMTEMPS_4 20
|
||||||
short temptable_4[NUMTEMPS_4][2] = {
|
short temptable_4[NUMTEMPS_4][2] = {
|
||||||
{1*OVERSAMPLENR, 430},
|
{1*OVERSAMPLENR, 430},
|
||||||
{54*OVERSAMPLENR, 137},
|
{54*OVERSAMPLENR, 137},
|
||||||
{107*OVERSAMPLENR, 107},
|
{107*OVERSAMPLENR, 107},
|
||||||
{160*OVERSAMPLENR, 91},
|
{160*OVERSAMPLENR, 91},
|
||||||
{213*OVERSAMPLENR, 80},
|
{213*OVERSAMPLENR, 80},
|
||||||
{266*OVERSAMPLENR, 71},
|
{266*OVERSAMPLENR, 71},
|
||||||
{319*OVERSAMPLENR, 64},
|
{319*OVERSAMPLENR, 64},
|
||||||
{372*OVERSAMPLENR, 57},
|
{372*OVERSAMPLENR, 57},
|
||||||
{425*OVERSAMPLENR, 51},
|
{425*OVERSAMPLENR, 51},
|
||||||
{478*OVERSAMPLENR, 46},
|
{478*OVERSAMPLENR, 46},
|
||||||
{531*OVERSAMPLENR, 41},
|
{531*OVERSAMPLENR, 41},
|
||||||
{584*OVERSAMPLENR, 35},
|
{584*OVERSAMPLENR, 35},
|
||||||
{637*OVERSAMPLENR, 30},
|
{637*OVERSAMPLENR, 30},
|
||||||
{690*OVERSAMPLENR, 25},
|
{690*OVERSAMPLENR, 25},
|
||||||
{743*OVERSAMPLENR, 20},
|
{743*OVERSAMPLENR, 20},
|
||||||
{796*OVERSAMPLENR, 14},
|
{796*OVERSAMPLENR, 14},
|
||||||
{849*OVERSAMPLENR, 7},
|
{849*OVERSAMPLENR, 7},
|
||||||
{902*OVERSAMPLENR, 0},
|
{902*OVERSAMPLENR, 0},
|
||||||
{955*OVERSAMPLENR, -11},
|
{955*OVERSAMPLENR, -11},
|
||||||
{1008*OVERSAMPLENR, -35}
|
{1008*OVERSAMPLENR, -35}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2)
|
#if (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2)
|
||||||
|
|
||||||
#define NUMTEMPS_5 61
|
#define NUMTEMPS_5 61
|
||||||
const short temptable_5[NUMTEMPS_5][2] = {
|
const short temptable_5[NUMTEMPS_5][2] = {
|
||||||
{1*OVERSAMPLENR, 713},
|
{1*OVERSAMPLENR, 713},
|
||||||
{18*OVERSAMPLENR, 316},
|
{18*OVERSAMPLENR, 316},
|
||||||
{35*OVERSAMPLENR, 266},
|
{35*OVERSAMPLENR, 266},
|
||||||
{52*OVERSAMPLENR, 239},
|
{52*OVERSAMPLENR, 239},
|
||||||
{69*OVERSAMPLENR, 221},
|
{69*OVERSAMPLENR, 221},
|
||||||
{86*OVERSAMPLENR, 208},
|
{86*OVERSAMPLENR, 208},
|
||||||
{103*OVERSAMPLENR, 197},
|
{103*OVERSAMPLENR, 197},
|
||||||
{120*OVERSAMPLENR, 188},
|
{120*OVERSAMPLENR, 188},
|
||||||
{137*OVERSAMPLENR, 181},
|
{137*OVERSAMPLENR, 181},
|
||||||
{154*OVERSAMPLENR, 174},
|
{154*OVERSAMPLENR, 174},
|
||||||
{171*OVERSAMPLENR, 169},
|
{171*OVERSAMPLENR, 169},
|
||||||
{188*OVERSAMPLENR, 163},
|
{188*OVERSAMPLENR, 163},
|
||||||
{205*OVERSAMPLENR, 159},
|
{205*OVERSAMPLENR, 159},
|
||||||
{222*OVERSAMPLENR, 154},
|
{222*OVERSAMPLENR, 154},
|
||||||
{239*OVERSAMPLENR, 150},
|
{239*OVERSAMPLENR, 150},
|
||||||
{256*OVERSAMPLENR, 147},
|
{256*OVERSAMPLENR, 147},
|
||||||
{273*OVERSAMPLENR, 143},
|
{273*OVERSAMPLENR, 143},
|
||||||
{290*OVERSAMPLENR, 140},
|
{290*OVERSAMPLENR, 140},
|
||||||
{307*OVERSAMPLENR, 136},
|
{307*OVERSAMPLENR, 136},
|
||||||
{324*OVERSAMPLENR, 133},
|
{324*OVERSAMPLENR, 133},
|
||||||
{341*OVERSAMPLENR, 130},
|
{341*OVERSAMPLENR, 130},
|
||||||
{358*OVERSAMPLENR, 128},
|
{358*OVERSAMPLENR, 128},
|
||||||
{375*OVERSAMPLENR, 125},
|
{375*OVERSAMPLENR, 125},
|
||||||
{392*OVERSAMPLENR, 122},
|
{392*OVERSAMPLENR, 122},
|
||||||
{409*OVERSAMPLENR, 120},
|
{409*OVERSAMPLENR, 120},
|
||||||
{426*OVERSAMPLENR, 117},
|
{426*OVERSAMPLENR, 117},
|
||||||
{443*OVERSAMPLENR, 115},
|
{443*OVERSAMPLENR, 115},
|
||||||
{460*OVERSAMPLENR, 112},
|
{460*OVERSAMPLENR, 112},
|
||||||
{477*OVERSAMPLENR, 110},
|
{477*OVERSAMPLENR, 110},
|
||||||
{494*OVERSAMPLENR, 108},
|
{494*OVERSAMPLENR, 108},
|
||||||
{511*OVERSAMPLENR, 106},
|
{511*OVERSAMPLENR, 106},
|
||||||
{528*OVERSAMPLENR, 103},
|
{528*OVERSAMPLENR, 103},
|
||||||
{545*OVERSAMPLENR, 101},
|
{545*OVERSAMPLENR, 101},
|
||||||
{562*OVERSAMPLENR, 99},
|
{562*OVERSAMPLENR, 99},
|
||||||
{579*OVERSAMPLENR, 97},
|
{579*OVERSAMPLENR, 97},
|
||||||
{596*OVERSAMPLENR, 95},
|
{596*OVERSAMPLENR, 95},
|
||||||
{613*OVERSAMPLENR, 92},
|
{613*OVERSAMPLENR, 92},
|
||||||
{630*OVERSAMPLENR, 90},
|
{630*OVERSAMPLENR, 90},
|
||||||
{647*OVERSAMPLENR, 88},
|
{647*OVERSAMPLENR, 88},
|
||||||
{664*OVERSAMPLENR, 86},
|
{664*OVERSAMPLENR, 86},
|
||||||
{681*OVERSAMPLENR, 84},
|
{681*OVERSAMPLENR, 84},
|
||||||
{698*OVERSAMPLENR, 81},
|
{698*OVERSAMPLENR, 81},
|
||||||
{715*OVERSAMPLENR, 79},
|
{715*OVERSAMPLENR, 79},
|
||||||
{732*OVERSAMPLENR, 77},
|
{732*OVERSAMPLENR, 77},
|
||||||
{749*OVERSAMPLENR, 75},
|
{749*OVERSAMPLENR, 75},
|
||||||
{766*OVERSAMPLENR, 72},
|
{766*OVERSAMPLENR, 72},
|
||||||
{783*OVERSAMPLENR, 70},
|
{783*OVERSAMPLENR, 70},
|
||||||
{800*OVERSAMPLENR, 67},
|
{800*OVERSAMPLENR, 67},
|
||||||
{817*OVERSAMPLENR, 64},
|
{817*OVERSAMPLENR, 64},
|
||||||
{834*OVERSAMPLENR, 61},
|
{834*OVERSAMPLENR, 61},
|
||||||
{851*OVERSAMPLENR, 58},
|
{851*OVERSAMPLENR, 58},
|
||||||
{868*OVERSAMPLENR, 55},
|
{868*OVERSAMPLENR, 55},
|
||||||
{885*OVERSAMPLENR, 52},
|
{885*OVERSAMPLENR, 52},
|
||||||
{902*OVERSAMPLENR, 48},
|
{902*OVERSAMPLENR, 48},
|
||||||
{919*OVERSAMPLENR, 44},
|
{919*OVERSAMPLENR, 44},
|
||||||
{936*OVERSAMPLENR, 40},
|
{936*OVERSAMPLENR, 40},
|
||||||
{953*OVERSAMPLENR, 34},
|
{953*OVERSAMPLENR, 34},
|
||||||
{970*OVERSAMPLENR, 28},
|
{970*OVERSAMPLENR, 28},
|
||||||
{987*OVERSAMPLENR, 20},
|
{987*OVERSAMPLENR, 20},
|
||||||
{1004*OVERSAMPLENR, 8},
|
{1004*OVERSAMPLENR, 8},
|
||||||
{1021*OVERSAMPLENR, 0}
|
{1021*OVERSAMPLENR, 0}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor
|
#if (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor
|
||||||
#define NUMTEMPS_6 36
|
#define NUMTEMPS_6 36
|
||||||
const short temptable_6[NUMTEMPS_6][2] = {
|
const short temptable_6[NUMTEMPS_6][2] = {
|
||||||
{28*OVERSAMPLENR, 250},
|
{28*OVERSAMPLENR, 250},
|
||||||
{31*OVERSAMPLENR, 245},
|
{31*OVERSAMPLENR, 245},
|
||||||
{35*OVERSAMPLENR, 240},
|
{35*OVERSAMPLENR, 240},
|
||||||
{39*OVERSAMPLENR, 235},
|
{39*OVERSAMPLENR, 235},
|
||||||
{42*OVERSAMPLENR, 230},
|
{42*OVERSAMPLENR, 230},
|
||||||
{44*OVERSAMPLENR, 225},
|
{44*OVERSAMPLENR, 225},
|
||||||
{49*OVERSAMPLENR, 220},
|
{49*OVERSAMPLENR, 220},
|
||||||
{53*OVERSAMPLENR, 215},
|
{53*OVERSAMPLENR, 215},
|
||||||
{62*OVERSAMPLENR, 210},
|
{62*OVERSAMPLENR, 210},
|
||||||
{73*OVERSAMPLENR, 205},
|
{73*OVERSAMPLENR, 205},
|
||||||
{72*OVERSAMPLENR, 200},
|
{72*OVERSAMPLENR, 200},
|
||||||
{94*OVERSAMPLENR, 190},
|
{94*OVERSAMPLENR, 190},
|
||||||
{102*OVERSAMPLENR, 185},
|
{102*OVERSAMPLENR, 185},
|
||||||
{116*OVERSAMPLENR, 170},
|
{116*OVERSAMPLENR, 170},
|
||||||
{143*OVERSAMPLENR, 160},
|
{143*OVERSAMPLENR, 160},
|
||||||
{183*OVERSAMPLENR, 150},
|
{183*OVERSAMPLENR, 150},
|
||||||
{223*OVERSAMPLENR, 140},
|
{223*OVERSAMPLENR, 140},
|
||||||
{270*OVERSAMPLENR, 130},
|
{270*OVERSAMPLENR, 130},
|
||||||
{318*OVERSAMPLENR, 120},
|
{318*OVERSAMPLENR, 120},
|
||||||
{383*OVERSAMPLENR, 110},
|
{383*OVERSAMPLENR, 110},
|
||||||
{413*OVERSAMPLENR, 105},
|
{413*OVERSAMPLENR, 105},
|
||||||
{439*OVERSAMPLENR, 100},
|
{439*OVERSAMPLENR, 100},
|
||||||
{484*OVERSAMPLENR, 95},
|
{484*OVERSAMPLENR, 95},
|
||||||
{513*OVERSAMPLENR, 90},
|
{513*OVERSAMPLENR, 90},
|
||||||
{607*OVERSAMPLENR, 80},
|
{607*OVERSAMPLENR, 80},
|
||||||
{664*OVERSAMPLENR, 70},
|
{664*OVERSAMPLENR, 70},
|
||||||
{781*OVERSAMPLENR, 60},
|
{781*OVERSAMPLENR, 60},
|
||||||
{810*OVERSAMPLENR, 55},
|
{810*OVERSAMPLENR, 55},
|
||||||
{849*OVERSAMPLENR, 50},
|
{849*OVERSAMPLENR, 50},
|
||||||
{914*OVERSAMPLENR, 45},
|
{914*OVERSAMPLENR, 45},
|
||||||
{914*OVERSAMPLENR, 40},
|
{914*OVERSAMPLENR, 40},
|
||||||
{935*OVERSAMPLENR, 35},
|
{935*OVERSAMPLENR, 35},
|
||||||
{954*OVERSAMPLENR, 30},
|
{954*OVERSAMPLENR, 30},
|
||||||
{970*OVERSAMPLENR, 25},
|
{970*OVERSAMPLENR, 25},
|
||||||
{978*OVERSAMPLENR, 22},
|
{978*OVERSAMPLENR, 22},
|
||||||
{1008*OVERSAMPLENR, 3}
|
{1008*OVERSAMPLENR, 3}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01
|
#if (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01
|
||||||
#define NUMTEMPS_7 54
|
#define NUMTEMPS_7 54
|
||||||
const short temptable_7[NUMTEMPS_7][2] = {
|
const short temptable_7[NUMTEMPS_7][2] = {
|
||||||
{46*OVERSAMPLENR, 270},
|
{46*OVERSAMPLENR, 270},
|
||||||
{50*OVERSAMPLENR, 265},
|
{50*OVERSAMPLENR, 265},
|
||||||
{54*OVERSAMPLENR, 260},
|
{54*OVERSAMPLENR, 260},
|
||||||
{58*OVERSAMPLENR, 255},
|
{58*OVERSAMPLENR, 255},
|
||||||
{62*OVERSAMPLENR, 250},
|
{62*OVERSAMPLENR, 250},
|
||||||
{67*OVERSAMPLENR, 245},
|
{67*OVERSAMPLENR, 245},
|
||||||
{72*OVERSAMPLENR, 240},
|
{72*OVERSAMPLENR, 240},
|
||||||
{79*OVERSAMPLENR, 235},
|
{79*OVERSAMPLENR, 235},
|
||||||
{85*OVERSAMPLENR, 230},
|
{85*OVERSAMPLENR, 230},
|
||||||
{91*OVERSAMPLENR, 225},
|
{91*OVERSAMPLENR, 225},
|
||||||
{99*OVERSAMPLENR, 220},
|
{99*OVERSAMPLENR, 220},
|
||||||
{107*OVERSAMPLENR, 215},
|
{107*OVERSAMPLENR, 215},
|
||||||
{116*OVERSAMPLENR, 210},
|
{116*OVERSAMPLENR, 210},
|
||||||
{126*OVERSAMPLENR, 205},
|
{126*OVERSAMPLENR, 205},
|
||||||
{136*OVERSAMPLENR, 200},
|
{136*OVERSAMPLENR, 200},
|
||||||
{149*OVERSAMPLENR, 195},
|
{149*OVERSAMPLENR, 195},
|
||||||
{160*OVERSAMPLENR, 190},
|
{160*OVERSAMPLENR, 190},
|
||||||
{175*OVERSAMPLENR, 185},
|
{175*OVERSAMPLENR, 185},
|
||||||
{191*OVERSAMPLENR, 180},
|
{191*OVERSAMPLENR, 180},
|
||||||
{209*OVERSAMPLENR, 175},
|
{209*OVERSAMPLENR, 175},
|
||||||
{224*OVERSAMPLENR, 170},
|
{224*OVERSAMPLENR, 170},
|
||||||
{246*OVERSAMPLENR, 165},
|
{246*OVERSAMPLENR, 165},
|
||||||
{267*OVERSAMPLENR, 160},
|
{267*OVERSAMPLENR, 160},
|
||||||
{293*OVERSAMPLENR, 155},
|
{293*OVERSAMPLENR, 155},
|
||||||
{316*OVERSAMPLENR, 150},
|
{316*OVERSAMPLENR, 150},
|
||||||
{340*OVERSAMPLENR, 145},
|
{340*OVERSAMPLENR, 145},
|
||||||
{364*OVERSAMPLENR, 140},
|
{364*OVERSAMPLENR, 140},
|
||||||
{396*OVERSAMPLENR, 135},
|
{396*OVERSAMPLENR, 135},
|
||||||
{425*OVERSAMPLENR, 130},
|
{425*OVERSAMPLENR, 130},
|
||||||
{460*OVERSAMPLENR, 125},
|
{460*OVERSAMPLENR, 125},
|
||||||
{489*OVERSAMPLENR, 120},
|
{489*OVERSAMPLENR, 120},
|
||||||
{526*OVERSAMPLENR, 115},
|
{526*OVERSAMPLENR, 115},
|
||||||
{558*OVERSAMPLENR, 110},
|
{558*OVERSAMPLENR, 110},
|
||||||
{591*OVERSAMPLENR, 105},
|
{591*OVERSAMPLENR, 105},
|
||||||
{628*OVERSAMPLENR, 100},
|
{628*OVERSAMPLENR, 100},
|
||||||
{660*OVERSAMPLENR, 95},
|
{660*OVERSAMPLENR, 95},
|
||||||
{696*OVERSAMPLENR, 90},
|
{696*OVERSAMPLENR, 90},
|
||||||
{733*OVERSAMPLENR, 85},
|
{733*OVERSAMPLENR, 85},
|
||||||
{761*OVERSAMPLENR, 80},
|
{761*OVERSAMPLENR, 80},
|
||||||
{794*OVERSAMPLENR, 75},
|
{794*OVERSAMPLENR, 75},
|
||||||
{819*OVERSAMPLENR, 70},
|
{819*OVERSAMPLENR, 70},
|
||||||
{847*OVERSAMPLENR, 65},
|
{847*OVERSAMPLENR, 65},
|
||||||
{870*OVERSAMPLENR, 60},
|
{870*OVERSAMPLENR, 60},
|
||||||
{892*OVERSAMPLENR, 55},
|
{892*OVERSAMPLENR, 55},
|
||||||
{911*OVERSAMPLENR, 50},
|
{911*OVERSAMPLENR, 50},
|
||||||
{929*OVERSAMPLENR, 45},
|
{929*OVERSAMPLENR, 45},
|
||||||
{944*OVERSAMPLENR, 40},
|
{944*OVERSAMPLENR, 40},
|
||||||
{959*OVERSAMPLENR, 35},
|
{959*OVERSAMPLENR, 35},
|
||||||
{971*OVERSAMPLENR, 30},
|
{971*OVERSAMPLENR, 30},
|
||||||
{981*OVERSAMPLENR, 25},
|
{981*OVERSAMPLENR, 25},
|
||||||
{989*OVERSAMPLENR, 20},
|
{989*OVERSAMPLENR, 20},
|
||||||
{994*OVERSAMPLENR, 15},
|
{994*OVERSAMPLENR, 15},
|
||||||
{1001*OVERSAMPLENR, 10},
|
{1001*OVERSAMPLENR, 10},
|
||||||
{1005*OVERSAMPLENR, 5}
|
{1005*OVERSAMPLENR, 5}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if THERMISTORHEATER_1 == 1
|
#if THERMISTORHEATER_1 == 1
|
||||||
#define NUMTEMPS_HEATER_1 NUMTEMPS_1
|
#define NUMTEMPS_HEATER_1 NUMTEMPS_1
|
||||||
#define temptable_1 temptable_1
|
#define temptable_1 temptable_1
|
||||||
#elif THERMISTORHEATER_1 == 2
|
#elif THERMISTORHEATER_1 == 2
|
||||||
#define NUMTEMPS_HEATER_1 NUMTEMPS_2
|
#define NUMTEMPS_HEATER_1 NUMTEMPS_2
|
||||||
#define temptable_1 temptable_2
|
#define temptable_1 temptable_2
|
||||||
#elif THERMISTORHEATER_1 == 3
|
#elif THERMISTORHEATER_1 == 3
|
||||||
#define NUMTEMPS_HEATER_1 NUMTEMPS_3
|
#define NUMTEMPS_HEATER_1 NUMTEMPS_3
|
||||||
#define temptable_1 temptable_3
|
#define temptable_1 temptable_3
|
||||||
#elif THERMISTORHEATER_1 == 4
|
#elif THERMISTORHEATER_1 == 4
|
||||||
#define NUMTEMPS_HEATER_1 NUMTEMPS_4
|
#define NUMTEMPS_HEATER_1 NUMTEMPS_4
|
||||||
#define temptable_1 temptable_4
|
#define temptable_1 temptable_4
|
||||||
#elif THERMISTORHEATER_1 == 5
|
#elif THERMISTORHEATER_1 == 5
|
||||||
#define NUMTEMPS_HEATER_1 NUMTEMPS_5
|
#define NUMTEMPS_HEATER_1 NUMTEMPS_5
|
||||||
#define temptable_1 temptable_5
|
#define temptable_1 temptable_5
|
||||||
#elif THERMISTORHEATER_1 == 6
|
#elif THERMISTORHEATER_1 == 6
|
||||||
#define NUMTEMPS_HEATER_1 NUMTEMPS_6
|
#define NUMTEMPS_HEATER_1 NUMTEMPS_6
|
||||||
#define temptable_1 temptable_6
|
#define temptable_1 temptable_6
|
||||||
#elif THERMISTORHEATER_1 == 7
|
#elif THERMISTORHEATER_1 == 7
|
||||||
#define NUMTEMPS_HEATER_1 NUMTEMPS_7
|
#define NUMTEMPS_HEATER_1 NUMTEMPS_7
|
||||||
#define temptable_1 temptable_7
|
#define temptable_1 temptable_7
|
||||||
#elif defined HEATER_1_USES_THERMISTOR
|
#elif defined HEATER_1_USES_THERMISTOR
|
||||||
#error No heater 1 thermistor table specified
|
#error No heater 1 thermistor table specified
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if THERMISTORHEATER_2 == 1
|
#if THERMISTORHEATER_2 == 1
|
||||||
#define NUMTEMPS_HEATER_2 NUMTEMPS_1
|
#define NUMTEMPS_HEATER_2 NUMTEMPS_1
|
||||||
#define temptable_2 temptable_1
|
#define temptable_2 temptable_1
|
||||||
#elif THERMISTORHEATER_2 == 2
|
#elif THERMISTORHEATER_2 == 2
|
||||||
#define NUMTEMPS_HEATER_2 NUMTEMPS_2
|
#define NUMTEMPS_HEATER_2 NUMTEMPS_2
|
||||||
#define temptable_2 temptable_2
|
#define temptable_2 temptable_2
|
||||||
#elif THERMISTORHEATER_2 == 3
|
#elif THERMISTORHEATER_2 == 3
|
||||||
#define NUMTEMPS_HEATER_2 NUMTEMPS_3
|
#define NUMTEMPS_HEATER_2 NUMTEMPS_3
|
||||||
#define temptable_2 temptable_3
|
#define temptable_2 temptable_3
|
||||||
#elif THERMISTORHEATER_2 == 4
|
#elif THERMISTORHEATER_2 == 4
|
||||||
#define NUMTEMPS_HEATER_2 NUMTEMPS_4
|
#define NUMTEMPS_HEATER_2 NUMTEMPS_4
|
||||||
#define temptable_2 temptable_4
|
#define temptable_2 temptable_4
|
||||||
#elif THERMISTORHEATER_2 == 5
|
#elif THERMISTORHEATER_2 == 5
|
||||||
#define NUMTEMPS_HEATER_2 NUMTEMPS_5
|
#define NUMTEMPS_HEATER_2 NUMTEMPS_5
|
||||||
#define temptable_2 temptable_5
|
#define temptable_2 temptable_5
|
||||||
#elif THERMISTORHEATER_2 == 6
|
#elif THERMISTORHEATER_2 == 6
|
||||||
#define NUMTEMPS_HEATER_2 NUMTEMPS_6
|
#define NUMTEMPS_HEATER_2 NUMTEMPS_6
|
||||||
#define temptable_2 temptable_6
|
#define temptable_2 temptable_6
|
||||||
#elif THERMISTORHEATER_2 == 7
|
#elif THERMISTORHEATER_2 == 7
|
||||||
#define NUMTEMPS_HEATER22 NUMTEMPS_7
|
#define NUMTEMPS_HEATER22 NUMTEMPS_7
|
||||||
#define temptable_2 temptable_7
|
#define temptable_2 temptable_7
|
||||||
#elif defined HEATER_2_USES_THERMISTOR
|
#elif defined HEATER_2_USES_THERMISTOR
|
||||||
#error No heater 2 thermistor table specified
|
#error No heater 2 thermistor table specified
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if THERMISTORBED == 1
|
#if THERMISTORBED == 1
|
||||||
#define BNUMTEMPS NUMTEMPS_1
|
#define BNUMTEMPS NUMTEMPS_1
|
||||||
#define bedtemptable temptable_1
|
#define bedtemptable temptable_1
|
||||||
#elif THERMISTORBED == 2
|
#elif THERMISTORBED == 2
|
||||||
#define BNUMTEMPS NUMTEMPS_2
|
#define BNUMTEMPS NUMTEMPS_2
|
||||||
#define bedtemptable temptable_2
|
#define bedtemptable temptable_2
|
||||||
#elif THERMISTORBED == 3
|
#elif THERMISTORBED == 3
|
||||||
#define BNUMTEMPS NUMTEMPS_3
|
#define BNUMTEMPS NUMTEMPS_3
|
||||||
#define bedtemptable temptable_3
|
#define bedtemptable temptable_3
|
||||||
#elif THERMISTORBED == 4
|
#elif THERMISTORBED == 4
|
||||||
#define BNUMTEMPS NUMTEMPS_4
|
#define BNUMTEMPS NUMTEMPS_4
|
||||||
#define bedtemptable temptable_4
|
#define bedtemptable temptable_4
|
||||||
#elif THERMISTORBED == 5
|
#elif THERMISTORBED == 5
|
||||||
#define BNUMTEMPS NUMTEMPS_5
|
#define BNUMTEMPS NUMTEMPS_5
|
||||||
#define bedtemptable temptable_5
|
#define bedtemptable temptable_5
|
||||||
#elif THERMISTORBED == 6
|
#elif THERMISTORBED == 6
|
||||||
#define BNUMTEMPS NUMTEMPS_6
|
#define BNUMTEMPS NUMTEMPS_6
|
||||||
#define bedtemptable temptable_6
|
#define bedtemptable temptable_6
|
||||||
#elif THERMISTORBED == 7
|
#elif THERMISTORBED == 7
|
||||||
#define BNUMTEMPS NUMTEMPS_7
|
#define BNUMTEMPS NUMTEMPS_7
|
||||||
#define bedtemptable temptable_7
|
#define bedtemptable temptable_7
|
||||||
#elif defined BED_USES_THERMISTOR
|
#elif defined BED_USES_THERMISTOR
|
||||||
#error No bed thermistor table specified
|
#error No bed thermistor table specified
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif //THERMISTORTABLES_H_
|
#endif //THERMISTORTABLES_H_
|
||||||
|
|
||||||
|
|
|
@ -1,156 +1,156 @@
|
||||||
#ifndef __ULTRALCDH
|
#ifndef __ULTRALCDH
|
||||||
#define __ULTRALCDH
|
#define __ULTRALCDH
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
|
|
||||||
#ifdef ULTRA_LCD
|
#ifdef ULTRA_LCD
|
||||||
|
|
||||||
void lcd_status();
|
void lcd_status();
|
||||||
void lcd_init();
|
void lcd_init();
|
||||||
void lcd_status(const char* message);
|
void lcd_status(const char* message);
|
||||||
void beep();
|
void beep();
|
||||||
void buttons_check();
|
void buttons_check();
|
||||||
#define LCDSTATUSRIGHT
|
#define LCDSTATUSRIGHT
|
||||||
|
|
||||||
#define LCD_UPDATE_INTERVAL 100
|
#define LCD_UPDATE_INTERVAL 100
|
||||||
#define STATUSTIMEOUT 15000
|
#define STATUSTIMEOUT 15000
|
||||||
|
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
|
|
||||||
#include <LiquidCrystal.h>
|
#include <LiquidCrystal.h>
|
||||||
extern LiquidCrystal lcd;
|
extern LiquidCrystal lcd;
|
||||||
|
|
||||||
//lcd display size
|
//lcd display size
|
||||||
|
|
||||||
#ifdef NEWPANEL
|
#ifdef NEWPANEL
|
||||||
//arduino pin witch triggers an piezzo beeper
|
//arduino pin witch triggers an piezzo beeper
|
||||||
#define BEEPER 18
|
#define BEEPER 18
|
||||||
|
|
||||||
#define LCD_PINS_RS 20
|
#define LCD_PINS_RS 20
|
||||||
#define LCD_PINS_ENABLE 17
|
#define LCD_PINS_ENABLE 17
|
||||||
#define LCD_PINS_D4 16
|
#define LCD_PINS_D4 16
|
||||||
#define LCD_PINS_D5 21
|
#define LCD_PINS_D5 21
|
||||||
#define LCD_PINS_D6 5
|
#define LCD_PINS_D6 5
|
||||||
#define LCD_PINS_D7 6
|
#define LCD_PINS_D7 6
|
||||||
|
|
||||||
//buttons are directly attached
|
//buttons are directly attached
|
||||||
#define BTN_EN1 40
|
#define BTN_EN1 40
|
||||||
#define BTN_EN2 42
|
#define BTN_EN2 42
|
||||||
#define BTN_ENC 19 //the click
|
#define BTN_ENC 19 //the click
|
||||||
|
|
||||||
#define BLEN_C 2
|
#define BLEN_C 2
|
||||||
#define BLEN_B 1
|
#define BLEN_B 1
|
||||||
#define BLEN_A 0
|
#define BLEN_A 0
|
||||||
|
|
||||||
#define SDCARDDETECT 38
|
#define SDCARDDETECT 38
|
||||||
|
|
||||||
#define EN_C (1<<BLEN_C)
|
#define EN_C (1<<BLEN_C)
|
||||||
#define EN_B (1<<BLEN_B)
|
#define EN_B (1<<BLEN_B)
|
||||||
#define EN_A (1<<BLEN_A)
|
#define EN_A (1<<BLEN_A)
|
||||||
|
|
||||||
//encoder rotation values
|
//encoder rotation values
|
||||||
#define encrot0 0
|
#define encrot0 0
|
||||||
#define encrot1 2
|
#define encrot1 2
|
||||||
#define encrot2 3
|
#define encrot2 3
|
||||||
#define encrot3 1
|
#define encrot3 1
|
||||||
|
|
||||||
|
|
||||||
#define CLICKED (buttons&EN_C)
|
#define CLICKED (buttons&EN_C)
|
||||||
#define BLOCK {blocking=millis()+blocktime;}
|
#define BLOCK {blocking=millis()+blocktime;}
|
||||||
#define CARDINSERTED (READ(SDCARDDETECT)==0)
|
#define CARDINSERTED (READ(SDCARDDETECT)==0)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
//arduino pin witch triggers an piezzo beeper
|
//arduino pin witch triggers an piezzo beeper
|
||||||
#define BEEPER 18
|
#define BEEPER 18
|
||||||
|
|
||||||
//buttons are attached to a shift register
|
//buttons are attached to a shift register
|
||||||
#define SHIFT_CLK 38
|
#define SHIFT_CLK 38
|
||||||
#define SHIFT_LD 42
|
#define SHIFT_LD 42
|
||||||
#define SHIFT_OUT 40
|
#define SHIFT_OUT 40
|
||||||
#define SHIFT_EN 17
|
#define SHIFT_EN 17
|
||||||
|
|
||||||
#define LCD_PINS_RS 16
|
#define LCD_PINS_RS 16
|
||||||
#define LCD_PINS_ENABLE 5
|
#define LCD_PINS_ENABLE 5
|
||||||
#define LCD_PINS_D4 6
|
#define LCD_PINS_D4 6
|
||||||
#define LCD_PINS_D5 21
|
#define LCD_PINS_D5 21
|
||||||
#define LCD_PINS_D6 20
|
#define LCD_PINS_D6 20
|
||||||
#define LCD_PINS_D7 19
|
#define LCD_PINS_D7 19
|
||||||
|
|
||||||
//bits in the shift register that carry the buttons for:
|
//bits in the shift register that carry the buttons for:
|
||||||
// left up center down right red
|
// left up center down right red
|
||||||
#define BL_LE 7
|
#define BL_LE 7
|
||||||
#define BL_UP 6
|
#define BL_UP 6
|
||||||
#define BL_MI 5
|
#define BL_MI 5
|
||||||
#define BL_DW 4
|
#define BL_DW 4
|
||||||
#define BL_RI 3
|
#define BL_RI 3
|
||||||
#define BL_ST 2
|
#define BL_ST 2
|
||||||
|
|
||||||
#define BLEN_B 1
|
#define BLEN_B 1
|
||||||
#define BLEN_A 0
|
#define BLEN_A 0
|
||||||
|
|
||||||
//encoder rotation values
|
//encoder rotation values
|
||||||
#define encrot0 0
|
#define encrot0 0
|
||||||
#define encrot1 2
|
#define encrot1 2
|
||||||
#define encrot2 3
|
#define encrot2 3
|
||||||
#define encrot3 1
|
#define encrot3 1
|
||||||
|
|
||||||
//atomatic, do not change
|
//atomatic, do not change
|
||||||
#define B_LE (1<<BL_LE)
|
#define B_LE (1<<BL_LE)
|
||||||
#define B_UP (1<<BL_UP)
|
#define B_UP (1<<BL_UP)
|
||||||
#define B_MI (1<<BL_MI)
|
#define B_MI (1<<BL_MI)
|
||||||
#define B_DW (1<<BL_DW)
|
#define B_DW (1<<BL_DW)
|
||||||
#define B_RI (1<<BL_RI)
|
#define B_RI (1<<BL_RI)
|
||||||
#define B_ST (1<<BL_ST)
|
#define B_ST (1<<BL_ST)
|
||||||
#define EN_B (1<<BLEN_B)
|
#define EN_B (1<<BLEN_B)
|
||||||
#define EN_A (1<<BLEN_A)
|
#define EN_A (1<<BLEN_A)
|
||||||
|
|
||||||
#define CLICKED ((buttons&B_MI)||(buttons&B_ST))
|
#define CLICKED ((buttons&B_MI)||(buttons&B_ST))
|
||||||
#define BLOCK {blocking[BL_MI]=millis()+blocktime;blocking[BL_ST]=millis()+blocktime;}
|
#define BLOCK {blocking[BL_MI]=millis()+blocktime;blocking[BL_ST]=millis()+blocktime;}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// blocking time for recognizing a new keypress of one key, ms
|
// blocking time for recognizing a new keypress of one key, ms
|
||||||
#define blocktime 500
|
#define blocktime 500
|
||||||
#define lcdslow 5
|
#define lcdslow 5
|
||||||
enum MainStatus{Main_Status, Main_Menu, Main_Prepare, Main_Control, Main_SD};
|
enum MainStatus{Main_Status, Main_Menu, Main_Prepare, Main_Control, Main_SD};
|
||||||
|
|
||||||
class MainMenu{
|
class MainMenu{
|
||||||
public:
|
public:
|
||||||
MainMenu();
|
MainMenu();
|
||||||
void update();
|
void update();
|
||||||
void getfilename(const uint8_t nr);
|
void getfilename(const uint8_t nr);
|
||||||
uint8_t activeline;
|
uint8_t activeline;
|
||||||
MainStatus status;
|
MainStatus status;
|
||||||
uint8_t displayStartingRow;
|
uint8_t displayStartingRow;
|
||||||
|
|
||||||
void showStatus();
|
void showStatus();
|
||||||
void showMainMenu();
|
void showMainMenu();
|
||||||
void showPrepare();
|
void showPrepare();
|
||||||
void showControl();
|
void showControl();
|
||||||
void showSD();
|
void showSD();
|
||||||
bool force_lcd_update;
|
bool force_lcd_update;
|
||||||
int lastencoderpos;
|
int lastencoderpos;
|
||||||
int8_t lineoffset;
|
int8_t lineoffset;
|
||||||
int8_t lastlineoffset;
|
int8_t lastlineoffset;
|
||||||
char filename[11];
|
char filename[11];
|
||||||
bool linechanging;
|
bool linechanging;
|
||||||
};
|
};
|
||||||
|
|
||||||
char *fillto(int8_t n,char *c);
|
char *fillto(int8_t n,char *c);
|
||||||
char *ftostr51(const float &x);
|
char *ftostr51(const float &x);
|
||||||
char *ftostr31(const float &x);
|
char *ftostr31(const float &x);
|
||||||
char *ftostr3(const float &x);
|
char *ftostr3(const float &x);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define LCD_MESSAGE(x) lcd_status(x);
|
#define LCD_MESSAGE(x) lcd_status(x);
|
||||||
#define LCD_STATUS lcd_status()
|
#define LCD_STATUS lcd_status()
|
||||||
#else //no lcd
|
#else //no lcd
|
||||||
#define LCD_STATUS
|
#define LCD_STATUS
|
||||||
#define LCD_MESSAGE(x)
|
#define LCD_MESSAGE(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ULTIPANEL
|
#ifndef ULTIPANEL
|
||||||
#define CLICKED false
|
#define CLICKED false
|
||||||
#define BLOCK ;
|
#define BLOCK ;
|
||||||
#endif
|
#endif
|
||||||
#endif //ULTRALCD
|
#endif //ULTRALCD
|
||||||
|
|
||||||
|
|
128
README
128
README
|
@ -1,64 +1,64 @@
|
||||||
This RepRap firmware is a mashup between Sprinter, grbl and many original parts.
|
This RepRap firmware is a mashup between Sprinter, grbl and many original parts.
|
||||||
(https://github.com/kliment/Sprinter)
|
(https://github.com/kliment/Sprinter)
|
||||||
(https://github.com/simen/grbl/tree)
|
(https://github.com/simen/grbl/tree)
|
||||||
|
|
||||||
Derived from Sprinter and Grbl by Erik van der Zalm.
|
Derived from Sprinter and Grbl by Erik van der Zalm.
|
||||||
Sprinters lead developers are Kliment and caru.
|
Sprinters lead developers are Kliment and caru.
|
||||||
Grbls lead developer is Simen Svale Skogsrud.
|
Grbls lead developer is Simen Svale Skogsrud.
|
||||||
It has been adapted to the Ultimaker Printer by:
|
It has been adapted to the Ultimaker Printer by:
|
||||||
Bernhard Kubicek, Matthijs Keuper, Bradley Feldman, and others...
|
Bernhard Kubicek, Matthijs Keuper, Bradley Feldman, and others...
|
||||||
|
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Interrupt based movement with real linear acceleration
|
- Interrupt based movement with real linear acceleration
|
||||||
- High steprate
|
- High steprate
|
||||||
- Look ahead (Keep the speed high when possible. High cornering speed)
|
- Look ahead (Keep the speed high when possible. High cornering speed)
|
||||||
- Interrupt based temperature protection
|
- Interrupt based temperature protection
|
||||||
- preliminary support for Matthew Roberts advance algorithm
|
- preliminary support for Matthew Roberts advance algorithm
|
||||||
For more info see: http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
|
For more info see: http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
|
||||||
- Full endstop support
|
- Full endstop support
|
||||||
- Simple LCD support (16x2)
|
- Simple LCD support (16x2)
|
||||||
- SD Card support
|
- SD Card support
|
||||||
- Provisions for Bernhard Kubicek's new hardware control console and 20x4 lcd
|
- Provisions for Bernhard Kubicek's new hardware control console and 20x4 lcd
|
||||||
|
|
||||||
This firmware is optimized for Ultimaker's gen6 electronics (including the Ultimaker 1.5.x daughterboard and Arduino Mega 2560).
|
This firmware is optimized for Ultimaker's gen6 electronics (including the Ultimaker 1.5.x daughterboard and Arduino Mega 2560).
|
||||||
|
|
||||||
The default baudrate is 115200.
|
The default baudrate is 115200.
|
||||||
|
|
||||||
|
|
||||||
========================================================================================
|
========================================================================================
|
||||||
|
|
||||||
Configuring and compilation
|
Configuring and compilation
|
||||||
|
|
||||||
|
|
||||||
Install the latest arduino software IDE/toolset (currently 0022)
|
Install the latest arduino software IDE/toolset (currently 0022)
|
||||||
http://www.arduino.cc/en/Main/Software
|
http://www.arduino.cc/en/Main/Software
|
||||||
|
|
||||||
Install Ultimaker's RepG 25 build
|
Install Ultimaker's RepG 25 build
|
||||||
http://software.ultimaker.com
|
http://software.ultimaker.com
|
||||||
(or alternatively install Kliment's printrun/pronterface https://github.com/kliment/Printrun_)
|
(or alternatively install Kliment's printrun/pronterface https://github.com/kliment/Printrun_)
|
||||||
|
|
||||||
Copy the Ultimaker Marlin firmware
|
Copy the Ultimaker Marlin firmware
|
||||||
https:/github.com/bkubicek/Marlin
|
https:/github.com/bkubicek/Marlin
|
||||||
(Use the download button)
|
(Use the download button)
|
||||||
|
|
||||||
Start the arduino IDE.
|
Start the arduino IDE.
|
||||||
Select Tools -> Board -> Arduino Mega 2560
|
Select Tools -> Board -> Arduino Mega 2560
|
||||||
Select the correct serial port in Tools ->Serial Port
|
Select the correct serial port in Tools ->Serial Port
|
||||||
Open Marlin.pde
|
Open Marlin.pde
|
||||||
|
|
||||||
Click the Verify/Compile button
|
Click the Verify/Compile button
|
||||||
|
|
||||||
Click the Upload button
|
Click the Upload button
|
||||||
If all goes well the firmware is uploading
|
If all goes well the firmware is uploading
|
||||||
|
|
||||||
Start Ultimaker's Custom RepG 25
|
Start Ultimaker's Custom RepG 25
|
||||||
Make sure Show Experimental Profiles is enabled in Preferences
|
Make sure Show Experimental Profiles is enabled in Preferences
|
||||||
Select Sprinter as the Driver
|
Select Sprinter as the Driver
|
||||||
|
|
||||||
Press the Connect button.
|
Press the Connect button.
|
||||||
|
|
||||||
KNOWN ISSUES: RepG will display: Unknown: marlin x.y.z
|
KNOWN ISSUES: RepG will display: Unknown: marlin x.y.z
|
||||||
|
|
||||||
That's ok. Enjoy Silky Smooth Printing.
|
That's ok. Enjoy Silky Smooth Printing.
|
||||||
|
|
||||||
|
|
138
README.md
138
README.md
|
@ -1,69 +1,69 @@
|
||||||
WARNING: THIS IN A PROCESS OF HEAVY OVERWORKING.
|
WARNING: THIS IN A PROCESS OF HEAVY OVERWORKING.
|
||||||
DO NOT USE THIS ON YOUR MACHINE UNTIL FURTHER NOTICE!!!
|
DO NOT USE THIS ON YOUR MACHINE UNTIL FURTHER NOTICE!!!
|
||||||
|
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
This RepRap firmware is a mashup between <a href="https://github.com/kliment/Sprinter">Sprinter</a>, <a href="https://github.com/simen/grbl/tree">grbl</a> and many original parts.
|
This RepRap firmware is a mashup between <a href="https://github.com/kliment/Sprinter">Sprinter</a>, <a href="https://github.com/simen/grbl/tree">grbl</a> and many original parts.
|
||||||
|
|
||||||
Derived from Sprinter and Grbl by Erik van der Zalm.
|
Derived from Sprinter and Grbl by Erik van der Zalm.
|
||||||
Sprinters lead developers are Kliment and caru.
|
Sprinters lead developers are Kliment and caru.
|
||||||
Grbls lead developer is Simen Svale Skogsrud.
|
Grbls lead developer is Simen Svale Skogsrud.
|
||||||
Some features have been added by and configuration has been added by:
|
Some features have been added by and configuration has been added by:
|
||||||
Bernhard Kubicek, Matthijs Keuper, Bradley Feldman, and others...
|
Bernhard Kubicek, Matthijs Keuper, Bradley Feldman, and others...
|
||||||
|
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Interrupt based movement with real linear acceleration
|
- Interrupt based movement with real linear acceleration
|
||||||
- High steprate
|
- High steprate
|
||||||
- Look ahead (Keep the speed high when possible. High cornering speed)
|
- Look ahead (Keep the speed high when possible. High cornering speed)
|
||||||
- Interrupt based temperature protection
|
- Interrupt based temperature protection
|
||||||
- preliminary support for Matthew Roberts advance algorithm
|
- preliminary support for Matthew Roberts advance algorithm
|
||||||
For more info see: http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
|
For more info see: http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
|
||||||
- Full endstop support
|
- Full endstop support
|
||||||
- Simple LCD support (16x2)
|
- Simple LCD support (16x2)
|
||||||
- SD Card support
|
- SD Card support
|
||||||
- Provisions for Bernhard Kubicek's new hardware control console and 20x4 lcd
|
- Provisions for Bernhard Kubicek's new hardware control console and 20x4 lcd
|
||||||
|
|
||||||
This firmware is optimized for Ultimaker's gen6 electronics (including the Ultimaker 1.5.x daughterboard and Arduino Mega 2560).
|
This firmware is optimized for Ultimaker's gen6 electronics (including the Ultimaker 1.5.x daughterboard and Arduino Mega 2560).
|
||||||
|
|
||||||
The default baudrate is 115200.
|
The default baudrate is 115200.
|
||||||
|
|
||||||
|
|
||||||
========================================================================================
|
========================================================================================
|
||||||
|
|
||||||
Configuring and compilation
|
Configuring and compilation
|
||||||
|
|
||||||
|
|
||||||
Install the latest arduino software IDE/toolset (currently 0022)
|
Install the latest arduino software IDE/toolset (currently 0022)
|
||||||
http://www.arduino.cc/en/Main/Software
|
http://www.arduino.cc/en/Main/Software
|
||||||
|
|
||||||
Install Ultimaker's RepG 25 build
|
Install Ultimaker's RepG 25 build
|
||||||
http://software.ultimaker.com
|
http://software.ultimaker.com
|
||||||
(or alternatively install Kliment's printrun/pronterface https://github.com/kliment/Printrun_)
|
(or alternatively install Kliment's printrun/pronterface https://github.com/kliment/Printrun_)
|
||||||
|
|
||||||
Copy the Ultimaker Marlin firmware
|
Copy the Ultimaker Marlin firmware
|
||||||
https:/github.com/bkubicek/Marlin
|
https:/github.com/bkubicek/Marlin
|
||||||
(Use the download button)
|
(Use the download button)
|
||||||
|
|
||||||
Start the arduino IDE.
|
Start the arduino IDE.
|
||||||
Select Tools -> Board -> Arduino Mega 2560
|
Select Tools -> Board -> Arduino Mega 2560
|
||||||
Select the correct serial port in Tools ->Serial Port
|
Select the correct serial port in Tools ->Serial Port
|
||||||
Open Marlin.pde
|
Open Marlin.pde
|
||||||
|
|
||||||
Click the Verify/Compile button
|
Click the Verify/Compile button
|
||||||
|
|
||||||
Click the Upload button
|
Click the Upload button
|
||||||
If all goes well the firmware is uploading
|
If all goes well the firmware is uploading
|
||||||
|
|
||||||
Start Ultimaker's Custom RepG 25
|
Start Ultimaker's Custom RepG 25
|
||||||
Make sure Show Experimental Profiles is enabled in Preferences
|
Make sure Show Experimental Profiles is enabled in Preferences
|
||||||
Select Sprinter as the Driver
|
Select Sprinter as the Driver
|
||||||
|
|
||||||
Press the Connect button.
|
Press the Connect button.
|
||||||
|
|
||||||
KNOWN ISSUES: RepG will display: Unknown: marlin x.y.z
|
KNOWN ISSUES: RepG will display: Unknown: marlin x.y.z
|
||||||
|
|
||||||
That's ok. Enjoy Silky Smooth Printing.
|
That's ok. Enjoy Silky Smooth Printing.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,58 +1,58 @@
|
||||||
files to compare manually:
|
files to compare manually:
|
||||||
planner.cpp
|
planner.cpp
|
||||||
stepper.cpp
|
stepper.cpp
|
||||||
temperature.cpp
|
temperature.cpp
|
||||||
|
|
||||||
---
|
---
|
||||||
things that changed:
|
things that changed:
|
||||||
* planner.cpp
|
* planner.cpp
|
||||||
estimate_acc_distance now works with floats.
|
estimate_acc_distance now works with floats.
|
||||||
in calculate_trapezoid:for_block
|
in calculate_trapezoid:for_block
|
||||||
long acceleration_rate=(long)((float)acceleration*8.388608) is gone
|
long acceleration_rate=(long)((float)acceleration*8.388608) is gone
|
||||||
so is block_>acceleration_rate
|
so is block_>acceleration_rate
|
||||||
void planner_reverse_pass:
|
void planner_reverse_pass:
|
||||||
some stuff I don't understand right now changed
|
some stuff I don't understand right now changed
|
||||||
in planner_forward_pass:
|
in planner_forward_pass:
|
||||||
done: BLOCK_BUFFER_SIZE is now necessarily power of 2 (aka 8 16, 32). Inportant to document this somewhere.
|
done: BLOCK_BUFFER_SIZE is now necessarily power of 2 (aka 8 16, 32). Inportant to document this somewhere.
|
||||||
no more inline in void plan_discard_current_block()
|
no more inline in void plan_discard_current_block()
|
||||||
no more inline in plan_get_current_block()
|
no more inline in plan_get_current_block()
|
||||||
in plan_buffer_line(...)
|
in plan_buffer_line(...)
|
||||||
the long target[4]; and calculations of thoose should go after the while(block_buffer_tail==..). if the axis_steps_per_unit are changed from the gcode (M92) the calculation for the currently planned buffer move will be corrupt, because Target is calculated with one value, and the stuff afterwards with another. At least this solved the problem I had with the M92 E* changes in the code. Very sure about this, I took me 20min to find this as the solution for the bug I was hunting.
|
the long target[4]; and calculations of thoose should go after the while(block_buffer_tail==..). if the axis_steps_per_unit are changed from the gcode (M92) the calculation for the currently planned buffer move will be corrupt, because Target is calculated with one value, and the stuff afterwards with another. At least this solved the problem I had with the M92 E* changes in the code. Very sure about this, I took me 20min to find this as the solution for the bug I was hunting.
|
||||||
around if(feed_rate<minimumfeedrate) this only should be done if it is not a pure extrusion. I think there is a bug right now.
|
around if(feed_rate<minimumfeedrate) this only should be done if it is not a pure extrusion. I think there is a bug right now.
|
||||||
~line 447 blockcount=
|
~line 447 blockcount=
|
||||||
not sure if this also works if the difference is negative, as it would happen if the ringbuffer runs over the end and start at 0.
|
not sure if this also works if the difference is negative, as it would happen if the ringbuffer runs over the end and start at 0.
|
||||||
~line 507 tmp_aceleration. not sure whats going on, but a lot changed.
|
~line 507 tmp_aceleration. not sure whats going on, but a lot changed.
|
||||||
|
|
||||||
|
|
||||||
* stepper.cpp
|
* stepper.cpp
|
||||||
~214: if (busy) should be a echoln, maybe
|
~214: if (busy) should be a echoln, maybe
|
||||||
~331: great, The Z_M_PIN checks are in :)
|
~331: great, The Z_M_PIN checks are in :)
|
||||||
|
|
||||||
*temperature.cpp
|
*temperature.cpp
|
||||||
done: enum for heater, bed,
|
done: enum for heater, bed,
|
||||||
manage_heater() is seriously different.
|
manage_heater() is seriously different.
|
||||||
done: if tem_meas_ready ==true->!true+return?
|
done: if tem_meas_ready ==true->!true+return?
|
||||||
done #define K1 0.95 maybe in the configuration.h?
|
done #define K1 0.95 maybe in the configuration.h?
|
||||||
semi-done: PID-C checking needed. Untested but added.
|
semi-done: PID-C checking needed. Untested but added.
|
||||||
----
|
----
|
||||||
|
|
||||||
still needed to finish the merge, before testin!
|
still needed to finish the merge, before testin!
|
||||||
|
|
||||||
manage_heater
|
manage_heater
|
||||||
ISR
|
ISR
|
||||||
movement planner
|
movement planner
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
remove traveling at maxpseed
|
remove traveling at maxpseed
|
||||||
remove Simplelcd
|
remove Simplelcd
|
||||||
|
|
||||||
remove DEBUG_STEPS?
|
remove DEBUG_STEPS?
|
||||||
|
|
||||||
block_t
|
block_t
|
||||||
pid_dt ->0.1 whats the changes to the PID, checking needed
|
pid_dt ->0.1 whats the changes to the PID, checking needed
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
second merge saturday morning:
|
second merge saturday morning:
|
||||||
done: PID_dt->0.1
|
done: PID_dt->0.1
|
Reference in a new issue