Browse Source

Firmware constructeur

(a compiler avec type de carte Arduino Mega 2560)
Arthur Suzuki 1 year ago
commit
86fa56a99f
41 changed files with 20199 additions and 0 deletions
  1. 283 0
      Configuration.h
  2. 245 0
      Configuration_adv.h
  3. 196 0
      EEPROMwrite.h
  4. 191 0
      Marlin.h
  5. 329 0
      MarlinSerial.cpp
  6. 150 0
      MarlinSerial.h
  7. 1757 0
      Marlin_gebruikte_dual_ballspindle_elecnieuw.ino
  8. 643 0
      Sd2Card.cpp
  9. 241 0
      Sd2Card.h
  10. 368 0
      Sd2PinMap.h
  11. 1791 0
      SdBaseFile.cpp
  12. 483 0
      SdBaseFile.h
  13. 114 0
      SdFatConfig.h
  14. 610 0
      SdFatStructs.h
  15. 79 0
      SdFatUtil.cpp
  16. 48 0
      SdFatUtil.h
  17. 92 0
      SdFile.cpp
  18. 54 0
      SdFile.h
  19. 280 0
      SdInfo.h
  20. 405 0
      SdVolume.cpp
  21. 214 0
      SdVolume.h
  22. 536 0
      cardreader.cpp
  23. 75 0
      cardreader.h
  24. 2582 0
      fastio.h
  25. 325 0
      language.h
  26. 147 0
      motion_control.cpp
  27. 32 0
      motion_control.h
  28. 1199 0
      pins.h
  29. 816 0
      planner.cpp
  30. 139 0
      planner.h
  31. 152 0
      speed_lookuptable.h
  32. 853 0
      stepper.cpp
  33. 71 0
      stepper.h
  34. 994 0
      temperature.cpp
  35. 169 0
      temperature.h
  36. 507 0
      thermistortables.h
  37. 165 0
      ultralcd.h
  38. 2644 0
      ultralcd.ino
  39. 16 0
      watchdog.h
  40. 63 0
      watchdog.ino
  41. 141 0
      wiring.h

+ 283 - 0
Configuration.h

@@ -0,0 +1,283 @@
1
+#ifndef CONFIGURATION_H
2
+#define CONFIGURATION_H
3
+
4
+// This configurtion file contains the basic settings.
5
+// Advanced settings can be found in Configuration_adv.h 
6
+// BASIC SETTINGS: select your board type, temperature sensor type, axis scaling, and endstop configuration
7
+
8
+//User specified version info of THIS file to display in [Pronterface, etc] terminal window during startup.
9
+//Implementation of an idea by Prof Braino to inform user that any changes made
10
+//to THIS file by the user have been successfully uploaded into firmware.
11
+#define STRING_VERSION_CONFIG_H "2013-12-05" //Personal revision number for changes to THIS file.
12
+#define STRING_CONFIG_H_AUTHOR "JanCees" //Who made the changes.
13
+
14
+// This determines the communication speed of the printer
15
+//#define BAUDRATE 250000
16
+#define BAUDRATE 115200
17
+
18
+#define EXTR2_X_OFFSET 34.0
19
+#define EXTR2_Y_OFFSET 0.0
20
+
21
+//// The following define selects which electronics board you have. Please choose the one that matches your setup
22
+// Gen7 custom (Alfons3 Version) = 10 "https://github.com/Alfons3/Generation_7_Electronics"
23
+// Gen7 v1.1, v1.2 = 11
24
+// Gen7 v1.3 = 12
25
+// Gen7 v1.4 = 13
26
+// MEGA/RAMPS up to 1.2 = 3
27
+// RAMPS 1.3 = 33 (Power outputs: Extruder, Bed, Fan)
28
+// RAMPS 1.3 = 34 (Power outputs: Extruder0, Extruder1, Bed)
29
+// Gen6 = 5
30
+// Gen6 deluxe = 51
31
+// Sanguinololu 1.2 and above = 62
32
+// Melzi = 63
33
+// Ultimaker = 7
34
+// Teensylu = 8
35
+// Gen3+ =9
36
+
37
+#ifndef MOTHERBOARD
38
+#define MOTHERBOARD 72
39
+#endif
40
+
41
+//===========================================================================
42
+//=============================Thermal Settings  ============================
43
+//===========================================================================
44
+//
45
+//--NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table
46
+//
47
+//// Temperature sensor settings:
48
+// -2 is thermocouple with MAX6675 (only for sensor 0)
49
+// -1 is thermocouple with AD595
50
+// 0 is not used
51
+// 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
52
+// 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup)
53
+// 3 is mendel-parts thermistor (4.7k pullup)
54
+// 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
55
+// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan) (4.7k pullup)
56
+// 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup)
57
+// 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup)
58
+//
59
+//    1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k 
60
+//                          (but gives greater accuracy and more stable PID)
61
+// 51 is 100k thermistor - EPCOS (1k pullup)
62
+// 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup)
63
+// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan) (1k pullup)
64
+
65
+#define TEMP_SENSOR_0 1
66
+#define TEMP_SENSOR_1 1
67
+#define TEMP_SENSOR_2 0
68
+#define TEMP_SENSOR_BED 1
69
+
70
+// Actual temperature must be close to target for this long before M109 returns success
71
+#define TEMP_RESIDENCY_TIME 10	// (seconds)
72
+#define TEMP_HYSTERESIS 3       // (degC) range of +/- temperatures considered "close" to the target one
73
+#define TEMP_WINDOW     1       // (degC) Window around target to start the recidency timer x degC early.
74
+
75
+// The minimal temperature defines the temperature below which the heater will not be enabled It is used
76
+// to check that the wiring to the thermistor is not broken. 
77
+// Otherwise this would lead to the heater being powered on all the time.
78
+#define HEATER_0_MINTEMP 5
79
+#define HEATER_1_MINTEMP 5
80
+#define HEATER_2_MINTEMP 5
81
+#define BED_MINTEMP 5
82
+
83
+// When temperature exceeds max temp, your heater will be switched off.
84
+// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure!
85
+// You should use MINTEMP for thermistor short/failure protection.
86
+#define HEATER_0_MAXTEMP 275
87
+#define HEATER_1_MAXTEMP 275
88
+#define HEATER_2_MAXTEMP 275
89
+#define BED_MAXTEMP 150
90
+
91
+
92
+// PID settings:
93
+// Comment the following line to disable PID and enable bang-bang.
94
+#define PIDTEMP
95
+#define PID_MAX 255 // limits current to nozzle; 255=full current
96
+#ifdef PIDTEMP
97
+  //#define PID_DEBUG // Sends debug data to the serial port. 
98
+  //#define PID_OPENLOOP 1 // Puts PID in open loop. M104 sets the output power in %
99
+  #define PID_INTEGRAL_DRIVE_MAX 255  //limit for the integral term
100
+  #define K1 0.95 //smoothing factor withing the PID
101
+  #define PID_dT ((16.0 * 8.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the
102
+
103
+// If you are using a preconfigured hotend then you can use one of the value sets by uncommenting it
104
+// Creatr
105
+    #define  DEFAULT_Kp 6.8
106
+    #define  DEFAULT_Ki 0.24  
107
+    #define  DEFAULT_Kd 48.15  
108
+
109
+// Makergear
110
+//    #define  DEFAULT_Kp 7.0
111
+//    #define  DEFAULT_Ki 0.1  
112
+//    #define  DEFAULT_Kd 12  
113
+
114
+// Mendel Parts V9 on 12V    
115
+//    #define  DEFAULT_Kp 63.0
116
+//    #define  DEFAULT_Ki 2.25
117
+//    #define  DEFAULT_Kd 440
118
+#endif // PIDTEMP
119
+
120
+//this prevents dangerous Extruder moves, i.e. if the temperature is under the limit
121
+//can be software-disabled for whatever purposes by
122
+#define PREVENT_DANGEROUS_EXTRUDE
123
+//if PREVENT_DANGEROUS_EXTRUDE is on, you can still disable (uncomment) very long bits of extrusion separately.
124
+#define PREVENT_LENGTHY_EXTRUDE
125
+
126
+#define EXTRUDE_MINTEMP 150
127
+#define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) //prevent extrusion of very large distances.
128
+
129
+//===========================================================================
130
+//=============================Mechanical Settings===========================
131
+//===========================================================================
132
+
133
+// corse Endstop Settings
134
+#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors
135
+
136
+#ifndef ENDSTOPPULLUPS
137
+  // fine Enstop settings: Individual Pullups. will be ignord if ENDSTOPPULLUPS is defined
138
+  #define ENDSTOPPULLUP_XMAX
139
+  #define ENDSTOPPULLUP_YMAX
140
+  #define ENDSTOPPULLUP_ZMAX
141
+  #define ENDSTOPPULLUP_XMIN
142
+  #define ENDSTOPPULLUP_YMIN
143
+  //#define ENDSTOPPULLUP_ZMIN
144
+#endif
145
+
146
+#ifdef ENDSTOPPULLUPS
147
+  #define ENDSTOPPULLUP_XMAX
148
+  #define ENDSTOPPULLUP_YMAX
149
+  #define ENDSTOPPULLUP_ZMAX
150
+  #define ENDSTOPPULLUP_XMIN
151
+  #define ENDSTOPPULLUP_YMIN
152
+  #define ENDSTOPPULLUP_ZMIN
153
+#endif
154
+
155
+
156
+  #define ENDSTOPPULLUP_ZMIN
157
+// The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins.
158
+const bool X_ENDSTOPS_INVERTING = false; // set to true to invert the logic of the endstops. 
159
+const bool Y_ENDSTOPS_INVERTING = false; // set to true to invert the logic of the endstops. 
160
+const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops. 
161
+//#define DISABLE_MAX_ENDSTOPS
162
+
163
+// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
164
+#define X_ENABLE_ON 0
165
+#define Y_ENABLE_ON 0
166
+#define Z_ENABLE_ON 0
167
+#define E_ENABLE_ON 0 // For all extruders
168
+
169
+// Disables axis when it's not being used.
170
+#define DISABLE_X false
171
+#define DISABLE_Y false
172
+#define DISABLE_Z true
173
+#define DISABLE_E true // For all extruders
174
+
175
+#define INVERT_X_DIR true    // for Mendel set to false, for Orca set to true
176
+#define INVERT_Y_DIR true    // for Mendel set to true, for Orca set to false
177
+#define INVERT_Z_DIR true     // for Mendel set to false, for Orca set to true
178
+#define INVERT_E0_DIR true   // for direct drive extruder v9 set to true, for geared extruder set to false
179
+#define INVERT_E1_DIR false    // for direct drive extruder v9 set to true, for geared extruder set to false
180
+#define INVERT_E2_DIR true   // for direct drive extruder v9 set to true, for geared extruder set to false
181
+
182
+// ENDSTOP SETTINGS:
183
+// Sets direction of endstops when homing; 1=MAX, -1=MIN
184
+#define X_HOME_DIR -1
185
+#define Y_HOME_DIR -1
186
+#define Z_HOME_DIR -1
187
+
188
+#define min_software_endstops true //If true, axis won't move to coordinates less than HOME_POS.
189
+#define max_software_endstops true  //If true, axis won't move to coordinates greater than the defined lengths below.
190
+#define X_MAX_LENGTH 230
191
+#define Y_MAX_LENGTH 270
192
+#define Z_MAX_LENGTH 200
193
+
194
+// The position of the homing switches. Use MAX_LENGTH * -0.5 if the center should be 0, 0, 0
195
+#define X_HOME_POS 0
196
+#define Y_HOME_POS 0
197
+#define Z_HOME_POS 0
198
+
199
+//// MOVEMENT SETTINGS
200
+#define NUM_AXIS 5 // The axis order in all axis related arrays is X, Y, Z, E
201
+#define HOMING_FEEDRATE {70*60, 70*60, 10*60, 0}  // set the homing speeds (mm/min)
202
+
203
+// default settings 
204
+
205
+#define DEFAULT_AXIS_STEPS_PER_UNIT   { 33.33*4, 33.33*4, 6400/5,55.465*4}  // default steps per unit for creatr with spindles 
206
+#define DEFAULT_MAX_FEEDRATE          {600, 600, 250, 45, 45}    // (mm/sec)    
207
+#define DEFAULT_MAX_ACCELERATION      {3000,3000,1000,10000, 10000}    // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for skeinforge 40+, for older versions raise them a lot.
208
+
209
+#define DEFAULT_ACCELERATION          3000    // X, Y, Z and E max acceleration in mm/s^2 for printing moves 
210
+#define DEFAULT_RETRACT_ACCELERATION  3000   // X, Y, Z and E max acceleration in mm/s^2 for r retracts
211
+
212
+// 
213
+#define DEFAULT_XYJERK                20.0    // (mm/sec)
214
+#define DEFAULT_ZJERK                 0.4     // (mm/sec)
215
+#define DEFAULT_EJERK                 5.0    // (mm/sec)
216
+
217
+// Oscillation delay
218
+#define OSCILLATION_DELAY 30
219
+
220
+
221
+//===========================================================================
222
+//=============================Additional Features===========================
223
+//===========================================================================
224
+
225
+// EEPROM
226
+// the microcontroller can store settings in the EEPROM, e.g. max velocity...
227
+// M500 - stores paramters in EEPROM
228
+// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).  
229
+// M502 - reverts to the default "factory settings".  You still need to store them in EEPROM afterwards if you want to.
230
+//define this to enable eeprom support
231
+//#define EEPROM_SETTINGS
232
+//to disable EEPROM Serial responses and decrease program space by ~1700 byte: comment this out:
233
+// please keep turned on if you can.
234
+//#define EEPROM_CHITCHAT
235
+
236
+//LCD and SD support
237
+//#define ULTRA_LCD  //general lcd support, also 16x2
238
+//#define SDSUPPORT // Enable SD Card Support in Hardware Console
239
+
240
+//#define ULTIMAKERCONTROLLER //as available from the ultimaker online store.
241
+//#define ULTIPANEL  //the ultipanel as on thingiverse
242
+
243
+
244
+#ifdef ULTIMAKERCONTROLLER    //automatic expansion
245
+ #define ULTIPANEL
246
+ #define NEWPANEL
247
+#endif 
248
+ 
249
+
250
+#ifdef ULTIPANEL
251
+//  #define NEWPANEL  //enable this if you have a click-encoder panel
252
+  #define SDSUPPORT
253
+  #define ULTRA_LCD
254
+  #define LCD_WIDTH 20
255
+  #define LCD_HEIGHT 4
256
+  
257
+// Preheat Constants
258
+  #define PLA_PREHEAT_HOTEND_TEMP 180 
259
+  #define PLA_PREHEAT_HPB_TEMP 70
260
+  #define PLA_PREHEAT_FAN_SPEED 255		// Insert Value between 0 and 255
261
+
262
+  #define ABS_PREHEAT_HOTEND_TEMP 240
263
+  #define ABS_PREHEAT_HPB_TEMP 100
264
+  #define ABS_PREHEAT_FAN_SPEED 255		// Insert Value between 0 and 255
265
+
266
+#else //no panel but just lcd 
267
+  #ifdef ULTRA_LCD
268
+    #define LCD_WIDTH 16
269
+    #define LCD_HEIGHT 2    
270
+  #endif
271
+#endif
272
+
273
+// Increase the FAN pwm frequency. Removes the PWM noise but increases heating in the FET/Arduino
274
+#define FAST_PWM_FAN
275
+
276
+// M240  Triggers a camera by emulating a Canon RC-1 Remote
277
+// Data from: http://www.doc-diy.net/photo/rc-1_hacked/
278
+// #define PHOTOGRAPH_PIN     23
279
+
280
+#include "Configuration_adv.h"
281
+#include "thermistortables.h"
282
+
283
+#endif //__CONFIGURATION_H

