first commit
This commit is contained in:
commit
8c39952965
1956 changed files with 1460685 additions and 0 deletions
304
buildroot/share/scripts/MarlinMesh.scad
Normal file
304
buildroot/share/scripts/MarlinMesh.scad
Normal file
|
@ -0,0 +1,304 @@
|
|||
/**************************************\
|
||||
* *
|
||||
* OpenSCAD Mesh Display *
|
||||
* by Thinkyhead - April 2017 *
|
||||
* *
|
||||
* Copy the grid output from Marlin, *
|
||||
* paste below as shown, and use *
|
||||
* OpenSCAD to see a visualization *
|
||||
* of your mesh. *
|
||||
* *
|
||||
\**************************************/
|
||||
|
||||
$t = 0.15; // comment out during animation!
|
||||
X = 0; Y = 1;
|
||||
L = 0; R = 1; F = 2; B = 3;
|
||||
|
||||
//
|
||||
// Sample Mesh - Replace with your own
|
||||
//
|
||||
measured_z = [
|
||||
[ -1.20, -1.13, -1.09, -1.03, -1.19 ],
|
||||
[ -1.16, -1.25, -1.27, -1.25, -1.08 ],
|
||||
[ -1.13, -1.26, -1.39, -1.31, -1.18 ],
|
||||
[ -1.09, -1.20, -1.26, -1.21, -1.18 ],
|
||||
[ -1.13, -0.99, -1.03, -1.06, -1.32 ]
|
||||
];
|
||||
|
||||
//
|
||||
// An offset to add to all points in the mesh
|
||||
//
|
||||
zadjust = 0;
|
||||
|
||||
//
|
||||
// Mesh characteristics
|
||||
//
|
||||
bed_size = [ 200, 200 ];
|
||||
|
||||
mesh_inset = [ 10, 10, 10, 10 ]; // L, F, R, B
|
||||
|
||||
mesh_bounds = [
|
||||
[ mesh_inset[L], mesh_inset[F] ],
|
||||
[ bed_size[X] - mesh_inset[R], bed_size[Y] - mesh_inset[B] ]
|
||||
];
|
||||
|
||||
mesh_size = mesh_bounds[1] - mesh_bounds[0];
|
||||
|
||||
// NOTE: Marlin meshes already subtract the probe offset
|
||||
NAN = 0; // Z to use for un-measured points
|
||||
|
||||
//
|
||||
// Geometry
|
||||
//
|
||||
|
||||
max_z_scale = 100; // Scale at Time 0.5
|
||||
min_z_scale = 10; // Scale at Time 0.0 and 1.0
|
||||
thickness = 0.5; // thickness of the mesh triangles
|
||||
tesselation = 1; // levels of tesselation from 0-2
|
||||
alternation = 2; // direction change modulus (try it)
|
||||
|
||||
//
|
||||
// Appearance
|
||||
//
|
||||
|
||||
show_plane = true;
|
||||
show_labels = true;
|
||||
show_coords = true;
|
||||
arrow_length = 5;
|
||||
|
||||
label_font_lg = "Arial";
|
||||
label_font_sm = "Arial";
|
||||
mesh_color = [1,1,1,0.5];
|
||||
plane_color = [0.4,0.6,0.9,0.6];
|
||||
|
||||
//================================================ Derive useful values
|
||||
|
||||
big_z = max_2D(measured_z,0);
|
||||
lil_z = min_2D(measured_z,0);
|
||||
|
||||
mean_value = (big_z + lil_z) / 2.0;
|
||||
|
||||
mesh_points_y = len(measured_z);
|
||||
mesh_points_x = len(measured_z[0]);
|
||||
|
||||
xspace = mesh_size[X] / (mesh_points_x - 1);
|
||||
yspace = mesh_size[Y] / (mesh_points_y - 1);
|
||||
|
||||
// At $t=0 and $t=1 scale will be 100%
|
||||
z_scale_factor = min_z_scale + (($t > 0.5) ? 1.0 - $t : $t) * (max_z_scale - min_z_scale) * 2;
|
||||
|
||||
//
|
||||
// Min and max recursive functions for 1D and 2D arrays
|
||||
// Return the smallest or largest value in the array
|
||||
//
|
||||
function some_1D(b,i) = (i<len(b)-1) ? (b[i] && some_1D(b,i+1)) : b[i] != 0;
|
||||
function some_2D(a,j) = (j<len(a)-1) ? some_2D(a,j+1) : some_1D(a[j], 0);
|
||||
function min_1D(b,i) = (i<len(b)-1) ? min(b[i], min_1D(b,i+1)) : b[i];
|
||||
function min_2D(a,j) = (j<len(a)-1) ? min_2D(a,j+1) : min_1D(a[j], 0);
|
||||
function max_1D(b,i) = (i<len(b)-1) ? max(b[i], max_1D(b,i+1)) : b[i];
|
||||
function max_2D(a,j) = (j<len(a)-1) ? max_2D(a,j+1) : max_1D(a[j], 0);
|
||||
|
||||
//
|
||||
// Get the corner probe points of a grid square.
|
||||
//
|
||||
// Input : x,y grid indexes
|
||||
// Output : An array of the 4 corner points
|
||||
//
|
||||
function grid_square(x,y) = [
|
||||
[x * xspace, y * yspace, z_scale_factor * (measured_z[y][x] - mean_value)],
|
||||
[x * xspace, (y+1) * yspace, z_scale_factor * (measured_z[y+1][x] - mean_value)],
|
||||
[(x+1) * xspace, (y+1) * yspace, z_scale_factor * (measured_z[y+1][x+1] - mean_value)],
|
||||
[(x+1) * xspace, y * yspace, z_scale_factor * (measured_z[y][x+1] - mean_value)]
|
||||
];
|
||||
|
||||
// The corner point of a grid square with Z centered on the mean
|
||||
function pos(x,y,z) = [x * xspace, y * yspace, z_scale_factor * (z - mean_value)];
|
||||
|
||||
//
|
||||
// Draw the point markers and labels
|
||||
//
|
||||
module point_markers(show_home=true) {
|
||||
// Mark the home position 0,0
|
||||
if (show_home)
|
||||
translate([1,1]) color([0,0,0,0.25])
|
||||
cylinder(r=1, h=z_scale_factor, center=true);
|
||||
|
||||
for (x=[0:mesh_points_x-1], y=[0:mesh_points_y-1]) {
|
||||
z = measured_z[y][x] - zadjust;
|
||||
down = z < mean_value;
|
||||
xyz = pos(x, y, z);
|
||||
translate([ xyz[0], xyz[1] ]) {
|
||||
|
||||
// Show the XY as well as the Z!
|
||||
if (show_coords) {
|
||||
color("black")
|
||||
translate([0,0,0.5]) {
|
||||
$fn=8;
|
||||
rotate([0,0]) {
|
||||
posx = floor(mesh_bounds[0][X] + x * xspace);
|
||||
posy = floor(mesh_bounds[0][Y] + y * yspace);
|
||||
text(str(posx, ",", posy), 2, label_font_sm, halign="center", valign="center");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
translate([ 0, 0, xyz[2] ]) {
|
||||
// Label each point with the Z
|
||||
v = z - mean_value;
|
||||
if (show_labels) {
|
||||
|
||||
color(abs(v) < 0.1 ? [0,0.5,0] : [0.25,0,0])
|
||||
translate([0,0,down?-10:10]) {
|
||||
|
||||
$fn=8;
|
||||
rotate([90,0])
|
||||
text(str(z), 6, label_font_lg, halign="center", valign="center");
|
||||
|
||||
if (v)
|
||||
translate([0,0,down?-6:6]) rotate([90,0])
|
||||
text(str(down || !v ? "" : "+", v), 3, label_font_sm, halign="center", valign="center");
|
||||
}
|
||||
}
|
||||
|
||||
// Show an arrow pointing up or down
|
||||
if (v) {
|
||||
rotate([0, down ? 180 : 0]) translate([0,0,-1])
|
||||
cylinder(
|
||||
r1=0.5,
|
||||
r2=0.1,
|
||||
h=arrow_length, $fn=12, center=1
|
||||
);
|
||||
}
|
||||
else
|
||||
color([1,0,1,0.4]) sphere(r=1.0, $fn=20, center=1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Split a square on the diagonal into
|
||||
// two triangles and render them.
|
||||
//
|
||||
// s : a square
|
||||
// alt : a flag to split on the other diagonal
|
||||
//
|
||||
module tesselated_square(s, alt=false) {
|
||||
add = [0,0,thickness];
|
||||
p1 = [
|
||||
s[0], s[1], s[2], s[3],
|
||||
s[0]+add, s[1]+add, s[2]+add, s[3]+add
|
||||
];
|
||||
f1 = alt
|
||||
? [ [0,1,3], [4,5,1,0], [4,7,5], [5,7,3,1], [7,4,0,3] ]
|
||||
: [ [0,1,2], [4,5,1,0], [4,6,5], [5,6,2,1], [6,4,0,2] ];
|
||||
f2 = alt
|
||||
? [ [1,2,3], [5,6,2,1], [5,6,7], [6,7,3,2], [7,5,1,3] ]
|
||||
: [ [0,2,3], [4,6,2,0], [4,7,6], [6,7,3,2], [7,4,0,3] ];
|
||||
|
||||
// Use the other diagonal
|
||||
polyhedron(points=p1, faces=f1);
|
||||
polyhedron(points=p1, faces=f2);
|
||||
}
|
||||
|
||||
/**
|
||||
* The simplest mesh display
|
||||
*/
|
||||
module simple_mesh(show_plane=show_plane) {
|
||||
if (show_plane) color(plane_color) cube([mesh_size[X], mesh_size[Y], thickness]);
|
||||
color(mesh_color)
|
||||
for (x=[0:mesh_points_x-2], y=[0:mesh_points_y-2])
|
||||
tesselated_square(grid_square(x, y));
|
||||
}
|
||||
|
||||
/**
|
||||
* Subdivide the mesh into smaller squares.
|
||||
*/
|
||||
module bilinear_mesh(show_plane=show_plane,tesselation=tesselation) {
|
||||
if (show_plane) color(plane_color) translate([-5,-5]) cube([mesh_size[X]+10, mesh_size[Y]+10, thickness]);
|
||||
|
||||
if (some_2D(measured_z, 0)) {
|
||||
|
||||
tesselation = tesselation % 4;
|
||||
color(mesh_color)
|
||||
for (x=[0:mesh_points_x-2], y=[0:mesh_points_y-2]) {
|
||||
square = grid_square(x, y);
|
||||
if (tesselation < 1) {
|
||||
tesselated_square(square,(x%alternation)-(y%alternation));
|
||||
}
|
||||
else {
|
||||
subdiv_4 = subdivided_square(square);
|
||||
if (tesselation < 2) {
|
||||
for (i=[0:3]) tesselated_square(subdiv_4[i],i%alternation);
|
||||
}
|
||||
else {
|
||||
for (i=[0:3]) {
|
||||
subdiv_16 = subdivided_square(subdiv_4[i]);
|
||||
if (tesselation < 3) {
|
||||
for (j=[0:3]) tesselated_square(subdiv_16[j],j%alternation);
|
||||
}
|
||||
else {
|
||||
for (j=[0:3]) {
|
||||
subdiv_64 = subdivided_square(subdiv_16[j]);
|
||||
if (tesselation < 4) {
|
||||
for (k=[0:3]) tesselated_square(subdiv_64[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Subdivision helpers
|
||||
//
|
||||
function ctrz(a) = (a[0][2]+a[1][2]+a[3][2]+a[2][2])/4;
|
||||
function avgx(a,i) = (a[i][0]+a[(i+1)%4][0])/2;
|
||||
function avgy(a,i) = (a[i][1]+a[(i+1)%4][1])/2;
|
||||
function avgz(a,i) = (a[i][2]+a[(i+1)%4][2])/2;
|
||||
|
||||
//
|
||||
// Convert one square into 4, applying bilinear averaging
|
||||
//
|
||||
// Input : 1 square (4 points)
|
||||
// Output : An array of 4 squares
|
||||
//
|
||||
function subdivided_square(a) = [
|
||||
[ // SW square
|
||||
a[0], // SW
|
||||
[a[0][0],avgy(a,0),avgz(a,0)], // CW
|
||||
[avgx(a,1),avgy(a,0),ctrz(a)], // CC
|
||||
[avgx(a,1),a[0][1],avgz(a,3)] // SC
|
||||
],
|
||||
[ // NW square
|
||||
[a[0][0],avgy(a,0),avgz(a,0)], // CW
|
||||
a[1], // NW
|
||||
[avgx(a,1),a[1][1],avgz(a,1)], // NC
|
||||
[avgx(a,1),avgy(a,0),ctrz(a)] // CC
|
||||
],
|
||||
[ // NE square
|
||||
[avgx(a,1),avgy(a,0),ctrz(a)], // CC
|
||||
[avgx(a,1),a[1][1],avgz(a,1)], // NC
|
||||
a[2], // NE
|
||||
[a[2][0],avgy(a,0),avgz(a,2)] // CE
|
||||
],
|
||||
[ // SE square
|
||||
[avgx(a,1),a[0][1],avgz(a,3)], // SC
|
||||
[avgx(a,1),avgy(a,0),ctrz(a)], // CC
|
||||
[a[2][0],avgy(a,0),avgz(a,2)], // CE
|
||||
a[3] // SE
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
//================================================ Run the plan
|
||||
|
||||
translate([-mesh_size[X] / 2, -mesh_size[Y] / 2]) {
|
||||
$fn = 12;
|
||||
point_markers();
|
||||
bilinear_mesh();
|
||||
}
|
200
buildroot/share/scripts/config-labels.py
Normal file
200
buildroot/share/scripts/config-labels.py
Normal file
|
@ -0,0 +1,200 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# for python3.5 or higher
|
||||
#-----------------------------------
|
||||
# Within Marlin project MarlinFirmware/Configurations, this program visits all folders
|
||||
# under .../config/examples/*, processing each Configuration.h, Configuration_adv.h,
|
||||
# _Bootscreen.h, and _Statusscreen.h, to insert:
|
||||
# #define CONFIG_EXAMPLES_DIR "examples/<style>/<vendor>/<model>"
|
||||
# ... or similar path leading to this file.
|
||||
#
|
||||
# Warning: The program modifies files in place, so be sure to back them up first if needed.
|
||||
# Can be run multiple times if needed. Only modifies files which don't have
|
||||
# correct #define CONFIG_EXAMPLES_DIR line.
|
||||
#
|
||||
# Invocation:
|
||||
#-------------
|
||||
# 1. Change directory to your MarlinFirmware/Configurations working copy
|
||||
# 2. python3 config-labels.py
|
||||
#
|
||||
#-----------------------------------
|
||||
# 2020-05-10 GMW original
|
||||
# 2020-06-05 SRL style tweaks
|
||||
#-----------------------------------
|
||||
#
|
||||
import sys,os
|
||||
from pathlib import Path
|
||||
from distutils.dir_util import copy_tree # for copy_tree, because shutil.copytree can't handle existing files, dirs
|
||||
|
||||
# Modify input_examples_dir and output_examples_dir for your installation
|
||||
# No trailing slash
|
||||
# Setting output_examples_dir = input_examples_dir causes the program to insert into the existing files.
|
||||
|
||||
input_examples_dir = r'config/examples'
|
||||
# output_examples_dir = input_examples_dir
|
||||
output_examples_dir = r'config/examples'
|
||||
|
||||
#-------------------------------------
|
||||
|
||||
files_to_mod = ['Configuration.h', 'Configuration_adv.h', '_Bootscreen.h', '_Statusscreen.h']
|
||||
|
||||
macro_name = 'CONFIG_EXAMPLES_DIR'
|
||||
def_macro_name = '#define ' + macro_name
|
||||
|
||||
filenum = 0
|
||||
different_out_dir = not (output_examples_dir == input_examples_dir)
|
||||
|
||||
#----------------------------------------------
|
||||
def process_file(subdir: str, filename: str):
|
||||
#----------------------------------------------
|
||||
global filenum
|
||||
filenum += 1
|
||||
|
||||
print(str(filenum) + ' ' + filename + ': ' + subdir)
|
||||
|
||||
def_line = (def_macro_name + ' "' + subdir.replace('\\', '/') + '"')
|
||||
|
||||
#------------------------
|
||||
# Read file
|
||||
#------------------------
|
||||
lines = []
|
||||
infilepath = os.path.join(input_examples_dir, subdir, filename)
|
||||
try:
|
||||
# UTF-8 because some files contain unicode chars
|
||||
with open(infilepath, 'rt', encoding="utf-8") as infile:
|
||||
lines = infile.readlines()
|
||||
|
||||
except Exception as e:
|
||||
print('Failed to read file: ' + str(e) )
|
||||
raise Exception
|
||||
|
||||
lines = [line.rstrip('\r\n') for line in lines]
|
||||
|
||||
#------------------------
|
||||
# Process lines
|
||||
#------------------------
|
||||
file_modified = False
|
||||
|
||||
# region state machine
|
||||
# -1 = before pragma once;
|
||||
# 0 = region to place define;
|
||||
# 1 = past region to place define
|
||||
region = -1
|
||||
|
||||
outlines = []
|
||||
for line in lines:
|
||||
outline = line
|
||||
|
||||
if (region == -1) and (def_macro_name in line):
|
||||
outline = None
|
||||
file_modified = True
|
||||
|
||||
elif (region == -1) and ('pragma once' in line):
|
||||
region = 0
|
||||
|
||||
elif (region == 0):
|
||||
if (line.strip() == ''):
|
||||
pass
|
||||
elif (def_macro_name in line):
|
||||
region = 1
|
||||
if line == def_line: # leave it as is
|
||||
pass
|
||||
else:
|
||||
outline = def_line
|
||||
file_modified = True
|
||||
else: # some other string
|
||||
outlines.append(def_line)
|
||||
outlines.append('')
|
||||
region = 1
|
||||
file_modified = True
|
||||
|
||||
elif (region == 1):
|
||||
if (def_macro_name in line):
|
||||
outline = None
|
||||
file_modified = True
|
||||
else:
|
||||
pass
|
||||
|
||||
# end if
|
||||
if outline is not None:
|
||||
outlines.append(outline)
|
||||
# end for
|
||||
|
||||
#-------------------------
|
||||
# Output file
|
||||
#-------------------------
|
||||
outdir = os.path.join(output_examples_dir, subdir)
|
||||
outfilepath = os.path.join(outdir, filename)
|
||||
|
||||
if file_modified:
|
||||
# Note: no need to create output dirs, as the initial copy_tree
|
||||
# will do that.
|
||||
|
||||
print(' writing ' + str(outfilepath))
|
||||
try:
|
||||
# Preserve unicode chars; Avoid CR-LF on Windows.
|
||||
with open(outfilepath, "w", encoding="utf-8", newline='\n') as outfile:
|
||||
outfile.write("\n".join(outlines))
|
||||
outfile.write("\n")
|
||||
|
||||
except Exception as e:
|
||||
print('Failed to write file: ' + str(e) )
|
||||
raise Exception
|
||||
else:
|
||||
print(' no change for ' + str(outfilepath))
|
||||
|
||||
#----------
|
||||
def main():
|
||||
#----------
|
||||
global filenum
|
||||
global input_examples_dir
|
||||
global output_examples_dir
|
||||
filenum = 0
|
||||
|
||||
#--------------------------------
|
||||
# Check for requirements
|
||||
#--------------------------------
|
||||
input_examples_dir = input_examples_dir.strip()
|
||||
input_examples_dir = input_examples_dir.rstrip('\\/')
|
||||
output_examples_dir = output_examples_dir.strip()
|
||||
output_examples_dir = output_examples_dir.rstrip('\\/')
|
||||
|
||||
for dir in [input_examples_dir, output_examples_dir]:
|
||||
if not (os.path.exists(dir)):
|
||||
print('Directory not found: ' + dir)
|
||||
sys.exit(1)
|
||||
|
||||
#--------------------------------
|
||||
# Copy tree if necessary.
|
||||
#--------------------------------
|
||||
# This includes files that are not otherwise included in the
|
||||
# insertion of the define statement.
|
||||
#
|
||||
if different_out_dir:
|
||||
print('Copying files to new directory: ' + output_examples_dir)
|
||||
try:
|
||||
copy_tree(input_examples_dir, output_examples_dir)
|
||||
except Exception as e:
|
||||
print('Failed to copy directory: ' + str(e) )
|
||||
raise Exception
|
||||
|
||||
#-----------------------------
|
||||
# Find and process files
|
||||
#-----------------------------
|
||||
len_input_examples_dir = len(input_examples_dir);
|
||||
len_input_examples_dir += 1
|
||||
|
||||
for filename in files_to_mod:
|
||||
input_path = Path(input_examples_dir)
|
||||
filepathlist = input_path.rglob(filename)
|
||||
|
||||
for filepath in filepathlist:
|
||||
fulldirpath = str(filepath.parent)
|
||||
subdir = fulldirpath[len_input_examples_dir:]
|
||||
|
||||
process_file(subdir, filename)
|
||||
|
||||
#==============
|
||||
print('--- Starting config-labels ---')
|
||||
main()
|
||||
print('--- Done ---')
|
53
buildroot/share/scripts/createSpeedLookupTable.py
Normal file
53
buildroot/share/scripts/createSpeedLookupTable.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import division
|
||||
|
||||
""" Generate the stepper delay lookup table for Marlin firmware. """
|
||||
|
||||
import argparse
|
||||
|
||||
__author__ = "Ben Gamari <bgamari@gmail.com>"
|
||||
__copyright__ = "Copyright 2012, Ben Gamari"
|
||||
__license__ = "GPL"
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('-f', '--cpu-freq', type=int, default=16, help='CPU clockrate in MHz (default=16)')
|
||||
parser.add_argument('-d', '--divider', type=int, default=8, help='Timer/counter pre-scale divider (default=8)')
|
||||
args = parser.parse_args()
|
||||
|
||||
cpu_freq = args.cpu_freq * 1000000
|
||||
timer_freq = cpu_freq / args.divider
|
||||
|
||||
print("#ifndef SPEED_LOOKUPTABLE_H")
|
||||
print("#define SPEED_LOOKUPTABLE_H")
|
||||
print()
|
||||
print('#include "MarlinCore.h"')
|
||||
print()
|
||||
|
||||
print("const uint16_t speed_lookuptable_fast[256][2] PROGMEM = {")
|
||||
a = [ timer_freq / ((i*256)+(args.cpu_freq*2)) for i in range(256) ]
|
||||
b = [ a[i] - a[i+1] for i in range(255) ]
|
||||
b.append(b[-1])
|
||||
for i in range(32):
|
||||
print(" ", end=' ')
|
||||
for j in range(8):
|
||||
print("{%d, %d}," % (a[8*i+j], b[8*i+j]), end=' ')
|
||||
print()
|
||||
print("};")
|
||||
print()
|
||||
|
||||
print("const uint16_t speed_lookuptable_slow[256][2] PROGMEM = {")
|
||||
a = [ timer_freq / ((i*8)+(args.cpu_freq*2)) for i in range(256) ]
|
||||
b = [ a[i] - a[i+1] for i in range(255) ]
|
||||
b.append(b[-1])
|
||||
for i in range(32):
|
||||
print(" ", end=' ')
|
||||
for j in range(8):
|
||||
print("{%d, %d}," % (a[8*i+j], b[8*i+j]), end=' ')
|
||||
print()
|
||||
print("};")
|
||||
print()
|
||||
|
||||
print("#endif")
|
||||
|
157
buildroot/share/scripts/createTemperatureLookupMarlin.py
Normal file
157
buildroot/share/scripts/createTemperatureLookupMarlin.py
Normal file
|
@ -0,0 +1,157 @@
|
|||
#!/usr/bin/env python
|
||||
"""Thermistor Value Lookup Table Generator
|
||||
|
||||
Generates lookup to temperature values for use in a microcontroller in C format based on:
|
||||
https://en.wikipedia.org/wiki/Steinhart-Hart_equation
|
||||
|
||||
The main use is for Arduino programs that read data from the circuit board described here:
|
||||
https://reprap.org/wiki/Temperature_Sensor_v2.0
|
||||
|
||||
Usage: python createTemperatureLookupMarlin.py [options]
|
||||
|
||||
Options:
|
||||
-h, --help show this help
|
||||
--rp=... pull-up resistor
|
||||
--t1=ttt:rrr low temperature temperature:resistance point (around 25 degC)
|
||||
--t2=ttt:rrr middle temperature temperature:resistance point (around 150 degC)
|
||||
--t3=ttt:rrr high temperature temperature:resistance point (around 250 degC)
|
||||
--num-temps=... the number of temperature points to calculate (default: 36)
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import division
|
||||
|
||||
from math import *
|
||||
import sys,getopt
|
||||
|
||||
"Constants"
|
||||
ZERO = 273.15 # zero point of Kelvin scale
|
||||
VADC = 5 # ADC voltage
|
||||
VCC = 5 # supply voltage
|
||||
ARES = pow(2,10) # 10 Bit ADC resolution
|
||||
VSTEP = VADC / ARES # ADC voltage resolution
|
||||
TMIN = 0 # lowest temperature in table
|
||||
TMAX = 350 # highest temperature in table
|
||||
|
||||
class Thermistor:
|
||||
"Class to do the thermistor maths"
|
||||
def __init__(self, rp, t1, r1, t2, r2, t3, r3):
|
||||
l1 = log(r1)
|
||||
l2 = log(r2)
|
||||
l3 = log(r3)
|
||||
y1 = 1.0 / (t1 + ZERO) # adjust scale
|
||||
y2 = 1.0 / (t2 + ZERO)
|
||||
y3 = 1.0 / (t3 + ZERO)
|
||||
x = (y2 - y1) / (l2 - l1)
|
||||
y = (y3 - y1) / (l3 - l1)
|
||||
c = (y - x) / ((l3 - l2) * (l1 + l2 + l3))
|
||||
b = x - c * (l1**2 + l2**2 + l1*l2)
|
||||
a = y1 - (b + l1**2 *c)*l1
|
||||
|
||||
if c < 0:
|
||||
print("//////////////////////////////////////////////////////////////////////////////////////")
|
||||
print("// WARNING: negative coefficient 'c'! Something may be wrong with the measurements! //")
|
||||
print("//////////////////////////////////////////////////////////////////////////////////////")
|
||||
c = -c
|
||||
self.c1 = a # Steinhart-Hart coefficients
|
||||
self.c2 = b
|
||||
self.c3 = c
|
||||
self.rp = rp # pull-up resistance
|
||||
|
||||
def resol(self, adc):
|
||||
"Convert ADC reading into a resolution"
|
||||
res = self.temp(adc)-self.temp(adc+1)
|
||||
return res
|
||||
|
||||
def voltage(self, adc):
|
||||
"Convert ADC reading into a Voltage"
|
||||
return adc * VSTEP # convert the 10 bit ADC value to a voltage
|
||||
|
||||
def resist(self, adc):
|
||||
"Convert ADC reading into a resistance in Ohms"
|
||||
r = self.rp * self.voltage(adc) / (VCC - self.voltage(adc)) # resistance of thermistor
|
||||
return r
|
||||
|
||||
def temp(self, adc):
|
||||
"Convert ADC reading into a temperature in Celcius"
|
||||
l = log(self.resist(adc))
|
||||
Tinv = self.c1 + self.c2*l + self.c3* l**3 # inverse temperature
|
||||
return (1/Tinv) - ZERO # temperature
|
||||
|
||||
def adc(self, temp):
|
||||
"Convert temperature into a ADC reading"
|
||||
x = (self.c1 - (1.0 / (temp+ZERO))) / (2*self.c3)
|
||||
y = sqrt((self.c2 / (3*self.c3))**3 + x**2)
|
||||
r = exp((y-x)**(1.0/3) - (y+x)**(1.0/3))
|
||||
return (r / (self.rp + r)) * ARES
|
||||
|
||||
def main(argv):
|
||||
"Default values"
|
||||
t1 = 25 # low temperature in Kelvin (25 degC)
|
||||
r1 = 100000 # resistance at low temperature (10 kOhm)
|
||||
t2 = 150 # middle temperature in Kelvin (150 degC)
|
||||
r2 = 1641.9 # resistance at middle temperature (1.6 KOhm)
|
||||
t3 = 250 # high temperature in Kelvin (250 degC)
|
||||
r3 = 226.15 # resistance at high temperature (226.15 Ohm)
|
||||
rp = 4700; # pull-up resistor (4.7 kOhm)
|
||||
num_temps = 36; # number of entries for look-up table
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(argv, "h", ["help", "rp=", "t1=", "t2=", "t3=", "num-temps="])
|
||||
except getopt.GetoptError as err:
|
||||
print(str(err))
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
for opt, arg in opts:
|
||||
if opt in ("-h", "--help"):
|
||||
usage()
|
||||
sys.exit()
|
||||
elif opt == "--rp":
|
||||
rp = int(arg)
|
||||
elif opt == "--t1":
|
||||
arg = arg.split(':')
|
||||
t1 = float(arg[0])
|
||||
r1 = float(arg[1])
|
||||
elif opt == "--t2":
|
||||
arg = arg.split(':')
|
||||
t2 = float(arg[0])
|
||||
r2 = float(arg[1])
|
||||
elif opt == "--t3":
|
||||
arg = arg.split(':')
|
||||
t3 = float(arg[0])
|
||||
r3 = float(arg[1])
|
||||
elif opt == "--num-temps":
|
||||
num_temps = int(arg)
|
||||
|
||||
t = Thermistor(rp, t1, r1, t2, r2, t3, r3)
|
||||
increment = int((ARES-1)/(num_temps-1));
|
||||
step = (TMIN-TMAX) / (num_temps-1)
|
||||
low_bound = t.temp(ARES-1);
|
||||
up_bound = t.temp(1);
|
||||
min_temp = int(TMIN if TMIN > low_bound else low_bound)
|
||||
max_temp = int(TMAX if TMAX < up_bound else up_bound)
|
||||
temps = list(range(max_temp, TMIN+step, step));
|
||||
|
||||
print("// Thermistor lookup table for Marlin")
|
||||
print("// ./createTemperatureLookupMarlin.py --rp=%s --t1=%s:%s --t2=%s:%s --t3=%s:%s --num-temps=%s" % (rp, t1, r1, t2, r2, t3, r3, num_temps))
|
||||
print("// Steinhart-Hart Coefficients: a=%.15g, b=%.15g, c=%.15g " % (t.c1, t.c2, t.c3))
|
||||
print("// Theoretical limits of thermistor: %.2f to %.2f degC" % (low_bound, up_bound))
|
||||
print()
|
||||
print("const short temptable[][2] PROGMEM = {")
|
||||
|
||||
for temp in temps:
|
||||
adc = t.adc(temp)
|
||||
print(" { OV(%7.2f), %4s }%s // v=%.3f\tr=%.3f\tres=%.3f degC/count" % (adc , temp, \
|
||||
',' if temp != temps[-1] else ' ', \
|
||||
t.voltage(adc), \
|
||||
t.resist( adc), \
|
||||
t.resol( adc) \
|
||||
))
|
||||
print("};")
|
||||
|
||||
def usage():
|
||||
print(__doc__)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
49
buildroot/share/scripts/findMissingTranslations.sh
Normal file
49
buildroot/share/scripts/findMissingTranslations.sh
Normal file
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# findMissingTranslations.sh
|
||||
#
|
||||
# Locate all language strings needing an update based on English
|
||||
#
|
||||
# Usage: findMissingTranslations.sh [language codes]
|
||||
#
|
||||
# If no language codes are specified then all languages will be checked
|
||||
#
|
||||
|
||||
LANGHOME="Marlin/src/lcd/language"
|
||||
|
||||
[ -d $LANGHOME ] && cd $LANGHOME
|
||||
|
||||
FILES=$(ls language_*.h | grep -v -E "(_en|_test)\.h" | sed -E 's/language_([^\.]+)\.h/\1/')
|
||||
declare -A STRING_MAP
|
||||
|
||||
# Get files matching the given arguments
|
||||
TEST_LANGS=$FILES
|
||||
if [[ -n $@ ]]; then
|
||||
TEST_LANGS=""
|
||||
for K in "$@"; do
|
||||
for F in $FILES; do
|
||||
[[ "$F" != "${F%$K*}" ]] && TEST_LANGS="$TEST_LANGS $F"
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
echo -n "Building list of missing strings..."
|
||||
|
||||
for i in $(awk '/Language_Str/{print $3}' language_en.h); do
|
||||
[[ $i == "MSG_CUBED" ]] && continue
|
||||
LANG_LIST=""
|
||||
for j in $TEST_LANGS; do
|
||||
[[ $(grep -c " ${i} " language_${j}.h) -eq 0 ]] && LANG_LIST="$LANG_LIST $j"
|
||||
done
|
||||
[[ -z $LANG_LIST ]] && continue
|
||||
STRING_MAP[$i]=$LANG_LIST
|
||||
done
|
||||
|
||||
echo
|
||||
|
||||
for K in $( printf "%s\n" "${!STRING_MAP[@]}" | sort ); do
|
||||
case "$#" in
|
||||
1 ) echo $K ;;
|
||||
* ) printf "%-35s :%s\n" "$K" "${STRING_MAP[$K]}" ;;
|
||||
esac
|
||||
done
|
188
buildroot/share/scripts/g29_auto.py
Normal file
188
buildroot/share/scripts/g29_auto.py
Normal file
|
@ -0,0 +1,188 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This file is for preprocessing gcode and the new G29 Autobedleveling from Marlin
|
||||
# It will analyse the first 2 Layer and return the maximum size for this part
|
||||
# After this it will replace with g29_keyword = ';MarlinG29Script' with the new G29 LRFB
|
||||
# the new file will be created in the same folder.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# your gcode-file/folder
|
||||
folder = './'
|
||||
my_file = 'test.gcode'
|
||||
|
||||
# this is the minimum of G1 instructions which should be between 2 different heights
|
||||
min_g1 = 3
|
||||
|
||||
# maximum number of lines to parse, I don't want to parse the complete file
|
||||
# only the first plane is we are interested in
|
||||
max_g1 = 100000000
|
||||
|
||||
# g29 keyword
|
||||
g29_keyword = 'g29'
|
||||
g29_keyword = g29_keyword.upper()
|
||||
|
||||
# output filename
|
||||
output_file = folder + 'g29_' + my_file
|
||||
# input filename
|
||||
input_file = folder + my_file
|
||||
|
||||
# minimum scan size
|
||||
min_size = 40
|
||||
probing_points = 3 # points x points
|
||||
|
||||
# other stuff
|
||||
min_x = 500
|
||||
min_y = min_x
|
||||
max_x = -500
|
||||
max_y = max_x
|
||||
last_z = 0.001
|
||||
|
||||
layer = 0
|
||||
lines_of_g1 = 0
|
||||
|
||||
gcode = []
|
||||
|
||||
|
||||
# return only g1-lines
|
||||
def has_g1(line):
|
||||
return line[:2].upper() == "G1"
|
||||
|
||||
|
||||
# find position in g1 (x,y,z)
|
||||
def find_axis(line, axis):
|
||||
found = False
|
||||
number = ""
|
||||
for char in line:
|
||||
if found:
|
||||
if char == ".":
|
||||
number += char
|
||||
elif char == "-":
|
||||
number += char
|
||||
else:
|
||||
try:
|
||||
int(char)
|
||||
number += char
|
||||
except ValueError:
|
||||
break
|
||||
else:
|
||||
found = char.upper() == axis.upper()
|
||||
try:
|
||||
return float(number)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
# save the min or max-values for each axis
|
||||
def set_mima(line):
|
||||
global min_x, max_x, min_y, max_y, last_z
|
||||
|
||||
current_x = find_axis(line, 'x')
|
||||
current_y = find_axis(line, 'y')
|
||||
|
||||
if current_x is not None:
|
||||
min_x = min(current_x, min_x)
|
||||
max_x = max(current_x, max_x)
|
||||
if current_y is not None:
|
||||
min_y = min(current_y, min_y)
|
||||
max_y = max(current_y, max_y)
|
||||
|
||||
return min_x, max_x, min_y, max_y
|
||||
|
||||
|
||||
# find z in the code and return it
|
||||
def find_z(gcode, start_at_line=0):
|
||||
for i in range(start_at_line, len(gcode)):
|
||||
my_z = find_axis(gcode[i], 'Z')
|
||||
if my_z is not None:
|
||||
return my_z, i
|
||||
|
||||
|
||||
def z_parse(gcode, start_at_line=0, end_at_line=0):
|
||||
i = start_at_line
|
||||
all_z = []
|
||||
line_between_z = []
|
||||
z_at_line = []
|
||||
# last_z = 0
|
||||
last_i = -1
|
||||
|
||||
while len(gcode) > i:
|
||||
try:
|
||||
z, i = find_z(gcode, i + 1)
|
||||
except TypeError:
|
||||
break
|
||||
|
||||
all_z.append(z)
|
||||
z_at_line.append(i)
|
||||
temp_line = i - last_i -1
|
||||
line_between_z.append(i - last_i - 1)
|
||||
# last_z = z
|
||||
last_i = i
|
||||
if 0 < end_at_line <= i or temp_line >= min_g1:
|
||||
# print('break at line {} at heigth {}'.format(i, z))
|
||||
break
|
||||
|
||||
line_between_z = line_between_z[1:]
|
||||
return all_z, line_between_z, z_at_line
|
||||
|
||||
|
||||
# get the lines which should be the first layer
|
||||
def get_lines(gcode, minimum):
|
||||
i = 0
|
||||
all_z, line_between_z, z_at_line = z_parse(gcode, end_at_line=max_g1)
|
||||
for count in line_between_z:
|
||||
i += 1
|
||||
if count > minimum:
|
||||
# print('layer: {}:{}'.format(z_at_line[i-1], z_at_line[i]))
|
||||
return z_at_line[i - 1], z_at_line[i]
|
||||
|
||||
|
||||
with open(input_file, 'r') as file:
|
||||
lines = 0
|
||||
for line in file:
|
||||
lines += 1
|
||||
if lines > 1000:
|
||||
break
|
||||
if has_g1(line):
|
||||
gcode.append(line)
|
||||
file.close()
|
||||
|
||||
start, end = get_lines(gcode, min_g1)
|
||||
for i in range(start, end):
|
||||
set_mima(gcode[i])
|
||||
|
||||
print('x_min:{} x_max:{}\ny_min:{} y_max:{}'.format(min_x, max_x, min_y, max_y))
|
||||
|
||||
# resize min/max - values for minimum scan
|
||||
if max_x - min_x < min_size:
|
||||
offset_x = int((min_size - (max_x - min_x)) / 2 + 0.5) # int round up
|
||||
# print('min_x! with {}'.format(int(max_x - min_x)))
|
||||
min_x = int(min_x) - offset_x
|
||||
max_x = int(max_x) + offset_x
|
||||
if max_y - min_y < min_size:
|
||||
offset_y = int((min_size - (max_y - min_y)) / 2 + 0.5) # int round up
|
||||
# print('min_y! with {}'.format(int(max_y - min_y)))
|
||||
min_y = int(min_y) - offset_y
|
||||
max_y = int(max_y) + offset_y
|
||||
|
||||
|
||||
new_command = 'G29 L{0} R{1} F{2} B{3} P{4}\n'.format(min_x,
|
||||
max_x,
|
||||
min_y,
|
||||
max_y,
|
||||
probing_points)
|
||||
|
||||
out_file = open(output_file, 'w')
|
||||
in_file = open(input_file, 'r')
|
||||
|
||||
for line in in_file:
|
||||
if line[:len(g29_keyword)].upper() == g29_keyword:
|
||||
out_file.write(new_command)
|
||||
print('write G29')
|
||||
else:
|
||||
out_file.write(line)
|
||||
|
||||
file.close()
|
||||
out_file.close()
|
||||
|
||||
print('auto G29 finished')
|
64
buildroot/share/scripts/gen-tft-image.py
Normal file
64
buildroot/share/scripts/gen-tft-image.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# Marlin 3D Printer Firmware
|
||||
# Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
#
|
||||
# Based on Sprinter and grbl.
|
||||
# Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# Generate Marlin TFT Images from bitmaps/PNG/JPG
|
||||
|
||||
import sys,re,struct
|
||||
from PIL import Image,ImageDraw
|
||||
|
||||
def image2bin(image, output_file):
|
||||
if output_file.endswith(('.c', '.cpp')):
|
||||
f = open(output_file, 'wt')
|
||||
is_cpp = True
|
||||
f.write("const uint16_t image[%d] = {\n" % (image.size[1] * image.size[0]))
|
||||
else:
|
||||
f = open(output_file, 'wb')
|
||||
is_cpp = False
|
||||
pixs = image.load()
|
||||
for y in range(image.size[1]):
|
||||
for x in range(image.size[0]):
|
||||
R = pixs[x, y][0] >> 3
|
||||
G = pixs[x, y][1] >> 2
|
||||
B = pixs[x, y][2] >> 3
|
||||
rgb = (R << 11) | (G << 5) | B
|
||||
if is_cpp:
|
||||
strHex = '0x{0:04X}, '.format(rgb)
|
||||
f.write(strHex)
|
||||
else:
|
||||
f.write(struct.pack("B", (rgb & 0xFF)))
|
||||
f.write(struct.pack("B", (rgb >> 8) & 0xFF))
|
||||
if is_cpp:
|
||||
f.write("\n")
|
||||
if is_cpp:
|
||||
f.write("};\n")
|
||||
f.close()
|
||||
|
||||
if len(sys.argv) <= 2:
|
||||
print("Utility to export a image in Marlin TFT friendly format.")
|
||||
print("It will dump a raw bin RGB565 image or create a CPP file with an array of 16 bit image pixels.")
|
||||
print("Usage: gen-tft-image.py INPUT_IMAGE.(png|bmp|jpg) OUTPUT_FILE.(cpp|bin)")
|
||||
print("Author: rhapsodyv")
|
||||
exit(1)
|
||||
|
||||
output_img = sys.argv[2]
|
||||
img = Image.open(sys.argv[1])
|
||||
image2bin(img, output_img)
|
170
buildroot/share/scripts/pinsformat.js
Normal file
170
buildroot/share/scripts/pinsformat.js
Normal file
|
@ -0,0 +1,170 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
//
|
||||
// Formatter script for pins_MYPINS.h files
|
||||
//
|
||||
// Usage: mffmt [infile] [outfile]
|
||||
//
|
||||
// With no parameters convert STDIN to STDOUT
|
||||
//
|
||||
|
||||
const fs = require("fs");
|
||||
|
||||
// String lpad / rpad
|
||||
String.prototype.lpad = function(len, chr) {
|
||||
if (!len) return this;
|
||||
if (chr === undefined) chr = ' ';
|
||||
var s = this+'', need = len - s.length;
|
||||
if (need > 0) s = new Array(need+1).join(chr) + s;
|
||||
return s;
|
||||
};
|
||||
|
||||
String.prototype.rpad = function(len, chr) {
|
||||
if (!len) return this;
|
||||
if (chr === undefined) chr = ' ';
|
||||
var s = this+'', need = len - s.length;
|
||||
if (need > 0) s += new Array(need+1).join(chr);
|
||||
return s;
|
||||
};
|
||||
|
||||
const mpatt = [ '-?\\d+', 'P[A-I]\\d+', 'P\\d_\\d+' ],
|
||||
definePatt = new RegExp(`^\\s*(//)?#define\\s+[A-Z_][A-Z0-9_]+\\s+(${mpatt[0]}|${mpatt[1]}|${mpatt[2]})\\s*(//.*)?$`, 'gm'),
|
||||
ppad = [ 3, 4, 5 ],
|
||||
col_comment = 50,
|
||||
col_value_rj = col_comment - 3;
|
||||
|
||||
var mexpr = [];
|
||||
for (let m of mpatt) mexpr.push(new RegExp('^' + m + '$'));
|
||||
|
||||
const argv = process.argv.slice(2), argc = argv.length;
|
||||
|
||||
var src_file = 0, src_name = 'STDIN', dst_file, do_log = false;
|
||||
if (argc > 0) {
|
||||
let ind = 0;
|
||||
if (argv[0] == '-v') { do_log = true; ind++; }
|
||||
dst_file = src_file = src_name = argv[ind++];
|
||||
if (ind < argc) dst_file = argv[ind];
|
||||
}
|
||||
|
||||
// Read from file or STDIN until it terminates
|
||||
const filtered = process_text(fs.readFileSync(src_file).toString());
|
||||
if (dst_file)
|
||||
fs.writeFileSync(dst_file, filtered);
|
||||
else
|
||||
console.log(filtered);
|
||||
|
||||
// Find the pin pattern so non-pin defines can be skipped
|
||||
function get_pin_pattern(txt) {
|
||||
var r, m = 0, match_count = [ 0, 0, 0 ];
|
||||
definePatt.lastIndex = 0;
|
||||
while ((r = definePatt.exec(txt)) !== null) {
|
||||
let ind = -1;
|
||||
if (mexpr.some((p) => {
|
||||
ind++;
|
||||
const didmatch = r[2].match(p);
|
||||
return r[2].match(p);
|
||||
}) ) {
|
||||
const m = ++match_count[ind];
|
||||
if (m >= 10) {
|
||||
return { match: mpatt[ind], pad:ppad[ind] };
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function process_text(txt) {
|
||||
if (!txt.length) return '(no text)';
|
||||
const patt = get_pin_pattern(txt);
|
||||
if (!patt) return txt;
|
||||
const pindefPatt = new RegExp(`^(\\s*(//)?#define)\\s+([A-Z_][A-Z0-9_]+)\\s+(${patt.match})\\s*(//.*)?$`),
|
||||
noPinPatt = new RegExp(`^(\\s*(//)?#define)\\s+([A-Z_][A-Z0-9_]+)\\s+(-1)\\s*(//.*)?$`),
|
||||
skipPatt = new RegExp('^(\\s*(//)?#define)\\s+(AT90USB|USBCON|BOARD_.+|.+_MACHINE_NAME|.+_SERIAL)\\s+(.+)\\s*(//.*)?$'),
|
||||
aliasPatt = new RegExp('^(\\s*(//)?#define)\\s+([A-Z_][A-Z0-9_]+)\\s+([A-Z_][A-Z0-9_()]+)\\s*(//.*)?$'),
|
||||
switchPatt = new RegExp('^(\\s*(//)?#define)\\s+([A-Z_][A-Z0-9_]+)\\s*(//.*)?$'),
|
||||
undefPatt = new RegExp('^(\\s*(//)?#undef)\\s+([A-Z_][A-Z0-9_]+)\\s*(//.*)?$'),
|
||||
defPatt = new RegExp('^(\\s*(//)?#define)\\s+([A-Z_][A-Z0-9_]+)\\s+([-_\\w]+)\\s*(//.*)?$'),
|
||||
condPatt = new RegExp('^(\\s*(//)?#(if|ifn?def|else|elif)(\\s+\\S+)*)\\s+(//.*)$'),
|
||||
commPatt = new RegExp('^\\s{20,}(//.*)?$');
|
||||
const col_value_lj = col_comment - patt.pad - 2;
|
||||
var r, out = '', check_comment_next = false;
|
||||
txt.split('\n').forEach((line) => {
|
||||
if (check_comment_next)
|
||||
check_comment_next = ((r = commPatt.exec(line)) !== null);
|
||||
|
||||
if (check_comment_next)
|
||||
// Comments in column 45
|
||||
line = ''.rpad(col_comment) + r[1];
|
||||
|
||||
else if ((r = pindefPatt.exec(line)) !== null) {
|
||||
//
|
||||
// #define MY_PIN [pin]
|
||||
//
|
||||
if (do_log) console.log("pin:", line);
|
||||
const pinnum = r[4].charAt(0) == 'P' ? r[4] : r[4].lpad(patt.pad);
|
||||
line = r[1] + ' ' + r[3];
|
||||
line = line.rpad(col_value_lj) + pinnum;
|
||||
if (r[5]) line = line.rpad(col_comment) + r[5];
|
||||
}
|
||||
else if ((r = noPinPatt.exec(line)) !== null) {
|
||||
//
|
||||
// #define MY_PIN -1
|
||||
//
|
||||
if (do_log) console.log("pin -1:", line);
|
||||
line = r[1] + ' ' + r[3];
|
||||
line = line.rpad(col_value_lj) + '-1';
|
||||
if (r[5]) line = line.rpad(col_comment) + r[5];
|
||||
}
|
||||
else if ((r = skipPatt.exec(line)) !== null) {
|
||||
//
|
||||
// #define SKIP_ME
|
||||
//
|
||||
if (do_log) console.log("skip:", line);
|
||||
}
|
||||
else if ((r = aliasPatt.exec(line)) !== null) {
|
||||
//
|
||||
// #define ALIAS OTHER
|
||||
//
|
||||
if (do_log) console.log("alias:", line);
|
||||
line = r[1] + ' ' + r[3];
|
||||
line += r[4].lpad(col_value_rj + 1 - line.length);
|
||||
if (r[5]) line = line.rpad(col_comment) + r[5];
|
||||
}
|
||||
else if ((r = switchPatt.exec(line)) !== null) {
|
||||
//
|
||||
// #define SWITCH
|
||||
//
|
||||
if (do_log) console.log("switch:", line);
|
||||
line = r[1] + ' ' + r[3];
|
||||
if (r[4]) line = line.rpad(col_comment) + r[4];
|
||||
check_comment_next = true;
|
||||
}
|
||||
else if ((r = defPatt.exec(line)) !== null) {
|
||||
//
|
||||
// #define ...
|
||||
//
|
||||
if (do_log) console.log("def:", line);
|
||||
line = r[1] + ' ' + r[3] + ' ';
|
||||
line += r[4].lpad(col_value_rj + 1 - line.length);
|
||||
if (r[5]) line = line.rpad(col_comment - 1) + ' ' + r[5];
|
||||
}
|
||||
else if ((r = undefPatt.exec(line)) !== null) {
|
||||
//
|
||||
// #undef ...
|
||||
//
|
||||
if (do_log) console.log("undef:", line);
|
||||
line = r[1] + ' ' + r[3];
|
||||
if (r[4]) line = line.rpad(col_comment) + r[4];
|
||||
}
|
||||
else if ((r = condPatt.exec(line)) !== null) {
|
||||
//
|
||||
// #if ...
|
||||
//
|
||||
if (do_log) console.log("cond:", line);
|
||||
line = r[1].rpad(col_comment) + r[5];
|
||||
check_comment_next = true;
|
||||
}
|
||||
out += line + '\n';
|
||||
});
|
||||
return out.replace(/\n\n+/g, '\n\n').replace(/\n\n$/g, '\n');
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue