/ Repetier / ui.h
ui.h
  1  /*
  2      This file is part of Repetier-Firmware.
  3  
  4      Repetier-Firmware is free software: you can redistribute it and/or modify
  5      it under the terms of the GNU General Public License as published by
  6      the Free Software Foundation, either version 3 of the License, or
  7      (at your option) any later version.
  8  
  9      Repetier-Firmware is distributed in the hope that it will be useful,
 10      but WITHOUT ANY WARRANTY; without even the implied warranty of
 11      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12      GNU General Public License for more details.
 13  
 14      You should have received a copy of the GNU General Public License
 15      along with Repetier-Firmware.  If not, see <http://www.gnu.org/licenses/>.
 16  
 17  */
 18  
 19  #ifndef _ui_h
 20  #define _ui_h
 21  
 22  #if defined(ARDUINO) && ARDUINO >= 100
 23  #include "Arduino.h"
 24  #else
 25  #include "WProgram.h"
 26  #define COMPAT_PRE1
 27  #endif
 28  #include <avr/pgmspace.h>
 29  #include "gcode.h"
 30  
 31  // ----------------------------------------------------------------------------
 32  //                          Action codes
 33  // 1-999     : Autorepeat
 34  // 1000-1999 : Execute
 35  // 2000-2999 : Write code
 36  // 4000-4999 : Show menu
 37  // Add UI_ACTION_TOPMENU to show a menu as top menu
 38  // ----------------------------------------------------------------------------
 39  
 40  #define UI_ACTION_TOPMENU 8192
 41  
 42  #define UI_ACTION_NEXT 1
 43  #define UI_ACTION_PREVIOUS 2
 44  
 45  #define UI_ACTION_X_UP                 100
 46  #define UI_ACTION_X_DOWN               101
 47  #define UI_ACTION_Y_UP                 102
 48  #define UI_ACTION_Y_DOWN               103
 49  #define UI_ACTION_Z_UP                 104
 50  #define UI_ACTION_Z_DOWN               105
 51  #define UI_ACTION_EXTRUDER_UP          106
 52  #define UI_ACTION_EXTRUDER_DOWN        107
 53  #define UI_ACTION_EXTRUDER_TEMP_UP     108
 54  #define UI_ACTION_EXTRUDER_TEMP_DOWN   109
 55  #define UI_ACTION_HEATED_BED_UP        110
 56  #define UI_ACTION_HEATED_BED_DOWN      111
 57  #define UI_ACTION_FAN_UP               112
 58  #define UI_ACTION_FAN_DOWN             113
 59  
 60  #define UI_ACTION_DUMMY 10000
 61  #define UI_ACTION_BACK                  1000
 62  #define UI_ACTION_OK                    1001
 63  #define UI_ACTION_MENU_UP               1002
 64  #define UI_ACTION_TOP_MENU              1003
 65  #define UI_ACTION_EMERGENCY_STOP        1004
 66  #define UI_ACTION_XPOSITION             1005
 67  #define UI_ACTION_YPOSITION             1006
 68  #define UI_ACTION_ZPOSITION             1007
 69  #define UI_ACTION_EPOSITION             1008
 70  #define UI_ACTION_BED_TEMP              1009
 71  #define UI_ACTION_EXTRUDER_TEMP         1010
 72  #define UI_ACTION_SD_DELETE             1012
 73  #define UI_ACTION_SD_PRINT              1013
 74  #define UI_ACTION_SD_PAUSE              1014
 75  #define UI_ACTION_SD_CONTINUE           1015
 76  #define UI_ACTION_SD_UNMOUNT            1016
 77  #define UI_ACTION_SD_MOUNT              1017
 78  #define UI_ACTION_XPOSITION_FAST        1018
 79  #define UI_ACTION_YPOSITION_FAST        1019
 80  #define UI_ACTION_ZPOSITION_FAST        1020
 81  #define UI_ACTION_HOME_ALL              1021
 82  #define UI_ACTION_HOME_X                1022
 83  #define UI_ACTION_HOME_Y                1023
 84  #define UI_ACTION_HOME_Z                1024
 85  #define UI_ACTION_SELECT_EXTRUDER1      1025
 86  #define UI_ACTION_OPS_RETRACTDISTANCE   1026
 87  #define UI_ACTION_OPS_BACKLASH          1027
 88  #define UI_ACTION_OPS_MOVE_AFTER        1028
 89  #define UI_ACTION_OPS_MINDISTANCE       1029
 90  #define UI_ACTION_STORE_EEPROM          1030
 91  #define UI_ACTION_LOAD_EEPROM           1031
 92  #define UI_ACTION_PRINT_ACCEL_X         1032
 93  #define UI_ACTION_PRINT_ACCEL_Y         1033
 94  #define UI_ACTION_PRINT_ACCEL_Z         1034
 95  #define UI_ACTION_MOVE_ACCEL_X          1035
 96  #define UI_ACTION_MOVE_ACCEL_Y          1036
 97  #define UI_ACTION_MOVE_ACCEL_Z          1037
 98  #define UI_ACTION_MAX_JERK              1038
 99  #define UI_ACTION_MAX_ZJERK             1039
