Skip to content

Commit 8a870a6

Browse files
authored
Merge pull request #4119 from hasnainvirk/cellular_feature_br
Cellular feature br
2 parents 944a17f + 24de27c commit 8a870a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+4677
-388
lines changed

drivers/RawSerial.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
*/
1616
#include "drivers/RawSerial.h"
1717
#include "platform/mbed_wait_api.h"
18+
#include <stdio.h>
1819
#include <cstdarg>
1920

21+
2022
#if DEVICE_SERIAL
2123

2224
#define STRING_STACK_LIMIT 120

drivers/Serial.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,23 @@ class Serial : public SerialBase, public Stream {
8181
*/
8282
Serial(PinName tx, PinName rx, int baud);
8383

84+
/* Stream gives us a FileHandle with non-functional poll()/readable()/writable. Pass through
85+
* the calls from the SerialBase instead for backwards compatibility. This problem is
86+
* part of why Stream and Serial should be deprecated.
87+
*/
88+
bool readable()
89+
{
90+
return SerialBase::readable();
91+
}
92+
bool writable()
93+
{
94+
return SerialBase::writeable();
95+
}
96+
bool writeable()
97+
{
98+
return SerialBase::writeable();
99+
}
100+
84101
protected:
85102
virtual int _getc();
86103
virtual int _putc(int c);

drivers/SerialBase.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
#if defined (DEVICE_SERIAL) || defined(DOXYGEN_ONLY)
2222

23-
#include "Stream.h"
2423
#include "Callback.h"
2524
#include "serial_api.h"
2625
#include "mbed_toolchain.h"

drivers/UARTSerial.cpp

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2017 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+
17+
#if DEVICE_SERIAL
18+
19+
#include <errno.h>
20+
#include "UARTSerial.h"
21+
#include "platform/mbed_poll.h"
22+
#include "platform/mbed_wait_api.h"
23+
24+
namespace mbed {
25+
26+
UARTSerial::UARTSerial(PinName tx, PinName rx, int baud) :
27+
SerialBase(tx, rx, baud),
28+
_blocking(true),
29+
_tx_irq_enabled(false),
30+
_dcd_irq(NULL)
31+
{
32+
/* Attatch IRQ routines to the serial device. */
33+
SerialBase::attach(callback(this, &UARTSerial::rx_irq), RxIrq);
34+
}
35+
36+
UARTSerial::~UARTSerial()
37+
{
38+
delete _dcd_irq;
39+
}
40+
41+
void UARTSerial::dcd_irq()
42+
{
43+
wake();
44+
}
45+
46+
void UARTSerial::set_data_carrier_detect(PinName dcd_pin, bool active_high)
47+
{
48+
delete _dcd_irq;
49+
_dcd_irq = NULL;
50+
51+
if (dcd_pin != NC) {
52+
_dcd_irq = new InterruptIn(dcd_pin);
53+
if (active_high) {
54+
_dcd_irq->fall(callback(this, &UARTSerial::dcd_irq));
55+
} else {
56+
_dcd_irq->rise(callback(this, &UARTSerial::dcd_irq));
57+
}
58+
}
59+
}
60+
61+
int UARTSerial::close()
62+
{
63+
/* Does not let us pass a file descriptor. So how to close ?
64+
* Also, does it make sense to close a device type file descriptor*/
65+
return 0;
66+
}
67+
68+
int UARTSerial::isatty()
69+
{
70+
return 1;
71+
72+
}
73+
74+
off_t UARTSerial::seek(off_t offset, int whence)
75+
{
76+
/*XXX lseek can be done theoratically, but is it sane to mark positions on a dynamically growing/shrinking
77+
* buffer system (from an interrupt context) */
78+
return -ESPIPE;
79+
}
80+
81+
int UARTSerial::sync()
82+
{
83+
lock();
84+
85+
while (!_txbuf.empty()) {
86+
unlock();
87+
// Doing better than wait would require TxIRQ to also do wake() when becoming empty. Worth it?
88+
wait_ms(1);
89+
lock();
90+
}
91+
92+
unlock();
93+
94+
return 0;
95+
}
96+
97+
void UARTSerial::sigio(Callback<void()> func) {
98+
core_util_critical_section_enter();
99+
_sigio_cb = func;
100+
if (_sigio_cb) {
101+
short current_events = poll(0x7FFF);
102+
if (current_events) {
103+
_sigio_cb();
104+
}
105+
}
106+
core_util_critical_section_exit();
107+
}
108+
109+
ssize_t UARTSerial::write(const void* buffer, size_t length)
110+
{
111+
size_t data_written = 0;
112+
const char *buf_ptr = static_cast<const char *>(buffer);
113+
114+
lock();
115+
116+
while (_txbuf.full()) {
117+
if (!_blocking) {
118+
unlock();
119+
return -EAGAIN;
120+
}
121+
unlock();
122+
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
123+
lock();
124+
}
125+
126+
while (data_written < length && !_txbuf.full()) {
127+
_txbuf.push(*buf_ptr++);
128+
data_written++;
129+
}
130+
131+
core_util_critical_section_enter();
132+
if (!_tx_irq_enabled) {
133+
UARTSerial::tx_irq(); // only write to hardware in one place
134+
if (!_txbuf.empty()) {
135+
SerialBase::attach(callback(this, &UARTSerial::tx_irq), TxIrq);
136+
_tx_irq_enabled = true;
137+
}
138+
}
139+
core_util_critical_section_exit();
140+
141+
unlock();
142+
143+
return data_written;
144+
}
145+
146+
ssize_t UARTSerial::read(void* buffer, size_t length)
147+
{
148+
size_t data_read = 0;
149+
150+
char *ptr = static_cast<char *>(buffer);
151+
152+
lock();
153+
154+
while (_rxbuf.empty()) {
155+
if (!_blocking) {
156+
unlock();
157+
return -EAGAIN;
158+
}
159+
unlock();
160+
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
161+
lock();
162+
}
163+
164+
while (data_read < length && !_rxbuf.empty()) {
165+
_rxbuf.pop(*ptr++);
166+
data_read++;
167+
}
168+
169+
unlock();
170+
171+
return data_read;
172+
}
173+
174+
bool UARTSerial::hup() const
175+
{
176+
return _dcd_irq && _dcd_irq->read() != 0;
177+
}
178+
179+
void UARTSerial::wake()
180+
{
181+
if (_sigio_cb) {
182+
_sigio_cb();
183+
}
184+
}
185+
186+
short UARTSerial::poll(short events) const {
187+
188+
short revents = 0;
189+
/* Check the Circular Buffer if space available for writing out */
190+
191+
192+
if (!_rxbuf.empty()) {
193+
revents |= POLLIN;
194+
}
195+
196+
/* POLLHUP and POLLOUT are mutually exclusive */
197+
if (hup()) {
198+
revents |= POLLHUP;
199+
} else if (!_txbuf.full()) {
200+
revents |= POLLOUT;
201+
}
202+
203+
/*TODO Handle other event types */
204+
205+
return revents;
206+
}
207+
208+
void UARTSerial::lock(void)
209+
{
210+
_mutex.lock();
211+
}
212+
213+
void UARTSerial::unlock(void)
214+
{
215+
_mutex.unlock();
216+
}
217+
218+
void UARTSerial::rx_irq(void)
219+
{
220+
bool was_empty = _rxbuf.empty();
221+
222+
/* Fill in the receive buffer if the peripheral is readable
223+
* and receive buffer is not full. */
224+
while (SerialBase::readable()) {
225+
char data = SerialBase::_base_getc();
226+
if (!_rxbuf.full()) {
227+
_rxbuf.push(data);
228+
} else {
229+
/* Drop - can we report in some way? */
230+
}
231+
}
232+
233+
/* Report the File handler that data is ready to be read from the buffer. */
234+
if (was_empty && !_rxbuf.empty()) {
235+
wake();
236+
}
237+
}
238+
239+
// Also called from write to start transfer
240+
void UARTSerial::tx_irq(void)
241+
{
242+
bool was_full = _txbuf.full();
243+
244+
/* Write to the peripheral if there is something to write
245+
* and if the peripheral is available to write. */
246+
while (!_txbuf.empty() && SerialBase::writeable()) {
247+
char data;
248+
_txbuf.pop(data);
249+
SerialBase::_base_putc(data);
250+
}
251+
252+
if (_tx_irq_enabled && _txbuf.empty()) {
253+
SerialBase::attach(NULL, TxIrq);
254+
_tx_irq_enabled = false;
255+
}
256+
257+
/* Report the File handler that data can be written to peripheral. */
258+
if (was_full && !_txbuf.full() && !hup()) {
259+
wake();
260+
}
261+
}
262+
263+
} //namespace mbed
264+
265+
#endif //DEVICE_SERIAL

0 commit comments

Comments
 (0)