Browse Source

Added unmodified MODSERIAL library code

Thomas Buck 8 years ago
parent
commit
f4fd1c3e1f

+ 177
- 0
lib/MODSERIAL/ChangeLog.c View File

@@ -0,0 +1,177 @@
1
+/* $Id:$
2
+
3
+1.25    8th January 2013
4
+    
5
+    * Bring back into line with MBed libraries.
6
+    * Credits: 
7
+        Erik Olieman : http://mbed.org/users/Sissors/code/MODSERIAL/rev/3ba4341d74d6
8
+        Erik Olieman : http://mbed.org/users/Sissors/code/MODSERIAL/rev/a469aa702bab
9
+    
10
+
11
+1.24    6th Dec 2012
12
+        
13
+    * Beta release for new Mbed library.
14
+
15
+1.23    25th July 2012
16
+
17
+    * LPC1768 code as was. This release includes "alpha" support for the LPC11U24
18
+
19
+1.22    19th April 2012
20
+
21
+    * http://mbed.org/forum/bugs-suggestions/topic/2936/
22
+    * Bug fix, protect important buffer pointers from IRQ corruption.
23
+    * Credits: 
24
+        Anthony Wieser  http://mbed.org/users/WieserSoftwareLtd/ for the fix.
25
+        BlazeX http://mbed.org/users/BlazeX/ for the alert that a fix was needed!
26
+
27
+1.21    10 May 2011
28
+    
29
+    * http://mbed.org/forum/mbed/topic/2264
30
+    
31
+1.20    26 April 2011
32
+
33
+    * Bug fix, not blocking on transmit
34
+      by Erik Petrich, http://mbed.org/forum/bugs-suggestions/topic/2200
35
+      
36
+1.19    20 April 2011
37
+
38
+    * Fixed some doxygen comment bugs.
39
+    
40
+1.18    20 April 2011
41
+
42
+    * All callbacks now use MODSERIAL_callback (rather than Mbed's FunctionPointer[1] type)
43
+      to store and invoke it's callbacks. This allows MODSERIAL to pass a parameter
44
+      to callbacks. The function prototype is now void func(MODSERIAL_IRQ_INFO *q).
45
+    * Callbacks now pass a pointer to a MODSERIAL_IRQ_INFO class type.
46
+      This class holds a pointer to the MODSERIAL object that invoked the callback
47
+      thus freeing callbacks need to use the global variable of the original 
48
+      MODSERIAL instance.
49
+    * MODSERIAL_IRQ_INFO also declares public functions that are protected within MODSERIAL
50
+      thus allowing certain functions to be restricted to callback context only.
51
+    * New function MODSERIAL_IRQ_INFO::rxDiscardLastChar() allows an rxCallback function
52
+      to remove the character that was just placed into the RX buffer.
53
+    
54
+    [1] http://mbed.org/users/AjK/libraries/FPointer/latest/docs/
55
+
56
+1.17   08/Mar/2011
57
+       Fixed a memory leak in the DMA code.
58
+       
59
+1.16 - 12 Feb 2011
60
+    
61
+    * Missed one, doh!
62
+
63
+1.15 - 12 Feb 2011
64
+    
65
+    * Fixed some typos.
66
+    
67
+1.14 - 7 Feb 2011
68
+
69
+    * Fixed a bug in __putc() that caused the output buffer pointer to 
70
+      become corrupted.
71
+
72
+1.13 - 20/01/2011
73
+
74
+    * Added extra documentation.
75
+    * Fixed some typos.
76
+    
77
+1.12 - 20/01/2011
78
+
79
+    * Added new "autoDetectChar()" function. To use:-
80
+      1st: Add a callback to invoke when the char is detected:-        
81
+        .attach(&detectedChar, MODSERIAL::RxAutoDetect);
82
+      2nd: Send the char to detect.
83
+        .autoDectectChar('\n');
84
+      Whenever that char goes into the RX buffer your callback will be invoked.
85
+      Added example2.cpp to demo a simple messaging system using this auto feature.
86
+
87
+
88
+1.11 - 23/11/2010
89
+
90
+    * Fixed a minor issue with 1.10 missed an alteration of name change.
91
+    
92
+1.10 - 23/11/2010
93
+
94
+    * Rename the DMA callback from attach_dma_complete() to attach_dmaSendComplete()
95
+    
96
+1.9 - 23/11/2010
97
+
98
+    * Added support for DMA sending of characters. Required is
99
+      the MODDMA library module:-
100
+      http://mbed.org/users/AjK/libraries/MODDMA/latest
101
+      See example_dma.cpp for more information.
102
+      
103
+1.8 - 22/11/2010
104
+
105
+    * Added code so that if a buffer is set to zero length then
106
+      MODSERIAL defaults to just using the FIFO for that stream
107
+      thus making the library "fall back" to teh same operation
108
+      that the Mbed Serial library performs.
109
+    * Removed dmaSend() function that should have been removed 
110
+      at 1.7
111
+    
112
+1.7 - 21/11/2010
113
+
114
+    * Remove the DMA enum from MODSERIAL.h as it's not currently 
115
+      ready for release.
116
+    * Added page doxygen comments.
117
+
118
+1.6 - 21/11/2010
119
+
120
+   * Version 1.5 solved a blocking problem on putc() when called 
121
+     from another ISR. However, isr_tx() invokes a callback of it's
122
+     own when a byte is tranferred from TX buffer to TX FIFO. User
123
+     programs may interpret that as an IRQ callback. That's an ISR
124
+     call from within an existing ISR which is not good. So the 
125
+     TxIrq callback from isr_tx is now conditional. It will only
126
+     be called when isr_tx() is actually within it's own ISR and
127
+     not when called from alternate ISR handlers.
128
+     
129
+1.5 - 21/11/2010
130
+
131
+    * Calling putc() (or any derived function that uses it like
132
+      printf()) while inside an interrupt service routine can
133
+      cause the system to lock up if the TX buffer is full. This
134
+      is because bytes are only transferred from the TX buffer to
135
+      the TX FIFO via the TX ISR. If we are, say in an RX ISR already,
136
+      then the TX ISR will never trigger. The TX buffer stays full and
137
+      there is never space to putc() the byte. So, while putc() blocks
138
+      waiting for space it calls isr_tx() to ensure if TX FIFO space
139
+      becomes available it will move bytes from the TX buffer to TX
140
+      FIFO thus removing the blocking condition within putc().
141
+
142
+1.4 - 21/11/2010
143
+
144
+    * Removed all the new DMA code. I wish mbed.org had proper SVN
145
+      versioning, I'm use to working in HEAD and BRANCHES after I've
146
+      released a project. Getting bug reports in current releases
147
+      while trying to dev new code is hard to manage without source
148
+      control of some type!
149
+
150
+1.3 - 21/11/2010
151
+
152
+    * Fixed a macro problem with txIsBusy()
153
+    * Started adding code to use "block data" sending using DMA
154
+    * Removed #include "IOMACROS.h"
155
+    
156
+1.2 - 21/11/2010
157
+
158
+    * Removed unsed variables from flushBuffer()
159
+    * Fixed a bug where both RX AND TX fifos are cleared/reset 
160
+      when just TX OR RX should be cleared.
161
+    * Fixed a bug that cleared IIR when in fact it should be left
162
+      alone so that any pending interrupt after flush is handled.
163
+    * Merged setBase() into init() as it wasn't required anywhere else.
164
+    * Changed init() to enforce _uidx is set by Serial to define the _base
165
+      address of the Uart in use.
166
+        
167
+1.1 - 20/11/2010
168
+
169
+    * Added this file
170
+    * Removed cruft from GETC.cpp
171
+    * "teh" should be "the", why do my fingers do that?
172
+
173
+1.0 - 20/11/2010
174
+
175
+    * First release.
176
+
177
+*/

