Bläddra i källkod

add HardwareSerial and SoftwareSerial for Re-ARM.

HardwareSerial has been tested on Uart0 (debug header) and Uart3 (i2c connector)
Software Serial has been tested to work bi-directionally at 9600 and 115200
using pins 6 and 63 on J5, and unidirectionally (write only) at 250000.
The code used to test was Teemuatlut's tmc2208 patch, and a few small changes to main used to echo recieved chars back to a host pc.
kfazz 6 år sedan
förälder
incheckning
18f97c4013

+ 4
- 1
Marlin/frameworks/CMSIS/LPC1768/lib/Print.cpp Visa fil

@@ -28,7 +28,10 @@
28 28
 #include "Print.h"
29 29
 #include <stdarg.h>
30 30
 
31
-#define PrintfEnable  0
31
+#define PrintfEnable  1
32
+typedef signed short sint16_t;
33
+typedef signed long sint32_t;
34
+
32 35
 // Public Methods //////////////////////////////////////////////////////////////
33 36
 
34 37
 /* default implementation: may be overridden */

+ 319
- 0
Marlin/frameworks/CMSIS/LPC1768/lib/Stream.cpp Visa fil

@@ -0,0 +1,319 @@
1
+/*
2
+ Stream.cpp - adds parsing methods to Stream class
3
+ Copyright (c) 2008 David A. Mellis.  All right reserved.
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
+
19
+ Created July 2011
20
+ parsing functions based on TextFinder library by Michael Margolis
21
+
22
+ findMulti/findUntil routines written by Jim Leonard/Xuth
23
+ */
24
+
25
+#include <stdlib.h>
26
+#include "../../../../src/HAL/HAL_LPC1768/arduino.h"
27
+
28
+#include "Stream.h"
29
+
30
+#define PARSE_TIMEOUT 1000  // default number of milli-seconds to wait
31
+#define NO_SKIP_CHAR  1  // a magic char not found in a valid ASCII numeric field
32
+
33
+// private method to read stream with timeout
34
+int Stream::timedRead()
35
+{
36
+  int c;
37
+  _startMillis = millis();
38
+  do {
39
+    c = read();
40
+    if (c >= 0) return c;
41
+  } while(millis() - _startMillis < _timeout);
42
+  return -1;     // -1 indicates timeout
43
+}
44
+
45
+// private method to peek stream with timeout
46
+int Stream::timedPeek()
47
+{
48
+  int c;
49
+  _startMillis = millis();
50
+  do {
51
+    c = peek();
52
+    if (c >= 0) return c;
53
+  } while(millis() - _startMillis < _timeout);
54
+  return -1;     // -1 indicates timeout
55
+}
56
+
57
+// returns peek of the next digit in the stream or -1 if timeout
58
+// discards non-numeric characters
59
+int Stream::peekNextDigit()
60
+{
61
+  int c;
62
+  while (1) {
63
+    c = timedPeek();
64
+    if (c < 0) return c;  // timeout
65
+    if (c == '-') return c;
66
+    if (c >= '0' && c <= '9') return c;
67
+    read();  // discard non-numeric
68
+  }
69
+}
70
+
71
+// Public Methods
72
+//////////////////////////////////////////////////////////////
73
+
74
+void Stream::setTimeout(unsigned long timeout)  // sets the maximum number of milliseconds to wait
75
+{
76
+  _timeout = timeout;
77
+}
78
+
79
+ // find returns true if the target string is found
80
+bool  Stream::find(char *target)
81
+{
82
+  return findUntil(target, strlen(target), NULL, 0);
83
+}
84
+
85
+// reads data from the stream until the target string of given length is found
86
+// returns true if target string is found, false if timed out
87
+bool Stream::find(char *target, size_t length)
88
+{
89
+  return findUntil(target, length, NULL, 0);
90
+}
91
+
92
+// as find but search ends if the terminator string is found
93
+bool  Stream::findUntil(char *target, char *terminator)
94
+{
95
+  return findUntil(target, strlen(target), terminator, strlen(terminator));
96
+}
97
+
98
+// reads data from the stream until the target string of the given length is found
99
+// search terminated if the terminator string is found
100
+// returns true if target string is found, false if terminated or timed out
101
+bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
102
+{
103
+  if (terminator == NULL) {
104
+    MultiTarget t[1] = {{target, targetLen, 0}};
105
+    return findMulti(t, 1) == 0 ? true : false;
106
+  } else {
107
+    MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};
108
+    return findMulti(t, 2) == 0 ? true : false;
109
+  }
110
+}
111
+
112
+
113
+// returns the first valid (long) integer value from the current position.
114
+// initial characters that are not digits (or the minus sign) are skipped
115
+// function is terminated by the first character that is not a digit.
116
+long Stream::parseInt()
117
+{
118
+  return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
119
+}
120
+
121
+// as above but a given skipChar is ignored
122
+// this allows format characters (typically commas) in values to be ignored
123
+long Stream::parseInt(char skipChar)
124
+{
125
+  bool isNegative = false;
126
+  long value = 0;
127
+  int c;
128
+
129
+  c = peekNextDigit();
130
+  // ignore non numeric leading characters
131
+  if(c < 0)
132
+    return 0; // zero returned if timeout
133
+
134
+  do{
135
+    if(c == skipChar)
136
+      ; // ignore this charactor
137
+    else if(c == '-')
138
+      isNegative = true;
139
+    else if(c >= '0' && c <= '9')        // is c a digit?
140
+      value = value * 10 + c - '0';
141
+    read();  // consume the character we got with peek
142
+    c = timedPeek();
143
+  }
144
+  while( (c >= '0' && c <= '9') || c == skipChar );
145
+
146
+  if(isNegative)
147
+    value = -value;
148
+  return value;
149
+}
150
+
151
+
152
+// as parseInt but returns a floating point value
153
+float Stream::parseFloat()
154
+{
155
+  return parseFloat(NO_SKIP_CHAR);
156
+}
157
+
158
+// as above but the given skipChar is ignored
159
+// this allows format characters (typically commas) in values to be ignored
160
+float Stream::parseFloat(char skipChar){
161
+  bool isNegative = false;
162
+  bool isFraction = false;
163
+  long value = 0;
164
+  char c;
165
+  float fraction = 1.0;
166
+
167
+  c = peekNextDigit();
168
+    // ignore non numeric leading characters
169
+  if(c < 0)
170
+    return 0; // zero returned if timeout
171
+
172
+  do{
173
+    if(c == skipChar)
174
+      ; // ignore
175
+    else if(c == '-')
176
+      isNegative = true;
177
+    else if (c == '.')
178
+      isFraction = true;
179
+    else if(c >= '0' && c <= '9')  {      // is c a digit?
180
+      value = value * 10 + c - '0';
181
+      if(isFraction)
182
+         fraction *= 0.1;
183
+    }
184
+    read();  // consume the character we got with peek
185
+    c = timedPeek();
186
+  }
187
+  while( (c >= '0' && c <= '9')  || c == '.' || c == skipChar );
188
+
189
+  if(isNegative)
190
+    value = -value;
191
+  if(isFraction)
192
+    return value * fraction;
193
+  else
194
+    return value;
195
+}
196
+
197
+// read characters from stream into buffer
198
+// terminates if length characters have been read, or timeout (see setTimeout)
199
+// returns the number of characters placed in the buffer
200
+// the buffer is NOT null terminated.
201
+//
202
+size_t Stream::readBytes(char *buffer, size_t length)
203
+{
204
+  size_t count = 0;
205
+  while (count < length) {
206
+    int c = timedRead();
207
+    if (c < 0) break;
208
+    *buffer++ = (char)c;
209
+    count++;
210
+  }
211
+  return count;
212
+}
213
+
214
+
215
+// as readBytes with terminator character
216
+// terminates if length characters have been read, timeout, or if the terminator character  detected
217
+// returns the number of characters placed in the buffer (0 means no valid data found)
218
+
219
+size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
220
+{
221
+  if (length < 1) return 0;
222
+  size_t index = 0;
223
+  while (index < length) {
224
+    int c = timedRead();
225
+    if (c < 0 || c == terminator) break;
226
+    *buffer++ = (char)c;
227
+    index++;
228
+  }
229
+  return index; // return number of characters, not including null terminator
230
+}
231
+
232
+String Stream::readString()
233
+{
234
+  String ret;
235
+  int c = timedRead();
236
+  while (c >= 0)
237
+  {
238
+    ret += (char)c;
239
+    c = timedRead();
240
+  }
241
+  return ret;
242
+}
243
+
244
+String Stream::readStringUntil(char terminator)
245
+{
246
+  String ret;
247
+  int c = timedRead();
248
+  while (c >= 0 && c != terminator)
249
+  {
250
+    ret += (char)c;
251
+    c = timedRead();
252
+  }
253
+  return ret;
254
+}
255
+
256
+int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
257
+  // any zero length target string automatically matches and would make
258
+  // a mess of the rest of the algorithm.
259
+  for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
260
+    if (t->len <= 0)
261
+      return t - targets;
262
+  }
263
+
264
+  while (1) {
265
+    int c = timedRead();
266
+    if (c < 0)
267
+      return -1;
268
+
269
+    for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
270
+      // the simple case is if we match, deal with that first.
271
+      if (c == t->str[t->index]) {
272
+        if (++t->index == t->len)
273
+          return t - targets;
274
+        else
275
+          continue;
276
+      }
277
+
278
+      // if not we need to walk back and see if we could have matched further
279
+      // down the stream (ie '1112' doesn't match the first position in '11112'
280
+      // but it will match the second position so we can't just reset the current
281
+      // index to 0 when we find a mismatch.
282
+      if (t->index == 0)
283
+        continue;
284
+
285
+      int origIndex = t->index;
286
+      do {
287
+        --t->index;
288
+        // first check if current char works against the new current index
289
+        if (c != t->str[t->index])
290
+          continue;
291
+
292
+        // if it's the only char then we're good, nothing more to check
293
+        if (t->index == 0) {
294
+          t->index++;
295
+          break;
296
+        }
297
+
298
+        // otherwise we need to check the rest of the found string
299
+        int diff = origIndex - t->index;
300
+        size_t i;
301
+        for (i = 0; i < t->index; ++i) {
302
+          if (t->str[i] != t->str[i + diff])
303
+            break;
304
+        }
305
+
306
+        // if we successfully got through the previous loop then our current
307
+        // index is good.
308
+        if (i == t->index) {
309
+          t->index++;
310
+          break;
311
+        }
312
+
313
+        // otherwise we just try the next index
314
+      } while (t->index);
315
+    }
316
+  }
317
+  // unreachable
318
+  return -1;
319
+}

+ 117
- 0
Marlin/frameworks/CMSIS/LPC1768/lib/Stream.h Visa fil

