1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2013 ARM Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef MBED_SERIALBASE_H
17 #define MBED_SERIALBASE_H
18 
19 #include "platform/platform.h"
20 
21 #if DEVICE_SERIAL
22 
23 #include "Stream.h"
24 #include "Callback.h"
25 #include "serial_api.h"
26 #include "mbed_toolchain.h"
27 
28 #if DEVICE_SERIAL_ASYNCH
29 #include "CThunk.h"
30 #include "dma_api.h"
31 #endif
32 
33 namespace mbed {
34 /** \addtogroup drivers */
35 /** @{*/
36 
37 /** A base class for serial port implementations
38  * Can't be instantiated directly (use Serial or RawSerial)
39  *
40  * @Note Synchronization level: Set by subclass
41  */
42 class SerialBase {
43 
44 public:
45     /** Set the baud rate of the serial port
46      *
47      *  @param baudrate The baudrate of the serial port (default = 9600).
48      */
49     void baud(int baudrate);
50 
51     enum Parity {
52         None = 0,
53         Odd,
54         Even,
55         Forced1,
56         Forced0
57     };
58 
59     enum IrqType {
60         RxIrq = 0,
61         TxIrq,
62 
63         IrqCnt
64     };
65 
66     enum Flow {
67         Disabled = 0,
68         RTS,
69         CTS,
70         RTSCTS
71     };
72 
73     /** Set the transmission format used by the serial port
74      *
75      *  @param bits The number of bits in a word (5-8; default = 8)
76      *  @param parity The parity used (SerialBase::None, SerialBase::Odd, SerialBase::Even, SerialBase::Forced1, SerialBase::Forced0; default = SerialBase::None)
77      *  @param stop The number of stop bits (1 or 2; default = 1)
78      */
79     void format(int bits=8, Parity parity=SerialBase::None, int stop_bits=1);
80 
81     /** Determine if there is a character available to read
82      *
83      *  @returns
84      *    1 if there is a character available to read,
85      *    0 otherwise
86      */
87     int readable();
88 
89     /** Determine if there is space available to write a character
90      *
91      *  @returns
92      *    1 if there is space to write a character,
93      *    0 otherwise
94      */
95     int writeable();
96 
97     /** Attach a function to call whenever a serial interrupt is generated
98      *
99      *  @param func A pointer to a void function, or 0 to set as none
100      *  @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
101      */
102     void attach(Callback<void()> func, IrqType type=RxIrq);
103 
104     /** Attach a member function to call whenever a serial interrupt is generated
105      *
106      *  @param obj pointer to the object to call the member function on
107      *  @param method pointer to the member function to be called
108      *  @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
109      *  @deprecated
110      *      The attach function does not support cv-qualifiers. Replaced by
111      *      attach(callback(obj, method), type).
112      */
113     template<typename T>
114     MBED_DEPRECATED_SINCE("mbed-os-5.1",
115         "The attach function does not support cv-qualifiers. Replaced by "
116         "attach(callback(obj, method), type).")
117     void attach(T *obj, void (T::*method)(), IrqType type=RxIrq) {
118         attach(callback(obj, method), type);
119     }
120 
121     /** Attach a member function to call whenever a serial interrupt is generated
122      *
123      *  @param obj pointer to the object to call the member function on
124      *  @param method pointer to the member function to be called
125      *  @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
126      *  @deprecated
127      *      The attach function does not support cv-qualifiers. Replaced by
128      *      attach(callback(obj, method), type).
129      */
130     template<typename T>
131     MBED_DEPRECATED_SINCE("mbed-os-5.1",
132         "The attach function does not support cv-qualifiers. Replaced by "
133         "attach(callback(obj, method), type).")
134     void attach(T *obj, void (*method)(T*), IrqType type=RxIrq) {
135         attach(callback(obj, method), type);
136     }
137 
138     /** Generate a break condition on the serial line
139      */
140     void send_break();
141 
142 protected:
143 
144     /** Acquire exclusive access to this serial port
145      */
146     virtual void lock(void);
147 
148     /** Release exclusive access to this serial port
149      */
150     virtual void unlock(void);
151 
152 public:
153 
154 #if DEVICE_SERIAL_FC
155     /** Set the flow control type on the serial port
156      *
157      *  @param type the flow control type (Disabled, RTS, CTS, RTSCTS)
158      *  @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for CTS)
159      *  @param flow2 the second flow control pin (CTS for RTSCTS)
160      */
161     void set_flow_control(Flow type, PinName flow1=NC, PinName flow2=NC);
162 #endif
163 
164     static void _irq_handler(uint32_t id, SerialIrq irq_type);
165 
166 #if DEVICE_SERIAL_ASYNCH
167 
168     /** Begin asynchronous write using 8bit buffer. The completition invokes registered TX event callback
169      *
170      *  @param buffer   The buffer where received data will be stored
171      *  @param length   The buffer length in bytes
172      *  @param callback The event callback function
173      *  @param event    The logical OR of TX events
174      */
175     int write(const uint8_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_TX_COMPLETE);
176 
177     /** Begin asynchronous write using 16bit buffer. The completition invokes registered TX event callback
178      *
179      *  @param buffer   The buffer where received data will be stored
180      *  @param length   The buffer length in bytes
181      *  @param callback The event callback function
182      *  @param event    The logical OR of TX events
183      */
184     int write(const uint16_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_TX_COMPLETE);
185 
186     /** Abort the on-going write transfer
187      */
188     void abort_write();
189 
190     /** Begin asynchronous reading using 8bit buffer. The completition invokes registred RX event callback.
191      *
192      *  @param buffer     The buffer where received data will be stored
193      *  @param length     The buffer length in bytes
194      *  @param callback   The event callback function
195      *  @param event      The logical OR of RX events
196      *  @param char_match The matching character
197      */
198     int read(uint8_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_RX_COMPLETE, unsigned char char_match = SERIAL_RESERVED_CHAR_MATCH);
199 
200     /** Begin asynchronous reading using 16bit buffer. The completition invokes registred RX event callback.
201      *
202      *  @param buffer     The buffer where received data will be stored
203      *  @param length     The buffer length in bytes
204      *  @param callback   The event callback function
205      *  @param event      The logical OR of RX events
206      *  @param char_match The matching character
207      */
208     int read(uint16_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_RX_COMPLETE, unsigned char char_match = SERIAL_RESERVED_CHAR_MATCH);
209 
210     /** Abort the on-going read transfer
211      */
212     void abort_read();
213 
214     /** Configure DMA usage suggestion for non-blocking TX transfers
215      *
216      *  @param usage The usage DMA hint for peripheral
217      *  @return Zero if the usage was set, -1 if a transaction is on-going
218      */
219     int set_dma_usage_tx(DMAUsage usage);
220 
221     /** Configure DMA usage suggestion for non-blocking RX transfers
222      *
223      *  @param usage The usage DMA hint for peripheral
224      *  @return Zero if the usage was set, -1 if a transaction is on-going
225      */
226     int set_dma_usage_rx(DMAUsage usage);
227 
228 protected:
229     void start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event, unsigned char char_match);
230     void start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event);
231     void interrupt_handler_asynch(void);
232 #endif
233 
234 protected:
235     SerialBase(PinName tx, PinName rx, int baud);
~SerialBase()236     virtual ~SerialBase() {
237     }
238 
239     int _base_getc();
240     int _base_putc(int c);
241 
242 #if DEVICE_SERIAL_ASYNCH
243     CThunk<SerialBase> _thunk_irq;
244     event_callback_t _tx_callback;
245     event_callback_t _rx_callback;
246     DMAUsage _tx_usage;
247     DMAUsage _rx_usage;
248 #endif
249 
250     serial_t         _serial;
251     Callback<void()> _irq[IrqCnt];
252     int              _baud;
253 
254 };
255 
256 } // namespace mbed
257 
258 #endif
259 
260 #endif
261 
262 /** @}*/
263