+ 245 - 0
Configuration_adv.h

@@ -0,0 +1,245 @@
1
+#ifndef CONFIGURATION_ADV_H
2
+#define CONFIGURATION_ADV_H
3
+
4
+//===========================================================================
5
+//=============================Thermal Settings  ============================
6
+//===========================================================================
7
+
8
+// Select one of these only to define how the bed temp is read.
9
+//
10
+//#define BED_LIMIT_SWITCHING
11
+#ifdef BED_LIMIT_SWITCHING
12
+  #define BED_HYSTERESIS 2 //only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS
13
+#endif
14
+#define BED_CHECK_INTERVAL 5000 //ms
15
+
16
+//// Heating sanity check:
17
+// This waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature
18
+// If the temperature has not increased at the end of that period, the target temperature is set to zero. 
19
+// It can be reset with another M104/M109
20
+//#define WATCHPERIOD 20000 //20 seconds
21
+
22
+// Wait for Cooldown
23
+// This defines if the M109 call should not block if it is cooling down.
24
+// example: From a current temp of 220, you set M109 S200. 
25
+// if CooldownNoWait is defined M109 will not wait for the cooldown to finish
26
+#define CooldownNoWait true
27
+
28
+#ifdef PIDTEMP
29
+  // this adds an experimental additional term to the heatingpower, proportional to the extrusion speed.
30
+  // if Kc is choosen well, the additional required power due to increased melting should be compensated.
31
+  #define PID_ADD_EXTRUSION_RATE  
32
+  #ifdef PID_ADD_EXTRUSION_RATE
33
+    #define  DEFAULT_Kc (1) //heatingpower=Kc*(e_speed)
34
+  #endif
35
+#endif
36
+
37
+
38
+//automatic temperature: The hot end target temperature is calculated by all the buffered lines of gcode.
39
+//The maximum buffered steps/sec of the extruder motor are called "se".
40
+//You enter the autotemp mode by a M109 S<mintemp> T<maxtemp> F<factor>
41
+// the target temperature is set to mintemp+factor*se[steps/sec] and limited by mintemp and maxtemp
42
+// you exit the value by any M109 without F*
43
+// Also, if the temperature is set to a value <mintemp, it is not changed by autotemp.
44
+// on an ultimaker, some initial testing worked with M109 S215 B260 F1 in the start.gcode
45
+#define AUTOTEMP
46
+#ifdef AUTOTEMP
47
+  #define AUTOTEMP_OLDWEIGHT 0.98
48
+#endif
49
+
50
+//  extruder run-out prevention. 
51
+//if the machine is idle, and the temperature over MINTEMP, every couple of SECONDS some filament is extruded
52
+//#define EXTRUDER_RUNOUT_PREVENT  
53
+#define EXTRUDER_RUNOUT_MINTEMP 190  
54
+#define EXTRUDER_RUNOUT_SECONDS 30.
55
+#define EXTRUDER_RUNOUT_ESTEPS 14. //mm filament
56
+#define EXTRUDER_RUNOUT_SPEED 1500.  //extrusion speed
57
+#define EXTRUDER_RUNOUT_EXTRUDE 100
58
+
59
+//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements.
60
+//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET"
61
+#define TEMP_SENSOR_AD595_OFFSET 0.0
62
+#define TEMP_SENSOR_AD595_GAIN   1.0
63
+
64
+//This is for controlling a fan to cool down the stepper drivers
65
+//it will turn on when any driver is enabled
66
+//and turn off after the set amount of seconds from last driver being disabled again
67
+//#define CONTROLLERFAN_PIN 23 //Pin used for the fan to cool controller, comment out to disable this function
68
+#define CONTROLLERFAN_SEC 60 //How many seconds, after all motors were disabled, the fan should run
69
+
70
+//===========================================================================
71
+//=============================Mechanical Settings===========================
72
+//===========================================================================
73
+
74
+// This defines the number of extruders
75
+#define EXTRUDERS 2
76
+
77
+#define ENDSTOPS_ONLY_FOR_HOMING // If defined the endstops will only be used for homing
78
+
79
+//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
80
+
81
+//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
82
+#define X_HOME_RETRACT_MM 5 
83
+#define Y_HOME_RETRACT_MM 5 
84
+#define Z_HOME_RETRACT_MM 1 
85
+//#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
86
+
87
+#define AXIS_RELATIVE_MODES {false, false, false, false}
88
+
89
+#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step)
90
+
91
+//default stepper release if idle
92
+#define DEFAULT_STEPPER_DEACTIVE_TIME 60
93
+
94
+#define DEFAULT_MINIMUMFEEDRATE       0.0     // minimum feedrate
95
+#define DEFAULT_MINTRAVELFEEDRATE     0.0
96
+
97
+// minimum time in microseconds that a movement needs to take if the buffer is emptied.
98
+#define DEFAULT_MINSEGMENTTIME        20000
99
+
100
+// If defined the movements slow down when the look ahead buffer is only half full
101
+#define SLOWDOWN
102
+
103
+// Frequency limit
104
+// See nophead's blog for more info
105
+// Not working O
106
+//#define XY_FREQUENCY_LIMIT  15
107
+
108
+// Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end
109
+// of the buffer and all stops. This should not be much greater than zero and should only be changed
110
+// if unwanted behavior is observed on a user's machine when running at very slow speeds.
111
+#define MINIMUM_PLANNER_SPEED 0.05// (mm/sec)
112
+
113
+//===========================================================================
114
+//=============================Additional Features===========================
115
+//===========================================================================
116
+
117
+
118
+#define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
119
+#define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // no z because of layer shift.
120
+
121
+// The hardware watchdog should halt the Microcontroller, in case the firmware gets stuck somewhere. However:
122
+// the Watchdog is not working well, so please only enable this for testing
123
+// this enables the watchdog interrupt.
124
+//#define USE_WATCHDOG
125
+//#ifdef USE_WATCHDOG
126
+  // you cannot reboot on a mega2560 due to a bug in he bootloader. Hence, you have to reset manually, and this is done hereby:
127
+//#define RESET_MANUAL
128
+//#define WATCHDOG_TIMEOUT 4  //seconds
129
+//#endif
130
+
131
+// extruder advance constant (s2/mm3)
132
+//
133
+// advance (steps) = STEPS_PER_CUBIC_MM_E * EXTUDER_ADVANCE_K * cubic mm per second ^ 2
134
+//
135
+// hooke's law says:		force = k * distance
136
+// bernoulli's priniciple says:	v ^ 2 / 2 + g . h + pressure / density = constant
137
+// so: v ^ 2 is proportional to number of steps we advance the extruder
138
+//#define ADVANCE
139
+
140
+#ifdef ADVANCE
141
+  #define EXTRUDER_ADVANCE_K .0
142
+
143
+  #define D_FILAMENT 2.85
144
+  #define STEPS_MM_E 836
145
+  #define EXTRUTION_AREA (0.25 * D_FILAMENT * D_FILAMENT * 3.14159)
146
+  #define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS]/ EXTRUTION_AREA)
147
+
148
+#endif // ADVANCE
149
+
150
+// Arc interpretation settings:
151
+#define MM_PER_ARC_SEGMENT 1
152
+#define N_ARC_CORRECTION 25
153
+
154
+const int dropsegments=5; //everything with less than this number of steps will be ignored as move and joined with the next movement
155
+
156
+// If you are using a RAMPS board or cheap E-bay purchased boards that do not detect when an SD card is inserted
157
+// You can get round this by connecting a push button or single throw switch to the pin defined as SDCARDCARDDETECT 
158
+// in the pins.h file.  When using a push button pulling the pin to ground this will need inverted.  This setting should
159
+// be commented out otherwise
160
+#define SDCARDDETECTINVERTED 
161
+
162
+#ifdef ULTIPANEL
163
+ #undef SDCARDDETECTINVERTED
164
+#endif
165
+//===========================================================================
166
+//=============================Buffers           ============================
167
+//===========================================================================
168
+
169
+// The number of linear motions that can be in the plan at any give time.  
170
+// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ringbuffering.
171
+#if defined SDSUPPORT
172
+  #define BLOCK_BUFFER_SIZE 16   // SD,LCD,Buttons take more memory, block buffer needs to be smaller
173
+#else
174
+  #define BLOCK_BUFFER_SIZE 16 // maximize block buffer
175
+#endif
176
+
177
+
178
+//The ASCII buffer for recieving from the serial:
179
+#define MAX_CMD_SIZE 96
180
+#define BUFSIZE 4
181
+
182
+
183
+// Firmware based and LCD controled retract
184
+// M207 and M208 can be used to define parameters for the retraction. 
185
+// The retraction can be called by the slicer using G10 and G11
186
+// until then, intended retractions can be detected by moves that only extrude and the direction. 
187
+// the moves are than replaced by the firmware controlled ones.
188
+
189
+// #define FWRETRACT  //ONLY PARTIALLY TESTED
190
+#define MIN_RETRACT 0.1 //minimum extruded mm to accept a automatic gcode retraction attempt
191
+
192
+//===========================================================================
193
+//=============================  Define Defines  ============================
194
+//===========================================================================
195
+
196
+#if TEMP_SENSOR_0 > 0
197
+  #define THERMISTORHEATER_0 TEMP_SENSOR_0
198
+  #define HEATER_0_USES_THERMISTOR
199
+#endif
200
+#if TEMP_SENSOR_1 > 0
201
+  #define THERMISTORHEATER_1 TEMP_SENSOR_1
202
+  #define HEATER_1_USES_THERMISTOR
203
+#endif
204
+#if TEMP_SENSOR_2 > 0
205
+  #define THERMISTORHEATER_2 TEMP_SENSOR_2
206
+  #define HEATER_2_USES_THERMISTOR
207
+#endif
208
+#if TEMP_SENSOR_BED > 0
209
+  #define THERMISTORBED TEMP_SENSOR_BED
210
+  #define BED_USES_THERMISTOR
211
+#endif
212
+#if TEMP_SENSOR_0 == -1
213
+  #define HEATER_0_USES_AD595
214
+#endif
215
+#if TEMP_SENSOR_1 == -1
216
+  #define HEATER_1_USES_AD595
217
+#endif
218
+#if TEMP_SENSOR_2 == -1
219
+  #define HEATER_2_USES_AD595
220
+#endif
221
+#if TEMP_SENSOR_BED == -1
222
+  #define BED_USES_AD595
223
+#endif
224
+#if TEMP_SENSOR_0 == -2
225
+  #define HEATER_0_USES_MAX6675
226
+#endif
227
+#if TEMP_SENSOR_0 == 0
228
+  #undef HEATER_0_MINTEMP
229
+  #undef HEATER_0_MAXTEMP
230
+#endif
231
+#if TEMP_SENSOR_1 == 0
232
+  #undef HEATER_1_MINTEMP
233
+  #undef HEATER_1_MAXTEMP
234
+#endif
235
+#if TEMP_SENSOR_2 == 0
236
+  #undef HEATER_2_MINTEMP
237
+  #undef HEATER_2_MAXTEMP
238
+#endif
239
+#if TEMP_SENSOR_BED == 0
240
+  #undef BED_MINTEMP
241
+  #undef BED_MAXTEMP
242
+#endif
243
+
244
+
245
+#endif //__CONFIGURATION_ADV_H

+ 196 - 0
EEPROMwrite.h

