Merge remote-tracking branch 'upstream/edge' into add/universal-panel-adapter
[clinton/Smoothieware.git] / src / libs / utils.cpp
1 /*
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie 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.
4 Smoothie 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.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
6 */
7
8 #include "libs/Kernel.h"
9 #include "libs/utils.h"
10 #include "system_LPC17xx.h"
11 #include "LPC17xx.h"
12 #include "utils.h"
13 using namespace std;
14 #include <string>
15 using std::string;
16 #include <cstring>
17 #include <stdio.h>
18
19 volatile bool _isr_context = false;
20
21 uint16_t get_checksum(const string& to_check){
22 return get_checksum(to_check.c_str());
23 }
24
25 uint16_t get_checksum(const char* to_check){
26 // From: http://en.wikipedia.org/wiki/Fletcher%27s_checksum
27 uint16_t sum1 = 0;
28 uint16_t sum2 = 0;
29 const char* p= to_check;
30 char c;
31 while((c= *p++) != 0) {
32 sum1 = (sum1 + c) % 255;
33 sum2 = (sum2 + sum1) % 255;
34 }
35 return (sum2 << 8) | sum1;
36 }
37
38 void get_checksums(uint16_t check_sums[], const string& key){
39 check_sums[0] = 0x0000;
40 check_sums[1] = 0x0000;
41 check_sums[2] = 0x0000;
42 size_t begin_key = 0;
43 unsigned int counter = 0;
44 while( begin_key < key.size() && counter < 3 ){
45 size_t end_key = key.find_first_of(".", begin_key);
46 string key_node;
47 if(end_key == string::npos) {
48 key_node= key.substr(begin_key);
49 }else{
50 key_node= key.substr(begin_key, end_key-begin_key);
51 }
52
53 check_sums[counter] = get_checksum(key_node);
54 if(end_key == string::npos) break;
55 begin_key = end_key + 1;
56 counter++;
57 }
58 }
59
60 bool is_alpha(int c)
61 {
62 if ((c >= 'a') && (c <= 'z')) return true;
63 if ((c >= 'A') && (c <= 'Z')) return true;
64 if ((c == '_')) return true;
65 return false;
66 }
67
68 bool is_digit(int c)
69 {
70 if ((c >= '0') && (c <= '9')) return true;
71 return false;
72 }
73
74 bool is_numeric(int c)
75 {
76 if (is_digit(c)) return true;
77 if ((c == '.') || (c == '-')) return true;
78 if ((c == 'e')) return true;
79 return false;
80 }
81
82 bool is_alphanum(int c)
83 {
84 return is_alpha(c) || is_numeric(c);
85 }
86
87 bool is_whitespace(int c)
88 {
89 if ((c == ' ') || (c == '\t')) return true;
90 return false;
91 }
92
93 // Convert to lowercase
94 string lc(string str){
95 for (unsigned int i=0; i<strlen(str.c_str()); i++)
96 if (str[i] >= 0x41 && str[i] <= 0x5A)
97 str[i] = str[i] + 0x20;
98 return str;
99 }
100
101 // Remove non-number characters
102 string remove_non_number( string str ){
103 string number_mask = "0123456789-.abcdefpxABCDEFPX";
104 size_t found=str.find_first_not_of(number_mask);
105 while (found!=string::npos){
106 //str[found]='*';
107 str.replace(found,1,"");
108 found=str.find_first_not_of(number_mask);
109 }
110 return str;
111 }
112
113 // Get the first parameter, and remove it from the original string
114 string shift_parameter( string &parameters ){
115 size_t beginning = parameters.find_first_of(" ");
116 if( beginning == string::npos ){ string temp = parameters; parameters = ""; return temp; }
117 string temp = parameters.substr( 0, beginning );
118 parameters = parameters.substr(beginning+1, parameters.size());
119 return temp;
120 }
121
122 // Separate command from arguments
123 string get_arguments( string possible_command ){
124 size_t beginning = possible_command.find_first_of(" ");
125 if( beginning == string::npos ){ return ""; }
126 return possible_command.substr( beginning + 1, possible_command.size() - beginning + 1);
127 }
128
129 // Returns true if the file exists
130 bool file_exists( const string file_name ){
131 bool exists = false;
132 FILE *lp = fopen(file_name.c_str(), "r");
133 if(lp){ exists = true; }
134 fclose(lp);
135 return exists;
136 }
137
138 // Prepares and executes a watchdog reset for dfu or reboot
139 void system_reset( bool dfu ){
140 if(dfu) {
141 LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK
142 uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4
143 LPC_WDT->WDTC = 1 * (float)clk; // Reset in 1 second
144 LPC_WDT->WDMOD = 0x3; // Enabled and Reset
145 LPC_WDT->WDFEED = 0xAA; // Kick the dog!
146 LPC_WDT->WDFEED = 0x55;
147 }else{
148 NVIC_SystemReset();
149 }
150 }
151
152 // Convert a path indication ( absolute or relative ) into a path ( absolute )
153 string absolute_from_relative( string path )
154 {
155 string cwd = THEKERNEL->current_path;
156
157 if ( path.empty() ) {
158 return THEKERNEL->current_path;
159 }
160
161 if ( path[0] == '/' ) {
162 return path;
163 }
164
165 string match = "../" ;
166 while ( path.substr(0,3) == match ) {
167 path = path.substr(3);
168 unsigned found = cwd.find_last_of("/");
169 cwd = cwd.substr(0,found);
170 }
171
172 match = ".." ;
173 if ( path.substr(0,2) == match ) {
174 path = path.substr(2);
175 unsigned found = cwd.find_last_of("/");
176 cwd = cwd.substr(0,found);
177 }
178
179 if ( cwd[cwd.length() - 1] == '/' ) {
180 return cwd + path;
181 }
182
183 return cwd + '/' + path;
184 }