@@ -0,0 +1,117 @@
1
+/*
2
+  Stream.h - base class for character-based streams.
3
+  Copyright (c) 2010 David A. Mellis.  All right reserved.
4
+
5
+  This library is free software; you can redistribute it and/or
6
+  modify it under the terms of the GNU Lesser General Public
7
+  License as published by the Free Software Foundation; either
8
+  version 2.1 of the License, or (at your option) any later version.
9
+
10
+  This library is distributed in the hope that it will be useful,
11
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
+  Lesser General Public License for more details.
14
+
15
+  You should have received a copy of the GNU Lesser General Public
16
+  License along with this library; if not, write to the Free Software
17
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
+
19
+  parsing functions based on TextFinder library by Michael Margolis
20
+*/
21
+
22
+#ifndef Stream_h
23
+#define Stream_h
24
+
25
+#include <stdint.h>
26
+#include <inttypes.h>
27
+#include "Print.h"
28
+#include "WString.h"
29
+
30
+// compatability macros for testing
31
+/*
32
+#define   getInt()            parseInt()
33
+#define   getInt(skipChar)    parseInt(skipchar)
34
+#define   getFloat()          parseFloat()
35
+#define   getFloat(skipChar)  parseFloat(skipChar)
36
+#define   getString( pre_string, post_string, buffer, length)
37
+readBytesBetween( pre_string, terminator, buffer, length)
38
+*/
39
+
40
+class Stream : public Print
41
+{
42
+  protected:
43
+    unsigned long _timeout;      // number of milliseconds to wait for the next char before aborting timed read
44
+    unsigned long _startMillis;  // used for timeout measurement
45
+    int timedRead();    // private method to read stream with timeout
46
+    int timedPeek();    // private method to peek stream with timeout
47
+    int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
48
+
49
+  public:
50
+    virtual int available() = 0;
51
+    virtual int read() = 0;
52
+    virtual int peek() = 0;
53
+    virtual void flush() = 0;
54
+
55
+    Stream() {_timeout=1000;}
56
+
57
+// parsing methods
58
+
59
+  void setTimeout(unsigned long timeout);  // sets maximum milliseconds to wait for stream data, default is 1 second
60
+
61
+  bool find(char *target);   // reads data from the stream until the target string is found
62
+  bool find(uint8_t *target) { return find ((char *)target); }
63
+  // returns true if target string is found, false if timed out (see setTimeout)
64
+
65
+  bool find(char *target, size_t length);   // reads data from the stream until the target string of given length is found
66
+  bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
67
+  // returns true if target string is found, false if timed out
68
+
69
+  bool find(char target) { return find (&target, 1); }
70
+
71
+  bool findUntil(char *target, char *terminator);   // as find but search ends if the terminator string is found
72
+  bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
73
+
74
+  bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen);   // as above but search ends if the terminate string is found
75
+  bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
76
+
77
+
78
+  long parseInt(); // returns the first valid (long) integer value from the current position.
79
+  // initial characters that are not digits (or the minus sign) are skipped
80
+  // integer is terminated by the first character that is not a digit.
81
+
82
+  float parseFloat();               // float version of parseInt
83
+
84
+  size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
85
+  size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
86
+  // terminates if length characters have been read or timeout (see setTimeout)
87
+  // returns the number of characters placed in the buffer (0 means no valid data found)
88
+
89
+  size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
90
+  size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
91
+  // terminates if length characters have been read, timeout, or if the terminator character  detected
92
+  // returns the number of characters placed in the buffer (0 means no valid data found)
93
+
94
+  // Arduino String functions to be added here
95
+  String readString();
96
+  String readStringUntil(char terminator);
97
+
98
+  protected:
99
+  long parseInt(char skipChar); // as above but the given skipChar is ignored
100
+  // as above but the given skipChar is ignored
101
+  // this allows format characters (typically commas) in values to be ignored
102
+
103
+  float parseFloat(char skipChar);  // as above but the given skipChar is ignored
104
+
105
+  struct MultiTarget {
106
+    const char *str;  // string you're searching for
107
+    size_t len;       // length of string you're searching for
108
+    size_t index;     // index used by the search routine.
109
+  };
110
+
111
+  // This allows you to search for an arbitrary number of strings.
112
+  // Returns index of the target that is found first or -1 if timeout occurs.
113
+  int findMulti(struct MultiTarget *targets, int tCount);
114
+};
115
+
116
+
117
+#endif

+ 229
- 0
Marlin/frameworks/CMSIS/LPC1768/lib/WString.h Visa fil

@@ -0,0 +1,229 @@
1
+/*
2
+  WString.h - String library for Wiring & Arduino
3
+  ...mostly rewritten by Paul Stoffregen...
4
+  Copyright (c) 2009-10 Hernando Barragan.  All right reserved.
5
+  Copyright 2011, Paul Stoffregen, paul@pjrc.com
6
+
7
+  This library is free software; you can redistribute it and/or
8
+  modify it under the terms of the GNU Lesser General Public
9
+  License as published by the Free Software Foundation; either
10
+  version 2.1 of the License, or (at your option) any later version.
11
+
12
+  This library is distributed in the hope that it will be useful,
13
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
+  Lesser General Public License for more details.
16
+
17
+  You should have received a copy of the GNU Lesser General Public
18
+  License along with this library; if not, write to the Free Software
19
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
+*/
21
+
22
+#ifndef String_class_h
23
+#define String_class_h
24
+#ifdef __cplusplus
25
+
26
+#include <stdlib.h>
27
+#include <string.h>
28
+#include <ctype.h>
29
+//#include <avr/pgmspace.h>
30
+
31
+// When compiling programs with this class, the following gcc parameters
32
+// dramatically increase performance and memory (RAM) efficiency, typically
33
+// with little or no increase in code size.
34
+//     -felide-constructors
35
+//     -std=c++0x
36
+
37
+class __FlashStringHelper;
38
+#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
39
+
40
+// An inherited class for holding the result of a concatenation.  These
41
+// result objects are assumed to be writable by subsequent concatenations.
42
+class StringSumHelper;
43
+
44
+// The string class
45
+class String
46
+{
47
+	// use a function pointer to allow for "if (s)" without the
48
+	// complications of an operator bool(). for more information, see:
49
+	// http://www.artima.com/cppsource/safebool.html
50
+	typedef void (String::*StringIfHelperType)() const;
51
+	void StringIfHelper() const {}
52
+
53
+public:
54
+	// constructors
55
+	// creates a copy of the initial value.
56
+	// if the initial value is null or invalid, or if memory allocation
57
+	// fails, the string will be marked as invalid (i.e. "if (s)" will
58
+	// be false).
59
+	String(const char *cstr = "");
60
+	String(const String &str);
61
+	String(const __FlashStringHelper *str);
62
+       #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
63
+	String(String &&rval);
64
+	String(StringSumHelper &&rval);
65
+	#endif
66
+	explicit String(char c);
67
+	explicit String(unsigned char, unsigned char base=10);
68
+	explicit String(int, unsigned char base=10);
69
+	explicit String(unsigned int, unsigned char base=10);
70
+	explicit String(long, unsigned char base=10);
71
+	explicit String(unsigned long, unsigned char base=10);
72
+	explicit String(float, unsigned char decimalPlaces=2);
73
+	explicit String(double, unsigned char decimalPlaces=2);
74
+	~String(void);
75
+
76
+	// memory management
77
+	// return true on success, false on failure (in which case, the string
78
+	// is left unchanged).  reserve(0), if successful, will validate an
79
+	// invalid string (i.e., "if (s)" will be true afterwards)
80
+	unsigned char reserve(unsigned int size);
81
+	inline unsigned int length(void) const {return len;}
82
+
83
+	// creates a copy of the assigned value.  if the value is null or
84
+	// invalid, or if the memory allocation fails, the string will be
85
+	// marked as invalid ("if (s)" will be false).
86
+	String & operator = (const String &rhs);
87
+	String & operator = (const char *cstr);
88
+	String & operator = (const __FlashStringHelper *str);
89
+       #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
90
+	String & operator = (String &&rval);
91
+	String & operator = (StringSumHelper &&rval);
92
+	#endif
93
+
94
+	// concatenate (works w/ built-in types)
95
+
96
+	// returns true on success, false on failure (in which case, the string
97
+	// is left unchanged).  if the argument is null or invalid, the
98
+	// concatenation is considered unsucessful.
99
+	unsigned char concat(const String &str);
100
+	unsigned char concat(const char *cstr);
101
+	unsigned char concat(char c);
102
+	unsigned char concat(unsigned char c);
103
+	unsigned char concat(int num);
104
+	unsigned char concat(unsigned int num);
105
+	unsigned char concat(long num);
106
+	unsigned char concat(unsigned long num);
107
+	unsigned char concat(float num);
108
+	unsigned char concat(double num);
109
+	unsigned char concat(const __FlashStringHelper * str);
110
+
111
+	// if there's not enough memory for the concatenated value, the string
112
+	// will be left unchanged (but this isn't signalled in any way)
113
+	String & operator += (const String &rhs)	{concat(rhs); return (*this);}
114
+	String & operator += (const char *cstr)		{concat(cstr); return (*this);}
115
+	String & operator += (char c)			{concat(c); return (*this);}
116
+	String & operator += (unsigned char num)		{concat(num); return (*this);}
117
+	String & operator += (int num)			{concat(num); return (*this);}
118
+	String & operator += (unsigned int num)		{concat(num); return (*this);}
119
+	String & operator += (long num)			{concat(num); return (*this);}
120
+	String & operator += (unsigned long num)	{concat(num); return (*this);}
121
+	String & operator += (float num)		{concat(num); return (*this);}
122
+	String & operator += (double num)		{concat(num); return (*this);}
123
+	String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
124
+
125
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
126
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
127
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
128
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
129
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
130
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
131
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
132
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
133
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
134
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
135
+	friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
136
+
137
+	// comparison (only works w/ Strings and "strings")
138
+	operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
139
+	int compareTo(const String &s) const;
140
+	unsigned char equals(const String &s) const;
141
+	unsigned char equals(const char *cstr) const;
142
+	unsigned char operator == (const String &rhs) const {return equals(rhs);}
143
+	unsigned char operator == (const char *cstr) const {return equals(cstr);}
144
+	unsigned char operator != (const String &rhs) const {return !equals(rhs);}
145
+	unsigned char operator != (const char *cstr) const {return !equals(cstr);}
146
+	unsigned char operator <  (const String &rhs) const;
147
+	unsigned char operator >  (const String &rhs) const;
148
+	unsigned char operator <= (const String &rhs) const;
149
+	unsigned char operator >= (const String &rhs) const;
150
+	unsigned char equalsIgnoreCase(const String &s) const;
151
+	unsigned char startsWith( const String &prefix) const;
152
+	unsigned char startsWith(const String &prefix, unsigned int offset) const;
153
+	unsigned char endsWith(const String &suffix) const;
154
+
155
+	// character acccess
156
+	char charAt(unsigned int index) const;
157
+	void setCharAt(unsigned int index, char c);
158
+	char operator [] (unsigned int index) const;
159
+	char& operator [] (unsigned int index);
160
+	void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
161
+	void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
162
+		{ getBytes((unsigned char *)buf, bufsize, index); }
163
+	const char* c_str() const { return buffer; }
164
+	char* begin() { return buffer; }
165
+	char* end() { return buffer + length(); }
166
+	const char* begin() const { return c_str(); }
167
+	const char* end() const { return c_str() + length(); }
168
+
169
+	// search
170
+	int indexOf( char ch ) const;
171
+	int indexOf( char ch, unsigned int fromIndex ) const;
172
+	int indexOf( const String &str ) const;
173
+	int indexOf( const String &str, unsigned int fromIndex ) const;
174
+	int lastIndexOf( char ch ) const;
175
+	int lastIndexOf( char ch, unsigned int fromIndex ) const;
176
+	int lastIndexOf( const String &str ) const;
177
+	int lastIndexOf( const String &str, unsigned int fromIndex ) const;
178
+	String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
179
+	String substring( unsigned int beginIndex, unsigned int endIndex ) const;
180
+
181
+	// modification
182
+	void replace(char find, char replace);
183
+	void replace(const String& find, const String& replace);
184
+	void remove(unsigned int index);
185
+	void remove(unsigned int index, unsigned int count);
186
+	void toLowerCase(void);
187
+	void toUpperCase(void);
188
+	void trim(void);
189
+
190
+	// parsing/conversion
191
+	long toInt(void) const;
192
+	float toFloat(void) const;
193
+	double toDouble(void) const;
194
+
195
+protected:
196
+	char *buffer;	        // the actual char array
197
+	unsigned int capacity;  // the array length minus one (for the '\0')
198
+	unsigned int len;       // the String length (not counting the '\0')
199
+protected:
200
+	void init(void);
201
+	void invalidate(void);
202
+	unsigned char changeBuffer(unsigned int maxStrLen);
203
+	unsigned char concat(const char *cstr, unsigned int length);
204
+
205
+	// copy and move
206
+	String & copy(const char *cstr, unsigned int length);
207
+	String & copy(const __FlashStringHelper *pstr, unsigned int length);
208
+       #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
209
+	void move(String &rhs);
210
+	#endif
211
+};
212
+
213
+class StringSumHelper : public String
214
+{
215
+public:
216
+	StringSumHelper(const String &s) : String(s) {}
217
+	StringSumHelper(const char *p) : String(p) {}
218
+	StringSumHelper(char c) : String(c) {}
219
+	StringSumHelper(unsigned char num) : String(num) {}
220
+	StringSumHelper(int num) : String(num) {}
221
+	StringSumHelper(unsigned int num) : String(num) {}
222
+	StringSumHelper(long num) : String(num) {}
223
+	StringSumHelper(unsigned long num) : String(num) {}
224
+	StringSumHelper(float num) : String(num) {}
225
+	StringSumHelper(double num) : String(num) {}
226
+};
227
+
228
+#endif  // __cplusplus
229
+#endif  // String_class_h

