// Uncomment this if you are using liquid crystal library
285 | #endif
286 |
287 | void setup()
288 | {
289 | Printer::setup();
290 | }
291 |
292 | void loop()
293 | {
294 | Commands::commandLoop();
295 | }
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
--------------------------------------------------------------------------------
/Wangsamas/SDCard.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan.
3 |
4 | Wangsamas-Firmware adalah perangkat lunak bebas:
5 | Anda dapat mendistribusikannya dan/atau mengubahnya
6 | dengan syarat dan ketentuan GNU General Public License
7 | yang dipublikasikan oleh Free Software Foundation,
8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru.
9 |
10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat,
11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau
12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License
13 | untuk keterangan lebih lanjut.
14 |
15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan
16 | dengan Wangsamas-Firmware. Jika tidak, lihat .
17 |
18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware
19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware.
20 |
21 | ---------------------
22 |
23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan.
24 |
25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify
26 | it under the terms of the GNU General Public License as published by
27 | the Free Software Foundation, either version 3 of the License, or
28 | (at your option) any later version.
29 |
30 | Wangsamas-Firmware is distributed in the hope that it will be useful,
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | GNU General Public License for more details.
34 |
35 | You should have received a copy of the GNU General Public License
36 | along with Wangsamas-Firmware. If not, see .
37 |
38 | This firmware is based on Repetier-Firmware which based on sprinter firmware
39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
40 | */
41 |
42 | #include "Wangsamas.h"
43 |
44 | #if SDSUPPORT
45 |
46 | char tempLongFilename[LONG_FILENAME_LENGTH + 1];
47 | char fullName[LONG_FILENAME_LENGTH * SD_MAX_FOLDER_DEPTH + SD_MAX_FOLDER_DEPTH + 1];
48 |
49 | SDCard sd;
50 |
51 | SDCard::SDCard()
52 | {
53 | sdmode = 0;
54 | sdactive = false;
55 | savetosd = false;
56 | Printer::setAutomount(false);
57 | }
58 |
59 | void SDCard::automount()
60 | {
61 | #if SDCARDDETECT > -1
62 | if(READ(SDCARDDETECT) != SDCARDDETECTINVERTED)
63 | {
64 | if(sdactive || sdmode == 100) // Card removed
65 | {
66 | Com::printFLN(PSTR("SD card removed"));
67 | #if UI_DISPLAY_TYPE != NO_DISPLAY
68 | uid.executeAction(UI_ACTION_TOP_MENU, true);
69 | #endif
70 | unmount();
71 | UI_STATUS_UPD_F(Com::translatedF(UI_TEXT_SD_REMOVED_ID));
72 | }
73 | }
74 | else
75 | {
76 | if(!sdactive && sdmode != 100)
77 | {
78 | UI_STATUS_UPD_F(Com::translatedF(UI_TEXT_SD_INSERTED_ID));
79 | mount();
80 | if(sdmode != 100) // send message only if we have success
81 | Com::printFLN(PSTR("SD card inserted")); // Not translatable or host will not understand signal
82 | #if UI_DISPLAY_TYPE != NO_DISPLAY
83 | if(sdactive && !uid.isWizardActive()) { // Wizards have priority
84 | Printer::setAutomount(true);
85 | uid.executeAction(UI_ACTION_SD_PRINT + UI_ACTION_TOPMENU, true);
86 | }
87 | #endif
88 | }
89 | }
90 | #endif
91 | }
92 |
93 | void SDCard::initsd()
94 | {
95 | sdactive = false;
96 | #if SDSS > -1
97 | #if SDCARDDETECT > -1
98 | if(READ(SDCARDDETECT) != SDCARDDETECTINVERTED)
99 | return;
100 | #endif
101 | HAL::pingWatchdog();
102 | HAL::delayMilliseconds(50); // wait for stabilization of contacts, bootup ...
103 | fat.begin(SDSS, SPI_FULL_SPEED); // dummy init of SD_CARD
104 | HAL::delayMilliseconds(50); // wait for init end
105 | HAL::pingWatchdog();
106 | /*if(dir[0].isOpen())
107 | dir[0].close();*/
108 | if(!fat.begin(SDSS, SPI_FULL_SPEED))
109 | {
110 | Com::printFLN(Com::tSDInitFail);
111 | sdmode = 100; // prevent automount loop!
112 | return;
113 | }
114 | sdactive = true;
115 | Printer::setMenuMode(MENU_MODE_SD_MOUNTED, true);
116 | HAL::pingWatchdog();
117 |
118 | fat.chdir();
119 | if(selectFile("init.g", true))
120 | {
121 | startPrint();
122 | }
123 | #endif
124 | }
125 |
126 | void SDCard::mount()
127 | {
128 | sdmode = 0;
129 | initsd();
130 | }
131 |
132 | void SDCard::unmount()
133 | {
134 | sdmode = 0;
135 | sdactive = false;
136 | savetosd = false;
137 | Printer::setAutomount(false);
138 | Printer::setMenuMode(MENU_MODE_SD_MOUNTED + MENU_MODE_SD_PAUSED + MENU_MODE_SD_PRINTING, false);
139 | #if UI_DISPLAY_TYPE != NO_DISPLAY && SDSUPPORT
140 | uid.cwd[0] = '/';
141 | uid.cwd[1] = 0;
142 | uid.folderLevel = 0;
143 | #endif
144 | }
145 |
146 | void SDCard::startPrint()
147 | {
148 | if(!sdactive) return;
149 | sdmode = 1;
150 | Printer::setMenuMode(MENU_MODE_SD_PRINTING, true);
151 | Printer::setMenuMode(MENU_MODE_SD_PAUSED, false);
152 | }
153 | void SDCard::pausePrint(bool intern)
154 | {
155 | if(!sd.sdactive) return;
156 | sdmode = 2; // finish running line
157 | Printer::setMenuMode(MENU_MODE_SD_PAUSED, true);
158 | if(intern) {
159 | Commands::waitUntilEndOfAllBuffers();
160 | sdmode = 0;
161 | Printer::MemoryPosition();
162 | Printer::moveToReal(IGNORE_COORDINATE, IGNORE_COORDINATE, IGNORE_COORDINATE,
163 | Printer::memoryE - RETRACT_ON_PAUSE,
164 | Printer::maxFeedrate[E_AXIS] / 2);
165 | #if DRIVE_SYSTEM == DELTA
166 | Printer::moveToReal(0, 0.9 * EEPROM::deltaMaxRadius(), IGNORE_COORDINATE, IGNORE_COORDINATE, Printer::maxFeedrate[X_AXIS]);
167 | #else
168 | Printer::moveToReal(Printer::xMin, Printer::yMin + Printer::yLength, IGNORE_COORDINATE, IGNORE_COORDINATE, Printer::maxFeedrate[X_AXIS]);
169 | #endif
170 | Printer::lastCmdPos[X_AXIS] = Printer::currentPosition[X_AXIS];
171 | Printer::lastCmdPos[Y_AXIS] = Printer::currentPosition[Y_AXIS];
172 | Printer::lastCmdPos[Z_AXIS] = Printer::currentPosition[Z_AXIS];
173 | GCode::executeFString(PSTR(PAUSE_START_COMMANDS));
174 | }
175 | }
176 |
177 | void SDCard::continuePrint(bool intern)
178 | {
179 | if(!sd.sdactive) return;
180 | if(intern) {
181 | GCode::executeFString(PSTR(PAUSE_END_COMMANDS));
182 | Printer::GoToMemoryPosition(true, true, false, false, Printer::maxFeedrate[X_AXIS]);
183 | Printer::GoToMemoryPosition(false, false, true, false, Printer::maxFeedrate[Z_AXIS] / 2.0f);
184 | Printer::GoToMemoryPosition(false, false, false, true, Printer::maxFeedrate[E_AXIS] / 2.0f);
185 | }
186 | Printer::setMenuMode(MENU_MODE_SD_PAUSED, false);
187 | sdmode = 1;
188 | }
189 |
190 | void SDCard::stopPrint()
191 | {
192 | if(!sd.sdactive) return;
193 | if(sdmode)
194 | Com::printFLN(PSTR("SD print stopped by user."));
195 | sdmode = 0;
196 | Printer::setMenuMode(MENU_MODE_SD_PRINTING,false);
197 | Printer::setMenuMode(MENU_MODE_SD_PAUSED,false);
198 | GCode::executeFString(PSTR(SD_RUN_ON_STOP));
199 | #if DRIVE_SYSTEM == SCARA
200 | Printer::closeArm(true, true, true);
201 | #endif
202 | if(SD_STOP_HEATER_AND_MOTORS_ON_STOP) {
203 | Commands::waitUntilEndOfAllMoves();
204 | Printer::kill(false);
205 | }
206 | }
207 |
208 | void SDCard::writeCommand(GCode *code)
209 | {
210 | unsigned int sum1 = 0, sum2 = 0; // for fletcher-16 checksum
211 | uint8_t buf[100];
212 | uint8_t p = 2;
213 | file.writeError = false;
214 | uint16_t params = 128 | (code->params & ~1);
215 | memcopy2(buf,¶ms);
216 | //*(int*)buf = params;
217 | if(code->isV2()) // Read G,M as 16 bit value
218 | {
219 | memcopy2(&buf[p],&code->params2);
220 | //*(int*)&buf[p] = code->params2;
221 | p += 2;
222 | if(code->hasString())
223 | buf[p++] = strlen(code->text);
224 | if(code->hasM())
225 | {
226 | memcopy2(&buf[p],&code->M);
227 | //*(int*)&buf[p] = code->M;
228 | p += 2;
229 | }
230 | if(code->hasG())
231 | {
232 | memcopy2(&buf[p],&code->G);
233 | //*(int*)&buf[p]= code->G;
234 | p += 2;
235 | }
236 | }
237 | else
238 | {
239 | if(code->hasM())
240 | {
241 | buf[p++] = (uint8_t)code->M;
242 | }
243 | if(code->hasG())
244 | {
245 | buf[p++] = (uint8_t)code->G;
246 | }
247 | }
248 | if(code->hasX())
249 | {
250 | memcopy4(&buf[p],&code->X);
251 | //*(float*)&buf[p] = code->X;
252 | p += 4;
253 | }
254 | if(code->hasY())
255 | {
256 | memcopy4(&buf[p],&code->Y);
257 | //*(float*)&buf[p] = code->Y;
258 | p += 4;
259 | }
260 | if(code->hasZ())
261 | {
262 | memcopy4(&buf[p],&code->Z);
263 | //*(float*)&buf[p] = code->Z;
264 | p += 4;
265 | }
266 | if(code->hasE())
267 | {
268 | memcopy4(&buf[p],&code->E);
269 | //*(float*)&buf[p] = code->E;
270 | p += 4;
271 | }
272 | if(code->hasF())
273 | {
274 | memcopy4(&buf[p],&code->F);
275 | //*(float*)&buf[p] = code->F;
276 | p += 4;
277 | }
278 | if(code->hasT())
279 | {
280 | buf[p++] = code->T;
281 | }
282 | if(code->hasS())
283 | {
284 | memcopy4(&buf[p],&code->S);
285 | //*(int32_t*)&buf[p] = code->S;
286 | p += 4;
287 | }
288 | if(code->hasP())
289 | {
290 | memcopy4(&buf[p],&code->P);
291 | //*(int32_t*)&buf[p] = code->P;
292 | p += 4;
293 | }
294 | if(code->hasI())
295 | {
296 | memcopy4(&buf[p],&code->I);
297 | //*(float*)&buf[p] = code->I;
298 | p += 4;
299 | }
300 | if(code->hasJ())
301 | {
302 | memcopy4(&buf[p],&code->J);
303 | //*(float*)&buf[p] = code->J;
304 | p += 4;
305 | }
306 | if(code->hasR())
307 | {
308 | memcopy4(&buf[p],&code->R);
309 | //*(float*)&buf[p] = code->R;
310 | p += 4;
311 | }
312 | if(code->hasD())
313 | {
314 | memcopy4(&buf[p],&code->D);
315 | //*(float*)&buf[p] = code->D;
316 | p += 4;
317 | }
318 | if(code->hasC())
319 | {
320 | memcopy4(&buf[p],&code->C);
321 | //*(float*)&buf[p] = code->C;
322 | p += 4;
323 | }
324 | if(code->hasH())
325 | {
326 | memcopy4(&buf[p],&code->H);
327 | //*(float*)&buf[p] = code->H;
328 | p += 4;
329 | }
330 | if(code->hasA())
331 | {
332 | memcopy4(&buf[p],&code->A);
333 | //*(float*)&buf[p] = code->A;
334 | p += 4;
335 | }
336 | if(code->hasB())
337 | {
338 | memcopy4(&buf[p],&code->B);
339 | //*(float*)&buf[p] = code->B;
340 | p += 4;
341 | }
342 | if(code->hasK())
343 | {
344 | memcopy4(&buf[p],&code->K);
345 | //*(float*)&buf[p] = code->K;
346 | p += 4;
347 | }
348 | if(code->hasL())
349 | {
350 | memcopy4(&buf[p],&code->L);
351 | //*(float*)&buf[p] = code->L;
352 | p += 4;
353 | }
354 | if(code->hasO())
355 | {
356 | memcopy4(&buf[p],&code->O);
357 | //*(float*)&buf[p] = code->O;
358 | p += 4;
359 | }
360 | if(code->hasString()) // read 16 uint8_t into string
361 | {
362 | char *sp = code->text;
363 | if(code->isV2())
364 | {
365 | uint8_t i = strlen(code->text);
366 | for(; i; i--) buf[p++] = *sp++;
367 | }
368 | else
369 | {
370 | for(uint8_t i = 0; i < 16; ++i) buf[p++] = *sp++;
371 | }
372 | }
373 | uint8_t *ptr = buf;
374 | uint8_t len = p;
375 | while (len)
376 | {
377 | uint8_t tlen = len > 21 ? 21 : len;
378 | len -= tlen;
379 | do
380 | {
381 | sum1 += *ptr++;
382 | if(sum1 >= 255) sum1 -= 255;
383 | sum2 += sum1;
384 | if(sum2 >= 255) sum2 -= 255;
385 | }
386 | while (--tlen);
387 | }
388 | buf[p++] = sum1;
389 | buf[p++] = sum2;
390 | // Debug
391 | /*Com::printF(PSTR("Buf: "));
392 | for(int i=0;iinit(targetFile);
514 | }
515 | if (!targetFile.isOpen()) {
516 | Com::printF(Com::tJSONErrorStart);
517 | Com::printF(Com::tNotSDPrinting);
518 | Com::printFLN(Com::tJSONErrorEnd);
519 | return;
520 | }
521 |
522 | // {"err":0,"size":457574,"height":4.00,"layerHeight":0.25,"filament":[6556.3],"generatedBy":"Slic3r 1.1.7 on 2014-11-09 at 17:11:32"}
523 | Com::printF(Com::tJSONFileInfoStart);
524 | Com::print(info->fileSize);
525 | Com::printF(Com::tJSONFileInfoHeight);
526 | Com::print(info->objectHeight);
527 | Com::printF(Com::tJSONFileInfoLayerHeight);
528 | Com::print(info->layerHeight);
529 | Com::printF(Com::tJSONFileInfoFilament);
530 | Com::print(info->filamentNeeded);
531 | Com::printF(Com::tJSONFileInfoGeneratedBy);
532 | Com::print(info->generatedBy);
533 | Com::print('"');
534 | if (strlen(filename) == 0) {
535 | Com::printF(Com::tJSONFileInfoName);
536 | file.printName();
537 | Com::print('"');
538 | }
539 | Com::print('}');
540 | Com::println();
541 | };
542 |
543 | #endif
544 |
545 | bool SDCard::selectFile(const char *filename, bool silent)
546 | {
547 | SdBaseFile parent;
548 | const char *oldP = filename;
549 |
550 | if(!sdactive) return false;
551 | sdmode = 0;
552 |
553 | file.close();
554 |
555 | parent = *fat.vwd();
556 | if (file.open(&parent, filename, O_READ))
557 | {
558 | if ((oldP = strrchr(filename, '/')) != NULL)
559 | oldP++;
560 | else
561 | oldP = filename;
562 |
563 | if(!silent)
564 | {
565 | Com::printF(Com::tFileOpened, oldP);
566 | Com::printFLN(Com::tSpaceSizeColon,file.fileSize());
567 | }
568 | #if JSON_OUTPUT
569 | fileInfo.init(file);
570 | #endif
571 | sdpos = 0;
572 | filesize = file.fileSize();
573 | Com::printFLN(Com::tFileSelected);
574 | return true;
575 | }
576 | else
577 | {
578 | if(!silent)
579 | Com::printFLN(Com::tFileOpenFailed);
580 | return false;
581 | }
582 | }
583 |
584 | void SDCard::printStatus()
585 | {
586 | if(sdactive)
587 | {
588 | Com::printF(Com::tSDPrintingByte, sdpos);
589 | Com::printFLN(Com::tSlash, filesize);
590 | }
591 | else
592 | {
593 | Com::printFLN(Com::tNotSDPrinting);
594 | }
595 | }
596 |
597 | void SDCard::startWrite(char *filename)
598 | {
599 | if(!sdactive) return;
600 | file.close();
601 | sdmode = 0;
602 | fat.chdir();
603 | if(!file.open(filename, O_CREAT | O_APPEND | O_WRITE | O_TRUNC))
604 | {
605 | Com::printFLN(Com::tOpenFailedFile,filename);
606 | }
607 | else
608 | {
609 | UI_STATUS_F(Com::translatedF(UI_TEXT_UPLOADING_ID));
610 | savetosd = true;
611 | Com::printFLN(Com::tWritingToFile,filename);
612 | }
613 | }
614 |
615 | void SDCard::finishWrite()
616 | {
617 | if(!savetosd) return; // already closed or never opened
618 | file.sync();
619 | file.close();
620 | savetosd = false;
621 | Com::printFLN(Com::tDoneSavingFile);
622 | UI_CLEAR_STATUS;
623 | }
624 |
625 | void SDCard::deleteFile(char *filename)
626 | {
627 | if(!sdactive) return;
628 | sdmode = 0;
629 | file.close();
630 | if(fat.remove(filename))
631 | {
632 | Com::printFLN(Com::tFileDeleted);
633 | }
634 | else
635 | {
636 | if(fat.rmdir(filename))
637 | Com::printFLN(Com::tFileDeleted);
638 | else
639 | Com::printFLN(Com::tDeletionFailed);
640 | }
641 | }
642 |
643 | void SDCard::makeDirectory(char *filename)
644 | {
645 | if(!sdactive) return;
646 | sdmode = 0;
647 | file.close();
648 | if(fat.mkdir(filename))
649 | {
650 | Com::printFLN(Com::tDirectoryCreated);
651 | }
652 | else
653 | {
654 | Com::printFLN(Com::tCreationFailed);
655 | }
656 | }
657 |
658 | #ifdef GLENN_DEBUG
659 | void SDCard::writeToFile()
660 | {
661 | size_t nbyte;
662 | char szName[10];
663 |
664 | strcpy(szName, "Testing\r\n");
665 | nbyte = file.write(szName, strlen(szName));
666 | Com::print("L=");
667 | Com::print((long)nbyte);
668 | Com::println();
669 | }
670 |
671 | #endif
672 |
673 | #endif
674 |
675 |
--------------------------------------------------------------------------------
/Wangsamas/uiconfig.h:
--------------------------------------------------------------------------------
1 | /*
2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan.
3 |
4 | Wangsamas-Firmware adalah perangkat lunak bebas:
5 | Anda dapat mendistribusikannya dan/atau mengubahnya
6 | dengan syarat dan ketentuan GNU General Public License
7 | yang dipublikasikan oleh Free Software Foundation,
8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru.
9 |
10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat,
11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau
12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License
13 | untuk keterangan lebih lanjut.
14 |
15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan
16 | dengan Wangsamas-Firmware. Jika tidak, lihat .
17 |
18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware
19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware.
20 |
21 | ---------------------
22 |
23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan.
24 |
25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify
26 | it under the terms of the GNU General Public License as published by
27 | the Free Software Foundation, either version 3 of the License, or
28 | (at your option) any later version.
29 |
30 | Wangsamas-Firmware is distributed in the hope that it will be useful,
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | GNU General Public License for more details.
34 |
35 | You should have received a copy of the GNU General Public License
36 | along with Wangsamas-Firmware. If not, see .
37 |
38 | This firmware is based on Repetier-Firmware which based on sprinter firmware
39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
40 |
41 | */
42 |
43 | /* ===================== IMPORTANT ========================
44 |
45 | The LCD and Key support is new. I tested everything as good as possible,
46 | but some combinations may not work as supposed.
47 | The I2C methods rely on a stable I2C connection. Noise may cause wrong signals
48 | which can cause the firmware to freeze.
49 |
50 | The ui adds quite some code, so AVRs with 64kB ram (Sanguino, Gen6) can not handle all features
51 | of the firmware at the same time. You have to disable some features to gain the
52 | ram needed. What should work:
53 | - No sd card - the sd card code is quite large.
54 | - No keys attached - The longest part is the menu handling.
55 | - EEPROM_MODE 0 .
56 |
57 | Currently supported hardware:
58 |
59 | *** Displays ***
60 |
61 | - direct connected lcd with 4 data lines
62 | - connected via i2c
63 |
64 | *** Keys ***
65 |
66 | - rotary encoder
67 | - push button
68 | - key matrix up to 4x4
69 | - rotary encoder via i2c (only slow turns are captured correct)
70 | - push button via i2c
71 |
72 | *** Buzzer ***
73 |
74 | - directly connected, high = on
75 | - connected via i2c, low = on
76 |
77 | ==============================================================*/
78 |
79 | #ifndef _ui_config_h
80 | #define _ui_config_h
81 |
82 | /** While the ascii chars are all the same, the driver have different charsets
83 | for special chars used in different countries. The charset allows to fix for
84 | this problem. If characters look wrong, try a different charset. If nothing
85 | works, use the ascii charset 0 as fallback. Not the nicest for everything but working!
86 |
87 | 0 = ASCII fallback
88 | 1 = Default works on most displays. This has some japanese chars in charset
89 | 2 = Alternative charset with more european chars
90 |
91 | */
92 | #define UI_DISPLAY_CHARSET 2
93 |
94 | /** Select type of beeper
95 | 0 = none
96 | 1 = Piezo connected to pin
97 | 2 = Piezo connected to a pin over I2C
98 | */
99 | #ifndef BEEPER_TYPE
100 | #define BEEPER_TYPE 1
101 | #define BEEPER_TYPE_INVERTING false
102 | #endif
103 |
104 | #if BEEPER_TYPE==1 && !defined(BEEPER_PIN)
105 | #define BEEPER_PIN 37
106 | #endif
107 | #if BEEPER_TYPE==2
108 | #define BEEPER_ADDRESS 0x40 // I2C address of the chip with the beeper pin
109 | #define BEEPER_PIN _BV(7) // Bit value for pin 8
110 | #define COMPILE_I2C_DRIVER // We need the I2C driver as we are using i2c
111 | #endif
112 |
113 |
114 | /**
115 | What display type do you use?
116 | 0 = No display - do not use here. Set FEATURE_CONTROLLER 0 instead
117 | 1 = LCD Display with 4 bit data bus
118 | 2 = LCD Display with 8 bit data bus (currently not implemented, fallback to 1)
119 | 3 = LCD Display with I2C connection, 4 bit mode
120 | 4 = Use the slower LiquiedCrystal library bundled with arduino.
121 | IMPORTANT: You need to uncomment the LiquidCrystal include in Repetier.pde for it to work.
122 | If you have Sanguino and want to use the library, you need to have Arduino 023 or older. (13.04.2012)
123 | 5 = U8G supported display
124 | */
125 | #define UI_DISPLAY_TYPE 5
126 |
127 | #if UI_DISPLAY_TYPE == DISPLAY_U8G // Special case for graphic displays
128 |
129 | // You need to define which controller you use and set pins accodringly
130 |
131 | // For software spi assign these definitions
132 | // SCK Pin: UI_DISPLAY_D4_PIN
133 | // Mosi Pin: UI_DISPLAY_ENABLE_PIN
134 | // CD Pin: UI_DISPLAY_RS_PIN
135 |
136 | // ST7920 with software SPI
137 | #define U8GLIB_ST7920
138 | // SSD1306 with software SPI
139 | //#define U8GLIB_SSD1306_SW_SPI
140 | // SH1106 with software SPI
141 | // U8GLIB_SH1106_SW_SPI
142 | // SSD1306 over I2C using hardware I2C pins
143 | //#define U8GLIB_SSD1306_I2C
144 | // For the 8 bit ks0108 display you need to set these pins
145 | // UI_DISPLAY_D0_PIN,UI_DISPLAY_D1_PIN,UI_DISPLAY_D2_PIN,UI_DISPLAY_D3_PIN,UI_DISPLAY_D4_PIN,UI_DISPLAY_D5_PIN,UI_DISPLAY_D6_PIN,UI_DISPLAY_D7_PIN
146 | // UI_DISPLAY_ENABLE_PIN,UI_DISPLAY_CS1,UI_DISPLAY_CS2,
147 | // UI_DISPLAY_DI,UI_DISPLAY_RW_PIN,UI_DISPLAY_RESET_PIN
148 | //#define U8GLIB_KS0108
149 | //#define U8GLIB_KS0108_FAST
150 | // UI_DISPLAY_RS_PIN = CS
151 | // UI_DISPLAY_D5_PIN = A0
152 | //#define U8GLIB_ST7565_NHD_C2832_HW_SPI
153 |
154 | #define UI_LCD_WIDTH 128
155 | #define UI_LCD_HEIGHT 64
156 |
157 | //select font size
158 | #define UI_FONT_6X10 //default font
159 | #ifdef UI_FONT_6X10
160 | #define UI_FONT_WIDTH 6
161 | #define UI_FONT_HEIGHT 10
162 | #define UI_FONT_SMALL_HEIGHT 7
163 | #define UI_FONT_DEFAULT wangsamas_6x10
164 | #define UI_FONT_SMALL wangsamas_5x7
165 | #define UI_FONT_SMALL_WIDTH 5 //smaller font for status display
166 | #define UI_ANIMATION false // Animations are too slow
167 | #endif
168 |
169 | //calculate rows and cols available with current font
170 | #define UI_COLS (UI_LCD_WIDTH/UI_FONT_WIDTH)
171 | #define UI_ROWS (UI_LCD_HEIGHT/UI_FONT_HEIGHT)
172 | #define UI_DISPLAY_CHARSET 3
173 | #else
174 | /** Number of columns per row
175 | Typical values are 16 and 20
176 | */
177 | #define UI_COLS 20
178 | /**
179 | Rows of your display. 2 or 4
180 | */
181 | #define UI_ROWS 4
182 | #endif // UI_DISPLAY_TYPE
183 |
184 | /* What type of chip is used for I2C communication
185 | 0 : PCF8574 or PCF8574A or compatible chips.
186 | 1 : MCP23017
187 | */
188 | #define UI_DISPLAY_I2C_CHIPTYPE 0
189 | // 0x40 till 0x4e for PCF8574, 0x40 for the adafruid RGB shield, 0x40 - 0x4e for MCP23017
190 | // Official addresses have a value half as high!
191 | #define UI_DISPLAY_I2C_ADDRESS 0x4e
192 | // For MCP 23017 define which pins should be output
193 | #define UI_DISPLAY_I2C_OUTPUT_PINS 65504
194 | // Set the output mask that is or'd over the output data. This is needed to activate
195 | // a backlight switched over the I2C.
196 | // The adafruit RGB shields enables a light if the bit is not set. Bits 6-8 are used for backlight.
197 | #define UI_DISPLAY_I2C_OUTPUT_START_MASK 0
198 | // For MCP which inputs are with pullup. 31 = pins 0-4 for adafruid rgb shield buttons
199 | #define UI_DISPLAY_I2C_PULLUP 31
200 | /* How fast should the I2C clock go. The PCF8574 work only with the lowest setting 100000.
201 | A MCP23017 can run also with 400000 Hz */
202 | #define UI_I2C_CLOCKSPEED 100000L
203 | /**
204 | Define the pin
205 | */
206 | #if UI_DISPLAY_TYPE == DISPLAY_I2C // I2C Pin configuration
207 | #define UI_DISPLAY_RS_PIN _BV(4)
208 | #define UI_DISPLAY_RW_PIN _BV(5)
209 | #define UI_DISPLAY_ENABLE_PIN _BV(6)
210 | #define UI_DISPLAY_D0_PIN _BV(0)
211 | #define UI_DISPLAY_D1_PIN _BV(1)
212 | #define UI_DISPLAY_D2_PIN _BV(2)
213 | #define UI_DISPLAY_D3_PIN _BV(3)
214 | #define UI_DISPLAY_D4_PIN _BV(0)
215 | #define UI_DISPLAY_D5_PIN _BV(1)
216 | #define UI_DISPLAY_D6_PIN _BV(2)
217 | #define UI_DISPLAY_D7_PIN _BV(3)
218 |
219 | // uncomment if your using led to indicated the bed is hot
220 | //#define UI_I2C_HEATBED_LED _BV(8)
221 |
222 | // uncomment if your using led to indicated the extruder is hot
223 | //#define UI_I2C_HOTEND_LED _BV(7)
224 |
225 | // uncomment if your using led to indicated the FAN is on
226 | //#define UI_I2C_FAN_LED _BV(6)
227 |
228 | // Pins for adafruid RGB shield
229 | /*#define UI_DISPLAY_RS_PIN _BV(15)
230 | #define UI_DISPLAY_RW_PIN _BV(14)
231 | #define UI_DISPLAY_ENABLE_PIN _BV(13)
232 | #define UI_DISPLAY_D0_PIN _BV(12)
233 | #define UI_DISPLAY_D1_PIN _BV(11)
234 | #define UI_DISPLAY_D2_PIN _BV(10)
235 | #define UI_DISPLAY_D3_PIN _BV(9)
236 | #define UI_DISPLAY_D4_PIN _BV(12)
237 | #define UI_DISPLAY_D5_PIN _BV(11)
238 | #define UI_DISPLAY_D6_PIN _BV(10)
239 | #define UI_DISPLAY_D7_PIN _BV(9)*/
240 |
241 | #else // Direct display connections
242 | #define UI_DISPLAY_RS_PIN 63 // PINK.1, 88, D_RS
243 | #define UI_DISPLAY_RW_PIN -1
244 | #define UI_DISPLAY_ENABLE_PIN 65 // PINK.3, 86, D_E
245 | #define UI_DISPLAY_D0_PIN 59 // PINF.5, 92, D_D4
246 | #define UI_DISPLAY_D1_PIN 64 // PINK.2, 87, D_D5
247 | #define UI_DISPLAY_D2_PIN 44 // PINL.5, 40, D_D6
248 | #define UI_DISPLAY_D3_PIN 66 // PINK.4, 85, D_D7
249 | #define UI_DISPLAY_D4_PIN 59 // PINF.5, 92, D_D4
250 | #define UI_DISPLAY_D5_PIN 64 // PINK.2, 87, D_D5
251 | #define UI_DISPLAY_D6_PIN 44 // PINL.5, 40, D_D6
252 | #define UI_DISPLAY_D7_PIN 66 // PINK.4, 85, D_D7
253 | #define UI_DELAYPERCHAR 50
254 |
255 | // Special pins for some u8g driven display
256 |
257 | #define UI_DISPLAY_CS1 59
258 | #define UI_DISPLAY_CS2 59
259 | #define UI_DISPLAY_DI 59
260 | #define UI_DISPLAY_RW_PIN 59
261 | #define UI_DISPLAY_RESET_PIN 59
262 | #endif
263 |
264 |
265 | /** \brief Are some keys connected?
266 |
267 | 0 = No keys attached - disables also menu
268 | 1 = Some keys attached
269 | */
270 | #define UI_HAS_KEYS 0
271 |
272 |
273 | /** \brief Is a back key present.
274 |
275 | If you have menus enabled, you need a method to leave it. If you have a back key, you can always go one level higher.
276 | Without a back key, you need to navigate to the back entry in the menu. Setting this value to 1 removes the back entry.
277 | */
278 | #define UI_HAS_BACK_KEY 1
279 |
280 | /* Then you have the next/previous keys more like up/down keys, it may be more intuitive to change the direction you skip through the menus.
281 | If you set it to true, next will go to previous menu instead of the next menu.
282 |
283 | */
284 | #define UI_INVERT_MENU_DIRECTION 0
285 |
286 | /** Uncomment this, if you have keys connected via i2c to a PCF8574 chip. */
287 | //#define UI_HAS_I2C_KEYS
288 |
289 | // Do you have a I2C connected encoder?
290 | #define UI_HAS_I2C_ENCODER 0
291 |
292 | // Under which address can the key status requested. This is the address of your PCF8574 where the keys are connected.
293 | // If you use a MCP23017 the address from display is used also for keys.
294 | #define UI_I2C_KEY_ADDRESS 0x40
295 |
296 |
297 | #ifdef UI_MAIN
298 | /* #######################################################################
299 | Key definitions
300 |
301 | The firmware is very flexible regarding your input methods. You can use one
302 | or more of the predefined key macros, to define a mapper. If no matching mapper
303 | is available, you can add you c-code for mapping directly into the keyboard
304 | routines. The predefined macros do the same, just hiding the code behind it.
305 |
306 | For each key, two seperate parts must be defined. The first is the initialization
307 | which must be added inside uiInitKeys() and the second ist a testing routine.
308 | These come into uiCheckKeys() or uiCheckSlowKeys() depending on the time needed
309 | for testing. If you are in doubt, put it in uiCheckSlowKeys().
310 | uiInitKeys() is called from an interrupt controlling the extruder, so only
311 | fast tests should be put there.
312 | The detect methods need an action identifier. A list of supported ids is found
313 | at the beginning of ui.h It's best to use the symbol name, in case the value changes.
314 |
315 | 1. Simple push button connected to gnd if closed on a free arduino pin
316 | init -> UI_KEYS_INIT_BUTTON_LOW(pinNumber);
317 | detect -> UI_KEYS_BUTTON_LOW(pinNumber,action);
318 |
319 | 2. Simple push button connected to 5v if closed on a free arduino pin
320 | init -> UI_KEYS_INIT_BUTTON_HIGH(pinNumber);
321 | detect -> UI_KEYS_BUTTON_HIGH(pinNumber,action);
322 |
323 | 3. Click encoder, A/B connected to gnd if closed.
324 | init -> UI_KEYS_INIT_CLICKENCODER_LOW(pinA,pinB);
325 | detect -> UI_KEYS_CLICKENCODER_LOW(pinA,pinB);
326 | or UI_KEYS_CLICKENCODER_LOW_REV(pinA,pinB); // reverse direction
327 | If you can move the menu cursor without a click, just be adding some force in one direction,
328 | toggle the _REV with non _REV and toggle pins.
329 | If the direction is wrong, toggle _REV with non _REV version.
330 | For the push button of the encoder use 1.
331 |
332 | 4. Click encoder, A/B connected to 5V if closed.
333 | init -> UI_KEYS_INIT_CLICKENCODER_HIGH(pinA,pinB);
334 | detect -> UI_KEYS_CLICKENCODER_HIGH(pinA,pinB);
335 | or UI_KEYS_CLICKENCODER_HIGH_REV(pinA,pinB); // reverse direction
336 | If you can move the menu cursor without a click, just be adding some force in one direction,
337 | toggle the _REV with non _REV and toggle pins.
338 | If the direction is wrong, toggle _REV with non _REV version.
339 | For the push button of the encoder use 2.
340 |
341 | 5. Maxtrix keyboard with 1-4 rows and 1-4 columns.
342 | init -> UI_KEYS_INIT_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4);
343 | detect -> UI_KEYS_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4);
344 | In addition you have to set UI_MATRIX_ACTIONS to match your desired actions.
345 |
346 | ------- Keys connected via I2C -------------
347 |
348 | All keys and the buzzer if present must be on a connected to a single PCF8574 chip!
349 | As all I2C request take time, they belong all in uiCheckSlowKeys.
350 | Dont use the pin ids but instead _BV(pinNumber0_7) as pin id. 0 = First pin
351 |
352 | 6. Click encoder, A/B connected to gnd if closed.
353 | init -> not needed, but make sure UI_HAS_I2C_KEY is not commented out.
354 | detect -> UI_KEYS_I2C_CLICKENCODER_LOW(pinA,pinB);
355 | or UI_KEYS_I2C_CLICKENCODER_LOW_REV(pinA,pinB); // reverse direction
356 | If you can move the menu cursor without a click, just be adding some force in one direction,
357 | toggle the _REV with non _REV and toggle pins.
358 | If the direction is wrong, toggle _REV with non _REV version.
359 | For the push button of the encoder use 7.
360 | NOTICE: The polling frequency is limited, so only slow turns are captured correct!
361 |
362 | 7. Simple push button connected to gnd if closed via I2C on a PCF8574
363 | init -> not needed, but make sure UI_HAS_I2C_KEY is not commented out.
364 | detect -> UI_KEYS_I2C_BUTTON_LOW(pinNumber,action);
365 |
366 | -------- Some notes on actions -------------
367 |
368 | There are three kinds of actions.
369 |
370 | Type 1: Immediate actions - these are execute and forget actions like home/pre-heat
371 | Type 2: Parameter change action - these change the mode for next/previous keys. They are valid
372 | until a new change action is initiated or the action is finished with ok button.
373 | Type 3: Show menu action. These actions have a _MENU_ in their name. If they are executed, a new
374 | menu is pushed on the menu stack and you see the menu. If you assign these actions directly
375 | to a key, you might not want this pushing behaviour. In this case add UI_ACTION_TOPMENU to the
376 | action, like UI_ACTION_TOPMENU+UI_ACTION_MENU_XPOSFAST. That will show the menu as top-menu
377 | closing all othe submenus that were open.
378 |
379 | ####################################################################### */
380 |
381 | // Use these codes for key detect. The main menu will show the pressed action in the lcd display.
382 | // after that assign the desired codes.
383 | //#define UI_MATRIX_ACTIONS {2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015}
384 | // Define your matrix actions
385 | #if DRIVE_SYSTEM == SCARA // Kusuma SCARA
386 | #define UI_MATRIX_ACTIONS {UI_ACTION_HOME_ALL, UI_ACTION_TOP_MENU, UI_ACTION_SET_ORIGIN, UI_ACTION_NEXT,\
387 | UI_ACTION_HOME_Z, UI_ACTION_MENU_ZPOS, UI_ACTION_COOLDOWN, UI_ACTION_OK,\
388 | UI_ACTION_MENU_Y_ANGLE_FAST, UI_ACTION_MENU_YPOSFAST, UI_ACTION_PREHEAT_ABS, UI_ACTION_PREVIOUS,\
389 | UI_ACTION_MENU_X_ANGLE_FAST, UI_ACTION_MENU_XPOSFAST, UI_ACTION_DISABLE_STEPPER, UI_ACTION_BACK}
390 | #else // Kusuma SCARA
391 | #define UI_MATRIX_ACTIONS {UI_ACTION_HOME_ALL, UI_ACTION_TOP_MENU, UI_ACTION_SET_ORIGIN, UI_ACTION_NEXT,\
392 | UI_ACTION_HOME_Z, UI_ACTION_MENU_ZPOS, UI_ACTION_COOLDOWN, UI_ACTION_OK,\
393 | UI_ACTION_HOME_Y, UI_ACTION_MENU_YPOSFAST, UI_ACTION_PREHEAT_ABS, UI_ACTION_PREVIOUS,\
394 | UI_ACTION_HOME_X, UI_ACTION_MENU_XPOSFAST, UI_ACTION_DISABLE_STEPPER, UI_ACTION_BACK}
395 | #endif // Kusuma SCARA
396 | #ifdef UI_MATRIX_ACTIONS
397 | const int matrixActions[] PROGMEM = UI_MATRIX_ACTIONS;
398 | #endif
399 |
400 | void uiInitKeys() {
401 | #if UI_HAS_KEYS!=0
402 | //UI_KEYS_INIT_CLICKENCODER_LOW(33,31); // click encoder on pins 47 and 45. Phase is connected with gnd for signals.
403 | UI_KEYS_INIT_BUTTON_LOW(4); // push button, connects gnd to pin
404 | UI_KEYS_INIT_BUTTON_LOW(5);
405 | UI_KEYS_INIT_BUTTON_LOW(6);
406 | UI_KEYS_INIT_BUTTON_LOW(11);
407 | UI_KEYS_INIT_BUTTON_LOW(42);
408 |
409 | // UI_KEYS_INIT_CLICKENCODER_LOW(47,45); // click encoder on pins 47 and 45. Phase is connected with gnd for signals.
410 | // UI_KEYS_INIT_BUTTON_LOW(43); // push button, connects gnd to pin
411 | // UI_KEYS_INIT_MATRIX(32,47,45,43,41,39,37,35);
412 | #endif
413 | }
414 | void uiCheckKeys(uint16_t &action) {
415 | #if UI_HAS_KEYS!=0
416 |
417 | //UI_KEYS_CLICKENCODER_LOW_REV(33,31); // click encoder on pins 47 and 45. Phase is connected with gnd for signals.
418 | UI_KEYS_BUTTON_LOW(4,UI_ACTION_OK); // push button, connects gnd to pin
419 | UI_KEYS_BUTTON_LOW(5,UI_ACTION_NEXT); // push button, connects gnd to pin
420 | UI_KEYS_BUTTON_LOW(6,UI_ACTION_PREVIOUS); // push button, connects gnd to pin
421 | UI_KEYS_BUTTON_LOW(11,UI_ACTION_BACK); // push button, connects gnd to pin
422 | UI_KEYS_BUTTON_LOW(42,UI_ACTION_SD_PRINT ); // push button, connects gnd to pin
423 | // UI_KEYS_CLICKENCODER_LOW_REV(47,45); // click encoder on pins 47 and 45. Phase is connected with gnd for signals.
424 | // UI_KEYS_BUTTON_LOW(43,UI_ACTION_OK); // push button, connects gnd to pin
425 | #endif
426 | }
427 | inline void uiCheckSlowEncoder() {
428 | #if defined(UI_HAS_I2C_KEYS) && UI_HAS_KEYS!=0
429 | #if UI_DISPLAY_I2C_CHIPTYPE==0
430 | HAL::i2cStartWait(UI_I2C_KEY_ADDRESS+I2C_READ);
431 | uint8_t keymask = HAL::i2cReadNak(); // Read current key mask
432 | #endif
433 | #if UI_DISPLAY_I2C_CHIPTYPE==1
434 | HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE);
435 | HAL::i2cWrite(0x12); // GIOA
436 | HAL::i2cStop();
437 | HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_READ);
438 | uint16_t keymask = HAL::i2cReadAck();
439 | keymask = keymask + (HAL::i2cReadNak()<<8);
440 | #endif
441 | HAL::i2cStop();
442 | // Add I2C click encoder tests here, all other i2c tests and a copy of the encoder test belog in uiCheckSlowKeys
443 | UI_KEYS_I2C_CLICKENCODER_LOW_REV(_BV(2),_BV(0)); // click encoder on pins 0 and 2. Phase is connected with gnd for signals.
444 | #endif
445 | }
446 | void uiCheckSlowKeys(uint16_t &action) {
447 | #if defined(UI_HAS_I2C_KEYS) && UI_HAS_KEYS!=0
448 | #if UI_DISPLAY_I2C_CHIPTYPE==0
449 | HAL::i2cStartWait(UI_I2C_KEY_ADDRESS+I2C_READ);
450 | uint8_t keymask = HAL::i2cReadNak(); // Read current key mask
451 | #endif
452 | #if UI_DISPLAY_I2C_CHIPTYPE==1
453 | HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE);
454 | HAL::i2cWrite(0x12); // GPIOA
455 | HAL::i2cStop();
456 | HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_READ);
457 | uint16_t keymask = HAL::i2cReadAck();
458 | keymask = keymask + (HAL::i2cReadNak()<<8);
459 | #endif
460 | HAL::i2cStop();
461 | // Add I2C key tests here
462 | UI_KEYS_I2C_CLICKENCODER_LOW_REV(_BV(2),_BV(0)); // click encoder on pins 0 and 2. Phase is connected with gnd for signals.
463 | UI_KEYS_I2C_BUTTON_LOW(_BV(1),UI_ACTION_OK); // push button, connects gnd to pin
464 | UI_KEYS_I2C_BUTTON_LOW(_BV(3),UI_ACTION_BACK); // push button, connects gnd to pin
465 | UI_KEYS_I2C_BUTTON_LOW(_BV(4),UI_ACTION_MENU_MOVE_Y+UI_ACTION_TOPMENU); // push button, connects gnd to pin
466 | UI_KEYS_I2C_BUTTON_LOW(_BV(5),UI_ACTION_MENU_EXTRUDER+UI_ACTION_TOPMENU); // push button, connects gnd to pin
467 | UI_KEYS_I2C_BUTTON_LOW(_BV(6),UI_ACTION_MENU_POSITIONS+UI_ACTION_TOPMENU); // push button, connects gnd to pin
468 | UI_KEYS_I2C_BUTTON_LOW(_BV(7),UI_ACTION_MENU_MOVE_X+UI_ACTION_TOPMENU); // push button, connects gnd to pin
469 | /*
470 | // Button handling for the Adafruit RGB shild
471 | UI_KEYS_I2C_BUTTON_LOW(4,UI_ACTION_PREVIOUS); // Up button
472 | UI_KEYS_I2C_BUTTON_LOW(8,UI_ACTION_NEXT); // down button
473 | UI_KEYS_I2C_BUTTON_LOW(16,UI_ACTION_BACK); // left button
474 | UI_KEYS_I2C_BUTTON_LOW(2,UI_ACTION_OK); // right button
475 | UI_KEYS_I2C_BUTTON_LOW(1,UI_ACTION_MENU_QUICKSETTINGS); //Select button
476 | // ----- End RGB shield ----------
477 | */
478 | #endif
479 |
480 | //UI_KEYS_MATRIX(32,47,45,43,41,39,37,35);
481 | }
482 |
483 | #endif
484 | #endif
485 |
486 |
487 |
488 |
--------------------------------------------------------------------------------
/Wangsamas/Eeprom.h:
--------------------------------------------------------------------------------
1 | /*
2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan.
3 |
4 | Wangsamas-Firmware adalah perangkat lunak bebas:
5 | Anda dapat mendistribusikannya dan/atau mengubahnya
6 | dengan syarat dan ketentuan GNU General Public License
7 | yang dipublikasikan oleh Free Software Foundation,
8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru.
9 |
10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat,
11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau
12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License
13 | untuk keterangan lebih lanjut.
14 |
15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan
16 | dengan Wangsamas-Firmware. Jika tidak, lihat .
17 |
18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware
19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware.
20 |
21 | ---------------------
22 |
23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan.
24 |
25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify
26 | it under the terms of the GNU General Public License as published by
27 | the Free Software Foundation, either version 3 of the License, or
28 | (at your option) any later version.
29 |
30 | Wangsamas-Firmware is distributed in the hope that it will be useful,
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | GNU General Public License for more details.
34 |
35 | You should have received a copy of the GNU General Public License
36 | along with Wangsamas-Firmware. If not, see .
37 |
38 | This firmware is based on Repetier-Firmware which based on sprinter firmware
39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
40 |
41 | */
42 |
43 | #ifndef _EEPROM_H
44 | #define _EEPROM_H
45 |
46 | // Id to distinguish version changes
47 | #define EEPROM_PROTOCOL_VERSION 16
48 |
49 | /** Where to start with our datablock in memory. Can be moved if you
50 | have problems with other modules using the eeprom */
51 |
52 | #define EPR_MAGIC_BYTE 0
53 | #define EPR_ACCELERATION_TYPE 1
54 | #define EPR_XAXIS_STEPS_PER_UNIT 3
55 | #define EPR_YAXIS_STEPS_PER_UNIT 7
56 | #define EPR_ZAXIS_STEPS_PER_UNIT 11
57 | #define EPR_X_MAX_FEEDRATE 15
58 | #define EPR_Y_MAX_FEEDRATE 19
59 | #define EPR_Z_MAX_FEEDRATE 23
60 | #define EPR_X_HOMING_FEEDRATE 27
61 | #define EPR_Y_HOMING_FEEDRATE 31
62 | #define EPR_Z_HOMING_FEEDRATE 35
63 | #define EPR_MAX_JERK 39
64 | //#define EPR_OPS_MIN_DISTANCE 43
65 | #define EPR_MAX_ZJERK 47
66 | #define EPR_X_MAX_ACCEL 51
67 | #define EPR_Y_MAX_ACCEL 55
68 | #define EPR_Z_MAX_ACCEL 59
69 | #define EPR_X_MAX_TRAVEL_ACCEL 63
70 | #define EPR_Y_MAX_TRAVEL_ACCEL 67
71 | #define EPR_Z_MAX_TRAVEL_ACCEL 71
72 | #define EPR_BAUDRATE 75
73 | #define EPR_MAX_INACTIVE_TIME 79
74 | #define EPR_STEPPER_INACTIVE_TIME 83
75 | //#define EPR_OPS_RETRACT_DISTANCE 87
76 | //#define EPR_OPS_RETRACT_BACKLASH 91
77 | #define EPR_EXTRUDER_SPEED 95
78 | //#define EPR_OPS_MOVE_AFTER 99
79 | //#define EPR_OPS_MODE 103
80 | #define EPR_INTEGRITY_BYTE 104 // Here the xored sum over eeprom is stored
81 | #define EPR_VERSION 105 // Version id for updates in EEPROM storage
82 | #define EPR_BED_HEAT_MANAGER 106
83 | #define EPR_BED_DRIVE_MAX 107
84 | #define EPR_BED_PID_PGAIN 108
85 | #define EPR_BED_PID_IGAIN 112
86 | #define EPR_BED_PID_DGAIN 116
87 | #define EPR_BED_PID_MAX 120
88 | #define EPR_BED_DRIVE_MIN 124
89 | #define EPR_PRINTING_TIME 125 // Time in seconds printing
90 | #define EPR_PRINTING_DISTANCE 129 // Filament length printed
91 | #define EPR_X_HOME_OFFSET 133
92 | #define EPR_Y_HOME_OFFSET 137
93 | #define EPR_Z_HOME_OFFSET 141
94 | #define EPR_X_LENGTH 145
95 | #define EPR_Y_LENGTH 149
96 | #define EPR_Z_LENGTH 153
97 | #define EPR_BACKLASH_X 157
98 | #define EPR_BACKLASH_Y 161
99 | #define EPR_BACKLASH_Z 165
100 |
101 | #define EPR_Z_PROBE_X_OFFSET 800
102 | #define EPR_Z_PROBE_Y_OFFSET 804
103 | #define EPR_Z_PROBE_HEIGHT 808
104 | #define EPR_Z_PROBE_SPEED 812
105 | #define EPR_Z_PROBE_X1 816
106 | #define EPR_Z_PROBE_Y1 820
107 | #define EPR_Z_PROBE_X2 824
108 | #define EPR_Z_PROBE_Y2 828
109 | #define EPR_Z_PROBE_X3 832
110 | #define EPR_Z_PROBE_Y3 836
111 | #define EPR_Z_PROBE_XY_SPEED 840
112 | #define EPR_AUTOLEVEL_MATRIX 844
113 | #define EPR_AUTOLEVEL_ACTIVE 880
114 | #define EPR_DELTA_DIAGONAL_ROD_LENGTH 881
115 | #define EPR_DELTA_HORIZONTAL_RADIUS 885
116 | #define EPR_DELTA_SEGMENTS_PER_SECOND_PRINT 889
117 | #define EPR_DELTA_SEGMENTS_PER_SECOND_MOVE 891
118 | #define EPR_DELTA_TOWERX_OFFSET_STEPS 893
119 | #define EPR_DELTA_TOWERY_OFFSET_STEPS 895
120 | #define EPR_DELTA_TOWERZ_OFFSET_STEPS 897
121 | #define EPR_DELTA_ALPHA_A 901
122 | #define EPR_DELTA_ALPHA_B 905
123 | #define EPR_DELTA_ALPHA_C 909
124 | #define EPR_DELTA_RADIUS_CORR_A 913
125 | #define EPR_DELTA_RADIUS_CORR_B 917
126 | #define EPR_DELTA_RADIUS_CORR_C 921
127 | #define EPR_DELTA_MAX_RADIUS 925
128 | #define EPR_Z_PROBE_BED_DISTANCE 929
129 | #define EPR_DELTA_DIAGONAL_CORRECTION_A 933
130 | #define EPR_DELTA_DIAGONAL_CORRECTION_B 937
131 | #define EPR_DELTA_DIAGONAL_CORRECTION_C 941
132 | #define EPR_TOUCHSCREEN 946 // - 975 = 30 byte for touchscreen calibration data
133 |
134 | #define EPR_ARM_LENGTH 1048 // Kusuma SCARA
135 | #define EPR_FOREARM_LENGTH 1052 // Kusuma SCARA
136 | #define EPR_SHOULDER_MIN_ANGLE 1056 // Kusuma SCARA
137 | #define EPR_ELBOW_MIN_ANGLE 1060 // Kusuma SCARA
138 | #define EPR_SHOULDER_MAX_ANGLE 1064 // Kusuma SCARA
139 | #define EPR_ELBOW_MAX_ANGLE 1068 // Kusuma SCARA
140 | #define EPR_SHOULDER_BED_CENTER_ANGLE 1072 // Kusuma SCARA
141 | #define EPR_ELBOW_BED_CENTER_ANGLE 1076 // Kusuma SCARA
142 |
143 | // Axis compensation
144 | #define EPR_AXISCOMP_TANXY 976
145 | #define EPR_AXISCOMP_TANYZ 980
146 | #define EPR_AXISCOMP_TANXZ 984
147 |
148 | #define EPR_DISTORTION_CORRECTION_ENABLED 988
149 | #define EPR_RETRACTION_LENGTH 992
150 | #define EPR_RETRACTION_LONG_LENGTH 996
151 | #define EPR_RETRACTION_SPEED 1000
152 | #define EPR_RETRACTION_Z_LIFT 1004
153 | #define EPR_RETRACTION_UNDO_EXTRA_LENGTH 1008
154 | #define EPR_RETRACTION_UNDO_EXTRA_LONG_LENGTH 1012
155 | #define EPR_RETRACTION_UNDO_SPEED 1016
156 | #define EPR_AUTORETRACT_ENABLED 1020
157 | #define EPR_Z_PROBE_Z_OFFSET 1024
158 | #define EPR_SELECTED_LANGUAGE 1028
159 | #define EPR_ACCELERATION_FACTOR_TOP 1032
160 | #define EPR_BENDING_CORRECTION_A 1036
161 | #define EPR_BENDING_CORRECTION_B 1040
162 | #define EPR_BENDING_CORRECTION_C 1044
163 |
164 | #if EEPROM_MODE != 0
165 | #define EEPROM_FLOAT(x) HAL::eprGetFloat(EPR_##x)
166 | #define EEPROM_INT32(x) HAL::eprGetInt32(EPR_##x)
167 | #define EEPROM_BYTE(x) HAL::eprGetByte(EPR_##x)
168 | #define EEPROM_SET_BYTE(x,val) HAL::eprSetByte(EPR_##x,val)
169 | #else
170 | #define EEPROM_FLOAT(x) (float)(x)
171 | #define EEPROM_INT32(x) (int32_t)(x)
172 | #define EEPROM_BYTE(x) (uint8_t)(x)
173 | #define EEPROM_SET_BYTE(x,val)
174 | #endif
175 |
176 | #define EEPROM_EXTRUDER_OFFSET 200
177 | // bytes per extruder needed, leave some space for future development
178 | #define EEPROM_EXTRUDER_LENGTH 100
179 | // Extruder positions relative to extruder start
180 | #define EPR_EXTRUDER_STEPS_PER_UNIT 0
181 | #define EPR_EXTRUDER_MAX_FEEDRATE 4
182 | // Feedrate from halted extruder in mm/s
183 | #define EPR_EXTRUDER_MAX_START_FEEDRATE 8
184 | // Acceleration in mm/s^2
185 | #define EPR_EXTRUDER_MAX_ACCELERATION 12
186 | #define EPR_EXTRUDER_HEAT_MANAGER 16
187 | #define EPR_EXTRUDER_DRIVE_MAX 17
188 | #define EPR_EXTRUDER_PID_PGAIN 18
189 | #define EPR_EXTRUDER_PID_IGAIN 22
190 | #define EPR_EXTRUDER_PID_DGAIN 26
191 | #define EPR_EXTRUDER_DEADTIME EPR_EXTRUDER_PID_PGAIN
192 | #define EPR_EXTRUDER_PID_MAX 30
193 | #define EPR_EXTRUDER_X_OFFSET 31
194 | #define EPR_EXTRUDER_Y_OFFSET 35
195 | #define EPR_EXTRUDER_WATCH_PERIOD 39
196 | #define EPR_EXTRUDER_ADVANCE_K 41
197 | #define EPR_EXTRUDER_DRIVE_MIN 45
198 | #define EPR_EXTRUDER_ADVANCE_L 46
199 | #define EPR_EXTRUDER_WAIT_RETRACT_TEMP 50
200 | #define EPR_EXTRUDER_WAIT_RETRACT_UNITS 52
201 | #define EPR_EXTRUDER_COOLER_SPEED 54
202 | // 55-57 free for byte sized parameter
203 | #define EPR_EXTRUDER_MIXING_RATIOS 58 // 16*2 byte ratios = 32 byte -> end = 89
204 | #define EPR_EXTRUDER_Z_OFFSET 90
205 | #ifndef Z_PROBE_BED_DISTANCE
206 | #define Z_PROBE_BED_DISTANCE 5.0
207 | #endif
208 |
209 | class EEPROM
210 | {
211 | #if EEPROM_MODE != 0
212 | static void writeExtruderPrefix(uint pos);
213 | static void writeFloat(uint pos,PGM_P text,uint8_t digits = 3);
214 | static void writeLong(uint pos,PGM_P text);
215 | static void writeInt(uint pos,PGM_P text);
216 | static void writeByte(uint pos,PGM_P text);
217 | public:
218 | static uint8_t computeChecksum();
219 | static void updateChecksum();
220 | #endif
221 | public:
222 |
223 | static void init();
224 | static void initBaudrate();
225 | static void storeDataIntoEEPROM(uint8_t corrupted = 0);
226 | static void storeScaraDataIntoEEPROM(uint8_t corrupted = 0); // Kusuma SCARA
227 | static void readDataFromEEPROM(bool includeExtruder);
228 | static void restoreEEPROMSettingsFromConfiguration();
229 | static void writeSettings();
230 | static void update(GCode *com);
231 | static void updatePrinterUsage();
232 | static inline void setVersion(uint8_t v) {
233 | #if EEPROM_MODE != 0
234 | HAL::eprSetByte(EPR_VERSION,v);
235 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,computeChecksum());
236 | #endif
237 | }
238 | static inline uint8_t getStoredLanguage() {
239 | #if EEPROM_MODE != 0
240 | return HAL::eprGetByte(EPR_SELECTED_LANGUAGE);
241 | #else
242 | return 0;
243 | #endif
244 | }
245 | static inline float zProbeZOffset() {
246 | #if EEPROM_MODE != 0
247 | return HAL::eprGetFloat(EPR_Z_PROBE_Z_OFFSET);
248 | #else
249 | return Z_PROBE_Z_OFFSET;
250 | #endif
251 | }
252 | static inline float zProbeSpeed() {
253 | #if EEPROM_MODE != 0
254 | return HAL::eprGetFloat(EPR_Z_PROBE_SPEED);
255 | #else
256 | return Z_PROBE_SPEED;
257 | #endif
258 | }
259 | static inline float zProbeXYSpeed() {
260 | #if EEPROM_MODE != 0
261 | return HAL::eprGetFloat(EPR_Z_PROBE_XY_SPEED);
262 | #else
263 | return Z_PROBE_XY_SPEED;
264 | #endif
265 | }
266 | static inline float zProbeXOffset() {
267 | #if EEPROM_MODE != 0
268 | return HAL::eprGetFloat(EPR_Z_PROBE_X_OFFSET);
269 | #else
270 | return Z_PROBE_X_OFFSET;
271 | #endif
272 | }
273 | static inline float zProbeYOffset() {
274 | #if EEPROM_MODE != 0
275 | return HAL::eprGetFloat(EPR_Z_PROBE_Y_OFFSET);
276 | #else
277 | return Z_PROBE_Y_OFFSET;
278 | #endif
279 | }
280 | static inline float zProbeHeight() {
281 | #if EEPROM_MODE != 0
282 | return HAL::eprGetFloat(EPR_Z_PROBE_HEIGHT);
283 | #else
284 | return Z_PROBE_HEIGHT;
285 | #endif
286 | }
287 | static inline float zProbeX1() {
288 | #if EEPROM_MODE != 0
289 | return HAL::eprGetFloat(EPR_Z_PROBE_X1);
290 | #else
291 | return Z_PROBE_X1;
292 | #endif
293 | }
294 | static inline float zProbeY1() {
295 | #if EEPROM_MODE != 0
296 | return HAL::eprGetFloat(EPR_Z_PROBE_Y1);
297 | #else
298 | return Z_PROBE_Y1;
299 | #endif
300 | }
301 | static inline float zProbeX2() {
302 | #if EEPROM_MODE != 0
303 | return HAL::eprGetFloat(EPR_Z_PROBE_X2);
304 | #else
305 | return Z_PROBE_X2;
306 | #endif
307 | }
308 | static inline float zProbeY2() {
309 | #if EEPROM_MODE != 0
310 | return HAL::eprGetFloat(EPR_Z_PROBE_Y2);
311 | #else
312 | return Z_PROBE_Y2;
313 | #endif
314 | }
315 | static inline float zProbeX3() {
316 | #if EEPROM_MODE != 0
317 | return HAL::eprGetFloat(EPR_Z_PROBE_X3);
318 | #else
319 | return Z_PROBE_X3;
320 | #endif
321 | }
322 | static inline float zProbeY3() {
323 | #if EEPROM_MODE != 0
324 | return HAL::eprGetFloat(EPR_Z_PROBE_Y3);
325 | #else
326 | return Z_PROBE_Y3;
327 | #endif
328 | }
329 | static inline float zProbeBedDistance() {
330 | #if EEPROM_MODE != 0
331 | return HAL::eprGetFloat(EPR_Z_PROBE_BED_DISTANCE);
332 | #else
333 | return Z_PROBE_BED_DISTANCE;
334 | #endif
335 | }
336 |
337 | static inline float axisCompTanXY() {
338 | #if EEPROM_MODE != 0
339 | return HAL::eprGetFloat(EPR_AXISCOMP_TANXY);
340 | #else
341 | return AXISCOMP_TANXY;
342 | #endif
343 | }
344 | static inline float axisCompTanYZ() {
345 | #if EEPROM_MODE != 0
346 | return HAL::eprGetFloat(EPR_AXISCOMP_TANYZ);
347 | #else
348 | return AXISCOMP_TANYZ;
349 | #endif
350 | }
351 | static inline float axisCompTanXZ() {
352 | #if EEPROM_MODE != 0
353 | return HAL::eprGetFloat(EPR_AXISCOMP_TANXZ);
354 | #else
355 | return AXISCOMP_TANXZ;
356 | #endif
357 | }
358 |
359 | #if NONLINEAR_SYSTEM
360 | static inline int16_t deltaSegmentsPerSecondMove() {
361 | #if EEPROM_MODE != 0
362 | return HAL::eprGetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_MOVE);
363 | #else
364 | return DELTA_SEGMENTS_PER_SECOND_MOVE;
365 | #endif
366 | }
367 | static inline float deltaDiagonalRodLength() {
368 | #if EEPROM_MODE != 0
369 | return HAL::eprGetFloat(EPR_DELTA_DIAGONAL_ROD_LENGTH);
370 | #else
371 | return DELTA_DIAGONAL_ROD;
372 | #endif
373 | }
374 | static inline int16_t deltaSegmentsPerSecondPrint() {
375 | #if EEPROM_MODE != 0
376 | return HAL::eprGetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_PRINT);
377 | #else
378 | return DELTA_SEGMENTS_PER_SECOND_PRINT;
379 | #endif
380 | }
381 | #endif
382 | #if DRIVE_SYSTEM == SCARA // Kusuma SCARA
383 | static inline float armLength() { // Kusuma SCARA
384 | #if EEPROM_MODE != 0 // Kusuma SCARA
385 | return HAL::eprGetFloat(EPR_ARM_LENGTH); // Kusuma SCARA
386 | #else // Kusuma SCARA
387 | return ARM_LENGTH; // Kusuma SCARA
388 | #endif // Kusuma SCARA
389 | } // Kusuma SCARA
390 | static inline float forearmLength() { // Kusuma SCARA
391 | #if EEPROM_MODE != 0 // Kusuma SCARA
392 | return HAL::eprGetFloat(EPR_FOREARM_LENGTH); // Kusuma SCARA
393 | #else // Kusuma SCARA
394 | return FOREARM_LENGTH; // Kusuma SCARA
395 | #endif // Kusuma SCARA
396 | } // Kusuma SCARA
397 | static inline float ShoulderMinAngle() { // Kusuma SCARA
398 | #if EEPROM_MODE != 0 // Kusuma SCARA
399 | return HAL::eprGetFloat(EPR_SHOULDER_MIN_ANGLE); // Kusuma SCARA
400 | #else // Kusuma SCARA
401 | return SHOULDER_MIN_ANGLE; // Kusuma SCARA
402 | #endif // Kusuma SCARA
403 | } // Kusuma SCARA
404 | static inline float ElbowMinAngle() { // Kusuma SCARA
405 | #if EEPROM_MODE != 0 // Kusuma SCARA
406 | return HAL::eprGetFloat(EPR_ELBOW_MIN_ANGLE); // Kusuma SCARA
407 | #else // Kusuma SCARA
408 | return ELBOW_MIN_ANGLE; // Kusuma SCARA
409 | #endif // Kusuma SCARA
410 | } // Kusuma SCARA
411 | static inline float ShoulderMaxAngle() { // Kusuma SCARA
412 | #if EEPROM_MODE != 0 // Kusuma SCARA
413 | return HAL::eprGetFloat(EPR_SHOULDER_MAX_ANGLE); // Kusuma SCARA
414 | #else // Kusuma SCARA
415 | return SHOULDER_MAX_ANGLE; // Kusuma SCARA
416 | #endif // Kusuma SCARA
417 | } // Kusuma SCARA
418 | static inline float ElbowMaxAngle() { // Kusuma SCARA
419 | #if EEPROM_MODE != 0 // Kusuma SCARA
420 | return HAL::eprGetFloat(EPR_ELBOW_MAX_ANGLE); // Kusuma SCARA
421 | #else // Kusuma SCARA
422 | return ELBOW_MAX_ANGLE; // Kusuma SCARA
423 | #endif // Kusuma SCARA
424 | } // Kusuma SCARA
425 | static inline float ShoulderBedCenterAngle() { // Kusuma SCARA
426 | #if EEPROM_MODE != 0 // Kusuma SCARA
427 | return HAL::eprGetFloat(EPR_SHOULDER_BED_CENTER_ANGLE); // Kusuma SCARA
428 | #else // Kusuma SCARA
429 | return SHOULDER_BED_CENTER_ANGLE; // Kusuma SCARA
430 | #endif // Kusuma SCARA
431 | } // Kusuma SCARA
432 | static inline float ElbowBedCenterAngle() { // Kusuma SCARA
433 | #if EEPROM_MODE != 0 // Kusuma SCARA
434 | return HAL::eprGetFloat(EPR_ELBOW_BED_CENTER_ANGLE); // Kusuma SCARA
435 | #else // Kusuma SCARA
436 | return ELBOW_BED_CENTER_ANGLE; // Kusuma SCARA
437 | #endif // Kusuma SCARA
438 | } // Kusuma SCARA
439 | #endif // Kusuma SCARA
440 | #if DRIVE_SYSTEM == DELTA
441 | static inline float deltaHorizontalRadius() {
442 | #if EEPROM_MODE != 0
443 | return HAL::eprGetFloat(EPR_DELTA_HORIZONTAL_RADIUS);
444 | #else
445 | return ROD_RADIUS;
446 | #endif
447 | }
448 | static inline int16_t deltaTowerXOffsetSteps() {
449 | #if EEPROM_MODE != 0
450 | return HAL::eprGetInt16(EPR_DELTA_TOWERX_OFFSET_STEPS);
451 | #else
452 | return DELTA_X_ENDSTOP_OFFSET_STEPS;
453 | #endif
454 | }
455 | static inline int16_t deltaTowerYOffsetSteps() {
456 | #if EEPROM_MODE != 0
457 | return HAL::eprGetInt16(EPR_DELTA_TOWERY_OFFSET_STEPS);
458 | #else
459 | return DELTA_Y_ENDSTOP_OFFSET_STEPS;
460 | #endif
461 | }
462 | static inline int16_t deltaTowerZOffsetSteps() {
463 | #if EEPROM_MODE != 0
464 | return HAL::eprGetInt16(EPR_DELTA_TOWERZ_OFFSET_STEPS);
465 | #else
466 | return DELTA_Z_ENDSTOP_OFFSET_STEPS;
467 | #endif
468 | }
469 |
470 | static inline void setRodRadius(float mm) {
471 | #if DRIVE_SYSTEM == DELTA
472 | Printer::radius0=mm;
473 | Printer::updateDerivedParameter();
474 | #if EEPROM_MODE != 0
475 | //This is an odd situation, the radius can only be changed if eeprom is on.
476 | // The radius is not saved to printer variablke now, it is all derived parameters of
477 | // fetching the radius, which if EEProm is off returns the Configuration constant.
478 | HAL::eprSetFloat(EPR_DELTA_HORIZONTAL_RADIUS, mm);
479 | Com::printFLN(PSTR("Rod Radius set to: "),mm,3);
480 | uint8_t newcheck = computeChecksum();
481 | if(newcheck!=HAL::eprGetByte(EPR_INTEGRITY_BYTE))
482 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck);
483 | #endif
484 | #endif
485 | }
486 | static inline void incrementRodRadius(float mm) {
487 | setRodRadius(mm + deltaHorizontalRadius());
488 | }
489 | static inline void setTowerXFloor(float newZ) {
490 | #if DRIVE_SYSTEM == DELTA
491 | Printer::xMin = newZ;
492 | Printer::updateDerivedParameter();
493 | Com::printFLN(PSTR("X (A) tower floor set to: "),Printer::xMin,3);
494 | #if EEPROM_MODE != 0
495 | HAL::eprSetFloat(EPR_X_HOME_OFFSET,Printer::xMin);
496 | uint8_t newcheck = computeChecksum();
497 | if(newcheck!=HAL::eprGetByte(EPR_INTEGRITY_BYTE))
498 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck);
499 | #endif
500 | #endif
501 | }
502 | static inline void setTowerYFloor(float newZ) {
503 | #if DRIVE_SYSTEM == DELTA
504 | Printer::yMin = newZ;
505 | Printer::updateDerivedParameter();
506 | Com::printFLN(PSTR("Y (B) tower floor set to: "), Printer::yMin, 3);
507 | #if EEPROM_MODE != 0
508 |
509 | HAL::eprSetFloat(EPR_Y_HOME_OFFSET,Printer::yMin);
510 | uint8_t newcheck = computeChecksum();
511 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
512 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck);
513 | #endif
514 | #endif
515 | }
516 | static inline void setTowerZFloor(float newZ) {
517 | #if DRIVE_SYSTEM == DELTA
518 | Printer::zMin = newZ;
519 | Printer::updateDerivedParameter();
520 | Com::printFLN(PSTR("Z (C) tower floor set to: "), Printer::zMin, 3);
521 | #if EEPROM_MODE != 0
522 | HAL::eprSetFloat(EPR_Z_HOME_OFFSET,Printer::zMin);
523 | uint8_t newcheck = computeChecksum();
524 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
525 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck);
526 | #endif
527 | #endif
528 | }
529 | static inline void setDeltaTowerXOffsetSteps(int16_t steps) {
530 | #if EEPROM_MODE != 0
531 | HAL::eprSetInt16(EPR_DELTA_TOWERX_OFFSET_STEPS,steps);
532 | uint8_t newcheck = computeChecksum();
533 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
534 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck);
535 | #endif
536 | }
537 | static inline void setDeltaTowerYOffsetSteps(int16_t steps) {
538 | #if EEPROM_MODE != 0
539 | HAL::eprSetInt16(EPR_DELTA_TOWERY_OFFSET_STEPS,steps);
540 | uint8_t newcheck = computeChecksum();
541 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
542 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck);
543 | #endif
544 | }
545 | static inline void setDeltaTowerZOffsetSteps(int16_t steps) {
546 | #if EEPROM_MODE != 0
547 | HAL::eprSetInt16(EPR_DELTA_TOWERZ_OFFSET_STEPS,steps);
548 | uint8_t newcheck = computeChecksum();
549 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
550 | HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck);
551 | #endif
552 | }
553 | static inline float deltaAlphaA() {
554 | #if EEPROM_MODE != 0
555 | return HAL::eprGetFloat(EPR_DELTA_ALPHA_A);
556 | #else
557 | return DELTA_ALPHA_A;
558 | #endif
559 | }
560 | static inline float deltaAlphaB() {
561 | #if EEPROM_MODE != 0
562 | return HAL::eprGetFloat(EPR_DELTA_ALPHA_B);
563 | #else
564 | return DELTA_ALPHA_B;
565 | #endif
566 | }
567 | static inline float deltaAlphaC() {
568 | #if EEPROM_MODE != 0
569 | return HAL::eprGetFloat(EPR_DELTA_ALPHA_C);
570 | #else
571 | return DELTA_ALPHA_C;
572 | #endif
573 | }
574 | static inline float deltaRadiusCorrectionA() {
575 | #if EEPROM_MODE != 0
576 | return HAL::eprGetFloat(EPR_DELTA_RADIUS_CORR_A);
577 | #else
578 | return DELTA_RADIUS_CORRECTION_A;
579 | #endif
580 | }
581 | static inline float deltaRadiusCorrectionB() {
582 | #if EEPROM_MODE != 0
583 | return HAL::eprGetFloat(EPR_DELTA_RADIUS_CORR_B);
584 | #else
585 | return DELTA_RADIUS_CORRECTION_B;
586 | #endif
587 | }
588 | static inline float deltaRadiusCorrectionC() {
589 | #if EEPROM_MODE != 0
590 | return HAL::eprGetFloat(EPR_DELTA_RADIUS_CORR_C);
591 | #else
592 | return DELTA_RADIUS_CORRECTION_C;
593 | #endif
594 | }
595 | static inline float deltaDiagonalCorrectionA() {
596 | return EEPROM_FLOAT(DELTA_DIAGONAL_CORRECTION_A);
597 | }
598 | static inline float deltaDiagonalCorrectionB() {
599 | return EEPROM_FLOAT(DELTA_DIAGONAL_CORRECTION_B);
600 | }
601 | static inline float deltaDiagonalCorrectionC() {
602 | return EEPROM_FLOAT(DELTA_DIAGONAL_CORRECTION_C);
603 | }
604 | static inline float deltaMaxRadius() {
605 | return EEPROM_FLOAT(DELTA_MAX_RADIUS);
606 | }
607 |
608 | #endif
609 | static void initalizeUncached();
610 | #if MIXING_EXTRUDER
611 | static void storeMixingRatios(bool updateChecksums = true);
612 | static void readMixingRatios();
613 | static void restoreMixingRatios();
614 | #endif
615 |
616 | static void setZCorrection(int32_t c,int index);
617 | static inline int32_t getZCorrection(int index) {
618 | return HAL::eprGetInt32(2048 + (index << 2));
619 | }
620 | static inline void setZCorrectionEnabled(int8_t on) {
621 | #if EEPROM_MODE != 0
622 | if(isZCorrectionEnabled() == on) return;
623 | HAL::eprSetInt16(EPR_DISTORTION_CORRECTION_ENABLED, on);
624 | uint8_t newcheck = computeChecksum();
625 | if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
626 | HAL::eprSetByte(EPR_INTEGRITY_BYTE, newcheck);
627 | #endif
628 | }
629 | static inline int8_t isZCorrectionEnabled() {
630 | #if EEPROM_MODE != 0
631 | return HAL::eprGetByte(EPR_DISTORTION_CORRECTION_ENABLED);
632 | #else
633 | return 0;
634 | #endif
635 | }
636 | static inline float bendingCorrectionA() {
637 | #if EEPROM_MODE != 0
638 | return HAL::eprGetFloat(EPR_BENDING_CORRECTION_A);
639 | #else
640 | return BENDING_CORRECTION_A;
641 | #endif
642 | }
643 | static inline float bendingCorrectionB() {
644 | #if EEPROM_MODE != 0
645 | return HAL::eprGetFloat(EPR_BENDING_CORRECTION_B);
646 | #else
647 | return BENDING_CORRECTION_B;
648 | #endif
649 | }
650 | static inline float bendingCorrectionC() {
651 | #if EEPROM_MODE != 0
652 | return HAL::eprGetFloat(EPR_BENDING_CORRECTION_C);
653 | #else
654 | return BENDING_CORRECTION_C;
655 | #endif
656 | }
657 | static inline float accelarationFactorTop() {
658 | #if EEPROM_MODE != 0
659 | return HAL::eprGetFloat(EPR_ACCELERATION_FACTOR_TOP);
660 | #else
661 | return ACCELERATION_FACTOR_TOP;
662 | #endif
663 | }
664 |
665 | };
666 | #endif
667 |
--------------------------------------------------------------------------------
/Wangsamas/motion.h:
--------------------------------------------------------------------------------
1 | /*
2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan.
3 |
4 | Wangsamas-Firmware adalah perangkat lunak bebas:
5 | Anda dapat mendistribusikannya dan/atau mengubahnya
6 | dengan syarat dan ketentuan GNU General Public License
7 | yang dipublikasikan oleh Free Software Foundation,
8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru.
9 |
10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat,
11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau
12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License
13 | untuk keterangan lebih lanjut.
14 |
15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan
16 | dengan Wangsamas-Firmware. Jika tidak, lihat .
17 |
18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware
19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware.
20 |
21 | ---------------------
22 |
23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan.
24 |
25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify
26 | it under the terms of the GNU General Public License as published by
27 | the Free Software Foundation, either version 3 of the License, or
28 | (at your option) any later version.
29 |
30 | Wangsamas-Firmware is distributed in the hope that it will be useful,
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | GNU General Public License for more details.
34 |
35 | You should have received a copy of the GNU General Public License
36 | along with Wangsamas-Firmware. If not, see .
37 |
38 | This firmware is based on Repetier-Firmware which based on sprinter firmware
39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
40 |
41 | Functions in this file are used to communicate using ascii or repetier protocol.
42 | */
43 |
44 | #ifndef MOTION_H_INCLUDED
45 | #define MOTION_H_INCLUDED
46 |
47 | /** Marks the first step of a new move */
48 | #define FLAG_WARMUP 1
49 | #define FLAG_NOMINAL 2
50 | #define FLAG_DECELERATING 4
51 | #define FLAG_ACCELERATION_ENABLED 8 // unused
52 | #define FLAG_CHECK_ENDSTOPS 16
53 | #define FLAG_ALL_E_MOTORS 32 // For mixed extruder move all motors instead of selected motor
54 | #define FLAG_SKIP_DEACCELERATING 64 // unused
55 | #define FLAG_BLOCKED 128
56 |
57 | /** Are the step parameter computed */
58 | #define FLAG_JOIN_STEPPARAMS_COMPUTED 1
59 | /** The right speed is fixed. Don't check this block or any block to the left. */
60 | #define FLAG_JOIN_END_FIXED 2
61 | /** The left speed is fixed. Don't check left block. */
62 | #define FLAG_JOIN_START_FIXED 4
63 | /** Start filament retraction at move start */
64 | #define FLAG_JOIN_START_RETRACT 8
65 | /** Wait for filament push back, before ending move */
66 | #define FLAG_JOIN_END_RETRACT 16
67 | /** Disable retract for this line */
68 | #define FLAG_JOIN_NO_RETRACT 32
69 | /** Wait for the extruder to finish it's up movement */
70 | #define FLAG_JOIN_WAIT_EXTRUDER_UP 64
71 | /** Wait for the extruder to finish it's down movement */
72 | #define FLAG_JOIN_WAIT_EXTRUDER_DOWN 128
73 | // Printing related data
74 | #if NONLINEAR_SYSTEM
75 | // Allow the delta cache to store segments for every line in line cache. Beware this gets big ... fast.
76 |
77 | class PrintLine;
78 | typedef struct
79 | {
80 | flag8_t dir; ///< Direction of delta movement.
81 | uint16_t deltaSteps[TOWER_ARRAY]; ///< Number of steps in move.
82 | inline bool checkEndstops(PrintLine *cur,bool checkall);
83 | inline void setXMoveFinished()
84 | {
85 | dir &= ~XSTEP;
86 | }
87 | inline void setYMoveFinished()
88 | {
89 | dir &= ~YSTEP;
90 | }
91 | inline void setZMoveFinished()
92 | {
93 | dir &= ~ZSTEP;
94 | }
95 | inline void setXYMoveFinished()
96 | {
97 | dir &= ~XY_STEP;
98 | }
99 | inline bool isXPositiveMove()
100 | {
101 | return (dir & X_STEP_DIRPOS) == X_STEP_DIRPOS;
102 | }
103 | inline bool isXNegativeMove()
104 | {
105 | return (dir & X_STEP_DIRPOS) == XSTEP;
106 | }
107 | inline bool isYPositiveMove()
108 | {
109 | return (dir & Y_STEP_DIRPOS) == Y_STEP_DIRPOS;
110 | }
111 | inline bool isYNegativeMove()
112 | {
113 | return (dir & Y_STEP_DIRPOS) == YSTEP;
114 | }
115 | inline bool isZPositiveMove()
116 | {
117 | return (dir & Z_STEP_DIRPOS) == Z_STEP_DIRPOS;
118 | }
119 | inline bool isZNegativeMove()
120 | {
121 | return (dir & Z_STEP_DIRPOS) == ZSTEP;
122 | }
123 | inline bool isEPositiveMove()
124 | {
125 | return (dir & E_STEP_DIRPOS) == E_STEP_DIRPOS;
126 | }
127 | inline bool isENegativeMove()
128 | {
129 | return (dir & E_STEP_DIRPOS) == ESTEP;
130 | }
131 | inline bool isXMove()
132 | {
133 | return (dir & XSTEP);
134 | }
135 | inline bool isYMove()
136 | {
137 | return (dir & YSTEP);
138 | }
139 | inline bool isXOrYMove()
140 | {
141 | return dir & XY_STEP;
142 | }
143 | inline bool isZMove()
144 | {
145 | return (dir & ZSTEP);
146 | }
147 | inline bool isEMove()
148 | {
149 | return (dir & ESTEP);
150 | }
151 | inline bool isEOnlyMove()
152 | {
153 | return (dir & XYZE_STEP)==ESTEP;
154 | }
155 | inline bool isNoMove()
156 | {
157 | return (dir & XYZE_STEP) == 0;
158 | }
159 | inline bool isXYZMove()
160 | {
161 | return dir & XYZ_STEP;
162 | }
163 | inline bool isMoveOfAxis(uint8_t axis)
164 | {
165 | return (dir & (XSTEP< inside interrupt handle
481 | inline void updateAdvanceSteps(speed_t v, uint8_t max_loops, bool accelerate)
482 | {
483 | #if USE_ADVANCE
484 | if(!Printer::isAdvanceActivated()) return;
485 | #if ENABLE_QUADRATIC_ADVANCE
486 | long advanceTarget = Printer::advanceExecuted;
487 | if(accelerate)
488 | {
489 | for(uint8_t loop = 0; loop < max_loops; loop++) advanceTarget += advanceRate;
490 | if(advanceTarget > advanceFull)
491 | advanceTarget = advanceFull;
492 | }
493 | else
494 | {
495 | for(uint8_t loop = 0; loop < max_loops; loop++) advanceTarget -= advanceRate;
496 | if(advanceTarget < advanceEnd)
497 | advanceTarget = advanceEnd;
498 | }
499 | long h = HAL::mulu16xu16to32(v, advanceL);
500 | int tred = ((advanceTarget + h) >> 16);
501 | HAL::forbidInterrupts();
502 | Printer::extruderStepsNeeded += tred - Printer::advanceStepsSet;
503 | if(tred > 0 && Printer::advanceStepsSet <= 0)
504 | Printer::extruderStepsNeeded += Extruder::current->advanceBacklash;
505 | else if(tred < 0 && Printer::advanceStepsSet >= 0)
506 | Printer::extruderStepsNeeded -= Extruder::current->advanceBacklash;
507 | Printer::advanceStepsSet = tred;
508 | HAL::allowInterrupts();
509 | Printer::advanceExecuted = advanceTarget;
510 | #else
511 | int tred = HAL::mulu6xu16shift16(v, advanceL);
512 | HAL::forbidInterrupts();
513 | Printer::extruderStepsNeeded += tred - Printer::advanceStepsSet;
514 | if(tred > 0 && Printer::advanceStepsSet <= 0)
515 | Printer::extruderStepsNeeded += (Extruder::current->advanceBacklash << 1);
516 | else if(tred < 0 && Printer::advanceStepsSet >= 0)
517 | Printer::extruderStepsNeeded -= (Extruder::current->advanceBacklash << 1);
518 | Printer::advanceStepsSet = tred;
519 | HAL::allowInterrupts();
520 | #endif
521 | #endif
522 | }
523 | INLINE bool moveDecelerating()
524 | {
525 | if(stepsRemaining <= decelSteps)
526 | {
527 | if (!(flags & FLAG_DECELERATING))
528 | {
529 | Printer::timer = 0;
530 | flags |= FLAG_DECELERATING;
531 | }
532 | return true;
533 | }
534 | else return false;
535 | }
536 | INLINE bool moveAccelerating()
537 | {
538 | return Printer::stepNumber <= accelSteps;
539 | }
540 | INLINE void startXStep()
541 | {
542 | #if !(GANTRY) || defined(FAST_COREXYZ)
543 | Printer::startXStep();
544 | #else
545 | #if DRIVE_SYSTEM == XY_GANTRY || DRIVE_SYSTEM == XZ_GANTRY
546 | if(isXPositiveMove())
547 | {
548 | Printer::motorX++;
549 | Printer::motorYorZ++;
550 | }
551 | else
552 | {
553 | Printer::motorX--;
554 | Printer::motorYorZ--;
555 | }
556 | #endif
557 | #if DRIVE_SYSTEM == YX_GANTRY || DRIVE_SYSTEM == ZX_GANTRY
558 | if(isXPositiveMove())
559 | {
560 | Printer::motorX++;
561 | Printer::motorYorZ--;
562 | }
563 | else
564 | {
565 | Printer::motorX--;
566 | Printer::motorYorZ++;
567 | }
568 | #endif
569 | #endif
570 | #ifdef DEBUG_STEPCOUNT
571 | totalStepsRemaining--;
572 | #endif
573 | }
574 | INLINE void startYStep()
575 | {
576 | #if !(GANTRY) || DRIVE_SYSTEM == ZX_GANTRY || DRIVE_SYSTEM == XZ_GANTRY || defined(FAST_COREXYZ)
577 | Printer::startYStep();
578 | #else
579 | #if DRIVE_SYSTEM == XY_GANTRY
580 | if(isYPositiveMove())
581 | {
582 | Printer::motorX++;
583 | Printer::motorYorZ--;
584 | }
585 | else
586 | {
587 | Printer::motorX--;
588 | Printer::motorYorZ++;
589 | }
590 | #endif
591 | #if DRIVE_SYSTEM == YX_GANTRY
592 | if(isYPositiveMove())
593 | {
594 | Printer::motorX++;
595 | Printer::motorYorZ++;
596 | }
597 | else
598 | {
599 | Printer::motorX--;
600 | Printer::motorYorZ--;
601 | }
602 | #endif
603 | #endif // GANTRY
604 | #ifdef DEBUG_STEPCOUNT
605 | totalStepsRemaining--;
606 | #endif
607 |
608 | }
609 | INLINE void startZStep()
610 | {
611 | #if !(GANTRY) || DRIVE_SYSTEM == YX_GANTRY || DRIVE_SYSTEM == XY_GANTRY || defined(FAST_COREXYZ)
612 | Printer::startZStep();
613 | #else
614 | #if DRIVE_SYSTEM == XZ_GANTRY
615 | if(isZPositiveMove())
616 | {
617 | Printer::motorX++;
618 | Printer::motorYorZ--;
619 | }
620 | else
621 | {
622 | Printer::motorX--;
623 | Printer::motorYorZ++;
624 | }
625 | #endif
626 | #if DRIVE_SYSTEM == ZX_GANTRY
627 | if(isZPositiveMove())
628 | {
629 | Printer::motorX++;
630 | Printer::motorYorZ++;
631 | }
632 | else
633 | {
634 | Printer::motorX--;
635 | Printer::motorYorZ--;
636 | }
637 | #endif
638 | #endif
639 | #ifdef DEBUG_STEPCOUNT
640 | totalStepsRemaining--;
641 | #endif
642 | }
643 | void updateStepsParameter();
644 | float safeSpeed(fast8_t drivingAxis);
645 | void calculateMove(float axis_diff[],uint8_t pathOptimize,fast8_t distanceBase);
646 | void logLine();
647 | INLINE long getWaitTicks()
648 | {
649 | return timeInTicks;
650 | }
651 | INLINE void setWaitTicks(long wait)
652 | {
653 | timeInTicks = wait;
654 | }
655 |
656 | static INLINE bool hasLines()
657 | {
658 | return linesCount;
659 | }
660 | static INLINE void setCurrentLine()
661 | {
662 | cur = &lines[linesPos];
663 | #if CPU_ARCH==ARCH_ARM
664 | PrintLine::nlFlag = true;
665 | #endif
666 | }
667 | // Only called from within interrupts
668 | static INLINE void removeCurrentLineForbidInterrupt()
669 | {
670 | linesPos++;
671 | if(linesPos >= PRINTLINE_CACHE_SIZE) linesPos = 0;
672 | cur = NULL;
673 | #if CPU_ARCH == ARCH_ARM
674 | nlFlag = false;
675 | #endif
676 | HAL::forbidInterrupts();
677 | --linesCount;
678 | if(!linesCount)
679 | Printer::setMenuMode(MENU_MODE_PRINTING, false);
680 | }
681 | static INLINE void pushLine()
682 | {
683 | linesWritePos++;
684 | if(linesWritePos >= PRINTLINE_CACHE_SIZE) linesWritePos = 0;
685 | Printer::setMenuMode(MENU_MODE_PRINTING, true);
686 | InterruptProtectedBlock noInts;
687 | linesCount++;
688 | }
689 | static uint8_t getLinesCount()
690 | {
691 | InterruptProtectedBlock noInts;
692 | return linesCount;
693 | }
694 | static PrintLine *getNextWriteLine()
695 | {
696 | return &lines[linesWritePos];
697 | }
698 | static inline void computeMaxJunctionSpeed(PrintLine *previous,PrintLine *current);
699 | static int32_t bresenhamStep();
700 | static void waitForXFreeLines(uint8_t b=1, bool allowMoves = false);
701 | static inline void forwardPlanner(ufast8_t p);
702 | static inline void backwardPlanner(ufast8_t p,ufast8_t last);
703 | static void updateTrapezoids();
704 | static uint8_t insertWaitMovesIfNeeded(uint8_t pathOptimize, uint8_t waitExtraLines);
705 | #if !NONLINEAR_SYSTEM
706 | static void queueCartesianMove(uint8_t check_endstops,uint8_t pathOptimize);
707 | #if DISTORTION_CORRECTION
708 | static void queueCartesianSegmentTo(uint8_t check_endstops, uint8_t pathOptimize);
709 | #endif
710 | #endif
711 | static void moveRelativeDistanceInSteps(int32_t x,int32_t y,int32_t z,int32_t e,float feedrate,bool waitEnd,bool check_endstop,bool pathOptimize = true);
712 | static void moveRelativeDistanceInStepsReal(int32_t x,int32_t y,int32_t z,int32_t e,float feedrate,bool waitEnd,bool pathOptimize = true);
713 | static void rotateInSteps(int32_t x,int32_t y,float feedrate,bool waitEnd,bool check_endstop,bool pathOptimize = true); // Kusuma SCARA
714 | static void rotateInStepsNoCheck(int32_t x,int32_t y,float feedrate,bool waitEnd,bool check_endstop,bool pathOptimize = true); // Kusuma SCARA
715 | #if ARC_SUPPORT
716 | static void arc(float *position, float *target, float *offset, float radius, uint8_t isclockwise);
717 | #endif
718 | static INLINE void previousPlannerIndex(ufast8_t &p)
719 | {
720 | p = (p ? p - 1 : PRINTLINE_CACHE_SIZE - 1);
721 | }
722 | static INLINE void nextPlannerIndex(ufast8_t& p)
723 | {
724 | p = (p == PRINTLINE_CACHE_SIZE - 1 ? 0 : p + 1);
725 | }
726 | #if NONLINEAR_SYSTEM
727 | static uint8_t queueNonlinearMove(uint8_t check_endstops,uint8_t pathOptimize, uint8_t softEndstop);
728 | static uint8_t queueRotation(uint8_t check_endstops,uint8_t pathOptimize, uint8_t softEndstop); // Kusuma SCARA
729 | inline uint16_t calculateRotationSubSegments(uint8_t softEndstop); // Kusuma SCARA
730 | static inline void queueEMove(int32_t e_diff,uint8_t check_endstops,uint8_t pathOptimize);
731 | inline uint16_t calculateNonlinearSubSegments(uint8_t softEndstop);
732 | static inline void calculateDirectionAndDelta(int32_t difference[], ufast8_t *dir, int32_t delta[]);
733 | static inline uint8_t calculateDistance(float axis_diff[], uint8_t dir, float *distance);
734 | #if SOFTWARE_LEVELING && DRIVE_SYSTEM == DELTA
735 | static void calculatePlane(int32_t factors[], int32_t p1[], int32_t p2[], int32_t p3[]);
736 | static float calcZOffset(int32_t factors[], int32_t pointX, int32_t pointY);
737 | #endif
738 | #endif
739 | };
740 |
741 |
742 |
743 | #endif // MOTION_H_INCLUDED
744 |
--------------------------------------------------------------------------------
/Wangsamas/HAL.h:
--------------------------------------------------------------------------------
1 | /*
2 | Berkas ini adalah bagian dari Wangsamas-Firmware oleh Kusuma Ruslan.
3 |
4 | Wangsamas-Firmware adalah perangkat lunak bebas:
5 | Anda dapat mendistribusikannya dan/atau mengubahnya
6 | dengan syarat dan ketentuan GNU General Public License
7 | yang dipublikasikan oleh Free Software Foundation,
8 | baik ijin versi 3, atau (menurut pilihanmu) versi yang terbaru.
9 |
10 | Wangsamas-Firmware didistribusikan dengan harapan agar dapat bermanfaat,
11 | tetapi TANPA JAMINAN; bahkan tanpa jaminan tersirat PERDAGANGAN atau
12 | KECOCOKAN UNTUK TUJUAN TERTENTU. Lihat GNU General Public License
13 | untuk keterangan lebih lanjut.
14 |
15 | Anda seharusnya sudah menerima salinan GNU General Public License bersamaan
16 | dengan Wangsamas-Firmware. Jika tidak, lihat .
17 |
18 | Firmware ini berdasarkan Repetier-Firmware yang berdasarkan Sprinter firmware
19 | yang berdasarkan Tonokip Reprap firmware yang berdasarkan Hydra-mmm firmware.
20 |
21 | ---------------------
22 |
23 | This file is part of Wangsamas-Firmware by Kusuma Ruslan.
24 |
25 | Wangsamas-Firmware is free software: you can redistribute it and/or modify
26 | it under the terms of the GNU General Public License as published by
27 | the Free Software Foundation, either version 3 of the License, or
28 | (at your option) any later version.
29 |
30 | Wangsamas-Firmware is distributed in the hope that it will be useful,
31 | but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | GNU General Public License for more details.
34 |
35 | You should have received a copy of the GNU General Public License
36 | along with Wangsamas-Firmware. If not, see .
37 |
38 | This firmware is based on Repetier-Firmware which based on sprinter firmware
39 | which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
40 | Functions in this file are used to communicate using ascii or repetier protocol.
41 | */
42 |
43 | #ifndef HAL_H
44 | #define HAL_H
45 |
46 | /**
47 | This is the main Hardware Abstraction Layer (HAL).
48 | To make the firmware work with different processors and toolchains,
49 | all hardware related code should be packed into the hal files.
50 | */
51 |
52 | #include
53 | #include
54 |
55 |
56 | #define INLINE __attribute__((always_inline))
57 |
58 | #if CPU_ARCH == ARCH_AVR
59 | #include
60 | #else
61 | #define PROGMEM
62 | #define PGM_P const char *
63 | #define PSTR(s) s
64 | #define pgm_read_byte_near(x) (*(uint8_t*)x)
65 | #define pgm_read_byte(x) (*(uint8_t*)x)
66 | #endif
67 |
68 | #define PACK
69 |
70 | #define FSTRINGVALUE(var,value) const char var[] PROGMEM = value;
71 | #define FSTRINGVAR(var) static const char var[] PROGMEM;
72 | #define FSTRINGPARAM(var) PGM_P var
73 |
74 | #include
75 | #include
76 | /** \brief Prescale factor, timer0 runs at.
77 |
78 | All known arduino boards use 64. This value is needed for the extruder timing. */
79 | #define TIMER0_PRESCALE 64
80 |
81 | #define ANALOG_PRESCALER _BV(ADPS0)|_BV(ADPS1)|_BV(ADPS2)
82 |
83 | #if MOTHERBOARD==8 || MOTHERBOARD==88 || MOTHERBOARD==9 || MOTHERBOARD==92 || CPU_ARCH!=ARCH_AVR
84 | #define EXTERNALSERIAL
85 | #endif
86 | //#define EXTERNALSERIAL // Force using arduino serial
87 | #ifndef EXTERNALSERIAL
88 | #define HardwareSerial_h // Don't use standard serial console
89 | #endif
90 | #include
91 | #include "Print.h"
92 | #ifdef EXTERNALSERIAL
93 | #define SERIAL_RX_BUFFER_SIZE 128
94 | #endif
95 | #if defined(ARDUINO) && ARDUINO >= 100
96 | #include "Arduino.h"
97 | #else
98 | #include "WProgram.h"
99 | #define COMPAT_PRE1
100 | #endif
101 | #if CPU_ARCH==ARCH_AVR
102 | #include "fastio.h"
103 | #else
104 | #define READ(IO) digitalRead(IO)
105 | #define WRITE(IO, v) digitalWrite(IO, v)
106 | #define SET_INPUT(IO) pinMode(IO, INPUT)
107 | #define SET_OUTPUT(IO) pinMode(IO, OUTPUT)
108 | #endif
109 |
110 | class InterruptProtectedBlock
111 | {
112 | uint8_t sreg;
113 | public:
114 | inline void protect()
115 | {
116 | cli();
117 | }
118 |
119 | inline void unprotect()
120 | {
121 | SREG = sreg;
122 | }
123 |
124 | inline InterruptProtectedBlock(bool later = false)
125 | {
126 | sreg = SREG;
127 | if(!later)
128 | cli();
129 | }
130 |
131 | inline ~InterruptProtectedBlock()
132 | {
133 | SREG = sreg;
134 | }
135 | };
136 |
137 | #define EEPROM_OFFSET 0
138 | #define SECONDS_TO_TICKS(s) (unsigned long)(s*(float)F_CPU)
139 | #define ANALOG_INPUT_SAMPLE 5
140 | // Bits of the ADC converter
141 | #define ANALOG_INPUT_BITS 10
142 | #define ANALOG_REDUCE_BITS 0
143 | #define ANALOG_REDUCE_FACTOR 1
144 |
145 | #define MAX_RAM 32767
146 |
147 | #define bit_clear(x,y) x&= ~(1<>8)*cur->accel)>>10;
448 | return res;
449 | #else
450 | return ((timer >> 8) * accel) >> 10;
451 | #endif
452 | }
453 | // Multiply two 16 bit values and return 32 bit result
454 | static inline uint32_t mulu16xu16to32(unsigned int a,unsigned int b)
455 | {
456 | uint32_t res;
457 | // 18 Ticks = 1.125 us
458 | __asm__ __volatile__ ( // 0 = res, 1 = timer, 2 = accel %D2=0 ,%A1 are unused is free
459 | // Result LSB first: %A0, %B0, %A1
460 | "clr r18 \n\t"
461 | "mul %B2,%B1 \n\t" // mul hig bytes
462 | "movw %C0,r0 \n\t"
463 | "mul %A1,%A2 \n\t" // mul low bytes
464 | "movw %A0,r0 \n\t"
465 | "mul %A1,%B2 \n\t"
466 | "add %B0,r0 \n\t"
467 | "adc %C0,r1 \n\t"
468 | "adc %D0,r18 \n\t"
469 | "mul %B1,%A2 \n\t"
470 | "add %B0,r0 \n\t"
471 | "adc %C0,r1 \n\t"
472 | "adc %D0,r18 \n\t"
473 | "clr r1 \n\t"
474 | :"=&r"(res),"=r"(a),"=r"(b)
475 | :"1"(a),"2"(b)
476 | :"r18" );
477 | // return (long)a*b;
478 | return res;
479 | }
480 | // Multiply two 16 bit values and return 32 bit result
481 | static inline unsigned int mulu6xu16shift16(unsigned int a,unsigned int b)
482 | {
483 | #if CPU_ARCH == ARCH_AVR
484 | unsigned int res;
485 | // 18 Ticks = 1.125 us
486 | __asm__ __volatile__ ( // 0 = res, 1 = timer, 2 = accel %D2=0 ,%A1 are unused is free
487 | // Result LSB first: %A0, %B0, %A1
488 | "clr r18 \n\t"
489 | "mul %B2,%B1 \n\t" // mul hig bytes
490 | "movw %A0,r0 \n\t"
491 | "mul %A1,%A2 \n\t" // mul low bytes
492 | "mov r19,r1 \n\t"
493 | "mul %A1,%B2 \n\t"
494 | "add r19,r0 \n\t"
495 | "adc %A0,r1 \n\t"
496 | "adc %B0,r18 \n\t"
497 | "mul %B1,%A2 \n\t"
498 | "add r19,r0 \n\t"
499 | "adc %A0,r1 \n\t"
500 | "adc %B0,r18 \n\t"
501 | "clr r1 \n\t"
502 | :"=&r"(res),"=r"(a),"=r"(b)
503 | :"1"(a),"2"(b)
504 | :"r18","r19" );
505 | return res;
506 | #else
507 | return ((int32_t)a * b) >> 16;
508 | #endif
509 | }
510 | static inline void digitalWrite(uint8_t pin,uint8_t value)
511 | {
512 | ::digitalWrite(pin,value);
513 | }
514 | static inline uint8_t digitalRead(uint8_t pin)
515 | {
516 | return ::digitalRead(pin);
517 | }
518 | static inline void pinMode(uint8_t pin,uint8_t mode)
519 | {
520 | ::pinMode(pin,mode);
521 | }
522 | static int32_t CPUDivU2(unsigned int divisor);
523 | static inline void delayMicroseconds(unsigned int delayUs)
524 | {
525 | ::delayMicroseconds(delayUs);
526 | }
527 | static inline void delayMilliseconds(unsigned int delayMs)
528 | {
529 | ::delay(delayMs);
530 | }
531 | static inline void tone(uint8_t pin,int duration)
532 | {
533 | ::tone(pin,duration);
534 | }
535 | static inline void noTone(uint8_t pin)
536 | {
537 | ::noTone(pin);
538 | }
539 | static inline void eprSetByte(unsigned int pos,uint8_t value)
540 | {
541 | eeprom_write_byte((unsigned char *)(EEPROM_OFFSET + pos), value);
542 | }
543 | static inline void eprSetInt16(unsigned int pos,int16_t value)
544 | {
545 | eeprom_write_word((unsigned int*)(EEPROM_OFFSET + pos),value);
546 | }
547 | static inline void eprSetInt32(unsigned int pos,int32_t value)
548 | {
549 | eeprom_write_dword((uint32_t*)(EEPROM_OFFSET + pos),value);
550 | }
551 | static inline void eprSetFloat(unsigned int pos,float value)
552 | {
553 | eeprom_write_block(&value,(void*)(EEPROM_OFFSET + pos), 4);
554 | }
555 | static inline uint8_t eprGetByte(unsigned int pos)
556 | {
557 | return eeprom_read_byte ((unsigned char *)(EEPROM_OFFSET + pos));
558 | }
559 | static inline int16_t eprGetInt16(unsigned int pos)
560 | {
561 | return eeprom_read_word((uint16_t *)(EEPROM_OFFSET + pos));
562 | }
563 | static inline int32_t eprGetInt32(unsigned int pos)
564 | {
565 | return eeprom_read_dword((uint32_t*)(EEPROM_OFFSET + pos));
566 | }
567 | static inline float eprGetFloat(unsigned int pos)
568 | {
569 | float v;
570 | eeprom_read_block(&v,(void *)(EEPROM_OFFSET + pos),4); // newer gcc have eeprom_read_block but not arduino 22
571 | return v;
572 | }
573 |
574 | // Faster version of InterruptProtectedBlock.
575 | // For safety it ma yonly be called from within an
576 | // interrupt handler.
577 | static inline void allowInterrupts()
578 | {
579 | sei();
580 | }
581 |
582 | // Faster version of InterruptProtectedBlock.
583 | // For safety it ma yonly be called from within an
584 | // interrupt handler.
585 | static inline void forbidInterrupts()
586 | {
587 | cli();
588 | }
589 | static inline unsigned long timeInMilliseconds()
590 | {
591 | return millis();
592 | }
593 | static inline char readFlashByte(PGM_P ptr)
594 | {
595 | return pgm_read_byte(ptr);
596 | }
597 | static inline void serialSetBaudrate(long baud)
598 | {
599 | RFSERIAL.begin(baud);
600 | }
601 | static inline bool serialByteAvailable()
602 | {
603 | return RFSERIAL.available() > 0;
604 | }
605 | static inline uint8_t serialReadByte()
606 | {
607 | return RFSERIAL.read();
608 | }
609 | static inline void serialWriteByte(char b)
610 | {
611 | RFSERIAL.write(b);
612 | }
613 | static inline void serialFlush()
614 | {
615 | RFSERIAL.flush();
616 | }
617 | static void setupTimer();
618 | static void showStartReason();
619 | static int getFreeRam();
620 | static void resetHardware();
621 |
622 | // SPI related functions
623 | static void spiBegin()
624 | {
625 | #if SDSS >= 0
626 | SET_INPUT(MISO_PIN);
627 | SET_OUTPUT(MOSI_PIN);
628 | SET_OUTPUT(SCK_PIN);
629 | // SS must be in output mode even it is not chip select
630 | SET_OUTPUT(SDSS);
631 | #if SDSSORIG >- 1
632 | SET_OUTPUT(SDSSORIG);
633 | #endif
634 | // set SS high - may be chip select for another SPI device
635 | #if defined(SET_SPI_SS_HIGH) && SET_SPI_SS_HIGH
636 | WRITE(SDSS, HIGH);
637 | #endif // SET_SPI_SS_HIGH
638 | #endif
639 | }
640 | static inline void spiInit(uint8_t spiRate)
641 | {
642 | uint8_t r = 0;
643 | for (uint8_t b = 2; spiRate > b && r < 6; b <<= 1, r++);
644 |
645 | SET_OUTPUT(SS);
646 | WRITE(SS,HIGH);
647 | SET_OUTPUT(SCK);
648 | SET_OUTPUT(MOSI_PIN);
649 | SET_INPUT(MISO_PIN);
650 | #ifdef PRR
651 | PRR &= ~(1<> 1);
657 | SPSR = (r & 1 || r == 6 ? 0 : 1) << SPI2X;
658 |
659 | }
660 | static inline uint8_t spiReceive(uint8_t send=0xff)
661 | {
662 | SPDR = send;
663 | while (!(SPSR & (1 << SPIF))) {}
664 | return SPDR;
665 | }
666 | static inline void spiReadBlock(uint8_t*buf,size_t nbyte)
667 | {
668 | if (nbyte-- == 0) return;
669 | SPDR = 0XFF;
670 | for (size_t i = 0; i < nbyte; i++)
671 | {
672 | while (!(SPSR & (1 << SPIF))) {}
673 | buf[i] = SPDR;
674 | SPDR = 0XFF;
675 | }
676 | while (!(SPSR & (1 << SPIF))) {}
677 | buf[nbyte] = SPDR;
678 | }
679 | static inline void spiSend(uint8_t b)
680 | {
681 | SPDR = b;
682 | while (!(SPSR & (1 << SPIF))) {}
683 | }
684 | static inline void spiSend(const uint8_t* buf , size_t n)
685 | {
686 | if (n == 0) return;
687 | SPDR = buf[0];
688 | if (n > 1)
689 | {
690 | uint8_t b = buf[1];
691 | size_t i = 2;
692 | while (1)
693 | {
694 | while (!(SPSR & (1 << SPIF))) {}
695 | SPDR = b;
696 | if (i == n) break;
697 | b = buf[i++];
698 | }
699 | }
700 | while (!(SPSR & (1 << SPIF))) {}
701 | }
702 |
703 | static inline __attribute__((always_inline))
704 | void spiSendBlock(uint8_t token, const uint8_t* buf)
705 | {
706 | SPDR = token;
707 | for (uint16_t i = 0; i < 512; i += 2)
708 | {
709 | while (!(SPSR & (1 << SPIF))) {}
710 | SPDR = buf[i];
711 | while (!(SPSR & (1 << SPIF))) {}
712 | SPDR = buf[i + 1];
713 | }
714 | while (!(SPSR & (1 << SPIF))) {}
715 | }
716 |
717 | // I2C Support
718 |
719 | static void i2cInit(uint32_t clockSpeedHz);
720 | static unsigned char i2cStart(uint8_t address);
721 | static void i2cStartWait(uint8_t address);
722 | static void i2cStop(void);
723 | static uint8_t i2cWrite( uint8_t data );
724 | static uint8_t i2cReadAck(void);
725 | static uint8_t i2cReadNak(void);
726 |
727 | // Watchdog support
728 |
729 | inline static void startWatchdog()
730 | {
731 | #if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
732 | WDTCSR = (1<