diff --git a/config/board.metadata b/config/board.metadata new file mode 100644 index 0000000..9b36e2c --- /dev/null +++ b/config/board.metadata @@ -0,0 +1,223 @@ + +/***************************************************************************\ +* * +* 1. CPU * +* * +\***************************************************************************/ + +/** \def CPU_TYPE + CPU types a user should be able to choose from in configtool. All + commented out. +*/ +//#define CPU_TYPE atmega1280 +//#define CPU_TYPE atmega2560 + +/** \def CPU + CPU actually present on the board. +*/ +#define CPU atmega2560 + +/** \def F_CPU_OPT + CPU clock frequencies a user should be able to choose from in configtool. + All commented out. +*/ +//#define F_CPU_OPT 16000000UL + +/** \def F_CPU + Actual CPU clock rate. #ifndef required for Arduino compatibility. +*/ +#ifndef F_CPU +#define F_CPU 16000000UL +#endif + +/** \def MOTHERBOARD + This is the motherboard, as opposed to the extruder. See extruder/ directory + for GEN3 extruder firmware. +*/ +#define MOTHERBOARD + + +/***************************************************************************\ +* * +* 2. PINOUTS * +* * +\***************************************************************************/ + +#define X_STEP_PIN +#define X_DIR_PIN +#define X_MIN_PIN +#define X_MAX_PIN +#define X_ENABLE_PIN +#define X_INVERT_DIR +#define X_INVERT_MIN +#define X_INVERT_MAX +#define X_INVERT_ENABLE + +#define Y_STEP_PIN +#define Y_DIR_PIN +#define Y_MIN_PIN +#define Y_MAX_PIN +#define Y_ENABLE_PIN +#define Y_INVERT_DIR +#define Y_INVERT_MIN +#define Y_INVERT_MAX +#define Y_INVERT_ENABLE + +#define Z_STEP_PIN +#define Z_DIR_PIN +#define Z_MIN_PIN +#define Z_MAX_PIN +#define Z_ENABLE_PIN +#define Z_INVERT_DIR +#define Z_INVERT_MIN +#define Z_INVERT_MAX +#define Z_INVERT_ENABLE + +#define E_STEP_PIN +#define E_DIR_PIN +#define E_ENABLE_PIN +#define E_INVERT_DIR +#define E_INVERT_ENABLE + +#define PS_ON_PIN +#define PS_MOSFET_PIN +#define STEPPER_ENABLE_PIN +#define STEPPER_INVERT_ENABLE + +/** \def DEBUG_LED_PIN + + Enable flashing of a LED during motor stepping. + + Disabled by default. Uncommenting this makes the binary a few bytes larger + and adds a few cycles to the step timing interrrupt in timer.c. Also used + for precision profiling (profiling works even without actually having such + a LED in hardware), see + http://reprap.org/wiki/Teacup_Firmware#Doing_precision_profiling +*/ +#define DEBUG_LED_PIN + + +/***************************************************************************\ +* * +* 3. TEMPERATURE SENSORS * +* * +\***************************************************************************/ + +/** \def TEMP_MAX6675 TEMP_THERMISTOR TEMP_AD595 TEMP_PT100 TEMP_INTERCOM + Which temperature sensor types are you using? Leave all used ones + uncommented, comment out all others to save binary size and enhance + performance. +*/ +#define TEMP_MAX6675 +#define TEMP_THERMISTOR +#define TEMP_AD595 +#define TEMP_PT100 +#define TEMP_INTERCOM + +/** \def TEMP_SENSOR_PIN + Temperature sensor pins a user should be able to choose from in configtool. + All commented out. +*/ +//#define TEMP_SENSOR_PIN AIO13 +//#define TEMP_SENSOR_PIN AIO14 +//#define TEMP_SENSOR_PIN AIO15 + +/** \def DEFINE_TEMP_SENSOR + Define your temperature sensors here. One line for each sensor, only + limited by the number of available ATmega pins. + + Name must match the name of the corresponding heater. If a heater "extruder" + exists, a temperature sensor of that name has to exist as well. Same for + heater "bed". There can be one sensor without corresponding heater, name it + "noheater". + + Types are same as TEMP_ list above - TT_MAX6675, TT_THERMISTOR, TT_AD595, + TT_PT100, TT_INTERCOM. See list in temp.c. + + The "additional" field is used for TT_THERMISTOR only. It defines the + name of the table(s) in thermistortable.h to use. This name is arbitrary, + often used names include THERMISTOR_EXTRUDER and THERMISTOR_BED. Also, + several sensors can share the same table, which saves binary size. + + For a GEN3 set temp_type to TT_INTERCOM and temp_pin to AIO0. The pin + won't be used in this case. +*/ +//DEFINE_TEMP_SENSORS_START +//DEFINE_TEMP_SENSORS_END + + +/***************************************************************************\ +* * +* 4. HEATERS * +* * +\***************************************************************************/ + +/** \def HEATER_PIN + Heater pins a user should be able to choose from in configtool. All + commented out. +*/ +//#define HEATER_PIN DIO4 +//#define HEATER_PIN DIO5 +//#define HEATER_PIN DIO8 +//#define HEATER_PIN DIO9 +//#define HEATER_PIN DIO10 + +/** \def DEFINE_HEATER + Define your heaters and devices here. + + To attach a heater to a temp sensor above, simply use exactly the same + name - copy+paste is your friend. Some common names are 'extruder', + 'bed', 'fan', 'motor', ... names with special meaning can be found + in gcode_process.c. Currently, these are: + HEATER_extruder (M104) + HEATER_bed (M140) + HEATER_fan (M106) + + Devices don't neccessarily have a temperature sensor, e.g. fans or + milling spindles. Operate such devices by setting their power (M106), + instead of setting their temperature (M104). + + Also note, the index of a heater (M106 P#) can differ from the index of + its attached temperature sensor (M104 P#) in case sensor-less devices + are defined or the order of the definitions differs. The first defined + device has the index 0 (zero). + + Set 'pwm' to ... + 1 for using PWM on a PWM-able pin and on/off on other pins. + 0 for using on/off on a PWM-able pin, too. + + Using PWM usually gives smoother temperature control but can conflict + with slow switches, like solid state relays. PWM frequency can be + influenced globally with FAST_PWM, see below. +*/ +//DEFINE_HEATERS_START +//DEFINE_HEATERS_END + + +/***************************************************************************\ +* * +* 5. COMMUNICATION OPTIONS * +* * +\***************************************************************************/ + +/** \def BAUD + Baud rate for the serial RS232 protocol connection to the host. Usually + 115200, other common values are 19200, 38400 or 57600. Ignored when USB_SERIAL + is defined. +*/ +#define BAUD + +/** \def XONXOFF + Xon/Xoff flow control. + + Redundant when using RepRap Host for sending G-code, but mandatory when + sending G-code files with a plain terminal emulator, like GtkTerm (Linux), + CoolTerm (Mac) or HyperTerminal (Windows). +*/ +#define XONXOFF + +/** \def USB_SERIAL + Define this for using USB instead of the serial RS232 protocol. Works on + USB-equipped ATmegas, like the ATmega32U4, only. +*/ +#define USB_SERIAL diff --git a/config/printer.metadata b/config/printer.metadata new file mode 100644 index 0000000..3e77955 --- /dev/null +++ b/config/printer.metadata @@ -0,0 +1,327 @@ + +/***************************************************************************\ +* * +* 6. MECHANICAL/HARDWARE * +* * +\***************************************************************************/ + +/** \def KINEMATICS_STRAIGHT KINEMATICS_COREXY + This defines the type of kinematics your printer uses. That's essential! + + Valid values (see dda_kinematics.h): + + KINEMATICS_STRAIGHT + Motors move axis directions directly. This is the + traditional type, found in many printers, including + Mendel, Prusa i3, Mendel90, Ormerod, Mantis. + + KINEMATICS_COREXY + A bot using CoreXY kinematics. Typical for CoreXY + are long and crossing toothed belts and a print head + moving on the X-Y-plane. +*/ +#define KINEMATICS + +/** \def STEPS_PER_M_X STEPS_PER_M_Y STEPS_PER_M_Z STEPS_PER_M_E + Steps per meter ( = steps per mm * 1000 ), calculate these values + appropriate for your machine. + + All numbers are integers, so no decimal point, please :-) + + Valid range: 20 to 4'0960'000 (0.02 to 40960 steps/mm) +*/ +#define STEPS_PER_M_X +#define STEPS_PER_M_Y +#define STEPS_PER_M_Z +#define STEPS_PER_M_E + +/** \def MAXIMUM_FEEDRATE_X MAXIMUM_FEEDRATE_Y MAXIMUM_FEEDRATE_Z MAXIMUM_FEEDRATE_E + Used for G0 rapid moves and as a cap for all other feedrates. +*/ +#define MAXIMUM_FEEDRATE_X +#define MAXIMUM_FEEDRATE_Y +#define MAXIMUM_FEEDRATE_Z +#define MAXIMUM_FEEDRATE_E + +/** \def SEARCH_FEEDRATE_X SEARCH_FEEDRATE_Y SEARCH_FEEDRATE_Z + Used when doing precision endstop search and as default feedrate. No + SEARCH_FEEDRATE_E, as E can't be searched. +*/ +#define SEARCH_FEEDRATE_X +#define SEARCH_FEEDRATE_Y +#define SEARCH_FEEDRATE_Z + +/** \def ENDSTOP_CLEARANCE_X ENDSTOP_CLEARANCE_Y ENDSTOP_CLEARANCE_Z + + When hitting an endstop, Teacup properly decelerates instead of doing an + aprupt stop to save your mechanics. Ineviteably, this means it overshoots + the endstop trigger point by some distance. + + To deal with this, Teacup adapts homing movement speeds to what your + endstops can deal with. The higher the allowed acceleration ( = deceleration, + see #define ACCELERATION) and the more clearance the endstop comes with, + the faster Teacup will do homing movements. + + Set here how many micrometers (mm * 1000) your endstop allows the carriage + to overshoot the trigger point. Typically 1000 or 2000 for mechanical + endstops, more for optical ones. You can set it to zero, in which case + SEARCH_FEEDRATE_{XYZ} is used, but expect very slow homing movements. + + Units: micrometers + Sane values: 0 to 20000 (0 to 20 mm) + Valid range: 0 to 1000000 +*/ +#define ENDSTOP_CLEARANCE_X +#define ENDSTOP_CLEARANCE_Y +#define ENDSTOP_CLEARANCE_Z + +/** \def X_MIN X_MAX Y_MIN Y_MAX Z_MIN Z_MAX + Soft axis limits. Define them to your machine's size relative to what your + G-code considers to be the origin (typically the bed's center or the bed's + front left corner). + + Note that relocating the origin at runtime with G92 will also relocate these + limits. + + Not defining them at all will disable limits checking and make the binary + about 250 bytes smaller. Enabling only some of them is perfectly fine. + + Units: millimeters + Sane values: according to printer build room size + Valid range: -1000.0 to 1000.0 +*/ +#define X_MIN +#define X_MAX + +#define Y_MIN +#define Y_MAX + +#define Z_MIN +#define Z_MAX + +/** \def E_ABSOLUTE + Some G-code creators produce relative length commands for the extruder, + others absolute ones. G-code using absolute lengths can be recognized when + there are G92 E0 commands from time to time. If you have G92 E0 in your + G-code, define this flag. + + This is the startup default and can be changed with M82/M83 while running. +*/ +#define E_ABSOLUTE + +/** \def ACCELERATION_REPRAP ACCELERATION_RAMPING ACCELERATION_TEMPORAL + Choose optionally one of ACCELERATION_REPRAP, ACCELERATION_RAMPING or + ACCELERATION_TEMPORAL. With none of them defined, movements are done + without acceleration. Recommended is ACCELERATION_RAMPING. +*/ +#define ACCELERATION_REPRAP +#define ACCELERATION_RAMPING +#define ACCELERATION_TEMPORAL + +/** \def ACCELERATION + How fast to accelerate when using ACCELERATION_RAMPING. Start with 10 for + milling (high precision) or 1000 for printing. + + Units: mm/s^2 + Useful range: 1 to 10'000 +*/ +#define ACCELERATION + +/** \def LOOKAHEAD + Define this to enable look-ahead during *ramping* acceleration to smoothly + transition between moves instead of performing a dead stop every move. + Enabling look-ahead requires about 3600 bytes of flash memory. +*/ +#define LOOKAHEAD + +/** \def MAX_JERK_X MAX_JERK_Y MAX_JERK_Z MAX_JERK_E + When performing look-ahead, we need to decide what an acceptable jerk to the + mechanics is. Look-ahead attempts to instantly change direction at movement + crossings, which means instant changes in the speed of the axes participating + in the movement. Define here how big the speed bumps on each of the axes is + allowed to be. + + If you want a full stop before and after moving a specific axis, define + MAX_JERK of this axis to 0. This is often wanted for the Z axis. If you want + to ignore jerk on an axis, define it to twice the maximum feedrate of this + axis. + + Having these values too low results in more than neccessary slowdown at + movement crossings, but is otherwise harmless. Too high values can result + in stepper motors suddenly stalling. If angles between movements in your + G-code are small and your printer runs through entire curves full speed, + there's no point in raising the values. + + Units: mm/min + Sane values: 0 to 400 + Valid range: 0 to 65535 +*/ +#define MAX_JERK_X +#define MAX_JERK_Y +#define MAX_JERK_Z +#define MAX_JERK_E + + +/***************************************************************************\ +* * +* 7. MISCELLANEOUS OPTIONS * +* * +\***************************************************************************/ + +/** \def USE_INTERNAL_PULLUPS + The ATmega has internal pullup resistors on it's input pins which are + counterproductive with the commonly used eletronic endstops, so they should + be switched off. For other endstops, like mechanical ones, you may want to + uncomment this. +*/ +#define USE_INTERNAL_PULLUPS + +/** \def TEMP_HYSTERESIS + Actual temperature must be target +/- this hysteresis before target + temperature is considered to be achieved. Also, BANG_BANG tries to stay + within half of this hysteresis. + + Unit: degree Celsius +*/ +#define TEMP_HYSTERESIS + +/** \def TEMP_RESIDENCY_TIME + Actual temperature must be close to target (within set temperature + +- TEMP_HYSTERESIS) for this long before target is achieved (and a M116 + succeeds). + + Unit: seconds +*/ +#define TEMP_RESIDENCY_TIME + +/** \def TEMP_EWMA + Smooth noisy temperature sensors. Good hardware shouldn't be noisy. Set to + 1.0 for unfiltered data (and a 140 bytes smaller binary). + + Instrument Engineer's Handbook, 4th ed, Vol 2 p126 says values of + 0.05 to 0.1 are typical. Smaller is smoother but slower adjusting, larger is + quicker but rougher. If you need to use this, set the PID parameter to zero + (M132 S0) to make the PID loop insensitive to noise. + + Valid range: 0.001 to 1.0 +*/ +#define TEMP_EWMA + +/** \def REPORT_TARGET_TEMPS + With this enabled, M105 commands will return the current temperatures along + with the target temps, separated by a slash: ok T:xxx.x/xxx.x B:xxx.x/xxx.x + With this disabled, only temps will be returned: ok T:xxx.x B:xxx.x + Enabling adds 78 bytes to the image. +*/ +#define REPORT_TARGET_TEMPS + +/** \def HEATER_SANITY_CHECK + Check if heater responds to changes in target temperature, disable and spit + errors if not largely untested, please comment in forum if this works, or + doesn't work for you! +*/ +#define HEATER_SANITY_CHECK + +/** \def EECONFIG + Enable EEPROM configuration storage. + + Enabled by default. Commenting this out makes the binary several hundred + bytes smaller, so you might want to disable EEPROM storage on small MCUs, + like the ATmega168. +*/ +#define EECONFIG + +/** \def BANG_BANG + Drops PID loop from heater control, reduces code size significantly + (1300 bytes!). +*/ +#define BANG_BANG + +/** \def BANG_BANG_ON + PWM value for Bang Bang 'on'. +*/ +#define BANG_BANG_ON + +/** \def BANG_BANG_OFF + PWM value for Bang Bang 'off'. +*/ +#define BANG_BANG_OFF + +/** \def MOVEBUFFER_SIZE + Move buffer size, in number of moves. + + Note that each move takes a fair chunk of ram (107 bytes as of this writing), + so don't make the buffer too big. However, a larger movebuffer will probably + help with lots of short consecutive moves, as each move takes a bunch of + math (hence time) to set up so a longer buffer allows more of the math to + be done during preceding longer moves. +*/ +#define MOVEBUFFER_SIZE + +/** \def DC_EXTRUDER DC_EXTRUDER_PWM + If you have a DC motor extruder, configure it as a "heater" above and define + this value as the index or name. You probably also want to comment out + E_STEP_PIN and E_DIR_PIN in the Pinouts section above. +*/ +#define DC_EXTRUDER +#define DC_EXTRUDER_PWM + +/** \def USE_WATCHDOG + Teacup implements a watchdog, which has to be reset every 250ms or it will + reboot the controller. As rebooting (and letting the GCode sending + application trying to continue the build with a then different Home point) + is probably even worse than just hanging, and there is no better restore + code in place, this is disabled for now. +*/ +#define USE_WATCHDOG + +/** \def TH_COUNT + Temperature history count. This is how many temperature readings to keep in + order to calculate derivative in PID loop higher values make PID derivative + term more stable at the expense of reaction time. +*/ +#define TH_COUNT + +/** \def FAST_PWM + Teacup offers two PWM frequencies, 76(61) Hz and 78000(62500) Hz on a + 20(16) MHz electronics. The slower one is the default, as it's the safer + choice and reduces MOSFET heating. Drawback is, in a quiet environment you + might notice the heaters and your power supply humming. + + Uncomment this option if you want to get rid of this humming and can afford + a hotter MOSFET or want faster PWM for other reasons. + + See also: http://reprap.org/wiki/Gen7_Research#MOSFET_heat_and_PWM +*/ +#define FAST_PWM + +/** \def PID_SCALE + This is the scaling of internally stored PID values. 1024L is a good value. +*/ +#define PID_SCALE + +/** \def ENDSTOP_STEPS + Number of steps to run into the endstops intentionally. As endstops trigger + false alarm sometimes, Teacup debounces them by counting a number of + consecutive positives. + + Use 4 or less for reliable endstops, 8 or even more for flaky ones. + + Valid range: 1...255. +*/ +#define ENDSTOP_STEPS 4 + +/** \def CANNED_CYCLE + G-code commands in this string will be executed over and over again, without + user interaction or even a serial connection. It's purpose is e.g. for + exhibitions or when using Teacup for other purposes than printing. You can + add any G-code supported by Teacup. + + Note: don't miss these newlines (\n) and backslashes (\). +*/ +/* +#define CANNED_CYCLE "G1 X100 F3000\n" \ +"G4 P500\n" \ +"G1 X0\n" \ +"G4 P500\n" +*/ diff --git a/configtool/boardpanel.py b/configtool/boardpanel.py index 9293b91..96f84b8 100644 --- a/configtool/boardpanel.py +++ b/configtool/boardpanel.py @@ -40,6 +40,7 @@ class BoardPanel(wx.Panel): self.candHeatPins = [] self.candThermPins = [] self.dir = os.path.join(self.settings.folder, "config") + self.cfgDir = os.path.join(self.settings.folder, "config") self.SetBackgroundColour(self.deco.getBackgroundColour()) self.Bind(wx.EVT_PAINT, self.deco.onPaintBackground) @@ -210,20 +211,26 @@ class BoardPanel(wx.Panel): return self.dir = os.path.dirname(path) - rc = self.loadConfigFile(path) + rc, efn = self.loadConfigFile(path) if not rc: - dlg = wx.MessageDialog(self, "Unable to process file %s." % path, + dlg = wx.MessageDialog(self, "Unable to process file %s." % efn, "File error", wx.OK + wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return def loadConfigFile(self, fn): + cfgFn = os.path.join(self.cfgDir, "board.metadata") try: - self.cfgBuffer = list(open(fn)) + self.cfgBuffer = list(open(cfgFn)) except: - return False + return False, cfgFn + + try: + self.userBuffer = list(open(fn)) + except: + return False, fn self.configFile = fn @@ -234,12 +241,13 @@ class BoardPanel(wx.Panel): self.candThermPins = [] self.candProcessors = [] self.candClocks = [] - tempTables = {} + self.tempTables = {} gatheringHelpText = False helpTextString = "" helpKey = None self.cfgValues = {} + self.cfgNames = [] self.helpText = {} prevLines = "" @@ -281,75 +289,26 @@ class BoardPanel(wx.Panel): prevLines = "" if ln.lstrip().startswith("//"): - m = reCandThermPins.match(ln) - if m: - t = m.groups() - if len(t) == 1: - self.candThermPins.append(t[0]) - continue + self.parseCandidateValues(ln) - m = reCandHeatPins.match(ln) - if m: - t = m.groups() - if len(t) == 1: - self.candHeatPins.append(t[0]) - continue - - m = reCandProcessors.match(ln) - if m: - t = m.groups() - if len(t) == 1: - self.candProcessors.append(t[0]) - continue - - m = reCandCPUClocks.match(ln) - if m: - t = m.groups() - if len(t) == 1: - self.candClocks.append(t[0]) - continue - - m = reDefTT.match(ln) - if m: - t = m.groups() - if len(t) == 2: - s = self.parseTempTable(t[1]) - if s: - tempTables[t[0]] = s - continue + elif ln.lstrip().startswith("#define"): + self.parseDefineName(ln) + prevLines = "" + for ln in self.userBuffer: + if ln.rstrip().endswith("\\"): + prevLines += ln.rstrip()[:-1] continue - if ln.lstrip().startswith("#define"): - m = reDefQS.search(ln) - if m: - t = m.groups() - if len(t) == 2: - m = reDefQSm.search(ln) - if m: - t = m.groups() - tt = re.findall(reDefQSm2, t[1]) - if len(tt) == 1: - self.cfgValues[t[0]] = tt[0] - continue - elif len(tt) > 1: - self.cfgValues[t[0]] = tt - continue + if prevLines != "": + ln = prevLines + ln + prevLines = "" - m = reDefine.search(ln) - if m: - t = m.groups() - if len(t) == 2: - self.cfgValues[t[0]] = t[1] - if reFloatAttr.search(ln): - pass - continue + if ln.lstrip().startswith("//"): + self.parseCandidateValues(ln) - m = reDefBool.search(ln) - if m: - t = m.groups() - if len(t) == 1: - self.cfgValues[t[0]] = True + elif ln.lstrip().startswith("#define"): + self.parseDefineValue(ln) else: m = reDefTS.search(ln) @@ -359,7 +318,7 @@ class BoardPanel(wx.Panel): s = self.parseSensor(t[0]) if s: self.sensors.append(s) - continue + continue m = reDefHT.search(ln) if m: @@ -368,12 +327,12 @@ class BoardPanel(wx.Panel): s = self.parseHeater(t[0]) if s: self.heaters.append(s) - continue + continue for k in range(len(self.sensors)): tn = self.sensors[k][0].upper() - if tn in tempTables.keys(): - self.sensors[k][3] = tempTables[tn] + if tn in self.tempTables.keys(): + self.sensors[k][3] = self.tempTables[tn] else: self.sensors[k][3] = None @@ -396,7 +355,82 @@ class BoardPanel(wx.Panel): self.pgSensors.setSensors(self.sensors) self.pgHeaters.setHeaters(self.heaters) - return True + return True, None + + def parseDefineName(self, ln): + m = reDefBool.search(ln) + if m: + t = m.groups() + if len(t) == 1: + self.cfgNames.append(t[0]) + + def parseDefineValue(self, ln): + m = reDefQS.search(ln) + if m: + t = m.groups() + if len(t) == 2: + m = reDefQSm.search(ln) + if m: + t = m.groups() + tt = re.findall(reDefQSm2, t[1]) + if len(tt) == 1: + self.cfgValues[t[0]] = tt[0] + return + elif len(tt) > 1: + self.cfgValues[t[0]] = tt + return + + m = reDefine.search(ln) + if m: + t = m.groups() + if len(t) == 2: + self.cfgValues[t[0]] = t[1] + return + + m = reDefBool.search(ln) + if m: + t = m.groups() + if len(t) == 1: + self.cfgValues[t[0]] = True + return + + def parseCandidateValues(self, ln): + m = reCandThermPins.match(ln) + if m: + t = m.groups() + if len(t) == 1: + self.candThermPins.append(t[0]) + return + + m = reCandHeatPins.match(ln) + if m: + t = m.groups() + if len(t) == 1: + self.candHeatPins.append(t[0]) + return + + m = reCandProcessors.match(ln) + if m: + t = m.groups() + if len(t) == 1: + self.candProcessors.append(t[0]) + return + + m = reCandCPUClocks.match(ln) + if m: + t = m.groups() + if len(t) == 1: + self.candClocks.append(t[0]) + return + + m = reDefTT.match(ln) + if m: + t = m.groups() + if len(t) == 2: + s = self.parseTempTable(t[1]) + if s: + self.tempTables[t[0]] = s + return def parseSensor(self, s): m = reSensor.search(s) @@ -489,7 +523,6 @@ class BoardPanel(wx.Panel): self.configFile = path values = {} - labelFound = [] for pg in self.pages: v1 = pg.getValues() @@ -557,90 +590,26 @@ class BoardPanel(wx.Panel): skipToHeaterEnd = False continue - m = reDefineBL.match(ln) - if m: - t = m.groups() - if len(t) == 2: - if t[0] in values.keys() and values[t[0]] != "": - fp.write(defineValueFormat % (t[0], values[t[0]])) - self.cfgValues[t[0]] = values[t[0]] - labelFound.append(t[0]) - elif t[0] in values.keys(): - fp.write("//" + ln) - if t[0] in self.cfgValues.keys(): - del self.cfgValues[t[0]] - labelFound.append(t[0]) - else: - fp.write(ln) - continue - m = reDefBoolBL.match(ln) if m: t = m.groups() if len(t) == 1: - if t[0] in values.keys() and values[t[0]]: - fp.write(defineBoolFormat % t[0]) - self.cfgValues[t[0]] = True - labelFound.append(t[0]) - elif t[0] in values.keys(): - fp.write("//" + ln) - if t[0] in self.cfgValues.keys(): - del self.cfgValues[t[0]] - labelFound.append(t[0]) + if t[0] in values.keys(): + v = values[t[0]] + self.cfgValues[t[0]] = v + if v == "" or v == False: + fp.write("//" + ln) + elif v == True: + fp.write(ln) + else: + fp.write(defineValueFormat % (t[0], v)) else: fp.write(ln) - continue - m = reCommDefBL.match(ln) - if m: - t = m.groups() - if len(t) == 2: - if t[0] in values.keys() and values[t[0]] != "": - fp.write(defineValueFormat % (t[0], values[t[0]])) - self.cfgValues[t[0]] = values[t[0]] - labelFound.append(t[0]) - elif t[0] in values.keys(): - fp.write(ln) - labelFound.append(t[0]) - else: - fp.write(ln) - continue - - m = reCommDefBoolBL.match(ln) - if m: - t = m.groups() - if len(t) == 1: - if t[0] in values.keys() and values[t[0]]: - fp.write(defineBoolFormat % t[0]) - self.cfgValues[t[0]] = True - labelFound.append(t[0]) - elif t[0] in values.keys(): - fp.write(ln) - labelFound.append(t[0]) - else: - fp.write(ln) continue fp.write(ln) - for k in labelFound: - del values[k] - - newLabels = "" - for k in values.keys(): - if newLabels == "": - newLabels = k - else: - newLabels += ", " + k - self.addNewDefine(fp, k, values[k]) - - if newLabels != "": - dlg = wx.MessageDialog(self, "New defines added to board config:\n" + - newLabels, "New defines", - wx.OK + wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - fp.close() return self.generateTempTables() @@ -653,17 +622,3 @@ class BoardPanel(wx.Panel): return False return True - - def addNewDefine(self, fp, key, val): - fp.write("\n") - fp.write("/** \\def %s\n" % key) - fp.write(" Add help text here.\n") - fp.write("*/\n") - if val == True: - fp.write(defineBoolFormat % key) - elif val == False: - fp.write("//#define %s\n" % key) - elif val == "": - fp.write("//#define %s\n" % key) - else: - fp.write(defineValueFormat % (key, val)) diff --git a/configtool/printerpanel.py b/configtool/printerpanel.py index 3a48f82..b03c375 100644 --- a/configtool/printerpanel.py +++ b/configtool/printerpanel.py @@ -29,6 +29,7 @@ class PrinterPanel(wx.Panel): self.cfgValues = {} self.heaters = [] self.dir = os.path.join(self.settings.folder, "config") + self.cfgDir = os.path.join(self.settings.folder, "config") self.SetBackgroundColour(self.deco.getBackgroundColour()) self.Bind(wx.EVT_PAINT, self.deco.onPaintBackground) @@ -171,20 +172,26 @@ class PrinterPanel(wx.Panel): return self.dir = os.path.dirname(path) - rc = self.loadConfigFile(path) + rc, efn = self.loadConfigFile(path) if not rc: - dlg = wx.MessageDialog(self, "Unable to process file %s." % path, + dlg = wx.MessageDialog(self, "Unable to process file %s." % efn, "File error", wx.OK + wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return def loadConfigFile(self, fn): + cfgFn = os.path.join(self.cfgDir, "printer.metadata") try: - self.cfgBuffer = list(open(fn)) + self.cfgBuffer = list(open(cfgFn)) except: - return False + return False, cfgFn + + try: + self.userBuffer = list(open(fn)) + except: + return False, fn self.configFile = fn @@ -194,6 +201,7 @@ class PrinterPanel(wx.Panel): helpKey = None self.cfgValues = {} + self.cfgNames = [] self.helpText = {} prevLines = "" @@ -237,34 +245,22 @@ class PrinterPanel(wx.Panel): if ln.lstrip().startswith("//"): continue - if ln.lstrip().startswith("#define"): - m = reDefQS.search(ln) - if m: - t = m.groups() - if len(t) == 2: - m = reDefQSm.search(ln) - if m: - t = m.groups() - tt = re.findall(reDefQSm2, t[1]) - if len(tt) == 1: - self.cfgValues[t[0]] = tt[0] - continue - elif len(tt) > 1: - self.cfgValues[t[0]] = tt - continue + self.parseDefineName(ln) - m = reDefine.search(ln) - if m: - t = m.groups() - if len(t) == 2: - self.cfgValues[t[0]] = t[1] - continue + prevLines = "" + for ln in self.userBuffer: + if ln.rstrip().endswith("\\"): + prevLines += ln.rstrip()[:-1] + continue - m = reDefBool.search(ln) - if m: - t = m.groups() - if len(t) == 1: - self.cfgValues[t[0]] = True + if prevLines != "": + ln = prevLines + ln + prevLines = "" + + if ln.lstrip().startswith("//"): + continue + + self.parseDefineValue(ln) if os.path.basename(fn) in protectedFiles: self.parent.enableSavePrinter(False, True) @@ -284,7 +280,45 @@ class PrinterPanel(wx.Panel): else: self.pgMiscellaneous.setOriginalHeater(None) - return True + return True, None + + def parseDefineName(self, ln): + m = reDefBool.search(ln) + if m: + t = m.groups() + if len(t) == 1: + self.cfgNames.append(t[0]) + + def parseDefineValue(self, ln): + if ln.lstrip().startswith("#define"): + m = reDefQS.search(ln) + if m: + t = m.groups() + if len(t) == 2: + m = reDefQSm.search(ln) + if m: + t = m.groups() + tt = re.findall(reDefQSm2, t[1]) + if len(tt) == 1: + self.cfgValues[t[0]] = tt[0] + return + elif len(tt) > 1: + self.cfgValues[t[0]] = tt + return + + m = reDefine.search(ln) + if m: + t = m.groups() + if len(t) == 2: + self.cfgValues[t[0]] = t[1] + return + + m = reDefBool.search(ln) + if m: + t = m.groups() + if len(t) == 1: + self.cfgValues[t[0]] = True + return def onSaveConfig(self, evt): path = self.configFile @@ -348,7 +382,6 @@ class PrinterPanel(wx.Panel): self.configFile = path values = {} - labelFound = [] for pg in self.pages: v1 = pg.getValues() @@ -356,104 +389,25 @@ class PrinterPanel(wx.Panel): values[k] = v1[k] for ln in self.cfgBuffer: - m = reDefineBL.match(ln) - if m: - t = m.groups() - if len(t) == 2: - if t[0] in values.keys() and values[t[0]] != "": - fp.write(defineValueFormat % (t[0], values[t[0]])) - self.cfgValues[t[0]] = values[t[0]] - labelFound.append(t[0]) - elif t[0] in values.keys(): - fp.write("//" + ln) - if t[0] in self.cfgValues.keys(): - del self.cfgValues[t[0]] - labelFound.append(t[0]) - else: - fp.write(ln) - continue - m = reDefBoolBL.match(ln) if m: t = m.groups() if len(t) == 1: - if t[0] in values.keys() and values[t[0]]: - fp.write(defineBoolFormat % t[0]) - self.cfgValues[t[0]] = True - labelFound.append(t[0]) - elif t[0] in values.keys(): - fp.write("//" + ln) - if t[0] in self.cfgValues.keys(): - del self.cfgValues[t[0]] - labelFound.append(t[0]) - else: - fp.write(ln) - continue - - m = reCommDefBL.match(ln) - if m: - t = m.groups() - if len(t) == 2: - if t[0] in values.keys() and values[t[0]] != "": - fp.write(defineValueFormat % (t[0], values[t[0]])) - self.cfgValues[t[0]] = values[t[0]] - labelFound.append(t[0]) - elif t[0] in values.keys(): - fp.write(ln) - labelFound.append(t[0]) - else: - fp.write(ln) - continue - - m = reCommDefBoolBL.match(ln) - if m: - t = m.groups() - if len(t) == 1: - if t[0] in values.keys() and values[t[0]]: - fp.write(defineBoolFormat % t[0]) - self.cfgValues[t[0]] = True - labelFound.append(t[0]) - elif t[0] in values.keys(): - fp.write(ln) - labelFound.append(t[0]) + if t[0] in values.keys(): + v = values[t[0]] + self.cfgValues[t[0]] = v + if v == "" or v == False: + fp.write("//" + ln) + elif v == True: + fp.write(ln) + else: + fp.write(defineValueFormat % (t[0], v)) else: fp.write(ln) continue fp.write(ln) - for k in labelFound: - del values[k] - - newLabels = "" - for k in values.keys(): - if newLabels == "": - newLabels = k - else: - newLabels += ", " + k - self.addNewDefine(fp, k, values[k]) - - if newLabels != "": - dlg = wx.MessageDialog(self, "New defines added to printer config:\n" + - newLabels, "New defines", - wx.OK + wx.ICON_INFORMATION) - dlg.ShowModal() - dlg.Destroy() - fp.close() return True - - def addNewDefine(self, fp, key, val): - fp.write("\n") - fp.write("/** \\def %s\n" % key) - fp.write(" Add help text here.\n") - fp.write("*/\n") - if val == True: - fp.write(defineBoolFormat % key) - elif val == False: - fp.write("//#define %s\n" % key) - elif val == "": - fp.write("//#define %s\n" % key) - else: - fp.write(defineValueFormat % (key, val))