+ 636
- 0
Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp Visa fil

@@ -0,0 +1,636 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../../../macros.h"
24
+#include "../HAL.h"
25
+#include "HardwareSerial.h"
26
+#define UART3 3
27
+HardwareSerial Serial3 = HardwareSerial(UART3);
28
+
29
+volatile uint32_t UART0Status, UART1Status, UART2Status, UART3Status;
30
+volatile uint8_t UART0TxEmpty = 1, UART1TxEmpty = 1, UART2TxEmpty=1, UART3TxEmpty=1;
31
+volatile uint8_t UART0Buffer[UARTRXQUEUESIZE], UART1Buffer[UARTRXQUEUESIZE], UART2Buffer[UARTRXQUEUESIZE], UART3Buffer[UARTRXQUEUESIZE];
32
+volatile uint32_t UART0RxQueueWritePos = 0, UART1RxQueueWritePos = 0, UART2RxQueueWritePos = 0, UART3RxQueueWritePos = 0;
33
+volatile uint32_t UART0RxQueueReadPos = 0, UART1RxQueueReadPos = 0, UART2RxQueueReadPos = 0, UART3RxQueueReadPos = 0;
34
+volatile uint8_t dummy;
35
+
36
+  void HardwareSerial::begin(uint32_t baudrate) {
37
+    uint32_t Fdiv;
38
+     uint32_t pclkdiv, pclk;
39
+
40
+     if ( PortNum == 0 )
41
+     {
42
+   	LPC_PINCON->PINSEL0 &= ~0x000000F0;
43
+   	LPC_PINCON->PINSEL0 |= 0x00000050;  /* RxD0 is P0.3 and TxD0 is P0.2 */
44
+   	/* By default, the PCLKSELx value is zero, thus, the PCLK for
45
+   	all the peripherals is 1/4 of the SystemFrequency. */
46
+   	/* Bit 6~7 is for UART0 */
47
+   	pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03;
48
+   	switch ( pclkdiv )
49
+   	{
50
+   	  case 0x00:
51
+   	  default:
52
+   		pclk = SystemCoreClock/4;
53
+   		break;
54
+   	  case 0x01:
55
+   		pclk = SystemCoreClock;
56
+   		break;
57
+   	  case 0x02:
58
+   		pclk = SystemCoreClock/2;
59
+   		break;
60
+   	  case 0x03:
61
+   		pclk = SystemCoreClock/8;
62
+   		break;
63
+   	}
64
+
65
+       LPC_UART0->LCR = 0x83;		/* 8 bits, no Parity, 1 Stop bit */
66
+   	Fdiv = ( pclk / 16 ) / baudrate ;	/*baud rate */
67
+       LPC_UART0->DLM = Fdiv / 256;
68
+       LPC_UART0->DLL = Fdiv % 256;
69
+   	LPC_UART0->LCR = 0x03;		/* DLAB = 0 */
70
+       LPC_UART0->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */
71
+
72
+      	NVIC_EnableIRQ(UART0_IRQn);
73
+
74
+       LPC_UART0->IER = IER_RBR | IER_THRE | IER_RLS;	/* Enable UART0 interrupt */
75
+     }
76
+     else if ( PortNum == 1 )
77
+     {
78
+   	LPC_PINCON->PINSEL4 &= ~0x0000000F;
79
+   	LPC_PINCON->PINSEL4 |= 0x0000000A;	/* Enable RxD1 P2.1, TxD1 P2.0 */
80
+
81
+   	/* By default, the PCLKSELx value is zero, thus, the PCLK for
82
+   	all the peripherals is 1/4 of the SystemFrequency. */
83
+   	/* Bit 8,9 are for UART1 */
84
+   	pclkdiv = (LPC_SC->PCLKSEL0 >> 8) & 0x03;
85
+   	switch ( pclkdiv )
86
+   	{
87
+   	  case 0x00:
88
+   	  default:
89
+   		pclk = SystemCoreClock/4;
90
+   		break;
91
+   	  case 0x01:
92
+   		pclk = SystemCoreClock;
93
+   		break;
94
+   	  case 0x02:
95
+   		pclk = SystemCoreClock/2;
96
+   		break;
97
+   	  case 0x03:
98
+   		pclk = SystemCoreClock/8;
99
+   		break;
100
+   	}
101
+
102
+       LPC_UART1->LCR = 0x83;		/* 8 bits, no Parity, 1 Stop bit */
103
+   	Fdiv = ( pclk / 16 ) / baudrate ;	/*baud rate */
104
+       LPC_UART1->DLM = Fdiv / 256;
105
+       LPC_UART1->DLL = Fdiv % 256;
106
+   	LPC_UART1->LCR = 0x03;		/* DLAB = 0 */
107
+       LPC_UART1->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */
108
+
109
+      	NVIC_EnableIRQ(UART1_IRQn);
110
+
111
+       LPC_UART1->IER = IER_RBR | IER_THRE | IER_RLS;	/* Enable UART1 interrupt */
112
+     }
113
+     else if ( PortNum == 2 )
114
+     {
115
+   	  //LPC_PINCON->PINSEL4 &= ~0x000F0000;  /*Pinsel4 Bits 16-19*/
116
+   	  //LPC_PINCON->PINSEL4 |=  0x000A0000;  /* RxD2 is P2.9 and TxD2 is P2.8, value 10*/
117
+   	  LPC_PINCON->PINSEL0 &= ~0x00F00000;  /*Pinsel0 Bits 20-23*/
118
+   	  LPC_PINCON->PINSEL0 |=  0x00500000;  /* RxD2 is P0.11 and TxD2 is P0.10, value 01*/
119
+
120
+   	  LPC_SC->PCONP |= 1<<24; //Enable PCUART2
121
+   	  /* By default, the PCLKSELx value is zero, thus, the PCLK for
122
+   		all the peripherals is 1/4 of the SystemFrequency. */
123
+   	  /* Bit 6~7 is for UART3 */
124
+   	  pclkdiv = (LPC_SC->PCLKSEL1 >> 16) & 0x03;
125
+   	  switch ( pclkdiv )
126
+   	  {
127
+   	  case 0x00:
128
+   	  default:
129
+   		  pclk = SystemCoreClock/4;
130
+   		  break;
131
+   	  case 0x01:
132
+   		  pclk = SystemCoreClock;
133
+   		  break;
134
+   	  case 0x02:
135
+   		  pclk = SystemCoreClock/2;
136
+   		  break;
137
+   	  case 0x03:
138
+   		  pclk = SystemCoreClock/8;
139
+   		  break;
140
+   	  }
141
+   	  LPC_UART2->LCR = 0x83;		/* 8 bits, no Parity, 1 Stop bit */
142
+   	  Fdiv = ( pclk / 16 ) / baudrate ;	/*baud rate */
143
+   	  LPC_UART2->DLM = Fdiv / 256;
144
+   	  LPC_UART2->DLL = Fdiv % 256;
145
+   	  LPC_UART2->LCR = 0x03;		/* DLAB = 0 */
146
+   	  LPC_UART2->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */
147
+
148
+   	  NVIC_EnableIRQ(UART2_IRQn);
149
+
150
+   	  LPC_UART2->IER = IER_RBR | IER_THRE | IER_RLS;	/* Enable UART3 interrupt */
151
+     }
152
+     else if ( PortNum == 3 )
153
+     {
154
+   	  LPC_PINCON->PINSEL0 &= ~0x0000000F;
155
+   	  LPC_PINCON->PINSEL0 |=  0x0000000A;  /* RxD3 is P0.1 and TxD3 is P0.0 */
156
+   	  LPC_SC->PCONP |= 1<<4 | 1<<25; //Enable PCUART1
157
+   	  /* By default, the PCLKSELx value is zero, thus, the PCLK for
158
+   		all the peripherals is 1/4 of the SystemFrequency. */
159
+   	  /* Bit 6~7 is for UART3 */
160
+   	  pclkdiv = (LPC_SC->PCLKSEL1 >> 18) & 0x03;
161
+   	  switch ( pclkdiv )
162
+   	  {
163
+   	  case 0x00:
164
+   	  default:
165
+   		  pclk = SystemCoreClock/4;
166
+   		  break;
167
+   	  case 0x01:
168
+   		  pclk = SystemCoreClock;
169
+   		  break;
170
+   	  case 0x02:
171
+   		  pclk = SystemCoreClock/2;
172
+   		  break;
173
+   	  case 0x03:
174
+   		  pclk = SystemCoreClock/8;
175
+   		  break;
176
+   	  }
177
+   	  LPC_UART3->LCR = 0x83;		/* 8 bits, no Parity, 1 Stop bit */
178
+   	  Fdiv = ( pclk / 16 ) / baudrate ;	/*baud rate */
179
+   	  LPC_UART3->DLM = Fdiv / 256;
180
+   	  LPC_UART3->DLL = Fdiv % 256;
181
+   	  LPC_UART3->LCR = 0x03;		/* DLAB = 0 */
182
+   	  LPC_UART3->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */
183
+
184
+   	  NVIC_EnableIRQ(UART3_IRQn);
185
+
186
+   	  LPC_UART3->IER = IER_RBR | IER_THRE | IER_RLS;	/* Enable UART3 interrupt */
187
+     }
188
+  }
189
+
190
+  int HardwareSerial::read() {
191
+    uint8_t rx;
192
+  	if ( PortNum == 0 )
193
+  	  {
194
+  		  if (UART0RxQueueReadPos == UART0RxQueueWritePos)
195
+  		    return -1;
196
+
197
+  		  // Read from "head"
198
+  		  rx = UART0Buffer[UART0RxQueueReadPos]; // grab next byte
199
+  		  UART0RxQueueReadPos = (UART0RxQueueReadPos + 1) % UARTRXQUEUESIZE;
200
+  		  return rx;
201
+  	  }
202
+  	  if ( PortNum == 1 )
203
+  	  {
204
+  		  if (UART1RxQueueReadPos == UART1RxQueueWritePos)
205
+  		    return -1;
206
+
207
+  		  // Read from "head"
208
+  		  rx = UART1Buffer[UART1RxQueueReadPos]; // grab next byte
209
+  		  UART1RxQueueReadPos = (UART1RxQueueReadPos + 1) % UARTRXQUEUESIZE;
210
+  		  return rx;
211
+  	  }
212
+  	  if ( PortNum == 2 )
213
+  	  {
214
+  		  if (UART2RxQueueReadPos == UART2RxQueueWritePos)
215
+  		    return -1;
216
+
217
+  		  // Read from "head"
218
+  		  rx = UART2Buffer[UART2RxQueueReadPos]; // grab next byte
219
+  		  UART2RxQueueReadPos = (UART2RxQueueReadPos + 1) % UARTRXQUEUESIZE;
220
+  		  return rx;
221
+  	  }
222
+  	  if ( PortNum == 3 )
223
+  	  {
224
+  		  if (UART3RxQueueReadPos == UART3RxQueueWritePos)
225
+  		    return -1;
226
+
227
+  		  // Read from "head"
228
+  		  rx = UART3Buffer[UART3RxQueueReadPos]; // grab next byte
229
+  		  UART3RxQueueReadPos = (UART3RxQueueReadPos + 1) % UARTRXQUEUESIZE;
230
+  		  return rx;
231
+  	  }
232
+  	  return 0;
233
+  }
234
+
235
+  size_t HardwareSerial::write(uint8_t send) {
236
+    if ( PortNum == 0 )
237
+     {
238
+   	  /* THRE status, contain valid data */
239
+   	  while ( !(UART0TxEmpty & 0x01) );
240
+   	  LPC_UART0->THR = send;
241
+   	  UART0TxEmpty = 0;	/* not empty in the THR until it shifts out */
242
+     }
243
+     else if (PortNum == 1)
244
+     {
245
+
246
+   	  /* THRE status, contain valid data */
247
+   	  while ( !(UART1TxEmpty & 0x01) );
248
+   	  LPC_UART1->THR = send;
249
+   	  UART1TxEmpty = 0;	/* not empty in the THR until it shifts out */
250
+
251
+
252
+     }
253
+     else if ( PortNum == 2 )
254
+     {
255
+   	  /* THRE status, contain valid data */
256
+   	  while ( !(UART2TxEmpty & 0x01) );
257
+   	  LPC_UART2->THR = send;
258
+   	  UART2TxEmpty = 0;	/* not empty in the THR until it shifts out */
259
+
260
+     }
261
+     else if ( PortNum == 3 )
262
+     {
263
+   	  /* THRE status, contain valid data */
264
+   	  while ( !(UART3TxEmpty & 0x01) );
265
+   	  LPC_UART3->THR = send;
266
+   	  UART3TxEmpty = 0;	/* not empty in the THR until it shifts out */
267
+
268
+     }
269
+     return 0;
270
+  }
271
+
272
+  int HardwareSerial::available() {
273
+    if ( PortNum == 0 )
274
+{
275
+  return (UART0RxQueueWritePos + UARTRXQUEUESIZE - UART0RxQueueReadPos) % UARTRXQUEUESIZE;
276
+}
277
+if ( PortNum == 1 )
278
+{
279
+  return (UART1RxQueueWritePos + UARTRXQUEUESIZE - UART1RxQueueReadPos) % UARTRXQUEUESIZE;
280
+}
281
+if ( PortNum == 2 )
282
+{
283
+  return (UART2RxQueueWritePos + UARTRXQUEUESIZE - UART2RxQueueReadPos) % UARTRXQUEUESIZE;
284
+}
285
+if ( PortNum == 3 )
286
+{
287
+  return (UART3RxQueueWritePos + UARTRXQUEUESIZE - UART3RxQueueReadPos) % UARTRXQUEUESIZE;
288
+}
289
+return 0;
290
+  }
291
+
292
+  void HardwareSerial::flush() {
293
+    if ( PortNum == 0 )
294
+{
295
+  UART0RxQueueWritePos = 0;
296
+  UART0RxQueueReadPos = 0;
297
+
298
+}
299
+if ( PortNum == 1 )
300
+{
301
+  UART1RxQueueWritePos = 0;
302
+  UART1RxQueueReadPos = 0;
303
+}
304
+if ( PortNum == 2 )
305
+{
306
+  UART2RxQueueWritePos = 0;
307
+  UART2RxQueueReadPos = 0;
308
+}
309
+if ( PortNum == 3 )
310
+{
311
+  UART3RxQueueWritePos = 0;
312
+  UART3RxQueueReadPos = 0;
313
+}
314
+return;
315
+  }
316
+
317
+  void HardwareSerial::printf(const char *format, ...) {
318
+    static char buffer[256];
319
+    va_list vArgs;
320
+    va_start(vArgs, format);
321
+    int length = vsnprintf((char *) buffer, 256, (char const *) format, vArgs);
322
+    va_end(vArgs);
323
+    if (length > 0 && length < 256) {
324
+        for (int i = 0; i < length;) {
325
+          write(buffer[i]);
326
+            ++i;
327
+          }
328
+        }
329
+    }
330
+
331
+#ifdef __cplusplus
332
+extern "C" {
333
+#endif
334
+
335
+/*****************************************************************************
336
+** Function name:		UART0_IRQHandler
337
+**
338
+** Descriptions:		UART0 interrupt handler
339
+**
340
+** parameters:			None
341
+** Returned value:		None
342
+**
343
+*****************************************************************************/
344
+void UART0_IRQHandler (void)
345
+{
346
+  uint8_t IIRValue, LSRValue;
347
+  uint8_t Dummy = Dummy;
348
+
349
+  IIRValue = LPC_UART0->IIR;
350
+
351
+  IIRValue >>= 1;			/* skip pending bit in IIR */
352
+  IIRValue &= 0x07;			/* check bit 1~3, interrupt identification */
353
+  if ( IIRValue == IIR_RLS )		/* Receive Line Status */
354
+  {
355
+	LSRValue = LPC_UART0->LSR;
356
+	/* Receive Line Status */
357
+	if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
358
+	{
359
+	  /* There are errors or break interrupt */
360
+	  /* Read LSR will clear the interrupt */
361
+	  UART0Status = LSRValue;
362
+	  Dummy = LPC_UART0->RBR;		/* Dummy read on RX to clear
363
+							interrupt, then bail out */
364
+	  return;
365
+	}
366
+	if ( LSRValue & LSR_RDR )	/* Receive Data Ready */
367
+	{
368
+	  /* If no error on RLS, normal ready, save into the data buffer. */
369
+	  /* Note: read RBR will clear the interrupt */
370
+		  if ((UART0RxQueueWritePos+1) % UARTRXQUEUESIZE != UART0RxQueueReadPos)
371
+		  {
372
+			  UART0Buffer[UART0RxQueueWritePos] = LPC_UART0->RBR;
373
+			  UART0RxQueueWritePos = (UART0RxQueueWritePos+1) % UARTRXQUEUESIZE;
374
+		  }
375
+		  else
376
+			  dummy = LPC_UART0->RBR;;
377
+	}
378
+  }
379
+  else if ( IIRValue == IIR_RDA )	/* Receive Data Available */
380
+  {
381
+	/* Receive Data Available */
382
+	  if ((UART0RxQueueWritePos+1) % UARTRXQUEUESIZE != UART0RxQueueReadPos)
383
+	  {
384
+		  UART0Buffer[UART0RxQueueWritePos] = LPC_UART0->RBR;
385
+		  UART0RxQueueWritePos = (UART0RxQueueWritePos+1) % UARTRXQUEUESIZE;
386
+	  }
387
+	  else
388
+		  dummy = LPC_UART1->RBR;;
389
+  }
390
+  else if ( IIRValue == IIR_CTI )	/* Character timeout indicator */
391
+  {
392
+	/* Character Time-out indicator */
393
+	UART0Status |= 0x100;		/* Bit 9 as the CTI error */
394
+  }
395
+  else if ( IIRValue == IIR_THRE )	/* THRE, transmit holding register empty */
396
+  {
397
+	/* THRE interrupt */
398
+	LSRValue = LPC_UART0->LSR;		/* Check status in the LSR to see if
399
+									valid data in U0THR or not */
400
+	if ( LSRValue & LSR_THRE )
401
+	{
402
+	  UART0TxEmpty = 1;
403
+	}
404
+	else
405
+	{
406
+	  UART0TxEmpty = 0;
407
+	}
408
+  }
409
+}
410
+
411
+/*****************************************************************************
412
+** Function name:		UART1_IRQHandler
413
+**
414
+** Descriptions:		UART1 interrupt handler
415
+**
416
+** parameters:			None
417
+** Returned value:		None
418
+**
419
+*****************************************************************************/
420
+void UART1_IRQHandler (void)
421
+{
422
+  uint8_t IIRValue, LSRValue;
423
+  uint8_t Dummy = Dummy;
424
+
425
+  IIRValue = LPC_UART1->IIR;
426
+
427
+  IIRValue >>= 1;			/* skip pending bit in IIR */
428
+  IIRValue &= 0x07;			/* check bit 1~3, interrupt identification */
429
+  if ( IIRValue == IIR_RLS )		/* Receive Line Status */
430
+  {
431
+	LSRValue = LPC_UART1->LSR;
432
+	/* Receive Line Status */
433
+	if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
434
+	{
435
+	  /* There are errors or break interrupt */
436
+	  /* Read LSR will clear the interrupt */
437
+	  UART1Status = LSRValue;
438
+	  Dummy = LPC_UART1->RBR;		/* Dummy read on RX to clear
439
+								interrupt, then bail out */
440
+	  return;
441
+	}
442
+	if ( LSRValue & LSR_RDR )	/* Receive Data Ready */
443
+	{
444
+	  /* If no error on RLS, normal ready, save into the data buffer. */
445
+	  /* Note: read RBR will clear the interrupt */
446
+	  if ((UART1RxQueueWritePos+1) % UARTRXQUEUESIZE != UART1RxQueueReadPos)
447
+	  {
448
+		  UART1Buffer[UART1RxQueueWritePos] = LPC_UART1->RBR;
449
+		  UART1RxQueueWritePos =(UART1RxQueueWritePos+1) % UARTRXQUEUESIZE;
450
+	  }
451
+	  else
452
+		  dummy = LPC_UART1->RBR;;
453
+	}
454
+  }
455
+  else if ( IIRValue == IIR_RDA )	/* Receive Data Available */
456
+  {
457
+	/* Receive Data Available */
458
+	  if ((UART1RxQueueWritePos+1) % UARTRXQUEUESIZE != UART1RxQueueReadPos)
459
+	  {
460
+		  UART1Buffer[UART1RxQueueWritePos] = LPC_UART1->RBR;
461
+		  UART1RxQueueWritePos = (UART1RxQueueWritePos+1) % UARTRXQUEUESIZE;
462
+	  }
463
+	  else
464
+		  dummy = LPC_UART1->RBR;;
465
+  }
466
+  else if ( IIRValue == IIR_CTI )	/* Character timeout indicator */
467
+  {
468
+	/* Character Time-out indicator */
469
+	UART1Status |= 0x100;		/* Bit 9 as the CTI error */
470
+  }
471
+  else if ( IIRValue == IIR_THRE )	/* THRE, transmit holding register empty */
472
+  {
473
+	/* THRE interrupt */
474
+	LSRValue = LPC_UART1->LSR;		/* Check status in the LSR to see if
475
+								valid data in U0THR or not */
476
+	if ( LSRValue & LSR_THRE )
477
+	{
478
+	  UART1TxEmpty = 1;
479
+	}
480
+	else
481
+	{
482
+	  UART1TxEmpty = 0;
483
+	}
484
+  }
485
+
486
+}
487
+/*****************************************************************************
488
+** Function name:		UART2_IRQHandler
489
+**
490
+** Descriptions:		UART2 interrupt handler
491
+**
492
+** parameters:			None
493
+** Returned value:		None
494
+**
495
+*****************************************************************************/
496
+void UART2_IRQHandler (void)
497
+{
498
+  uint8_t IIRValue, LSRValue;
499
+  uint8_t Dummy = Dummy;
500
+
501
+  IIRValue = LPC_UART2->IIR;
502
+
503
+  IIRValue >>= 1;			/* skip pending bit in IIR */
504
+  IIRValue &= 0x07;			/* check bit 1~3, interrupt identification */
505
+  if ( IIRValue == IIR_RLS )		/* Receive Line Status */
506
+  {
507
+	LSRValue = LPC_UART2->LSR;
508
+	/* Receive Line Status */
509
+	if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
510
+	{
511
+	  /* There are errors or break interrupt */
512
+	  /* Read LSR will clear the interrupt */
513
+	  UART2Status = LSRValue;
514
+	  Dummy = LPC_UART2->RBR;		/* Dummy read on RX to clear
515
+							interrupt, then bail out */
516
+	  return;
517
+	}
518
+	if ( LSRValue & LSR_RDR )	/* Receive Data Ready */
519
+	{
520
+	  /* If no error on RLS, normal ready, save into the data buffer. */
521
+	  /* Note: read RBR will clear the interrupt */
522
+		 if ((UART2RxQueueWritePos+1) % UARTRXQUEUESIZE != UART2RxQueueReadPos)
523
+		  {
524
+			  UART2Buffer[UART2RxQueueWritePos] = LPC_UART2->RBR;
525
+			  UART2RxQueueWritePos = (UART2RxQueueWritePos+1) % UARTRXQUEUESIZE;
526
+		  }
527
+	}
528
+  }
529
+  else if ( IIRValue == IIR_RDA )	/* Receive Data Available */
530
+  {
531
+	/* Receive Data Available */
532
+	  if ((UART2RxQueueWritePos+1) % UARTRXQUEUESIZE != UART2RxQueueReadPos)
533
+	  {
534
+		  UART2Buffer[UART2RxQueueWritePos] = LPC_UART2->RBR;
535
+		  UART2RxQueueWritePos = (UART2RxQueueWritePos+1) % UARTRXQUEUESIZE;
536
+	  }
537
+	  else
538
+		  dummy = LPC_UART2->RBR;;
539
+  }
540
+  else if ( IIRValue == IIR_CTI )	/* Character timeout indicator */
541
+  {
542
+	/* Character Time-out indicator */
543
+	UART2Status |= 0x100;		/* Bit 9 as the CTI error */
544
+  }
545
+  else if ( IIRValue == IIR_THRE )	/* THRE, transmit holding register empty */
546
+  {
547
+	/* THRE interrupt */
548
+	LSRValue = LPC_UART2->LSR;		/* Check status in the LSR to see if
549
+									valid data in U0THR or not */
550
+	if ( LSRValue & LSR_THRE )
551
+	{
552
+	  UART2TxEmpty = 1;
553
+	}
554
+	else
555
+	{
556
+	  UART2TxEmpty = 0;
557
+	}
558
+  }
559
+}
560
+/*****************************************************************************
561
+** Function name:		UART3_IRQHandler
562
+**
563
+** Descriptions:		UART0 interrupt handler
564
+**
565
+** parameters:			None
566
+** Returned value:		None
567
+**
568
+*****************************************************************************/
569
+void UART3_IRQHandler (void)
570
+{
571
+  uint8_t IIRValue, LSRValue;
572
+  uint8_t Dummy = Dummy;
573
+
574
+  IIRValue = LPC_UART3->IIR;
575
+
576
+  IIRValue >>= 1;			/* skip pending bit in IIR */
577
+  IIRValue &= 0x07;			/* check bit 1~3, interrupt identification */
578
+  if ( IIRValue == IIR_RLS )		/* Receive Line Status */
579
+  {
580
+	LSRValue = LPC_UART3->LSR;
581
+	/* Receive Line Status */
582
+	if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
583
+	{
584
+	  /* There are errors or break interrupt */
585
+	  /* Read LSR will clear the interrupt */
586
+	  UART3Status = LSRValue;
587
+	  Dummy = LPC_UART3->RBR;		/* Dummy read on RX to clear
588
+							interrupt, then bail out */
589
+	  return;
590
+	}
591
+	if ( LSRValue & LSR_RDR )	/* Receive Data Ready */
592
+	{
593
+	  /* If no error on RLS, normal ready, save into the data buffer. */
594
+	  /* Note: read RBR will clear the interrupt */
595
+		 if ((UART3RxQueueWritePos+1) % UARTRXQUEUESIZE != UART3RxQueueReadPos)
596
+		  {
597
+			  UART3Buffer[UART3RxQueueWritePos] = LPC_UART3->RBR;
598
+			  UART3RxQueueWritePos = (UART3RxQueueWritePos+1) % UARTRXQUEUESIZE;
599
+		  }
600
+	}
601
+  }
602
+  else if ( IIRValue == IIR_RDA )	/* Receive Data Available */
603
+  {
604
+	/* Receive Data Available */
605
+	  if ((UART3RxQueueWritePos+1) % UARTRXQUEUESIZE != UART3RxQueueReadPos)
606
+	  {
607
+		  UART3Buffer[UART3RxQueueWritePos] = LPC_UART3->RBR;
608
+		  UART3RxQueueWritePos = (UART3RxQueueWritePos+1) % UARTRXQUEUESIZE;
609
+	  }
610
+	  else
611
+		  dummy = LPC_UART3->RBR;;
612
+  }
613
+  else if ( IIRValue == IIR_CTI )	/* Character timeout indicator */
614
+  {
615
+	/* Character Time-out indicator */
616
+	UART3Status |= 0x100;		/* Bit 9 as the CTI error */
617
+  }
618
+  else if ( IIRValue == IIR_THRE )	/* THRE, transmit holding register empty */
619
+  {
620
+	/* THRE interrupt */
621
+	LSRValue = LPC_UART3->LSR;		/* Check status in the LSR to see if
622
+									valid data in U0THR or not */
623
+	if ( LSRValue & LSR_THRE )
624
+	{
625
+	  UART3TxEmpty = 1;
626
+	}
627
+	else
628
+	{
629
+	  UART3TxEmpty = 0;
630
+	}
631
+  }
632
+}
633
+
634
+#ifdef __cplusplus
635
+}
636
+#endif