+ 47
- 0
lib/MODSERIAL/FLUSH.cpp View File

@@ -0,0 +1,47 @@
1
+/*
2
+    Copyright (c) 2010 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+*/
22
+
23
+#include "MODSERIAL.h"
24
+#include "MACROS.h"
25
+
26
+namespace AjK {
27
+
28
+void
29
+MODSERIAL::flushBuffer(IrqType type)
30
+{
31
+    uint32_t ier = _IER;
32
+    switch(type) {
33
+        case TxIrq: _IER &= ~(1UL << 1); break;
34
+        case RxIrq: _IER &= ~(1UL << 0); break;
35
+    }
36
+    buffer_in[type]       = 0;
37
+    buffer_out[type]      = 0;
38
+    buffer_count[type]    = 0;
39
+    buffer_overflow[type] = 0;  
40
+    switch(type) {
41
+        case TxIrq: _FCR = MODSERIAL_FIFO_TX_RESET; break;
42
+        case RxIrq: _FCR = MODSERIAL_FIFO_RX_RESET; break;
43
+    }
44
+    _IER = ier;
45
+}
46
+
47
+}; // namespace AjK ends

+ 65
- 0
lib/MODSERIAL/GETC.cpp View File

@@ -0,0 +1,65 @@
1
+/*
2
+    Copyright (c) 2010 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+*/
22
+
23
+#include "MODSERIAL.h"
24
+#include "MACROS.h"
25
+
26
+namespace AjK {
27
+
28
+int 
29
+MODSERIAL::__getc(bool block)
30
+{
31
+    // If no buffer is in use fall back to standard RX FIFO usage.
32
+    // Note, we must block in this case and ignore bool "block" 
33
+    // so as to maintain compat with Mbed Serial.
34
+    if (buffer_size[RxIrq] == 0 || buffer[RxIrq] == (char *)NULL) {
35
+        while(! MODSERIAL_RBR_HAS_DATA ) ;
36
+        return (int)(_RBR & 0xFF);
37
+    }
38
+
39
+    if (block) { while ( MODSERIAL_RX_BUFFER_EMPTY ) ; } // Blocks.
40
+    else if ( MODSERIAL_RX_BUFFER_EMPTY ) return -1;
41
+    
42
+    int c = buffer[RxIrq][buffer_out[RxIrq]];
43
+    buffer_out[RxIrq]++;
44
+    if (buffer_out[RxIrq] >= buffer_size[RxIrq]) {
45
+        buffer_out[RxIrq] = 0;
46
+    }
47
+    
48
+    // If we have made space in the RX Buffer then copy over
49
+    // any characters in the RX FIFO that my reside there.
50
+    // Temporarily disable the RX IRQ so that we do not re-enter 
51
+    // it under interrupts.
52
+    if ( ! MODSERIAL_RX_BUFFER_FULL ) {
53
+        uint32_t ier = _IER;
54
+        _IER &= ~(1UL << 0);
55
+        isr_rx();    
56
+        _IER = ier;
57
+    }
58
+    
59
+    __disable_irq();
60
+    buffer_count[RxIrq]--;   
61
+    __enable_irq();
62
+    return c;
63
+}
64
+
65
+}; // namespace AjK ends

+ 81
- 0
lib/MODSERIAL/INIT.cpp View File

@@ -0,0 +1,81 @@
1
+/*
2
+    Copyright (c) 2010 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+*/
22
+
23
+#include "MODSERIAL.h"
24
+#include "MACROS.h"
25
+
26
+
27
+namespace AjK {
28
+
29
+void
30
+MODSERIAL::init( int txSize, int rxSize, PinName rx )
31
+{
32
+    disableIrq();
33
+    
34
+    callbackInfo.setSerial(this);
35
+
36
+#ifdef __LPC11UXX_H__
37
+
38
+    _base = LPC_USART;
39
+    
40
+#else    
41
+    switch( _serial.index ) {
42
+        case 0: _base = LPC_UART0; break;
43
+        case 1: _base = LPC_UART1; break;
44
+        case 2: _base = LPC_UART2; break;
45
+        case 3: _base = LPC_UART3; break;
46
+        default: _base = NULL;      break;
47
+    }
48
+#endif
49
+    
50
+    dmaSendChannel  = -1;
51
+    moddma_p        = (void *)NULL;
52
+    
53
+    if ( _base != NULL ) {
54
+        buffer_size[RxIrq]     = rxSize;
55
+        buffer[RxIrq]          = rxSize > 0 ? (char *)malloc(buffer_size[RxIrq]) : (char *)NULL;
56
+        buffer_in[RxIrq]       = 0;
57
+        buffer_out[RxIrq]      = 0;
58
+        buffer_count[RxIrq]    = 0;
59
+        buffer_overflow[RxIrq] = 0;
60
+        Serial::attach( this, &MODSERIAL::isr_rx, Serial::RxIrq );        
61
+        
62
+        buffer_size[TxIrq]     = txSize;
63
+        buffer[TxIrq]          = txSize > 0 ? (char *)malloc(buffer_size[TxIrq]) : (char *)NULL;
64
+        buffer_in[TxIrq]       = 0;
65
+        buffer_out[TxIrq]      = 0;
66
+        buffer_count[TxIrq]    = 0;
67
+        buffer_overflow[TxIrq] = 0;
68
+        Serial::attach( this, &MODSERIAL::isr_tx, Serial::TxIrq );
69
+    }
70
+    else {
71
+        error("MODSERIAL must have a defined UART to function.");
72
+    }
73
+    
74
+    _FCR = MODSERIAL_FIFO_ENABLE | MODSERIAL_FIFO_RX_RESET | MODSERIAL_FIFO_TX_RESET;
75
+    
76
+    auto_detect_char = 0;
77
+    
78
+    enableIrq();
79
+}
80
+
81
+}; // namespace AjK ends

+ 60
- 0
lib/MODSERIAL/ISR_RX.cpp View File