@@ -0,0 +1,196 @@
1
+#ifndef EEPROM_H
2
+#define EEPROM_H
3
+
4
+#include "Marlin.h"
5
+#include "planner.h"
6
+#include "temperature.h"
7
+//#include <EEPROM.h>
8
+
9
+
10
+
11
+template <class T> int EEPROM_writeAnything(int &ee, const T& value)
12
+{
13
+  const byte* p = (const byte*)(const void*)&value;
14
+  int i;
15
+  for (i = 0; i < (int)sizeof(value); i++)
16
+    eeprom_write_byte((unsigned char *)ee++, *p++);
17
+  return i;
18
+}
19
+
20
+template <class T> int EEPROM_readAnything(int &ee, T& value)
21
+{
22
+  byte* p = (byte*)(void*)&value;
23
+  int i;
24
+  for (i = 0; i < (int)sizeof(value); i++)
25
+    *p++ = eeprom_read_byte((unsigned char *)ee++);
26
+  return i;
27
+}
28
+//======================================================================================
29
+
30
+
31
+
32
+
33
+#define EEPROM_OFFSET 100
34
+
35
+
36
+// IMPORTANT:  Whenever there are changes made to the variables stored in EEPROM
37
+// in the functions below, also increment the version number. This makes sure that
38
+// the default values are used whenever there is a change to the data, to prevent
39
+// wrong data being written to the variables.
40
+// ALSO:  always make sure the variables in the Store and retrieve sections are in the same order.
41
+#define EEPROM_VERSION "V05"  
42
+
43
+inline void EEPROM_StoreSettings() 
44
+{
45
+#ifdef EEPROM_SETTINGS
46
+  char ver[4]= "000";
47
+  int i=EEPROM_OFFSET;
48
+  EEPROM_writeAnything(i,ver); // invalidate data first 
49
+  EEPROM_writeAnything(i,axis_steps_per_unit);  
50
+  EEPROM_writeAnything(i,max_feedrate);  
51
+  EEPROM_writeAnything(i,max_acceleration_units_per_sq_second);
52
+  EEPROM_writeAnything(i,acceleration);
53
+  EEPROM_writeAnything(i,retract_acceleration);
54
+  EEPROM_writeAnything(i,minimumfeedrate);
55
+  EEPROM_writeAnything(i,mintravelfeedrate);
56
+  EEPROM_writeAnything(i,minsegmenttime);
57
+  EEPROM_writeAnything(i,max_xy_jerk);
58
+  EEPROM_writeAnything(i,max_z_jerk);
59
+  EEPROM_writeAnything(i,max_e_jerk);
60
+  #ifdef PIDTEMP
61
+    EEPROM_writeAnything(i,Kp);
62
+    EEPROM_writeAnything(i,Ki);
63
+    EEPROM_writeAnything(i,Kd);
64
+  #else
65
+    EEPROM_writeAnything(i,3000);
66
+    EEPROM_writeAnything(i,0);
67
+    EEPROM_writeAnything(i,0);
68
+  #endif
69
+  char ver2[4]=EEPROM_VERSION;
70
+  i=EEPROM_OFFSET;
71
+  EEPROM_writeAnything(i,ver2); // validate data
72
+  SERIAL_ECHO_START;
73
+  SERIAL_ECHOLNPGM("Settings Stored");
74
+#endif //EEPROM_SETTINGS
75
+}
76
+
77
+
78
+inline void EEPROM_printSettings()
79
+{  // if def=true, the default values will be used
80
+  #ifdef EEPROM_SETTINGS  
81
+      SERIAL_ECHO_START;
82
+      SERIAL_ECHOLNPGM("Steps per unit:");
83
+      SERIAL_ECHO_START;
84
+      SERIAL_ECHOPAIR("  M92 X",axis_steps_per_unit[0]);
85
+      SERIAL_ECHOPAIR(" Y",axis_steps_per_unit[1]);
86
+      SERIAL_ECHOPAIR(" Z",axis_steps_per_unit[2]);
87
+      SERIAL_ECHOPAIR(" E",axis_steps_per_unit[3]);
88
+      SERIAL_ECHOLN("");
89
+      
90
+    SERIAL_ECHO_START;
91
+      SERIAL_ECHOLNPGM("Maximum feedrates (mm/s):");
92
+      SERIAL_ECHO_START;
93
+      SERIAL_ECHOPAIR("  M203 X",max_feedrate[0]);
94
+      SERIAL_ECHOPAIR(" Y",max_feedrate[1] ); 
95
+      SERIAL_ECHOPAIR(" Z", max_feedrate[2] ); 
96
+      SERIAL_ECHOPAIR(" E", max_feedrate[3]);
97
+      SERIAL_ECHOLN("");
98
+    SERIAL_ECHO_START;
99
+      SERIAL_ECHOLNPGM("Maximum Acceleration (mm/s2):");
100
+      SERIAL_ECHO_START;
101
+      SERIAL_ECHOPAIR("  M201 X" ,max_acceleration_units_per_sq_second[0] ); 
102
+      SERIAL_ECHOPAIR(" Y" , max_acceleration_units_per_sq_second[1] ); 
103
+      SERIAL_ECHOPAIR(" Z" ,max_acceleration_units_per_sq_second[2] );
104
+      SERIAL_ECHOPAIR(" E" ,max_acceleration_units_per_sq_second[3]);
105
+      SERIAL_ECHOLN("");
106
+    SERIAL_ECHO_START;
107
+      SERIAL_ECHOLNPGM("Acceleration: S=acceleration, T=retract acceleration");
108
+      SERIAL_ECHO_START;
109
+      SERIAL_ECHOPAIR("  M204 S",acceleration ); 
110
+      SERIAL_ECHOPAIR(" T" ,retract_acceleration);
111
+      SERIAL_ECHOLN("");
112
+    SERIAL_ECHO_START;
113
+      SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum xY jerk (mm/s),  Z=maximum Z jerk (mm/s)");
114
+      SERIAL_ECHO_START;
115
+      SERIAL_ECHOPAIR("  M205 S",minimumfeedrate ); 
116
+      SERIAL_ECHOPAIR(" T" ,mintravelfeedrate ); 
117
+      SERIAL_ECHOPAIR(" B" ,minsegmenttime ); 
118
+      SERIAL_ECHOPAIR(" X" ,max_xy_jerk ); 
119
+      SERIAL_ECHOPAIR(" Z" ,max_z_jerk);
120
+      SERIAL_ECHOPAIR(" E" ,max_e_jerk);
121
+      SERIAL_ECHOLN(""); 
122
+    #ifdef PIDTEMP
123
+      SERIAL_ECHO_START;
124
+      SERIAL_ECHOLNPGM("PID settings:");
125
+      SERIAL_ECHO_START;
126
+      SERIAL_ECHOPAIR("   M301 P",Kp); 
127
+      SERIAL_ECHOPAIR(" I" ,Ki/PID_dT); 
128
+      SERIAL_ECHOPAIR(" D" ,Kd*PID_dT);
129
+      SERIAL_ECHOLN(""); 
130
+    #endif
131
+  #endif
132
+} 
133
+
134
+
135
+inline void EEPROM_RetrieveSettings(bool def=false)
136
+{  // if def=true, the default values will be used
137
+  #ifdef EEPROM_SETTINGS
138
+    int i=EEPROM_OFFSET;
139
+    char stored_ver[4];
140
+    char ver[4]=EEPROM_VERSION;
141
+    EEPROM_readAnything(i,stored_ver); //read stored version
142
+    //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]");
143
+    if ((!def)&&(strncmp(ver,stored_ver,3)==0)) 
144
+    {   // version number match
145
+      EEPROM_readAnything(i,axis_steps_per_unit);  
146
+      EEPROM_readAnything(i,max_feedrate);  
147
+      EEPROM_readAnything(i,max_acceleration_units_per_sq_second);
148
+      EEPROM_readAnything(i,acceleration);
149
+      EEPROM_readAnything(i,retract_acceleration);
150
+      EEPROM_readAnything(i,minimumfeedrate);
151
+      EEPROM_readAnything(i,mintravelfeedrate);
152
+      EEPROM_readAnything(i,minsegmenttime);
153
+      EEPROM_readAnything(i,max_xy_jerk);
154
+      EEPROM_readAnything(i,max_z_jerk);
155
+      EEPROM_readAnything(i,max_e_jerk);
156
+      #ifndef PIDTEMP
157
+        float Kp,Ki,Kd;
158
+      #endif
159
+      EEPROM_readAnything(i,Kp);
160
+      EEPROM_readAnything(i,Ki);
161
+      EEPROM_readAnything(i,Kd);
162
+
163
+      SERIAL_ECHO_START;
164
+      SERIAL_ECHOLNPGM("Stored settings retreived:");
165
+    }
166
+    else 
167
+  #endif
168
+    {
169
+      float tmp1[]=DEFAULT_AXIS_STEPS_PER_UNIT;
170
+      float tmp2[]=DEFAULT_MAX_FEEDRATE;
171
+      long tmp3[]=DEFAULT_MAX_ACCELERATION;
172
+      for (short i=0;i<4;i++) 
173
+      {
174
+        axis_steps_per_unit[i]=tmp1[i];  
175
+        max_feedrate[i]=tmp2[i];  
176
+        max_acceleration_units_per_sq_second[i]=tmp3[i];
177
+      }
178
+      acceleration=DEFAULT_ACCELERATION;
179
+      retract_acceleration=DEFAULT_RETRACT_ACCELERATION;
180
+      minimumfeedrate=DEFAULT_MINIMUMFEEDRATE;
181
+      minsegmenttime=DEFAULT_MINSEGMENTTIME;       
182
+      mintravelfeedrate=DEFAULT_MINTRAVELFEEDRATE;
183
+      max_xy_jerk=DEFAULT_XYJERK;
184
+      max_z_jerk=DEFAULT_ZJERK;
185
+      max_e_jerk=DEFAULT_EJERK;
186
+      SERIAL_ECHO_START;
187
+      SERIAL_ECHOLN("Using Default settings:");
188
+    }
189
+  #ifdef EEPROM_CHITCHAT
190
+    EEPROM_printSettings();
191
+  #endif
192
+}  
193
+
194
+#endif
195
+
196
+

+ 191 - 0
Marlin.h

@@ -0,0 +1,191 @@
1
+// Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
2
+// Licence: GPL
3
+
4
+#ifndef MARLIN_H
5
+#define MARLIN_H
6
+
7
+#define  HardwareSerial_h // trick to disable the standard HWserial
8
+
9
+#define  FORCE_INLINE __attribute__((always_inline)) inline
10
+
11
+#include <math.h>
12
+#include <stdio.h>
13
+#include <stdlib.h>
14
+#include <string.h>
15
+#include <inttypes.h>
16
+
17
+#include <util/delay.h>
18
+#include <avr/pgmspace.h>
19
+#include <avr/eeprom.h>
20
+#include  <avr/wdt.h>
21
+#include  <avr/interrupt.h>
22
+
23
+
24
+#include "fastio.h"
25
+#include "Configuration.h"
26
+#include "pins.h"
27
+
28
+#if ARDUINO >= 100 
29
+  #if defined(__AVR_ATmega644P__)
30
+    #include "WProgram.h"
31
+  #else
32
+    #include "Arduino.h"
33
+  #endif
34
+#else
35
+   #include "WProgram.h"
36
+#endif
37
+
38
+#include "MarlinSerial.h"
39
+
40
+#ifndef cbi
41
+#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
42
+#endif
43
+#ifndef sbi
44
+#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
45
+#endif
46
+
47
+#include "WString.h"
48
+
49
+#if MOTHERBOARD == 8  // Teensylu
50
+  #define MYSERIAL Serial
51
+#else
52
+  #define MYSERIAL MSerial
53
+#endif
54
+
55
+//this is a unfinsihed attemp to removes a lot of warning messages, see:
56
+// http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=57011
57
+//typedef char prog_char PROGMEM; 
58
+// //#define PSTR    (s )        ((const PROGMEM char *)(s))
59
+// //# define MYPGM(s) (__extension__({static prog_char __c[] = (s); &__c[0];})) 
60
+// //#define MYPGM(s) ((const prog_char *g PROGMEM=s))
61
+#define MYPGM(s) PSTR(s)
62
+//#define MYPGM(s)  (__extension__({static char __c[] __attribute__((__progmem__)) = (s); &__c[0];}))  //This is the normal behaviour
63
+//#define MYPGM(s)  (__extension__({static prog_char __c[]  = (s); &__c[0];})) //this does not work but hides the warnings
64
+
65
+
66
+#define SERIAL_PROTOCOL(x) MYSERIAL.print(x);
67
+#define SERIAL_PROTOCOL_F(x,y) MYSERIAL.print(x,y);
68
+#define SERIAL_PROTOCOLPGM(x) serialprintPGM(MYPGM(x));
69
+#define SERIAL_PROTOCOLLN(x) {MYSERIAL.print(x);MYSERIAL.write('\n');}
70
+#define SERIAL_PROTOCOLLNPGM(x) {serialprintPGM(MYPGM(x));MYSERIAL.write('\n');}
71
+
72
+
73
+const char errormagic[] PROGMEM ="Error:";
74
+const char echomagic[] PROGMEM ="echo:";
75
+#define SERIAL_ERROR_START serialprintPGM(errormagic);
76
+#define SERIAL_ERROR(x) SERIAL_PROTOCOL(x)
77
+#define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x)
78
+#define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x)
79
+#define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
80
+
81
+#define SERIAL_ECHO_START serialprintPGM(echomagic);
82
+#define SERIAL_ECHO(x) SERIAL_PROTOCOL(x)
83
+#define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x)
84
+#define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x)
85
+#define SERIAL_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
86
+
87
+#define SERIAL_ECHOPAIR(name,value) {SERIAL_ECHOPGM(name);SERIAL_ECHO(value);}
88
+
89
+
90
+//things to write to serial from Programmemory. saves 400 to 2k of RAM.
91
+#define SerialprintPGM(x) serialprintPGM(MYPGM(x))
92
+FORCE_INLINE void serialprintPGM(const char *str)
93
+{
94
+  char ch=pgm_read_byte(str);
95
+  while(ch)
96
+  {
97
+    MYSERIAL.write(ch);
98
+    ch=pgm_read_byte(++str);
99
+  }
100
+}
101
+
102
+
103
+void get_command();
104
+void process_commands();
105
+
106
+void manage_inactivity(byte debug);
107
+
108
+#if X_ENABLE_PIN > -1
109
+  #define  enable_x() WRITE(X_ENABLE_PIN, X_ENABLE_ON)
110
+  #define disable_x() WRITE(X_ENABLE_PIN,!X_ENABLE_ON)
111
+#else
112
+  #define enable_x() ;
113
+  #define disable_x() ;
114
+#endif
115
+
116
+#if Y_ENABLE_PIN > -1
117
+  #define  enable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON)
118
+  #define disable_y() WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON)
119
+#else
120
+  #define enable_y() ;
121
+  #define disable_y() ;
122
+#endif
123
+
124
+#if Z_ENABLE_PIN > -1
125
+  #define  enable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON)
126
+  #define disable_z() WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON)
127
+#else
128
+  #define enable_z() ;
129
+  #define disable_z() ;
130
+#endif
131
+
132
+#if defined(E0_ENABLE_PIN) && (E0_ENABLE_PIN > -1)
133
+  #define enable_e0() WRITE(E0_ENABLE_PIN, E_ENABLE_ON)
134
+  #define disable_e0() WRITE(E0_ENABLE_PIN,!E_ENABLE_ON)
135
+#else
136
+  #define enable_e0()  /* nothing */
137
+  #define disable_e0() /* nothing */
138
+#endif
139
+
140
+#if (EXTRUDERS > 1) && defined(E1_ENABLE_PIN) && (E1_ENABLE_PIN > -1)
141
+  #define enable_e1() WRITE(E1_ENABLE_PIN, E_ENABLE_ON)
142
+  #define disable_e1() WRITE(E1_ENABLE_PIN,!E_ENABLE_ON)
143
+#else
144
+  #define enable_e1()  /* nothing */
145
+  #define disable_e1() /* nothing */
146
+#endif
147
+
148
+#if (EXTRUDERS > 2) && defined(E2_ENABLE_PIN) && (E2_ENABLE_PIN > -1)
149
+  #define enable_e2() WRITE(E2_ENABLE_PIN, E_ENABLE_ON)
150
+  #define disable_e2() WRITE(E2_ENABLE_PIN,!E_ENABLE_ON)
151
+#else
152
+  #define enable_e2()  /* nothing */
153
+  #define disable_e2() /* nothing */
154
+#endif
155
+
156
+
157
+enum AxisEnum {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, E_AXIS=3};
158
+
159
+
160
+void FlushSerialRequestResend();
161
+void ClearToSend();
162
+
163
+void get_coordinates();
164
+void prepare_move();
165
+void kill();
166
+void Stop();
167
+
168
+bool IsStopped();
169
+
170
+void enquecommand(const char *cmd); //put an ascii command at the end of the current buffer.
171
+void prepare_arc_move(char isclockwise);
172
+
173
+#ifdef FAST_PWM_FAN
174
+void setPwmFrequency(uint8_t pin, int val);
175
+#endif
176
+
177
+#ifndef CRITICAL_SECTION_START
178
+  #define CRITICAL_SECTION_START  unsigned char _sreg = SREG; cli();
179
+  #define CRITICAL_SECTION_END    SREG = _sreg;
180
+#endif //CRITICAL_SECTION_START
181
+
182
+extern float homing_feedrate[];
183
+extern bool axis_relative_modes[];
184
+extern float current_position[NUM_AXIS] ;
185
+extern float add_homeing[3];
186
+extern unsigned char FanSpeed;
187
+
188
+// Handling multiple extruders pins
189
+extern uint8_t active_extruder;
190
+
191
+#endif