+ 149
- 0
Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h Visa fil

@@ -0,0 +1,149 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#ifndef HARDWARE_SERIAL_H_
24
+#define HARDWARE_SERIAL_H_
25
+
26
+#include <stdarg.h>
27
+#include <stdio.h>
28
+#include <Stream.h>
29
+
30
+extern "C" {
31
+  #include <debug_frmwrk.h>
32
+
33
+//#include <lpc17xx_uart.h>
34
+}
35
+
36
+#define IER_RBR		0x01
37
+#define IER_THRE	0x02
38
+#define IER_RLS		0x04
39
+
40
+#define IIR_PEND	0x01
41
+#define IIR_RLS		0x03
42
+#define IIR_RDA		0x02
43
+#define IIR_CTI		0x06
44
+#define IIR_THRE	0x01
45
+
46
+#define LSR_RDR		0x01
47
+#define LSR_OE		0x02
48
+#define LSR_PE		0x04
49
+#define LSR_FE		0x08
50
+#define LSR_BI		0x10
51
+#define LSR_THRE	0x20
52
+#define LSR_TEMT	0x40
53
+#define LSR_RXFE	0x80
54
+
55
+#define UARTRXQUEUESIZE		0x10
56
+
57
+class HardwareSerial : public Stream {
58
+private:
59
+uint8_t PortNum;
60
+uint32_t baudrate;
61
+
62
+public:
63
+  HardwareSerial(uint32_t uart) :
64
+    PortNum(uart)
65
+    {
66
+    }
67
+
68
+  void begin(uint32_t baudrate);
69
+  int read();
70
+  size_t write(uint8_t send);
71
+  int available();
72
+  void flush();
73
+  void printf(const char *format, ...);
74
+  int peek() {
75
+    return 0;
76
+  };
77
+
78
+
79
+  operator bool() {
80
+    return true;
81
+  }
82
+
83
+    void print(const char value[]) {
84
+      printf("%s" , value);
85
+    }
86
+    void print(char value, int = 0) {
87
+      printf("%c" , value);
88
+    }
89
+    void print(unsigned char value, int = 0) {
90
+      printf("%u" , value);
91
+    }
92
+    void print(int value, int = 0) {
93
+      printf("%d" , value);
94
+    }
95
+    void print(unsigned int value, int = 0) {
96
+      printf("%u" , value);
97
+    }
98
+    void print(long value, int = 0) {
99
+      printf("%ld" , value);
100
+    }
101
+    void print(unsigned long value, int = 0) {
102
+      printf("%lu" , value);
103
+    }
104
+
105
+    void print(float value, int round = 6) {
106
+      printf("%f" , value);
107
+    }
108
+    void print(double value, int round = 6) {
109
+      printf("%f" , value );
110
+    }
111
+
112
+    void println(const char value[]) {
113
+      printf("%s\n" , value);
114
+    }
115
+    void println(char value, int = 0) {
116
+      printf("%c\n" , value);
117
+    }
118
+    void println(unsigned char value, int = 0) {
119
+      printf("%u\r\n" , value);
120
+    }
121
+    void println(int value, int = 0) {
122
+      printf("%d\n" , value);
123
+    }
124
+    void println(unsigned int value, int = 0) {
125
+      printf("%u\n" , value);
126
+    }
127
+    void println(long value, int = 0) {
128
+      printf("%ld\n" , value);
129
+    }
130
+    void println(unsigned long value, int = 0) {
131
+      printf("%lu\n" , value);
132
+    }
133
+    void println(float value, int round = 6) {
134
+      printf("%f\n" , value );
135
+    }
136
+    void println(double value, int round = 6) {
137
+      printf("%f\n" , value );
138
+    }
139
+    void println(void) {
140
+      print('\n');
141
+    }
142
+
143
+};
144
+//extern HardwareSerial Serial0;
145
+//extern HardwareSerial Serial1;
146
+//extern HardwareSerial Serial2;
147
+extern HardwareSerial Serial3;
148
+
149
+#endif /* MARLIN_SRC_HAL_HAL_SERIAL_H_ */