@@ -0,0 +1,60 @@
1
+/*
2
+    Copyright (c) 2010 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+*/
22
+
23
+#include "MODSERIAL.h"
24
+#include "MACROS.h"
25
+
26
+namespace AjK {
27
+        
28
+void 
29
+MODSERIAL::isr_rx(void)
30
+{
31
+    if (! _base || buffer_size[RxIrq] == 0 || buffer[RxIrq] == (char *)NULL) {
32
+        _isr[RxIrq].call(&this->callbackInfo); 
33
+        return;
34
+    } 
35
+    
36
+    while( MODSERIAL_RBR_HAS_DATA ) {
37
+        rxc = (char)(_RBR & 0xFF); 
38
+        if ( MODSERIAL_RX_BUFFER_FULL ) {
39
+            buffer_overflow[RxIrq] = rxc; // Oh dear, no room in buffer.
40
+            _isr[RxOvIrq].call(&this->callbackInfo);
41
+        }
42
+        else {
43
+            if (buffer[RxIrq] != (char *)NULL) {
44
+                buffer[RxIrq][buffer_in[RxIrq]] = rxc;
45
+                buffer_count[RxIrq]++; 
46
+                buffer_in[RxIrq]++;
47
+                if (buffer_in[RxIrq] >= buffer_size[RxIrq]) {
48
+                    buffer_in[RxIrq] = 0;
49
+                }
50
+            }  
51
+            _isr[RxIrq].call(&this->callbackInfo); 
52
+        }
53
+        if (auto_detect_char == rxc) {
54
+            _isr[RxAutoDetect].call(&this->callbackInfo);
55
+        }
56
+    }    
57
+}
58
+
59
+}; // namespace AjK ends
60
+

+ 54
- 0
lib/MODSERIAL/ISR_TX.cpp View File

@@ -0,0 +1,54 @@
1
+/*
2
+    Copyright (c) 2010 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+*/
22
+
23
+#include "MODSERIAL.h"
24
+#include "MACROS.h"
25
+
26
+namespace AjK {
27
+
28
+void 
29
+MODSERIAL::isr_tx(bool doCallback)
30
+{
31
+    if (! _base || buffer_size[TxIrq] == 0 || buffer[TxIrq] == (char *)NULL) {
32
+        _isr[TxIrq].call(&this->callbackInfo); 
33
+        return;
34
+    }
35
+    
36
+    while (! MODSERIAL_TX_BUFFER_EMPTY && MODSERIAL_THR_HAS_SPACE ) {
37
+        _THR = txc = (uint8_t)(buffer[TxIrq][buffer_out[TxIrq]]);
38
+        buffer_count[TxIrq]--;   
39
+        buffer_out[TxIrq]++;
40
+        if (buffer_out[TxIrq] >= buffer_size[TxIrq]) {
41
+            buffer_out[TxIrq] = 0;
42
+        }
43
+        if (doCallback) _isr[TxIrq].call(&this->callbackInfo);
44
+    }
45
+        
46
+    if ( MODSERIAL_TX_BUFFER_EMPTY ) { 
47
+        _IER = 1;
48
+        _isr[TxEmpty].call(&this->callbackInfo);
49
+    }        
50
+}
51
+
52
+}; // namespace AjK ends
53
+
54
+        

+ 70
- 0
lib/MODSERIAL/MACROS.h View File

@@ -0,0 +1,70 @@
1
+/*
2
+    Copyright (c) 2010 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+*/
22
+
23
+#ifndef MODSERIAL_MACROS_H
24
+#define MODSERIAL_MACROS_H
25
+
26
+#define MODSERIAL_RBR  0x00
27
+#define MODSERIAL_THR  0x00
28
+#define MODSERIAL_DLL  0x00
29
+#define MODSERIAL_IER  0x04
30
+#define MODSERIAL_DML  0x04
31
+#define MODSERIAL_IIR  0x08
32
+#define MODSERIAL_FCR  0x08
33
+#define MODSERIAL_LCR  0x0C
34
+#define MODSERIAL_LSR  0x14
35
+#define MODSERIAL_SCR  0x1C
36
+#define MODSERIAL_ACR  0x20
37
+#define MODSERIAL_ICR  0x24
38
+#define MODSERIAL_FDR  0x28
39
+#define MODSERIAL_TER  0x30
40
+
41
+#define MODSERIAL_LSR_RDR  (1UL << 0)
42
+#define MODSERIAL_LSR_OE   (1UL << 1)
43
+#define MODSERIAL_LSR_PE   (1UL << 2)
44
+#define MODSERIAL_LSR_FE   (1UL << 3)
45
+#define MODSERIAL_LSR_BR   (1UL << 4)
46
+#define MODSERIAL_LSR_THRE (1UL << 5)
47
+#define MODSERIAL_LSR_TEMT (1UL << 6)
48
+#define MODSERIAL_LSR_RXFE (1UL << 7)
49
+
50
+#define MODSERIAL_FIFO_ENABLE   1
51
+#define MODSERIAL_FIFO_RX_RESET 2
52
+#define MODSERIAL_FIFO_TX_RESET 4
53
+
54
+#define _RBR    *((char *)_base+MODSERIAL_RBR)
55
+#define _THR    *((char *)_base+MODSERIAL_THR)
56
+#define _IIR    *((char *)_base+MODSERIAL_IIR)
57
+#define _IER    *((char *)_base+MODSERIAL_IER)
58
+#define _LSR    *((char *)_base+MODSERIAL_LSR)
59
+#define _FCR    *((char *)_base+MODSERIAL_FCR)
60
+
61
+#define MODSERIAL_TX_BUFFER_EMPTY (buffer_count[TxIrq]==0)
62
+#define MODSERIAL_RX_BUFFER_EMPTY (buffer_count[RxIrq]==0)
63
+#define MODSERIAL_TX_BUFFER_FULL  (buffer_count[TxIrq]==buffer_size[TxIrq])
64
+#define MODSERIAL_RX_BUFFER_FULL  (buffer_count[RxIrq]==buffer_size[RxIrq])
65
+
66
+#define MODSERIAL_THR_HAS_SPACE ((int)_LSR&MODSERIAL_LSR_THRE)
67
+#define MODSERIAL_TEMT_IS_EMPTY ((int)_LSR&MODSERIAL_LSR_TEMT)
68
+#define MODSERIAL_RBR_HAS_DATA  ((int)_LSR&MODSERIAL_LSR_RDR)
69
+
70
+#endif

+ 137
- 0
lib/MODSERIAL/MODSERIAL.cpp View File