+ 329 - 0
MarlinSerial.cpp

@@ -0,0 +1,329 @@
1
+/*
2
+  HardwareSerial.cpp - Hardware serial library for Wiring
3
+  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.
4
+
5
+  This library is free software; you can redistribute it and/or
6
+  modify it under the terms of the GNU Lesser General Public
7
+  License as published by the Free Software Foundation; either
8
+  version 2.1 of the License, or (at your option) any later version.
9
+
10
+  This library is distributed in the hope that it will be useful,
11
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
+  Lesser General Public License for more details.
14
+
15
+  You should have received a copy of the GNU Lesser General Public
16
+  License along with this library; if not, write to the Free Software
17
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
+  
19
+  Modified 23 November 2006 by David A. Mellis
20
+  Modified 28 September 2010 by Mark Sproul
21
+*/
22
+
23
+#include "Marlin.h"
24
+#include "MarlinSerial.h"
25
+
26
+#if MOTHERBOARD != 8 // !teensylu
27
+// this next line disables the entire HardwareSerial.cpp, 
28
+// this is so I can support Attiny series and any other chip without a uart
29
+#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)
30
+
31
+#if defined(UBRRH) || defined(UBRR0H)
32
+  ring_buffer rx_buffer  =  { { 0 }, 0, 0 };
33
+#endif
34
+
35
+FORCE_INLINE void store_char(unsigned char c)
36
+{
37
+  int i = (unsigned int)(rx_buffer.head + 1) % RX_BUFFER_SIZE;
38
+
39
+  // if we should be storing the received character into the location
40
+  // just before the tail (meaning that the head would advance to the
41
+  // current location of the tail), we're about to overflow the buffer
42
+  // and so we don't write the character or advance the head.
43
+  if (i != rx_buffer.tail) {
44
+    rx_buffer.buffer[rx_buffer.head] = c;
45
+    rx_buffer.head = i;
46
+  }
47
+}
48
+
49
+
50
+//#elif defined(SIG_USART_RECV)
51
+#if defined(USART0_RX_vect)
52
+  // fixed by Mark Sproul this is on the 644/644p
53
+  //SIGNAL(SIG_USART_RECV)
54
+  SIGNAL(USART0_RX_vect)
55
+  {
56
+  #if defined(UDR0)
57
+    unsigned char c  =  UDR0;
58
+  #elif defined(UDR)
59
+    unsigned char c  =  UDR;  //  atmega8, atmega32
60
+  #else
61
+    #error UDR not defined
62
+  #endif
63
+    store_char(c);
64
+  }
65
+#endif
66
+
67
+// Constructors ////////////////////////////////////////////////////////////////
68
+
69
+MarlinSerial::MarlinSerial()
70
+{
71
+
72
+}
73
+
74
+// Public Methods //////////////////////////////////////////////////////////////
75
+
76
+void MarlinSerial::begin(long baud)
77
+{
78
+  uint16_t baud_setting;
79
+  bool useU2X0 = true;
80
+
81
+#if F_CPU == 16000000UL
82
+  // hardcoded exception for compatibility with the bootloader shipped
83
+  // with the Duemilanove and previous boards and the firmware on the 8U2
84
+  // on the Uno and Mega 2560.
85
+  if (baud == 57600) {
86
+    useU2X0 = false;
87
+  }
88
+#endif
89
+  
90
+  if (useU2X0) {
91
+    UCSR0A = 1 << U2X0;
92
+    baud_setting = (F_CPU / 4 / baud - 1) / 2;
93
+  } else {
94
+    UCSR0A = 0;
95
+    baud_setting = (F_CPU / 8 / baud - 1) / 2;
96
+  }
97
+
98
+  // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
99
+  UBRR0H = baud_setting >> 8;
100
+  UBRR0L = baud_setting;
101
+
102
+  sbi(UCSR0B, RXEN0);
103
+  sbi(UCSR0B, TXEN0);
104
+  sbi(UCSR0B, RXCIE0);
105
+}
106
+
107
+void MarlinSerial::end()
108
+{
109
+  cbi(UCSR0B, RXEN0);
110
+  cbi(UCSR0B, TXEN0);
111
+  cbi(UCSR0B, RXCIE0);  
112
+}
113
+
114
+
115
+
116
+int MarlinSerial::peek(void)
117
+{
118
+  if (rx_buffer.head == rx_buffer.tail) {
119
+    return -1;
120
+  } else {
121
+    return rx_buffer.buffer[rx_buffer.tail];
122
+  }
123
+}
124
+
125
+int MarlinSerial::read(void)
126
+{
127
+  // if the head isn't ahead of the tail, we don't have any characters
128
+  if (rx_buffer.head == rx_buffer.tail) {
129
+    return -1;
130
+  } else {
131
+    unsigned char c = rx_buffer.buffer[rx_buffer.tail];
132
+    rx_buffer.tail = (unsigned int)(rx_buffer.tail + 1) % RX_BUFFER_SIZE;
133
+    return c;
134
+  }
135
+}
136
+
137
+void MarlinSerial::flush()
138
+{
139
+  // don't reverse this or there may be problems if the RX interrupt
140
+  // occurs after reading the value of rx_buffer_head but before writing
141
+  // the value to rx_buffer_tail; the previous value of rx_buffer_head
142
+  // may be written to rx_buffer_tail, making it appear as if the buffer
143
+  // don't reverse this or there may be problems if the RX interrupt
144
+  // occurs after reading the value of rx_buffer_head but before writing
145
+  // the value to rx_buffer_tail; the previous value of rx_buffer_head
146
+  // may be written to rx_buffer_tail, making it appear as if the buffer
147
+  // were full, not empty.
148
+  rx_buffer.head = rx_buffer.tail;
149
+}
150
+
151
+
152
+
153
+
154
+/// imports from print.h
155
+
156
+
157
+
158
+
159
+void MarlinSerial::print(char c, int base)
160
+{
161
+  print((long) c, base);
162
+}
163
+
164
+void MarlinSerial::print(unsigned char b, int base)
165
+{
166
+  print((unsigned long) b, base);
167
+}
168
+
169
+void MarlinSerial::print(int n, int base)
170
+{
171
+  print((long) n, base);
172
+}
173
+
174
+void MarlinSerial::print(unsigned int n, int base)
175
+{
176
+  print((unsigned long) n, base);
177
+}
178
+
179
+void MarlinSerial::print(long n, int base)
180
+{
181
+  if (base == 0) {
182
+    write(n);
183
+  } else if (base == 10) {
184
+    if (n < 0) {
185
+      print('-');
186
+      n = -n;
187
+    }
188
+    printNumber(n, 10);
189
+  } else {
190
+    printNumber(n, base);
191
+  }
192
+}
193
+
194
+void MarlinSerial::print(unsigned long n, int base)
195
+{
196
+  if (base == 0) write(n);
197
+  else printNumber(n, base);
198
+}
199
+
200
+void MarlinSerial::print(double n, int digits)
201
+{
202
+  printFloat(n, digits);
203
+}
204
+
205
+void MarlinSerial::println(void)
206
+{
207
+  print('\r');
208
+  print('\n');  
209
+}
210
+
211
+void MarlinSerial::println(const String &s)
212
+{
213
+  print(s);
214
+  println();
215
+}
216
+
217
+void MarlinSerial::println(const char c[])
218
+{
219
+  print(c);
220
+  println();
221
+}
222
+
223
+void MarlinSerial::println(char c, int base)
224
+{
225
+  print(c, base);
226
+  println();
227
+}
228
+
229
+void MarlinSerial::println(unsigned char b, int base)
230
+{
231
+  print(b, base);
232
+  println();
233
+}
234
+
235
+void MarlinSerial::println(int n, int base)
236
+{
237
+  print(n, base);
238
+  println();
239
+}
240
+
241
+void MarlinSerial::println(unsigned int n, int base)
242
+{
243
+  print(n, base);
244
+  println();
245
+}
246
+
247
+void MarlinSerial::println(long n, int base)
248
+{
249
+  print(n, base);
250
+  println();
251
+}
252
+
253
+void MarlinSerial::println(unsigned long n, int base)
254
+{
255
+  print(n, base);
256
+  println();
257
+}
258
+
259
+void MarlinSerial::println(double n, int digits)
260
+{
261
+  print(n, digits);
262
+  println();
263
+}
264
+
265
+// Private Methods /////////////////////////////////////////////////////////////
266
+
267
+void MarlinSerial::printNumber(unsigned long n, uint8_t base)
268
+{
269
+  unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. 
270
+  unsigned long i = 0;
271
+
272
+  if (n == 0) {
273
+    print('0');
274
+    return;
275
+  } 
276
+
277
+  while (n > 0) {
278
+    buf[i++] = n % base;
279
+    n /= base;
280
+  }
281
+
282
+  for (; i > 0; i--)
283
+    print((char) (buf[i - 1] < 10 ?
284
+      '0' + buf[i - 1] :
285
+      'A' + buf[i - 1] - 10));
286
+}
287
+
288
+void MarlinSerial::printFloat(double number, uint8_t digits) 
289
+{ 
290
+  // Handle negative numbers
291
+  if (number < 0.0)
292
+  {
293
+     print('-');
294
+     number = -number;
295
+  }
296
+
297
+  // Round correctly so that print(1.999, 2) prints as "2.00"
298
+  double rounding = 0.5;
299
+  for (uint8_t i=0; i<digits; ++i)
300
+    rounding /= 10.0;
301
+  
302
+  number += rounding;
303
+
304
+  // Extract the integer part of the number and print it
305
+  unsigned long int_part = (unsigned long)number;
306
+  double remainder = number - (double)int_part;
307
+  print(int_part);
308
+
309
+  // Print the decimal point, but only if there are digits beyond
310
+  if (digits > 0)
311
+    print("."); 
312
+
313
+  // Extract digits from the remainder one at a time
314
+  while (digits-- > 0)
315
+  {
316
+    remainder *= 10.0;
317
+    int toPrint = int(remainder);
318
+    print(toPrint);
319
+    remainder -= toPrint; 
320
+  } 
321
+}
322
+// Preinstantiate Objects //////////////////////////////////////////////////////
323
+
324
+
325
+MarlinSerial MSerial;
326
+
327
+#endif // whole file
328
+#endif //teensylu
329
+

+ 150 - 0
MarlinSerial.h

@@ -0,0 +1,150 @@
1
+/*
2
+  HardwareSerial.h - Hardware serial library for Wiring
3
+  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.
4
+
5
+  This library is free software; you can redistribute it and/or
6
+  modify it under the terms of the GNU Lesser General Public
7
+  License as published by the Free Software Foundation; either
8
+  version 2.1 of the License, or (at your option) any later version.
9
+
10
+  This library is distributed in the hope that it will be useful,
11
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
+  Lesser General Public License for more details.
14
+
15
+  You should have received a copy of the GNU Lesser General Public
16
+  License along with this library; if not, write to the Free Software
17
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
+
19
+  Modified 28 September 2010 by Mark Sproul
20
+*/
21
+
22
+#ifndef MarlinSerial_h
23
+#define MarlinSerial_h
24
+#include "Marlin.h"
25
+
26
+
27
+#define DEC 10
28
+#define HEX 16
29
+#define OCT 8
30
+#define BIN 2
31
+#define BYTE 0
32
+
33
+
34
+#if MOTHERBOARD != 8 // ! teensylu
35
+// Define constants and variables for buffering incoming serial data.  We're
36
+// using a ring buffer (I think), in which rx_buffer_head is the index of the
37
+// location to which to write the next incoming character and rx_buffer_tail
38
+// is the index of the location from which to read.
39
+#define RX_BUFFER_SIZE 128
40
+
41
+
42
+struct ring_buffer
43
+{
44
+  unsigned char buffer[RX_BUFFER_SIZE];
45
+  int head;
46
+  int tail;
47
+};
48
+
49
+#if defined(UBRRH) || defined(UBRR0H)
50
+  extern ring_buffer rx_buffer;
51
+#endif
52
+
53
+class MarlinSerial //: public Stream
54
+{
55
+
56
+  public:
57
+    MarlinSerial();
58
+    void begin(long);
59
+    void end();
60
+    int peek(void);
61
+    int read(void);
62
+    void flush(void);
63
+    
64
+    FORCE_INLINE int available(void)
65
+    {
66
+      return (unsigned int)(RX_BUFFER_SIZE + rx_buffer.head - rx_buffer.tail) % RX_BUFFER_SIZE;
67
+    }
68
+    
69
+    FORCE_INLINE void write(uint8_t c)
70
+    {
71
+      while (!((UCSR0A) & (1 << UDRE0)))
72
+        ;
73
+
74
+      UDR0 = c;
75
+    }
76
+    
77
+    
78
+    FORCE_INLINE void checkRx(void)
79
+    {
80
+      if((UCSR0A & (1<<RXC0)) != 0) {
81
+        unsigned char c  =  UDR0;
82
+        int i = (unsigned int)(rx_buffer.head + 1) % RX_BUFFER_SIZE;
83
+
84
+        // if we should be storing the received character into the location
85
+        // just before the tail (meaning that the head would advance to the
86
+        // current location of the tail), we're about to overflow the buffer
87
+        // and so we don't write the character or advance the head.
88
+        if (i != rx_buffer.tail) {
89
+          rx_buffer.buffer[rx_buffer.head] = c;
90
+          rx_buffer.head = i;
91
+        }
92
+      }
93
+    }
94
+    
95
+    
96
+    private:
97
+    void printNumber(unsigned long, uint8_t);
98
+    void printFloat(double, uint8_t);
99
+    
100
+    
101
+  public:
102
+    
103
+    FORCE_INLINE void write(const char *str)
104
+    {
105
+      while (*str)
106
+        write(*str++);
107
+    }
108
+
109
+
110
+    FORCE_INLINE void write(const uint8_t *buffer, size_t size)
111
+    {
112
+      while (size--)
113
+        write(*buffer++);
114
+    }
115
+
116
+    FORCE_INLINE void print(const String &s)
117
+    {
118
+      for (int i = 0; i < (int)s.length(); i++) {
119
+        write(s[i]);
120
+      }
121
+    }
122
+    
123
+    FORCE_INLINE void print(const char *str)
124
+    {
125
+      write(str);
126
+    }
127
+    void print(char, int = BYTE);
128
+    void print(unsigned char, int = BYTE);
129
+    void print(int, int = DEC);
130
+    void print(unsigned int, int = DEC);
131
+    void print(long, int = DEC);
132
+    void print(unsigned long, int = DEC);
133
+    void print(double, int = 2);
134
+
135
+    void println(const String &s);
136
+    void println(const char[]);
137
+    void println(char, int = BYTE);
138
+    void println(unsigned char, int = BYTE);
139
+    void println(int, int = DEC);
140
+    void println(unsigned int, int = DEC);
141
+    void println(long, int = DEC);
142
+    void println(unsigned long, int = DEC);
143
+    void println(double, int = 2);
144
+    void println(void);
145
+};
146
+
147
+extern MarlinSerial MSerial;
148
+#endif // ! teensylu
149
+
150
+#endif