+ 398
- 0
Marlin/src/HAL/HAL_LPC1768/SoftwareSerial.cpp Visa fil

@@ -0,0 +1,398 @@
1
+/*
2
+SoftwareSerial.cpp (formerly NewSoftSerial.cpp) -
3
+Multi-instance software serial library for Arduino/Wiring
4
+-- Interrupt-driven receive and other improvements by ladyada
5
+   (http://ladyada.net)
6
+-- Tuning, circular buffer, derivation from class Print/Stream,
7
+   multi-instance support, porting to 8MHz processors,
8
+   various optimizations, PROGMEM delay tables, inverse logic and
9
+   direct port writing by Mikal Hart (http://www.arduiniana.org)
10
+-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
11
+-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
12
+-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
13
+
14
+This library is free software; you can redistribute it and/or
15
+modify it under the terms of the GNU Lesser General Public
16
+License as published by the Free Software Foundation; either
17
+version 2.1 of the License, or (at your option) any later version.
18
+
19
+This library is distributed in the hope that it will be useful,
20
+but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22
+Lesser General Public License for more details.
23
+
24
+You should have received a copy of the GNU Lesser General Public
25
+License along with this library; if not, write to the Free Software
26
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
27
+
28
+The latest version of this library can always be found at
29
+http://arduiniana.org.
30
+*/
31
+
32
+
33
+//
34
+// Includes
35
+//
36
+//#include <WInterrupts.h>
37
+#include "../../../macros.h"
38
+#include "../HAL.h"
39
+#include <stdint.h>
40
+#include <stdarg.h>
41
+#include "arduino.h"
42
+#include "pinmapping.h"
43
+#include "pinmap_re_arm.h"
44
+#include "fastio.h"
45
+#include "SoftwareSerial.h"
46
+
47
+void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
48
+void GpioDisableInt(uint32_t port, uint32_t pin);
49
+//
50
+// Statics
51
+//
52
+SoftwareSerial *SoftwareSerial::active_object = 0;
53
+unsigned char SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF];
54
+volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
55
+volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
56
+
57
+typedef struct _DELAY_TABLE
58
+{
59
+  long baud;
60
+  uint16_t rx_delay_centering;
61
+  uint16_t rx_delay_intrabit;
62
+  uint16_t rx_delay_stopbit;
63
+  uint16_t tx_delay;
64
+} DELAY_TABLE;
65
+
66
+// rough delay estimation
67
+static const DELAY_TABLE table[] =
68
+{
69
+  //baud    |rxcenter|rxintra |rxstop  |tx
70
+  { 250000,   2,      4,       4,       4,   }, //Done but not good due to instruction cycle error
71
+  { 115200,   4,      8,       8,       8,   }, //Done but not good due to instruction cycle error
72
+  //{ 74880,   69,       139,       62,      162,  }, // estimation
73
+//  { 57600,   100,       185,      1,       208,  }, // Done but not good due to instruction cycle error
74
+  //{ 38400,   13,      26,      26,      26,  }, // Done
75
+  //{ 19200,   26,      52,      52,      52,  }, // Done
76
+  { 9600,    52,      104,     104,     104, }, // Done
77
+  //{ 4800,    104,     208,     208,     208, },
78
+  //{ 2400,    208,     417,     417,     417, },
79
+  //{ 1200,    416,    833,      833,     833,},
80
+};
81
+
82
+//
83
+// Private methods
84
+//
85
+
86
+#if 0
87
+/* static */
88
+inline void SoftwareSerial::tunedDelay(uint32_t count) {
89
+
90
+	asm volatile(
91
+
92
+    "mov r3, %[loopsPerMicrosecond] \n\t" //load the initial loop counter
93
+    "1: \n\t"
94
+    "sub r3, r3, #1 \n\t"
95
+    "bne 1b \n\t"
96
+
97
+    ://empty output list
98
+    :[loopsPerMicrosecond] "r" (count)
99
+    :"r3", "cc" //clobber list
100
+  );
101
+
102
+}
103
+#else
104
+inline void SoftwareSerial::tunedDelay(uint32_t count) {
105
+  delayMicroseconds(count);
106
+}
107
+#endif
108
+
109
+// This function sets the current object as the "listening"
110
+// one and returns true if it replaces another
111
+bool SoftwareSerial::listen()
112
+{
113
+  if (!_rx_delay_stopbit)
114
+    return false;
115
+
116
+  if (active_object != this)
117
+  {
118
+    if (active_object)
119
+      active_object->stopListening();
120
+
121
+    _buffer_overflow = false;
122
+    _receive_buffer_head = _receive_buffer_tail = 0;
123
+    active_object = this;
124
+
125
+    setRxIntMsk(true);
126
+    return true;
127
+  }
128
+
129
+  return false;
130
+}
131
+
132
+// Stop listening. Returns true if we were actually listening.
133
+bool SoftwareSerial::stopListening()
134
+{
135
+  if (active_object == this)
136
+  {
137
+    setRxIntMsk(false);
138
+    active_object = NULL;
139
+    return true;
140
+  }
141
+  return false;
142
+}
143
+
144
+//
145
+// The receive routine called by the interrupt handler
146
+//
147
+void SoftwareSerial::recv()
148
+{
149
+  uint8_t d = 0;
150
+
151
+  // If RX line is high, then we don't see any start bit
152
+  // so interrupt is probably not for us
153
+  if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
154
+  {
155
+    // Disable further interrupts during reception, this prevents
156
+    // triggering another interrupt directly after we return, which can
157
+    // cause problems at higher baudrates.
158
+    setRxIntMsk(false);//__disable_irq();//
159
+
160
+    // Wait approximately 1/2 of a bit width to "center" the sample
161
+    tunedDelay(_rx_delay_centering);
162
+    // Read each of the 8 bits
163
+    for (uint8_t i=8; i > 0; --i)
164
+    {
165
+	  tunedDelay(_rx_delay_intrabit);
166
+      d >>= 1;
167
+      if (rx_pin_read())
168
+        d |= 0x80;
169
+    }
170
+
171
+    if (_inverse_logic)
172
+      d = ~d;
173
+
174
+    // if buffer full, set the overflow flag and return
175
+    uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
176
+    if (next != _receive_buffer_head)
177
+    {
178
+      // save new data in buffer: tail points to where byte goes
179
+      _receive_buffer[_receive_buffer_tail] = d; // save new byte
180
+      _receive_buffer_tail = next;
181
+    }
182
+    else
183
+    {
184
+      _buffer_overflow = true;
185
+    }
186
+	tunedDelay(_rx_delay_stopbit);
187
+    // Re-enable interrupts when we're sure to be inside the stop bit
188
+	setRxIntMsk(true);//__enable_irq();//
189
+
190
+  }
191
+}
192
+
193
+uint32_t SoftwareSerial::rx_pin_read()
194
+{
195
+  return digitalRead(_receivePin);
196
+}
197
+
198
+//
199
+// Interrupt handling
200
+//
201
+
202
+/* static */
203
+inline void SoftwareSerial::handle_interrupt()
204
+{
205
+  if (active_object)
206
+  {
207
+    active_object->recv();
208
+  }
209
+}
210
+extern "C" void intWrapper() {
211
+  SoftwareSerial::handle_interrupt();
212
+}
213
+//
214
+// Constructor
215
+//
216
+SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
217
+  _rx_delay_centering(0),
218
+  _rx_delay_intrabit(0),
219
+  _rx_delay_stopbit(0),
220
+  _tx_delay(0),
221
+  _buffer_overflow(false),
222
+  _inverse_logic(inverse_logic)
223
+{
224
+  setTX(transmitPin);
225
+  setRX(receivePin);
226
+
227
+}
228
+
229
+//
230
+// Destructor
231
+//
232
+SoftwareSerial::~SoftwareSerial()
233
+{
234
+  end();
235
+}
236
+
237
+void SoftwareSerial::setTX(uint8_t tx)
238
+{
239
+  // First write, then set output. If we do this the other way around,
240
+  // the pin would be output low for a short while before switching to
241
+  // output hihg. Now, it is input with pullup for a short while, which
242
+  // is fine. With inverse logic, either order is fine.
243
+
244
+  digitalWrite(tx, _inverse_logic ? LOW : HIGH);
245
+  pinMode(tx,OUTPUT);
246
+  _transmitPin = tx;
247
+
248
+}
249
+
250
+void SoftwareSerial::setRX(uint8_t rx)
251
+{
252
+  pinMode(rx, INPUT_PULLUP); // pullup for normal logic!
253
+  //if (!_inverse_logic)
254
+  // digitalWrite(rx, HIGH);
255
+  _receivePin = rx;
256
+  _receivePort = pin_map[rx].port;
257
+  _receivePortPin = pin_map[rx].pin;
258
+/*  GPIO_T * rxPort = digitalPinToPort(rx);
259
+  _receivePortRegister = portInputRegister(rxPort);
260
+  _receiveBitMask = digitalPinToBitMask(rx);*/
261
+
262
+}
263
+
264
+//
265
+// Public methods
266
+//
267
+
268
+void SoftwareSerial::begin(long speed)
269
+{
270
+  _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;
271
+
272
+  for(uint8_t i = 0; i < sizeof(table)/sizeof(table[0]); ++i)
273
+  {
274
+    long baud = table[i].baud;
275
+    if(baud == speed)
276
+    {
277
+      _rx_delay_centering = table[i].rx_delay_centering;
278
+      _rx_delay_intrabit = table[i].rx_delay_intrabit;
279
+      _rx_delay_stopbit = table[i].rx_delay_stopbit;
280
+      _tx_delay = table[i].tx_delay;
281
+      break;
282
+    }
283
+  }
284
+
285
+  attachInterrupt(_receivePin, intWrapper, CHANGE); //this->handle_interrupt, CHANGE);
286
+
287
+  listen();
288
+  tunedDelay(_tx_delay);
289
+
290
+}
291
+
292
+void SoftwareSerial::setRxIntMsk(bool enable)
293
+{
294
+    if (enable)
295
+        GpioEnableInt(_receivePort,_receivePin,CHANGE);
296
+    else
297
+        GpioDisableInt(_receivePort,_receivePin);
298
+}
299
+
300
+void SoftwareSerial::end()
301
+{
302
+  stopListening();
303
+}
304
+
305
+
306
+// Read data from buffer
307
+int SoftwareSerial::read()
308
+{
309
+  if (!isListening())
310
+    return -1;
311
+
312
+  // Empty buffer?
313
+  if (_receive_buffer_head == _receive_buffer_tail)
314
+    return -1;
315
+
316
+  // Read from "head"
317
+  uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
318
+  _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
319
+  return d;
320
+}
321
+
322
+int SoftwareSerial::available()
323
+{
324
+  if (!isListening())
325
+    return 0;
326
+
327
+  return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
328
+}
329
+
330
+size_t SoftwareSerial::write(uint8_t b)
331
+{
332
+  // By declaring these as local variables, the compiler will put them
333
+  // in registers _before_ disabling interrupts and entering the
334
+  // critical timing sections below, which makes it a lot easier to
335
+  // verify the cycle timings
336
+
337
+  bool inv = _inverse_logic;
338
+  uint16_t delay = _tx_delay;
339
+
340
+  if(inv)
341
+	  b = ~b;
342
+
343
+  cli();  // turn off interrupts for a clean txmit
344
+
345
+  // Write the start bit
346
+  if (inv)
347
+    digitalWrite(_transmitPin, 1);
348
+  else
349
+    digitalWrite(_transmitPin, 0);
350
+
351
+  tunedDelay(delay);
352
+
353
+  // Write each of the 8 bits
354
+  for (uint8_t i = 8; i > 0; --i)
355
+  {
356
+    if (b & 1) // choose bit
357
+      digitalWrite(_transmitPin, 1); // send 1 //(GPIO_Desc[_transmitPin].P)->DOUT |= GPIO_Desc[_transmitPin].bit;
358
+    else
359
+      digitalWrite(_transmitPin, 0); // send 0 //(GPIO_Desc[_transmitPin].P)->DOUT &= ~GPIO_Desc[_transmitPin].bit;
360
+
361
+    tunedDelay(delay);
362
+    b >>= 1;
363
+  }
364
+
365
+  // restore pin to natural state
366
+  if (inv)
367
+    digitalWrite(_transmitPin, 0);
368
+  else
369
+    digitalWrite(_transmitPin, 1);
370
+
371
+	sei(); // turn interrupts back on
372
+  tunedDelay(delay);
373
+
374
+  return 1;
375
+}
376
+
377
+void SoftwareSerial::flush()
378
+{
379
+  if (!isListening())
380
+    return;
381
+
382
+  cli();
383
+  _receive_buffer_head = _receive_buffer_tail = 0;
384
+  sei();
385
+}
386
+
387
+int SoftwareSerial::peek()
388
+{
389
+  if (!isListening())
390
+    return -1;
391
+
392
+  // Empty buffer?
393
+  if (_receive_buffer_head == _receive_buffer_tail)
394
+    return -1;
395
+
396
+  // Read from "head"
397
+  return _receive_buffer[_receive_buffer_head];
398
+}