@@ -0,0 +1,137 @@
1
+/*
2
+    Copyright (c) 2010 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+    
22
+    @file          MODSERIAL.h 
23
+    @purpose       Extends Serial to provide fully buffered IO
24
+    @version       1.6
25
+    @date          Nov 2010
26
+    @author        Andy Kirkham    
27
+*/
28
+
29
+#include "MODSERIAL.h"
30
+#include "MACROS.h"
31
+
32
+namespace AjK {
33
+
34
+MODSERIAL::MODSERIAL( PinName tx, PinName rx, const char* name ) : Serial( tx, rx, name )
35
+{
36
+    init( MODSERIAL_DEFAULT_TX_BUFFER_SIZE, MODSERIAL_DEFAULT_RX_BUFFER_SIZE, rx );
37
+}
38
+
39
+MODSERIAL::MODSERIAL( PinName tx, PinName rx, int bufferSize, const char* name ) : Serial( tx, rx, name )
40
+{
41
+    init( bufferSize, bufferSize, rx );
42
+}
43
+
44
+MODSERIAL::MODSERIAL( PinName tx, PinName rx, int txSize, int rxSize, const char* name ) : Serial( tx, rx, name )
45
+{
46
+    init( txSize, rxSize, rx );
47
+}
48
+
49
+MODSERIAL::~MODSERIAL()
50
+{
51
+    disableIrq();
52
+    if ( buffer[0] != NULL) free((char *)buffer[0] );
53
+    if ( buffer[1] != NULL) free((char *)buffer[1] );    
54
+}
55
+
56
+bool 
57
+MODSERIAL::txBufferFull( void ) 
58
+{ 
59
+    return MODSERIAL_TX_BUFFER_FULL; 
60
+}
61
+
62
+bool 
63
+MODSERIAL::rxBufferFull( void ) 
64
+{ 
65
+    return MODSERIAL_RX_BUFFER_FULL; 
66
+}
67
+
68
+bool 
69
+MODSERIAL::txBufferEmpty( void ) 
70
+{ 
71
+    return MODSERIAL_TX_BUFFER_EMPTY; 
72
+}
73
+
74
+bool 
75
+MODSERIAL::rxBufferEmpty( void ) 
76
+{ 
77
+    return MODSERIAL_RX_BUFFER_EMPTY; 
78
+}
79
+
80
+bool 
81
+MODSERIAL::txIsBusy( void ) 
82
+{ 
83
+    return ( _LSR & ( 3UL << 5 ) == 0 ) ? true : false; 
84
+} 
85
+
86
+void
87
+MODSERIAL::disableIrq( void )
88
+{
89
+
90
+#ifdef __LPC11UXX_H__
91
+    NVIC_DisableIRQ( UART_IRQn );
92
+#else
93
+    switch( _serial.index ) {
94
+        case 0:   NVIC_DisableIRQ( UART0_IRQn ); break;
95
+        case 1:   NVIC_DisableIRQ( UART1_IRQn ); break;
96
+        case 2:   NVIC_DisableIRQ( UART2_IRQn ); break;
97
+        case 3:   NVIC_DisableIRQ( UART3_IRQn ); break;
98
+    }
99
+#endif
100
+}
101
+
102
+void
103
+MODSERIAL::enableIrq(void)
104
+{
105
+#ifdef __LPC11UXX_H__
106
+    NVIC_EnableIRQ( UART_IRQn );
107
+#else
108
+    switch( _serial.index ) {
109
+        case 0:   NVIC_EnableIRQ( UART0_IRQn ); break;
110
+        case 1:   NVIC_EnableIRQ( UART1_IRQn ); break;
111
+        case 2:   NVIC_EnableIRQ( UART2_IRQn ); break;
112
+        case 3:   NVIC_EnableIRQ( UART3_IRQn ); break;
113
+    }
114
+#endif
115
+}
116
+
117
+int 
118
+MODSERIAL::rxDiscardLastChar( void )
119
+{
120
+    // This function can only be called indirectly from
121
+    // an rxCallback function. Therefore, we know we 
122
+    // just placed a char into the buffer.
123
+    char c = buffer[RxIrq][buffer_in[RxIrq]];
124
+    
125
+    if (buffer_count[RxIrq]) {        
126
+        buffer_count[RxIrq]--;
127
+        buffer_in[RxIrq]--;
128
+        if (buffer_in[RxIrq] < 0) {
129
+            buffer_in[RxIrq] = buffer_size[RxIrq] - 1;
130
+        }
131
+    }
132
+    
133
+    return (int)c;
134
+}
135
+
136
+
137
+}; // namespace AjK ends

+ 1089
- 0
lib/MODSERIAL/MODSERIAL.h
File diff suppressed because it is too large
View File


+ 38
- 0
lib/MODSERIAL/MODSERIAL_IRQ_INFO.cpp View File

@@ -0,0 +1,38 @@
1
+/*
2
+    Copyright (c) 2010 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+    
22
+    @file          MODSERIAL_IRQ_INFO.cpp 
23
+    @author        Andy Kirkham    
24
+*/
25
+
26
+#include "MODSERIAL.h"
27
+
28
+namespace AjK {
29
+
30
+int 
31
+MODSERIAL_IRQ_INFO::rxDiscardLastChar(void) 
32
+{ 
33
+    if (!serial) return -1;
34
+    
35
+    return serial->rxDiscardLastChar(); 
36
+}
37
+
38
+}; // namespace AjK ends

+ 81
- 0
lib/MODSERIAL/PUTC.cpp View File

@@ -0,0 +1,81 @@
1
+/*
2
+    Copyright (c) 2010 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+*/
22
+
23
+#include "MODSERIAL.h"
24
+#include "MACROS.h"
25
+
26
+namespace AjK {
27
+
28
+int
29
+MODSERIAL::__putc(int c, bool block) {
30
+    
31
+    // If no buffer is in use fall back to standard TX FIFO usage.
32
+    // Note, we must block in this case and ignore bool "block" 
33
+    // so as to maintain compat with Mbed Serial.
34
+    if (buffer[TxIrq] == (char *)NULL || buffer_size[TxIrq] == 0) {
35
+        while (! MODSERIAL_THR_HAS_SPACE) ; // Wait for space in the TX FIFO.
36
+        _THR = (uint32_t)c;
37
+        return 0;
38
+    }
39
+    
40
+    if ( MODSERIAL_THR_HAS_SPACE && MODSERIAL_TX_BUFFER_EMPTY && dmaSendChannel == -1 ) {
41
+        _THR = (uint32_t)c;
42
+    }
43
+    else {
44
+        if (block) {
45
+            uint32_t ier = _IER; _IER = 1;
46
+            while ( MODSERIAL_TX_BUFFER_FULL ) {  // Blocks!
47
+                // If putc() is called from an ISR then we are stuffed
48
+                // because in an ISR no bytes from the TX buffer will 
49
+                // get transferred to teh TX FIFOs while we block here.
50
+                // So, to work around this, instead of sitting in a 
51
+                // loop waiting for space in the TX buffer (which will
52
+                // never happen in IRQ context), check to see if the
53
+                // TX FIFO has space available to move bytes from the
54
+                // TX buffer to TX FIFO to make space. The easiest way
55
+                // to do this is to poll the isr_tx() function while we
56
+                // are blocking.
57
+                isr_tx(false);
58
+            }
59
+            _IER = ier;
60
+        }
61
+        else if( MODSERIAL_TX_BUFFER_FULL ) {
62
+            buffer_overflow[TxIrq] = c; // Oh dear, no room in buffer.
63
+            _isr[TxOvIrq].call(&this->callbackInfo);
64
+            return -1;
65
+        }
66
+        _IER &= ~2;
67
+        buffer[TxIrq][buffer_in[TxIrq]] = c;
68
+        __disable_irq();
69
+        buffer_count[TxIrq]++;
70
+        __enable_irq();
71
+        buffer_in[TxIrq]++;
72
+        if (buffer_in[TxIrq] >= buffer_size[TxIrq]) {
73
+            buffer_in[TxIrq] = 0;
74
+        }            
75
+        _IER |= 2;        
76
+    }
77
+      
78
+    return 0;
79
+}
80
+
81
+}; // namespace AjK ends

+ 123
- 0
lib/MODSERIAL/RESIZE.cpp View File