File diff suppressed because it is too large
+ 1757 - 0
Marlin_gebruikte_dual_ballspindle_elecnieuw.ino


+ 643 - 0
Sd2Card.cpp

@@ -0,0 +1,643 @@
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
+ * <http://www.gnu.org/licenses/>.
19
+ */
20
+#include "Marlin.h"
21
+
22
+#ifdef SDSUPPORT
23
+#include "Sd2Card.h"
24
+//------------------------------------------------------------------------------
25
+#ifndef SOFTWARE_SPI
26
+// functions for hardware SPI
27
+//------------------------------------------------------------------------------
28
+// make sure SPCR rate is in expected bits
29
+#if (SPR0 != 0 || SPR1 != 1)
30
+#error unexpected SPCR bits
31
+#endif
32
+/**
33
+ * Initialize hardware SPI
34
+ * Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6]
35
+ */
36
+static void spiInit(uint8_t spiRate) {
37
+  // See avr processor documentation
38
+  SPCR = (1 << SPE) | (1 << MSTR) | (spiRate >> 1);
39
+  SPSR = spiRate & 1 || spiRate == 6 ? 0 : 1 << SPI2X;
40
+}
41
+//------------------------------------------------------------------------------
42
+/** SPI receive a byte */
43
+static uint8_t spiRec() {
44
+  SPDR = 0XFF;
45
+  while (!(SPSR & (1 << SPIF)));
46
+  return SPDR;
47
+}
48
+//------------------------------------------------------------------------------
49
+/** SPI read data - only one call so force inline */
50
+static inline __attribute__((always_inline))
51
+  void spiRead(uint8_t* buf, uint16_t nbyte) {
52
+  if (nbyte-- == 0) return;
53
+  SPDR = 0XFF;
54
+  for (uint16_t i = 0; i < nbyte; i++) {
55
+    while (!(SPSR & (1 << SPIF)));
56
+    buf[i] = SPDR;
57
+    SPDR = 0XFF;
58
+  }
59
+  while (!(SPSR & (1 << SPIF)));
60
+  buf[nbyte] = SPDR;
61
+}
62
+//------------------------------------------------------------------------------
63
+/** SPI send a byte */
64
+static void spiSend(uint8_t b) {
65
+  SPDR = b;
66
+  while (!(SPSR & (1 << SPIF)));
67
+}
68
+//------------------------------------------------------------------------------
69
+/** SPI send block - only one call so force inline */
70
+static inline __attribute__((always_inline))
71
+  void spiSendBlock(uint8_t token, const uint8_t* buf) {
72
+  SPDR = token;
73
+  for (uint16_t i = 0; i < 512; i += 2) {
74
+    while (!(SPSR & (1 << SPIF)));
75
+    SPDR = buf[i];
76
+    while (!(SPSR & (1 << SPIF)));
77
+    SPDR = buf[i + 1];
78
+  }
79
+  while (!(SPSR & (1 << SPIF)));
80
+}
81
+//------------------------------------------------------------------------------
82
+#else  // SOFTWARE_SPI
83
+//------------------------------------------------------------------------------
84
+/** nop to tune soft SPI timing */
85
+#define nop asm volatile ("nop\n\t")
86
+//------------------------------------------------------------------------------
87
+/** Soft SPI receive byte */
88
+static uint8_t spiRec() {
89
+  uint8_t data = 0;
90
+  // no interrupts during byte receive - about 8 us
91
+  cli();
92
+  // output pin high - like sending 0XFF
93
+  fastDigitalWrite(SPI_MOSI_PIN, HIGH);
94
+
95
+  for (uint8_t i = 0; i < 8; i++) {
96
+    fastDigitalWrite(SPI_SCK_PIN, HIGH);
97
+
98
+    // adjust so SCK is nice
99
+    nop;
100
+    nop;
101
+
102
+    data <<= 1;
103
+
104
+    if (fastDigitalRead(SPI_MISO_PIN)) data |= 1;
105
+
106
+    fastDigitalWrite(SPI_SCK_PIN, LOW);
107
+  }
108
+  // enable interrupts
109
+  sei();
110
+  return data;
111
+}
112
+//------------------------------------------------------------------------------
113
+/** Soft SPI read data */
114
+static void spiRead(uint8_t* buf, uint16_t nbyte) {
115
+  for (uint16_t i = 0; i < nbyte; i++) {
116
+    buf[i] = spiRec();
117
+  }
118
+}
119
+//------------------------------------------------------------------------------
120
+/** Soft SPI send byte */
121
+static void spiSend(uint8_t data) {
122
+  // no interrupts during byte send - about 8 us
123
+  cli();
124
+  for (uint8_t i = 0; i < 8; i++) {
125
+    fastDigitalWrite(SPI_SCK_PIN, LOW);
126
+
127
+    fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
128
+
129
+    data <<= 1;
130
+
131
+    fastDigitalWrite(SPI_SCK_PIN, HIGH);
132
+  }
133
+  // hold SCK high for a few ns
134
+  nop;
135
+  nop;
136
+  nop;
137
+  nop;
138
+
139
+  fastDigitalWrite(SPI_SCK_PIN, LOW);
140
+  // enable interrupts
141
+  sei();
142
+}
143
+//------------------------------------------------------------------------------
144
+/** Soft SPI send block */
145
+  void spiSendBlock(uint8_t token, const uint8_t* buf) {
146
+  spiSend(token);
147
+  for (uint16_t i = 0; i < 512; i++) {
148
+    spiSend(buf[i]);
149
+  }
150
+}
151
+#endif  // SOFTWARE_SPI
152
+//------------------------------------------------------------------------------
153
+// send command and return error code.  Return zero for OK
154
+uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
155
+  // select card
156
+  chipSelectLow();
157
+
158
+  // wait up to 300 ms if busy
159
+  waitNotBusy(300);
160
+
161
+  // send command
162
+  spiSend(cmd | 0x40);
163
+
164
+  // send argument
165
+  for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s);
166
+
167
+  // send CRC
168
+  uint8_t crc = 0XFF;
169
+  if (cmd == CMD0) crc = 0X95;  // correct crc for CMD0 with arg 0
170
+  if (cmd == CMD8) crc = 0X87;  // correct crc for CMD8 with arg 0X1AA
171
+  spiSend(crc);
172
+
173
+  // skip stuff byte for stop read
174
+  if (cmd == CMD12) spiRec();
175
+
176
+  // wait for response
177
+  for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++);
178
+  return status_;
179
+}
180
+//------------------------------------------------------------------------------
181
+/**
182
+ * Determine the size of an SD flash memory card.
183
+ *
184
+ * \return The number of 512 byte data blocks in the card
185
+ *         or zero if an error occurs.
186
+ */
187
+uint32_t Sd2Card::cardSize() {
188
+  csd_t csd;
189
+  if (!readCSD(&csd)) return 0;
190
+  if (csd.v1.csd_ver == 0) {
191
+    uint8_t read_bl_len = csd.v1.read_bl_len;
192
+    uint16_t c_size = (csd.v1.c_size_high << 10)
193
+                      | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low;
194
+    uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1)
195
+                          | csd.v1.c_size_mult_low;
196
+    return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7);
197
+  } else if (csd.v2.csd_ver == 1) {
198
+    uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16)
199
+                      | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low;
200
+    return (c_size + 1) << 10;
201
+  } else {
202
+    error(SD_CARD_ERROR_BAD_CSD);
203
+    return 0;
204
+  }
205
+}
206
+//------------------------------------------------------------------------------
207
+void Sd2Card::chipSelectHigh() {
208
+  digitalWrite(chipSelectPin_, HIGH);
209
+}
210
+//------------------------------------------------------------------------------
211
+void Sd2Card::chipSelectLow() {
212
+#ifndef SOFTWARE_SPI
213
+  spiInit(spiRate_);
214
+#endif  // SOFTWARE_SPI
215
+  digitalWrite(chipSelectPin_, LOW);
216
+}
217
+//------------------------------------------------------------------------------
218
+/** Erase a range of blocks.
219
+ *
220
+ * \param[in] firstBlock The address of the first block in the range.
221
+ * \param[in] lastBlock The address of the last block in the range.
222
+ *
223
+ * \note This function requests the SD card to do a flash erase for a
224
+ * range of blocks.  The data on the card after an erase operation is
225
+ * either 0 or 1, depends on the card vendor.  The card must support
226
+ * single block erase.
227
+ *
228
+ * \return The value one, true, is returned for success and
229
+ * the value zero, false, is returned for failure.
230
+ */
231
+bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
232
+  csd_t csd;
233
+  if (!readCSD(&csd)) goto fail;
234
+  // check for single block erase
235
+  if (!csd.v1.erase_blk_en) {
236
+    // erase size mask
237
+    uint8_t m = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low;
238
+    if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) {
239
+      // error card can't erase specified area
240
+      error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);
241
+      goto fail;
242
+    }
243
+  }
244
+  if (type_ != SD_CARD_TYPE_SDHC) {
245
+    firstBlock <<= 9;
246
+    lastBlock <<= 9;
247
+  }
248
+  if (cardCommand(CMD32, firstBlock)
249
+    || cardCommand(CMD33, lastBlock)
250
+    || cardCommand(CMD38, 0)) {
251
+      error(SD_CARD_ERROR_ERASE);
252
+      goto fail;
253
+  }
254
+  if (!waitNotBusy(SD_ERASE_TIMEOUT)) {
255
+    error(SD_CARD_ERROR_ERASE_TIMEOUT);
256
+    goto fail;
257
+  }
258
+  chipSelectHigh();
259
+  return true;
260
+
261
+ fail:
262
+  chipSelectHigh();
263
+  return false;
264
+}
265
+//------------------------------------------------------------------------------
266
+/** Determine if card supports single block erase.
267
+ *
268
+ * \return The value one, true, is returned if single block erase is supported.
269
+ * The value zero, false, is returned if single block erase is not supported.
270
+ */
271
+bool Sd2Card::eraseSingleBlockEnable() {
272
+  csd_t csd;
273
+  return readCSD(&csd) ? csd.v1.erase_blk_en : false;
274
+}
275
+//------------------------------------------------------------------------------
276
+/**
277
+ * Initialize an SD flash memory card.
278
+ *
279
+ * \param[in] sckRateID SPI clock rate selector. See setSckRate().
280
+ * \param[in] chipSelectPin SD chip select pin number.
281
+ *
282
+ * \return The value one, true, is returned for success and
283
+ * the value zero, false, is returned for failure.  The reason for failure
284
+ * can be determined by calling errorCode() and errorData().
285
+ */
286
+bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
287
+  errorCode_ = type_ = 0;
288
+  chipSelectPin_ = chipSelectPin;
289
+  // 16-bit init start time allows over a minute
290
+  uint16_t t0 = (uint16_t)millis();
291
+  uint32_t arg;
292
+
293
+  // set pin modes
294
+  pinMode(chipSelectPin_, OUTPUT);
295
+  chipSelectHigh();
296
+  pinMode(SPI_MISO_PIN, INPUT);
297
+  pinMode(SPI_MOSI_PIN, OUTPUT);
298
+  pinMode(SPI_SCK_PIN, OUTPUT);
299
+
300
+#ifndef SOFTWARE_SPI
301
+  // SS must be in output mode even it is not chip select
302
+  pinMode(SS_PIN, OUTPUT);
303
+  // set SS high - may be chip select for another SPI device
304
+#if SET_SPI_SS_HIGH
305
+  digitalWrite(SS_PIN, HIGH);
306
+#endif  // SET_SPI_SS_HIGH
307
+  // set SCK rate for initialization commands
308
+  spiRate_ = SPI_SD_INIT_RATE;
309
+  spiInit(spiRate_);
310
+#endif  // SOFTWARE_SPI
311
+
312
+  // must supply min of 74 clock cycles with CS high.
313
+  for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
314
+
315
+  // command to go idle in SPI mode
316
+  while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
317
+    if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
318
+      error(SD_CARD_ERROR_CMD0);
319
+      goto fail;
320
+    }
321
+  }
322
+  // check SD version
323
+  if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
324
+    type(SD_CARD_TYPE_SD1);
325
+  } else {
326
+    // only need last byte of r7 response
327
+    for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
328
+    if (status_ != 0XAA) {
329
+      error(SD_CARD_ERROR_CMD8);
330
+      goto fail;
331
+    }
332
+    type(SD_CARD_TYPE_SD2);
333
+  }
334
+  // initialize card and send host supports SDHC if SD2
335
+  arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;
336
+
337
+  while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
338
+    // check for timeout
339
+    if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
340
+      error(SD_CARD_ERROR_ACMD41);
341
+      goto fail;
342
+    }
343
+  }
344
+  // if SD2 read OCR register to check for SDHC card
345
+  if (type() == SD_CARD_TYPE_SD2) {
346
+    if (cardCommand(CMD58, 0)) {
347
+      error(SD_CARD_ERROR_CMD58);
348
+      goto fail;
349
+    }
350
+    if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC);
351
+    // discard rest of ocr - contains allowed voltage range
352
+    for (uint8_t i = 0; i < 3; i++) spiRec();
353
+  }
354
+  chipSelectHigh();
355
+
356
+#ifndef SOFTWARE_SPI
357
+  return setSckRate(sckRateID);
358
+#else  // SOFTWARE_SPI
359
+  return true;
360
+#endif  // SOFTWARE_SPI
361
+
362
+ fail:
363
+  chipSelectHigh();
364
+  return false;
365
+}
366
+//------------------------------------------------------------------------------
367
+/**
368
+ * Read a 512 byte block from an SD card.
369
+ *
370
+ * \param[in] blockNumber Logical block to be read.
371
+ * \param[out] dst Pointer to the location that will receive the data.
372
+
373
+ * \return The value one, true, is returned for success and
374
+ * the value zero, false, is returned for failure.
375
+ */
376
+bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
377
+  // use address if not SDHC card
378
+  if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9;
379
+  if (cardCommand(CMD17, blockNumber)) {
380
+    error(SD_CARD_ERROR_CMD17);
381
+    goto fail;
382
+  }
383
+  return readData(dst, 512);
384
+
385
+ fail:
386
+  chipSelectHigh();
387
+  return false;
388
+}
389
+//------------------------------------------------------------------------------
390
+/** Read one data block in a multiple block read sequence
391
+ *
392
+ * \param[in] dst Pointer to the location for the data to be read.
393
+ *
394
+ * \return The value one, true, is returned for success and
395
+ * the value zero, false, is returned for failure.
396
+ */
397
+bool Sd2Card::readData(uint8_t *dst) {
398
+  chipSelectLow();
399
+  return readData(dst, 512);
400
+}
401
+//------------------------------------------------------------------------------
402
+bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
403
+  // wait for start block token
404
+  uint16_t t0 = millis();
405
+  while ((status_ = spiRec()) == 0XFF) {
406
+    if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
407
+      error(SD_CARD_ERROR_READ_TIMEOUT);
408
+      goto fail;
409
+    }
410
+  }
411
+  if (status_ != DATA_START_BLOCK) {
412
+    error(SD_CARD_ERROR_READ);
413
+    goto fail;
414
+  }
415
+  // transfer data
416
+  spiRead(dst, count);
417
+
418
+  // discard CRC
419
+  spiRec();
420
+  spiRec();
421
+  chipSelectHigh();
422
+  return true;
423
+
424
+ fail:
425
+  chipSelectHigh();
426
+  return false;
427
+}
428
+//------------------------------------------------------------------------------
429
+/** read CID or CSR register */
430
+bool Sd2Card::readRegister(uint8_t cmd, void* buf) {
431
+  uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
432
+  if (cardCommand(cmd, 0)) {
433
+    error(SD_CARD_ERROR_READ_REG);
434
+    goto fail;
435
+  }
436
+  return readData(dst, 16);
437
+
438
+ fail:
439
+  chipSelectHigh();
440
+  return false;
441
+}
442
+//------------------------------------------------------------------------------
443
+/** Start a read multiple blocks sequence.
444
+ *
445
+ * \param[in] blockNumber Address of first block in sequence.
446
+ *
447
+ * \note This function is used with readData() and readStop() for optimized
448
+ * multiple block reads.  SPI chipSelect must be low for the entire sequence.
449
+ *
450
+ * \return The value one, true, is returned for success and
451
+ * the value zero, false, is returned for failure.
452
+ */
453
+bool Sd2Card::readStart(uint32_t blockNumber) {
454
+  if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9;
455
+  if (cardCommand(CMD18, blockNumber)) {
456
+    error(SD_CARD_ERROR_CMD18);
457
+    goto fail;
458
+  }
459
+  chipSelectHigh();
460
+  return true;
461
+
462
+ fail:
463
+  chipSelectHigh();
464
+  return false;
465
+}
466
+//------------------------------------------------------------------------------
467
+/** End a read multiple blocks sequence.
468
+ *
469
+* \return The value one, true, is returned for success and
470
+ * the value zero, false, is returned for failure.
471
+ */
472
+bool Sd2Card::readStop() {
473
+  chipSelectLow();
474
+  if (cardCommand(CMD12, 0)) {
475
+    error(SD_CARD_ERROR_CMD12);
476
+    goto fail;
477
+  }
478
+  chipSelectHigh();
479
+  return true;
480
+
481
+ fail:
482
+  chipSelectHigh();
483
+  return false;
484
+}
485
+//------------------------------------------------------------------------------
486
+/**
487
+ * Set the SPI clock rate.
488
+ *
489
+ * \param[in] sckRateID A value in the range [0, 6].
490
+ *
491
+ * The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum
492
+ * SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128
493
+ * for \a scsRateID = 6.
494
+ *
495
+ * \return The value one, true, is returned for success and the value zero,
496
+ * false, is returned for an invalid value of \a sckRateID.
497
+ */
498
+bool Sd2Card::setSckRate(uint8_t sckRateID) {
499
+  if (sckRateID > 6) {
500
+    error(SD_CARD_ERROR_SCK_RATE);
501
+    return false;
502
+  }
503
+  spiRate_ = sckRateID;
504
+  return true;
505
+}
506
+//------------------------------------------------------------------------------
507
+// wait for card to go not busy
508
+bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
509
+  uint16_t t0 = millis();
510
+  while (spiRec() != 0XFF) {
511
+    if (((uint16_t)millis() - t0) >= timeoutMillis) goto fail;
512
+  }
513
+  return true;
514
+
515
+ fail:
516
+  return false;
517
+}
518
+//------------------------------------------------------------------------------
519
+/**
520
+ * Writes a 512 byte block to an SD card.
521
+ *
522
+ * \param[in] blockNumber Logical block to be written.
523
+ * \param[in] src Pointer to the location of the data to be written.
524
+ * \return The value one, true, is returned for success and
525
+ * the value zero, false, is returned for failure.
526
+ */
527
+bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
528
+  // use address if not SDHC card
529
+  if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
530
+  if (cardCommand(CMD24, blockNumber)) {
531
+    error(SD_CARD_ERROR_CMD24);
532
+    goto fail;
533
+  }
534
+  if (!writeData(DATA_START_BLOCK, src)) goto fail;
535
+
536
+  // wait for flash programming to complete
537
+  if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
538
+    error(SD_CARD_ERROR_WRITE_TIMEOUT);
539
+    goto fail;
540
+  }
541
+  // response is r2 so get and check two bytes for nonzero
542
+  if (cardCommand(CMD13, 0) || spiRec()) {
543
+    error(SD_CARD_ERROR_WRITE_PROGRAMMING);
544
+    goto fail;
545
+  }
546
+  chipSelectHigh();
547
+  return true;
548
+
549
+ fail:
550
+  chipSelectHigh();
551
+  return false;
552
+}
553
+//------------------------------------------------------------------------------
554
+/** Write one data block in a multiple block write sequence
555
+ * \param[in] src Pointer to the location of the data to be written.
556
+ * \return The value one, true, is returned for success and
557
+ * the value zero, false, is returned for failure.
558
+ */
559
+bool Sd2Card::writeData(const uint8_t* src) {
560
+  chipSelectLow();
561
+  // wait for previous write to finish
562
+  if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
563
+  if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto fail;
564
+  chipSelectHigh();
565
+  return true;
566
+
567
+ fail:
568
+  error(SD_CARD_ERROR_WRITE_MULTIPLE);
569
+  chipSelectHigh();
570
+  return false;
571
+}
572
+//------------------------------------------------------------------------------
573
+// send one block of data for write block or write multiple blocks
574
+bool Sd2Card::writeData(uint8_t token, const uint8_t* src) {
575
+  spiSendBlock(token, src);
576
+
577
+  spiSend(0xff);  // dummy crc
578
+  spiSend(0xff);  // dummy crc
579
+
580
+  status_ = spiRec();
581
+  if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
582
+    error(SD_CARD_ERROR_WRITE);
583
+    goto fail;
584
+  }
585
+  return true;
586
+
587
+ fail:
588
+  chipSelectHigh();
589
+  return false;
590
+}
591
+//------------------------------------------------------------------------------
592
+/** Start a write multiple blocks sequence.
593
+ *
594
+ * \param[in] blockNumber Address of first block in sequence.
595
+ * \param[in] eraseCount The number of blocks to be pre-erased.
596
+ *
597
+ * \note This function is used with writeData() and writeStop()
598
+ * for optimized multiple block writes.
599
+ *
600
+ * \return The value one, true, is returned for success and
601
+ * the value zero, false, is returned for failure.
602
+ */
603
+bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
604
+  // send pre-erase count
605
+  if (cardAcmd(ACMD23, eraseCount)) {
606
+    error(SD_CARD_ERROR_ACMD23);
607
+    goto fail;
608
+  }
609
+  // use address if not SDHC card
610
+  if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
611
+  if (cardCommand(CMD25, blockNumber)) {
612
+    error(SD_CARD_ERROR_CMD25);
613
+    goto fail;
614
+  }
615
+  chipSelectHigh();
616
+  return true;
617
+
618
+ fail:
619
+  chipSelectHigh();
620
+  return false;
621
+}
622
+//------------------------------------------------------------------------------
623
+/** End a write multiple blocks sequence.
624
+ *
625
+* \return The value one, true, is returned for success and
626
+ * the value zero, false, is returned for failure.
627
+ */
628
+bool Sd2Card::writeStop() {
629
+  chipSelectLow();
630
+  if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
631
+  spiSend(STOP_TRAN_TOKEN);
632
+  if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
633
+  chipSelectHigh();
634
+  return true;
635
+
636
+ fail:
637
+  error(SD_CARD_ERROR_STOP_TRAN);
638
+  chipSelectHigh();
639
+  return false;
640
+}
641
+
642
+
643
+#endif