+ 119
- 0
Marlin/src/HAL/HAL_LPC1768/SoftwareSerial.h Visa fil

@@ -0,0 +1,119 @@
1
+/*
2
+SoftwareSerial.h (formerly NewSoftSerial.h) -
3
+Multi-instance software serial library for Arduino/Wiring
4
+-- Interrupt-driven receive and other improvements by ladyada
5
+   (http://ladyada.net)
6
+-- Tuning, circular buffer, derivation from class Print/Stream,
7
+   multi-instance support, porting to 8MHz processors,
8
+   various optimizations, PROGMEM delay tables, inverse logic and
9
+   direct port writing by Mikal Hart (http://www.arduiniana.org)
10
+-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
11
+-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
12
+-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
13
+
14
+This library is free software; you can redistribute it and/or
15
+modify it under the terms of the GNU Lesser General Public
16
+License as published by the Free Software Foundation; either
17
+version 2.1 of the License, or (at your option) any later version.
18
+
19
+This library is distributed in the hope that it will be useful,
20
+but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22
+Lesser General Public License for more details.
23
+
24
+You should have received a copy of the GNU Lesser General Public
25
+License along with this library; if not, write to the Free Software
26
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
27
+
28
+The latest version of this library can always be found at
29
+http://arduiniana.org.
30
+*/
31
+
32
+#ifndef SoftwareSerial_h
33
+#define SoftwareSerial_h
34
+
35
+#include "arduino.h"
36
+#include <inttypes.h>
37
+//#include "serial.h"
38
+ #include <Stream.h>
39
+#include <Print.h>
40
+
41
+/******************************************************************************
42
+* Definitions
43
+******************************************************************************/
44
+
45
+#define _SS_MAX_RX_BUFF 64 // RX buffer size
46
+
47
+class SoftwareSerial : public Stream
48
+{
49
+private:
50
+  // per object data
51
+  uint8_t _receivePin;
52
+  uint8_t _transmitPin;
53
+//  uint32_t _receiveBitMask; // for rx interrupts
54
+  uint32_t _receivePort;
55
+  uint32_t _receivePortPin;
56
+
57
+
58
+  // Expressed as 4-cycle delays (must never be 0!)
59
+  uint16_t _rx_delay_centering;
60
+  uint16_t _rx_delay_intrabit;
61
+  uint16_t _rx_delay_stopbit;
62
+  uint16_t _tx_delay;
63
+
64
+  uint16_t _buffer_overflow:1;
65
+  uint16_t _inverse_logic:1;
66
+
67
+  // static data
68
+  static unsigned char _receive_buffer[_SS_MAX_RX_BUFF];
69
+  static volatile uint8_t _receive_buffer_tail;
70
+  static volatile uint8_t _receive_buffer_head;
71
+  static SoftwareSerial *active_object;
72
+
73
+  // private methods
74
+  void recv() __attribute__((__always_inline__));
75
+  uint32_t rx_pin_read();
76
+  void tx_pin_write(uint8_t pin_state) __attribute__((__always_inline__));
77
+  void setTX(uint8_t transmitPin);
78
+  void setRX(uint8_t receivePin);
79
+  void setRxIntMsk(bool enable) __attribute__((__always_inline__));
80
+
81
+  // private static method for timing
82
+  static inline void tunedDelay(uint32_t delay);
83
+
84
+public:
85
+  // public methods
86
+
87
+  SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
88
+  ~SoftwareSerial();
89
+  void begin(long speed);
90
+  bool listen();
91
+  void end();
92
+  bool isListening() { return this == active_object; }
93
+  bool stopListening();
94
+  bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; }
95
+  int peek();
96
+
97
+  virtual size_t write(uint8_t byte);
98
+  virtual int read();
99
+  virtual int available();
100
+  virtual void flush();
101
+  operator bool() { return true; }
102
+
103
+  using Print::write;
104
+  //using HalSerial::write;
105
+
106
+  // public only for easy access by interrupt handlers
107
+  static inline void handle_interrupt() __attribute__((__always_inline__));
108
+};
109
+
110
+// Arduino 0012 workaround
111
+#undef int
112
+#undef char
113
+#undef long
114
+#undef byte
115
+#undef float
116
+#undef abs
117
+#undef round
118
+
119
+#endif

