├── Schematic.png ├── LCD_GRBL ├── lib │ ├── LiquidCrystal_I2C │ │ ├── README.md │ │ ├── LiquidCrystal_I2C.o │ │ ├── library.json │ │ ├── library.properties │ │ ├── examples │ │ │ ├── HelloWorld │ │ │ │ └── HelloWorld.pde │ │ │ ├── SerialDisplay │ │ │ │ └── SerialDisplay.pde │ │ │ └── CustomChars │ │ │ │ └── CustomChars.pde │ │ ├── keywords.txt │ │ ├── LiquidCrystal_I2C.h │ │ └── LiquidCrystal_I2C.cpp │ ├── Encoder │ │ ├── keywords.txt │ │ ├── Encoder.cpp │ │ ├── README.md │ │ ├── library.properties │ │ ├── library.json │ │ ├── examples │ │ │ ├── Basic │ │ │ │ └── Basic.pde │ │ │ ├── TwoKnobs │ │ │ │ └── TwoKnobs.pde │ │ │ ├── NoInterrupts │ │ │ │ └── NoInterrupts.pde │ │ │ └── SpeedTest │ │ │ │ └── SpeedTest.pde │ │ └── utility │ │ │ ├── interrupt_config.h │ │ │ ├── direct_pin_read.h │ │ │ └── interrupt_pins.h │ ├── SD │ │ ├── library.properties │ │ ├── src │ │ │ ├── README.txt │ │ │ ├── utility │ │ │ │ ├── SdFatUtil.h │ │ │ │ ├── SdInfo.h │ │ │ │ ├── SdFatmainpage.h │ │ │ │ ├── Sd2Card.h │ │ │ │ ├── SdVolume.cpp │ │ │ │ ├── FatStructs.h │ │ │ │ ├── Sd2PinMap.h │ │ │ │ ├── SdFat.h │ │ │ │ └── Sd2Card.cpp │ │ │ ├── File.cpp │ │ │ ├── SD.h │ │ │ └── SD.cpp │ │ ├── keywords.txt │ │ ├── README.adoc │ │ └── examples │ │ │ ├── DumpFile │ │ │ └── DumpFile.ino │ │ │ ├── listfiles │ │ │ └── listfiles.ino │ │ │ ├── Files │ │ │ └── Files.ino │ │ │ ├── ReadWrite │ │ │ └── ReadWrite.ino │ │ │ ├── Datalogger │ │ │ └── Datalogger.ino │ │ │ └── CardInfo │ │ │ └── CardInfo.ino │ └── README ├── platformio.ini ├── test │ └── README └── include │ └── README ├── Algorithms-Flow charts ├── void loop().png ├── void menuP().png ├── void setup().png ├── byte fileMenu().png ├── void modMenu().png ├── void moveMenu().png ├── void sendFile().png ├── byte filecount().png ├── void checkForOk().png ├── void controlMenu().png ├── void getStatus().png ├── void moveOption().png ├── void settingMenu().png ├── String getFileName().png ├── void clearRXBuffer().png ├── void menuMoveAxis().png ├── void resetSDReader().png ├── void sendCodeLine().png ├── void setAxisToMove().png ├── String removeIfExists().png ├── void checkButtonSlect().png ├── void setTextDisplay().png ├── void updateDisplayStatus().png └── String ignoreUnsupportedCommands().png └── README.md /Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Schematic.png -------------------------------------------------------------------------------- /LCD_GRBL/lib/LiquidCrystal_I2C/README.md: -------------------------------------------------------------------------------- 1 | # LiquidCrystal_I2C 2 | LiquidCrystal Arduino library for the DFRobot I2C LCD displays 3 | -------------------------------------------------------------------------------- /Algorithms-Flow charts/void loop().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void loop().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void menuP().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void menuP().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void setup().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void setup().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/byte fileMenu().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/byte fileMenu().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void modMenu().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void modMenu().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void moveMenu().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void moveMenu().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void sendFile().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void sendFile().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/byte filecount().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/byte filecount().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void checkForOk().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void checkForOk().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void controlMenu().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void controlMenu().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void getStatus().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void getStatus().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void moveOption().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void moveOption().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void settingMenu().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void settingMenu().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/String getFileName().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/String getFileName().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void clearRXBuffer().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void clearRXBuffer().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void menuMoveAxis().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void menuMoveAxis().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void resetSDReader().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void resetSDReader().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void sendCodeLine().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void sendCodeLine().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void setAxisToMove().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void setAxisToMove().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/String removeIfExists().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/String removeIfExists().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void checkButtonSlect().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void checkButtonSlect().png -------------------------------------------------------------------------------- /Algorithms-Flow charts/void setTextDisplay().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void setTextDisplay().png -------------------------------------------------------------------------------- /LCD_GRBL/lib/LiquidCrystal_I2C/LiquidCrystal_I2C.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/LCD_GRBL/lib/LiquidCrystal_I2C/LiquidCrystal_I2C.o -------------------------------------------------------------------------------- /Algorithms-Flow charts/void updateDisplayStatus().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/void updateDisplayStatus().png -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/keywords.txt: -------------------------------------------------------------------------------- 1 | ENCODER_USE_INTERRUPTS LITERAL1 2 | ENCODER_OPTIMIZE_INTERRUPTS LITERAL1 3 | ENCODER_DO_NOT_USE_INTERRUPTS LITERAL1 4 | Encoder KEYWORD1 5 | -------------------------------------------------------------------------------- /Algorithms-Flow charts/String ignoreUnsupportedCommands().png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cguerrero1205/LCD_GRBL/HEAD/Algorithms-Flow charts/String ignoreUnsupportedCommands().png -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/Encoder.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Encoder.h" 3 | 4 | // Yes, all the code is in the header file, to provide the user 5 | // configure options with #define (before they include it), and 6 | // to facilitate some crafty optimizations! 7 | 8 | Encoder_internal_state_t * Encoder::interruptArgs[]; 9 | 10 | 11 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/README.md: -------------------------------------------------------------------------------- 1 | #Encoder Library# 2 | 3 | Encoder counts pulses from quadrature encoded signals, which are commonly available from rotary knobs, motor or shaft sensors and other position sensors. 4 | 5 | http://www.pjrc.com/teensy/td_libs_Encoder.html 6 | 7 | http://www.youtube.com/watch?v=2puhIong-cs 8 | 9 | ![Encoder Knobs Demo](http://www.pjrc.com/teensy/td_libs_Encoder_1.jpg) 10 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/LiquidCrystal_I2C/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "LiquidCrystal_I2C", 3 | "keywords": "LCD, liquidcrystal, I2C", 4 | "description": "A library for DFRobot I2C LCD displays", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/marcoschwartz/LiquidCrystal_I2C.git" 9 | }, 10 | "frameworks": "arduino", 11 | "platforms": 12 | [ 13 | "atmelavr" 14 | ] 15 | } -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/library.properties: -------------------------------------------------------------------------------- 1 | name=SD 2 | version=1.1.1 3 | author=Arduino, SparkFun 4 | maintainer=Arduino 5 | sentence=Enables reading and writing on SD cards. 6 | paragraph=Once an SD memory card is connected to the SPI interface of the Arduino or Genuino board you can create files and read/write on them. You can also move through directories on the SD card. 7 | category=Data Storage 8 | url=http://www.arduino.cc/en/Reference/SD 9 | architectures=* 10 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/README.txt: -------------------------------------------------------------------------------- 1 | 2 | ** SD - a slightly more friendly wrapper for sdfatlib ** 3 | 4 | This library aims to expose a subset of SD card functionality in the 5 | form of a higher level "wrapper" object. 6 | 7 | License: GNU General Public License V3 8 | (Because sdfatlib is licensed with this.) 9 | 10 | (C) Copyright 2010 SparkFun Electronics 11 | 12 | Now better than ever with optimization, multiple file support, directory handling, etc - ladyada! 13 | 14 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/library.properties: -------------------------------------------------------------------------------- 1 | name=Encoder 2 | version=1.4.1 3 | author=Paul Stoffregen 4 | maintainer=Paul Stoffregen 5 | sentence=Counts quadrature pulses from rotary & linear position encoders. 6 | paragraph=Encoder counts pulses from quadrature encoded signals, which are commonly available from rotary knobs, motor or shaft sensors and other position sensors. 7 | category=Signal Input/Output 8 | url=http://www.pjrc.com/teensy/td_libs_Encoder.html 9 | architectures=* 10 | 11 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/LiquidCrystal_I2C/library.properties: -------------------------------------------------------------------------------- 1 | name=LiquidCrystal I2C 2 | version=1.1.2 3 | author=Frank de Brabander 4 | maintainer=Marco Schwartz 5 | sentence=A library for I2C LCD displays. 6 | paragraph= The library allows to control I2C displays with functions extremely similar to LiquidCrystal library. THIS LIBRARY MIGHT NOT BE COMPATIBLE WITH EXISTING SKETCHES. 7 | category=Display 8 | url=https://github.com/marcoschwartz/LiquidCrystal_I2C 9 | architectures=avr 10 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Encoder", 3 | "keywords": "encoder, signal, pulse", 4 | "description": "Encoder counts pulses from quadrature encoded signals, which are commonly available from rotary knobs, motor or shaft sensors and other position sensors", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/PaulStoffregen/Encoder.git" 9 | }, 10 | "frameworks": "arduino", 11 | "platforms": 12 | [ 13 | "atmelavr", 14 | "teensy" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /LCD_GRBL/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:megaatmega2560] 12 | platform = atmelavr 13 | board = megaatmega2560 14 | framework = arduino 15 | -------------------------------------------------------------------------------- /LCD_GRBL/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/LiquidCrystal_I2C/examples/HelloWorld/HelloWorld.pde: -------------------------------------------------------------------------------- 1 | //YWROBOT 2 | //Compatible with the Arduino IDE 1.0 3 | //Library version:1.1 4 | #include 5 | #include 6 | 7 | LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display 8 | 9 | void setup() 10 | { 11 | lcd.init(); // initialize the lcd 12 | lcd.init(); 13 | // Print a message to the LCD. 14 | lcd.backlight(); 15 | lcd.setCursor(3,0); 16 | lcd.print("Hello, world!"); 17 | lcd.setCursor(2,1); 18 | lcd.print("Ywrobot Arduino!"); 19 | lcd.setCursor(0,2); 20 | lcd.print("Arduino LCM IIC 2004"); 21 | lcd.setCursor(2,3); 22 | lcd.print("Power By Ec-yuan!"); 23 | } 24 | 25 | 26 | void loop() 27 | { 28 | } 29 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map SD 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | SD KEYWORD1 SD 10 | File KEYWORD1 SD 11 | SDFile KEYWORD1 SD 12 | 13 | ####################################### 14 | # Methods and Functions (KEYWORD2) 15 | ####################################### 16 | begin KEYWORD2 17 | exists KEYWORD2 18 | mkdir KEYWORD2 19 | remove KEYWORD2 20 | rmdir KEYWORD2 21 | open KEYWORD2 22 | close KEYWORD2 23 | seek KEYWORD2 24 | position KEYWORD2 25 | size KEYWORD2 26 | 27 | ####################################### 28 | # Constants (LITERAL1) 29 | ####################################### 30 | FILE_READ LITERAL1 31 | FILE_WRITE LITERAL1 32 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/examples/Basic/Basic.pde: -------------------------------------------------------------------------------- 1 | /* Encoder Library - Basic Example 2 | * http://www.pjrc.com/teensy/td_libs_Encoder.html 3 | * 4 | * This example code is in the public domain. 5 | */ 6 | 7 | #include 8 | 9 | // Change these two numbers to the pins connected to your encoder. 10 | // Best Performance: both pins have interrupt capability 11 | // Good Performance: only the first pin has interrupt capability 12 | // Low Performance: neither pin has interrupt capability 13 | Encoder myEnc(5, 6); 14 | // avoid using pins with LEDs attached 15 | 16 | void setup() { 17 | Serial.begin(9600); 18 | Serial.println("Basic Encoder Test:"); 19 | } 20 | 21 | long oldPosition = -999; 22 | 23 | void loop() { 24 | long newPosition = myEnc.read(); 25 | if (newPosition != oldPosition) { 26 | oldPosition = newPosition; 27 | Serial.println(newPosition); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/README.adoc: -------------------------------------------------------------------------------- 1 | = SD Library for Arduino = 2 | 3 | The SD library allows for reading from and writing to SD cards. 4 | 5 | For more information about this library please visit us at 6 | http://www.arduino.cc/en/Reference/SD 7 | 8 | == License == 9 | 10 | Copyright (C) 2009 by William Greiman 11 | Copyright (c) 2010 SparkFun Electronics 12 | 13 | This program is free software: you can redistribute it and/or modify 14 | it under the terms of the GNU General Public License as published by 15 | the Free Software Foundation, either version 3 of the License, or 16 | (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program. If not, see . 25 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/LiquidCrystal_I2C/examples/SerialDisplay/SerialDisplay.pde: -------------------------------------------------------------------------------- 1 | /* 2 | * Displays text sent over the serial port (e.g. from the Serial Monitor) on 3 | * an attached LCD. 4 | * YWROBOT 5 | *Compatible with the Arduino IDE 1.0 6 | *Library version:1.1 7 | */ 8 | #include 9 | #include 10 | 11 | LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display 12 | 13 | void setup() 14 | { 15 | lcd.init(); // initialize the lcd 16 | lcd.backlight(); 17 | Serial.begin(9600); 18 | } 19 | 20 | void loop() 21 | { 22 | // when characters arrive over the serial port... 23 | if (Serial.available()) { 24 | // wait a bit for the entire message to arrive 25 | delay(100); 26 | // clear the screen 27 | lcd.clear(); 28 | // read all the available characters 29 | while (Serial.available() > 0) { 30 | // display each character to the LCD 31 | lcd.write(Serial.read()); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2 | This is an offline controller for a CNC machine with GRBL V1.1. 3 | 4 | It executes the basic functions, such as:\ 5 | -Displaying the status of the machine \ 6 | -Move the axes \ 7 | -Auto Home ($H) \ 8 | -Unlock grbl ($X) \ 9 | -Make position 0 (G92 on all axes) \ 10 | -Read a MicroSD and send the commands to the machine \ 11 | -Modify in real time the speed of movement of the machine \ 12 | -Modify in real time the spindle RPM \ 13 | -Among other options that will be added 14 | 15 | Components: \ 16 | -Arduino Mega \ 17 | -Rotary encoder \ 18 | -SPI microSD card reader \ 19 | -Button for E-STOP \ 20 | -LCD screen with i2c module 21 | 22 | The box to be printed can be downloaded from the following link: \ 23 | https://www.thingiverse.com/thing:4354456 24 | 25 | The file to compile from Arduino IDE, is in the folder LCD_GRBL/src/Codigo.ino 26 | 27 | If you want to work from VSCode and PlatformIO, import the folder containing \ 28 | the platformio.ini file. This folder already has the necessary libraries for the \ 29 | operation of the project, so it will not be necessary to download them. 30 | 31 | If you want to collaborate with the project, you can do it through PayPal 32 | https://www.paypal.com/paypalme/cguerrero1205 33 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/LiquidCrystal_I2C/keywords.txt: -------------------------------------------------------------------------------- 1 | ########################################### 2 | # Syntax Coloring Map For LiquidCrystal_I2C 3 | ########################################### 4 | 5 | ########################################### 6 | # Datatypes (KEYWORD1) 7 | ########################################### 8 | 9 | LiquidCrystal_I2C KEYWORD1 10 | 11 | ########################################### 12 | # Methods and Functions (KEYWORD2) 13 | ########################################### 14 | init KEYWORD2 15 | begin KEYWORD2 16 | clear KEYWORD2 17 | home KEYWORD2 18 | noDisplay KEYWORD2 19 | display KEYWORD2 20 | noBlink KEYWORD2 21 | blink KEYWORD2 22 | noCursor KEYWORD2 23 | cursor KEYWORD2 24 | scrollDisplayLeft KEYWORD2 25 | scrollDisplayRight KEYWORD2 26 | leftToRight KEYWORD2 27 | rightToLeft KEYWORD2 28 | shiftIncrement KEYWORD2 29 | shiftDecrement KEYWORD2 30 | noBacklight KEYWORD2 31 | backlight KEYWORD2 32 | autoscroll KEYWORD2 33 | noAutoscroll KEYWORD2 34 | createChar KEYWORD2 35 | setCursor KEYWORD2 36 | print KEYWORD2 37 | blink_on KEYWORD2 38 | blink_off KEYWORD2 39 | cursor_on KEYWORD2 40 | cursor_off KEYWORD2 41 | setBacklight KEYWORD2 42 | load_custom_character KEYWORD2 43 | printstr KEYWORD2 44 | ########################################### 45 | # Constants (LITERAL1) 46 | ########################################### 47 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/examples/TwoKnobs/TwoKnobs.pde: -------------------------------------------------------------------------------- 1 | /* Encoder Library - TwoKnobs Example 2 | * http://www.pjrc.com/teensy/td_libs_Encoder.html 3 | * 4 | * This example code is in the public domain. 5 | */ 6 | 7 | #include 8 | 9 | // Change these pin numbers to the pins connected to your encoder. 10 | // Best Performance: both pins have interrupt capability 11 | // Good Performance: only the first pin has interrupt capability 12 | // Low Performance: neither pin has interrupt capability 13 | Encoder knobLeft(5, 6); 14 | Encoder knobRight(7, 8); 15 | // avoid using pins with LEDs attached 16 | 17 | void setup() { 18 | Serial.begin(9600); 19 | Serial.println("TwoKnobs Encoder Test:"); 20 | } 21 | 22 | long positionLeft = -999; 23 | long positionRight = -999; 24 | 25 | void loop() { 26 | long newLeft, newRight; 27 | newLeft = knobLeft.read(); 28 | newRight = knobRight.read(); 29 | if (newLeft != positionLeft || newRight != positionRight) { 30 | Serial.print("Left = "); 31 | Serial.print(newLeft); 32 | Serial.print(", Right = "); 33 | Serial.print(newRight); 34 | Serial.println(); 35 | positionLeft = newLeft; 36 | positionRight = newRight; 37 | } 38 | // if a character is sent from the serial monitor, 39 | // reset both back to zero. 40 | if (Serial.available()) { 41 | Serial.read(); 42 | Serial.println("Reset both knobs to zero"); 43 | knobLeft.write(0); 44 | knobRight.write(0); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /LCD_GRBL/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/examples/DumpFile/DumpFile.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SD card file dump 3 | 4 | This example shows how to read a file from the SD card using the 5 | SD library and send it over the serial port. 6 | 7 | The circuit: 8 | * SD card attached to SPI bus as follows: 9 | ** MOSI - pin 11 10 | ** MISO - pin 12 11 | ** CLK - pin 13 12 | ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN) 13 | 14 | created 22 December 2010 15 | by Limor Fried 16 | modified 9 Apr 2012 17 | by Tom Igoe 18 | 19 | This example code is in the public domain. 20 | 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | const int chipSelect = 4; 27 | 28 | void setup() { 29 | // Open serial communications and wait for port to open: 30 | Serial.begin(9600); 31 | while (!Serial) { 32 | ; // wait for serial port to connect. Needed for native USB port only 33 | } 34 | 35 | 36 | Serial.print("Initializing SD card..."); 37 | 38 | // see if the card is present and can be initialized: 39 | if (!SD.begin(chipSelect)) { 40 | Serial.println("Card failed, or not present"); 41 | // don't do anything more: 42 | return; 43 | } 44 | Serial.println("card initialized."); 45 | 46 | // open the file. note that only one file can be open at a time, 47 | // so you have to close this one before opening another. 48 | File dataFile = SD.open("datalog.txt"); 49 | 50 | // if the file is available, write to it: 51 | if (dataFile) { 52 | while (dataFile.available()) { 53 | Serial.write(dataFile.read()); 54 | } 55 | dataFile.close(); 56 | } 57 | // if the file isn't open, pop up an error: 58 | else { 59 | Serial.println("error opening datalog.txt"); 60 | } 61 | } 62 | 63 | void loop() { 64 | } 65 | 66 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/examples/NoInterrupts/NoInterrupts.pde: -------------------------------------------------------------------------------- 1 | /* Encoder Library - NoInterrupts Example 2 | * http://www.pjrc.com/teensy/td_libs_Encoder.html 3 | * 4 | * This example code is in the public domain. 5 | */ 6 | 7 | // If you define ENCODER_DO_NOT_USE_INTERRUPTS *before* including 8 | // Encoder, the library will never use interrupts. This is mainly 9 | // useful to reduce the size of the library when you are using it 10 | // with pins that do not support interrupts. Without interrupts, 11 | // your program must call the read() function rapidly, or risk 12 | // missing changes in position. 13 | #define ENCODER_DO_NOT_USE_INTERRUPTS 14 | #include 15 | 16 | // Beware of Serial.print() speed. Without interrupts, if you 17 | // transmit too much data with Serial.print() it can slow your 18 | // reading from Encoder. Arduino 1.0 has improved transmit code. 19 | // Using the fastest baud rate also helps. Teensy has USB packet 20 | // buffering. But all boards can experience problems if you print 21 | // too much and fill up buffers. 22 | 23 | // Change these two numbers to the pins connected to your encoder. 24 | // With ENCODER_DO_NOT_USE_INTERRUPTS, no interrupts are ever 25 | // used, even if the pin has interrupt capability 26 | Encoder myEnc(5, 6); 27 | // avoid using pins with LEDs attached 28 | 29 | void setup() { 30 | Serial.begin(9600); 31 | Serial.println("Basic NoInterrupts Test:"); 32 | } 33 | 34 | long position = -999; 35 | 36 | void loop() { 37 | long newPos = myEnc.read(); 38 | if (newPos != position) { 39 | position = newPos; 40 | Serial.println(position); 41 | } 42 | // With any substantial delay added, Encoder can only track 43 | // very slow motion. You may uncomment this line to see 44 | // how badly a delay affects your encoder. 45 | //delay(50); 46 | } 47 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/examples/listfiles/listfiles.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Listfiles 3 | 4 | This example shows how print out the files in a 5 | directory on a SD card 6 | 7 | The circuit: 8 | * SD card attached to SPI bus as follows: 9 | ** MOSI - pin 11 10 | ** MISO - pin 12 11 | ** CLK - pin 13 12 | ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN) 13 | 14 | created Nov 2010 15 | by David A. Mellis 16 | modified 9 Apr 2012 17 | by Tom Igoe 18 | modified 2 Feb 2014 19 | by Scott Fitzgerald 20 | 21 | This example code is in the public domain. 22 | 23 | */ 24 | #include 25 | #include 26 | 27 | File root; 28 | 29 | void setup() { 30 | // Open serial communications and wait for port to open: 31 | Serial.begin(9600); 32 | while (!Serial) { 33 | ; // wait for serial port to connect. Needed for native USB port only 34 | } 35 | 36 | Serial.print("Initializing SD card..."); 37 | 38 | if (!SD.begin(4)) { 39 | Serial.println("initialization failed!"); 40 | return; 41 | } 42 | Serial.println("initialization done."); 43 | 44 | root = SD.open("/"); 45 | 46 | printDirectory(root, 0); 47 | 48 | Serial.println("done!"); 49 | } 50 | 51 | void loop() { 52 | // nothing happens after setup finishes. 53 | } 54 | 55 | void printDirectory(File dir, int numTabs) { 56 | while (true) { 57 | 58 | File entry = dir.openNextFile(); 59 | if (! entry) { 60 | // no more files 61 | break; 62 | } 63 | for (uint8_t i = 0; i < numTabs; i++) { 64 | Serial.print('\t'); 65 | } 66 | Serial.print(entry.name()); 67 | if (entry.isDirectory()) { 68 | Serial.println("/"); 69 | printDirectory(entry, numTabs + 1); 70 | } else { 71 | // files have sizes, directories do not 72 | Serial.print("\t\t"); 73 | Serial.println(entry.size(), DEC); 74 | } 75 | entry.close(); 76 | } 77 | } 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/examples/Files/Files.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SD card basic file example 3 | 4 | This example shows how to create and destroy an SD card file 5 | The circuit: 6 | * SD card attached to SPI bus as follows: 7 | ** MOSI - pin 11 8 | ** MISO - pin 12 9 | ** CLK - pin 13 10 | ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN) 11 | 12 | created Nov 2010 13 | by David A. Mellis 14 | modified 9 Apr 2012 15 | by Tom Igoe 16 | 17 | This example code is in the public domain. 18 | 19 | */ 20 | #include 21 | #include 22 | 23 | File myFile; 24 | 25 | void setup() { 26 | // Open serial communications and wait for port to open: 27 | Serial.begin(9600); 28 | while (!Serial) { 29 | ; // wait for serial port to connect. Needed for native USB port only 30 | } 31 | 32 | 33 | Serial.print("Initializing SD card..."); 34 | 35 | if (!SD.begin(4)) { 36 | Serial.println("initialization failed!"); 37 | return; 38 | } 39 | Serial.println("initialization done."); 40 | 41 | if (SD.exists("example.txt")) { 42 | Serial.println("example.txt exists."); 43 | } else { 44 | Serial.println("example.txt doesn't exist."); 45 | } 46 | 47 | // open a new file and immediately close it: 48 | Serial.println("Creating example.txt..."); 49 | myFile = SD.open("example.txt", FILE_WRITE); 50 | myFile.close(); 51 | 52 | // Check to see if the file exists: 53 | if (SD.exists("example.txt")) { 54 | Serial.println("example.txt exists."); 55 | } else { 56 | Serial.println("example.txt doesn't exist."); 57 | } 58 | 59 | // delete the file: 60 | Serial.println("Removing example.txt..."); 61 | SD.remove("example.txt"); 62 | 63 | if (SD.exists("example.txt")) { 64 | Serial.println("example.txt exists."); 65 | } else { 66 | Serial.println("example.txt doesn't exist."); 67 | } 68 | } 69 | 70 | void loop() { 71 | // nothing happens after setup finishes. 72 | } 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/LiquidCrystal_I2C/examples/CustomChars/CustomChars.pde: -------------------------------------------------------------------------------- 1 | //YWROBOT 2 | //Compatible with the Arduino IDE 1.0 3 | //Library version:1.1 4 | #include 5 | #include 6 | 7 | #if defined(ARDUINO) && ARDUINO >= 100 8 | #define printByte(args) write(args); 9 | #else 10 | #define printByte(args) print(args,BYTE); 11 | #endif 12 | 13 | uint8_t bell[8] = {0x4,0xe,0xe,0xe,0x1f,0x0,0x4}; 14 | uint8_t note[8] = {0x2,0x3,0x2,0xe,0x1e,0xc,0x0}; 15 | uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0}; 16 | uint8_t heart[8] = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0}; 17 | uint8_t duck[8] = {0x0,0xc,0x1d,0xf,0xf,0x6,0x0}; 18 | uint8_t check[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0}; 19 | uint8_t cross[8] = {0x0,0x1b,0xe,0x4,0xe,0x1b,0x0}; 20 | uint8_t retarrow[8] = { 0x1,0x1,0x5,0x9,0x1f,0x8,0x4}; 21 | 22 | LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display 23 | 24 | void setup() 25 | { 26 | lcd.init(); // initialize the lcd 27 | lcd.backlight(); 28 | 29 | lcd.createChar(0, bell); 30 | lcd.createChar(1, note); 31 | lcd.createChar(2, clock); 32 | lcd.createChar(3, heart); 33 | lcd.createChar(4, duck); 34 | lcd.createChar(5, check); 35 | lcd.createChar(6, cross); 36 | lcd.createChar(7, retarrow); 37 | lcd.home(); 38 | 39 | lcd.print("Hello world..."); 40 | lcd.setCursor(0, 1); 41 | lcd.print(" i "); 42 | lcd.printByte(3); 43 | lcd.print(" arduinos!"); 44 | delay(5000); 45 | displayKeyCodes(); 46 | 47 | } 48 | 49 | // display all keycodes 50 | void displayKeyCodes(void) { 51 | uint8_t i = 0; 52 | while (1) { 53 | lcd.clear(); 54 | lcd.print("Codes 0x"); lcd.print(i, HEX); 55 | lcd.print("-0x"); lcd.print(i+16, HEX); 56 | lcd.setCursor(0, 1); 57 | for (int j=0; j<16; j++) { 58 | lcd.printByte(i+j); 59 | } 60 | i+=16; 61 | 62 | delay(4000); 63 | } 64 | } 65 | 66 | void loop() 67 | { 68 | 69 | } 70 | 71 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/examples/ReadWrite/ReadWrite.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SD card read/write 3 | 4 | This example shows how to read and write data to and from an SD card file 5 | The circuit: 6 | * SD card attached to SPI bus as follows: 7 | ** MOSI - pin 11 8 | ** MISO - pin 12 9 | ** CLK - pin 13 10 | ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN) 11 | 12 | created Nov 2010 13 | by David A. Mellis 14 | modified 9 Apr 2012 15 | by Tom Igoe 16 | 17 | This example code is in the public domain. 18 | 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | File myFile; 25 | 26 | void setup() { 27 | // Open serial communications and wait for port to open: 28 | Serial.begin(9600); 29 | while (!Serial) { 30 | ; // wait for serial port to connect. Needed for native USB port only 31 | } 32 | 33 | 34 | Serial.print("Initializing SD card..."); 35 | 36 | if (!SD.begin(4)) { 37 | Serial.println("initialization failed!"); 38 | return; 39 | } 40 | Serial.println("initialization done."); 41 | 42 | // open the file. note that only one file can be open at a time, 43 | // so you have to close this one before opening another. 44 | myFile = SD.open("test.txt", FILE_WRITE); 45 | 46 | // if the file opened okay, write to it: 47 | if (myFile) { 48 | Serial.print("Writing to test.txt..."); 49 | myFile.println("testing 1, 2, 3."); 50 | // close the file: 51 | myFile.close(); 52 | Serial.println("done."); 53 | } else { 54 | // if the file didn't open, print an error: 55 | Serial.println("error opening test.txt"); 56 | } 57 | 58 | // re-open the file for reading: 59 | myFile = SD.open("test.txt"); 60 | if (myFile) { 61 | Serial.println("test.txt:"); 62 | 63 | // read from the file until there's nothing else in it: 64 | while (myFile.available()) { 65 | Serial.write(myFile.read()); 66 | } 67 | // close the file: 68 | myFile.close(); 69 | } else { 70 | // if the file didn't open, print an error: 71 | Serial.println("error opening test.txt"); 72 | } 73 | } 74 | 75 | void loop() { 76 | // nothing happens after setup 77 | } 78 | 79 | 80 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/examples/Datalogger/Datalogger.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SD card datalogger 3 | 4 | This example shows how to log data from three analog sensors 5 | to an SD card using the SD library. 6 | 7 | The circuit: 8 | * analog sensors on analog ins 0, 1, and 2 9 | * SD card attached to SPI bus as follows: 10 | ** MOSI - pin 11 11 | ** MISO - pin 12 12 | ** CLK - pin 13 13 | ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN) 14 | 15 | created 24 Nov 2010 16 | modified 9 Apr 2012 17 | by Tom Igoe 18 | 19 | This example code is in the public domain. 20 | 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | const int chipSelect = 4; 27 | 28 | void setup() { 29 | // Open serial communications and wait for port to open: 30 | Serial.begin(9600); 31 | while (!Serial) { 32 | ; // wait for serial port to connect. Needed for native USB port only 33 | } 34 | 35 | 36 | Serial.print("Initializing SD card..."); 37 | 38 | // see if the card is present and can be initialized: 39 | if (!SD.begin(chipSelect)) { 40 | Serial.println("Card failed, or not present"); 41 | // don't do anything more: 42 | return; 43 | } 44 | Serial.println("card initialized."); 45 | } 46 | 47 | void loop() { 48 | // make a string for assembling the data to log: 49 | String dataString = ""; 50 | 51 | // read three sensors and append to the string: 52 | for (int analogPin = 0; analogPin < 3; analogPin++) { 53 | int sensor = analogRead(analogPin); 54 | dataString += String(sensor); 55 | if (analogPin < 2) { 56 | dataString += ","; 57 | } 58 | } 59 | 60 | // open the file. note that only one file can be open at a time, 61 | // so you have to close this one before opening another. 62 | File dataFile = SD.open("datalog.txt", FILE_WRITE); 63 | 64 | // if the file is available, write to it: 65 | if (dataFile) { 66 | dataFile.println(dataString); 67 | dataFile.close(); 68 | // print to the serial port too: 69 | Serial.println(dataString); 70 | } 71 | // if the file isn't open, pop up an error: 72 | else { 73 | Serial.println("error opening datalog.txt"); 74 | } 75 | } 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/utility/interrupt_config.h: -------------------------------------------------------------------------------- 1 | #if defined(__AVR__) 2 | 3 | #include 4 | #include 5 | 6 | #define attachInterrupt(num, func, mode) enableInterrupt(num) 7 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 8 | #define SCRAMBLE_INT_ORDER(num) ((num < 4) ? num + 2 : ((num < 6) ? num - 4 : num)) 9 | #define DESCRAMBLE_INT_ORDER(num) ((num < 2) ? num + 4 : ((num < 6) ? num - 2 : num)) 10 | #else 11 | #define SCRAMBLE_INT_ORDER(num) (num) 12 | #define DESCRAMBLE_INT_ORDER(num) (num) 13 | #endif 14 | 15 | static void enableInterrupt(uint8_t num) 16 | { 17 | switch (DESCRAMBLE_INT_ORDER(num)) { 18 | #if defined(EICRA) && defined(EIMSK) 19 | case 0: 20 | EICRA = (EICRA & 0xFC) | 0x01; 21 | EIMSK |= 0x01; 22 | return; 23 | case 1: 24 | EICRA = (EICRA & 0xF3) | 0x04; 25 | EIMSK |= 0x02; 26 | return; 27 | case 2: 28 | EICRA = (EICRA & 0xCF) | 0x10; 29 | EIMSK |= 0x04; 30 | return; 31 | case 3: 32 | EICRA = (EICRA & 0x3F) | 0x40; 33 | EIMSK |= 0x08; 34 | return; 35 | #elif defined(MCUCR) && defined(GICR) 36 | case 0: 37 | MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); 38 | GICR |= (1 << INT0); 39 | return; 40 | case 1: 41 | MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); 42 | GICR |= (1 << INT1); 43 | return; 44 | #elif defined(MCUCR) && defined(GIMSK) 45 | case 0: 46 | MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); 47 | GIMSK |= (1 << INT0); 48 | return; 49 | case 1: 50 | MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); 51 | GIMSK |= (1 << INT1); 52 | return; 53 | #endif 54 | #if defined(EICRB) && defined(EIMSK) 55 | case 4: 56 | EICRB = (EICRB & 0xFC) | 0x01; 57 | EIMSK |= 0x10; 58 | return; 59 | case 5: 60 | EICRB = (EICRB & 0xF3) | 0x04; 61 | EIMSK |= 0x20; 62 | return; 63 | case 6: 64 | EICRB = (EICRB & 0xCF) | 0x10; 65 | EIMSK |= 0x40; 66 | return; 67 | case 7: 68 | EICRB = (EICRB & 0x3F) | 0x40; 69 | EIMSK |= 0x80; 70 | return; 71 | #endif 72 | } 73 | } 74 | 75 | #elif defined(__PIC32MX__) 76 | 77 | #ifdef ENCODER_OPTIMIZE_INTERRUPTS 78 | #undef ENCODER_OPTIMIZE_INTERRUPTS 79 | #endif 80 | 81 | #else 82 | 83 | #ifdef ENCODER_OPTIMIZE_INTERRUPTS 84 | #undef ENCODER_OPTIMIZE_INTERRUPTS 85 | #endif 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/utility/SdFatUtil.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2008 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef SdFatUtil_h 21 | #define SdFatUtil_h 22 | /** 23 | * \file 24 | * Useful utility functions. 25 | */ 26 | #include 27 | #ifdef __AVR__ 28 | #include 29 | /** Store and print a string in flash memory.*/ 30 | #define PgmPrint(x) SerialPrint_P(PSTR(x)) 31 | /** Store and print a string in flash memory followed by a CR/LF.*/ 32 | #define PgmPrintln(x) SerialPrintln_P(PSTR(x)) 33 | /** Defined so doxygen works for function definitions. */ 34 | #endif 35 | #define NOINLINE __attribute__((noinline,unused)) 36 | #define UNUSEDOK __attribute__((unused)) 37 | //------------------------------------------------------------------------------ 38 | /** Return the number of bytes currently free in RAM. */ 39 | static UNUSEDOK int FreeRam(void) { 40 | extern int __bss_end; 41 | extern int* __brkval; 42 | int free_memory; 43 | if (reinterpret_cast(__brkval) == 0) { 44 | // if no heap use from end of bss section 45 | free_memory = reinterpret_cast(&free_memory) 46 | - reinterpret_cast(&__bss_end); 47 | } else { 48 | // use from top of stack to heap 49 | free_memory = reinterpret_cast(&free_memory) 50 | - reinterpret_cast(__brkval); 51 | } 52 | return free_memory; 53 | } 54 | #ifdef __AVR__ 55 | //------------------------------------------------------------------------------ 56 | /** 57 | * %Print a string in flash memory to the serial port. 58 | * 59 | * \param[in] str Pointer to string stored in flash memory. 60 | */ 61 | static NOINLINE void SerialPrint_P(PGM_P str) { 62 | for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.write(c); 63 | } 64 | //------------------------------------------------------------------------------ 65 | /** 66 | * %Print a string in flash memory followed by a CR/LF. 67 | * 68 | * \param[in] str Pointer to string stored in flash memory. 69 | */ 70 | static NOINLINE void SerialPrintln_P(PGM_P str) { 71 | SerialPrint_P(str); 72 | Serial.println(); 73 | } 74 | #endif // __AVR__ 75 | #endif // #define SdFatUtil_h 76 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/utility/direct_pin_read.h: -------------------------------------------------------------------------------- 1 | #ifndef direct_pin_read_h_ 2 | #define direct_pin_read_h_ 3 | 4 | #if defined(__AVR__) || (defined(__arm__) && defined(CORE_TEENSY)) 5 | 6 | #define IO_REG_TYPE uint8_t 7 | #define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 8 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 9 | #define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 10 | 11 | #elif defined(__SAM3X8E__) // || defined(ESP8266) 12 | 13 | #define IO_REG_TYPE uint32_t 14 | #define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 15 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 16 | #define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 17 | 18 | #elif defined(__PIC32MX__) 19 | 20 | #define IO_REG_TYPE uint32_t 21 | #define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin))) 22 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 23 | #define DIRECT_PIN_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) 24 | 25 | /* ESP8266 v2.0.0 Arduino workaround for bug https://github.com/esp8266/Arduino/issues/1110 */ 26 | #elif defined(ESP8266) 27 | 28 | #define IO_REG_TYPE uint32_t 29 | #define PIN_TO_BASEREG(pin) ((volatile uint32_t *)(0x60000000+(0x318))) 30 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 31 | #define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 32 | 33 | #elif defined(__SAMD21G18A__) 34 | 35 | #define IO_REG_TYPE uint32_t 36 | #define PIN_TO_BASEREG(pin) portModeRegister(digitalPinToPort(pin)) 37 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 38 | #define DIRECT_PIN_READ(base, mask) (((*((base)+8)) & (mask)) ? 1 : 0) 39 | 40 | #elif defined(RBL_NRF51822) 41 | 42 | #define IO_REG_TYPE uint32_t 43 | #define PIN_TO_BASEREG(pin) (0) 44 | #define PIN_TO_BITMASK(pin) (pin) 45 | #define DIRECT_PIN_READ(base, pin) nrf_gpio_pin_read(pin) 46 | 47 | #elif defined(__arc__) /* Arduino101/Genuino101 specifics */ 48 | 49 | #include "scss_registers.h" 50 | #include "portable.h" 51 | #include "avr/pgmspace.h" 52 | #define GPIO_ID(pin) (g_APinDescription[pin].ulGPIOId) 53 | #define GPIO_TYPE(pin) (g_APinDescription[pin].ulGPIOType) 54 | #define GPIO_BASE(pin) (g_APinDescription[pin].ulGPIOBase) 55 | #define EXT_PORT_OFFSET_SS 0x0A 56 | #define EXT_PORT_OFFSET_SOC 0x50 57 | #define PIN_TO_BASEREG(pin) ((volatile uint32_t *)g_APinDescription[pin].ulGPIOBase) 58 | #define PIN_TO_BITMASK(pin) pin 59 | #define IO_REG_TYPE uint32_t 60 | static inline __attribute__((always_inline)) 61 | IO_REG_TYPE directRead(volatile IO_REG_TYPE *base, IO_REG_TYPE pin) 62 | { 63 | IO_REG_TYPE ret; 64 | if (SS_GPIO == GPIO_TYPE(pin)) { 65 | ret = READ_ARC_REG(((IO_REG_TYPE)base + EXT_PORT_OFFSET_SS)); 66 | } else { 67 | ret = MMIO_REG_VAL_FROM_BASE((IO_REG_TYPE)base, EXT_PORT_OFFSET_SOC); 68 | } 69 | return ((ret >> GPIO_ID(pin)) & 0x01); 70 | } 71 | #define DIRECT_PIN_READ(base, pin) directRead(base, pin) 72 | 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/File.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SD - a slightly more friendly wrapper for sdfatlib 4 | 5 | This library aims to expose a subset of SD card functionality 6 | in the form of a higher level "wrapper" object. 7 | 8 | License: GNU General Public License V3 9 | (Because sdfatlib is licensed with this.) 10 | 11 | (C) Copyright 2010 SparkFun Electronics 12 | 13 | */ 14 | 15 | #include 16 | 17 | /* for debugging file open/close leaks 18 | uint8_t nfilecount=0; 19 | */ 20 | 21 | File::File(SdFile f, const char *n) { 22 | // oh man you are kidding me, new() doesnt exist? Ok we do it by hand! 23 | _file = (SdFile *)malloc(sizeof(SdFile)); 24 | if (_file) { 25 | memcpy(_file, &f, sizeof(SdFile)); 26 | 27 | strncpy(_name, n, 12); 28 | _name[12] = 0; 29 | 30 | /* for debugging file open/close leaks 31 | nfilecount++; 32 | Serial.print("Created \""); 33 | Serial.print(n); 34 | Serial.print("\": "); 35 | Serial.println(nfilecount, DEC); 36 | */ 37 | } 38 | } 39 | 40 | File::File(void) { 41 | _file = 0; 42 | _name[0] = 0; 43 | //Serial.print("Created empty file object"); 44 | } 45 | 46 | // returns a pointer to the file name 47 | char *File::name(void) { 48 | return _name; 49 | } 50 | 51 | // a directory is a special type of file 52 | boolean File::isDirectory(void) { 53 | return (_file && _file->isDir()); 54 | } 55 | 56 | 57 | size_t File::write(uint8_t val) { 58 | return write(&val, 1); 59 | } 60 | 61 | size_t File::write(const uint8_t *buf, size_t size) { 62 | size_t t; 63 | if (!_file) { 64 | setWriteError(); 65 | return 0; 66 | } 67 | _file->clearWriteError(); 68 | t = _file->write(buf, size); 69 | if (_file->getWriteError()) { 70 | setWriteError(); 71 | return 0; 72 | } 73 | return t; 74 | } 75 | 76 | int File::peek() { 77 | if (! _file) 78 | return 0; 79 | 80 | int c = _file->read(); 81 | if (c != -1) _file->seekCur(-1); 82 | return c; 83 | } 84 | 85 | int File::read() { 86 | if (_file) 87 | return _file->read(); 88 | return -1; 89 | } 90 | 91 | // buffered read for more efficient, high speed reading 92 | int File::read(void *buf, uint16_t nbyte) { 93 | if (_file) 94 | return _file->read(buf, nbyte); 95 | return 0; 96 | } 97 | 98 | int File::available() { 99 | if (! _file) return 0; 100 | 101 | uint32_t n = size() - position(); 102 | 103 | return n > 0X7FFF ? 0X7FFF : n; 104 | } 105 | 106 | void File::flush() { 107 | if (_file) 108 | _file->sync(); 109 | } 110 | 111 | boolean File::seek(uint32_t pos) { 112 | if (! _file) return false; 113 | 114 | return _file->seekSet(pos); 115 | } 116 | 117 | uint32_t File::position() { 118 | if (! _file) return -1; 119 | return _file->curPosition(); 120 | } 121 | 122 | uint32_t File::size() { 123 | if (! _file) return 0; 124 | return _file->fileSize(); 125 | } 126 | 127 | void File::close() { 128 | if (_file) { 129 | _file->close(); 130 | free(_file); 131 | _file = 0; 132 | 133 | /* for debugging file open/close leaks 134 | nfilecount--; 135 | Serial.print("Deleted "); 136 | Serial.println(nfilecount, DEC); 137 | */ 138 | } 139 | } 140 | 141 | File::operator bool() { 142 | if (_file) 143 | return _file->isOpen(); 144 | return false; 145 | } 146 | 147 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/examples/CardInfo/CardInfo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SD card test 3 | 4 | This example shows how use the utility libraries on which the' 5 | SD library is based in order to get info about your SD card. 6 | Very useful for testing a card when you're not sure whether its working or not. 7 | 8 | The circuit: 9 | * SD card attached to SPI bus as follows: 10 | ** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila 11 | ** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila 12 | ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila 13 | ** CS - depends on your SD card shield or module. 14 | Pin 4 used here for consistency with other Arduino examples 15 | 16 | 17 | created 28 Mar 2011 18 | by Limor Fried 19 | modified 9 Apr 2012 20 | by Tom Igoe 21 | */ 22 | // include the SD library: 23 | #include 24 | #include 25 | 26 | // set up variables using the SD utility library functions: 27 | Sd2Card card; 28 | SdVolume volume; 29 | SdFile root; 30 | 31 | // change this to match your SD shield or module; 32 | // Arduino Ethernet shield: pin 4 33 | // Adafruit SD shields and modules: pin 10 34 | // Sparkfun SD shield: pin 8 35 | // MKRZero SD: SDCARD_SS_PIN 36 | const int chipSelect = 4; 37 | 38 | void setup() { 39 | // Open serial communications and wait for port to open: 40 | Serial.begin(9600); 41 | while (!Serial) { 42 | ; // wait for serial port to connect. Needed for native USB port only 43 | } 44 | 45 | 46 | Serial.print("\nInitializing SD card..."); 47 | 48 | // we'll use the initialization code from the utility libraries 49 | // since we're just testing if the card is working! 50 | if (!card.init(SPI_HALF_SPEED, chipSelect)) { 51 | Serial.println("initialization failed. Things to check:"); 52 | Serial.println("* is a card inserted?"); 53 | Serial.println("* is your wiring correct?"); 54 | Serial.println("* did you change the chipSelect pin to match your shield or module?"); 55 | return; 56 | } else { 57 | Serial.println("Wiring is correct and a card is present."); 58 | } 59 | 60 | // print the type of card 61 | Serial.print("\nCard type: "); 62 | switch (card.type()) { 63 | case SD_CARD_TYPE_SD1: 64 | Serial.println("SD1"); 65 | break; 66 | case SD_CARD_TYPE_SD2: 67 | Serial.println("SD2"); 68 | break; 69 | case SD_CARD_TYPE_SDHC: 70 | Serial.println("SDHC"); 71 | break; 72 | default: 73 | Serial.println("Unknown"); 74 | } 75 | 76 | // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32 77 | if (!volume.init(card)) { 78 | Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card"); 79 | return; 80 | } 81 | 82 | 83 | // print the type and size of the first FAT-type volume 84 | uint32_t volumesize; 85 | Serial.print("\nVolume type is FAT"); 86 | Serial.println(volume.fatType(), DEC); 87 | Serial.println(); 88 | 89 | volumesize = volume.blocksPerCluster(); // clusters are collections of blocks 90 | volumesize *= volume.clusterCount(); // we'll have a lot of clusters 91 | volumesize *= 512; // SD card blocks are always 512 bytes 92 | Serial.print("Volume size (bytes): "); 93 | Serial.println(volumesize); 94 | Serial.print("Volume size (Kbytes): "); 95 | volumesize /= 1024; 96 | Serial.println(volumesize); 97 | Serial.print("Volume size (Mbytes): "); 98 | volumesize /= 1024; 99 | Serial.println(volumesize); 100 | 101 | 102 | Serial.println("\nFiles found on the card (name, date and size in bytes): "); 103 | root.openRoot(volume); 104 | 105 | // list all files in the card with date and size 106 | root.ls(LS_R | LS_DATE | LS_SIZE); 107 | } 108 | 109 | 110 | void loop(void) { 111 | 112 | } 113 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/LiquidCrystal_I2C/LiquidCrystal_I2C.h: -------------------------------------------------------------------------------- 1 | //YWROBOT 2 | #ifndef LiquidCrystal_I2C_h 3 | #define LiquidCrystal_I2C_h 4 | 5 | #include 6 | #include "Print.h" 7 | #include 8 | 9 | // commands 10 | #define LCD_CLEARDISPLAY 0x01 11 | #define LCD_RETURNHOME 0x02 12 | #define LCD_ENTRYMODESET 0x04 13 | #define LCD_DISPLAYCONTROL 0x08 14 | #define LCD_CURSORSHIFT 0x10 15 | #define LCD_FUNCTIONSET 0x20 16 | #define LCD_SETCGRAMADDR 0x40 17 | #define LCD_SETDDRAMADDR 0x80 18 | 19 | // flags for display entry mode 20 | #define LCD_ENTRYRIGHT 0x00 21 | #define LCD_ENTRYLEFT 0x02 22 | #define LCD_ENTRYSHIFTINCREMENT 0x01 23 | #define LCD_ENTRYSHIFTDECREMENT 0x00 24 | 25 | // flags for display on/off control 26 | #define LCD_DISPLAYON 0x04 27 | #define LCD_DISPLAYOFF 0x00 28 | #define LCD_CURSORON 0x02 29 | #define LCD_CURSOROFF 0x00 30 | #define LCD_BLINKON 0x01 31 | #define LCD_BLINKOFF 0x00 32 | 33 | // flags for display/cursor shift 34 | #define LCD_DISPLAYMOVE 0x08 35 | #define LCD_CURSORMOVE 0x00 36 | #define LCD_MOVERIGHT 0x04 37 | #define LCD_MOVELEFT 0x00 38 | 39 | // flags for function set 40 | #define LCD_8BITMODE 0x10 41 | #define LCD_4BITMODE 0x00 42 | #define LCD_2LINE 0x08 43 | #define LCD_1LINE 0x00 44 | #define LCD_5x10DOTS 0x04 45 | #define LCD_5x8DOTS 0x00 46 | 47 | // flags for backlight control 48 | #define LCD_BACKLIGHT 0x08 49 | #define LCD_NOBACKLIGHT 0x00 50 | 51 | #define En B00000100 // Enable bit 52 | #define Rw B00000010 // Read/Write bit 53 | #define Rs B00000001 // Register select bit 54 | 55 | class LiquidCrystal_I2C : public Print { 56 | public: 57 | LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows); 58 | void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS ); 59 | void clear(); 60 | void home(); 61 | void noDisplay(); 62 | void display(); 63 | void noBlink(); 64 | void blink(); 65 | void noCursor(); 66 | void cursor(); 67 | void scrollDisplayLeft(); 68 | void scrollDisplayRight(); 69 | void printLeft(); 70 | void printRight(); 71 | void leftToRight(); 72 | void rightToLeft(); 73 | void shiftIncrement(); 74 | void shiftDecrement(); 75 | void noBacklight(); 76 | void backlight(); 77 | void autoscroll(); 78 | void noAutoscroll(); 79 | void createChar(uint8_t, uint8_t[]); 80 | void setCursor(uint8_t, uint8_t); 81 | #if defined(ARDUINO) && ARDUINO >= 100 82 | virtual size_t write(uint8_t); 83 | #else 84 | virtual void write(uint8_t); 85 | #endif 86 | void command(uint8_t); 87 | void init(); 88 | 89 | ////compatibility API function aliases 90 | void blink_on(); // alias for blink() 91 | void blink_off(); // alias for noBlink() 92 | void cursor_on(); // alias for cursor() 93 | void cursor_off(); // alias for noCursor() 94 | void setBacklight(uint8_t new_val); // alias for backlight() and nobacklight() 95 | void load_custom_character(uint8_t char_num, uint8_t *rows); // alias for createChar() 96 | void printstr(const char[]); 97 | 98 | ////Unsupported API functions (not implemented in this library) 99 | uint8_t status(); 100 | void setContrast(uint8_t new_val); 101 | uint8_t keypad(); 102 | void setDelay(int,int); 103 | void on(); 104 | void off(); 105 | uint8_t init_bargraph(uint8_t graphtype); 106 | void draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); 107 | void draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); 108 | 109 | 110 | private: 111 | void init_priv(); 112 | void send(uint8_t, uint8_t); 113 | void write4bits(uint8_t); 114 | void expanderWrite(uint8_t); 115 | void pulseEnable(uint8_t); 116 | uint8_t _Addr; 117 | uint8_t _displayfunction; 118 | uint8_t _displaycontrol; 119 | uint8_t _displaymode; 120 | uint8_t _numlines; 121 | uint8_t _cols; 122 | uint8_t _rows; 123 | uint8_t _backlightval; 124 | }; 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/SD.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SD - a slightly more friendly wrapper for sdfatlib 4 | 5 | This library aims to expose a subset of SD card functionality 6 | in the form of a higher level "wrapper" object. 7 | 8 | License: GNU General Public License V3 9 | (Because sdfatlib is licensed with this.) 10 | 11 | (C) Copyright 2010 SparkFun Electronics 12 | 13 | */ 14 | 15 | #ifndef __SD_H__ 16 | #define __SD_H__ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | #define FILE_READ O_READ 24 | #define FILE_WRITE (O_READ | O_WRITE | O_CREAT) 25 | 26 | namespace SDLib { 27 | 28 | class File : public Stream { 29 | private: 30 | char _name[13]; // our name 31 | SdFile *_file; // underlying file pointer 32 | 33 | public: 34 | File(SdFile f, const char *name); // wraps an underlying SdFile 35 | File(void); // 'empty' constructor 36 | virtual size_t write(uint8_t); 37 | virtual size_t write(const uint8_t *buf, size_t size); 38 | virtual int read(); 39 | virtual int peek(); 40 | virtual int available(); 41 | virtual void flush(); 42 | int read(void *buf, uint16_t nbyte); 43 | boolean seek(uint32_t pos); 44 | uint32_t position(); 45 | uint32_t size(); 46 | void close(); 47 | operator bool(); 48 | char * name(); 49 | 50 | boolean isDirectory(void); 51 | File openNextFile(uint8_t mode = O_RDONLY); 52 | void rewindDirectory(void); 53 | 54 | using Print::write; 55 | }; 56 | 57 | class SDClass { 58 | 59 | private: 60 | // These are required for initialisation and use of sdfatlib 61 | Sd2Card card; 62 | SdVolume volume; 63 | SdFile root; 64 | 65 | // my quick&dirty iterator, should be replaced 66 | SdFile getParentDir(const char *filepath, int *indx); 67 | public: 68 | // This needs to be called to set up the connection to the SD card 69 | // before other methods are used. 70 | boolean begin(uint8_t csPin = SD_CHIP_SELECT_PIN); 71 | boolean begin(uint32_t clock, uint8_t csPin); 72 | 73 | // Open the specified file/directory with the supplied mode (e.g. read or 74 | // write, etc). Returns a File object for interacting with the file. 75 | // Note that currently only one file can be open at a time. 76 | File open(const char *filename, uint8_t mode = FILE_READ); 77 | File open(const String &filename, uint8_t mode = FILE_READ) { return open( filename.c_str(), mode ); } 78 | 79 | // Methods to determine if the requested file path exists. 80 | boolean exists(const char *filepath); 81 | boolean exists(const String &filepath) { return exists(filepath.c_str()); } 82 | 83 | // Create the requested directory heirarchy--if intermediate directories 84 | // do not exist they will be created. 85 | boolean mkdir(const char *filepath); 86 | boolean mkdir(const String &filepath) { return mkdir(filepath.c_str()); } 87 | 88 | // Delete the file. 89 | boolean remove(const char *filepath); 90 | boolean remove(const String &filepath) { return remove(filepath.c_str()); } 91 | 92 | boolean rmdir(const char *filepath); 93 | boolean rmdir(const String &filepath) { return rmdir(filepath.c_str()); } 94 | 95 | private: 96 | 97 | // This is used to determine the mode used to open a file 98 | // it's here because it's the easiest place to pass the 99 | // information through the directory walking function. But 100 | // it's probably not the best place for it. 101 | // It shouldn't be set directly--it is set via the parameters to `open`. 102 | int fileOpenMode; 103 | 104 | friend class File; 105 | friend boolean callback_openPath(SdFile&, const char *, boolean, void *); 106 | }; 107 | 108 | extern SDClass SD; 109 | 110 | }; 111 | 112 | // We enclose File and SD classes in namespace SDLib to avoid conflicts 113 | // with others legacy libraries that redefines File class. 114 | 115 | // This ensure compatibility with sketches that uses only SD library 116 | using namespace SDLib; 117 | 118 | // This allows sketches to use SDLib::File with other libraries (in the 119 | // sketch you must use SDFile instead of File to disambiguate) 120 | typedef SDLib::File SDFile; 121 | typedef SDLib::SDClass SDFileSystemClass; 122 | #define SDFileSystem SDLib::SD 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/examples/SpeedTest/SpeedTest.pde: -------------------------------------------------------------------------------- 1 | /* Encoder Library - SpeedTest - for measuring maximum Encoder speed 2 | * http://www.pjrc.com/teensy/td_libs_Encoder.html 3 | * 4 | * This example code is in the public domain. 5 | */ 6 | 7 | 8 | // This SpeedTest example provides a simple way to verify how much 9 | // CPU time Encoder is consuming. Connect a DC voltmeter to the 10 | // output pin and measure the voltage while the encoder is stopped 11 | // or running at a very slow speed. Even though the pin is rapidly 12 | // pulsing, a DC voltmeter will show the average voltage. Due to 13 | // software timing, it will read a number much less than a steady 14 | // logic high, but this number will give you a baseline reading 15 | // for output with minimal interrupt overhead. Then increase the 16 | // encoder speed. The voltage will decrease as the processor spends 17 | // more time in Encoder's interrupt routines counting the pulses 18 | // and less time pulsing the output pin. When the voltage is 19 | // close to zero and will not decrease any farther, you have reached 20 | // the absolute speed limit. Or, if using a mechanical system where 21 | // you reach a speed limit imposed by your motors or other hardware, 22 | // the amount this voltage has decreased, compared to the baseline, 23 | // should give you a good approximation of the portion of available 24 | // CPU time Encoder is consuming at your maximum speed. 25 | 26 | // Encoder requires low latency interrupt response. Available CPU 27 | // time does NOT necessarily prove or guarantee correct performance. 28 | // If another library, like NewSoftSerial, is disabling interrupts 29 | // for lengthy periods of time, Encoder can be prevented from 30 | // properly counting the intput signals while interrupt are disabled. 31 | 32 | 33 | // This optional setting causes Encoder to use more optimized code, 34 | // but the downside is a conflict if any other part of your sketch 35 | // or any other library you're using requires attachInterrupt(). 36 | // It must be defined before Encoder.h is included. 37 | //#define ENCODER_OPTIMIZE_INTERRUPTS 38 | 39 | #include 40 | #include "pins_arduino.h" 41 | 42 | // Change these two numbers to the pins connected to your encoder 43 | // or shift register circuit which emulates a quadrature encoder 44 | // case 1: both pins are interrupts 45 | // case 2: only first pin used as interrupt 46 | Encoder myEnc(5, 6); 47 | 48 | // Connect a DC voltmeter to this pin. 49 | const int outputPin = 12; 50 | 51 | /* This simple circuit, using a Dual Flip-Flop chip, can emulate 52 | quadrature encoder signals. The clock can come from a fancy 53 | function generator or a cheap 555 timer chip. The clock 54 | frequency can be measured with another board running FreqCount 55 | http://www.pjrc.com/teensy/td_libs_FreqCount.html 56 | 57 | +5V 58 | | Quadrature Encoder Signal Emulator 59 | Clock | 60 | Input o----*-------------------------- ---------------------------o Output1 61 | | |14 | | 62 | | _______|_______ | | _______________ 63 | | | CD4013 | | | | CD4013 | 64 | | 5 | | 1 | | 9 | | 13 65 | ---------| D Q |-----|----*----| D Q |------o Output2 66 | | | | | | | | 67 | | | 3 | | | 11 | | 68 | | ----|> Clk | ---------|> Clk | 69 | | | | | | 70 | | 6 | | 8 | | 71 | | ----| S | ----| S | 72 | | | | | | | | 73 | | | 4 | _ | 2 | 10 | _ | 12 74 | | *----| R Q |--- *----| R Q |---- 75 | | | | | | | | | 76 | | | |_______________| | |_______________| | 77 | | | | | | 78 | | | | 7 | | 79 | | | | | | 80 | -------------------------------------------------------------- 81 | | | | 82 | | | | 83 | ----- ----- ----- 84 | --- --- --- 85 | - - - 86 | */ 87 | 88 | 89 | void setup() { 90 | pinMode(outputPin, OUTPUT); 91 | } 92 | 93 | #if defined(__AVR__) 94 | #define REGTYPE unsigned char 95 | #elif defined(__PIC32MX__) 96 | #define REGTYPE unsigned long 97 | #endif 98 | 99 | void loop() { 100 | volatile int count = 0; 101 | volatile REGTYPE *reg = portOutputRegister(digitalPinToPort(outputPin)); 102 | REGTYPE mask = digitalPinToBitMask(outputPin); 103 | 104 | while (1) { 105 | myEnc.read(); // Read the encoder while interrupts are enabled. 106 | noInterrupts(); 107 | *reg |= mask; // Pulse the pin high, while interrupts are disabled. 108 | count = count + 1; 109 | *reg &= ~mask; 110 | interrupts(); 111 | } 112 | } 113 | 114 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/Encoder/utility/interrupt_pins.h: -------------------------------------------------------------------------------- 1 | // interrupt pins for known boards 2 | 3 | // Teensy (and maybe others) define these automatically 4 | #if !defined(CORE_NUM_INTERRUPT) 5 | 6 | // Wiring boards 7 | #if defined(WIRING) 8 | #define CORE_NUM_INTERRUPT NUM_EXTERNAL_INTERRUPTS 9 | #if NUM_EXTERNAL_INTERRUPTS > 0 10 | #define CORE_INT0_PIN EI0 11 | #endif 12 | #if NUM_EXTERNAL_INTERRUPTS > 1 13 | #define CORE_INT1_PIN EI1 14 | #endif 15 | #if NUM_EXTERNAL_INTERRUPTS > 2 16 | #define CORE_INT2_PIN EI2 17 | #endif 18 | #if NUM_EXTERNAL_INTERRUPTS > 3 19 | #define CORE_INT3_PIN EI3 20 | #endif 21 | #if NUM_EXTERNAL_INTERRUPTS > 4 22 | #define CORE_INT4_PIN EI4 23 | #endif 24 | #if NUM_EXTERNAL_INTERRUPTS > 5 25 | #define CORE_INT5_PIN EI5 26 | #endif 27 | #if NUM_EXTERNAL_INTERRUPTS > 6 28 | #define CORE_INT6_PIN EI6 29 | #endif 30 | #if NUM_EXTERNAL_INTERRUPTS > 7 31 | #define CORE_INT7_PIN EI7 32 | #endif 33 | 34 | // Arduino Uno, Duemilanove, Diecimila, LilyPad, Mini, Fio, etc... 35 | #elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) 36 | #define CORE_NUM_INTERRUPT 2 37 | #define CORE_INT0_PIN 2 38 | #define CORE_INT1_PIN 3 39 | 40 | // Arduino Mega 41 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 42 | #define CORE_NUM_INTERRUPT 6 43 | #define CORE_INT0_PIN 2 44 | #define CORE_INT1_PIN 3 45 | #define CORE_INT2_PIN 21 46 | #define CORE_INT3_PIN 20 47 | #define CORE_INT4_PIN 19 48 | #define CORE_INT5_PIN 18 49 | 50 | // Arduino Leonardo (untested) 51 | #elif defined(__AVR_ATmega32U4__) && !defined(CORE_TEENSY) 52 | #define CORE_NUM_INTERRUPT 4 53 | #define CORE_INT0_PIN 3 54 | #define CORE_INT1_PIN 2 55 | #define CORE_INT2_PIN 0 56 | #define CORE_INT3_PIN 1 57 | 58 | // Sanguino (untested) 59 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) 60 | #define CORE_NUM_INTERRUPT 3 61 | #define CORE_INT0_PIN 10 62 | #define CORE_INT1_PIN 11 63 | #define CORE_INT2_PIN 2 64 | 65 | // Chipkit Uno32 - attachInterrupt may not support CHANGE option 66 | #elif defined(__PIC32MX__) && defined(_BOARD_UNO_) 67 | #define CORE_NUM_INTERRUPT 5 68 | #define CORE_INT0_PIN 38 69 | #define CORE_INT1_PIN 2 70 | #define CORE_INT2_PIN 7 71 | #define CORE_INT3_PIN 8 72 | #define CORE_INT4_PIN 35 73 | 74 | // Chipkit Uno32 - attachInterrupt may not support CHANGE option 75 | #elif defined(__PIC32MX__) && defined(_BOARD_MEGA_) 76 | #define CORE_NUM_INTERRUPT 5 77 | #define CORE_INT0_PIN 3 78 | #define CORE_INT1_PIN 2 79 | #define CORE_INT2_PIN 7 80 | #define CORE_INT3_PIN 21 81 | #define CORE_INT4_PIN 20 82 | 83 | // http://hlt.media.mit.edu/?p=1229 84 | #elif defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) 85 | #define CORE_NUM_INTERRUPT 1 86 | #define CORE_INT0_PIN 2 87 | 88 | // Arduino Due 89 | #elif defined(__SAM3X8E__) 90 | #define CORE_NUM_INTERRUPT 54 91 | #define CORE_INT0_PIN 0 92 | #define CORE_INT1_PIN 1 93 | #define CORE_INT2_PIN 2 94 | #define CORE_INT3_PIN 3 95 | #define CORE_INT4_PIN 4 96 | #define CORE_INT5_PIN 5 97 | #define CORE_INT6_PIN 6 98 | #define CORE_INT7_PIN 7 99 | #define CORE_INT8_PIN 8 100 | #define CORE_INT9_PIN 9 101 | #define CORE_INT10_PIN 10 102 | #define CORE_INT11_PIN 11 103 | #define CORE_INT12_PIN 12 104 | #define CORE_INT13_PIN 13 105 | #define CORE_INT14_PIN 14 106 | #define CORE_INT15_PIN 15 107 | #define CORE_INT16_PIN 16 108 | #define CORE_INT17_PIN 17 109 | #define CORE_INT18_PIN 18 110 | #define CORE_INT19_PIN 19 111 | #define CORE_INT20_PIN 20 112 | #define CORE_INT21_PIN 21 113 | #define CORE_INT22_PIN 22 114 | #define CORE_INT23_PIN 23 115 | #define CORE_INT24_PIN 24 116 | #define CORE_INT25_PIN 25 117 | #define CORE_INT26_PIN 26 118 | #define CORE_INT27_PIN 27 119 | #define CORE_INT28_PIN 28 120 | #define CORE_INT29_PIN 29 121 | #define CORE_INT30_PIN 30 122 | #define CORE_INT31_PIN 31 123 | #define CORE_INT32_PIN 32 124 | #define CORE_INT33_PIN 33 125 | #define CORE_INT34_PIN 34 126 | #define CORE_INT35_PIN 35 127 | #define CORE_INT36_PIN 36 128 | #define CORE_INT37_PIN 37 129 | #define CORE_INT38_PIN 38 130 | #define CORE_INT39_PIN 39 131 | #define CORE_INT40_PIN 40 132 | #define CORE_INT41_PIN 41 133 | #define CORE_INT42_PIN 42 134 | #define CORE_INT43_PIN 43 135 | #define CORE_INT44_PIN 44 136 | #define CORE_INT45_PIN 45 137 | #define CORE_INT46_PIN 46 138 | #define CORE_INT47_PIN 47 139 | #define CORE_INT48_PIN 48 140 | #define CORE_INT49_PIN 49 141 | #define CORE_INT50_PIN 50 142 | #define CORE_INT51_PIN 51 143 | #define CORE_INT52_PIN 52 144 | #define CORE_INT53_PIN 53 145 | 146 | // ESP8266 (https://github.com/esp8266/Arduino/) 147 | #elif defined(ESP8266) 148 | #define CORE_NUM_INTERRUPT EXTERNAL_NUM_INTERRUPTS 149 | #define CORE_INT0_PIN 0 150 | #define CORE_INT1_PIN 1 151 | #define CORE_INT2_PIN 2 152 | #define CORE_INT3_PIN 3 153 | #define CORE_INT4_PIN 4 154 | #define CORE_INT5_PIN 5 155 | // GPIO6-GPIO11 are typically used to interface with the flash memory IC on 156 | // most esp8266 modules, so we should avoid adding interrupts to these pins. 157 | #define CORE_INT12_PIN 12 158 | #define CORE_INT13_PIN 13 159 | #define CORE_INT14_PIN 14 160 | #define CORE_INT15_PIN 15 161 | 162 | // Arduino Zero - TODO: interrupts do not seem to work 163 | // please help, contribute a fix! 164 | #elif defined(__SAMD21G18A__) 165 | #define CORE_NUM_INTERRUPT 20 166 | #define CORE_INT0_PIN 0 167 | #define CORE_INT1_PIN 1 168 | #define CORE_INT2_PIN 2 169 | #define CORE_INT3_PIN 3 170 | #define CORE_INT5_PIN 5 171 | #define CORE_INT6_PIN 6 172 | #define CORE_INT7_PIN 7 173 | #define CORE_INT8_PIN 8 174 | #define CORE_INT9_PIN 9 175 | #define CORE_INT10_PIN 10 176 | #define CORE_INT11_PIN 11 177 | #define CORE_INT12_PIN 12 178 | #define CORE_INT13_PIN 13 179 | #define CORE_INT14_PIN 14 180 | #define CORE_INT15_PIN 15 181 | #define CORE_INT16_PIN 16 182 | #define CORE_INT17_PIN 17 183 | #define CORE_INT18_PIN 18 184 | #define CORE_INT19_PIN 19 185 | 186 | // Arduino 101 187 | #elif defined(__arc__) 188 | #define CORE_NUM_INTERRUPT 14 189 | #define CORE_INT2_PIN 2 190 | #define CORE_INT5_PIN 5 191 | #define CORE_INT7_PIN 7 192 | #define CORE_INT8_PIN 8 193 | #define CORE_INT10_PIN 10 194 | #define CORE_INT11_PIN 11 195 | #define CORE_INT12_PIN 12 196 | #define CORE_INT13_PIN 13 197 | 198 | #endif 199 | #endif 200 | 201 | #if !defined(CORE_NUM_INTERRUPT) 202 | #error "Interrupts are unknown for this board, please add to this code" 203 | #endif 204 | #if CORE_NUM_INTERRUPT <= 0 205 | #error "Encoder requires interrupt pins, but this board does not have any :(" 206 | #error "You could try defining ENCODER_DO_NOT_USE_INTERRUPTS as a kludge." 207 | #endif 208 | 209 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/utility/SdInfo.h: -------------------------------------------------------------------------------- 1 | /* Arduino Sd2Card Library 2 | * Copyright (C) 2009 by William Greiman 3 | * 4 | * This file is part of the Arduino Sd2Card Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino Sd2Card Library. If not, see 18 | * . 19 | */ 20 | #ifndef SdInfo_h 21 | #define SdInfo_h 22 | #include 23 | // Based on the document: 24 | // 25 | // SD Specifications 26 | // Part 1 27 | // Physical Layer 28 | // Simplified Specification 29 | // Version 2.00 30 | // September 25, 2006 31 | // 32 | // www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf 33 | //------------------------------------------------------------------------------ 34 | // SD card commands 35 | /** GO_IDLE_STATE - init card in spi mode if CS low */ 36 | uint8_t const CMD0 = 0X00; 37 | /** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ 38 | uint8_t const CMD8 = 0X08; 39 | /** SEND_CSD - read the Card Specific Data (CSD register) */ 40 | uint8_t const CMD9 = 0X09; 41 | /** SEND_CID - read the card identification information (CID register) */ 42 | uint8_t const CMD10 = 0X0A; 43 | /** SEND_STATUS - read the card status register */ 44 | uint8_t const CMD13 = 0X0D; 45 | /** READ_BLOCK - read a single data block from the card */ 46 | uint8_t const CMD17 = 0X11; 47 | /** WRITE_BLOCK - write a single data block to the card */ 48 | uint8_t const CMD24 = 0X18; 49 | /** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */ 50 | uint8_t const CMD25 = 0X19; 51 | /** ERASE_WR_BLK_START - sets the address of the first block to be erased */ 52 | uint8_t const CMD32 = 0X20; 53 | /** ERASE_WR_BLK_END - sets the address of the last block of the continuous 54 | range to be erased*/ 55 | uint8_t const CMD33 = 0X21; 56 | /** ERASE - erase all previously selected blocks */ 57 | uint8_t const CMD38 = 0X26; 58 | /** APP_CMD - escape for application specific command */ 59 | uint8_t const CMD55 = 0X37; 60 | /** READ_OCR - read the OCR register of a card */ 61 | uint8_t const CMD58 = 0X3A; 62 | /** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be 63 | pre-erased before writing */ 64 | uint8_t const ACMD23 = 0X17; 65 | /** SD_SEND_OP_COMD - Sends host capacity support information and 66 | activates the card's initialization process */ 67 | uint8_t const ACMD41 = 0X29; 68 | //------------------------------------------------------------------------------ 69 | /** status for card in the ready state */ 70 | uint8_t const R1_READY_STATE = 0X00; 71 | /** status for card in the idle state */ 72 | uint8_t const R1_IDLE_STATE = 0X01; 73 | /** status bit for illegal command */ 74 | uint8_t const R1_ILLEGAL_COMMAND = 0X04; 75 | /** start data token for read or write single block*/ 76 | uint8_t const DATA_START_BLOCK = 0XFE; 77 | /** stop token for write multiple blocks*/ 78 | uint8_t const STOP_TRAN_TOKEN = 0XFD; 79 | /** start data token for write multiple blocks*/ 80 | uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC; 81 | /** mask for data response tokens after a write block operation */ 82 | uint8_t const DATA_RES_MASK = 0X1F; 83 | /** write data accepted token */ 84 | uint8_t const DATA_RES_ACCEPTED = 0X05; 85 | //------------------------------------------------------------------------------ 86 | typedef struct CID { 87 | // byte 0 88 | uint8_t mid; // Manufacturer ID 89 | // byte 1-2 90 | char oid[2]; // OEM/Application ID 91 | // byte 3-7 92 | char pnm[5]; // Product name 93 | // byte 8 94 | unsigned prv_m : 4; // Product revision n.m 95 | unsigned prv_n : 4; 96 | // byte 9-12 97 | uint32_t psn; // Product serial number 98 | // byte 13 99 | unsigned mdt_year_high : 4; // Manufacturing date 100 | unsigned reserved : 4; 101 | // byte 14 102 | unsigned mdt_month : 4; 103 | unsigned mdt_year_low :4; 104 | // byte 15 105 | unsigned always1 : 1; 106 | unsigned crc : 7; 107 | }cid_t; 108 | //------------------------------------------------------------------------------ 109 | // CSD for version 1.00 cards 110 | typedef struct CSDV1 { 111 | // byte 0 112 | unsigned reserved1 : 6; 113 | unsigned csd_ver : 2; 114 | // byte 1 115 | uint8_t taac; 116 | // byte 2 117 | uint8_t nsac; 118 | // byte 3 119 | uint8_t tran_speed; 120 | // byte 4 121 | uint8_t ccc_high; 122 | // byte 5 123 | unsigned read_bl_len : 4; 124 | unsigned ccc_low : 4; 125 | // byte 6 126 | unsigned c_size_high : 2; 127 | unsigned reserved2 : 2; 128 | unsigned dsr_imp : 1; 129 | unsigned read_blk_misalign :1; 130 | unsigned write_blk_misalign : 1; 131 | unsigned read_bl_partial : 1; 132 | // byte 7 133 | uint8_t c_size_mid; 134 | // byte 8 135 | unsigned vdd_r_curr_max : 3; 136 | unsigned vdd_r_curr_min : 3; 137 | unsigned c_size_low :2; 138 | // byte 9 139 | unsigned c_size_mult_high : 2; 140 | unsigned vdd_w_cur_max : 3; 141 | unsigned vdd_w_curr_min : 3; 142 | // byte 10 143 | unsigned sector_size_high : 6; 144 | unsigned erase_blk_en : 1; 145 | unsigned c_size_mult_low : 1; 146 | // byte 11 147 | unsigned wp_grp_size : 7; 148 | unsigned sector_size_low : 1; 149 | // byte 12 150 | unsigned write_bl_len_high : 2; 151 | unsigned r2w_factor : 3; 152 | unsigned reserved3 : 2; 153 | unsigned wp_grp_enable : 1; 154 | // byte 13 155 | unsigned reserved4 : 5; 156 | unsigned write_partial : 1; 157 | unsigned write_bl_len_low : 2; 158 | // byte 14 159 | unsigned reserved5: 2; 160 | unsigned file_format : 2; 161 | unsigned tmp_write_protect : 1; 162 | unsigned perm_write_protect : 1; 163 | unsigned copy : 1; 164 | unsigned file_format_grp : 1; 165 | // byte 15 166 | unsigned always1 : 1; 167 | unsigned crc : 7; 168 | }csd1_t; 169 | //------------------------------------------------------------------------------ 170 | // CSD for version 2.00 cards 171 | typedef struct CSDV2 { 172 | // byte 0 173 | unsigned reserved1 : 6; 174 | unsigned csd_ver : 2; 175 | // byte 1 176 | uint8_t taac; 177 | // byte 2 178 | uint8_t nsac; 179 | // byte 3 180 | uint8_t tran_speed; 181 | // byte 4 182 | uint8_t ccc_high; 183 | // byte 5 184 | unsigned read_bl_len : 4; 185 | unsigned ccc_low : 4; 186 | // byte 6 187 | unsigned reserved2 : 4; 188 | unsigned dsr_imp : 1; 189 | unsigned read_blk_misalign :1; 190 | unsigned write_blk_misalign : 1; 191 | unsigned read_bl_partial : 1; 192 | // byte 7 193 | unsigned reserved3 : 2; 194 | unsigned c_size_high : 6; 195 | // byte 8 196 | uint8_t c_size_mid; 197 | // byte 9 198 | uint8_t c_size_low; 199 | // byte 10 200 | unsigned sector_size_high : 6; 201 | unsigned erase_blk_en : 1; 202 | unsigned reserved4 : 1; 203 | // byte 11 204 | unsigned wp_grp_size : 7; 205 | unsigned sector_size_low : 1; 206 | // byte 12 207 | unsigned write_bl_len_high : 2; 208 | unsigned r2w_factor : 3; 209 | unsigned reserved5 : 2; 210 | unsigned wp_grp_enable : 1; 211 | // byte 13 212 | unsigned reserved6 : 5; 213 | unsigned write_partial : 1; 214 | unsigned write_bl_len_low : 2; 215 | // byte 14 216 | unsigned reserved7: 2; 217 | unsigned file_format : 2; 218 | unsigned tmp_write_protect : 1; 219 | unsigned perm_write_protect : 1; 220 | unsigned copy : 1; 221 | unsigned file_format_grp : 1; 222 | // byte 15 223 | unsigned always1 : 1; 224 | unsigned crc : 7; 225 | }csd2_t; 226 | //------------------------------------------------------------------------------ 227 | // union of old and new style CSD register 228 | union csd_t { 229 | csd1_t v1; 230 | csd2_t v2; 231 | }; 232 | #endif // SdInfo_h 233 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/utility/SdFatmainpage.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2009 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | 21 | /** 22 | \mainpage Arduino SdFat Library 23 |
Copyright © 2009 by William Greiman 24 |
25 | 26 | \section Intro Introduction 27 | The Arduino SdFat Library is a minimal implementation of FAT16 and FAT32 28 | file systems on SD flash memory cards. Standard SD and high capacity 29 | SDHC cards are supported. 30 | 31 | The SdFat only supports short 8.3 names. 32 | 33 | The main classes in SdFat are Sd2Card, SdVolume, and SdFile. 34 | 35 | The Sd2Card class supports access to standard SD cards and SDHC cards. Most 36 | applications will only need to call the Sd2Card::init() member function. 37 | 38 | The SdVolume class supports FAT16 and FAT32 partitions. Most applications 39 | will only need to call the SdVolume::init() member function. 40 | 41 | The SdFile class provides file access functions such as open(), read(), 42 | remove(), write(), close() and sync(). This class supports access to the root 43 | directory and subdirectories. 44 | 45 | A number of example are provided in the SdFat/examples folder. These were 46 | developed to test SdFat and illustrate its use. 47 | 48 | SdFat was developed for high speed data recording. SdFat was used to implement 49 | an audio record/play class, WaveRP, for the Adafruit Wave Shield. This 50 | application uses special Sd2Card calls to write to contiguous files in raw mode. 51 | These functions reduce write latency so that audio can be recorded with the 52 | small amount of RAM in the Arduino. 53 | 54 | \section SDcard SD\SDHC Cards 55 | 56 | Arduinos access SD cards using the cards SPI protocol. PCs, Macs, and 57 | most consumer devices use the 4-bit parallel SD protocol. A card that 58 | functions well on A PC or Mac may not work well on the Arduino. 59 | 60 | Most cards have good SPI read performance but cards vary widely in SPI 61 | write performance. Write performance is limited by how efficiently the 62 | card manages internal erase/remapping operations. The Arduino cannot 63 | optimize writes to reduce erase operations because of its limit RAM. 64 | 65 | SanDisk cards generally have good write performance. They seem to have 66 | more internal RAM buffering than other cards and therefore can limit 67 | the number of flash erase operations that the Arduino forces due to its 68 | limited RAM. 69 | 70 | \section Hardware Hardware Configuration 71 | 72 | SdFat was developed using an 73 | Adafruit Industries 74 | Wave Shield. 75 | 76 | The hardware interface to the SD card should not use a resistor based level 77 | shifter. SdFat sets the SPI bus frequency to 8 MHz which results in signal 78 | rise times that are too slow for the edge detectors in many newer SD card 79 | controllers when resistor voltage dividers are used. 80 | 81 | The 5 to 3.3 V level shifter for 5 V Arduinos should be IC based like the 82 | 74HC4050N based circuit shown in the file SdLevel.png. The Adafruit Wave Shield 83 | uses a 74AHC125N. Gravitech sells SD and MicroSD Card Adapters based on the 84 | 74LCX245. 85 | 86 | If you are using a resistor based level shifter and are having problems try 87 | setting the SPI bus frequency to 4 MHz. This can be done by using 88 | card.init(SPI_HALF_SPEED) to initialize the SD card. 89 | 90 | \section comment Bugs and Comments 91 | 92 | If you wish to report bugs or have comments, send email to fat16lib@sbcglobal.net. 93 | 94 | \section SdFatClass SdFat Usage 95 | 96 | SdFat uses a slightly restricted form of short names. 97 | Only printable ASCII characters are supported. No characters with code point 98 | values greater than 127 are allowed. Space is not allowed even though space 99 | was allowed in the API of early versions of DOS. 100 | 101 | Short names are limited to 8 characters followed by an optional period (.) 102 | and extension of up to 3 characters. The characters may be any combination 103 | of letters and digits. The following special characters are also allowed: 104 | 105 | $ % ' - _ @ ~ ` ! ( ) { } ^ # & 106 | 107 | Short names are always converted to upper case and their original case 108 | value is lost. 109 | 110 | \note 111 | The Arduino Print class uses character 112 | at a time writes so it was necessary to use a \link SdFile::sync() sync() \endlink 113 | function to control when data is written to the SD card. 114 | 115 | \par 116 | An application which writes to a file using \link Print::print() print()\endlink, 117 | \link Print::println() println() \endlink 118 | or \link SdFile::write write() \endlink must call \link SdFile::sync() sync() \endlink 119 | at the appropriate time to force data and directory information to be written 120 | to the SD Card. Data and directory information are also written to the SD card 121 | when \link SdFile::close() close() \endlink is called. 122 | 123 | \par 124 | Applications must use care calling \link SdFile::sync() sync() \endlink 125 | since 2048 bytes of I/O is required to update file and 126 | directory information. This includes writing the current data block, reading 127 | the block that contains the directory entry for update, writing the directory 128 | block back and reading back the current data block. 129 | 130 | It is possible to open a file with two or more instances of SdFile. A file may 131 | be corrupted if data is written to the file by more than one instance of SdFile. 132 | 133 | \section HowTo How to format SD Cards as FAT Volumes 134 | 135 | You should use a freshly formatted SD card for best performance. FAT 136 | file systems become slower if many files have been created and deleted. 137 | This is because the directory entry for a deleted file is marked as deleted, 138 | but is not deleted. When a new file is created, these entries must be scanned 139 | before creating the file, a flaw in the FAT design. Also files can become 140 | fragmented which causes reads and writes to be slower. 141 | 142 | Microsoft operating systems support removable media formatted with a 143 | Master Boot Record, MBR, or formatted as a super floppy with a FAT Boot Sector 144 | in block zero. 145 | 146 | Microsoft operating systems expect MBR formatted removable media 147 | to have only one partition. The first partition should be used. 148 | 149 | Microsoft operating systems do not support partitioning SD flash cards. 150 | If you erase an SD card with a program like KillDisk, Most versions of 151 | Windows will format the card as a super floppy. 152 | 153 | The best way to restore an SD card's format is to use SDFormatter 154 | which can be downloaded from: 155 | 156 | http://www.sdcard.org/consumers/formatter/ 157 | 158 | SDFormatter aligns flash erase boundaries with file 159 | system structures which reduces write latency and file system overhead. 160 | 161 | SDFormatter does not have an option for FAT type so it may format 162 | small cards as FAT12. 163 | 164 | After the MBR is restored by SDFormatter you may need to reformat small 165 | cards that have been formatted FAT12 to force the volume type to be FAT16. 166 | 167 | If you reformat the SD card with an OS utility, choose a cluster size that 168 | will result in: 169 | 170 | 4084 < CountOfClusters && CountOfClusters < 65525 171 | 172 | The volume will then be FAT16. 173 | 174 | If you are formatting an SD card on OS X or Linux, be sure to use the first 175 | partition. Format this partition with a cluster count in above range. 176 | 177 | \section References References 178 | 179 | Adafruit Industries: 180 | 181 | http://www.adafruit.com/ 182 | 183 | http://www.ladyada.net/make/waveshield/ 184 | 185 | The Arduino site: 186 | 187 | http://www.arduino.cc/ 188 | 189 | For more information about FAT file systems see: 190 | 191 | http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx 192 | 193 | For information about using SD cards as SPI devices see: 194 | 195 | http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf 196 | 197 | The ATmega328 datasheet: 198 | 199 | http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf 200 | 201 | 202 | */ 203 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp: -------------------------------------------------------------------------------- 1 | // Based on the work by DFRobot 2 | 3 | #include "LiquidCrystal_I2C.h" 4 | #include 5 | #if defined(ARDUINO) && ARDUINO >= 100 6 | 7 | #include "Arduino.h" 8 | 9 | #define printIIC(args) Wire.write(args) 10 | inline size_t LiquidCrystal_I2C::write(uint8_t value) { 11 | send(value, Rs); 12 | return 1; 13 | } 14 | 15 | #else 16 | #include "WProgram.h" 17 | 18 | #define printIIC(args) Wire.send(args) 19 | inline void LiquidCrystal_I2C::write(uint8_t value) { 20 | send(value, Rs); 21 | } 22 | 23 | #endif 24 | #include "Wire.h" 25 | 26 | 27 | 28 | // When the display powers up, it is configured as follows: 29 | // 30 | // 1. Display clear 31 | // 2. Function set: 32 | // DL = 1; 8-bit interface data 33 | // N = 0; 1-line display 34 | // F = 0; 5x8 dot character font 35 | // 3. Display on/off control: 36 | // D = 0; Display off 37 | // C = 0; Cursor off 38 | // B = 0; Blinking off 39 | // 4. Entry mode set: 40 | // I/D = 1; Increment by 1 41 | // S = 0; No shift 42 | // 43 | // Note, however, that resetting the Arduino doesn't reset the LCD, so we 44 | // can't assume that its in that state when a sketch starts (and the 45 | // LiquidCrystal constructor is called). 46 | 47 | LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows) 48 | { 49 | _Addr = lcd_Addr; 50 | _cols = lcd_cols; 51 | _rows = lcd_rows; 52 | _backlightval = LCD_NOBACKLIGHT; 53 | } 54 | 55 | void LiquidCrystal_I2C::init(){ 56 | init_priv(); 57 | } 58 | 59 | void LiquidCrystal_I2C::init_priv() 60 | { 61 | Wire.begin(); 62 | _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; 63 | begin(_cols, _rows); 64 | } 65 | 66 | void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { 67 | if (lines > 1) { 68 | _displayfunction |= LCD_2LINE; 69 | } 70 | _numlines = lines; 71 | 72 | // for some 1 line displays you can select a 10 pixel high font 73 | if ((dotsize != 0) && (lines == 1)) { 74 | _displayfunction |= LCD_5x10DOTS; 75 | } 76 | 77 | // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! 78 | // according to datasheet, we need at least 40ms after power rises above 2.7V 79 | // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 80 | delay(50); 81 | 82 | // Now we pull both RS and R/W low to begin commands 83 | expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) 84 | delay(1000); 85 | 86 | //put the LCD into 4 bit mode 87 | // this is according to the hitachi HD44780 datasheet 88 | // figure 24, pg 46 89 | 90 | // we start in 8bit mode, try to set 4 bit mode 91 | write4bits(0x03 << 4); 92 | delayMicroseconds(4500); // wait min 4.1ms 93 | 94 | // second try 95 | write4bits(0x03 << 4); 96 | delayMicroseconds(4500); // wait min 4.1ms 97 | 98 | // third go! 99 | write4bits(0x03 << 4); 100 | delayMicroseconds(150); 101 | 102 | // finally, set to 4-bit interface 103 | write4bits(0x02 << 4); 104 | 105 | 106 | // set # lines, font size, etc. 107 | command(LCD_FUNCTIONSET | _displayfunction); 108 | 109 | // turn the display on with no cursor or blinking default 110 | _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 111 | display(); 112 | 113 | // clear it off 114 | clear(); 115 | 116 | // Initialize to default text direction (for roman languages) 117 | _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; 118 | 119 | // set the entry mode 120 | command(LCD_ENTRYMODESET | _displaymode); 121 | 122 | home(); 123 | 124 | } 125 | 126 | /********** high level commands, for the user! */ 127 | void LiquidCrystal_I2C::clear(){ 128 | command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero 129 | delayMicroseconds(2000); // this command takes a long time! 130 | } 131 | 132 | void LiquidCrystal_I2C::home(){ 133 | command(LCD_RETURNHOME); // set cursor position to zero 134 | delayMicroseconds(2000); // this command takes a long time! 135 | } 136 | 137 | void LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row){ 138 | int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; 139 | if ( row > _numlines ) { 140 | row = _numlines-1; // we count rows starting w/0 141 | } 142 | command(LCD_SETDDRAMADDR | (col + row_offsets[row])); 143 | } 144 | 145 | // Turn the display on/off (quickly) 146 | void LiquidCrystal_I2C::noDisplay() { 147 | _displaycontrol &= ~LCD_DISPLAYON; 148 | command(LCD_DISPLAYCONTROL | _displaycontrol); 149 | } 150 | void LiquidCrystal_I2C::display() { 151 | _displaycontrol |= LCD_DISPLAYON; 152 | command(LCD_DISPLAYCONTROL | _displaycontrol); 153 | } 154 | 155 | // Turns the underline cursor on/off 156 | void LiquidCrystal_I2C::noCursor() { 157 | _displaycontrol &= ~LCD_CURSORON; 158 | command(LCD_DISPLAYCONTROL | _displaycontrol); 159 | } 160 | void LiquidCrystal_I2C::cursor() { 161 | _displaycontrol |= LCD_CURSORON; 162 | command(LCD_DISPLAYCONTROL | _displaycontrol); 163 | } 164 | 165 | // Turn on and off the blinking cursor 166 | void LiquidCrystal_I2C::noBlink() { 167 | _displaycontrol &= ~LCD_BLINKON; 168 | command(LCD_DISPLAYCONTROL | _displaycontrol); 169 | } 170 | void LiquidCrystal_I2C::blink() { 171 | _displaycontrol |= LCD_BLINKON; 172 | command(LCD_DISPLAYCONTROL | _displaycontrol); 173 | } 174 | 175 | // These commands scroll the display without changing the RAM 176 | void LiquidCrystal_I2C::scrollDisplayLeft(void) { 177 | command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); 178 | } 179 | void LiquidCrystal_I2C::scrollDisplayRight(void) { 180 | command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); 181 | } 182 | 183 | // This is for text that flows Left to Right 184 | void LiquidCrystal_I2C::leftToRight(void) { 185 | _displaymode |= LCD_ENTRYLEFT; 186 | command(LCD_ENTRYMODESET | _displaymode); 187 | } 188 | 189 | // This is for text that flows Right to Left 190 | void LiquidCrystal_I2C::rightToLeft(void) { 191 | _displaymode &= ~LCD_ENTRYLEFT; 192 | command(LCD_ENTRYMODESET | _displaymode); 193 | } 194 | 195 | // This will 'right justify' text from the cursor 196 | void LiquidCrystal_I2C::autoscroll(void) { 197 | _displaymode |= LCD_ENTRYSHIFTINCREMENT; 198 | command(LCD_ENTRYMODESET | _displaymode); 199 | } 200 | 201 | // This will 'left justify' text from the cursor 202 | void LiquidCrystal_I2C::noAutoscroll(void) { 203 | _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; 204 | command(LCD_ENTRYMODESET | _displaymode); 205 | } 206 | 207 | // Allows us to fill the first 8 CGRAM locations 208 | // with custom characters 209 | void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) { 210 | location &= 0x7; // we only have 8 locations 0-7 211 | command(LCD_SETCGRAMADDR | (location << 3)); 212 | for (int i=0; i<8; i++) { 213 | write(charmap[i]); 214 | } 215 | } 216 | 217 | // Turn the (optional) backlight off/on 218 | void LiquidCrystal_I2C::noBacklight(void) { 219 | _backlightval=LCD_NOBACKLIGHT; 220 | expanderWrite(0); 221 | } 222 | 223 | void LiquidCrystal_I2C::backlight(void) { 224 | _backlightval=LCD_BACKLIGHT; 225 | expanderWrite(0); 226 | } 227 | 228 | 229 | 230 | /*********** mid level commands, for sending data/cmds */ 231 | 232 | inline void LiquidCrystal_I2C::command(uint8_t value) { 233 | send(value, 0); 234 | } 235 | 236 | 237 | /************ low level data pushing commands **********/ 238 | 239 | // write either command or data 240 | void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) { 241 | uint8_t highnib=value&0xf0; 242 | uint8_t lownib=(value<<4)&0xf0; 243 | write4bits((highnib)|mode); 244 | write4bits((lownib)|mode); 245 | } 246 | 247 | void LiquidCrystal_I2C::write4bits(uint8_t value) { 248 | expanderWrite(value); 249 | pulseEnable(value); 250 | } 251 | 252 | void LiquidCrystal_I2C::expanderWrite(uint8_t _data){ 253 | Wire.beginTransmission(_Addr); 254 | printIIC((int)(_data) | _backlightval); 255 | Wire.endTransmission(); 256 | } 257 | 258 | void LiquidCrystal_I2C::pulseEnable(uint8_t _data){ 259 | expanderWrite(_data | En); // En high 260 | delayMicroseconds(1); // enable pulse must be >450ns 261 | 262 | expanderWrite(_data & ~En); // En low 263 | delayMicroseconds(50); // commands need > 37us to settle 264 | } 265 | 266 | 267 | // Alias functions 268 | 269 | void LiquidCrystal_I2C::cursor_on(){ 270 | cursor(); 271 | } 272 | 273 | void LiquidCrystal_I2C::cursor_off(){ 274 | noCursor(); 275 | } 276 | 277 | void LiquidCrystal_I2C::blink_on(){ 278 | blink(); 279 | } 280 | 281 | void LiquidCrystal_I2C::blink_off(){ 282 | noBlink(); 283 | } 284 | 285 | void LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows){ 286 | createChar(char_num, rows); 287 | } 288 | 289 | void LiquidCrystal_I2C::setBacklight(uint8_t new_val){ 290 | if(new_val){ 291 | backlight(); // turn backlight on 292 | }else{ 293 | noBacklight(); // turn backlight off 294 | } 295 | } 296 | 297 | void LiquidCrystal_I2C::printstr(const char c[]){ 298 | //This function is not identical to the function used for "real" I2C displays 299 | //it's here so the user sketch doesn't have to be changed 300 | print(c); 301 | } 302 | 303 | 304 | // unsupported API functions 305 | void LiquidCrystal_I2C::off(){} 306 | void LiquidCrystal_I2C::on(){} 307 | void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {} 308 | uint8_t LiquidCrystal_I2C::status(){return 0;} 309 | uint8_t LiquidCrystal_I2C::keypad (){return 0;} 310 | uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;} 311 | void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){} 312 | void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){} 313 | void LiquidCrystal_I2C::setContrast(uint8_t new_val){} 314 | 315 | 316 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/utility/Sd2Card.h: -------------------------------------------------------------------------------- 1 | /* Arduino Sd2Card Library 2 | * Copyright (C) 2009 by William Greiman 3 | * 4 | * This file is part of the Arduino Sd2Card Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino Sd2Card Library. If not, see 18 | * . 19 | */ 20 | #ifndef Sd2Card_h 21 | #define Sd2Card_h 22 | /** 23 | * \file 24 | * Sd2Card class 25 | */ 26 | #include "Sd2PinMap.h" 27 | #include "SdInfo.h" 28 | /** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */ 29 | uint8_t const SPI_FULL_SPEED = 0; 30 | /** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */ 31 | uint8_t const SPI_HALF_SPEED = 1; 32 | /** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */ 33 | uint8_t const SPI_QUARTER_SPEED = 2; 34 | /** 35 | * USE_SPI_LIB: if set, use the SPI library bundled with Arduino IDE, otherwise 36 | * run with a standalone driver for AVR. 37 | */ 38 | #define USE_SPI_LIB 39 | /** 40 | * Define MEGA_SOFT_SPI non-zero to use software SPI on Mega Arduinos. 41 | * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13. 42 | * 43 | * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used 44 | * on Mega Arduinos. Software SPI works well with GPS Shield V1.1 45 | * but many SD cards will fail with GPS Shield V1.0. 46 | */ 47 | #define MEGA_SOFT_SPI 0 48 | //------------------------------------------------------------------------------ 49 | #if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__)) 50 | #define SOFTWARE_SPI 51 | #endif // MEGA_SOFT_SPI 52 | //------------------------------------------------------------------------------ 53 | // SPI pin definitions 54 | // 55 | #ifndef SOFTWARE_SPI 56 | // hardware pin defs 57 | 58 | // include pins_arduino.h or variant.h depending on architecture, via Arduino.h 59 | #include 60 | 61 | /** 62 | * SD Chip Select pin 63 | * 64 | * Warning if this pin is redefined the hardware SS will pin will be enabled 65 | * as an output by init(). An avr processor will not function as an SPI 66 | * master unless SS is set to output mode. 67 | */ 68 | #ifndef SDCARD_SS_PIN 69 | /** The default chip select pin for the SD card is SS. */ 70 | uint8_t const SD_CHIP_SELECT_PIN = SS; 71 | #else 72 | uint8_t const SD_CHIP_SELECT_PIN = SDCARD_SS_PIN; 73 | #endif 74 | 75 | // The following three pins must not be redefined for hardware SPI, 76 | // so ensure that they are taken from pins_arduino.h or variant.h, depending on architecture. 77 | #ifndef SDCARD_MOSI_PIN 78 | /** SPI Master Out Slave In pin */ 79 | uint8_t const SPI_MOSI_PIN = MOSI; 80 | /** SPI Master In Slave Out pin */ 81 | uint8_t const SPI_MISO_PIN = MISO; 82 | /** SPI Clock pin */ 83 | uint8_t const SPI_SCK_PIN = SCK; 84 | #else 85 | uint8_t const SPI_MOSI_PIN = SDCARD_MOSI_PIN; 86 | uint8_t const SPI_MISO_PIN = SDCARD_MISO_PIN; 87 | uint8_t const SPI_SCK_PIN = SDCARD_SCK_PIN; 88 | #endif 89 | 90 | /** optimize loops for hardware SPI */ 91 | #ifndef USE_SPI_LIB 92 | #define OPTIMIZE_HARDWARE_SPI 93 | #endif 94 | 95 | #else // SOFTWARE_SPI 96 | // define software SPI pins so Mega can use unmodified GPS Shield 97 | /** SPI chip select pin */ 98 | uint8_t const SD_CHIP_SELECT_PIN = 10; 99 | /** SPI Master Out Slave In pin */ 100 | uint8_t const SPI_MOSI_PIN = 11; 101 | /** SPI Master In Slave Out pin */ 102 | uint8_t const SPI_MISO_PIN = 12; 103 | /** SPI Clock pin */ 104 | uint8_t const SPI_SCK_PIN = 13; 105 | #endif // SOFTWARE_SPI 106 | //------------------------------------------------------------------------------ 107 | /** Protect block zero from write if nonzero */ 108 | #define SD_PROTECT_BLOCK_ZERO 1 109 | /** init timeout ms */ 110 | uint16_t const SD_INIT_TIMEOUT = 2000; 111 | /** erase timeout ms */ 112 | uint16_t const SD_ERASE_TIMEOUT = 10000; 113 | /** read timeout ms */ 114 | uint16_t const SD_READ_TIMEOUT = 300; 115 | /** write time out ms */ 116 | uint16_t const SD_WRITE_TIMEOUT = 600; 117 | //------------------------------------------------------------------------------ 118 | // SD card errors 119 | /** timeout error for command CMD0 */ 120 | uint8_t const SD_CARD_ERROR_CMD0 = 0X1; 121 | /** CMD8 was not accepted - not a valid SD card*/ 122 | uint8_t const SD_CARD_ERROR_CMD8 = 0X2; 123 | /** card returned an error response for CMD17 (read block) */ 124 | uint8_t const SD_CARD_ERROR_CMD17 = 0X3; 125 | /** card returned an error response for CMD24 (write block) */ 126 | uint8_t const SD_CARD_ERROR_CMD24 = 0X4; 127 | /** WRITE_MULTIPLE_BLOCKS command failed */ 128 | uint8_t const SD_CARD_ERROR_CMD25 = 0X05; 129 | /** card returned an error response for CMD58 (read OCR) */ 130 | uint8_t const SD_CARD_ERROR_CMD58 = 0X06; 131 | /** SET_WR_BLK_ERASE_COUNT failed */ 132 | uint8_t const SD_CARD_ERROR_ACMD23 = 0X07; 133 | /** card's ACMD41 initialization process timeout */ 134 | uint8_t const SD_CARD_ERROR_ACMD41 = 0X08; 135 | /** card returned a bad CSR version field */ 136 | uint8_t const SD_CARD_ERROR_BAD_CSD = 0X09; 137 | /** erase block group command failed */ 138 | uint8_t const SD_CARD_ERROR_ERASE = 0X0A; 139 | /** card not capable of single block erase */ 140 | uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0X0B; 141 | /** Erase sequence timed out */ 142 | uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0X0C; 143 | /** card returned an error token instead of read data */ 144 | uint8_t const SD_CARD_ERROR_READ = 0X0D; 145 | /** read CID or CSD failed */ 146 | uint8_t const SD_CARD_ERROR_READ_REG = 0X0E; 147 | /** timeout while waiting for start of read data */ 148 | uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X0F; 149 | /** card did not accept STOP_TRAN_TOKEN */ 150 | uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X10; 151 | /** card returned an error token as a response to a write operation */ 152 | uint8_t const SD_CARD_ERROR_WRITE = 0X11; 153 | /** attempt to write protected block zero */ 154 | uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X12; 155 | /** card did not go ready for a multiple block write */ 156 | uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X13; 157 | /** card returned an error to a CMD13 status check after a write */ 158 | uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X14; 159 | /** timeout occurred during write programming */ 160 | uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X15; 161 | /** incorrect rate selected */ 162 | uint8_t const SD_CARD_ERROR_SCK_RATE = 0X16; 163 | //------------------------------------------------------------------------------ 164 | // card types 165 | /** Standard capacity V1 SD card */ 166 | uint8_t const SD_CARD_TYPE_SD1 = 1; 167 | /** Standard capacity V2 SD card */ 168 | uint8_t const SD_CARD_TYPE_SD2 = 2; 169 | /** High Capacity SD card */ 170 | uint8_t const SD_CARD_TYPE_SDHC = 3; 171 | //------------------------------------------------------------------------------ 172 | /** 173 | * \class Sd2Card 174 | * \brief Raw access to SD and SDHC flash memory cards. 175 | */ 176 | class Sd2Card { 177 | public: 178 | /** Construct an instance of Sd2Card. */ 179 | Sd2Card(void) : errorCode_(0), inBlock_(0), partialBlockRead_(0), type_(0) {} 180 | uint32_t cardSize(void); 181 | uint8_t erase(uint32_t firstBlock, uint32_t lastBlock); 182 | uint8_t eraseSingleBlockEnable(void); 183 | /** 184 | * \return error code for last error. See Sd2Card.h for a list of error codes. 185 | */ 186 | uint8_t errorCode(void) const {return errorCode_;} 187 | /** \return error data for last error. */ 188 | uint8_t errorData(void) const {return status_;} 189 | /** 190 | * Initialize an SD flash memory card with default clock rate and chip 191 | * select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). 192 | */ 193 | uint8_t init(void) { 194 | return init(SPI_FULL_SPEED, SD_CHIP_SELECT_PIN); 195 | } 196 | /** 197 | * Initialize an SD flash memory card with the selected SPI clock rate 198 | * and the default SD chip select pin. 199 | * See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin). 200 | */ 201 | uint8_t init(uint8_t sckRateID) { 202 | return init(sckRateID, SD_CHIP_SELECT_PIN); 203 | } 204 | uint8_t init(uint8_t sckRateID, uint8_t chipSelectPin); 205 | void partialBlockRead(uint8_t value); 206 | /** Returns the current value, true or false, for partial block read. */ 207 | uint8_t partialBlockRead(void) const {return partialBlockRead_;} 208 | uint8_t readBlock(uint32_t block, uint8_t* dst); 209 | uint8_t readData(uint32_t block, 210 | uint16_t offset, uint16_t count, uint8_t* dst); 211 | /** 212 | * Read a cards CID register. The CID contains card identification 213 | * information such as Manufacturer ID, Product name, Product serial 214 | * number and Manufacturing date. */ 215 | uint8_t readCID(cid_t* cid) { 216 | return readRegister(CMD10, cid); 217 | } 218 | /** 219 | * Read a cards CSD register. The CSD contains Card-Specific Data that 220 | * provides information regarding access to the card's contents. */ 221 | uint8_t readCSD(csd_t* csd) { 222 | return readRegister(CMD9, csd); 223 | } 224 | void readEnd(void); 225 | uint8_t setSckRate(uint8_t sckRateID); 226 | #ifdef USE_SPI_LIB 227 | uint8_t setSpiClock(uint32_t clock); 228 | #endif 229 | /** Return the card type: SD V1, SD V2 or SDHC */ 230 | uint8_t type(void) const {return type_;} 231 | uint8_t writeBlock(uint32_t blockNumber, const uint8_t* src); 232 | uint8_t writeData(const uint8_t* src); 233 | uint8_t writeStart(uint32_t blockNumber, uint32_t eraseCount); 234 | uint8_t writeStop(void); 235 | private: 236 | uint32_t block_; 237 | uint8_t chipSelectPin_; 238 | uint8_t errorCode_; 239 | uint8_t inBlock_; 240 | uint16_t offset_; 241 | uint8_t partialBlockRead_; 242 | uint8_t status_; 243 | uint8_t type_; 244 | // private functions 245 | uint8_t cardAcmd(uint8_t cmd, uint32_t arg) { 246 | cardCommand(CMD55, 0); 247 | return cardCommand(cmd, arg); 248 | } 249 | uint8_t cardCommand(uint8_t cmd, uint32_t arg); 250 | void error(uint8_t code) {errorCode_ = code;} 251 | uint8_t readRegister(uint8_t cmd, void* buf); 252 | uint8_t sendWriteCommand(uint32_t blockNumber, uint32_t eraseCount); 253 | void chipSelectHigh(void); 254 | void chipSelectLow(void); 255 | void type(uint8_t value) {type_ = value;} 256 | uint8_t waitNotBusy(uint16_t timeoutMillis); 257 | uint8_t writeData(uint8_t token, const uint8_t* src); 258 | uint8_t waitStartBlock(void); 259 | }; 260 | #endif // Sd2Card_h 261 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/utility/SdVolume.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2009 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #include "SdFat.h" 21 | //------------------------------------------------------------------------------ 22 | // raw block cache 23 | // init cacheBlockNumber_to invalid SD block number 24 | uint32_t SdVolume::cacheBlockNumber_ = 0XFFFFFFFF; 25 | cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card 26 | Sd2Card* SdVolume::sdCard_; // pointer to SD card object 27 | uint8_t SdVolume::cacheDirty_ = 0; // cacheFlush() will write block if true 28 | uint32_t SdVolume::cacheMirrorBlock_ = 0; // mirror block for second FAT 29 | //------------------------------------------------------------------------------ 30 | // find a contiguous group of clusters 31 | uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) { 32 | // start of group 33 | uint32_t bgnCluster; 34 | 35 | // flag to save place to start next search 36 | uint8_t setStart; 37 | 38 | // set search start cluster 39 | if (*curCluster) { 40 | // try to make file contiguous 41 | bgnCluster = *curCluster + 1; 42 | 43 | // don't save new start location 44 | setStart = false; 45 | } else { 46 | // start at likely place for free cluster 47 | bgnCluster = allocSearchStart_; 48 | 49 | // save next search start if one cluster 50 | setStart = 1 == count; 51 | } 52 | // end of group 53 | uint32_t endCluster = bgnCluster; 54 | 55 | // last cluster of FAT 56 | uint32_t fatEnd = clusterCount_ + 1; 57 | 58 | // search the FAT for free clusters 59 | for (uint32_t n = 0;; n++, endCluster++) { 60 | // can't find space checked all clusters 61 | if (n >= clusterCount_) return false; 62 | 63 | // past end - start from beginning of FAT 64 | if (endCluster > fatEnd) { 65 | bgnCluster = endCluster = 2; 66 | } 67 | uint32_t f; 68 | if (!fatGet(endCluster, &f)) return false; 69 | 70 | if (f != 0) { 71 | // cluster in use try next cluster as bgnCluster 72 | bgnCluster = endCluster + 1; 73 | } else if ((endCluster - bgnCluster + 1) == count) { 74 | // done - found space 75 | break; 76 | } 77 | } 78 | // mark end of chain 79 | if (!fatPutEOC(endCluster)) return false; 80 | 81 | // link clusters 82 | while (endCluster > bgnCluster) { 83 | if (!fatPut(endCluster - 1, endCluster)) return false; 84 | endCluster--; 85 | } 86 | if (*curCluster != 0) { 87 | // connect chains 88 | if (!fatPut(*curCluster, bgnCluster)) return false; 89 | } 90 | // return first cluster number to caller 91 | *curCluster = bgnCluster; 92 | 93 | // remember possible next free cluster 94 | if (setStart) allocSearchStart_ = bgnCluster + 1; 95 | 96 | return true; 97 | } 98 | //------------------------------------------------------------------------------ 99 | uint8_t SdVolume::cacheFlush(void) { 100 | if (cacheDirty_) { 101 | if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) { 102 | return false; 103 | } 104 | // mirror FAT tables 105 | if (cacheMirrorBlock_) { 106 | if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) { 107 | return false; 108 | } 109 | cacheMirrorBlock_ = 0; 110 | } 111 | cacheDirty_ = 0; 112 | } 113 | return true; 114 | } 115 | //------------------------------------------------------------------------------ 116 | uint8_t SdVolume::cacheRawBlock(uint32_t blockNumber, uint8_t action) { 117 | if (cacheBlockNumber_ != blockNumber) { 118 | if (!cacheFlush()) return false; 119 | if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) return false; 120 | cacheBlockNumber_ = blockNumber; 121 | } 122 | cacheDirty_ |= action; 123 | return true; 124 | } 125 | //------------------------------------------------------------------------------ 126 | // cache a zero block for blockNumber 127 | uint8_t SdVolume::cacheZeroBlock(uint32_t blockNumber) { 128 | if (!cacheFlush()) return false; 129 | 130 | // loop take less flash than memset(cacheBuffer_.data, 0, 512); 131 | for (uint16_t i = 0; i < 512; i++) { 132 | cacheBuffer_.data[i] = 0; 133 | } 134 | cacheBlockNumber_ = blockNumber; 135 | cacheSetDirty(); 136 | return true; 137 | } 138 | //------------------------------------------------------------------------------ 139 | // return the size in bytes of a cluster chain 140 | uint8_t SdVolume::chainSize(uint32_t cluster, uint32_t* size) const { 141 | uint32_t s = 0; 142 | do { 143 | if (!fatGet(cluster, &cluster)) return false; 144 | s += 512UL << clusterSizeShift_; 145 | } while (!isEOC(cluster)); 146 | *size = s; 147 | return true; 148 | } 149 | //------------------------------------------------------------------------------ 150 | // Fetch a FAT entry 151 | uint8_t SdVolume::fatGet(uint32_t cluster, uint32_t* value) const { 152 | if (cluster > (clusterCount_ + 1)) return false; 153 | uint32_t lba = fatStartBlock_; 154 | lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7; 155 | if (lba != cacheBlockNumber_) { 156 | if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; 157 | } 158 | if (fatType_ == 16) { 159 | *value = cacheBuffer_.fat16[cluster & 0XFF]; 160 | } else { 161 | *value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK; 162 | } 163 | return true; 164 | } 165 | //------------------------------------------------------------------------------ 166 | // Store a FAT entry 167 | uint8_t SdVolume::fatPut(uint32_t cluster, uint32_t value) { 168 | // error if reserved cluster 169 | if (cluster < 2) return false; 170 | 171 | // error if not in FAT 172 | if (cluster > (clusterCount_ + 1)) return false; 173 | 174 | // calculate block address for entry 175 | uint32_t lba = fatStartBlock_; 176 | lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7; 177 | 178 | if (lba != cacheBlockNumber_) { 179 | if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false; 180 | } 181 | // store entry 182 | if (fatType_ == 16) { 183 | cacheBuffer_.fat16[cluster & 0XFF] = value; 184 | } else { 185 | cacheBuffer_.fat32[cluster & 0X7F] = value; 186 | } 187 | cacheSetDirty(); 188 | 189 | // mirror second FAT 190 | if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; 191 | return true; 192 | } 193 | //------------------------------------------------------------------------------ 194 | // free a cluster chain 195 | uint8_t SdVolume::freeChain(uint32_t cluster) { 196 | // clear free cluster location 197 | allocSearchStart_ = 2; 198 | 199 | do { 200 | uint32_t next; 201 | if (!fatGet(cluster, &next)) return false; 202 | 203 | // free cluster 204 | if (!fatPut(cluster, 0)) return false; 205 | 206 | cluster = next; 207 | } while (!isEOC(cluster)); 208 | 209 | return true; 210 | } 211 | //------------------------------------------------------------------------------ 212 | /** 213 | * Initialize a FAT volume. 214 | * 215 | * \param[in] dev The SD card where the volume is located. 216 | * 217 | * \param[in] part The partition to be used. Legal values for \a part are 218 | * 1-4 to use the corresponding partition on a device formatted with 219 | * a MBR, Master Boot Record, or zero if the device is formatted as 220 | * a super floppy with the FAT boot sector in block zero. 221 | * 222 | * \return The value one, true, is returned for success and 223 | * the value zero, false, is returned for failure. Reasons for 224 | * failure include not finding a valid partition, not finding a valid 225 | * FAT file system in the specified partition or an I/O error. 226 | */ 227 | uint8_t SdVolume::init(Sd2Card* dev, uint8_t part) { 228 | uint32_t volumeStartBlock = 0; 229 | sdCard_ = dev; 230 | // if part == 0 assume super floppy with FAT boot sector in block zero 231 | // if part > 0 assume mbr volume with partition table 232 | if (part) { 233 | if (part > 4)return false; 234 | if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false; 235 | part_t* p = &cacheBuffer_.mbr.part[part-1]; 236 | if ((p->boot & 0X7F) !=0 || 237 | p->totalSectors < 100 || 238 | p->firstSector == 0) { 239 | // not a valid partition 240 | return false; 241 | } 242 | volumeStartBlock = p->firstSector; 243 | } 244 | if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false; 245 | bpb_t* bpb = &cacheBuffer_.fbs.bpb; 246 | if (bpb->bytesPerSector != 512 || 247 | bpb->fatCount == 0 || 248 | bpb->reservedSectorCount == 0 || 249 | bpb->sectorsPerCluster == 0) { 250 | // not valid FAT volume 251 | return false; 252 | } 253 | fatCount_ = bpb->fatCount; 254 | blocksPerCluster_ = bpb->sectorsPerCluster; 255 | 256 | // determine shift that is same as multiply by blocksPerCluster_ 257 | clusterSizeShift_ = 0; 258 | while (blocksPerCluster_ != (1 << clusterSizeShift_)) { 259 | // error if not power of 2 260 | if (clusterSizeShift_++ > 7) return false; 261 | } 262 | blocksPerFat_ = bpb->sectorsPerFat16 ? 263 | bpb->sectorsPerFat16 : bpb->sectorsPerFat32; 264 | 265 | fatStartBlock_ = volumeStartBlock + bpb->reservedSectorCount; 266 | 267 | // count for FAT16 zero for FAT32 268 | rootDirEntryCount_ = bpb->rootDirEntryCount; 269 | 270 | // directory start for FAT16 dataStart for FAT32 271 | rootDirStart_ = fatStartBlock_ + bpb->fatCount * blocksPerFat_; 272 | 273 | // data start for FAT16 and FAT32 274 | dataStartBlock_ = rootDirStart_ + ((32 * bpb->rootDirEntryCount + 511)/512); 275 | 276 | // total blocks for FAT16 or FAT32 277 | uint32_t totalBlocks = bpb->totalSectors16 ? 278 | bpb->totalSectors16 : bpb->totalSectors32; 279 | // total data blocks 280 | clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock); 281 | 282 | // divide by cluster size to get cluster count 283 | clusterCount_ >>= clusterSizeShift_; 284 | 285 | // FAT type is determined by cluster count 286 | if (clusterCount_ < 4085) { 287 | fatType_ = 12; 288 | } else if (clusterCount_ < 65525) { 289 | fatType_ = 16; 290 | } else { 291 | rootDirStart_ = bpb->fat32RootCluster; 292 | fatType_ = 32; 293 | } 294 | return true; 295 | } 296 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/SD.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SD - a slightly more friendly wrapper for sdfatlib 4 | 5 | This library aims to expose a subset of SD card functionality 6 | in the form of a higher level "wrapper" object. 7 | 8 | License: GNU General Public License V3 9 | (Because sdfatlib is licensed with this.) 10 | 11 | (C) Copyright 2010 SparkFun Electronics 12 | 13 | 14 | This library provides four key benefits: 15 | 16 | * Including `SD.h` automatically creates a global 17 | `SD` object which can be interacted with in a similar 18 | manner to other standard global objects like `Serial` and `Ethernet`. 19 | 20 | * Boilerplate initialisation code is contained in one method named 21 | `begin` and no further objects need to be created in order to access 22 | the SD card. 23 | 24 | * Calls to `open` can supply a full path name including parent 25 | directories which simplifies interacting with files in subdirectories. 26 | 27 | * Utility methods are provided to determine whether a file exists 28 | and to create a directory heirarchy. 29 | 30 | 31 | Note however that not all functionality provided by the underlying 32 | sdfatlib library is exposed. 33 | 34 | */ 35 | 36 | /* 37 | 38 | Implementation Notes 39 | 40 | In order to handle multi-directory path traversal, functionality that 41 | requires this ability is implemented as callback functions. 42 | 43 | Individual methods call the `walkPath` function which performs the actual 44 | directory traversal (swapping between two different directory/file handles 45 | along the way) and at each level calls the supplied callback function. 46 | 47 | Some types of functionality will take an action at each level (e.g. exists 48 | or make directory) which others will only take an action at the bottom 49 | level (e.g. open). 50 | 51 | */ 52 | 53 | #include "SD.h" 54 | 55 | namespace SDLib { 56 | 57 | // Used by `getNextPathComponent` 58 | #define MAX_COMPONENT_LEN 12 // What is max length? 59 | #define PATH_COMPONENT_BUFFER_LEN MAX_COMPONENT_LEN+1 60 | 61 | bool getNextPathComponent(const char *path, unsigned int *p_offset, 62 | char *buffer) { 63 | /* 64 | 65 | Parse individual path components from a path. 66 | 67 | e.g. after repeated calls '/foo/bar/baz' will be split 68 | into 'foo', 'bar', 'baz'. 69 | 70 | This is similar to `strtok()` but copies the component into the 71 | supplied buffer rather than modifying the original string. 72 | 73 | 74 | `buffer` needs to be PATH_COMPONENT_BUFFER_LEN in size. 75 | 76 | `p_offset` needs to point to an integer of the offset at 77 | which the previous path component finished. 78 | 79 | Returns `true` if more components remain. 80 | 81 | Returns `false` if this is the last component. 82 | (This means path ended with 'foo' or 'foo/'.) 83 | 84 | */ 85 | 86 | // TODO: Have buffer local to this function, so we know it's the 87 | // correct length? 88 | 89 | int bufferOffset = 0; 90 | 91 | int offset = *p_offset; 92 | 93 | // Skip root or other separator 94 | if (path[offset] == '/') { 95 | offset++; 96 | } 97 | 98 | // Copy the next next path segment 99 | while (bufferOffset < MAX_COMPONENT_LEN 100 | && (path[offset] != '/') 101 | && (path[offset] != '\0')) { 102 | buffer[bufferOffset++] = path[offset++]; 103 | } 104 | 105 | buffer[bufferOffset] = '\0'; 106 | 107 | // Skip trailing separator so we can determine if this 108 | // is the last component in the path or not. 109 | if (path[offset] == '/') { 110 | offset++; 111 | } 112 | 113 | *p_offset = offset; 114 | 115 | return (path[offset] != '\0'); 116 | } 117 | 118 | 119 | 120 | boolean walkPath(const char *filepath, SdFile& parentDir, 121 | boolean (*callback)(SdFile& parentDir, 122 | const char *filePathComponent, 123 | boolean isLastComponent, 124 | void *object), 125 | void *object = NULL) { 126 | /* 127 | 128 | When given a file path (and parent directory--normally root), 129 | this function traverses the directories in the path and at each 130 | level calls the supplied callback function while also providing 131 | the supplied object for context if required. 132 | 133 | e.g. given the path '/foo/bar/baz' 134 | the callback would be called at the equivalent of 135 | '/foo', '/foo/bar' and '/foo/bar/baz'. 136 | 137 | The implementation swaps between two different directory/file 138 | handles as it traverses the directories and does not use recursion 139 | in an attempt to use memory efficiently. 140 | 141 | If a callback wishes to stop the directory traversal it should 142 | return false--in this case the function will stop the traversal, 143 | tidy up and return false. 144 | 145 | If a directory path doesn't exist at some point this function will 146 | also return false and not subsequently call the callback. 147 | 148 | If a directory path specified is complete, valid and the callback 149 | did not indicate the traversal should be interrupted then this 150 | function will return true. 151 | 152 | */ 153 | 154 | 155 | SdFile subfile1; 156 | SdFile subfile2; 157 | 158 | char buffer[PATH_COMPONENT_BUFFER_LEN]; 159 | 160 | unsigned int offset = 0; 161 | 162 | SdFile *p_parent; 163 | SdFile *p_child; 164 | 165 | SdFile *p_tmp_sdfile; 166 | 167 | p_child = &subfile1; 168 | 169 | p_parent = &parentDir; 170 | 171 | while (true) { 172 | 173 | boolean moreComponents = getNextPathComponent(filepath, &offset, buffer); 174 | 175 | boolean shouldContinue = callback((*p_parent), buffer, !moreComponents, object); 176 | 177 | if (!shouldContinue) { 178 | // TODO: Don't repeat this code? 179 | // If it's one we've created then we 180 | // don't need the parent handle anymore. 181 | if (p_parent != &parentDir) { 182 | (*p_parent).close(); 183 | } 184 | return false; 185 | } 186 | 187 | if (!moreComponents) { 188 | break; 189 | } 190 | 191 | boolean exists = (*p_child).open(*p_parent, buffer, O_RDONLY); 192 | 193 | // If it's one we've created then we 194 | // don't need the parent handle anymore. 195 | if (p_parent != &parentDir) { 196 | (*p_parent).close(); 197 | } 198 | 199 | // Handle case when it doesn't exist and we can't continue... 200 | if (exists) { 201 | // We alternate between two file handles as we go down 202 | // the path. 203 | if (p_parent == &parentDir) { 204 | p_parent = &subfile2; 205 | } 206 | 207 | p_tmp_sdfile = p_parent; 208 | p_parent = p_child; 209 | p_child = p_tmp_sdfile; 210 | } else { 211 | return false; 212 | } 213 | } 214 | 215 | if (p_parent != &parentDir) { 216 | (*p_parent).close(); // TODO: Return/ handle different? 217 | } 218 | 219 | return true; 220 | } 221 | 222 | 223 | 224 | /* 225 | 226 | The callbacks used to implement various functionality follow. 227 | 228 | Each callback is supplied with a parent directory handle, 229 | character string with the name of the current file path component, 230 | a flag indicating if this component is the last in the path and 231 | a pointer to an arbitrary object used for context. 232 | 233 | */ 234 | 235 | boolean callback_pathExists(SdFile& parentDir, const char *filePathComponent, 236 | boolean /* isLastComponent */, void * /* object */) { 237 | /* 238 | 239 | Callback used to determine if a file/directory exists in parent 240 | directory. 241 | 242 | Returns true if file path exists. 243 | 244 | */ 245 | SdFile child; 246 | 247 | boolean exists = child.open(parentDir, filePathComponent, O_RDONLY); 248 | 249 | if (exists) { 250 | child.close(); 251 | } 252 | 253 | return exists; 254 | } 255 | 256 | 257 | 258 | boolean callback_makeDirPath(SdFile& parentDir, const char *filePathComponent, 259 | boolean isLastComponent, void *object) { 260 | /* 261 | 262 | Callback used to create a directory in the parent directory if 263 | it does not already exist. 264 | 265 | Returns true if a directory was created or it already existed. 266 | 267 | */ 268 | boolean result = false; 269 | SdFile child; 270 | 271 | result = callback_pathExists(parentDir, filePathComponent, isLastComponent, object); 272 | if (!result) { 273 | result = child.makeDir(parentDir, filePathComponent); 274 | } 275 | 276 | return result; 277 | } 278 | 279 | 280 | /* 281 | 282 | boolean callback_openPath(SdFile& parentDir, char *filePathComponent, 283 | boolean isLastComponent, void *object) { 284 | 285 | Callback used to open a file specified by a filepath that may 286 | specify one or more directories above it. 287 | 288 | Expects the context object to be an instance of `SDClass` and 289 | will use the `file` property of the instance to open the requested 290 | file/directory with the associated file open mode property. 291 | 292 | Always returns true if the directory traversal hasn't reached the 293 | bottom of the directory heirarchy. 294 | 295 | Returns false once the file has been opened--to prevent the traversal 296 | from descending further. (This may be unnecessary.) 297 | 298 | if (isLastComponent) { 299 | SDClass *p_SD = static_cast(object); 300 | p_SD->file.open(parentDir, filePathComponent, p_SD->fileOpenMode); 301 | if (p_SD->fileOpenMode == FILE_WRITE) { 302 | p_SD->file.seekSet(p_SD->file.fileSize()); 303 | } 304 | // TODO: Return file open result? 305 | return false; 306 | } 307 | return true; 308 | } 309 | */ 310 | 311 | 312 | 313 | boolean callback_remove(SdFile& parentDir, const char *filePathComponent, 314 | boolean isLastComponent, void * /* object */) { 315 | if (isLastComponent) { 316 | return SdFile::remove(parentDir, filePathComponent); 317 | } 318 | return true; 319 | } 320 | 321 | boolean callback_rmdir(SdFile& parentDir, const char *filePathComponent, 322 | boolean isLastComponent, void * /* object */) { 323 | if (isLastComponent) { 324 | SdFile f; 325 | if (!f.open(parentDir, filePathComponent, O_READ)) return false; 326 | return f.rmDir(); 327 | } 328 | return true; 329 | } 330 | 331 | 332 | 333 | /* Implementation of class used to create `SDCard` object. */ 334 | 335 | 336 | 337 | boolean SDClass::begin(uint8_t csPin) { 338 | /* 339 | 340 | Performs the initialisation required by the sdfatlib library. 341 | 342 | Return true if initialization succeeds, false otherwise. 343 | 344 | */ 345 | root.close(); 346 | return card.init(SPI_HALF_SPEED, csPin) && 347 | volume.init(card) && 348 | root.openRoot(volume); 349 | } 350 | 351 | boolean SDClass::begin(uint32_t clock, uint8_t csPin) { 352 | return card.init(SPI_HALF_SPEED, csPin) && 353 | card.setSpiClock(clock) && 354 | volume.init(card) && 355 | root.openRoot(volume); 356 | } 357 | 358 | // this little helper is used to traverse paths 359 | SdFile SDClass::getParentDir(const char *filepath, int *index) { 360 | // get parent directory 361 | SdFile d1 = root; // start with the mostparent, root! 362 | SdFile d2; 363 | 364 | // we'll use the pointers to swap between the two objects 365 | SdFile *parent = &d1; 366 | SdFile *subdir = &d2; 367 | 368 | const char *origpath = filepath; 369 | 370 | while (strchr(filepath, '/')) { 371 | 372 | // get rid of leading /'s 373 | if (filepath[0] == '/') { 374 | filepath++; 375 | continue; 376 | } 377 | 378 | if (! strchr(filepath, '/')) { 379 | // it was in the root directory, so leave now 380 | break; 381 | } 382 | 383 | // extract just the name of the next subdirectory 384 | uint8_t idx = strchr(filepath, '/') - filepath; 385 | if (idx > 12) 386 | idx = 12; // dont let them specify long names 387 | char subdirname[13]; 388 | strncpy(subdirname, filepath, idx); 389 | subdirname[idx] = 0; 390 | 391 | // close the subdir (we reuse them) if open 392 | subdir->close(); 393 | if (! subdir->open(parent, subdirname, O_READ)) { 394 | // failed to open one of the subdirectories 395 | return SdFile(); 396 | } 397 | // move forward to the next subdirectory 398 | filepath += idx; 399 | 400 | // we reuse the objects, close it. 401 | parent->close(); 402 | 403 | // swap the pointers 404 | SdFile *t = parent; 405 | parent = subdir; 406 | subdir = t; 407 | } 408 | 409 | *index = (int)(filepath - origpath); 410 | // parent is now the parent diretory of the file! 411 | return *parent; 412 | } 413 | 414 | 415 | File SDClass::open(const char *filepath, uint8_t mode) { 416 | /* 417 | 418 | Open the supplied file path for reading or writing. 419 | 420 | The file content can be accessed via the `file` property of 421 | the `SDClass` object--this property is currently 422 | a standard `SdFile` object from `sdfatlib`. 423 | 424 | Defaults to read only. 425 | 426 | If `write` is true, default action (when `append` is true) is to 427 | append data to the end of the file. 428 | 429 | If `append` is false then the file will be truncated first. 430 | 431 | If the file does not exist and it is opened for writing the file 432 | will be created. 433 | 434 | An attempt to open a file for reading that does not exist is an 435 | error. 436 | 437 | */ 438 | 439 | int pathidx; 440 | 441 | // do the interative search 442 | SdFile parentdir = getParentDir(filepath, &pathidx); 443 | // no more subdirs! 444 | 445 | filepath += pathidx; 446 | 447 | if (! filepath[0]) { 448 | // it was the directory itself! 449 | return File(parentdir, "/"); 450 | } 451 | 452 | // Open the file itself 453 | SdFile file; 454 | 455 | // failed to open a subdir! 456 | if (!parentdir.isOpen()) 457 | return File(); 458 | 459 | // there is a special case for the Root directory since its a static dir 460 | if (parentdir.isRoot()) { 461 | if ( ! file.open(root, filepath, mode)) { 462 | // failed to open the file :( 463 | return File(); 464 | } 465 | // dont close the root! 466 | } else { 467 | if ( ! file.open(parentdir, filepath, mode)) { 468 | return File(); 469 | } 470 | // close the parent 471 | parentdir.close(); 472 | } 473 | 474 | if (mode & (O_APPEND | O_WRITE)) 475 | file.seekSet(file.fileSize()); 476 | return File(file, filepath); 477 | } 478 | 479 | 480 | /* 481 | File SDClass::open(char *filepath, uint8_t mode) { 482 | // 483 | 484 | Open the supplied file path for reading or writing. 485 | 486 | The file content can be accessed via the `file` property of 487 | the `SDClass` object--this property is currently 488 | a standard `SdFile` object from `sdfatlib`. 489 | 490 | Defaults to read only. 491 | 492 | If `write` is true, default action (when `append` is true) is to 493 | append data to the end of the file. 494 | 495 | If `append` is false then the file will be truncated first. 496 | 497 | If the file does not exist and it is opened for writing the file 498 | will be created. 499 | 500 | An attempt to open a file for reading that does not exist is an 501 | error. 502 | 503 | // 504 | 505 | // TODO: Allow for read&write? (Possibly not, as it requires seek.) 506 | 507 | fileOpenMode = mode; 508 | walkPath(filepath, root, callback_openPath, this); 509 | 510 | return File(); 511 | 512 | } 513 | */ 514 | 515 | 516 | //boolean SDClass::close() { 517 | // /* 518 | // 519 | // Closes the file opened by the `open` method. 520 | // 521 | // */ 522 | // file.close(); 523 | //} 524 | 525 | 526 | boolean SDClass::exists(const char *filepath) { 527 | /* 528 | 529 | Returns true if the supplied file path exists. 530 | 531 | */ 532 | return walkPath(filepath, root, callback_pathExists); 533 | } 534 | 535 | 536 | //boolean SDClass::exists(char *filepath, SdFile& parentDir) { 537 | // /* 538 | // 539 | // Returns true if the supplied file path rooted at `parentDir` 540 | // exists. 541 | // 542 | // */ 543 | // return walkPath(filepath, parentDir, callback_pathExists); 544 | //} 545 | 546 | 547 | boolean SDClass::mkdir(const char *filepath) { 548 | /* 549 | 550 | Makes a single directory or a heirarchy of directories. 551 | 552 | A rough equivalent to `mkdir -p`. 553 | 554 | */ 555 | return walkPath(filepath, root, callback_makeDirPath); 556 | } 557 | 558 | boolean SDClass::rmdir(const char *filepath) { 559 | /* 560 | 561 | Remove a single directory or a heirarchy of directories. 562 | 563 | A rough equivalent to `rm -rf`. 564 | 565 | */ 566 | return walkPath(filepath, root, callback_rmdir); 567 | } 568 | 569 | boolean SDClass::remove(const char *filepath) { 570 | return walkPath(filepath, root, callback_remove); 571 | } 572 | 573 | 574 | // allows you to recurse into a directory 575 | File File::openNextFile(uint8_t mode) { 576 | dir_t p; 577 | 578 | //Serial.print("\t\treading dir..."); 579 | while (_file->readDir(&p) > 0) { 580 | 581 | // done if past last used entry 582 | if (p.name[0] == DIR_NAME_FREE) { 583 | //Serial.println("end"); 584 | return File(); 585 | } 586 | 587 | // skip deleted entry and entries for . and .. 588 | if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') { 589 | //Serial.println("dots"); 590 | continue; 591 | } 592 | 593 | // only list subdirectories and files 594 | if (!DIR_IS_FILE_OR_SUBDIR(&p)) { 595 | //Serial.println("notafile"); 596 | continue; 597 | } 598 | 599 | // print file name with possible blank fill 600 | SdFile f; 601 | char name[13]; 602 | _file->dirName(p, name); 603 | //Serial.print("try to open file "); 604 | //Serial.println(name); 605 | 606 | if (f.open(_file, name, mode)) { 607 | //Serial.println("OK!"); 608 | return File(f, name); 609 | } else { 610 | //Serial.println("ugh"); 611 | return File(); 612 | } 613 | } 614 | 615 | //Serial.println("nothing"); 616 | return File(); 617 | } 618 | 619 | void File::rewindDirectory(void) { 620 | if (isDirectory()) 621 | _file->rewind(); 622 | } 623 | 624 | SDClass SD; 625 | 626 | }; 627 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/utility/FatStructs.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2009 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef FatStructs_h 21 | #define FatStructs_h 22 | /** 23 | * \file 24 | * FAT file structures 25 | */ 26 | /* 27 | * mostly from Microsoft document fatgen103.doc 28 | * http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx 29 | */ 30 | //------------------------------------------------------------------------------ 31 | /** Value for byte 510 of boot block or MBR */ 32 | uint8_t const BOOTSIG0 = 0X55; 33 | /** Value for byte 511 of boot block or MBR */ 34 | uint8_t const BOOTSIG1 = 0XAA; 35 | //------------------------------------------------------------------------------ 36 | /** 37 | * \struct partitionTable 38 | * \brief MBR partition table entry 39 | * 40 | * A partition table entry for a MBR formatted storage device. 41 | * The MBR partition table has four entries. 42 | */ 43 | struct partitionTable { 44 | /** 45 | * Boot Indicator . Indicates whether the volume is the active 46 | * partition. Legal values include: 0X00. Do not use for booting. 47 | * 0X80 Active partition. 48 | */ 49 | uint8_t boot; 50 | /** 51 | * Head part of Cylinder-head-sector address of the first block in 52 | * the partition. Legal values are 0-255. Only used in old PC BIOS. 53 | */ 54 | uint8_t beginHead; 55 | /** 56 | * Sector part of Cylinder-head-sector address of the first block in 57 | * the partition. Legal values are 1-63. Only used in old PC BIOS. 58 | */ 59 | unsigned beginSector : 6; 60 | /** High bits cylinder for first block in partition. */ 61 | unsigned beginCylinderHigh : 2; 62 | /** 63 | * Combine beginCylinderLow with beginCylinderHigh. Legal values 64 | * are 0-1023. Only used in old PC BIOS. 65 | */ 66 | uint8_t beginCylinderLow; 67 | /** 68 | * Partition type. See defines that begin with PART_TYPE_ for 69 | * some Microsoft partition types. 70 | */ 71 | uint8_t type; 72 | /** 73 | * head part of cylinder-head-sector address of the last sector in the 74 | * partition. Legal values are 0-255. Only used in old PC BIOS. 75 | */ 76 | uint8_t endHead; 77 | /** 78 | * Sector part of cylinder-head-sector address of the last sector in 79 | * the partition. Legal values are 1-63. Only used in old PC BIOS. 80 | */ 81 | unsigned endSector : 6; 82 | /** High bits of end cylinder */ 83 | unsigned endCylinderHigh : 2; 84 | /** 85 | * Combine endCylinderLow with endCylinderHigh. Legal values 86 | * are 0-1023. Only used in old PC BIOS. 87 | */ 88 | uint8_t endCylinderLow; 89 | /** Logical block address of the first block in the partition. */ 90 | uint32_t firstSector; 91 | /** Length of the partition, in blocks. */ 92 | uint32_t totalSectors; 93 | } __attribute__((packed)); 94 | /** Type name for partitionTable */ 95 | typedef struct partitionTable part_t; 96 | //------------------------------------------------------------------------------ 97 | /** 98 | * \struct masterBootRecord 99 | * 100 | * \brief Master Boot Record 101 | * 102 | * The first block of a storage device that is formatted with a MBR. 103 | */ 104 | struct masterBootRecord { 105 | /** Code Area for master boot program. */ 106 | uint8_t codeArea[440]; 107 | /** Optional WindowsNT disk signature. May contain more boot code. */ 108 | uint32_t diskSignature; 109 | /** Usually zero but may be more boot code. */ 110 | uint16_t usuallyZero; 111 | /** Partition tables. */ 112 | part_t part[4]; 113 | /** First MBR signature byte. Must be 0X55 */ 114 | uint8_t mbrSig0; 115 | /** Second MBR signature byte. Must be 0XAA */ 116 | uint8_t mbrSig1; 117 | } __attribute__((packed)); 118 | /** Type name for masterBootRecord */ 119 | typedef struct masterBootRecord mbr_t; 120 | //------------------------------------------------------------------------------ 121 | /** 122 | * \struct biosParmBlock 123 | * 124 | * \brief BIOS parameter block 125 | * 126 | * The BIOS parameter block describes the physical layout of a FAT volume. 127 | */ 128 | struct biosParmBlock { 129 | /** 130 | * Count of bytes per sector. This value may take on only the 131 | * following values: 512, 1024, 2048 or 4096 132 | */ 133 | uint16_t bytesPerSector; 134 | /** 135 | * Number of sectors per allocation unit. This value must be a 136 | * power of 2 that is greater than 0. The legal values are 137 | * 1, 2, 4, 8, 16, 32, 64, and 128. 138 | */ 139 | uint8_t sectorsPerCluster; 140 | /** 141 | * Number of sectors before the first FAT. 142 | * This value must not be zero. 143 | */ 144 | uint16_t reservedSectorCount; 145 | /** The count of FAT data structures on the volume. This field should 146 | * always contain the value 2 for any FAT volume of any type. 147 | */ 148 | uint8_t fatCount; 149 | /** 150 | * For FAT12 and FAT16 volumes, this field contains the count of 151 | * 32-byte directory entries in the root directory. For FAT32 volumes, 152 | * this field must be set to 0. For FAT12 and FAT16 volumes, this 153 | * value should always specify a count that when multiplied by 32 154 | * results in a multiple of bytesPerSector. FAT16 volumes should 155 | * use the value 512. 156 | */ 157 | uint16_t rootDirEntryCount; 158 | /** 159 | * This field is the old 16-bit total count of sectors on the volume. 160 | * This count includes the count of all sectors in all four regions 161 | * of the volume. This field can be 0; if it is 0, then totalSectors32 162 | * must be non-zero. For FAT32 volumes, this field must be 0. For 163 | * FAT12 and FAT16 volumes, this field contains the sector count, and 164 | * totalSectors32 is 0 if the total sector count fits 165 | * (is less than 0x10000). 166 | */ 167 | uint16_t totalSectors16; 168 | /** 169 | * This dates back to the old MS-DOS 1.x media determination and is 170 | * no longer usually used for anything. 0xF8 is the standard value 171 | * for fixed (non-removable) media. For removable media, 0xF0 is 172 | * frequently used. Legal values are 0xF0 or 0xF8-0xFF. 173 | */ 174 | uint8_t mediaType; 175 | /** 176 | * Count of sectors occupied by one FAT on FAT12/FAT16 volumes. 177 | * On FAT32 volumes this field must be 0, and sectorsPerFat32 178 | * contains the FAT size count. 179 | */ 180 | uint16_t sectorsPerFat16; 181 | /** Sectors per track for interrupt 0x13. Not used otherwise. */ 182 | uint16_t sectorsPerTrtack; 183 | /** Number of heads for interrupt 0x13. Not used otherwise. */ 184 | uint16_t headCount; 185 | /** 186 | * Count of hidden sectors preceding the partition that contains this 187 | * FAT volume. This field is generally only relevant for media 188 | * visible on interrupt 0x13. 189 | */ 190 | uint32_t hidddenSectors; 191 | /** 192 | * This field is the new 32-bit total count of sectors on the volume. 193 | * This count includes the count of all sectors in all four regions 194 | * of the volume. This field can be 0; if it is 0, then 195 | * totalSectors16 must be non-zero. 196 | */ 197 | uint32_t totalSectors32; 198 | /** 199 | * Count of sectors occupied by one FAT on FAT32 volumes. 200 | */ 201 | uint32_t sectorsPerFat32; 202 | /** 203 | * This field is only defined for FAT32 media and does not exist on 204 | * FAT12 and FAT16 media. 205 | * Bits 0-3 -- Zero-based number of active FAT. 206 | * Only valid if mirroring is disabled. 207 | * Bits 4-6 -- Reserved. 208 | * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. 209 | * -- 1 means only one FAT is active; it is the one referenced in bits 0-3. 210 | * Bits 8-15 -- Reserved. 211 | */ 212 | uint16_t fat32Flags; 213 | /** 214 | * FAT32 version. High byte is major revision number. 215 | * Low byte is minor revision number. Only 0.0 define. 216 | */ 217 | uint16_t fat32Version; 218 | /** 219 | * Cluster number of the first cluster of the root directory for FAT32. 220 | * This usually 2 but not required to be 2. 221 | */ 222 | uint32_t fat32RootCluster; 223 | /** 224 | * Sector number of FSINFO structure in the reserved area of the 225 | * FAT32 volume. Usually 1. 226 | */ 227 | uint16_t fat32FSInfo; 228 | /** 229 | * If non-zero, indicates the sector number in the reserved area 230 | * of the volume of a copy of the boot record. Usually 6. 231 | * No value other than 6 is recommended. 232 | */ 233 | uint16_t fat32BackBootBlock; 234 | /** 235 | * Reserved for future expansion. Code that formats FAT32 volumes 236 | * should always set all of the bytes of this field to 0. 237 | */ 238 | uint8_t fat32Reserved[12]; 239 | } __attribute__((packed)); 240 | /** Type name for biosParmBlock */ 241 | typedef struct biosParmBlock bpb_t; 242 | //------------------------------------------------------------------------------ 243 | /** 244 | * \struct fat32BootSector 245 | * 246 | * \brief Boot sector for a FAT16 or FAT32 volume. 247 | * 248 | */ 249 | struct fat32BootSector { 250 | /** X86 jmp to boot program */ 251 | uint8_t jmpToBootCode[3]; 252 | /** informational only - don't depend on it */ 253 | char oemName[8]; 254 | /** BIOS Parameter Block */ 255 | bpb_t bpb; 256 | /** for int0x13 use value 0X80 for hard drive */ 257 | uint8_t driveNumber; 258 | /** used by Windows NT - should be zero for FAT */ 259 | uint8_t reserved1; 260 | /** 0X29 if next three fields are valid */ 261 | uint8_t bootSignature; 262 | /** usually generated by combining date and time */ 263 | uint32_t volumeSerialNumber; 264 | /** should match volume label in root dir */ 265 | char volumeLabel[11]; 266 | /** informational only - don't depend on it */ 267 | char fileSystemType[8]; 268 | /** X86 boot code */ 269 | uint8_t bootCode[420]; 270 | /** must be 0X55 */ 271 | uint8_t bootSectorSig0; 272 | /** must be 0XAA */ 273 | uint8_t bootSectorSig1; 274 | } __attribute__((packed)); 275 | //------------------------------------------------------------------------------ 276 | // End Of Chain values for FAT entries 277 | /** FAT16 end of chain value used by Microsoft. */ 278 | uint16_t const FAT16EOC = 0XFFFF; 279 | /** Minimum value for FAT16 EOC. Use to test for EOC. */ 280 | uint16_t const FAT16EOC_MIN = 0XFFF8; 281 | /** FAT32 end of chain value used by Microsoft. */ 282 | uint32_t const FAT32EOC = 0X0FFFFFFF; 283 | /** Minimum value for FAT32 EOC. Use to test for EOC. */ 284 | uint32_t const FAT32EOC_MIN = 0X0FFFFFF8; 285 | /** Mask a for FAT32 entry. Entries are 28 bits. */ 286 | uint32_t const FAT32MASK = 0X0FFFFFFF; 287 | 288 | /** Type name for fat32BootSector */ 289 | typedef struct fat32BootSector fbs_t; 290 | //------------------------------------------------------------------------------ 291 | /** 292 | * \struct directoryEntry 293 | * \brief FAT short directory entry 294 | * 295 | * Short means short 8.3 name, not the entry size. 296 | * 297 | * Date Format. A FAT directory entry date stamp is a 16-bit field that is 298 | * basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the 299 | * format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 300 | * 16-bit word): 301 | * 302 | * Bits 9-15: Count of years from 1980, valid value range 0-127 303 | * inclusive (1980-2107). 304 | * 305 | * Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. 306 | * 307 | * Bits 0-4: Day of month, valid value range 1-31 inclusive. 308 | * 309 | * Time Format. A FAT directory entry time stamp is a 16-bit field that has 310 | * a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the 311 | * 16-bit word, bit 15 is the MSB of the 16-bit word). 312 | * 313 | * Bits 11-15: Hours, valid value range 0-23 inclusive. 314 | * 315 | * Bits 5-10: Minutes, valid value range 0-59 inclusive. 316 | * 317 | * Bits 0-4: 2-second count, valid value range 0-29 inclusive (0 - 58 seconds). 318 | * 319 | * The valid time range is from Midnight 00:00:00 to 23:59:58. 320 | */ 321 | struct directoryEntry { 322 | /** 323 | * Short 8.3 name. 324 | * The first eight bytes contain the file name with blank fill. 325 | * The last three bytes contain the file extension with blank fill. 326 | */ 327 | uint8_t name[11]; 328 | /** Entry attributes. 329 | * 330 | * The upper two bits of the attribute byte are reserved and should 331 | * always be set to 0 when a file is created and never modified or 332 | * looked at after that. See defines that begin with DIR_ATT_. 333 | */ 334 | uint8_t attributes; 335 | /** 336 | * Reserved for use by Windows NT. Set value to 0 when a file is 337 | * created and never modify or look at it after that. 338 | */ 339 | uint8_t reservedNT; 340 | /** 341 | * The granularity of the seconds part of creationTime is 2 seconds 342 | * so this field is a count of tenths of a second and its valid 343 | * value range is 0-199 inclusive. (WHG note - seems to be hundredths) 344 | */ 345 | uint8_t creationTimeTenths; 346 | /** Time file was created. */ 347 | uint16_t creationTime; 348 | /** Date file was created. */ 349 | uint16_t creationDate; 350 | /** 351 | * Last access date. Note that there is no last access time, only 352 | * a date. This is the date of last read or write. In the case of 353 | * a write, this should be set to the same date as lastWriteDate. 354 | */ 355 | uint16_t lastAccessDate; 356 | /** 357 | * High word of this entry's first cluster number (always 0 for a 358 | * FAT12 or FAT16 volume). 359 | */ 360 | uint16_t firstClusterHigh; 361 | /** Time of last write. File creation is considered a write. */ 362 | uint16_t lastWriteTime; 363 | /** Date of last write. File creation is considered a write. */ 364 | uint16_t lastWriteDate; 365 | /** Low word of this entry's first cluster number. */ 366 | uint16_t firstClusterLow; 367 | /** 32-bit unsigned holding this file's size in bytes. */ 368 | uint32_t fileSize; 369 | } __attribute__((packed)); 370 | //------------------------------------------------------------------------------ 371 | // Definitions for directory entries 372 | // 373 | /** Type name for directoryEntry */ 374 | typedef struct directoryEntry dir_t; 375 | /** escape for name[0] = 0XE5 */ 376 | uint8_t const DIR_NAME_0XE5 = 0X05; 377 | /** name[0] value for entry that is free after being "deleted" */ 378 | uint8_t const DIR_NAME_DELETED = 0XE5; 379 | /** name[0] value for entry that is free and no allocated entries follow */ 380 | uint8_t const DIR_NAME_FREE = 0X00; 381 | /** file is read-only */ 382 | uint8_t const DIR_ATT_READ_ONLY = 0X01; 383 | /** File should hidden in directory listings */ 384 | uint8_t const DIR_ATT_HIDDEN = 0X02; 385 | /** Entry is for a system file */ 386 | uint8_t const DIR_ATT_SYSTEM = 0X04; 387 | /** Directory entry contains the volume label */ 388 | uint8_t const DIR_ATT_VOLUME_ID = 0X08; 389 | /** Entry is for a directory */ 390 | uint8_t const DIR_ATT_DIRECTORY = 0X10; 391 | /** Old DOS archive bit for backup support */ 392 | uint8_t const DIR_ATT_ARCHIVE = 0X20; 393 | /** Test value for long name entry. Test is 394 | (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */ 395 | uint8_t const DIR_ATT_LONG_NAME = 0X0F; 396 | /** Test mask for long name entry */ 397 | uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F; 398 | /** defined attribute bits */ 399 | uint8_t const DIR_ATT_DEFINED_BITS = 0X3F; 400 | /** Directory entry is part of a long name */ 401 | static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) { 402 | return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME; 403 | } 404 | /** Mask for file/subdirectory tests */ 405 | uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY); 406 | /** Directory entry is for a file */ 407 | static inline uint8_t DIR_IS_FILE(const dir_t* dir) { 408 | return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0; 409 | } 410 | /** Directory entry is for a subdirectory */ 411 | static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) { 412 | return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY; 413 | } 414 | /** Directory entry is for a file or subdirectory */ 415 | static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) { 416 | return (dir->attributes & DIR_ATT_VOLUME_ID) == 0; 417 | } 418 | #endif // FatStructs_h 419 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/utility/Sd2PinMap.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2010 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #if defined(__arm__) // Arduino Due Board follows 21 | 22 | #ifndef Sd2PinMap_h 23 | #define Sd2PinMap_h 24 | 25 | #include 26 | 27 | uint8_t const SS_PIN = SS; 28 | uint8_t const MOSI_PIN = MOSI; 29 | uint8_t const MISO_PIN = MISO; 30 | uint8_t const SCK_PIN = SCK; 31 | 32 | #endif // Sd2PinMap_h 33 | 34 | #elif defined(__AVR__) // Other AVR based Boards follows 35 | 36 | // Warning this file was generated by a program. 37 | #ifndef Sd2PinMap_h 38 | #define Sd2PinMap_h 39 | #include 40 | 41 | //------------------------------------------------------------------------------ 42 | /** struct for mapping digital pins */ 43 | struct pin_map_t { 44 | volatile uint8_t* ddr; 45 | volatile uint8_t* pin; 46 | volatile uint8_t* port; 47 | uint8_t bit; 48 | }; 49 | //------------------------------------------------------------------------------ 50 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 51 | // Mega 52 | 53 | // Two Wire (aka I2C) ports 54 | uint8_t const SDA_PIN = 20; 55 | uint8_t const SCL_PIN = 21; 56 | 57 | // SPI port 58 | uint8_t const SS_PIN = 53; 59 | uint8_t const MOSI_PIN = 51; 60 | uint8_t const MISO_PIN = 50; 61 | uint8_t const SCK_PIN = 52; 62 | 63 | static const pin_map_t digitalPinMap[] = { 64 | {&DDRE, &PINE, &PORTE, 0}, // E0 0 65 | {&DDRE, &PINE, &PORTE, 1}, // E1 1 66 | {&DDRE, &PINE, &PORTE, 4}, // E4 2 67 | {&DDRE, &PINE, &PORTE, 5}, // E5 3 68 | {&DDRG, &PING, &PORTG, 5}, // G5 4 69 | {&DDRE, &PINE, &PORTE, 3}, // E3 5 70 | {&DDRH, &PINH, &PORTH, 3}, // H3 6 71 | {&DDRH, &PINH, &PORTH, 4}, // H4 7 72 | {&DDRH, &PINH, &PORTH, 5}, // H5 8 73 | {&DDRH, &PINH, &PORTH, 6}, // H6 9 74 | {&DDRB, &PINB, &PORTB, 4}, // B4 10 75 | {&DDRB, &PINB, &PORTB, 5}, // B5 11 76 | {&DDRB, &PINB, &PORTB, 6}, // B6 12 77 | {&DDRB, &PINB, &PORTB, 7}, // B7 13 78 | {&DDRJ, &PINJ, &PORTJ, 1}, // J1 14 79 | {&DDRJ, &PINJ, &PORTJ, 0}, // J0 15 80 | {&DDRH, &PINH, &PORTH, 1}, // H1 16 81 | {&DDRH, &PINH, &PORTH, 0}, // H0 17 82 | {&DDRD, &PIND, &PORTD, 3}, // D3 18 83 | {&DDRD, &PIND, &PORTD, 2}, // D2 19 84 | {&DDRD, &PIND, &PORTD, 1}, // D1 20 85 | {&DDRD, &PIND, &PORTD, 0}, // D0 21 86 | {&DDRA, &PINA, &PORTA, 0}, // A0 22 87 | {&DDRA, &PINA, &PORTA, 1}, // A1 23 88 | {&DDRA, &PINA, &PORTA, 2}, // A2 24 89 | {&DDRA, &PINA, &PORTA, 3}, // A3 25 90 | {&DDRA, &PINA, &PORTA, 4}, // A4 26 91 | {&DDRA, &PINA, &PORTA, 5}, // A5 27 92 | {&DDRA, &PINA, &PORTA, 6}, // A6 28 93 | {&DDRA, &PINA, &PORTA, 7}, // A7 29 94 | {&DDRC, &PINC, &PORTC, 7}, // C7 30 95 | {&DDRC, &PINC, &PORTC, 6}, // C6 31 96 | {&DDRC, &PINC, &PORTC, 5}, // C5 32 97 | {&DDRC, &PINC, &PORTC, 4}, // C4 33 98 | {&DDRC, &PINC, &PORTC, 3}, // C3 34 99 | {&DDRC, &PINC, &PORTC, 2}, // C2 35 100 | {&DDRC, &PINC, &PORTC, 1}, // C1 36 101 | {&DDRC, &PINC, &PORTC, 0}, // C0 37 102 | {&DDRD, &PIND, &PORTD, 7}, // D7 38 103 | {&DDRG, &PING, &PORTG, 2}, // G2 39 104 | {&DDRG, &PING, &PORTG, 1}, // G1 40 105 | {&DDRG, &PING, &PORTG, 0}, // G0 41 106 | {&DDRL, &PINL, &PORTL, 7}, // L7 42 107 | {&DDRL, &PINL, &PORTL, 6}, // L6 43 108 | {&DDRL, &PINL, &PORTL, 5}, // L5 44 109 | {&DDRL, &PINL, &PORTL, 4}, // L4 45 110 | {&DDRL, &PINL, &PORTL, 3}, // L3 46 111 | {&DDRL, &PINL, &PORTL, 2}, // L2 47 112 | {&DDRL, &PINL, &PORTL, 1}, // L1 48 113 | {&DDRL, &PINL, &PORTL, 0}, // L0 49 114 | {&DDRB, &PINB, &PORTB, 3}, // B3 50 115 | {&DDRB, &PINB, &PORTB, 2}, // B2 51 116 | {&DDRB, &PINB, &PORTB, 1}, // B1 52 117 | {&DDRB, &PINB, &PORTB, 0}, // B0 53 118 | {&DDRF, &PINF, &PORTF, 0}, // F0 54 119 | {&DDRF, &PINF, &PORTF, 1}, // F1 55 120 | {&DDRF, &PINF, &PORTF, 2}, // F2 56 121 | {&DDRF, &PINF, &PORTF, 3}, // F3 57 122 | {&DDRF, &PINF, &PORTF, 4}, // F4 58 123 | {&DDRF, &PINF, &PORTF, 5}, // F5 59 124 | {&DDRF, &PINF, &PORTF, 6}, // F6 60 125 | {&DDRF, &PINF, &PORTF, 7}, // F7 61 126 | {&DDRK, &PINK, &PORTK, 0}, // K0 62 127 | {&DDRK, &PINK, &PORTK, 1}, // K1 63 128 | {&DDRK, &PINK, &PORTK, 2}, // K2 64 129 | {&DDRK, &PINK, &PORTK, 3}, // K3 65 130 | {&DDRK, &PINK, &PORTK, 4}, // K4 66 131 | {&DDRK, &PINK, &PORTK, 5}, // K5 67 132 | {&DDRK, &PINK, &PORTK, 6}, // K6 68 133 | {&DDRK, &PINK, &PORTK, 7} // K7 69 134 | }; 135 | //------------------------------------------------------------------------------ 136 | #elif (defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && defined(CORE_MICRODUINO) 137 | // Microduino Core+ 138 | 139 | // Two Wire (aka I2C) ports 140 | uint8_t const SDA_PIN = 20; 141 | uint8_t const SCL_PIN = 21; 142 | 143 | // SPI port 144 | uint8_t const SS_PIN = 10; 145 | uint8_t const MOSI_PIN = 11; 146 | uint8_t const MISO_PIN = 12; 147 | uint8_t const SCK_PIN = 13; 148 | 149 | static const pin_map_t digitalPinMap[] = { 150 | {&DDRD, &PIND, &PORTD, 0}, // D0 PD0 151 | {&DDRD, &PIND, &PORTD, 1}, // D1 PD1 152 | {&DDRD, &PIND, &PORTD, 2}, // D2 PD2 153 | {&DDRD, &PIND, &PORTD, 3}, // D3 PD3 154 | {&DDRB, &PINB, &PORTB, 0}, // D4 PB0 155 | {&DDRB, &PINB, &PORTB, 1}, // D5 PB1 156 | {&DDRB, &PINB, &PORTB, 2}, // D6 PB2 157 | {&DDRB, &PINB, &PORTB, 3}, // D7 PB3 158 | {&DDRD, &PIND, &PORTD, 6}, // D8 PD6 159 | {&DDRD, &PIND, &PORTD, 5}, // D9 PD5 160 | {&DDRB, &PINB, &PORTB, 4}, // D10 PB4 161 | {&DDRB, &PINB, &PORTB, 5}, // D11 PB5 162 | {&DDRB, &PINB, &PORTB, 6}, // D12 PB6 163 | {&DDRB, &PINB, &PORTB, 7}, // D13 PB7 164 | {&DDRC, &PINC, &PORTC, 7}, // D14 PC7 165 | {&DDRC, &PINC, &PORTC, 6}, // D15 PC6 166 | {&DDRC, &PINC, &PORTC, 5}, // D16 PC5 167 | {&DDRC, &PINC, &PORTC, 4}, // D17 PC4 168 | {&DDRC, &PINC, &PORTC, 3}, // D18 PC3 169 | {&DDRC, &PINC, &PORTC, 2}, // D19 PC2 170 | {&DDRC, &PINC, &PORTC, 1}, // D20 PC1 171 | {&DDRC, &PINC, &PORTC, 0}, // D21 PC0 172 | {&DDRD, &PIND, &PORTD, 4}, // D22 PD4 173 | {&DDRD, &PIND, &PORTD, 7}, // D23 PD7 174 | {&DDRA, &PINA, &PORTA, 7}, // D24 PA7 175 | {&DDRA, &PINA, &PORTA, 6}, // D25 PA6 176 | {&DDRA, &PINA, &PORTA, 5}, // D26 PA5 177 | {&DDRA, &PINA, &PORTA, 4}, // D27 PA4 178 | {&DDRA, &PINA, &PORTA, 3}, // D28 PA3 179 | {&DDRA, &PINA, &PORTA, 2}, // D29 PA2 180 | {&DDRA, &PINA, &PORTA, 1}, // D30 PA1 181 | {&DDRA, &PINA, &PORTA, 0} // D31 PA0 182 | }; 183 | //------------------------------------------------------------------------------ 184 | #elif defined(__AVR_ATmega128RFA1__) && defined(CORE_MICRODUINO) 185 | // Microduino Core RF 186 | 187 | // Two Wire (aka I2C) ports 188 | uint8_t const SDA_PIN = 18; 189 | uint8_t const SCL_PIN = 19; 190 | 191 | // SPI port 192 | uint8_t const SS_PIN = 10; 193 | uint8_t const MOSI_PIN = 11; 194 | uint8_t const MISO_PIN = 12; 195 | uint8_t const SCK_PIN = 13; 196 | 197 | static const pin_map_t digitalPinMap[] = { 198 | {&DDRD, &PINE, &PORTE, 0}, // D0 PE0 199 | {&DDRD, &PINE, &PORTE, 1}, // D1 PE1 200 | {&DDRD, &PIND, &PORTD, 2}, // D2 PD2 201 | {&DDRD, &PIND, &PORTD, 3}, // D3 PD3 202 | {&DDRB, &PINE, &PORTE, 3}, // D4 PE3 203 | {&DDRB, &PINE, &PORTE, 4}, // D5 PE4 204 | {&DDRB, &PINE, &PORTE, 5}, // D6 PE5 205 | {&DDRB, &PINB, &PORTB, 7}, // D7 PB7 206 | {&DDRD, &PINB, &PORTB, 6}, // D8 PB6 207 | {&DDRD, &PINB, &PORTB, 5}, // D9 PB5 208 | {&DDRB, &PINB, &PORTB, 4}, // D10 PB4 209 | {&DDRB, &PINB, &PORTB, 2}, // D11 PB2 210 | {&DDRB, &PINB, &PORTB, 3}, // D12 PB3 211 | {&DDRB, &PINB, &PORTB, 1}, // D13 PB1 212 | {&DDRF, &PINF, &PORTF, 7}, // D14 PF7 213 | {&DDRF, &PINF, &PORTF, 6}, // D15 PF6 214 | {&DDRF, &PINF, &PORTF, 5}, // D16 PF5 215 | {&DDRF, &PINF, &PORTF, 4}, // D17 PF4 216 | {&DDRD, &PIND, &PORTD, 1}, // D18 PD1 217 | {&DDRD, &PIND, &PORTD, 0}, // D19 PD0 218 | {&DDRF, &PINF, &PORTF, 3}, // D20 PF3 219 | {&DDRF, &PINF, &PORTF, 2}, // D21 PF2 220 | }; 221 | //------------------------------------------------------------------------------ 222 | #elif defined(__AVR_ATmega32U4__) && defined(CORE_MICRODUINO) 223 | // Microduino Core USB 224 | 225 | // Two Wire (aka I2C) ports 226 | uint8_t const SDA_PIN = 18; 227 | uint8_t const SCL_PIN = 19; 228 | 229 | // SPI port 230 | uint8_t const SS_PIN = 10; 231 | uint8_t const MOSI_PIN = 11; 232 | uint8_t const MISO_PIN = 12; 233 | uint8_t const SCK_PIN = 13; 234 | 235 | static const pin_map_t digitalPinMap[] = { 236 | {&DDRD, &PIND, &PORTD, 2}, // D0 - PD2 237 | {&DDRD, &PIND, &PORTD, 3}, // D1 - PD3 238 | {&DDRE, &PINE, &PORTE, 6}, // D2 - PE6 239 | {&DDRD, &PIND, &PORTD, 6}, // D3 - PD6 240 | {&DDRD, &PIND, &PORTD, 7}, // D4 - PD7 241 | {&DDRC, &PINC, &PORTC, 6}, // D5 - PC6 242 | {&DDRC, &PINC, &PORTC, 7}, // D6 - PC7 243 | {&DDRE, &PINE, &PORTE, 7}, // D7 - PE7 244 | {&DDRB, &PINB, &PORTB, 6}, // D8 - PB6 245 | {&DDRB, &PINB, &PORTB, 5}, // D9 - PB5 246 | {&DDRB, &PINB, &PORTB, 0}, // D10 - PB0 247 | {&DDRB, &PINB, &PORTB, 2}, // D11 - MOSI - PB2 248 | {&DDRB, &PINB, &PORTB, 3}, // D12 -MISO - PB3 249 | {&DDRB, &PINB, &PORTB, 1}, // D13 -SCK - PB1 250 | {&DDRF, &PINF, &PORTF, 7}, // D14 - A0 - PF7 251 | {&DDRF, &PINF, &PORTF, 6}, // D15 - A1 - PF6 252 | {&DDRF, &PINF, &PORTF, 5}, // D16 - A2 - PF5 253 | {&DDRF, &PINF, &PORTF, 4}, // D17 - A3 - PF4 254 | {&DDRD, &PIND, &PORTD, 1}, // D18 - PD1 255 | {&DDRD, &PIND, &PORTD, 0}, // D19 - PD0 256 | {&DDRF, &PINF, &PORTF, 1}, // D20 - A6 - PF1 257 | {&DDRF, &PINF, &PORTF, 0}, // D21 - A7 - PF0 258 | }; 259 | //------------------------------------------------------------------------------ 260 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) 261 | // Sanguino 262 | 263 | // Two Wire (aka I2C) ports 264 | uint8_t const SDA_PIN = 17; 265 | uint8_t const SCL_PIN = 18; 266 | 267 | // SPI port 268 | uint8_t const SS_PIN = 4; 269 | uint8_t const MOSI_PIN = 5; 270 | uint8_t const MISO_PIN = 6; 271 | uint8_t const SCK_PIN = 7; 272 | 273 | static const pin_map_t digitalPinMap[] = { 274 | {&DDRB, &PINB, &PORTB, 0}, // B0 0 275 | {&DDRB, &PINB, &PORTB, 1}, // B1 1 276 | {&DDRB, &PINB, &PORTB, 2}, // B2 2 277 | {&DDRB, &PINB, &PORTB, 3}, // B3 3 278 | {&DDRB, &PINB, &PORTB, 4}, // B4 4 279 | {&DDRB, &PINB, &PORTB, 5}, // B5 5 280 | {&DDRB, &PINB, &PORTB, 6}, // B6 6 281 | {&DDRB, &PINB, &PORTB, 7}, // B7 7 282 | {&DDRD, &PIND, &PORTD, 0}, // D0 8 283 | {&DDRD, &PIND, &PORTD, 1}, // D1 9 284 | {&DDRD, &PIND, &PORTD, 2}, // D2 10 285 | {&DDRD, &PIND, &PORTD, 3}, // D3 11 286 | {&DDRD, &PIND, &PORTD, 4}, // D4 12 287 | {&DDRD, &PIND, &PORTD, 5}, // D5 13 288 | {&DDRD, &PIND, &PORTD, 6}, // D6 14 289 | {&DDRD, &PIND, &PORTD, 7}, // D7 15 290 | {&DDRC, &PINC, &PORTC, 0}, // C0 16 291 | {&DDRC, &PINC, &PORTC, 1}, // C1 17 292 | {&DDRC, &PINC, &PORTC, 2}, // C2 18 293 | {&DDRC, &PINC, &PORTC, 3}, // C3 19 294 | {&DDRC, &PINC, &PORTC, 4}, // C4 20 295 | {&DDRC, &PINC, &PORTC, 5}, // C5 21 296 | {&DDRC, &PINC, &PORTC, 6}, // C6 22 297 | {&DDRC, &PINC, &PORTC, 7}, // C7 23 298 | {&DDRA, &PINA, &PORTA, 7}, // A7 24 299 | {&DDRA, &PINA, &PORTA, 6}, // A6 25 300 | {&DDRA, &PINA, &PORTA, 5}, // A5 26 301 | {&DDRA, &PINA, &PORTA, 4}, // A4 27 302 | {&DDRA, &PINA, &PORTA, 3}, // A3 28 303 | {&DDRA, &PINA, &PORTA, 2}, // A2 29 304 | {&DDRA, &PINA, &PORTA, 1}, // A1 30 305 | {&DDRA, &PINA, &PORTA, 0} // A0 31 306 | }; 307 | //------------------------------------------------------------------------------ 308 | #elif defined(__AVR_ATmega32U4__) 309 | // Leonardo 310 | 311 | // Two Wire (aka I2C) ports 312 | uint8_t const SDA_PIN = 2; 313 | uint8_t const SCL_PIN = 3; 314 | 315 | // SPI port 316 | uint8_t const SS_PIN = 17; 317 | uint8_t const MOSI_PIN = 16; 318 | uint8_t const MISO_PIN = 14; 319 | uint8_t const SCK_PIN = 15; 320 | 321 | static const pin_map_t digitalPinMap[] = { 322 | {&DDRD, &PIND, &PORTD, 2}, // D2 0 323 | {&DDRD, &PIND, &PORTD, 3}, // D3 1 324 | {&DDRD, &PIND, &PORTD, 1}, // D1 2 325 | {&DDRD, &PIND, &PORTD, 0}, // D0 3 326 | {&DDRD, &PIND, &PORTD, 4}, // D4 4 327 | {&DDRC, &PINC, &PORTC, 6}, // C6 5 328 | {&DDRD, &PIND, &PORTD, 7}, // D7 6 329 | {&DDRE, &PINE, &PORTE, 6}, // E6 7 330 | {&DDRB, &PINB, &PORTB, 4}, // B4 8 331 | {&DDRB, &PINB, &PORTB, 5}, // B5 9 332 | {&DDRB, &PINB, &PORTB, 6}, // B6 10 333 | {&DDRB, &PINB, &PORTB, 7}, // B7 11 334 | {&DDRD, &PIND, &PORTD, 6}, // D6 12 335 | {&DDRC, &PINC, &PORTC, 7}, // C7 13 336 | {&DDRB, &PINB, &PORTB, 3}, // B3 14 337 | {&DDRB, &PINB, &PORTB, 1}, // B1 15 338 | {&DDRB, &PINB, &PORTB, 2}, // B2 16 339 | {&DDRB, &PINB, &PORTB, 0}, // B0 17 340 | {&DDRF, &PINF, &PORTF, 7}, // F7 18 341 | {&DDRF, &PINF, &PORTF, 6}, // F6 19 342 | {&DDRF, &PINF, &PORTF, 5}, // F5 20 343 | {&DDRF, &PINF, &PORTF, 4}, // F4 21 344 | {&DDRF, &PINF, &PORTF, 1}, // F1 22 345 | {&DDRF, &PINF, &PORTF, 0}, // F0 23 346 | }; 347 | //------------------------------------------------------------------------------ 348 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) 349 | // Teensy++ 1.0 & 2.0 350 | 351 | // Two Wire (aka I2C) ports 352 | uint8_t const SDA_PIN = 1; 353 | uint8_t const SCL_PIN = 0; 354 | 355 | // SPI port 356 | uint8_t const SS_PIN = 20; 357 | uint8_t const MOSI_PIN = 22; 358 | uint8_t const MISO_PIN = 23; 359 | uint8_t const SCK_PIN = 21; 360 | 361 | static const pin_map_t digitalPinMap[] = { 362 | {&DDRD, &PIND, &PORTD, 0}, // D0 0 363 | {&DDRD, &PIND, &PORTD, 1}, // D1 1 364 | {&DDRD, &PIND, &PORTD, 2}, // D2 2 365 | {&DDRD, &PIND, &PORTD, 3}, // D3 3 366 | {&DDRD, &PIND, &PORTD, 4}, // D4 4 367 | {&DDRD, &PIND, &PORTD, 5}, // D5 5 368 | {&DDRD, &PIND, &PORTD, 6}, // D6 6 369 | {&DDRD, &PIND, &PORTD, 7}, // D7 7 370 | {&DDRE, &PINE, &PORTE, 0}, // E0 8 371 | {&DDRE, &PINE, &PORTE, 1}, // E1 9 372 | {&DDRC, &PINC, &PORTC, 0}, // C0 10 373 | {&DDRC, &PINC, &PORTC, 1}, // C1 11 374 | {&DDRC, &PINC, &PORTC, 2}, // C2 12 375 | {&DDRC, &PINC, &PORTC, 3}, // C3 13 376 | {&DDRC, &PINC, &PORTC, 4}, // C4 14 377 | {&DDRC, &PINC, &PORTC, 5}, // C5 15 378 | {&DDRC, &PINC, &PORTC, 6}, // C6 16 379 | {&DDRC, &PINC, &PORTC, 7}, // C7 17 380 | {&DDRE, &PINE, &PORTE, 6}, // E6 18 381 | {&DDRE, &PINE, &PORTE, 7}, // E7 19 382 | {&DDRB, &PINB, &PORTB, 0}, // B0 20 383 | {&DDRB, &PINB, &PORTB, 1}, // B1 21 384 | {&DDRB, &PINB, &PORTB, 2}, // B2 22 385 | {&DDRB, &PINB, &PORTB, 3}, // B3 23 386 | {&DDRB, &PINB, &PORTB, 4}, // B4 24 387 | {&DDRB, &PINB, &PORTB, 5}, // B5 25 388 | {&DDRB, &PINB, &PORTB, 6}, // B6 26 389 | {&DDRB, &PINB, &PORTB, 7}, // B7 27 390 | {&DDRA, &PINA, &PORTA, 0}, // A0 28 391 | {&DDRA, &PINA, &PORTA, 1}, // A1 29 392 | {&DDRA, &PINA, &PORTA, 2}, // A2 30 393 | {&DDRA, &PINA, &PORTA, 3}, // A3 31 394 | {&DDRA, &PINA, &PORTA, 4}, // A4 32 395 | {&DDRA, &PINA, &PORTA, 5}, // A5 33 396 | {&DDRA, &PINA, &PORTA, 6}, // A6 34 397 | {&DDRA, &PINA, &PORTA, 7}, // A7 35 398 | {&DDRE, &PINE, &PORTE, 4}, // E4 36 399 | {&DDRE, &PINE, &PORTE, 5}, // E5 37 400 | {&DDRF, &PINF, &PORTF, 0}, // F0 38 401 | {&DDRF, &PINF, &PORTF, 1}, // F1 39 402 | {&DDRF, &PINF, &PORTF, 2}, // F2 40 403 | {&DDRF, &PINF, &PORTF, 3}, // F3 41 404 | {&DDRF, &PINF, &PORTF, 4}, // F4 42 405 | {&DDRF, &PINF, &PORTF, 5}, // F5 43 406 | {&DDRF, &PINF, &PORTF, 6}, // F6 44 407 | {&DDRF, &PINF, &PORTF, 7} // F7 45 408 | }; 409 | //------------------------------------------------------------------------------ 410 | #else // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 411 | // 168 and 328 Arduinos 412 | 413 | // Two Wire (aka I2C) ports 414 | uint8_t const SDA_PIN = 18; 415 | uint8_t const SCL_PIN = 19; 416 | 417 | // SPI port 418 | uint8_t const SS_PIN = 10; 419 | uint8_t const MOSI_PIN = 11; 420 | uint8_t const MISO_PIN = 12; 421 | uint8_t const SCK_PIN = 13; 422 | 423 | static const pin_map_t digitalPinMap[] = { 424 | {&DDRD, &PIND, &PORTD, 0}, // D0 0 425 | {&DDRD, &PIND, &PORTD, 1}, // D1 1 426 | {&DDRD, &PIND, &PORTD, 2}, // D2 2 427 | {&DDRD, &PIND, &PORTD, 3}, // D3 3 428 | {&DDRD, &PIND, &PORTD, 4}, // D4 4 429 | {&DDRD, &PIND, &PORTD, 5}, // D5 5 430 | {&DDRD, &PIND, &PORTD, 6}, // D6 6 431 | {&DDRD, &PIND, &PORTD, 7}, // D7 7 432 | {&DDRB, &PINB, &PORTB, 0}, // B0 8 433 | {&DDRB, &PINB, &PORTB, 1}, // B1 9 434 | {&DDRB, &PINB, &PORTB, 2}, // B2 10 435 | {&DDRB, &PINB, &PORTB, 3}, // B3 11 436 | {&DDRB, &PINB, &PORTB, 4}, // B4 12 437 | {&DDRB, &PINB, &PORTB, 5}, // B5 13 438 | {&DDRC, &PINC, &PORTC, 0}, // C0 14 439 | {&DDRC, &PINC, &PORTC, 1}, // C1 15 440 | {&DDRC, &PINC, &PORTC, 2}, // C2 16 441 | {&DDRC, &PINC, &PORTC, 3}, // C3 17 442 | {&DDRC, &PINC, &PORTC, 4}, // C4 18 443 | {&DDRC, &PINC, &PORTC, 5} // C5 19 444 | }; 445 | #endif // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 446 | //------------------------------------------------------------------------------ 447 | static const uint8_t digitalPinCount = sizeof(digitalPinMap)/sizeof(pin_map_t); 448 | 449 | uint8_t badPinNumber(void) 450 | __attribute__((error("Pin number is too large or not a constant"))); 451 | 452 | static inline __attribute__((always_inline)) 453 | uint8_t getPinMode(uint8_t pin) { 454 | if (__builtin_constant_p(pin) && pin < digitalPinCount) { 455 | return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1; 456 | } else { 457 | return badPinNumber(); 458 | } 459 | } 460 | static inline __attribute__((always_inline)) 461 | void setPinMode(uint8_t pin, uint8_t mode) { 462 | if (__builtin_constant_p(pin) && pin < digitalPinCount) { 463 | if (mode) { 464 | *digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit; 465 | } else { 466 | *digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit); 467 | } 468 | } else { 469 | badPinNumber(); 470 | } 471 | } 472 | static inline __attribute__((always_inline)) 473 | uint8_t fastDigitalRead(uint8_t pin) { 474 | if (__builtin_constant_p(pin) && pin < digitalPinCount) { 475 | return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1; 476 | } else { 477 | return badPinNumber(); 478 | } 479 | } 480 | static inline __attribute__((always_inline)) 481 | void fastDigitalWrite(uint8_t pin, uint8_t value) { 482 | if (__builtin_constant_p(pin) && pin < digitalPinCount) { 483 | if (value) { 484 | *digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit; 485 | } else { 486 | *digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit); 487 | } 488 | } else { 489 | badPinNumber(); 490 | } 491 | } 492 | #endif // Sd2PinMap_h 493 | 494 | #elif defined (__CPU_ARC__) 495 | 496 | #if defined (__ARDUINO_ARC__) 497 | // Two Wire (aka I2C) ports 498 | uint8_t const SDA_PIN = 18; 499 | uint8_t const SCL_PIN = 19; 500 | 501 | // SPI port 502 | uint8_t const SS_PIN = 10; 503 | uint8_t const MOSI_PIN = 11; 504 | uint8_t const MISO_PIN = 12; 505 | uint8_t const SCK_PIN = 13; 506 | 507 | #endif // Arduino ARC 508 | 509 | #else 510 | #error Architecture or board not supported. 511 | #endif 512 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/utility/SdFat.h: -------------------------------------------------------------------------------- 1 | /* Arduino SdFat Library 2 | * Copyright (C) 2009 by William Greiman 3 | * 4 | * This file is part of the Arduino SdFat Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino SdFat Library. If not, see 18 | * . 19 | */ 20 | #ifndef SdFat_h 21 | #define SdFat_h 22 | /** 23 | * \file 24 | * SdFile and SdVolume classes 25 | */ 26 | #if defined (__AVR__) || defined (__CPU_ARC__) 27 | #include 28 | #endif 29 | #include "Sd2Card.h" 30 | #include "FatStructs.h" 31 | #include "Print.h" 32 | //------------------------------------------------------------------------------ 33 | /** 34 | * Allow use of deprecated functions if non-zero 35 | */ 36 | #define ALLOW_DEPRECATED_FUNCTIONS 1 37 | //------------------------------------------------------------------------------ 38 | // forward declaration since SdVolume is used in SdFile 39 | class SdVolume; 40 | //============================================================================== 41 | // SdFile class 42 | 43 | // flags for ls() 44 | /** ls() flag to print modify date */ 45 | uint8_t const LS_DATE = 1; 46 | /** ls() flag to print file size */ 47 | uint8_t const LS_SIZE = 2; 48 | /** ls() flag for recursive list of subdirectories */ 49 | uint8_t const LS_R = 4; 50 | 51 | // use the gnu style oflag in open() 52 | /** open() oflag for reading */ 53 | uint8_t const O_READ = 0X01; 54 | /** open() oflag - same as O_READ */ 55 | uint8_t const O_RDONLY = O_READ; 56 | /** open() oflag for write */ 57 | uint8_t const O_WRITE = 0X02; 58 | /** open() oflag - same as O_WRITE */ 59 | uint8_t const O_WRONLY = O_WRITE; 60 | /** open() oflag for reading and writing */ 61 | uint8_t const O_RDWR = (O_READ | O_WRITE); 62 | /** open() oflag mask for access modes */ 63 | uint8_t const O_ACCMODE = (O_READ | O_WRITE); 64 | /** The file offset shall be set to the end of the file prior to each write. */ 65 | uint8_t const O_APPEND = 0X04; 66 | /** synchronous writes - call sync() after each write */ 67 | uint8_t const O_SYNC = 0X08; 68 | /** create the file if nonexistent */ 69 | uint8_t const O_CREAT = 0X10; 70 | /** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */ 71 | uint8_t const O_EXCL = 0X20; 72 | /** truncate the file to zero length */ 73 | uint8_t const O_TRUNC = 0X40; 74 | 75 | // flags for timestamp 76 | /** set the file's last access date */ 77 | uint8_t const T_ACCESS = 1; 78 | /** set the file's creation date and time */ 79 | uint8_t const T_CREATE = 2; 80 | /** Set the file's write date and time */ 81 | uint8_t const T_WRITE = 4; 82 | // values for type_ 83 | /** This SdFile has not been opened. */ 84 | uint8_t const FAT_FILE_TYPE_CLOSED = 0; 85 | /** SdFile for a file */ 86 | uint8_t const FAT_FILE_TYPE_NORMAL = 1; 87 | /** SdFile for a FAT16 root directory */ 88 | uint8_t const FAT_FILE_TYPE_ROOT16 = 2; 89 | /** SdFile for a FAT32 root directory */ 90 | uint8_t const FAT_FILE_TYPE_ROOT32 = 3; 91 | /** SdFile for a subdirectory */ 92 | uint8_t const FAT_FILE_TYPE_SUBDIR = 4; 93 | /** Test value for directory type */ 94 | uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT16; 95 | 96 | /** date field for FAT directory entry */ 97 | static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { 98 | return (year - 1980) << 9 | month << 5 | day; 99 | } 100 | /** year part of FAT directory date field */ 101 | static inline uint16_t FAT_YEAR(uint16_t fatDate) { 102 | return 1980 + (fatDate >> 9); 103 | } 104 | /** month part of FAT directory date field */ 105 | static inline uint8_t FAT_MONTH(uint16_t fatDate) { 106 | return (fatDate >> 5) & 0XF; 107 | } 108 | /** day part of FAT directory date field */ 109 | static inline uint8_t FAT_DAY(uint16_t fatDate) { 110 | return fatDate & 0X1F; 111 | } 112 | /** time field for FAT directory entry */ 113 | static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { 114 | return hour << 11 | minute << 5 | second >> 1; 115 | } 116 | /** hour part of FAT directory time field */ 117 | static inline uint8_t FAT_HOUR(uint16_t fatTime) { 118 | return fatTime >> 11; 119 | } 120 | /** minute part of FAT directory time field */ 121 | static inline uint8_t FAT_MINUTE(uint16_t fatTime) { 122 | return(fatTime >> 5) & 0X3F; 123 | } 124 | /** second part of FAT directory time field */ 125 | static inline uint8_t FAT_SECOND(uint16_t fatTime) { 126 | return 2*(fatTime & 0X1F); 127 | } 128 | /** Default date for file timestamps is 1 Jan 2000 */ 129 | uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; 130 | /** Default time for file timestamp is 1 am */ 131 | uint16_t const FAT_DEFAULT_TIME = (1 << 11); 132 | //------------------------------------------------------------------------------ 133 | /** 134 | * \class SdFile 135 | * \brief Access FAT16 and FAT32 files on SD and SDHC cards. 136 | */ 137 | class SdFile : public Print { 138 | public: 139 | /** Create an instance of SdFile. */ 140 | SdFile(void) : type_(FAT_FILE_TYPE_CLOSED) {} 141 | /** 142 | * writeError is set to true if an error occurs during a write(). 143 | * Set writeError to false before calling print() and/or write() and check 144 | * for true after calls to print() and/or write(). 145 | */ 146 | //bool writeError; 147 | /** 148 | * Cancel unbuffered reads for this file. 149 | * See setUnbufferedRead() 150 | */ 151 | void clearUnbufferedRead(void) { 152 | flags_ &= ~F_FILE_UNBUFFERED_READ; 153 | } 154 | uint8_t close(void); 155 | uint8_t contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); 156 | uint8_t createContiguous(SdFile* dirFile, 157 | const char* fileName, uint32_t size); 158 | /** \return The current cluster number for a file or directory. */ 159 | uint32_t curCluster(void) const {return curCluster_;} 160 | /** \return The current position for a file or directory. */ 161 | uint32_t curPosition(void) const {return curPosition_;} 162 | /** 163 | * Set the date/time callback function 164 | * 165 | * \param[in] dateTime The user's call back function. The callback 166 | * function is of the form: 167 | * 168 | * \code 169 | * void dateTime(uint16_t* date, uint16_t* time) { 170 | * uint16_t year; 171 | * uint8_t month, day, hour, minute, second; 172 | * 173 | * // User gets date and time from GPS or real-time clock here 174 | * 175 | * // return date using FAT_DATE macro to format fields 176 | * *date = FAT_DATE(year, month, day); 177 | * 178 | * // return time using FAT_TIME macro to format fields 179 | * *time = FAT_TIME(hour, minute, second); 180 | * } 181 | * \endcode 182 | * 183 | * Sets the function that is called when a file is created or when 184 | * a file's directory entry is modified by sync(). All timestamps, 185 | * access, creation, and modify, are set when a file is created. 186 | * sync() maintains the last access date and last modify date/time. 187 | * 188 | * See the timestamp() function. 189 | */ 190 | static void dateTimeCallback( 191 | void (*dateTime)(uint16_t* date, uint16_t* time)) { 192 | dateTime_ = dateTime; 193 | } 194 | /** 195 | * Cancel the date/time callback function. 196 | */ 197 | static void dateTimeCallbackCancel(void) { 198 | // use explicit zero since NULL is not defined for Sanguino 199 | dateTime_ = 0; 200 | } 201 | /** \return Address of the block that contains this file's directory. */ 202 | uint32_t dirBlock(void) const {return dirBlock_;} 203 | uint8_t dirEntry(dir_t* dir); 204 | /** \return Index of this file's directory in the block dirBlock. */ 205 | uint8_t dirIndex(void) const {return dirIndex_;} 206 | static void dirName(const dir_t& dir, char* name); 207 | /** \return The total number of bytes in a file or directory. */ 208 | uint32_t fileSize(void) const {return fileSize_;} 209 | /** \return The first cluster number for a file or directory. */ 210 | uint32_t firstCluster(void) const {return firstCluster_;} 211 | /** \return True if this is a SdFile for a directory else false. */ 212 | uint8_t isDir(void) const {return type_ >= FAT_FILE_TYPE_MIN_DIR;} 213 | /** \return True if this is a SdFile for a file else false. */ 214 | uint8_t isFile(void) const {return type_ == FAT_FILE_TYPE_NORMAL;} 215 | /** \return True if this is a SdFile for an open file/directory else false. */ 216 | uint8_t isOpen(void) const {return type_ != FAT_FILE_TYPE_CLOSED;} 217 | /** \return True if this is a SdFile for a subdirectory else false. */ 218 | uint8_t isSubDir(void) const {return type_ == FAT_FILE_TYPE_SUBDIR;} 219 | /** \return True if this is a SdFile for the root directory. */ 220 | uint8_t isRoot(void) const { 221 | return type_ == FAT_FILE_TYPE_ROOT16 || type_ == FAT_FILE_TYPE_ROOT32; 222 | } 223 | void ls(uint8_t flags = 0, uint8_t indent = 0); 224 | uint8_t makeDir(SdFile* dir, const char* dirName); 225 | uint8_t open(SdFile* dirFile, uint16_t index, uint8_t oflag); 226 | uint8_t open(SdFile* dirFile, const char* fileName, uint8_t oflag); 227 | 228 | uint8_t openRoot(SdVolume* vol); 229 | static void printDirName(const dir_t& dir, uint8_t width); 230 | static void printFatDate(uint16_t fatDate); 231 | static void printFatTime(uint16_t fatTime); 232 | static void printTwoDigits(uint8_t v); 233 | /** 234 | * Read the next byte from a file. 235 | * 236 | * \return For success read returns the next byte in the file as an int. 237 | * If an error occurs or end of file is reached -1 is returned. 238 | */ 239 | int16_t read(void) { 240 | uint8_t b; 241 | return read(&b, 1) == 1 ? b : -1; 242 | } 243 | int16_t read(void* buf, uint16_t nbyte); 244 | int8_t readDir(dir_t* dir); 245 | static uint8_t remove(SdFile* dirFile, const char* fileName); 246 | uint8_t remove(void); 247 | /** Set the file's current position to zero. */ 248 | void rewind(void) { 249 | curPosition_ = curCluster_ = 0; 250 | } 251 | uint8_t rmDir(void); 252 | uint8_t rmRfStar(void); 253 | /** Set the files position to current position + \a pos. See seekSet(). */ 254 | uint8_t seekCur(uint32_t pos) { 255 | return seekSet(curPosition_ + pos); 256 | } 257 | /** 258 | * Set the files current position to end of file. Useful to position 259 | * a file for append. See seekSet(). 260 | */ 261 | uint8_t seekEnd(void) {return seekSet(fileSize_);} 262 | uint8_t seekSet(uint32_t pos); 263 | /** 264 | * Use unbuffered reads to access this file. Used with Wave 265 | * Shield ISR. Used with Sd2Card::partialBlockRead() in WaveRP. 266 | * 267 | * Not recommended for normal applications. 268 | */ 269 | void setUnbufferedRead(void) { 270 | if (isFile()) flags_ |= F_FILE_UNBUFFERED_READ; 271 | } 272 | uint8_t timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, 273 | uint8_t hour, uint8_t minute, uint8_t second); 274 | uint8_t sync(void); 275 | /** Type of this SdFile. You should use isFile() or isDir() instead of type() 276 | * if possible. 277 | * 278 | * \return The file or directory type. 279 | */ 280 | uint8_t type(void) const {return type_;} 281 | uint8_t truncate(uint32_t size); 282 | /** \return Unbuffered read flag. */ 283 | uint8_t unbufferedRead(void) const { 284 | return flags_ & F_FILE_UNBUFFERED_READ; 285 | } 286 | /** \return SdVolume that contains this file. */ 287 | SdVolume* volume(void) const {return vol_;} 288 | size_t write(uint8_t b); 289 | size_t write(const void* buf, uint16_t nbyte); 290 | size_t write(const char* str); 291 | #ifdef __AVR__ 292 | void write_P(PGM_P str); 293 | void writeln_P(PGM_P str); 294 | #endif 295 | //------------------------------------------------------------------------------ 296 | #if ALLOW_DEPRECATED_FUNCTIONS 297 | // Deprecated functions - suppress cpplint warnings with NOLINT comment 298 | /** \deprecated Use: 299 | * uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); 300 | */ 301 | uint8_t contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT 302 | return contiguousRange(&bgnBlock, &endBlock); 303 | } 304 | /** \deprecated Use: 305 | * uint8_t SdFile::createContiguous(SdFile* dirFile, 306 | * const char* fileName, uint32_t size) 307 | */ 308 | uint8_t createContiguous(SdFile& dirFile, // NOLINT 309 | const char* fileName, uint32_t size) { 310 | return createContiguous(&dirFile, fileName, size); 311 | } 312 | 313 | /** 314 | * \deprecated Use: 315 | * static void SdFile::dateTimeCallback( 316 | * void (*dateTime)(uint16_t* date, uint16_t* time)); 317 | */ 318 | static void dateTimeCallback( 319 | void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT 320 | oldDateTime_ = dateTime; 321 | dateTime_ = dateTime ? oldToNew : 0; 322 | } 323 | /** \deprecated Use: uint8_t SdFile::dirEntry(dir_t* dir); */ 324 | uint8_t dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT 325 | /** \deprecated Use: 326 | * uint8_t SdFile::makeDir(SdFile* dir, const char* dirName); 327 | */ 328 | uint8_t makeDir(SdFile& dir, const char* dirName) { // NOLINT 329 | return makeDir(&dir, dirName); 330 | } 331 | /** \deprecated Use: 332 | * uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag); 333 | */ 334 | uint8_t open(SdFile& dirFile, // NOLINT 335 | const char* fileName, uint8_t oflag) { 336 | return open(&dirFile, fileName, oflag); 337 | } 338 | /** \deprecated Do not use in new apps */ 339 | uint8_t open(SdFile& dirFile, const char* fileName) { // NOLINT 340 | return open(dirFile, fileName, O_RDWR); 341 | } 342 | /** \deprecated Use: 343 | * uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag); 344 | */ 345 | uint8_t open(SdFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT 346 | return open(&dirFile, index, oflag); 347 | } 348 | /** \deprecated Use: uint8_t SdFile::openRoot(SdVolume* vol); */ 349 | uint8_t openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT 350 | 351 | /** \deprecated Use: int8_t SdFile::readDir(dir_t* dir); */ 352 | int8_t readDir(dir_t& dir) {return readDir(&dir);} // NOLINT 353 | /** \deprecated Use: 354 | * static uint8_t SdFile::remove(SdFile* dirFile, const char* fileName); 355 | */ 356 | static uint8_t remove(SdFile& dirFile, const char* fileName) { // NOLINT 357 | return remove(&dirFile, fileName); 358 | } 359 | //------------------------------------------------------------------------------ 360 | // rest are private 361 | private: 362 | static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT 363 | static void oldToNew(uint16_t* date, uint16_t* time) { 364 | uint16_t d; 365 | uint16_t t; 366 | oldDateTime_(d, t); 367 | *date = d; 368 | *time = t; 369 | } 370 | #endif // ALLOW_DEPRECATED_FUNCTIONS 371 | private: 372 | // bits defined in flags_ 373 | // should be 0XF 374 | static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC); 375 | // available bits 376 | static uint8_t const F_UNUSED = 0X30; 377 | // use unbuffered SD read 378 | static uint8_t const F_FILE_UNBUFFERED_READ = 0X40; 379 | // sync of directory entry required 380 | static uint8_t const F_FILE_DIR_DIRTY = 0X80; 381 | 382 | // make sure F_OFLAG is ok 383 | #if ((F_UNUSED | F_FILE_UNBUFFERED_READ | F_FILE_DIR_DIRTY) & F_OFLAG) 384 | #error flags_ bits conflict 385 | #endif // flags_ bits 386 | 387 | // private data 388 | uint8_t flags_; // See above for definition of flags_ bits 389 | uint8_t type_; // type of file see above for values 390 | uint32_t curCluster_; // cluster for current file position 391 | uint32_t curPosition_; // current file position in bytes from beginning 392 | uint32_t dirBlock_; // SD block that contains directory entry for file 393 | uint8_t dirIndex_; // index of entry in dirBlock 0 <= dirIndex_ <= 0XF 394 | uint32_t fileSize_; // file size in bytes 395 | uint32_t firstCluster_; // first cluster of file 396 | SdVolume* vol_; // volume where file is located 397 | 398 | // private functions 399 | uint8_t addCluster(void); 400 | uint8_t addDirCluster(void); 401 | dir_t* cacheDirEntry(uint8_t action); 402 | static void (*dateTime_)(uint16_t* date, uint16_t* time); 403 | static uint8_t make83Name(const char* str, uint8_t* name); 404 | uint8_t openCachedEntry(uint8_t cacheIndex, uint8_t oflags); 405 | dir_t* readDirCache(void); 406 | }; 407 | //============================================================================== 408 | // SdVolume class 409 | /** 410 | * \brief Cache for an SD data block 411 | */ 412 | union cache_t { 413 | /** Used to access cached file data blocks. */ 414 | uint8_t data[512]; 415 | /** Used to access cached FAT16 entries. */ 416 | uint16_t fat16[256]; 417 | /** Used to access cached FAT32 entries. */ 418 | uint32_t fat32[128]; 419 | /** Used to access cached directory entries. */ 420 | dir_t dir[16]; 421 | /** Used to access a cached MasterBoot Record. */ 422 | mbr_t mbr; 423 | /** Used to access to a cached FAT boot sector. */ 424 | fbs_t fbs; 425 | }; 426 | //------------------------------------------------------------------------------ 427 | /** 428 | * \class SdVolume 429 | * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards. 430 | */ 431 | class SdVolume { 432 | public: 433 | /** Create an instance of SdVolume */ 434 | SdVolume(void) :allocSearchStart_(2), fatType_(0) {} 435 | /** Clear the cache and returns a pointer to the cache. Used by the WaveRP 436 | * recorder to do raw write to the SD card. Not for normal apps. 437 | */ 438 | static uint8_t* cacheClear(void) { 439 | cacheFlush(); 440 | cacheBlockNumber_ = 0XFFFFFFFF; 441 | return cacheBuffer_.data; 442 | } 443 | /** 444 | * Initialize a FAT volume. Try partition one first then try super 445 | * floppy format. 446 | * 447 | * \param[in] dev The Sd2Card where the volume is located. 448 | * 449 | * \return The value one, true, is returned for success and 450 | * the value zero, false, is returned for failure. Reasons for 451 | * failure include not finding a valid partition, not finding a valid 452 | * FAT file system or an I/O error. 453 | */ 454 | uint8_t init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);} 455 | uint8_t init(Sd2Card* dev, uint8_t part); 456 | 457 | // inline functions that return volume info 458 | /** \return The volume's cluster size in blocks. */ 459 | uint8_t blocksPerCluster(void) const {return blocksPerCluster_;} 460 | /** \return The number of blocks in one FAT. */ 461 | uint32_t blocksPerFat(void) const {return blocksPerFat_;} 462 | /** \return The total number of clusters in the volume. */ 463 | uint32_t clusterCount(void) const {return clusterCount_;} 464 | /** \return The shift count required to multiply by blocksPerCluster. */ 465 | uint8_t clusterSizeShift(void) const {return clusterSizeShift_;} 466 | /** \return The logical block number for the start of file data. */ 467 | uint32_t dataStartBlock(void) const {return dataStartBlock_;} 468 | /** \return The number of FAT structures on the volume. */ 469 | uint8_t fatCount(void) const {return fatCount_;} 470 | /** \return The logical block number for the start of the first FAT. */ 471 | uint32_t fatStartBlock(void) const {return fatStartBlock_;} 472 | /** \return The FAT type of the volume. Values are 12, 16 or 32. */ 473 | uint8_t fatType(void) const {return fatType_;} 474 | /** \return The number of entries in the root directory for FAT16 volumes. */ 475 | uint32_t rootDirEntryCount(void) const {return rootDirEntryCount_;} 476 | /** \return The logical block number for the start of the root directory 477 | on FAT16 volumes or the first cluster number on FAT32 volumes. */ 478 | uint32_t rootDirStart(void) const {return rootDirStart_;} 479 | /** return a pointer to the Sd2Card object for this volume */ 480 | static Sd2Card* sdCard(void) {return sdCard_;} 481 | //------------------------------------------------------------------------------ 482 | #if ALLOW_DEPRECATED_FUNCTIONS 483 | // Deprecated functions - suppress cpplint warnings with NOLINT comment 484 | /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev); */ 485 | uint8_t init(Sd2Card& dev) {return init(&dev);} // NOLINT 486 | 487 | /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev, uint8_t vol); */ 488 | uint8_t init(Sd2Card& dev, uint8_t part) { // NOLINT 489 | return init(&dev, part); 490 | } 491 | #endif // ALLOW_DEPRECATED_FUNCTIONS 492 | //------------------------------------------------------------------------------ 493 | private: 494 | // Allow SdFile access to SdVolume private data. 495 | friend class SdFile; 496 | 497 | // value for action argument in cacheRawBlock to indicate read from cache 498 | static uint8_t const CACHE_FOR_READ = 0; 499 | // value for action argument in cacheRawBlock to indicate cache dirty 500 | static uint8_t const CACHE_FOR_WRITE = 1; 501 | 502 | static cache_t cacheBuffer_; // 512 byte cache for device blocks 503 | static uint32_t cacheBlockNumber_; // Logical number of block in the cache 504 | static Sd2Card* sdCard_; // Sd2Card object for cache 505 | static uint8_t cacheDirty_; // cacheFlush() will write block if true 506 | static uint32_t cacheMirrorBlock_; // block number for mirror FAT 507 | // 508 | uint32_t allocSearchStart_; // start cluster for alloc search 509 | uint8_t blocksPerCluster_; // cluster size in blocks 510 | uint32_t blocksPerFat_; // FAT size in blocks 511 | uint32_t clusterCount_; // clusters in one FAT 512 | uint8_t clusterSizeShift_; // shift to convert cluster count to block count 513 | uint32_t dataStartBlock_; // first data block number 514 | uint8_t fatCount_; // number of FATs on volume 515 | uint32_t fatStartBlock_; // start block for first FAT 516 | uint8_t fatType_; // volume type (12, 16, OR 32) 517 | uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir 518 | uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32 519 | //---------------------------------------------------------------------------- 520 | uint8_t allocContiguous(uint32_t count, uint32_t* curCluster); 521 | uint8_t blockOfCluster(uint32_t position) const { 522 | return (position >> 9) & (blocksPerCluster_ - 1);} 523 | uint32_t clusterStartBlock(uint32_t cluster) const { 524 | return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);} 525 | uint32_t blockNumber(uint32_t cluster, uint32_t position) const { 526 | return clusterStartBlock(cluster) + blockOfCluster(position);} 527 | static uint8_t cacheFlush(void); 528 | static uint8_t cacheRawBlock(uint32_t blockNumber, uint8_t action); 529 | static void cacheSetDirty(void) {cacheDirty_ |= CACHE_FOR_WRITE;} 530 | static uint8_t cacheZeroBlock(uint32_t blockNumber); 531 | uint8_t chainSize(uint32_t beginCluster, uint32_t* size) const; 532 | uint8_t fatGet(uint32_t cluster, uint32_t* value) const; 533 | uint8_t fatPut(uint32_t cluster, uint32_t value); 534 | uint8_t fatPutEOC(uint32_t cluster) { 535 | return fatPut(cluster, 0x0FFFFFFF); 536 | } 537 | uint8_t freeChain(uint32_t cluster); 538 | uint8_t isEOC(uint32_t cluster) const { 539 | return cluster >= (fatType_ == 16 ? FAT16EOC_MIN : FAT32EOC_MIN); 540 | } 541 | uint8_t readBlock(uint32_t block, uint8_t* dst) { 542 | return sdCard_->readBlock(block, dst);} 543 | uint8_t readData(uint32_t block, uint16_t offset, 544 | uint16_t count, uint8_t* dst) { 545 | return sdCard_->readData(block, offset, count, dst); 546 | } 547 | uint8_t writeBlock(uint32_t block, const uint8_t* dst) { 548 | return sdCard_->writeBlock(block, dst); 549 | } 550 | }; 551 | #endif // SdFat_h 552 | -------------------------------------------------------------------------------- /LCD_GRBL/lib/SD/src/utility/Sd2Card.cpp: -------------------------------------------------------------------------------- 1 | /* Arduino Sd2Card Library 2 | * Copyright (C) 2009 by William Greiman 3 | * 4 | * This file is part of the Arduino Sd2Card Library 5 | * 6 | * This Library is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This Library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with the Arduino Sd2Card Library. If not, see 18 | * . 19 | */ 20 | #define USE_SPI_LIB 21 | #include 22 | #include "Sd2Card.h" 23 | //------------------------------------------------------------------------------ 24 | #ifndef SOFTWARE_SPI 25 | #ifdef USE_SPI_LIB 26 | 27 | #ifndef SDCARD_SPI 28 | #define SDCARD_SPI SPI 29 | #endif 30 | 31 | #include 32 | static SPISettings settings; 33 | #endif 34 | // functions for hardware SPI 35 | /** Send a byte to the card */ 36 | static void spiSend(uint8_t b) { 37 | #ifndef USE_SPI_LIB 38 | SPDR = b; 39 | while (!(SPSR & (1 << SPIF))) 40 | ; 41 | #else 42 | SDCARD_SPI.transfer(b); 43 | #endif 44 | } 45 | /** Receive a byte from the card */ 46 | static uint8_t spiRec(void) { 47 | #ifndef USE_SPI_LIB 48 | spiSend(0XFF); 49 | return SPDR; 50 | #else 51 | return SDCARD_SPI.transfer(0xFF); 52 | #endif 53 | } 54 | #else // SOFTWARE_SPI 55 | //------------------------------------------------------------------------------ 56 | /** nop to tune soft SPI timing */ 57 | #define nop asm volatile ("nop\n\t") 58 | //------------------------------------------------------------------------------ 59 | /** Soft SPI receive */ 60 | uint8_t spiRec(void) { 61 | uint8_t data = 0; 62 | // no interrupts during byte receive - about 8 us 63 | cli(); 64 | // output pin high - like sending 0XFF 65 | fastDigitalWrite(SPI_MOSI_PIN, HIGH); 66 | 67 | for (uint8_t i = 0; i < 8; i++) { 68 | fastDigitalWrite(SPI_SCK_PIN, HIGH); 69 | 70 | // adjust so SCK is nice 71 | nop; 72 | nop; 73 | 74 | data <<= 1; 75 | 76 | if (fastDigitalRead(SPI_MISO_PIN)) data |= 1; 77 | 78 | fastDigitalWrite(SPI_SCK_PIN, LOW); 79 | } 80 | // enable interrupts 81 | sei(); 82 | return data; 83 | } 84 | //------------------------------------------------------------------------------ 85 | /** Soft SPI send */ 86 | void spiSend(uint8_t data) { 87 | // no interrupts during byte send - about 8 us 88 | cli(); 89 | for (uint8_t i = 0; i < 8; i++) { 90 | fastDigitalWrite(SPI_SCK_PIN, LOW); 91 | 92 | fastDigitalWrite(SPI_MOSI_PIN, data & 0X80); 93 | 94 | data <<= 1; 95 | 96 | fastDigitalWrite(SPI_SCK_PIN, HIGH); 97 | } 98 | // hold SCK high for a few ns 99 | nop; 100 | nop; 101 | nop; 102 | nop; 103 | 104 | fastDigitalWrite(SPI_SCK_PIN, LOW); 105 | // enable interrupts 106 | sei(); 107 | } 108 | #endif // SOFTWARE_SPI 109 | //------------------------------------------------------------------------------ 110 | // send command and return error code. Return zero for OK 111 | uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { 112 | // end read if in partialBlockRead mode 113 | readEnd(); 114 | 115 | // select card 116 | chipSelectLow(); 117 | 118 | // wait up to 300 ms if busy 119 | waitNotBusy(300); 120 | 121 | // send command 122 | spiSend(cmd | 0x40); 123 | 124 | // send argument 125 | for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s); 126 | 127 | // send CRC 128 | uint8_t crc = 0XFF; 129 | if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0 130 | if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA 131 | spiSend(crc); 132 | 133 | // wait for response 134 | for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++) 135 | ; 136 | return status_; 137 | } 138 | //------------------------------------------------------------------------------ 139 | /** 140 | * Determine the size of an SD flash memory card. 141 | * 142 | * \return The number of 512 byte data blocks in the card 143 | * or zero if an error occurs. 144 | */ 145 | uint32_t Sd2Card::cardSize(void) { 146 | csd_t csd; 147 | if (!readCSD(&csd)) return 0; 148 | if (csd.v1.csd_ver == 0) { 149 | uint8_t read_bl_len = csd.v1.read_bl_len; 150 | uint16_t c_size = (csd.v1.c_size_high << 10) 151 | | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low; 152 | uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1) 153 | | csd.v1.c_size_mult_low; 154 | return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7); 155 | } else if (csd.v2.csd_ver == 1) { 156 | uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16) 157 | | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low; 158 | return (c_size + 1) << 10; 159 | } else { 160 | error(SD_CARD_ERROR_BAD_CSD); 161 | return 0; 162 | } 163 | } 164 | //------------------------------------------------------------------------------ 165 | static uint8_t chip_select_asserted = 0; 166 | 167 | void Sd2Card::chipSelectHigh(void) { 168 | digitalWrite(chipSelectPin_, HIGH); 169 | #ifdef USE_SPI_LIB 170 | if (chip_select_asserted) { 171 | chip_select_asserted = 0; 172 | SDCARD_SPI.endTransaction(); 173 | } 174 | #endif 175 | } 176 | //------------------------------------------------------------------------------ 177 | void Sd2Card::chipSelectLow(void) { 178 | #ifdef USE_SPI_LIB 179 | if (!chip_select_asserted) { 180 | chip_select_asserted = 1; 181 | SDCARD_SPI.beginTransaction(settings); 182 | } 183 | #endif 184 | digitalWrite(chipSelectPin_, LOW); 185 | } 186 | //------------------------------------------------------------------------------ 187 | /** Erase a range of blocks. 188 | * 189 | * \param[in] firstBlock The address of the first block in the range. 190 | * \param[in] lastBlock The address of the last block in the range. 191 | * 192 | * \note This function requests the SD card to do a flash erase for a 193 | * range of blocks. The data on the card after an erase operation is 194 | * either 0 or 1, depends on the card vendor. The card must support 195 | * single block erase. 196 | * 197 | * \return The value one, true, is returned for success and 198 | * the value zero, false, is returned for failure. 199 | */ 200 | uint8_t Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { 201 | if (!eraseSingleBlockEnable()) { 202 | error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); 203 | goto fail; 204 | } 205 | if (type_ != SD_CARD_TYPE_SDHC) { 206 | firstBlock <<= 9; 207 | lastBlock <<= 9; 208 | } 209 | if (cardCommand(CMD32, firstBlock) 210 | || cardCommand(CMD33, lastBlock) 211 | || cardCommand(CMD38, 0)) { 212 | error(SD_CARD_ERROR_ERASE); 213 | goto fail; 214 | } 215 | if (!waitNotBusy(SD_ERASE_TIMEOUT)) { 216 | error(SD_CARD_ERROR_ERASE_TIMEOUT); 217 | goto fail; 218 | } 219 | chipSelectHigh(); 220 | return true; 221 | 222 | fail: 223 | chipSelectHigh(); 224 | return false; 225 | } 226 | //------------------------------------------------------------------------------ 227 | /** Determine if card supports single block erase. 228 | * 229 | * \return The value one, true, is returned if single block erase is supported. 230 | * The value zero, false, is returned if single block erase is not supported. 231 | */ 232 | uint8_t Sd2Card::eraseSingleBlockEnable(void) { 233 | csd_t csd; 234 | return readCSD(&csd) ? csd.v1.erase_blk_en : 0; 235 | } 236 | //------------------------------------------------------------------------------ 237 | /** 238 | * Initialize an SD flash memory card. 239 | * 240 | * \param[in] sckRateID SPI clock rate selector. See setSckRate(). 241 | * \param[in] chipSelectPin SD chip select pin number. 242 | * 243 | * \return The value one, true, is returned for success and 244 | * the value zero, false, is returned for failure. The reason for failure 245 | * can be determined by calling errorCode() and errorData(). 246 | */ 247 | uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) { 248 | errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0; 249 | chipSelectPin_ = chipSelectPin; 250 | // 16-bit init start time allows over a minute 251 | uint16_t t0 = (uint16_t)millis(); 252 | uint32_t arg; 253 | 254 | // set pin modes 255 | pinMode(chipSelectPin_, OUTPUT); 256 | digitalWrite(chipSelectPin_, HIGH); 257 | #ifndef USE_SPI_LIB 258 | pinMode(SPI_MISO_PIN, INPUT); 259 | pinMode(SPI_MOSI_PIN, OUTPUT); 260 | pinMode(SPI_SCK_PIN, OUTPUT); 261 | #endif 262 | 263 | #ifndef SOFTWARE_SPI 264 | #ifndef USE_SPI_LIB 265 | // SS must be in output mode even it is not chip select 266 | pinMode(SS_PIN, OUTPUT); 267 | digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin 268 | // Enable SPI, Master, clock rate f_osc/128 269 | SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); 270 | // clear double speed 271 | SPSR &= ~(1 << SPI2X); 272 | #else // USE_SPI_LIB 273 | SDCARD_SPI.begin(); 274 | settings = SPISettings(250000, MSBFIRST, SPI_MODE0); 275 | #endif // USE_SPI_LIB 276 | #endif // SOFTWARE_SPI 277 | 278 | // must supply min of 74 clock cycles with CS high. 279 | #ifdef USE_SPI_LIB 280 | SDCARD_SPI.beginTransaction(settings); 281 | #endif 282 | for (uint8_t i = 0; i < 10; i++) spiSend(0XFF); 283 | #ifdef USE_SPI_LIB 284 | SDCARD_SPI.endTransaction(); 285 | #endif 286 | 287 | chipSelectLow(); 288 | 289 | // command to go idle in SPI mode 290 | while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) { 291 | if (((uint16_t)(millis() - t0)) > SD_INIT_TIMEOUT) { 292 | error(SD_CARD_ERROR_CMD0); 293 | goto fail; 294 | } 295 | } 296 | // check SD version 297 | if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) { 298 | type(SD_CARD_TYPE_SD1); 299 | } else { 300 | // only need last byte of r7 response 301 | for (uint8_t i = 0; i < 4; i++) status_ = spiRec(); 302 | if (status_ != 0XAA) { 303 | error(SD_CARD_ERROR_CMD8); 304 | goto fail; 305 | } 306 | type(SD_CARD_TYPE_SD2); 307 | } 308 | // initialize card and send host supports SDHC if SD2 309 | arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0; 310 | 311 | while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) { 312 | // check for timeout 313 | if (((uint16_t)(millis() - t0)) > SD_INIT_TIMEOUT) { 314 | error(SD_CARD_ERROR_ACMD41); 315 | goto fail; 316 | } 317 | } 318 | // if SD2 read OCR register to check for SDHC card 319 | if (type() == SD_CARD_TYPE_SD2) { 320 | if (cardCommand(CMD58, 0)) { 321 | error(SD_CARD_ERROR_CMD58); 322 | goto fail; 323 | } 324 | if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC); 325 | // discard rest of ocr - contains allowed voltage range 326 | for (uint8_t i = 0; i < 3; i++) spiRec(); 327 | } 328 | chipSelectHigh(); 329 | 330 | #ifndef SOFTWARE_SPI 331 | return setSckRate(sckRateID); 332 | #else // SOFTWARE_SPI 333 | return true; 334 | #endif // SOFTWARE_SPI 335 | 336 | fail: 337 | chipSelectHigh(); 338 | return false; 339 | } 340 | //------------------------------------------------------------------------------ 341 | /** 342 | * Enable or disable partial block reads. 343 | * 344 | * Enabling partial block reads improves performance by allowing a block 345 | * to be read over the SPI bus as several sub-blocks. Errors may occur 346 | * if the time between reads is too long since the SD card may timeout. 347 | * The SPI SS line will be held low until the entire block is read or 348 | * readEnd() is called. 349 | * 350 | * Use this for applications like the Adafruit Wave Shield. 351 | * 352 | * \param[in] value The value TRUE (non-zero) or FALSE (zero).) 353 | */ 354 | void Sd2Card::partialBlockRead(uint8_t value) { 355 | readEnd(); 356 | partialBlockRead_ = value; 357 | } 358 | //------------------------------------------------------------------------------ 359 | /** 360 | * Read a 512 byte block from an SD card device. 361 | * 362 | * \param[in] block Logical block to be read. 363 | * \param[out] dst Pointer to the location that will receive the data. 364 | 365 | * \return The value one, true, is returned for success and 366 | * the value zero, false, is returned for failure. 367 | */ 368 | uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) { 369 | return readData(block, 0, 512, dst); 370 | } 371 | //------------------------------------------------------------------------------ 372 | /** 373 | * Read part of a 512 byte block from an SD card. 374 | * 375 | * \param[in] block Logical block to be read. 376 | * \param[in] offset Number of bytes to skip at start of block 377 | * \param[out] dst Pointer to the location that will receive the data. 378 | * \param[in] count Number of bytes to read 379 | * \return The value one, true, is returned for success and 380 | * the value zero, false, is returned for failure. 381 | */ 382 | uint8_t Sd2Card::readData(uint32_t block, 383 | uint16_t offset, uint16_t count, uint8_t* dst) { 384 | if (count == 0) return true; 385 | if ((count + offset) > 512) { 386 | goto fail; 387 | } 388 | if (!inBlock_ || block != block_ || offset < offset_) { 389 | block_ = block; 390 | // use address if not SDHC card 391 | if (type()!= SD_CARD_TYPE_SDHC) block <<= 9; 392 | if (cardCommand(CMD17, block)) { 393 | error(SD_CARD_ERROR_CMD17); 394 | goto fail; 395 | } 396 | if (!waitStartBlock()) { 397 | goto fail; 398 | } 399 | offset_ = 0; 400 | inBlock_ = 1; 401 | } 402 | 403 | #ifdef OPTIMIZE_HARDWARE_SPI 404 | // start first spi transfer 405 | SPDR = 0XFF; 406 | 407 | // skip data before offset 408 | for (;offset_ < offset; offset_++) { 409 | while (!(SPSR & (1 << SPIF))) 410 | ; 411 | SPDR = 0XFF; 412 | } 413 | // transfer data 414 | n = count - 1; 415 | for (uint16_t i = 0; i < n; i++) { 416 | while (!(SPSR & (1 << SPIF))) 417 | ; 418 | dst[i] = SPDR; 419 | SPDR = 0XFF; 420 | } 421 | // wait for last byte 422 | while (!(SPSR & (1 << SPIF))) 423 | ; 424 | dst[n] = SPDR; 425 | 426 | #else // OPTIMIZE_HARDWARE_SPI 427 | 428 | // skip data before offset 429 | for (;offset_ < offset; offset_++) { 430 | spiRec(); 431 | } 432 | // transfer data 433 | for (uint16_t i = 0; i < count; i++) { 434 | dst[i] = spiRec(); 435 | } 436 | #endif // OPTIMIZE_HARDWARE_SPI 437 | 438 | offset_ += count; 439 | if (!partialBlockRead_ || offset_ >= 512) { 440 | // read rest of data, checksum and set chip select high 441 | readEnd(); 442 | } 443 | return true; 444 | 445 | fail: 446 | chipSelectHigh(); 447 | return false; 448 | } 449 | //------------------------------------------------------------------------------ 450 | /** Skip remaining data in a block when in partial block read mode. */ 451 | void Sd2Card::readEnd(void) { 452 | if (inBlock_) { 453 | // skip data and crc 454 | #ifdef OPTIMIZE_HARDWARE_SPI 455 | // optimize skip for hardware 456 | SPDR = 0XFF; 457 | while (offset_++ < 513) { 458 | while (!(SPSR & (1 << SPIF))) 459 | ; 460 | SPDR = 0XFF; 461 | } 462 | // wait for last crc byte 463 | while (!(SPSR & (1 << SPIF))) 464 | ; 465 | #else // OPTIMIZE_HARDWARE_SPI 466 | while (offset_++ < 514) spiRec(); 467 | #endif // OPTIMIZE_HARDWARE_SPI 468 | chipSelectHigh(); 469 | inBlock_ = 0; 470 | } 471 | } 472 | //------------------------------------------------------------------------------ 473 | /** read CID or CSR register */ 474 | uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) { 475 | uint8_t* dst = reinterpret_cast(buf); 476 | if (cardCommand(cmd, 0)) { 477 | error(SD_CARD_ERROR_READ_REG); 478 | goto fail; 479 | } 480 | if (!waitStartBlock()) goto fail; 481 | // transfer data 482 | for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec(); 483 | spiRec(); // get first crc byte 484 | spiRec(); // get second crc byte 485 | chipSelectHigh(); 486 | return true; 487 | 488 | fail: 489 | chipSelectHigh(); 490 | return false; 491 | } 492 | //------------------------------------------------------------------------------ 493 | /** 494 | * Set the SPI clock rate. 495 | * 496 | * \param[in] sckRateID A value in the range [0, 6]. 497 | * 498 | * The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum 499 | * SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128 500 | * for \a scsRateID = 6. 501 | * 502 | * \return The value one, true, is returned for success and the value zero, 503 | * false, is returned for an invalid value of \a sckRateID. 504 | */ 505 | uint8_t Sd2Card::setSckRate(uint8_t sckRateID) { 506 | if (sckRateID > 6) { 507 | error(SD_CARD_ERROR_SCK_RATE); 508 | return false; 509 | } 510 | #ifndef USE_SPI_LIB 511 | // see avr processor datasheet for SPI register bit definitions 512 | if ((sckRateID & 1) || sckRateID == 6) { 513 | SPSR &= ~(1 << SPI2X); 514 | } else { 515 | SPSR |= (1 << SPI2X); 516 | } 517 | SPCR &= ~((1 < SD_READ_TIMEOUT) { 558 | error(SD_CARD_ERROR_READ_TIMEOUT); 559 | goto fail; 560 | } 561 | } 562 | if (status_ != DATA_START_BLOCK) { 563 | error(SD_CARD_ERROR_READ); 564 | goto fail; 565 | } 566 | return true; 567 | 568 | fail: 569 | chipSelectHigh(); 570 | return false; 571 | } 572 | //------------------------------------------------------------------------------ 573 | /** 574 | * Writes a 512 byte block to an SD card. 575 | * 576 | * \param[in] blockNumber Logical block to be written. 577 | * \param[in] src Pointer to the location of the data to be written. 578 | * \return The value one, true, is returned for success and 579 | * the value zero, false, is returned for failure. 580 | */ 581 | uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) { 582 | #if SD_PROTECT_BLOCK_ZERO 583 | // don't allow write to first block 584 | if (blockNumber == 0) { 585 | error(SD_CARD_ERROR_WRITE_BLOCK_ZERO); 586 | goto fail; 587 | } 588 | #endif // SD_PROTECT_BLOCK_ZERO 589 | 590 | // use address if not SDHC card 591 | if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; 592 | if (cardCommand(CMD24, blockNumber)) { 593 | error(SD_CARD_ERROR_CMD24); 594 | goto fail; 595 | } 596 | if (!writeData(DATA_START_BLOCK, src)) goto fail; 597 | 598 | // wait for flash programming to complete 599 | if (!waitNotBusy(SD_WRITE_TIMEOUT)) { 600 | error(SD_CARD_ERROR_WRITE_TIMEOUT); 601 | goto fail; 602 | } 603 | // response is r2 so get and check two bytes for nonzero 604 | if (cardCommand(CMD13, 0) || spiRec()) { 605 | error(SD_CARD_ERROR_WRITE_PROGRAMMING); 606 | goto fail; 607 | } 608 | chipSelectHigh(); 609 | return true; 610 | 611 | fail: 612 | chipSelectHigh(); 613 | return false; 614 | } 615 | //------------------------------------------------------------------------------ 616 | /** Write one data block in a multiple block write sequence */ 617 | uint8_t Sd2Card::writeData(const uint8_t* src) { 618 | // wait for previous write to finish 619 | if (!waitNotBusy(SD_WRITE_TIMEOUT)) { 620 | error(SD_CARD_ERROR_WRITE_MULTIPLE); 621 | chipSelectHigh(); 622 | return false; 623 | } 624 | return writeData(WRITE_MULTIPLE_TOKEN, src); 625 | } 626 | //------------------------------------------------------------------------------ 627 | // send one block of data for write block or write multiple blocks 628 | uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) { 629 | #ifdef OPTIMIZE_HARDWARE_SPI 630 | 631 | // send data - optimized loop 632 | SPDR = token; 633 | 634 | // send two byte per iteration 635 | for (uint16_t i = 0; i < 512; i += 2) { 636 | while (!(SPSR & (1 << SPIF))) 637 | ; 638 | SPDR = src[i]; 639 | while (!(SPSR & (1 << SPIF))) 640 | ; 641 | SPDR = src[i+1]; 642 | } 643 | 644 | // wait for last data byte 645 | while (!(SPSR & (1 << SPIF))) 646 | ; 647 | 648 | #else // OPTIMIZE_HARDWARE_SPI 649 | spiSend(token); 650 | for (uint16_t i = 0; i < 512; i++) { 651 | spiSend(src[i]); 652 | } 653 | #endif // OPTIMIZE_HARDWARE_SPI 654 | spiSend(0xff); // dummy crc 655 | spiSend(0xff); // dummy crc 656 | 657 | status_ = spiRec(); 658 | if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { 659 | error(SD_CARD_ERROR_WRITE); 660 | chipSelectHigh(); 661 | return false; 662 | } 663 | return true; 664 | } 665 | //------------------------------------------------------------------------------ 666 | /** Start a write multiple blocks sequence. 667 | * 668 | * \param[in] blockNumber Address of first block in sequence. 669 | * \param[in] eraseCount The number of blocks to be pre-erased. 670 | * 671 | * \note This function is used with writeData() and writeStop() 672 | * for optimized multiple block writes. 673 | * 674 | * \return The value one, true, is returned for success and 675 | * the value zero, false, is returned for failure. 676 | */ 677 | uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) { 678 | #if SD_PROTECT_BLOCK_ZERO 679 | // don't allow write to first block 680 | if (blockNumber == 0) { 681 | error(SD_CARD_ERROR_WRITE_BLOCK_ZERO); 682 | goto fail; 683 | } 684 | #endif // SD_PROTECT_BLOCK_ZERO 685 | // send pre-erase count 686 | if (cardAcmd(ACMD23, eraseCount)) { 687 | error(SD_CARD_ERROR_ACMD23); 688 | goto fail; 689 | } 690 | // use address if not SDHC card 691 | if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; 692 | if (cardCommand(CMD25, blockNumber)) { 693 | error(SD_CARD_ERROR_CMD25); 694 | goto fail; 695 | } 696 | return true; 697 | 698 | fail: 699 | chipSelectHigh(); 700 | return false; 701 | } 702 | //------------------------------------------------------------------------------ 703 | /** End a write multiple blocks sequence. 704 | * 705 | * \return The value one, true, is returned for success and 706 | * the value zero, false, is returned for failure. 707 | */ 708 | uint8_t Sd2Card::writeStop(void) { 709 | if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; 710 | spiSend(STOP_TRAN_TOKEN); 711 | if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; 712 | chipSelectHigh(); 713 | return true; 714 | 715 | fail: 716 | error(SD_CARD_ERROR_STOP_TRAN); 717 | chipSelectHigh(); 718 | return false; 719 | } 720 | --------------------------------------------------------------------------------