+ 241 - 0
Sd2Card.h

@@ -0,0 +1,241 @@
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
+ * <http://www.gnu.org/licenses/>.
19
+ */
20
+
21
+#include "Marlin.h"
22
+#ifdef SDSUPPORT
23
+
24
+#ifndef Sd2Card_h
25
+#define Sd2Card_h
26
+/**
27
+ * \file
28
+ * \brief Sd2Card class for V2 SD/SDHC cards
29
+ */
30
+#include "SdFatConfig.h"
31
+#include "Sd2PinMap.h"
32
+#include "SdInfo.h"
33
+//------------------------------------------------------------------------------
34
+// SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6
35
+/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */
36
+uint8_t const SPI_FULL_SPEED = 0;
37
+/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */
38
+uint8_t const SPI_HALF_SPEED = 1;
39
+/** Set SCK rate to F_CPU/8. See Sd2Card::setSckRate(). */
40
+uint8_t const SPI_QUARTER_SPEED = 2;
41
+/** Set SCK rate to F_CPU/16. See Sd2Card::setSckRate(). */
42
+uint8_t const SPI_EIGHTH_SPEED = 3;
43
+/** Set SCK rate to F_CPU/32. See Sd2Card::setSckRate(). */
44
+uint8_t const SPI_SIXTEENTH_SPEED = 4;
45
+//------------------------------------------------------------------------------
46
+/** init timeout ms */
47
+uint16_t const SD_INIT_TIMEOUT = 2000;
48
+/** erase timeout ms */
49
+uint16_t const SD_ERASE_TIMEOUT = 10000;
50
+/** read timeout ms */
51
+uint16_t const SD_READ_TIMEOUT = 300;
52
+/** write time out ms */
53
+uint16_t const SD_WRITE_TIMEOUT = 600;
54
+//------------------------------------------------------------------------------
55
+// SD card errors
56
+/** timeout error for command CMD0 (initialize card in SPI mode) */
57
+uint8_t const SD_CARD_ERROR_CMD0 = 0X1;
58
+/** CMD8 was not accepted - not a valid SD card*/
59
+uint8_t const SD_CARD_ERROR_CMD8 = 0X2;
60
+/** card returned an error response for CMD12 (write stop) */
61
+uint8_t const SD_CARD_ERROR_CMD12 = 0X3;
62
+/** card returned an error response for CMD17 (read block) */
63
+uint8_t const SD_CARD_ERROR_CMD17 = 0X4;
64
+/** card returned an error response for CMD18 (read multiple block) */
65
+uint8_t const SD_CARD_ERROR_CMD18 = 0X5;
66
+/** card returned an error response for CMD24 (write block) */
67
+uint8_t const SD_CARD_ERROR_CMD24 = 0X6;
68
+/**  WRITE_MULTIPLE_BLOCKS command failed */
69
+uint8_t const SD_CARD_ERROR_CMD25 = 0X7;
70
+/** card returned an error response for CMD58 (read OCR) */
71
+uint8_t const SD_CARD_ERROR_CMD58 = 0X8;
72
+/** SET_WR_BLK_ERASE_COUNT failed */
73
+uint8_t const SD_CARD_ERROR_ACMD23 = 0X9;
74
+/** ACMD41 initialization process timeout */
75
+uint8_t const SD_CARD_ERROR_ACMD41 = 0XA;
76
+/** card returned a bad CSR version field */
77
+uint8_t const SD_CARD_ERROR_BAD_CSD = 0XB;
78
+/** erase block group command failed */
79
+uint8_t const SD_CARD_ERROR_ERASE = 0XC;
80
+/** card not capable of single block erase */
81
+uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD;
82
+/** Erase sequence timed out */
83
+uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0XE;
84
+/** card returned an error token instead of read data */
85
+uint8_t const SD_CARD_ERROR_READ = 0XF;
86
+/** read CID or CSD failed */
87
+uint8_t const SD_CARD_ERROR_READ_REG = 0X10;
88
+/** timeout while waiting for start of read data */
89
+uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X11;
90
+/** card did not accept STOP_TRAN_TOKEN */
91
+uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X12;
92
+/** card returned an error token as a response to a write operation */
93
+uint8_t const SD_CARD_ERROR_WRITE = 0X13;
94
+/** attempt to write protected block zero */
95
+uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X14;  // REMOVE - not used
96
+/** card did not go ready for a multiple block write */
97
+uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X15;
98
+/** card returned an error to a CMD13 status check after a write */
99
+uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X16;
100
+/** timeout occurred during write programming */
101
+uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X17;
102
+/** incorrect rate selected */
103
+uint8_t const SD_CARD_ERROR_SCK_RATE = 0X18;
104
+/** init() not called */
105
+uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19;
106
+//------------------------------------------------------------------------------
107
+// card types
108
+/** Standard capacity V1 SD card */
109
+uint8_t const SD_CARD_TYPE_SD1  = 1;
110
+/** Standard capacity V2 SD card */
111
+uint8_t const SD_CARD_TYPE_SD2  = 2;
112
+/** High Capacity SD card */
113
+uint8_t const SD_CARD_TYPE_SDHC = 3;
114
+/**
115
+ * define SOFTWARE_SPI to use bit-bang SPI
116
+ */
117
+//------------------------------------------------------------------------------
118
+#if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__))
119
+#define SOFTWARE_SPI
120
+#elif USE_SOFTWARE_SPI
121
+#define SOFTWARE_SPI
122
+#endif  // MEGA_SOFT_SPI
123
+//------------------------------------------------------------------------------
124
+// SPI pin definitions - do not edit here - change in SdFatConfig.h
125
+//
126
+#ifndef SOFTWARE_SPI
127
+// hardware pin defs
128
+/** The default chip select pin for the SD card is SS. */
129
+uint8_t const  SD_CHIP_SELECT_PIN = SS_PIN;
130
+// The following three pins must not be redefined for hardware SPI.
131
+/** SPI Master Out Slave In pin */
132
+uint8_t const  SPI_MOSI_PIN = MOSI_PIN;
133
+/** SPI Master In Slave Out pin */
134
+uint8_t const  SPI_MISO_PIN = MISO_PIN;
135
+/** SPI Clock pin */
136
+uint8_t const  SPI_SCK_PIN = SCK_PIN;
137
+
138
+#else  // SOFTWARE_SPI
139
+
140
+/** SPI chip select pin */
141
+uint8_t const SD_CHIP_SELECT_PIN = SOFT_SPI_CS_PIN;
142
+/** SPI Master Out Slave In pin */
143
+uint8_t const SPI_MOSI_PIN = SOFT_SPI_MOSI_PIN;
144
+/** SPI Master In Slave Out pin */
145
+uint8_t const SPI_MISO_PIN = SOFT_SPI_MISO_PIN;
146
+/** SPI Clock pin */
147
+uint8_t const SPI_SCK_PIN = SOFT_SPI_SCK_PIN;
148
+#endif  // SOFTWARE_SPI
149
+//------------------------------------------------------------------------------
150
+/**
151
+ * \class Sd2Card
152
+ * \brief Raw access to SD and SDHC flash memory cards.
153
+ */
154
+class Sd2Card {
155
+ public:
156
+  /** Construct an instance of Sd2Card. */
157
+  Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {}
158
+  uint32_t cardSize();
159
+  bool erase(uint32_t firstBlock, uint32_t lastBlock);
160
+  bool eraseSingleBlockEnable();
161
+  /**
162
+   *  Set SD error code.
163
+   *  \param[in] code value for error code.
164
+   */
165
+  void error(uint8_t code) {errorCode_ = code;}
166
+  /**
167
+   * \return error code for last error. See Sd2Card.h for a list of error codes.
168
+   */
169
+  int errorCode() const {return errorCode_;}
170
+  /** \return error data for last error. */
171
+  int errorData() const {return status_;}
172
+  /**
173
+   * Initialize an SD flash memory card with default clock rate and chip
174
+   * select pin.  See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
175
+   *
176
+   * \return true for success or false for failure.
177
+   */
178
+  bool init(uint8_t sckRateID = SPI_FULL_SPEED,
179
+    uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
180
+  bool readBlock(uint32_t block, uint8_t* dst);
181
+  /**
182
+   * Read a card's CID register. The CID contains card identification
183
+   * information such as Manufacturer ID, Product name, Product serial
184
+   * number and Manufacturing date. 
185
+   *
186
+   * \param[out] cid pointer to area for returned data.
187
+   *
188
+   * \return true for success or false for failure.
189
+   */
190
+  bool readCID(cid_t* cid) {
191
+    return readRegister(CMD10, cid);
192
+  }
193
+  /**
194
+   * Read a card's CSD register. The CSD contains Card-Specific Data that
195
+   * provides information regarding access to the card's contents.
196
+   *
197
+   * \param[out] csd pointer to area for returned data.
198
+   *
199
+   * \return true for success or false for failure.
200
+   */
201
+  bool readCSD(csd_t* csd) {
202
+    return readRegister(CMD9, csd);
203
+  }
204
+  bool readData(uint8_t *dst);
205
+  bool readStart(uint32_t blockNumber);
206
+  bool readStop();
207
+  bool setSckRate(uint8_t sckRateID);
208
+  /** Return the card type: SD V1, SD V2 or SDHC
209
+   * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC.
210
+   */
211
+  int type() const {return type_;}
212
+  bool writeBlock(uint32_t blockNumber, const uint8_t* src);
213
+  bool writeData(const uint8_t* src);
214
+  bool writeStart(uint32_t blockNumber, uint32_t eraseCount);
215
+  bool writeStop();
216
+ private:
217
+  //----------------------------------------------------------------------------
218
+  uint8_t chipSelectPin_;
219
+  uint8_t errorCode_;
220
+  uint8_t spiRate_;
221
+  uint8_t status_;
222
+  uint8_t type_;
223
+  // private functions
224
+  uint8_t cardAcmd(uint8_t cmd, uint32_t arg) {
225
+    cardCommand(CMD55, 0);
226
+    return cardCommand(cmd, arg);
227
+  }
228
+  uint8_t cardCommand(uint8_t cmd, uint32_t arg);
229
+
230
+  bool readData(uint8_t* dst, uint16_t count);
231
+  bool readRegister(uint8_t cmd, void* buf);
232
+  void chipSelectHigh();
233
+  void chipSelectLow();
234
+  void type(uint8_t value) {type_ = value;}
235
+  bool waitNotBusy(uint16_t timeoutMillis);
236
+  bool writeData(uint8_t token, const uint8_t* src);
237
+};
238
+#endif  // Sd2Card_h
239
+
240
+
241
+#endif

+ 368 - 0
Sd2PinMap.h

@@ -0,0 +1,368 @@
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
+ * <http://www.gnu.org/licenses/>.
19
+ */
20
+// Warning this file was generated by a program.
21
+#include "Marlin.h"
22
+#ifdef SDSUPPORT
23
+
24
+#ifndef Sd2PinMap_h
25
+#define Sd2PinMap_h
26
+#include <avr/io.h>
27
+//------------------------------------------------------------------------------
28
+/** struct for mapping digital pins */
29
+struct pin_map_t {
30
+  volatile uint8_t* ddr;
31
+  volatile uint8_t* pin;
32
+  volatile uint8_t* port;
33
+  uint8_t bit;
34
+};
35
+//------------------------------------------------------------------------------
36
+#if defined(__AVR_ATmega1280__)\
37
+|| defined(__AVR_ATmega2560__)
38
+// Mega
39
+
40
+// Two Wire (aka I2C) ports
41
+uint8_t const SDA_PIN = 20;  // D1
42
+uint8_t const SCL_PIN = 21;  // D0
43
+
44
+#undef MOSI_PIN
45
+#undef MISO_PIN
46
+// SPI port
47
+uint8_t const SS_PIN = 53;    // B0
48
+uint8_t const MOSI_PIN = 51;  // B2
49
+uint8_t const MISO_PIN = 50;  // B3
50
+uint8_t const SCK_PIN = 52;   // B1
51
+
52
+static const pin_map_t digitalPinMap[] = {
53
+  {&DDRE, &PINE, &PORTE, 0},  // E0  0
54
+  {&DDRE, &PINE, &PORTE, 1},  // E1  1
55
+  {&DDRE, &PINE, &PORTE, 4},  // E4  2
56
+  {&DDRE, &PINE, &PORTE, 5},  // E5  3
57
+  {&DDRG, &PING, &PORTG, 5},  // G5  4
58
+  {&DDRE, &PINE, &PORTE, 3},  // E3  5
59
+  {&DDRH, &PINH, &PORTH, 3},  // H3  6
60
+  {&DDRH, &PINH, &PORTH, 4},  // H4  7
61
+  {&DDRH, &PINH, &PORTH, 5},  // H5  8
62
+  {&DDRH, &PINH, &PORTH, 6},  // H6  9
63
+  {&DDRB, &PINB, &PORTB, 4},  // B4 10
64
+  {&DDRB, &PINB, &PORTB, 5},  // B5 11
65
+  {&DDRB, &PINB, &PORTB, 6},  // B6 12
66
+  {&DDRB, &PINB, &PORTB, 7},  // B7 13
67
+  {&DDRJ, &PINJ, &PORTJ, 1},  // J1 14
68
+  {&DDRJ, &PINJ, &PORTJ, 0},  // J0 15
69
+  {&DDRH, &PINH, &PORTH, 1},  // H1 16
70
+  {&DDRH, &PINH, &PORTH, 0},  // H0 17
71
+  {&DDRD, &PIND, &PORTD, 3},  // D3 18
72
+  {&DDRD, &PIND, &PORTD, 2},  // D2 19
73
+  {&DDRD, &PIND, &PORTD, 1},  // D1 20
74
+  {&DDRD, &PIND, &PORTD, 0},  // D0 21
75
+  {&DDRA, &PINA, &PORTA, 0},  // A0 22
76
+  {&DDRA, &PINA, &PORTA, 1},  // A1 23
77
+  {&DDRA, &PINA, &PORTA, 2},  // A2 24
78
+  {&DDRA, &PINA, &PORTA, 3},  // A3 25
79
+  {&DDRA, &PINA, &PORTA, 4},  // A4 26
80
+  {&DDRA, &PINA, &PORTA, 5},  // A5 27
81
+  {&DDRA, &PINA, &PORTA, 6},  // A6 28
82
+  {&DDRA, &PINA, &PORTA, 7},  // A7 29
83
+  {&DDRC, &PINC, &PORTC, 7},  // C7 30
84
+  {&DDRC, &PINC, &PORTC, 6},  // C6 31
85
+  {&DDRC, &PINC, &PORTC, 5},  // C5 32
86
+  {&DDRC, &PINC, &PORTC, 4},  // C4 33
87
+  {&DDRC, &PINC, &PORTC, 3},  // C3 34
88
+  {&DDRC, &PINC, &PORTC, 2},  // C2 35
89
+  {&DDRC, &PINC, &PORTC, 1},  // C1 36
90
+  {&DDRC, &PINC, &PORTC, 0},  // C0 37
91
+  {&DDRD, &PIND, &PORTD, 7},  // D7 38
92
+  {&DDRG, &PING, &PORTG, 2},  // G2 39
93
+  {&DDRG, &PING, &PORTG, 1},  // G1 40
94
+  {&DDRG, &PING, &PORTG, 0},  // G0 41
95
+  {&DDRL, &PINL, &PORTL, 7},  // L7 42
96
+  {&DDRL, &PINL, &PORTL, 6},  // L6 43
97
+  {&DDRL, &PINL, &PORTL, 5},  // L5 44
98
+  {&DDRL, &PINL, &PORTL, 4},  // L4 45
99
+  {&DDRL, &PINL, &PORTL, 3},  // L3 46
100
+  {&DDRL, &PINL, &PORTL, 2},  // L2 47
101
+  {&DDRL, &PINL, &PORTL, 1},  // L1 48
102
+  {&DDRL, &PINL, &PORTL, 0},  // L0 49
103
+  {&DDRB, &PINB, &PORTB, 3},  // B3 50
104
+  {&DDRB, &PINB, &PORTB, 2},  // B2 51
105
+  {&DDRB, &PINB, &PORTB, 1},  // B1 52
106
+  {&DDRB, &PINB, &PORTB, 0},  // B0 53
107
+  {&DDRF, &PINF, &PORTF, 0},  // F0 54
108
+  {&DDRF, &PINF, &PORTF, 1},  // F1 55
109
+  {&DDRF, &PINF, &PORTF, 2},  // F2 56
110
+  {&DDRF, &PINF, &PORTF, 3},  // F3 57
111
+  {&DDRF, &PINF, &PORTF, 4},  // F4 58
112
+  {&DDRF, &PINF, &PORTF, 5},  // F5 59
113
+  {&DDRF, &PINF, &PORTF, 6},  // F6 60
114
+  {&DDRF, &PINF, &PORTF, 7},  // F7 61
115
+  {&DDRK, &PINK, &PORTK, 0},  // K0 62
116
+  {&DDRK, &PINK, &PORTK, 1},  // K1 63
117
+  {&DDRK, &PINK, &PORTK, 2},  // K2 64
118
+  {&DDRK, &PINK, &PORTK, 3},  // K3 65
119
+  {&DDRK, &PINK, &PORTK, 4},  // K4 66
120
+  {&DDRK, &PINK, &PORTK, 5},  // K5 67
121
+  {&DDRK, &PINK, &PORTK, 6},  // K6 68
122
+  {&DDRK, &PINK, &PORTK, 7}   // K7 69
123
+};
124
+//------------------------------------------------------------------------------
125
+#elif defined(__AVR_ATmega644P__)\
126
+|| defined(__AVR_ATmega644__)\
127
+|| defined(__AVR_ATmega1284P__)
128
+// Sanguino
129
+
130
+// Two Wire (aka I2C) ports
131
+uint8_t const SDA_PIN = 17;  // C1
132
+uint8_t const SCL_PIN = 18;  // C2
133
+
134
+// SPI port
135
+uint8_t const SS_PIN = 4;    // B4
136
+uint8_t const MOSI_PIN = 5;  // B5
137
+uint8_t const MISO_PIN = 6;  // B6
138
+uint8_t const SCK_PIN = 7;   // B7
139
+
140
+static const pin_map_t digitalPinMap[] = {
141
+  {&DDRB, &PINB, &PORTB, 0},  // B0  0
142
+  {&DDRB, &PINB, &PORTB, 1},  // B1  1
143
+  {&DDRB, &PINB, &PORTB, 2},  // B2  2
144
+  {&DDRB, &PINB, &PORTB, 3},  // B3  3
145
+  {&DDRB, &PINB, &PORTB, 4},  // B4  4
146
+  {&DDRB, &PINB, &PORTB, 5},  // B5  5
147
+  {&DDRB, &PINB, &PORTB, 6},  // B6  6
148
+  {&DDRB, &PINB, &PORTB, 7},  // B7  7
149
+  {&DDRD, &PIND, &PORTD, 0},  // D0  8
150
+  {&DDRD, &PIND, &PORTD, 1},  // D1  9
151
+  {&DDRD, &PIND, &PORTD, 2},  // D2 10
152
+  {&DDRD, &PIND, &PORTD, 3},  // D3 11
153
+  {&DDRD, &PIND, &PORTD, 4},  // D4 12
154
+  {&DDRD, &PIND, &PORTD, 5},  // D5 13
155
+  {&DDRD, &PIND, &PORTD, 6},  // D6 14
156
+  {&DDRD, &PIND, &PORTD, 7},  // D7 15
157
+  {&DDRC, &PINC, &PORTC, 0},  // C0 16
158
+  {&DDRC, &PINC, &PORTC, 1},  // C1 17
159
+  {&DDRC, &PINC, &PORTC, 2},  // C2 18
160
+  {&DDRC, &PINC, &PORTC, 3},  // C3 19
161
+  {&DDRC, &PINC, &PORTC, 4},  // C4 20
162
+  {&DDRC, &PINC, &PORTC, 5},  // C5 21
163
+  {&DDRC, &PINC, &PORTC, 6},  // C6 22
164
+  {&DDRC, &PINC, &PORTC, 7},  // C7 23
165
+  {&DDRA, &PINA, &PORTA, 7},  // A7 24
166
+  {&DDRA, &PINA, &PORTA, 6},  // A6 25
167
+  {&DDRA, &PINA, &PORTA, 5},  // A5 26
168
+  {&DDRA, &PINA, &PORTA, 4},  // A4 27
169
+  {&DDRA, &PINA, &PORTA, 3},  // A3 28
170
+  {&DDRA, &PINA, &PORTA, 2},  // A2 29
171
+  {&DDRA, &PINA, &PORTA, 1},  // A1 30
172
+  {&DDRA, &PINA, &PORTA, 0}   // A0 31
173
+};
174
+//------------------------------------------------------------------------------
175
+#elif defined(__AVR_ATmega32U4__)
176
+// Teensy 2.0
177
+
178
+// Two Wire (aka I2C) ports
179
+uint8_t const SDA_PIN = 6;  // D1
180
+uint8_t const SCL_PIN = 5;  // D0
181
+
182
+// SPI port
183
+uint8_t const SS_PIN = 0;    // B0
184
+uint8_t const MOSI_PIN = 2;  // B2
185
+uint8_t const MISO_PIN = 3;  // B3
186
+uint8_t const SCK_PIN = 1;   // B1
187
+
188
+static const pin_map_t digitalPinMap[] = {
189
+  {&DDRB, &PINB, &PORTB, 0},  // B0  0
190
+  {&DDRB, &PINB, &PORTB, 1},  // B1  1
191
+  {&DDRB, &PINB, &PORTB, 2},  // B2  2
192
+  {&DDRB, &PINB, &PORTB, 3},  // B3  3
193
+  {&DDRB, &PINB, &PORTB, 7},  // B7  4
194
+  {&DDRD, &PIND, &PORTD, 0},  // D0  5
195
+  {&DDRD, &PIND, &PORTD, 1},  // D1  6
196
+  {&DDRD, &PIND, &PORTD, 2},  // D2  7
197
+  {&DDRD, &PIND, &PORTD, 3},  // D3  8
198
+  {&DDRC, &PINC, &PORTC, 6},  // C6  9
199
+  {&DDRC, &PINC, &PORTC, 7},  // C7 10
200
+  {&DDRD, &PIND, &PORTD, 6},  // D6 11
201
+  {&DDRD, &PIND, &PORTD, 7},  // D7 12
202
+  {&DDRB, &PINB, &PORTB, 4},  // B4 13
203
+  {&DDRB, &PINB, &PORTB, 5},  // B5 14
204
+  {&DDRB, &PINB, &PORTB, 6},  // B6 15
205
+  {&DDRF, &PINF, &PORTF, 7},  // F7 16
206
+  {&DDRF, &PINF, &PORTF, 6},  // F6 17
207
+  {&DDRF, &PINF, &PORTF, 5},  // F5 18
208
+  {&DDRF, &PINF, &PORTF, 4},  // F4 19
209
+  {&DDRF, &PINF, &PORTF, 1},  // F1 20
210
+  {&DDRF, &PINF, &PORTF, 0},  // F0 21
211
+  {&DDRD, &PIND, &PORTD, 4},  // D4 22
212
+  {&DDRD, &PIND, &PORTD, 5},  // D5 23
213
+  {&DDRE, &PINE, &PORTE, 6}   // E6 24
214
+};
215
+//------------------------------------------------------------------------------
216
+#elif defined(__AVR_AT90USB646__)\
217
+|| defined(__AVR_AT90USB1286__)
218
+// Teensy++ 1.0 & 2.0
219
+
220
+// Two Wire (aka I2C) ports
221
+uint8_t const SDA_PIN = 1;  // D1
222
+uint8_t const SCL_PIN = 0;  // D0
223
+
224
+// SPI port
225
+uint8_t const SS_PIN = 20;    // B0
226
+uint8_t const MOSI_PIN = 22;  // B2
227
+uint8_t const MISO_PIN = 23;  // B3
228
+uint8_t const SCK_PIN = 21;   // B1
229
+
230
+static const pin_map_t digitalPinMap[] = {
231
+  {&DDRD, &PIND, &PORTD, 0},  // D0  0
232
+  {&DDRD, &PIND, &PORTD, 1},  // D1  1
233
+  {&DDRD, &PIND, &PORTD, 2},  // D2  2
234
+  {&DDRD, &PIND, &PORTD, 3},  // D3  3
235
+  {&DDRD, &PIND, &PORTD, 4},  // D4  4
236
+  {&DDRD, &PIND, &PORTD, 5},  // D5  5
237
+  {&DDRD, &PIND, &PORTD, 6},  // D6  6
238
+  {&DDRD, &PIND, &PORTD, 7},  // D7  7
239
+  {&DDRE, &PINE, &PORTE, 0},  // E0  8
240
+  {&DDRE, &PINE, &PORTE, 1},  // E1  9
241
+  {&DDRC, &PINC, &PORTC, 0},  // C0 10
242
+  {&DDRC, &PINC, &PORTC, 1},  // C1 11
243
+  {&DDRC, &PINC, &PORTC, 2},  // C2 12
244
+  {&DDRC, &PINC, &PORTC, 3},  // C3 13
245
+  {&DDRC, &PINC, &PORTC, 4},  // C4 14
246
+  {&DDRC, &PINC, &PORTC, 5},  // C5 15
247
+  {&DDRC, &PINC, &PORTC, 6},  // C6 16
248
+  {&DDRC, &PINC, &PORTC, 7},  // C7 17
249
+  {&DDRE, &PINE, &PORTE, 6},  // E6 18
250
+  {&DDRE, &PINE, &PORTE, 7},  // E7 19
251
+  {&DDRB, &PINB, &PORTB, 0},  // B0 20
252
+  {&DDRB, &PINB, &PORTB, 1},  // B1 21
253
+  {&DDRB, &PINB, &PORTB, 2},  // B2 22
254
+  {&DDRB, &PINB, &PORTB, 3},  // B3 23
255
+  {&DDRB, &PINB, &PORTB, 4},  // B4 24
256
+  {&DDRB, &PINB, &PORTB, 5},  // B5 25
257
+  {&DDRB, &PINB, &PORTB, 6},  // B6 26
258
+  {&DDRB, &PINB, &PORTB, 7},  // B7 27
259
+  {&DDRA, &PINA, &PORTA, 0},  // A0 28
260
+  {&DDRA, &PINA, &PORTA, 1},  // A1 29
261
+  {&DDRA, &PINA, &PORTA, 2},  // A2 30
262
+  {&DDRA, &PINA, &PORTA, 3},  // A3 31
263
+  {&DDRA, &PINA, &PORTA, 4},  // A4 32
264
+  {&DDRA, &PINA, &PORTA, 5},  // A5 33
265
+  {&DDRA, &PINA, &PORTA, 6},  // A6 34
266
+  {&DDRA, &PINA, &PORTA, 7},  // A7 35
267
+  {&DDRE, &PINE, &PORTE, 4},  // E4 36
268
+  {&DDRE, &PINE, &PORTE, 5},  // E5 37
269
+  {&DDRF, &PINF, &PORTF, 0},  // F0 38
270
+  {&DDRF, &PINF, &PORTF, 1},  // F1 39
271
+  {&DDRF, &PINF, &PORTF, 2},  // F2 40
272
+  {&DDRF, &PINF, &PORTF, 3},  // F3 41
273
+  {&DDRF, &PINF, &PORTF, 4},  // F4 42
274
+  {&DDRF, &PINF, &PORTF, 5},  // F5 43
275
+  {&DDRF, &PINF, &PORTF, 6},  // F6 44
276
+  {&DDRF, &PINF, &PORTF, 7}   // F7 45
277
+};
278
+//------------------------------------------------------------------------------
279
+#elif defined(__AVR_ATmega168__)\
280
+||defined(__AVR_ATmega168P__)\
281
+||defined(__AVR_ATmega328P__)
282
+// 168 and 328 Arduinos
283
+
284
+// Two Wire (aka I2C) ports
285
+uint8_t const SDA_PIN = 18;  // C4
286
+uint8_t const SCL_PIN = 19;  // C5
287
+
288
+// SPI port
289
+uint8_t const SS_PIN = 10;    // B2
290
+uint8_t const MOSI_PIN = 11;  // B3
291
+uint8_t const MISO_PIN = 12;  // B4
292
+uint8_t const SCK_PIN = 13;   // B5
293
+
294
+static const pin_map_t digitalPinMap[] = {
295
+  {&DDRD, &PIND, &PORTD, 0},  // D0  0
296
+  {&DDRD, &PIND, &PORTD, 1},  // D1  1
297
+  {&DDRD, &PIND, &PORTD, 2},  // D2  2
298
+  {&DDRD, &PIND, &PORTD, 3},  // D3  3
299
+  {&DDRD, &PIND, &PORTD, 4},  // D4  4
300
+  {&DDRD, &PIND, &PORTD, 5},  // D5  5
301
+  {&DDRD, &PIND, &PORTD, 6},  // D6  6
302
+  {&DDRD, &PIND, &PORTD, 7},  // D7  7
303
+  {&DDRB, &PINB, &PORTB, 0},  // B0  8
304
+  {&DDRB, &PINB, &PORTB, 1},  // B1  9
305
+  {&DDRB, &PINB, &PORTB, 2},  // B2 10
306
+  {&DDRB, &PINB, &PORTB, 3},  // B3 11
307
+  {&DDRB, &PINB, &PORTB, 4},  // B4 12
308
+  {&DDRB, &PINB, &PORTB, 5},  // B5 13
309
+  {&DDRC, &PINC, &PORTC, 0},  // C0 14
310
+  {&DDRC, &PINC, &PORTC, 1},  // C1 15
311
+  {&DDRC, &PINC, &PORTC, 2},  // C2 16
312
+  {&DDRC, &PINC, &PORTC, 3},  // C3 17
313
+  {&DDRC, &PINC, &PORTC, 4},  // C4 18
314
+  {&DDRC, &PINC, &PORTC, 5}   // C5 19
315
+};
316
+#else  // defined(__AVR_ATmega1280__)
317
+#error unknown chip
318
+#endif  // defined(__AVR_ATmega1280__)
319
+//------------------------------------------------------------------------------
320
+static const uint8_t digitalPinCount = sizeof(digitalPinMap)/sizeof(pin_map_t);
321
+
322
+uint8_t badPinNumber(void)
323
+  __attribute__((error("Pin number is too large or not a constant")));
324
+
325
+static inline __attribute__((always_inline))
326
+  bool getPinMode(uint8_t pin) {
327
+  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
328
+    return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1;
329
+  } else {
330
+    return badPinNumber();
331
+  }
332
+}
333
+static inline __attribute__((always_inline))
334
+  void setPinMode(uint8_t pin, uint8_t mode) {
335
+  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
336
+    if (mode) {
337
+      *digitalPinMap[pin].ddr |= 1 << digitalPinMap[pin].bit;
338
+    } else {
339
+      *digitalPinMap[pin].ddr &= ~(1 << digitalPinMap[pin].bit);
340
+    }
341
+  } else {
342
+    badPinNumber();
343
+  }
344
+}
345
+static inline __attribute__((always_inline))
346
+  bool fastDigitalRead(uint8_t pin) {
347
+  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
348
+    return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1;
349
+  } else {
350
+    return badPinNumber();
351
+  }
352
+}
353
+static inline __attribute__((always_inline))
354
+  void fastDigitalWrite(uint8_t pin, uint8_t value) {
355
+  if (__builtin_constant_p(pin) && pin < digitalPinCount) {
356
+    if (value) {
357
+      *digitalPinMap[pin].port |= 1 << digitalPinMap[pin].bit;
358
+    } else {
359
+      *digitalPinMap[pin].port &= ~(1 << digitalPinMap[pin].bit);
360
+    }
361
+  } else {
362
+    badPinNumber();
363
+  }
364
+}
365
+#endif  // Sd2PinMap_h
366
+
367
+
368
+#endif