@@ -0,0 +1,123 @@
1
+/*
2
+    Copyright (c) 2010 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+*/
22
+
23
+#include "MODSERIAL.h"
24
+#include "MACROS.h"
25
+
26
+namespace AjK {
27
+
28
+int
29
+MODSERIAL::resizeBuffer(int size, IrqType type, bool memory_check)
30
+{
31
+    int rval = Ok;
32
+    
33
+    // If the requested size is the same as the current size there's nothing to do,
34
+    // just continue to use the same buffer as it's fine as it is.
35
+    if (buffer_size[type] == size) return rval;
36
+    
37
+    // Make sure the ISR cannot use the buffers while we are manipulating them.
38
+    disableIrq();
39
+    
40
+    // If the requested buffer size is larger than the current size, 
41
+    // attempt to create a new buffer and use it.
42
+    if (buffer_size[type] < size) {
43
+        rval = upSizeBuffer(size, type, memory_check);
44
+    }
45
+    else if (buffer_size[type] > size) {
46
+        rval = downSizeBuffer(size, type, memory_check);
47
+    }
48
+    
49
+    // Start the ISR system again with the new buffers.
50
+    enableIrq();
51
+    
52
+    return rval;
53
+}
54
+
55
+int 
56
+MODSERIAL::downSizeBuffer(int size, IrqType type, bool memory_check)
57
+{
58
+    if (size >= buffer_count[type]) {
59
+        return BufferOversize;
60
+    }
61
+    
62
+    char *s = (char *)malloc(size);
63
+    
64
+    if (s == (char *)NULL) {
65
+        if (memory_check) {
66
+            error("Failed to allocate memory for %s buffer", type == TxIrq ? "TX" : "RX");
67
+        }
68
+        return NoMemory;
69
+    }
70
+    
71
+    int c, new_in = 0;
72
+    
73
+    do {
74
+        c = __getc(false);
75
+        if (c != -1) s[new_in++] = (char)c;
76
+        if (new_in >= size) new_in = 0;
77
+    }
78
+    while (c != -1);
79
+    
80
+    free((char *)buffer[type]);
81
+    buffer[type]      = s;
82
+    buffer_in[type]   = new_in;
83
+    buffer_out[type]  = 0;
84
+    return Ok;        
85
+}
86
+
87
+int 
88
+MODSERIAL::upSizeBuffer(int size, IrqType type, bool memory_check)
89
+{
90
+    char *s = (char *)malloc(size);
91
+    
92
+    if (s == (char *)NULL) {
93
+        if (memory_check) {
94
+            error("Failed to allocate memory for %s buffer", type == TxIrq ? "TX" : "RX");
95
+        }
96
+        return NoMemory;
97
+    }
98
+    
99
+    if (buffer_count[type] == 0) { // Current buffer empty?
100
+        free((char *)buffer[type]);
101
+        buffer[type]      = s;
102
+        buffer_in[type]   = 0;
103
+        buffer_out[type]  = 0;
104
+    }        
105
+    else { // Copy the current contents into the new buffer.
106
+        int c, new_in = 0;
107
+        do {
108
+            c = __getc(false);
109
+            if (c != -1) s[new_in++] = (char)c;
110
+            if (new_in >= size) new_in = 0; // Shouldn't happen, but be sure.
111
+        }
112
+        while (c != -1);
113
+        free((char *)buffer[type]);
114
+        buffer[type]      = s;
115
+        buffer_in[type]   = new_in;
116
+        buffer_out[type]  = 0;
117
+    }
118
+    
119
+    buffer_size[type] = size;
120
+    return Ok;
121
+}
122
+
123
+}; // namespace AjK ends

+ 120
- 0
lib/MODSERIAL/example1.cpp View File

@@ -0,0 +1,120 @@
1
+#ifdef COMPILE_EXAMPLE1_CODE_MODSERIAL
2
+
3
+/*
4
+ * To run this test program, link p9 to p10 so the Serial loops
5
+ * back and receives characters it sends.
6
+ */
7
+ 
8
+#include "mbed.h"
9
+#include "MODSERIAL.h"
10
+
11
+DigitalOut led1(LED1);
12
+DigitalOut led2(LED2);
13
+DigitalOut led3(LED3);
14
+DigitalOut led4(LED4);
15
+
16
+MODSERIAL pc(USBTX, USBRX);
17
+
18
+/*
19
+ * As experiement, you can define MODSERIAL as show here and see what
20
+ * effects it has on the LEDs.
21
+ *
22
+ * MODSERIAL uart(TX_PIN, RX_PIN, 512);
23
+ *   With this, the 512 characters sent can straight into the buffer
24
+ *   vary quickly. This means LED1 is only on briefly as the TX buffer
25
+ *   fills.
26
+ *
27
+ * MODSERIAL uart(TX_PIN, RX_PIN, 32);
28
+ *   With this, the buffer is smaller than the default 256 bytes and
29
+ *   therefore LED1 stays on much longer while the system waits for
30
+ *   room in the TX buffer.
31
+ */
32
+MODSERIAL uart(TX_PIN, RX_PIN);
33
+
34
+// This function is called when a character goes from the TX buffer
35
+// to the Uart THR FIFO register.
36
+void txCallback(MODSERIAL_IRQ_INFO *q) {
37
+    led2 = !led2;
38
+}
39
+
40
+// This function is called when TX buffer goes empty
41
+void txEmpty(MODSERIAL_IRQ_INFO *q) {
42
+    led2 = 0;
43
+    pc.puts(" Done. ");
44
+}
45
+
46
+// This function is called when a character goes into the RX buffer.
47
+void rxCallback(MODSERIAL_IRQ_INFO *q) {
48
+    led3 = !led3;
49
+    pc.putc(uart.getc());
50
+}
51
+
52
+int main() {
53
+    int c = 'A';
54
+    
55
+    // Ensure the baud rate for the PC "USB" serial is much
56
+    // higher than "uart" baud rate below.
57
+    pc.baud(PC_BAUD);
58
+    
59
+    // Use a deliberatly slow baud to fill up the TX buffer
60
+    uart.baud(1200);
61
+    
62
+    uart.attach(&txCallback, MODSERIAL::TxIrq);
63
+    uart.attach(&rxCallback, MODSERIAL::RxIrq);
64
+    uart.attach(&txEmpty,    MODSERIAL::TxEmpty);
65
+    
66
+    // Loop sending characters. We send 512
67
+    // which is twice the default TX/RX buffer size.
68
+    
69
+    led1 = 1; // Show start of sending with LED1.
70
+    
71
+    for (int loop = 0; loop < 512; loop++) {
72
+        uart.printf("%c", c);        
73
+        c++;
74
+        if (c > 'Z') c = 'A';
75
+    }
76
+    
77
+    led1 = 0; // Show the end of sending by switching off LED1.
78
+    
79
+    // End program. Flash LED4. Notice how LED 2 and 3 continue
80
+    // to flash for a short period while the interrupt system 
81
+    // continues to send the characters left in the TX buffer.
82
+    
83
+    while(1) {
84
+        led4 = !led4;
85
+        wait(0.25);
86
+    }
87
+}
88
+
89
+/*
90
+ * Notes. Here is the sort of output you can expect on your PC/Mac/Linux host
91
+ * machine that is connected to the "pc" USB serial port.
92
+ *
93
+ * ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV
94
+ * WXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQR
95
+ * STUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMN
96
+ * OPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJ
97
+ * KLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF
98
+ * GHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZAB
99
+ * CDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQ Done. R
100
+ *
101
+ * Of interest is that last "R" character after the system has said "Done."
102
+ * This comes from the fact that the TxEmpty callback is made when the TX buffer
103
+ * becomes empty. MODSERIAL makes use of the fact that the Uarts built into the 
104
+ * LPC17xx device use a 16 byte FIFO on both RX and TX channels. This means that
105
+ * when the TxEmpty callback is made, the TX buffer is empty, but that just means
106
+ * the "last few characters" were written to the TX FIFO. So although the TX
107
+ * buffer has gone empty, the Uart's transmit system is still sending any remaining
108
+ * characters from it's TX FIFO. If you want to be truely sure all the characters
109
+ * you have sent have left the Mbed then call txIsBusy(); This function will
110
+ * return true if characters are still being sent. If it returns false after
111
+ * the Tx buffer is empty then all your characters have been sent.
112
+ *
113
+ * In a similar way, when characters are received into the RX FIFO, the entire
114
+ * FIFO contents is moved to the RX buffer, assuming there is room left in the
115
+ * RX buffer. If there is not, any remaining characters are left in the RX FIFO
116
+ * and will be moved to the RX buffer on the next interrupt or when the running 
117
+ * program removes a character(s) from the RX buffer with the getc() method.
118
+ */
119
+ 
120
+#endif