+ 224
- 0
Marlin/src/HAL/HAL_LPC1768/WInterrupts.cpp Visa fil

@@ -0,0 +1,224 @@
1
+/*
2
+  Copyright (c) 2011-2012 Arduino.  All right reserved.
3
+
4
+  This library is free software; you can redistribute it and/or
5
+  modify it under the terms of the GNU Lesser General Public
6
+  License as published by the Free Software Foundation; either
7
+  version 2.1 of the License, or (at your option) any later version.
8
+
9
+  This library 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.
12
+  See the GNU Lesser General Public License for more details.
13
+
14
+  You should have received a copy of the GNU Lesser General Public
15
+  License along with this library; if not, write to the Free Software
16
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
+*/
18
+
19
+#include "../../../macros.h"
20
+#include "../HAL.h"
21
+#include "arduino.h"
22
+#include "pinmapping.h"
23
+//#include "HAL_timers.h"
24
+#include "fastio.h"
25
+
26
+#define GNUM 31
27
+
28
+typedef void (*interruptCB)(void);
29
+
30
+static interruptCB callbacksP0[GNUM];
31
+static interruptCB callbacksP2[GNUM];
32
+
33
+	extern "C" void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
34
+	extern "C" void GpioDisableInt(uint32_t port, uint32_t pin);
35
+
36
+//void deadloop(void) {}
37
+
38
+/* Configure PIO interrupt sources */
39
+static void __initialize() {
40
+	int i;
41
+	for (i=0; i<GNUM; i++) {
42
+		callbacksP0[i] = 0;
43
+		callbacksP2[i] = 0;
44
+		}
45
+NVIC_EnableIRQ(EINT3_IRQn);
46
+}
47
+
48
+void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode)
49
+{
50
+	static int enabled = 0;
51
+
52
+	if(!INTERRUPT_PIN(pin)) return;
53
+
54
+	if (!enabled) {
55
+		__initialize();
56
+		enabled = 1;
57
+	}
58
+	uint8_t myport = pin_map[pin].port;
59
+	uint8_t mypin = pin_map[pin].pin;
60
+
61
+
62
+	if (myport == 0 )
63
+		callbacksP0[mypin] = callback;
64
+	else
65
+		callbacksP2[mypin] = callback;
66
+
67
+	// Enable interrupt
68
+		GpioEnableInt(myport,mypin,mode);
69
+}
70
+
71
+void detachInterrupt(uint32_t pin)
72
+{
73
+	if(!INTERRUPT_PIN(pin)) return;
74
+
75
+  uint8_t myport = pin_map[pin].port;
76
+  uint8_t mypin = pin_map[pin].pin;
77
+
78
+	// Disable interrupt
79
+	GpioDisableInt(myport,mypin);
80
+
81
+//unset callback
82
+	if (myport == 0 )
83
+		callbacksP0[mypin] = 0;
84
+	else //if (myport == 2 )
85
+		callbacksP2[mypin] = 0;
86
+	}
87
+
88
+
89
+	extern "C" void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode) {
90
+	//pin here is the processor pin, not logical pin
91
+	if (port==0) {
92
+		LPC_GPIOINT->IO0IntClr = (1 << pin);
93
+		if (mode ==RISING) {
94
+			LPC_GPIOINT->IO0IntEnR |= (1<<pin);
95
+  		LPC_GPIOINT->IO0IntEnF &= ~(1<<pin);
96
+		}
97
+		else if (mode==FALLING) {
98
+			LPC_GPIOINT->IO0IntEnF |= (1<<pin);
99
+  		LPC_GPIOINT->IO0IntEnR &= ~(1<<pin);
100
+		}
101
+		else if (mode==CHANGE) {
102
+		LPC_GPIOINT->IO0IntEnR |= (1<<pin);
103
+		LPC_GPIOINT->IO0IntEnF |= (1<<pin);
104
+		}
105
+	}
106
+	else{
107
+		LPC_GPIOINT->IO2IntClr = (1 << pin);
108
+		if (mode ==RISING) {
109
+			LPC_GPIOINT->IO2IntEnR |= (1<<pin);
110
+			LPC_GPIOINT->IO2IntEnF &= ~(1<<pin);
111
+		}
112
+		else if (mode==FALLING) {
113
+			LPC_GPIOINT->IO2IntEnF |= (1<<pin);
114
+			LPC_GPIOINT->IO2IntEnR &= ~(1<<pin);
115
+		}
116
+		else if (mode==CHANGE) {
117
+		LPC_GPIOINT->IO2IntEnR |= (1<<pin);
118
+		LPC_GPIOINT->IO2IntEnF |= (1<<pin);
119
+		}
120
+	}
121
+}
122
+extern "C"  void GpioDisableInt(uint32_t port, uint32_t pin)
123
+{
124
+	if (port==0){
125
+		LPC_GPIOINT->IO0IntEnR &= ~(1<<pin);
126
+		LPC_GPIOINT->IO0IntEnF &= ~(1<<pin);
127
+		LPC_GPIOINT->IO0IntClr = 1 << pin;
128
+	}
129
+	else {
130
+		LPC_GPIOINT->IO2IntEnR &= ~(1<<pin);
131
+		LPC_GPIOINT->IO2IntEnF &= ~(1<<pin);
132
+		LPC_GPIOINT->IO2IntClr = 1 << pin;
133
+	}
134
+}
135
+
136
+bool isPowerOf2(unsigned int n)
137
+
138
+{
139
+
140
+    return n == 1 || (n & (n-1)) == 0;
141
+
142
+}
143
+
144
+#if 0
145
+extern "C" void EINT3_IRQHandler () {
146
+	LPC_GPIOINT->IO0IntClr = LPC_GPIOINT->IO2IntClr = 0xFFFFFFFF;
147
+	TOGGLE(13);
148
+	//NVIC_ClearPendingIRQ(EINT3_IRQn);
149
+}
150
+#else
151
+extern "C" void EINT3_IRQHandler(void)
152
+{
153
+	// Read in all current interrupt registers. We do this once as the
154
+// GPIO interrupt registers are on the APB bus, and this is slow.
155
+uint32_t rise0 = LPC_GPIOINT->IO0IntStatR;
156
+uint32_t fall0 = LPC_GPIOINT->IO0IntStatF;
157
+uint32_t rise2 = LPC_GPIOINT->IO2IntStatR;
158
+uint32_t fall2 = LPC_GPIOINT->IO2IntStatF;
159
+//Clear teh interrupts ASAP
160
+LPC_GPIOINT->IO0IntClr = LPC_GPIOINT->IO2IntClr = 0xFFFFFFFF;
161
+NVIC_ClearPendingIRQ(EINT3_IRQn);
162
+uint8_t bitloc;
163
+if (rise0 == 0)
164
+	goto fall0;
165
+	/* multiple pins changes happened.*/
166
+	while(rise0 > 0) {      //Continue as long as there are interrupts pending
167
+			bitloc = 31 - __CLZ(rise0); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
168
+			if (callbacksP0[bitloc]!=0)
169
+				callbacksP0[bitloc]();
170
+			rise0 -= 1<<bitloc;
171
+	}
172
+fall0:
173
+if (fall0==0)
174
+	goto rise2;
175
+/* if (isPowerOf2(fall0) && callbacksP0[31 - __CLZ(rise0)])
176
+  callbacksP0[31 - __CLZ(rise0)](); */
177
+	//LPC_GPIOINT->IO0IntClr = fall0;*/
178
+else {
179
+while(fall0 > 0) {
180
+		bitloc = 31 - __CLZ(fall0);
181
+		if (callbacksP0[bitloc]!=0)
182
+			callbacksP0[bitloc]();
183
+		fall0 -= 1<<bitloc;
184
+  }
185
+}
186
+rise2:
187
+if (rise2==0)
188
+	goto fall2;
189
+/*if ((rise2 & (rise2 - 1)) == 0) {
190
+  callbacksP2[rise2]();
191
+	//LPC_GPIOINT->IO2IntClr = rise2;
192
+}*/
193
+else {
194
+while(rise2 > 0) {
195
+		bitloc = 31 - __CLZ(rise2);
196
+		if (callbacksP2[bitloc]!=0)
197
+			callbacksP2[bitloc]();
198
+		//LPC_GPIOINT->IO2IntClr = 1 << bitloc;
199
+		rise2 -= 1<<bitloc;
200
+  }
201
+}
202
+fall2:
203
+if (fall2==0)
204
+	goto end;
205
+/*if ((fall2 & (fall2 - 1)) == 0) {
206
+  callbacksP2[fall2]();
207
+	//LPC_GPIOINT->IO2IntClr = fall2;
208
+}*/
209
+else {
210
+while(fall2 > 0) {
211
+		bitloc = 31 - __CLZ(fall2);
212
+		if (callbacksP2[bitloc]!=0)
213
+			callbacksP2[bitloc]();
214
+		//LPC_GPIOINT->IO2IntClr = 1 << bitloc;
215
+		fall2 -= 1<<bitloc;
216
+}
217
+end:
218
+//NVIC_ClearPendingIRQ(EINT3_IRQn);
219
+//LPC_GPIOINT->IO0IntClr = LPC_GPIOINT->IO2IntClr = 0xFFFFFFFF;
220
+//NVIC_ClearPendingIRQ(EINT3_IRQn);
221
+return; //silences warning
222
+}
223
+}
224
+#endif