File diff suppressed because it is too large
+ 1791 - 0
SdBaseFile.cpp


+ 483 - 0
SdBaseFile.h

@@ -0,0 +1,483 @@
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
+ * <http://www.gnu.org/licenses/>.
19
+ */
20
+#include "Marlin.h"
21
+#ifdef SDSUPPORT
22
+
23
+#ifndef SdBaseFile_h
24
+#define SdBaseFile_h
25
+/**
26
+ * \file
27
+ * \brief SdBaseFile class
28
+ */
29
+#include "Marlin.h"
30
+#include "SdFatConfig.h"
31
+#include "SdVolume.h"
32
+//------------------------------------------------------------------------------
33
+/**
34
+ * \struct fpos_t
35
+ * \brief internal type for istream
36
+ * do not use in user apps
37
+ */
38
+struct fpos_t {
39
+  /** stream position */
40
+  uint32_t position;
41
+  /** cluster for position */
42
+  uint32_t cluster;
43
+  fpos_t() : position(0), cluster(0) {}
44
+};
45
+
46
+// use the gnu style oflag in open()
47
+/** open() oflag for reading */
48
+uint8_t const O_READ = 0X01;
49
+/** open() oflag - same as O_IN */
50
+uint8_t const O_RDONLY = O_READ;
51
+/** open() oflag for write */
52
+uint8_t const O_WRITE = 0X02;
53
+/** open() oflag - same as O_WRITE */
54
+uint8_t const O_WRONLY = O_WRITE;
55
+/** open() oflag for reading and writing */
56
+uint8_t const O_RDWR = (O_READ | O_WRITE);
57
+/** open() oflag mask for access modes */
58
+uint8_t const O_ACCMODE = (O_READ | O_WRITE);
59
+/** The file offset shall be set to the end of the file prior to each write. */
60
+uint8_t const O_APPEND = 0X04;
61
+/** synchronous writes - call sync() after each write */
62
+uint8_t const O_SYNC = 0X08;
63
+/** truncate the file to zero length */
64
+uint8_t const O_TRUNC = 0X10;
65
+/** set the initial position at the end of the file */
66
+uint8_t const O_AT_END = 0X20;
67
+/** create the file if nonexistent */
68
+uint8_t const O_CREAT = 0X40;
69
+/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
70
+uint8_t const O_EXCL = 0X80;
71
+
72
+// SdBaseFile class static and const definitions
73
+// flags for ls()
74
+/** ls() flag to print modify date */
75
+uint8_t const LS_DATE = 1;
76
+/** ls() flag to print file size */
77
+uint8_t const LS_SIZE = 2;
78
+/** ls() flag for recursive list of subdirectories */
79
+uint8_t const LS_R = 4;
80
+
81
+
82
+// flags for timestamp
83
+/** set the file's last access date */
84
+uint8_t const T_ACCESS = 1;
85
+/** set the file's creation date and time */
86
+uint8_t const T_CREATE = 2;
87
+/** Set the file's write date and time */
88
+uint8_t const T_WRITE = 4;
89
+// values for type_
90
+/** This file has not been opened. */
91
+uint8_t const FAT_FILE_TYPE_CLOSED = 0;
92
+/** A normal file */
93
+uint8_t const FAT_FILE_TYPE_NORMAL = 1;
94
+/** A FAT12 or FAT16 root directory */
95
+uint8_t const FAT_FILE_TYPE_ROOT_FIXED = 2;
96
+/** A FAT32 root directory */
97
+uint8_t const FAT_FILE_TYPE_ROOT32 = 3;
98
+/** A subdirectory file*/
99
+uint8_t const FAT_FILE_TYPE_SUBDIR = 4;
100
+/** Test value for directory type */
101
+uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED;
102
+
103
+/** date field for FAT directory entry
104
+ * \param[in] year [1980,2107]
105
+ * \param[in] month [1,12]
106
+ * \param[in] day [1,31]
107
+ *
108
+ * \return Packed date for dir_t entry.
109
+ */
110
+static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) {
111
+  return (year - 1980) << 9 | month << 5 | day;
112
+}
113
+/** year part of FAT directory date field
114
+ * \param[in] fatDate Date in packed dir format.
115
+ *
116
+ * \return Extracted year [1980,2107]
117
+ */
118
+static inline uint16_t FAT_YEAR(uint16_t fatDate) {
119
+  return 1980 + (fatDate >> 9);
120
+}
121
+/** month part of FAT directory date field
122