+ 167
- 0
lib/MODSERIAL/example2.cpp View File

@@ -0,0 +1,167 @@
1
+/*
2
+    Copyright (c) 2011 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+    
22
+    @file          example2.cpp 
23
+    @purpose       Demos a simple messaging system.
24
+    @version       see ChangeLog.c
25
+    @date          Jan 2011
26
+    @author        Andy Kirkham
27
+*/
28
+
29
+/*
30
+    This example demostrates a simple "messaging" system. You can use it with
31
+    a terminal program to test it out or write a cusom C#/C++/VB/etc program
32
+    to read and write messages to or from the Mbed. The default baud rate in
33
+    this example is 115200.
34
+    
35
+    In this example, the LEDs are controlled and pins p21 to p24 are set as
36
+    InterruptIn and send messages out when their value changes.
37
+    
38
+    To use, hook up the MBed USB and open your fav terminal. All messages
39
+    end with the \n character, don't forget to hit carriage return!. 
40
+    As an example:-
41
+        
42
+        to switch on LED1 send LED1:1\n, off is LED1:0\n and toggle is LED1:2\n
43
+        to switch on LED2 send LED2:1\n, off is LED2:0\n and toggle is LED2:2\n
44
+        to switch on LED3 send LED3:1\n, off is LED3:0\n and toggle is LED3:2\n
45
+        to switch on LED4 send LED4:1\n, off is LED4:0\n and toggle is LED4:2\n
46
+        
47
+    When a pin change on p21 to p24 happens, a message is sent. As an example
48
+    when p21 goes low PIN21:0\n is sent, when goes high PIN21:1\n is sent.
49
+    
50
+    Note, the InterruptIn pins p21 to p24 are setup to have pullups. This means
51
+    they are high. To activate them use a wire to short the pin to 0volts.
52
+    
53
+    If you find that p21 to p24 sent a lot of on/off/on/off then it's probably
54
+    due to "bounce". If you are connecting a mechanical switch to a pin you
55
+    may prefer to use the PinDetect library rather than using InterruptIn.
56
+    @see http://mbed.org/users/AjK/libraries/PinDetect/latest
57
+    
58
+    One point you may notice. Incoming messages are processed via main()'s
59
+    while(1) loop whereas pin changes have their messages directly sent.
60
+    The reason for this is when MODSERIAL makes callbacks to your application
61
+    it is in "interrupt context". And one thing you want to avoid is spending
62
+    lots of CPU time in that context. So, the callback moves the message from
63
+    the input buffer to a local holding buffer and it then sets a bool flag
64
+    which tells main()'s while(1) loop to process that buffer. This means the 
65
+    time spent doing the real incoming message handing is within your program
66
+    and not within MODSERIAL's interrupt context. So you may ask, why not do
67
+    the same for out going messages? Well, because MODSERIAL output buffers
68
+    all your sent content then sending chars is very fast. MODSERIAL handles
69
+    all the nitty gritty bits for you. You can just send. This example uses
70
+    puts() to send the message. If you can, always try and use sprintf()+puts()
71
+    rathe than printf(), printf() is known to often screw things up when used
72
+    within an interrupt context. Better still, just use puts() and do away
73
+    with any of the crappy ?printf() calls if possible. But I found the code
74
+    below to work fine even at 115200baud.
75
+    
76
+*/
77
+
78
+
79
+#ifdef COMPILE_EXAMPLE1_CODE_MODSERIAL
80
+
81
+#include "mbed.h"
82
+#include "MODSERIAL.h"
83
+
84
+#define MESSAGE_BUFFER_SIZE 32
85
+
86
+DigitalOut led1(LED1);
87
+DigitalOut led2(LED2);
88
+DigitalOut led3(LED3);
89
+DigitalOut led4(LED4);
90
+
91
+InterruptIn P21(p21);
92
+InterruptIn P22(p22);
93
+InterruptIn P23(p23);
94
+InterruptIn P24(p24);
95
+
96
+MODSERIAL messageSystem(USBTX, USBRX);
97
+
98
+char messageBufferIncoming[MESSAGE_BUFFER_SIZE];
99
+char messageBufferOutgoing[MESSAGE_BUFFER_SIZE];
100
+bool messageReceived;
101
+
102
+void messageReceive(MODSERIAL_IRQ_INFO *q) {
103
+    MODSERIAL *sys = q->serial;
104
+    sys->move(messageBufferIncoming, MESSAGE_BUFFER_SIZE);
105
+    messageReceived = true;
106
+    return 0;
107
+}
108
+
109
+void messageProcess(void) {
110
+         if (!strncmp(messageBufferIncoming, "LED1:1", sizeof("LED1:1")-1)) led1 = 1;
111
+    else if (!strncmp(messageBufferIncoming, "LED1:0", sizeof("LED1:0")-1)) led1 = 0;
112
+    else if (!strncmp(messageBufferIncoming, "LED1:2", sizeof("LED1:2")-1)) led1 = !led1;
113
+    
114
+    else if (!strncmp(messageBufferIncoming, "LED2:1", sizeof("LED2:1")-1)) led2 = 1;
115
+    else if (!strncmp(messageBufferIncoming, "LED2:0", sizeof("LED2:0")-1)) led2 = 0;
116
+    else if (!strncmp(messageBufferIncoming, "LED2:2", sizeof("LED2:2")-1)) led2 = !led2;
117
+    
118
+    else if (!strncmp(messageBufferIncoming, "LED3:1", sizeof("LED3:1")-1)) led3 = 1;
119
+    else if (!strncmp(messageBufferIncoming, "LED3:0", sizeof("LED3:0")-1)) led3 = 0;
120
+    else if (!strncmp(messageBufferIncoming, "LED3:2", sizeof("LED3:2")-1)) led3 = !led3;
121
+    
122
+    else if (!strncmp(messageBufferIncoming, "LED4:1", sizeof("LED4:1")-1)) led4 = 1;
123
+    else if (!strncmp(messageBufferIncoming, "LED4:0", sizeof("LED4:0")-1)) led4 = 0;
124
+    else if (!strncmp(messageBufferIncoming, "LED4:2", sizeof("LED4:2")-1)) led4 = !led4;
125
+    
126
+    messageReceived = false;
127
+}
128
+
129
+#define PIN_MESSAGE_SEND(x,y) \
130
+    sprintf(messageBufferOutgoing,"PIN%02d:%d\n",x,y);\
131
+    messageSystem.puts(messageBufferOutgoing);
132
+
133
+void pin21Rise(void) { PIN_MESSAGE_SEND(21, 1); }
134
+void pin21Fall(void) { PIN_MESSAGE_SEND(21, 0); }
135
+void pin22Rise(void) { PIN_MESSAGE_SEND(22, 1); }
136
+void pin22Fall(void) { PIN_MESSAGE_SEND(22, 0); }
137
+void pin23Rise(void) { PIN_MESSAGE_SEND(23, 1); }
138
+void pin23Fall(void) { PIN_MESSAGE_SEND(23, 0); }
139
+void pin24Rise(void) { PIN_MESSAGE_SEND(24, 1); }
140
+void pin24Fall(void) { PIN_MESSAGE_SEND(24, 0); }
141
+
142
+int main() {
143
+
144
+    messageReceived = false;
145
+    messageSystem.baud(115200);
146
+    messageSystem.attach(&messageReceive, MODSERIAL::RxAutoDetect);
147
+    messageSystem.autoDetectChar('\n'); 
148
+
149
+    // Enable pullup resistors on pins.
150
+    P21.mode(PullUp); P22.mode(PullUp); P23.mode(PullUp); P24.mode(PullUp);
151
+    
152
+    // Fix Mbed library bug, see http://mbed.org/forum/bugs-suggestions/topic/1498
153
+    LPC_GPIOINT->IO2IntClr = (1UL << 5) | (1UL << 4) | (1UL << 3) | (1UL << 2); 
154
+    
155
+    // Attach InterruptIn pin callbacks.
156
+    P21.rise(&pin21Rise); P21.fall(&pin21Fall);
157
+    P22.rise(&pin22Rise); P22.fall(&pin22Fall);
158
+    P23.rise(&pin23Rise); P23.fall(&pin23Fall);
159
+    P24.rise(&pin24Rise); P24.fall(&pin24Fall);
160
+    
161
+    while(1) {
162
+        // Process incoming messages.
163
+        if (messageReceived) messageProcess();
164
+    }
165
+}
166
+
167
+#endif