100  #define UI_ACTION_BAUDRATE              1040
101  #define UI_ACTION_HOMING_FEEDRATE_X     1041
102  #define UI_ACTION_HOMING_FEEDRATE_Y     1042
103  #define UI_ACTION_HOMING_FEEDRATE_Z     1043
104  #define UI_ACTION_MAX_FEEDRATE_X        1044
105  #define UI_ACTION_MAX_FEEDRATE_Y        1045
106  #define UI_ACTION_MAX_FEEDRATE_Z        1046
107  #define UI_ACTION_STEPS_X               1047
108  #define UI_ACTION_STEPS_Y               1048
109  #define UI_ACTION_STEPS_Z               1049
110  #define UI_ACTION_FAN_OFF               1050
111  #define UI_ACTION_FAN_25                1051
112  #define UI_ACTION_FAN_50                1052
113  #define UI_ACTION_FAN_75                1053
114  #define UI_ACTION_FAN_FULL              1054
115  #define UI_ACTION_FEEDRATE_MULTIPLY     1055
116  #define UI_ACTION_STEPPER_INACTIVE      1056
117  #define UI_ACTION_MAX_INACTIVE          1057
118  #define UI_ACTION_PID_PGAIN             1058
119  #define UI_ACTION_PID_IGAIN             1059
120  #define UI_ACTION_PID_DGAIN             1060
121  #define UI_ACTION_DRIVE_MIN             1061
122  #define UI_ACTION_DRIVE_MAX             1062
123  #define UI_ACTION_X_OFFSET              1063
124  #define UI_ACTION_Y_OFFSET              1064
125  #define UI_ACTION_EXTR_STEPS            1065
126  #define UI_ACTION_EXTR_ACCELERATION     1066
127  #define UI_ACTION_EXTR_MAX_FEEDRATE     1067
128  #define UI_ACTION_EXTR_START_FEEDRATE   1068
129  #define UI_ACTION_EXTR_HEATMANAGER      1069
130  #define UI_ACTION_EXTR_WATCH_PERIOD     1070
131  #define UI_ACTION_PID_MAX               1071
132  #define UI_ACTION_ADVANCE_K             1072
133  #define UI_ACTION_SET_ORIGIN            1073
134  #define UI_ACTION_DEBUG_ECHO            1074
135  #define UI_ACTION_DEBUG_INFO            1075
136  #define UI_ACTION_DEBUG_ERROR           1076
137  #define UI_ACTION_DEBUG_DRYRUN          1077
138  #define UI_ACTION_POWER                 1078
139  #define UI_ACTION_PREHEAT_PLA           1079
140  #define UI_ACTION_COOLDOWN              1080
141  #define UI_ACTION_HEATED_BED_OFF        1081
142  #define UI_ACTION_EXTRUDER0_OFF         1082
143  #define UI_ACTION_EXTRUDER1_OFF         1083
144  #define UI_ACTION_HEATED_BED_TEMP       1084
145  #define UI_ACTION_EXTRUDER0_TEMP        1085
146  #define UI_ACTION_EXTRUDER1_TEMP        1086
147  #define UI_ACTION_OPS_OFF               1087
148  #define UI_ACTION_OPS_CLASSIC           1088
149  #define UI_ACTION_OPS_FAST              1089
150  #define UI_ACTION_DISABLE_STEPPER       1090
151  #define UI_ACTION_RESET_EXTRUDER        1091
152  #define UI_ACTION_EXTRUDER_RELATIVE     1092
153  #define UI_ACTION_SELECT_EXTRUDER0      1093
154  #define UI_ACTION_ADVANCE_L             1094
155  #define UI_ACTION_PREHEAT_ABS           1095
156  #define UI_ACTION_FLOWRATE_MULTIPLY     1096
157  #define UI_ACTION_KILL                  1097
158  #define UI_ACTION_RESET                 1098
159  #define UI_ACTION_PAUSE                 1099
160  #define UI_ACTION_EXTR_WAIT_RETRACT_TEMP 1100
161  #define UI_ACTION_EXTR_WAIT_RETRACT_UNITS 1101
162  
163  #define UI_ACTION_MENU_XPOS             4000
164  #define UI_ACTION_MENU_YPOS             4001
165  #define UI_ACTION_MENU_ZPOS             4002
166  #define UI_ACTION_MENU_XPOSFAST         4003
167  #define UI_ACTION_MENU_YPOSFAST         4004
168  #define UI_ACTION_MENU_ZPOSFAST         4005
169  #define UI_ACTION_MENU_SDCARD           4006
170  #define UI_ACTION_MENU_QUICKSETTINGS    4007
171  #define UI_ACTION_MENU_EXTRUDER         4008
172  #define UI_ACTION_MENU_POSITIONS        4009
173  #define UI_ACTION_SHOW_MEASUREMENT		4010
174  #define UI_ACTION_RESET_MEASUREMENT		4011
175  #define UI_ACTION_SET_MEASURED_ORIGIN	4012
176  #define UI_ACTION_SET_P1				4013
177  #define UI_ACTION_SET_P2				4014
178  #define UI_ACTION_SET_P3				4015
179  #define UI_ACTION_CALC_LEVEL			4016
180  
181  #define UI_ACTION_SHOW_USERMENU1        4101
182  #define UI_ACTION_SHOW_USERMENU2        4102
183  #define UI_ACTION_SHOW_USERMENU3        4103
184  #define UI_ACTION_SHOW_USERMENU4        4104
185  #define UI_ACTION_SHOW_USERMENU5        4105
186  #define UI_ACTION_SHOW_USERMENU6        4106
187  #define UI_ACTION_SHOW_USERMENU7        4107
188  #define UI_ACTION_SHOW_USERMENU8        4108
189  #define UI_ACTION_SHOW_USERMENU9        4109
190  #define UI_ACTION_SHOW_USERMENU10       4110
191  
192  // Load basic language definition to make sure all values are defined
193  #include "uilang.h"
194  
195  #include "Configuration.h"
196  #include <avr/pgmspace.h>
197  #include "fastio.h"
198  
199  typedef struct {
200    const char *text; // Menu text 
201    unsigned char menuType; // 0 = Info, 1 = Headline, 2 = submenu ref, 3 = direct action command, 4 = modify action command
202    unsigned int action;
203  } const UIMenuEntry;
204  
205  typedef struct {
206    // 0 = info page
207    // 1 = file selector
208    // 2 = submenu
209    // 3 = modififaction menu
210    unsigned char menuType;
211    int id; // Type of modification
212    int numEntries;
213    const UIMenuEntry * const * entries;
214  } const UIMenu;
215  extern const int8_t encoder_table[16] PROGMEM ;
216  
217  //#ifdef COMPILE_I2C_DRIVER
218  
219  /************************************************************************* 
220  * Title:    C include file for the I2C master interface 
221  *           (i2cmaster.S or twimaster.c)
222  * Author:   Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury
223  * File:     $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $
224  * Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
225  * Target:   any AVR device
226  * Usage:    see Doxygen manual
227  **************************************************************************/
228  
229  #if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
230  #error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
231  #endif
232  
233  #include <avr/io.h>
234  
235  /** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */
236  #define I2C_READ    1
237  /** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */
238  #define I2C_WRITE   0
239  
240  /** 
241   @brief Terminates the data transfer and releases the I2C bus 
242   @param void
243   @return none
244   */
245  extern void i2c_stop(void);
246  /** 
247   @brief Issues a start condition and sends address and transfer direction 
248    
249   @param    addr address and transfer direction of I2C device
250   @retval   0   device accessible 
251   @retval   1   failed to access device 
252   */
253  extern unsigned char i2c_start(unsigned char addr);
254  /**
255   @brief Issues a start condition and sends address and transfer direction 
256     
257   If device is busy, use ack polling to wait until device ready 
258   @param    addr address and transfer direction of I2C device
259   @return   none
260   */
261  extern void i2c_start_wait(unsigned char addr);
262  /**
263   @brief Send one byte to I2C device
264   @param    data  byte to be transfered
265   @retval   0 write successful
266   @retval   1 write failed
267   */
268  extern unsigned char i2c_write(unsigned char data);
269  /**
270   @brief    read one byte from the I2C device, request more data from device 
271   @return   byte read from I2C device
272   */
273  extern unsigned char i2c_readAck(void);
274  /**
275   @brief    read one byte from the I2C device, read is followed by a stop condition 
276   @return   byte read from I2C device
277   */
278  extern unsigned char i2c_readNak(void);
279  /** 
280   @brief    read one byte from the I2C device
281   
282   Implemented as a macro, which calls either i2c_readAck or i2c_readNak
283   
284   @param    ack 1 send ack, request more data from device<br>
285                 0 send nak, read is followed by a stop condition 
286   @return   byte read from I2C device
287   */
288  extern unsigned char i2c_read(unsigned char ack);
289  #define i2c_read(ack)  (ack) ? i2c_readAck() : i2c_readNak(); 
290  /**@}*/
291  
292  
293  
294  //extern const int matrixActions[] PROGMEM;
295  // Key codes
296  #define UI_KEYS_INIT_CLICKENCODER_LOW(pinA,pinB) SET_INPUT(pinA);SET_INPUT(pinB); WRITE(pinA,HIGH);WRITE(pinB,HIGH);
297  #define UI_KEYS_INIT_BUTTON_LOW(pin) SET_INPUT(pin);WRITE(pin,HIGH);
298  #define UI_KEYS_INIT_CLICKENCODER_HIGH(pinA,pinB) SET_INPUT(pinA);SET_INPUT(pinB); WRITE(pinA,LOW);WRITE(pinB,LOW);
299  #define UI_KEYS_INIT_BUTTON_HIGH(pin) SET_INPUT(pin);WRITE(pin,LOW);
300  
301  #define UI_KEYS_CLICKENCODER_LOW(pinA,pinB)  uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (!READ(pinA)) uid.encoderLast |=2;if (!READ(pinB)) uid.encoderLast |=1; uid.encoderPos += pgm_read_byte(&encoder_table[uid.encoderLast]);
302  #define UI_KEYS_CLICKENCODER_LOW_REV(pinA,pinB)  uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (!READ(pinA)) uid.encoderLast |=2;if (!READ(pinB)) uid.encoderLast |=1; uid.encoderPos -= pgm_read_byte(&encoder_table[uid.encoderLast]);
303  #define UI_KEYS_BUTTON_LOW(pin,action_) if(READ(pin)==0) action=action_;
304  #define UI_KEYS_CLICKENCODER_HIGH(pinA,pinB)  uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (READ(pinA)) uid.encoderLast |=2;if (READ(pinB)) uid.encoderLast |=1; uid.encoderPos += pgm_read_byte(&encoder_table[uid.encoderLast]);
305  #define UI_KEYS_CLICKENCODER_HIGH_REV(pinA,pinB)  uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (READ(pinA)) uid.encoderLast |=2;if (READ(pinB)) uid.encoderLast |=1; uid.encoderPos -= pgm_read_byte(&encoder_table[uid.encoderLast]);
306  #define UI_KEYS_BUTTON_HIGH(pin,action_) if(READ(pin)!=0) action=action_;
307  #define UI_KEYS_INIT_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4) if(c1>=0){SET_INPUT(c1);WRITE(c1,HIGH);}if(c2>=0){SET_INPUT(c2);WRITE(c2,HIGH);}if(c3>=0){SET_INPUT(c3);WRITE(c3,HIGH);}\
308      if(c4>=0) {SET_INPUT(c4);WRITE(c4,HIGH);}if(r1>=0)SET_OUTPUT(r1);if(r2>=0)SET_OUTPUT(r2);if(r3>=0)SET_OUTPUT(r3);if(r4>=0)SET_OUTPUT(r4);\
309      if(r1>=0)WRITE(r1,LOW);if(r2>=0)WRITE(r2,LOW);if(r3>=0)WRITE(r3,LOW);if(r4>=0)WRITE(r4,LOW);
310  //      out.print_int_P(PSTR("r4=>c1:"),READ(c1));out.print_int_P(PSTR(" c2:"),READ(c2));out.print_int_P(PSTR(" c3:"),READ(c3));out.println_int_P(PSTR(" c4:"),READ(c4));
311  #define UI_KEYS_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4) {byte r = (c1>=0?READ(c1):0) && (c2>=0?READ(c2):0) && (c3>=0?READ(c3):0) && (c4>=0?READ(c4):0);\
312      if(!r) {\
313        r = 255;\
314        if(r2>=0)WRITE(r2,HIGH);if(r3>=0)WRITE(r3,HIGH);if(r4>=0)WRITE(r4,HIGH);\
315        if(r1>=0) {\
316          asm volatile ("nop\nnop\nnop\nnop\nnop");\
317          if(!((c1>=0?READ(c1):1) && (c2>=0?READ(c2):1) && (c3>=0?READ(c3):1) && (c4>=0?READ(c4):1))) r = 0;\
318          else WRITE(r1,HIGH);\
319        }\
320        if(r==255 && r2>=0) {\
321          WRITE(r2,LOW);asm volatile ("nop\nnop\nnop\nnop\nnop");\
322          if(!((c1>=0?READ(c1):1) && (c2>=0?READ(c2):1) && (c3>=0?READ(c3):1) && (c4>=0?READ(c4):1))) r = 4;\
323          else WRITE(r2,HIGH);\
324        }\
325        if(r==255 && r3>=0) {\
326          WRITE(r3,LOW);asm volatile ("nop\nnop\nnop\nnop\nnop");\
327          if(!((c1>=0?READ(c1):0) && (c2>=0?READ(c2):1) && (c3>=0?READ(c3):1) && (c4>=0?READ(c4):1))) r = 8;\
328          else WRITE(r3,HIGH);\
329        }\
330        if(r==255 && r4>=0) {\
331          WRITE(r4,LOW);asm volatile ("nop\nnop\nnop\nnop\nnop");\
332          if(!((c1>=0?READ(c1):1) && (c2>=0?READ(c2):1) && (c3>=0?READ(c3):1) && (c4>=0?READ(c4):1))) r = 12;\
333          else WRITE(r4,HIGH);\
334        }\
335        if(c2>=0 && !READ(c2)) r+=1;\
336        else if(c3>=0 && !READ(c3)) r+=2;\
337        else if(c4>=0 && !READ(c4)) r+=3;\
338        if(r<16) {action = pgm_read_word(&(matrixActions[r]));}\
339      }if(r1>=0)WRITE(r1,LOW);if(r2>=0)WRITE(r2,LOW);if(r3>=0)WRITE(r3,LOW);if(r4>=0)WRITE(r4,LOW);}
340  // I2C keymask tests
341  #define UI_KEYS_I2C_CLICKENCODER_LOW(pinA,pinB)  uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (!(keymask & pinA)) uid.encoderLast |=2;if (!(keymask & pinB)) uid.encoderLast |=1; uid.encoderPos += pgm_read_byte(&encoder_table[uid.encoderLast]);
342  #define UI_KEYS_I2C_CLICKENCODER_LOW_REV(pinA,pinB)  uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (!(keymask & pinA)) uid.encoderLast |=2;if (!(keymask & pinB)) uid.encoderLast |=1; uid.encoderPos -= pgm_read_byte(&encoder_table[uid.encoderLast]);
343  #define UI_KEYS_I2C_BUTTON_LOW(pin,action_) if((keymask & pin)==0) action=action_;
344  #define UI_KEYS_I2C_CLICKENCODER_HIGH(pinA,pinB)  uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (keymask & pinA) uid.encoderLast |=2;if (keymask & pinB) uid.encoderLast |=1; uid.encoderPos += pgm_read_byte(&encoder_table[uid.encoderLast]);
345  #define UI_KEYS_I2C_CLICKENCODER_HIGH_REV(pinA,pinB)  uid.encoderLast = (uid.encoderLast << 2) & 0x0F;if (keymask & pinA) uid.encoderLast |=2;if (keymask & pinB) uid.encoderLast |=1; uid.encoderPos -= pgm_read_byte(&encoder_table[uid.encoderLast]);
346  #define UI_KEYS_I2C_BUTTON_HIGH(pin,action_) if((pin & keymask)!=0) action=action_;
347  
348  #define UI_STRING(name,text) const char PROGMEM name[] = text;
349  
350  #define UI_PAGE4(name,row1,row2,row3,row4) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);UI_STRING(name ## _3txt,row3);UI_STRING(name ## _4txt,row4);\
351    UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0};\
352    UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0};\
353    UIMenuEntry name ## _3 PROGMEM ={name ## _3txt,0,0};\
354    UIMenuEntry name ## _4 PROGMEM ={name ## _4txt,0,0};\
355    const UIMenuEntry * const name ## _entries [] PROGMEM = {&name ## _1,&name ## _2,&name ## _3,&name ## _4};\
356    const UIMenu name PROGMEM = {0,0,4,name ## _entries};
357  #define UI_PAGE2(name,row1,row2) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);\
358    UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0};\
359    UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0};\
360    const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2};\
361    const UIMenu name PROGMEM = {0,0,2,name ## _entries};
362  #define UI_MENU_ACTION4C(name,action,rows) UI_MENU_ACTION4(name,action,rows)
363  #define UI_MENU_ACTION2C(name,action,rows) UI_MENU_ACTION2(name,action,rows)
364  #define UI_MENU_ACTION4(name,action,row1,row2,row3,row4) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);UI_STRING(name ## _3txt,row3);UI_STRING(name ## _4txt,row4);\
365    UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0};\
366    UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0};\
367    UIMenuEntry name ## _3 PROGMEM ={name ## _3txt,0,0};\
368    UIMenuEntry name ## _4 PROGMEM ={name ## _4txt,0,0};\
369    const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2,&name ## _3,&name ## _4};\
370    const UIMenu name PROGMEM = {3,action,4,name ## _entries};
371  #define UI_MENU_ACTION2(name,action,row1,row2) UI_STRING(name ## _1txt,row1);UI_STRING(name ## _2txt,row2);\
372    UIMenuEntry name ## _1 PROGMEM ={name ## _1txt,0,0};\
373    UIMenuEntry name ## _2 PROGMEM ={name ## _2txt,0,0};\
374    const UIMenuEntry * const name ## _entries[] PROGMEM = {&name ## _1,&name ## _2};\
375    const UIMenu name PROGMEM = {3,action,2,name ## _entries};
376  #define UI_MENU_HEADLINE(name,text) UI_STRING(name ## _txt,text);UIMenuEntry name PROGMEM = {name ## _txt,1,0};
377  #define UI_MENU_CHANGEACTION(name,row,action) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,4,action};
378  #define UI_MENU_ACTIONCOMMAND(name,row,action) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,3,action};
379  #define UI_MENU_ACTIONSELECTOR(name,row,entries) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,2,(unsigned int)&entries};
380  #define UI_MENU_SUBMENU(name,row,entries) UI_STRING(name ## _txt,row);UIMenuEntry name PROGMEM = {name ## _txt,2,(unsigned int)&entries};
381  #define UI_MENU(name,items,itemsCnt) const UIMenuEntry * const name ## _entries[] PROGMEM = items;const UIMenu name PROGMEM = {2,0,itemsCnt,name ## _entries}
382  #define UI_MENU_FILESELECT(name,items,itemsCnt) const UIMenuEntry * const name ## _entries[]  PROGMEM = items;const UIMenu name PROGMEM = {1,0,itemsCnt,name ## _entries}
383  
384  #if FEATURE_CONTROLLER==2 // reprapdiscount smartcontroller has a sd card buildin 
385  #undef SDCARDDETECT
386  #define SDCARDDETECT 49
387  #undef SDCARDDETECTINVERTED
388  #define SDCARDDETECTINVERTED false
389  #undef SDSUPPORT
390  #define SDSUPPORT true
391  #endif
392  
393  class UIDisplay {
394    public:
395      volatile byte flags; // 1 = fast key action, 2 = slow key action, 4 = slow action running, 8 = key test running
396      byte col; // current col for buffer prefill
397      byte menuLevel; // current menu level, 0 = info, 1 = group, 2 = groupdata select, 3 = value change
398      byte menuPos[5]; // Positions in menu
399      void *menu[5]; // Menus active
400      byte menuTop[5]; // Top row in menu
401      int pageDelay; // Counter. If 0 page is refreshed if menuLevel is 0.
402      void *errorMsg;
403      unsigned int activeAction; // action for ok/next/previous
404      unsigned int lastAction;
405      unsigned long lastSwitch; // Last time display switched pages
406      unsigned long lastRefresh;
407      unsigned int lastButtonAction;
408      unsigned long lastButtonStart;
409      unsigned long nextRepeat; // Time of next autorepeat
410      unsigned int outputMask; // Output mask for backlight, leds etc.
411      int repeatDuration; // Time beween to actions if autorepeat is enabled
412      void addInt(int value,byte digits); // Print int into printCols
413      void addLong(long value,char digits);
414      void addFloat(float number, char fixdigits,byte digits);
415      void addStringP(PGM_P text);
416      void okAction();
417      void nextPreviousAction(char next);
418      char statusMsg[17];
419      char encoderPos;
420      int8_t encoderLast;
421      PGM_P statusText;
422      UIDisplay();
423      void createChar(byte location,const byte charmap[]);
424      void initialize(); // Initialize display and keys
425      void printRow(byte r,char *txt); // Print row on display
426      void printRowP(byte r,PGM_P txt);
427      void parse(char *txt,bool ram); /// Parse output and write to printCols;
428      void refreshPage();
429      void executeAction(int action);
430      void finishAction(int action);
431      void slowAction();
432      void fastAction();
433      void mediumAction();
434      void pushMenu(void *men,bool refresh);
435      void setStatusP(PGM_P txt);
436      void setStatus(char *txt);
437      inline void setOutputMaskBits(unsigned int bits) {outputMask|=bits;}
438      inline void unsetOutputMaskBits(unsigned int bits) {outputMask&=~bits;}
439  #if SDSUPPORT
440      void updateSDFileCount();
441      void sdrefresh(byte &r);
442      void goDir(char *name);
443      bool isDirname(char *name);
444      char cwd[SD_MAX_FOLDER_DEPTH*13+2];
445      byte folderLevel;
446  #endif
447  };
448  extern UIDisplay uid;
449  
450  
451  #if FEATURE_CONTROLLER==1
452  #include "uiconfig.h"
453  #endif
454  #if FEATURE_CONTROLLER==0 // No controller at all
455  #define UI_HAS_KEYS 0
456  #define UI_DISPLAY_TYPE 0
457  #ifdef UI_MAIN
458  void ui_init_keys() {}
459  void ui_check_keys(int &action) {}
460  inline void ui_check_slow_encoder() {}
461  void ui_check_slow_keys(int &action) {}
462  #endif
463  #endif
464  #if FEATURE_CONTROLLER==2 // reprapdiscount smartcontroller
465  #define UI_HAS_KEYS 1
466  #define UI_HAS_BACK_KEY 0
467  #define UI_DISPLAY_TYPE 1
468  #define UI_DISPLAY_CHARSET 1
469  #define BEEPER_TYPE 1
470  #define UI_COLS 20
471  #define UI_ROWS 4
472  #if MOTHERBOARD==80 // Rumba has different pins as RAMPS!
473  #define BEEPER_PIN             44
474  #define UI_DISPLAY_RS_PIN      19
475  #define UI_DISPLAY_RW_PIN      -1
476  #define UI_DISPLAY_ENABLE_PIN  42
477  #define UI_DISPLAY_D0_PIN      18
478  #define UI_DISPLAY_D1_PIN      38
479  #define UI_DISPLAY_D2_PIN      41
480  #define UI_DISPLAY_D3_PIN      40
481  #define UI_DISPLAY_D4_PIN      18
482  #define UI_DISPLAY_D5_PIN      38
483  #define UI_DISPLAY_D6_PIN      41
484  #define UI_DISPLAY_D7_PIN      40
485  #define UI_ENCODER_A           12
486  #define UI_ENCODER_B           11
487  #define UI_ENCODER_CLICK       43
488  #define UI_RESET_PIN           46
489  #else
490  #define BEEPER_PIN             37
491  #define UI_DISPLAY_RS_PIN      16
492  #define UI_DISPLAY_RW_PIN      -1
493  #define UI_DISPLAY_ENABLE_PIN  17
494  #define UI_DISPLAY_D0_PIN      23
495  #define UI_DISPLAY_D1_PIN      25
496  #define UI_DISPLAY_D2_PIN      27
497  #define UI_DISPLAY_D3_PIN      29
498  #define UI_DISPLAY_D4_PIN      23
499  #define UI_DISPLAY_D5_PIN      25
500  #define UI_DISPLAY_D6_PIN      27
501  #define UI_DISPLAY_D7_PIN      29
502  #define UI_ENCODER_A           33
503  #define UI_ENCODER_B           31
504  #define UI_ENCODER_CLICK       35
505  #define UI_RESET_PIN           41
506  #endif
507  #define UI_DELAYPERCHAR 320
508  #define UI_INVERT_MENU_DIRECTION false
509  #ifdef UI_MAIN
510  void ui_init_keys() {  
511    UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A,UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals.
512    UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK); // push button, connects gnd to pin
513    UI_KEYS_INIT_BUTTON_LOW(UI_RESET_PIN); // Kill pin
514  }
515  void ui_check_keys(int &action) {
516   UI_KEYS_CLICKENCODER_LOW_REV(UI_ENCODER_A,UI_ENCODER_B); // click encoder on pins 47 and 45. Phase is connected with gnd for signals.
517   UI_KEYS_BUTTON_LOW(UI_ENCODER_CLICK,UI_ACTION_OK); // push button, connects gnd to pin
518   UI_KEYS_BUTTON_LOW(UI_RESET_PIN,UI_ACTION_RESET); 
519  }
520  inline void ui_check_slow_encoder() {}
521  void ui_check_slow_keys(int &action) {}
522  #endif
523  #endif // Controller 2
524  
525  #if FEATURE_CONTROLLER==3 // Adafruit RGB controller
526  #define UI_HAS_KEYS 1
527  #define UI_HAS_BACK_KEY 1
528  #define UI_DISPLAY_TYPE 3
529  #define UI_DISPLAY_CHARSET 1
530  #define UI_COLS 16
531  #define UI_ROWS 2
532  #define UI_DISPLAY_I2C_CHIPTYPE 1
533  #define UI_DISPLAY_I2C_ADDRESS 0x40
534  #define UI_DISPLAY_I2C_OUTPUT_PINS 65504
535  #define UI_DISPLAY_I2C_OUTPUT_START_MASK 0
536  #define UI_DISPLAY_I2C_PULLUP 31
537  #define UI_I2C_CLOCKSPEED 400000L
538  #define UI_DISPLAY_RS_PIN _BV(15)
539  #define UI_DISPLAY_RW_PIN _BV(14)
540  #define UI_DISPLAY_ENABLE_PIN _BV(13)
541  #define UI_DISPLAY_D0_PIN _BV(12)
542  #define UI_DISPLAY_D1_PIN _BV(11)
543  #define UI_DISPLAY_D2_PIN _BV(10)
544  #define UI_DISPLAY_D3_PIN _BV(9)
545  #define UI_DISPLAY_D4_PIN _BV(12)
546  #define UI_DISPLAY_D5_PIN _BV(11)
547  #define UI_DISPLAY_D6_PIN _BV(10)
548  #define UI_DISPLAY_D7_PIN _BV(9)
549  #define UI_INVERT_MENU_DIRECTION true
550  #define UI_HAS_I2C_KEYS
551  #define UI_HAS_I2C_ENCODER 0
552  #define UI_I2C_KEY_ADDRESS 0x40
553  #ifdef UI_MAIN
554  void ui_init_keys() {}
555  void ui_check_keys(int &action) {}
556  inline void ui_check_slow_encoder() {
557    i2c_start_wait(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE);
558    i2c_write(0x12); // GIOA
559    i2c_stop();
560    i2c_start_wait(UI_DISPLAY_I2C_ADDRESS+I2C_READ);
561    unsigned int keymask = i2c_readAck();
562    keymask = keymask + (i2c_readNak()<<8);
563    i2c_stop();
564  }
565  void ui_check_slow_keys(int &action) {
566    i2c_start_wait(UI_DISPLAY_I2C_ADDRESS+I2C_WRITE);
567    i2c_write(0x12); // GPIOA
568    i2c_stop();
569    i2c_start_wait(UI_DISPLAY_I2C_ADDRESS+I2C_READ);
570    unsigned int keymask = i2c_readAck();
571    keymask = keymask + (i2c_readNak()<<8);
572    i2c_stop();
573    UI_KEYS_I2C_BUTTON_LOW(4,UI_ACTION_PREVIOUS); // Up button
574    UI_KEYS_I2C_BUTTON_LOW(8,UI_ACTION_NEXT); // down button
575    UI_KEYS_I2C_BUTTON_LOW(16,UI_ACTION_BACK); // left button
576    UI_KEYS_I2C_BUTTON_LOW(2,UI_ACTION_OK); // right button
577    UI_KEYS_I2C_BUTTON_LOW(1,UI_ACTION_MENU_QUICKSETTINGS);  //Select button
578  }
579  #endif
580  #endif // Controller 3
581  
582  #if FEATURE_CONTROLLER==4 // Foltyn 3D Master
583  #define UI_HAS_KEYS 1
584  #define UI_HAS_BACK_KEY 1
585  #define UI_DISPLAY_TYPE 1
586  #define UI_DISPLAY_CHARSET 2
587  #define UI_COLS 20
588  #define UI_ROWS 4
589  #define UI_DISPLAY_RS_PIN		63		// PINK.1, 88, D_RS
590  #define UI_DISPLAY_RW_PIN		-1
591  #define UI_DISPLAY_ENABLE_PIN	        65		// PINK.3, 86, D_E
592  #define UI_DISPLAY_D0_PIN		59		// PINF.5, 92, D_D4
593  #define UI_DISPLAY_D1_PIN		64		// PINK.2, 87, D_D5
594  #define UI_DISPLAY_D2_PIN		44		// PINL.5, 40, D_D6
595  #define UI_DISPLAY_D3_PIN		66		// PINK.4, 85, D_D7
596  #define UI_DISPLAY_D4_PIN		59		// PINF.5, 92, D_D4
597  #define UI_DISPLAY_D5_PIN		64		// PINK.2, 87, D_D5
598  #define UI_DISPLAY_D6_PIN		44		// PINL.5, 40, D_D6
599  #define UI_DISPLAY_D7_PIN		66		// PINK.4, 85, D_D7
600  #define UI_DELAYPERCHAR		   320
601  #define UI_INVERT_MENU_DIRECTION false
602  #ifdef UI_MAIN
603  void ui_init_keys() {  
604    UI_KEYS_INIT_BUTTON_LOW(4); // push button, connects gnd to pin
605    UI_KEYS_INIT_BUTTON_LOW(5);
606    UI_KEYS_INIT_BUTTON_LOW(6);
607    UI_KEYS_INIT_BUTTON_LOW(11);
608    UI_KEYS_INIT_BUTTON_LOW(42);
609  }
610  void ui_check_keys(int &action) {
611   UI_KEYS_BUTTON_LOW(4,UI_ACTION_OK); // push button, connects gnd to pin
612   UI_KEYS_BUTTON_LOW(5,UI_ACTION_NEXT); // push button, connects gnd to pin
613   UI_KEYS_BUTTON_LOW(6,UI_ACTION_PREVIOUS); // push button, connects gnd to pin
614   UI_KEYS_BUTTON_LOW(11,UI_ACTION_BACK); // push button, connects gnd to pin
615   UI_KEYS_BUTTON_LOW(42,UI_ACTION_SD_PRINT ); // push button, connects gnd to pin
616  }
617  inline void ui_check_slow_encoder() {}
618  void ui_check_slow_keys(int &action) {}
619  #endif
620  #endif // Controller 4
621  
622  
623  #if FEATURE_CONTROLLER>0
624  
625  #if UI_ROWS==4
626  #if UI_COLS==16
627  #define UI_LINE_OFFSETS {0,0x40,0x10,0x50} // 4x16
628  #elif UI_COLS==20
629  //#define UI_LINE_OFFSETS {0,0x20,0x40,0x60} // 4x20 with KS0073
630  #define UI_LINE_OFFSETS {0,0x40,0x14,0x54} // 4x20 with HD44780
631  #else
632  #error Unknown combination off rows/columns - define UI_LINE_OFFSETS manually.
633  #endif
634  #else
635  #define UI_LINE_OFFSETS {0,0x40,0x10,0x50} // 2x16, 2x20, 2x24
636  #endif
637  #include "uilang.h"
638  #include "uimenu.h"
639  #endif
640  
641  #define UI_VERSION_STRING "Repetier " REPETIER_VERSION
642  
643  #ifdef UI_HAS_I2C_KEYS
644  #define COMPILE_I2C_DRIVER
645  #endif
646  
647  #if UI_DISPLAY_TYPE!=0
648  
649  
650  #if UI_DISPLAY_TYPE==3
651  #define COMPILE_I2C_DRIVER
652  #endif
653  
654  #ifndef UI_TEMP_PRECISION
655  #if UI_COLS>16
656  #define UI_TEMP_PRECISION 1
657  #else
658  #define UI_TEMP_PRECISION 0
659  #endif
660  #endif
661  
662  #define UI_INITIALIZE uid.initialize();
663  #define UI_FAST if(pwm_count & 4) {uid.fastAction();}
664  #define UI_MEDIUM uid.mediumAction();
665  #define UI_SLOW uid.slowAction();
666  #define UI_STATUS(status) uid.setStatusP(PSTR(status));
667  #define UI_STATUS_UPD(status) {uid.setStatusP(PSTR(status));uid.refreshPage();}
668  #define UI_STATUS_RAM(status) uid.setStatus(status);
669  #define UI_STATUS_UPD_RAM(status) {uid.setStatus(status);uid.refreshPage();}
670  #define UI_ERROR(msg) {uid.errorMsg=(void*)STR(msg);pushMenu((void*)&ui_menu_error,true);}
671  #define UI_CLEAR_STATUS {uid.statusMsg[0]=0;}
672  #else
673  #define UI_INITIALIZE {}
674  #define UI_FAST {}
675  #define UI_MEDIUM {}
676  #define UI_SLOW {}
677  #define UI_STATUS(status) {}
678  #define UI_STATUS_UPD(status) {}
679  #define UI_CLEAR_STATUS {}
680  #define UI_ERROR(msg) {}
681  #define UI_STATUS_UPD_RAM(status) {}
682  #endif  // Display
683  
684  // Beeper methods
685  #if BEEPER_TYPE==0
686  #define BEEP_SHORT {}
687  #define BEEP_LONG {}
688  #else
689  #define BEEP_SHORT beep(BEEPER_SHORT_SEQUENCE);
690  #define BEEP_LONG beep(BEEPER_LONG_SEQUENCE);
691  #endif
692  extern void beep(byte duration,byte count);
693  
694  #endif
695