+ 7
- 0
Marlin/src/HAL/HAL_LPC1768/arduino.h Visa fil

@@ -28,6 +28,9 @@
28 28
 
29 29
 #define LOW          0x00
30 30
 #define HIGH         0x01
31
+#define CHANGE       0x02
32
+#define FALLING      0x03
33
+#define RISING       0x04
31 34
 
32 35
 #define INPUT        0x00
33 36
 #define OUTPUT       0x01
@@ -64,6 +67,10 @@ typedef uint8_t byte;
64 67
 //Interrupts
65 68
 void cli(void); // Disable
66 69
 void sei(void); // Enable
70
+void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode);
71
+void detachInterrupt(uint32_t pin);
72
+extern "C" void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
73
+extern "C" void GpioDisableInt(uint32_t port, uint32_t pin);
67 74
 
68 75
 // Program Memory
69 76
 #define pgm_read_ptr(address_short) (*(address_short))

+ 44
- 0
Marlin/src/HAL/HAL_LPC1768/pinmap_re_arm.h Visa fil

@@ -95,6 +95,50 @@ const adc_pin_data adc_pin_map[] = {
95 95
                        r == 54 ? 1 :\
96 96
                        r == 60 ? 1 : 0)
97 97
 
98
+#define NUM_INTERRUPT_PINS 35
99
+
100
+#define INTERRUPT_PIN(r)  ( r< 0  ? 0 :\
101
+                        r == 0  ? 1 :\
102
+                        r == 1  ? 1 :\
103
+                        r == 8  ? 1 :\
104
+                        r == 9  ? 1 :\
105
+                        r == 10 ? 1 :\
106
+                        r == 12 ? 1 :\
107
+                        r == 16 ? 1 :\
108
+                        r == 20 ? 1 :\
109
+                        r == 21 ? 1 :\
110
+                        r == 24 ? 1 :\
111
+                        r == 25 ? 1 :\
112
+                        r == 26 ? 1 :\
113
+                        r == 28 ? 1 :\
114
+                        r == 34 ? 1 :\
115
+                        r == 35 ? 1 :\
116
+                        r == 36 ? 1 :\
117
+                        r == 38 ? 1 :\
118
+                        r == 46 ? 1 :\
119
+                        r == 48 ? 1 :\
120
+                        r == 50 ? 1 :\
121
+                        r == 51 ? 1 :\
122
+                        r == 52 ? 1 :\
123
+                        r == 54 ? 1 :\
124
+                        r == 55 ? 1 :\
125
+                        r == 56 ? 1 :\
126
+                        r == 57 ? 1 :\
127
+                        r == 58 ? 1 :\
128
+                        r == 59 ? 1 :\
129
+                        r == 60 ? 1 :\
130
+                        r == 61 ? 1 :\
131
+                        r == 62 ? 1 :\
132
+                        r == 63 ? 1 :\
133
+                        r == 67 ? 1 :\
134
+                        r == 68 ? 1 :\
135
+                        r == 69 ? 1 : 0)
136
+                        /*Internal SD Card */
137
+                        /*r == 80 ? 1 :\
138
+                        r == 81 ? 1 :\
139
+                        r == 82 ? 1 :\
140
+                        r == 83 ? 1 :\*/
141
+
98 142
 const pin_data pin_map[] = { // pin map for variable pin function
99 143
   {0,3},        //  DIO0   RXD0             A6               J4-4                           AUX-1
100 144
   {0,2},        //  DIO1   TXD0             A7               J4-5                           AUX-1

Laddar…
Avbryt
Spara