+ 83
- 0
lib/MODSERIAL/example3a.cpp View File

@@ -0,0 +1,83 @@
1
+/*
2
+    Copyright (c) 2011 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+    
22
+    @file          example3.cpp 
23
+    @purpose       Demos a simple filter.
24
+    @version       see ChangeLog.c
25
+    @author        Andy Kirkham
26
+*/
27
+
28
+/*
29
+    This example shows how to use the new callback system. In the old system
30
+    Mbed's FunctionPointer[1] type was used to store abd make calls to callbacks.
31
+    However, that limits the callback function prototype to void func(void);
32
+    which means we cannot pass parameters.
33
+    
34
+    This latest version of MODSERIAL now uses its own callback object. This allows
35
+    the passing of a pointer to a class that holds information about the MODSERIAL
36
+    object making the callback. As of version 1.18 one critcal piece of information
37
+    is passed, a pointer to the MODSERIAL object. This allows callbacks to use the
38
+    MODSERIAL functions and data.
39
+        
40
+    Additionally, since MODSERIAL and the callback parameter class MODSERIAL_IRQ_INFO
41
+    are friends, MODSERIAL_IRQ_INFO can access the protected functions of MODSERIAL.
42
+    This is used to ensure functions that can only be called during a callback
43
+    can be invoked from a callback. 
44
+    
45
+    [1] http://mbed.org/projects/libraries/svn/mbed/trunk/FunctionPointer.h    
46
+*/
47
+
48
+#ifdef COMPILE_EXAMPLE3_CODE_MODSERIAL
49
+
50
+#include "mbed.h"
51
+#include "MODSERIAL.h"
52
+
53
+DigitalOut led1(LED1);
54
+
55
+MODSERIAL pc(USBTX, USBRX);
56
+
57
+// The following callback is defined in example3b.cpp
58
+//! @see example3b.cpp
59
+void rxCallback(MODSERIAL_IRQ_INFO *info);
60
+
61
+int main() {
62
+    
63
+    int life_counter = 0;
64
+    
65
+    pc.baud(115200);
66
+    
67
+    pc.attach(&rxCallback, MODSERIAL::RxIrq);
68
+
69
+    while(1) {
70
+        // Echo back any chars we get except 'A' which is filtered by the rxCallback.
71
+        if (pc.readable()) {
72
+            pc.putc(pc.getc());
73
+        }
74
+        
75
+        // Toggle LED1 every so often to show we are alive.
76
+        if (life_counter++ == 1000000) {
77
+            life_counter = 0;
78
+            led1 = !led1;
79
+        }
80
+    }
81
+}
82
+
83
+#endif

+ 78
- 0
lib/MODSERIAL/example3b.cpp View File

@@ -0,0 +1,78 @@
1
+/*
2
+    Copyright (c) 2011 Andy Kirkham
3
+ 
4
+    Permission is hereby granted, free of charge, to any person obtaining a copy
5
+    of this software and associated documentation files (the "Software"), to deal
6
+    in the Software without restriction, including without limitation the rights
7
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+    copies of the Software, and to permit persons to whom the Software is
9
+    furnished to do so, subject to the following conditions:
10
+ 
11
+    The above copyright notice and this permission notice shall be included in
12
+    all copies or substantial portions of the Software.
13
+ 
14
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+    THE SOFTWARE.
21
+    
22
+    @file          example3b.cpp 
23
+    @purpose       Demos a simple filter.
24
+    @version       see ChangeLog.c
25
+    @author        Andy Kirkham
26
+*/
27
+
28
+/*
29
+    This example shows how to use the new callback system. In the old system
30
+    Mbed's FunctionPointer[1] type was used to store abd make calls to callbacks.
31
+    However, that limits the callback function prototype to void func(void);
32
+    which means we cannot pass parameters.
33
+    
34
+    This latest version of MODSERIAL now uses its own callback object. This allows
35
+    the passing of a pointer to a class that holds information about the MODSERIAL
36
+    object making the callback. As of version 1.18 one critcal piece of information
37
+    is passed, a pointer to the MODSERIAL object. This allows callbacks to use the
38
+    MODSERIAL functions and data.
39
+        
40
+    Additionally, since MODSERIAL and the callback parameter class MODSERIAL_IRQ_INFO
41
+    are friends, MODSERIAL_IRQ_INFO can access the protected functions of MODSERIAL.
42
+    This is used to ensure functions that can only be called during a callback
43
+    can be invoked from a callback. 
44
+    
45
+    [1] http://mbed.org/projects/libraries/svn/mbed/trunk/FunctionPointer.h    
46
+*/
47
+
48
+
49
+#ifdef COMPILE_EXAMPLE3_CODE_MODSERIAL
50
+
51
+#include "mbed.h"
52
+#include "MODSERIAL.h"
53
+
54
+void rxCallback(MODSERIAL_IRQ_INFO *info) {
55
+
56
+    // Get the pointer to our MODSERIAL object that invoked this callback.
57
+    MODSERIAL *pc = info->serial;
58
+    
59
+    // info->serial points at the MODSERIAL instance so we can use it to call
60
+    // any of the public MODSERIAL functions that are normally available. So
61
+    // there's now no need to use the global version (pc in our case) inside
62
+    // callback functions.    
63
+    char c = pc->rxGetLastChar(); // Where local pc variable is a pointer to the global MODSERIAL pc object.
64
+    
65
+    // The following is rather daft but demos the point.
66
+    // Don't allow the letter "A" go into the RX buffer.
67
+    // Basically acts as a filter to remove the letter "A" 
68
+    // if it goes into the RX buffer.
69
+    if (c == 'A') {
70
+        // Note, we call the MODSERIAL_IRQ_INFO::rxDiscardLastChar() public function which
71
+        // is permitted access to the protected version of MODSERIAL::rxDiscardLastChar()
72
+        // within MODSERIAL (because they are friends). This ensures rxDiscardLastChar()
73
+        // can only be called within an rxCallback function. 
74
+        info->rxDiscardLastChar(); 
75
+    }
76
+}
77
+
78
+#endif

+ 144
- 0
lib/MODSERIAL/example_dma.cpp View File

@@ -0,0 +1,144 @@
1
+#ifdef COMPILE_EXAMPLE_CODE_MODSERIAL_MODDMA
2
+
3
+/*
4
+ * To run this test program, link p9 to p10 so the Serial loops
5
+ * back and receives characters it sends.
6
+ */
7
+ 
8
+#include "mbed.h"
9
+
10
+/* Note, this example requires that you also import into the Mbed
11
+   compiler the MODDMA project as well as MODSERIAL
12
+   http://mbed.org/users/AjK/libraries/MODDMA/latest 
13
+   MODDMA.h MUST come before MODSERIAL.h */
14
+#include "MODDMA.h"     // <--- Declare first
15
+#include "MODSERIAL.h"  // Flollowed by MODSERIAL
16
+
17
+DigitalOut led1(LED1);
18
+DigitalOut led2(LED2);
19
+DigitalOut led3(LED3);
20
+DigitalOut led4(LED4);
21
+
22
+MODSERIAL pc(USBTX, USBRX);
23
+
24
+/*
25
+ * As experiement, you can define MODSERIAL as show here and see what
26
+ * effects it has on the LEDs.
27
+ *
28
+ * MODSERIAL uart(TX_PIN, RX_PIN, 512);
29
+ *   With this, the 512 characters sent can straight into the buffer
30
+ *   vary quickly. This means LED1 is only on briefly as the TX buffer
31
+ *   fills.
32
+ *
33
+ * MODSERIAL uart(TX_PIN, RX_PIN, 32);
34
+ *   With this, the buffer is smaller than the default 256 bytes and
35
+ *   therefore LED1 stays on much longer while the system waits for
36
+ *   room in the TX buffer.
37
+ */
38
+MODSERIAL uart(TX_PIN, RX_PIN);
39
+
40
+MODDMA dma;
41
+
42
+// This function is called when a character goes from the TX buffer
43
+// to the Uart THR FIFO register.
44
+void txCallback(void) {
45
+    led2 = !led2;
46
+}
47
+
48
+// This function is called when TX buffer goes empty
49
+void txEmpty(void) {
50
+    led2 = 0;
51
+    pc.puts(" Done. ");
52
+}
53
+
54
+void dmaComplete(void) {
55
+    led1 = 1;
56
+}
57
+
58
+// This function is called when a character goes into the RX buffer.
59
+void rxCallback(void) {
60
+    led3 = !led3;
61
+    pc.putc(uart.getc());
62
+}
63
+
64
+int main() {
65
+    char s1[] = " *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* ";
66
+    int c = 'A';
67
+    
68
+    // Tell MODSERIAL where the MODDMA controller is.
69
+    pc.MODDMA( &dma );
70
+    
71
+    // Ensure the baud rate for the PC "USB" serial is much
72
+    // higher than "uart" baud rate below.
73
+    pc.baud( PC_BAUD );
74
+    
75
+    // Use a deliberatly slow baud to fill up the TX buffer
76
+    uart.baud(1200);
77
+    
78
+    uart.attach( &txCallback, MODSERIAL::TxIrq );
79
+    uart.attach( &rxCallback, MODSERIAL::RxIrq );
80
+    uart.attach( &txEmpty,    MODSERIAL::TxEmpty );
81
+    
82
+    // Loop sending characters. We send 512
83
+    // which is twice the default TX/RX buffer size.
84
+    
85
+    led1 = 0;
86
+    
87
+    // Send the buffer s using DMA channel 7
88
+    pc.attach_dmaSendComplete( &dmaComplete );
89
+    pc.dmaSend( s1, sizeof(s1), MODDMA::Channel_7 );
90
+    
91
+    for (int loop = 0; loop < 512; loop++) {
92
+        uart.printf("%c", c);        
93
+        c++;
94
+        if (c > 'Z') c = 'A';
95
+    }
96
+    
97
+    led1 = 0; // Show the end of sending by switching off LED1.
98
+    
99
+    // End program. Flash LED4. Notice how LED 2 and 3 continue
100
+    // to flash for a short period while the interrupt system 
101
+    // continues to send the characters left in the TX buffer.
102
+    
103
+    while(1) {
104
+        led4 = !led4;
105
+        wait(0.25);
106
+    }
107
+}
108
+
109
+/*
110
+ * Notes. Here is the sort of output you can expect on your PC/Mac/Linux host
111
+ * machine that is connected to the "pc" USB serial port.
112
+ *
113
+ *  *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* ABCDEFGHIJKLMNOPQRSTUVWXYZABCDE
114
+ * FGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZA
115
+ * BCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVW
116
+ * XYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRS
117
+ * TUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNO
118
+ * PQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJK
119
+ * LMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFG
120
+ * HIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQ Done. R
121
+ *
122
+ * Note how the DMA blocks the TX buffer sending under standard interrupt control.
123
+ * Not until the DMA transfer is complete will "normal" buffered TX sending resume.
124
+ *
125
+ * Of interest is that last "R" character after the system has said "Done."
126
+ * This comes from the fact that the TxEmpty callback is made when the TX buffer
127
+ * becomes empty. MODSERIAL makes use of the fact that the Uarts built into the 
128
+ * LPC17xx device use a 16 byte FIFO on both RX and TX channels. This means that
129
+ * when the TxEmpty callback is made, the TX buffer is empty, but that just means
130
+ * the "last few characters" were written to the TX FIFO. So although the TX
131
+ * buffer has gone empty, the Uart's transmit system is still sending any remaining
132
+ * characters from it's TX FIFO. If you want to be truely sure all the characters
133
+ * you have sent have left the Mbed then call txIsBusy(); This function will
134
+ * return true if characters are still being sent. If it returns false after
135
+ * the Tx buffer is empty then all your characters have been sent.
136
+ *
137
+ * In a similar way, when characters are received into the RX FIFO, the entire
138
+ * FIFO contents is moved to the RX buffer, assuming there is room left in the
139
+ * RX buffer. If there is not, any remaining characters are left in the RX FIFO
140
+ * and will be moved to the RX buffer on the next interrupt or when the running 
141
+ * program removes a character(s) from the RX buffer with the getc() method.
142
+ */
143
+ 
144
+#endif

Loading…
Cancel
Save