Skip to content

Commit a7f4388

Browse files
authored
Merge pull request #8971 from jarvte/add_datacarrier_detect
Cellular: added setting of data carrier support for UART.
2 parents f1691e4 + e4956ce commit a7f4388

File tree

13 files changed

+137
-16
lines changed

13 files changed

+137
-16
lines changed

UNITTESTS/features/cellular/framework/AT/at_cellularcontext/unittest.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,6 @@ set(unittest-test-sources
3737
stubs/randLIB_stub.cpp
3838
stubs/Semaphore_stub.cpp
3939
stubs/us_ticker_stub.cpp
40+
stubs/UARTSerial_stub.cpp
41+
stubs/SerialBase_stub.cpp
4042
)

UNITTESTS/stubs/AT_CellularContext_stub.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ AT_CellularContext::~AT_CellularContext()
4242
{
4343
}
4444

45+
void AT_CellularContext::set_file_handle(UARTSerial *serial, PinName dcd_pin, bool active_high)
46+
{
47+
}
48+
49+
void AT_CellularContext::enable_hup(bool enable)
50+
{
51+
}
52+
4553
void AT_CellularContext::set_file_handle(FileHandle *fh)
4654
{
4755
}

UNITTESTS/stubs/AT_CellularDevice_stub.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,12 @@ void AT_CellularDevice::release_at_handler(ATHandler *at_handler)
5757
{
5858
}
5959

60-
CellularContext *create_context(FileHandle *fh = NULL, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN)
60+
CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
61+
bool active_high)
62+
{
63+
}
64+
65+
CellularContext *create_context(FileHandle *fh, const char *apn)
6166
{
6267
}
6368

UNITTESTS/target_h/myCellularDevice.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ class myCellularDevice : public CellularDevice {
5252
return NSAPI_ERROR_OK;
5353
}
5454

55+
virtual CellularContext *create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
56+
bool active_high)
57+
{
58+
return NULL;
59+
}
60+
5561
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL)
5662
{
5763
EventQueue que;

features/cellular/framework/API/CellularContext.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ class CellularContext : public CellularBase {
101101
// friend of CellularDevice so that it's the only way to close/delete this class.
102102
friend class CellularDevice;
103103
virtual ~CellularContext() {}
104-
105104
public: // from NetworkInterface
106105
virtual nsapi_error_t set_blocking(bool blocking) = 0;
107106
virtual NetworkStack *get_stack() = 0;
@@ -211,6 +210,15 @@ class CellularContext : public CellularBase {
211210
*/
212211
virtual void set_file_handle(FileHandle *fh) = 0;
213212

213+
/** Set the UART serial used to communicate with the modem. Can be used to change default file handle.
214+
* File handle set with this method will use data carrier detect to be able to detect disconnection much faster in PPP mode.
215+
*
216+
* @param serial UARTSerial used in communication to modem. If null then the default file handle is used.
217+
* @param dcd_pin Pin used to set data carrier detect on/off for the given UART
218+
* @param active_high a boolean set to true if DCD polarity is active low
219+
*/
220+
virtual void set_file_handle(UARTSerial *serial, PinName dcd_pin = NC, bool active_high = false) = 0;
221+
214222
protected: // Device specific implementations might need these so protected
215223
enum ContextOperation {
216224
OP_INVALID = -1,
@@ -230,6 +238,15 @@ class CellularContext : public CellularBase {
230238
*/
231239
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr) = 0;
232240

241+
/** Enable or disable hang-up detection
242+
*
243+
* When in PPP data pump mode, it is helpful if the FileHandle will signal hang-up via
244+
* POLLHUP, e.g., if the DCD line is deasserted on a UART. During command mode, this
245+
* signaling is not desired. enable_hup() controls whether this function should be
246+
* active.
247+
*/
248+
virtual void enable_hup(bool enable) = 0;
249+
233250
// member variables needed in target override methods
234251
NetworkStack *_stack; // must be pointer because of PPP
235252
nsapi_ip_stack_t _ip_stack_type;
@@ -244,6 +261,8 @@ class CellularContext : public CellularBase {
244261
const char *_apn;
245262
const char *_uname;
246263
const char *_pwd;
264+
PinName _dcd_pin;
265+
bool _active_high;
247266
};
248267

249268
} // namespace mbed

features/cellular/framework/API/CellularDevice.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "CellularTargets.h"
2222
#include "CellularStateMachine.h"
2323
#include "Callback.h"
24+
#include "UARTSerial.h"
2425

2526
namespace mbed {
2627

@@ -29,7 +30,6 @@ class CellularSMS;
2930
class CellularInformation;
3031
class CellularNetwork;
3132
class CellularContext;
32-
class FileHandle;
3333

3434
const int MAX_PIN_SIZE = 8;
3535
const int MAX_PLMN_SIZE = 16;
@@ -96,6 +96,21 @@ class CellularDevice {
9696
*/
9797
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL) = 0;
9898

99+
/** Creates a new CellularContext interface. This API should be used if serial is UART and PPP mode used.
100+
* CellularContext created will use data carrier detect to be able to detect disconnection much faster in PPP mode.
101+
* UARTSerial usually is the same which was given for the CellularDevice.
102+
*
103+
* @param serial UARTSerial used in communication to modem. If null then the default file handle is used.
104+
* @param apn access point to use with context, can be null.
105+
* @param dcd_pin Pin used to set data carrier detect on/off for the given UART
106+
* @param active_high a boolean set to true if DCD polarity is active low
107+
*
108+
* @return new instance of class CellularContext or NULL in case of failure
109+
*
110+
*/
111+
virtual CellularContext *create_context(UARTSerial *serial, const char *apn, PinName dcd_pin = NC,
112+
bool active_high = false) = 0;
113+
99114
/** Deletes the given CellularContext instance
100115
*
101116
* @param context CellularContext to delete
@@ -107,6 +122,12 @@ class CellularDevice {
107122
*/
108123
void stop();
109124

125+
/** Get the current FileHandle item used when communicating with the modem.
126+
*
127+
* @return reference to FileHandle
128+
*/
129+
FileHandle &get_file_handle() const;
130+
110131
/** Get event queue that can be chained to main event queue.
111132
* @return event queue
112133
*/

features/cellular/framework/AT/ATHandler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ void ATHandler::set_file_handle(FileHandle *fh)
154154
void ATHandler::set_is_filehandle_usable(bool usable)
155155
{
156156
_is_fh_usable = usable;
157+
if (usable) {
158+
// set file handle sigio and blocking mode back
159+
set_file_handle(_fileHandle);
160+
}
157161
}
158162

159163
void ATHandler::set_urc_handler(const char *prefix, Callback<void()> callback)

features/cellular/framework/AT/AT_CellularContext.cpp

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
5959
_cid = -1;
6060
_new_context_set = false;
6161
_next = NULL;
62+
_dcd_pin = NC;
63+
_active_high = false;
6264
}
6365

6466
AT_CellularContext::~AT_CellularContext()
6567
{
66-
tr_info("Delete CellularContext %s (%p)", _apn ? _apn : "", this);
68+
tr_info("Delete CellularContext with apn: [%s] (%p)", _apn ? _apn : "", this);
6769

6870
(void)disconnect();
6971

@@ -79,6 +81,23 @@ void AT_CellularContext::set_file_handle(FileHandle *fh)
7981
_at.set_file_handle(_fh);
8082
}
8183

84+
void AT_CellularContext::set_file_handle(UARTSerial *serial, PinName dcd_pin, bool active_high)
85+
{
86+
tr_info("CellularContext serial %p", serial);
87+
_dcd_pin = dcd_pin;
88+
_active_high = active_high;
89+
_fh = serial;
90+
_at.set_file_handle(static_cast<FileHandle *>(serial));
91+
enable_hup(false);
92+
}
93+
94+
void AT_CellularContext::enable_hup(bool enable)
95+
{
96+
if (_dcd_pin != NC) {
97+
static_cast<UARTSerial *>(_fh)->set_data_carrier_detect(enable ? _dcd_pin : NC, _active_high);
98+
}
99+
}
100+
82101
nsapi_error_t AT_CellularContext::connect()
83102
{
84103
tr_info("CellularContext connect");
@@ -595,18 +614,25 @@ nsapi_error_t AT_CellularContext::open_data_channel()
595614
}
596615

597616
_at.set_is_filehandle_usable(false);
598-
617+
enable_hup(true);
599618
/* Initialize PPP
600619
* If blocking: mbed_ppp_init() is a blocking call, it will block until
601620
connected, or timeout after 30 seconds*/
602-
return nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, _ip_stack_type);
621+
nsapi_error_t err = nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, _ip_stack_type);
622+
if (err) {
623+
ppp_disconnected();
624+
}
625+
626+
return err;
603627
}
604628

605629
void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
606630
{
607631
tr_debug("ppp_status_cb: event %d, ptr %d", ev, ptr);
608632
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_GLOBAL_UP) {
609633
_is_connected = true;
634+
} else if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
635+
ppp_disconnected();
610636
} else {
611637
_is_connected = false;
612638
}
@@ -617,6 +643,20 @@ void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
617643
_device->cellular_callback(ev, ptr);
618644
}
619645

646+
void AT_CellularContext::ppp_disconnected()
647+
{
648+
enable_hup(false);
649+
650+
// after ppp disconnect if we wan't to use same at handler we need to set filehandle again to athandler so it
651+
// will set the correct sigio and nonblocking
652+
_at.lock();
653+
_at.set_is_filehandle_usable(true);
654+
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
655+
tr_error("AT sync failed after PPP Disconnect");
656+
}
657+
_at.unlock();
658+
}
659+
620660
#endif //#if NSAPI_PPP_AVAILABLE
621661

622662
nsapi_error_t AT_CellularContext::disconnect()
@@ -631,15 +671,7 @@ nsapi_error_t AT_CellularContext::disconnect()
631671
tr_error("CellularContext disconnect failed!");
632672
// continue even in failure due to ppp disconnect in any case releases filehandle
633673
}
634-
// after ppp disconnect if we wan't to use same at handler we need to set filehandle again to athandler so it
635-
// will set the correct sigio and nonblocking
636-
_at.lock();
637-
_at.set_file_handle(_at.get_file_handle());
638-
_at.set_is_filehandle_usable(true);
639-
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
640-
tr_error("AT sync failed after PPP Disconnect");
641-
}
642-
_at.unlock();
674+
ppp_disconnected();
643675
#endif // NSAPI_PPP_AVAILABLE
644676
_at.lock();
645677

features/cellular/framework/AT/AT_CellularContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class AT_CellularContext : public CellularContext, public AT_CellularBase {
5757
virtual nsapi_error_t register_to_network();
5858
virtual nsapi_error_t attach_to_network();
5959
virtual void set_file_handle(FileHandle *fh);
60+
virtual void set_file_handle(UARTSerial *serial, PinName dcd_pin = NC, bool active_high = false);
61+
virtual void enable_hup(bool enable);
6062

6163
protected:
6264
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr);
@@ -93,6 +95,7 @@ class AT_CellularContext : public CellularContext, public AT_CellularBase {
9395
#if NSAPI_PPP_AVAILABLE
9496
nsapi_error_t open_data_channel();
9597
void ppp_status_cb(nsapi_event_t ev, intptr_t ptr);
98+
void ppp_disconnected();
9699
#endif // #if NSAPI_PPP_AVAILABLE
97100
nsapi_error_t do_activate_context();
98101
bool set_new_context(int cid);

features/cellular/framework/AT/AT_CellularDevice.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,17 @@ CellularContext *AT_CellularDevice::get_context_list() const
199199
return _context_list;
200200
}
201201

202+
CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
203+
bool active_high)
204+
{
205+
// Call FileHandle base version - explict upcast to avoid recursing into ourselves
206+
CellularContext *ctx = create_context(static_cast<FileHandle *>(serial), apn);
207+
if (serial) {
208+
ctx->set_file_handle(serial, dcd_pin, active_high);
209+
}
210+
return ctx;
211+
}
212+
202213
CellularContext *AT_CellularDevice::create_context(FileHandle *fh, const char *apn)
203214
{
204215
AT_CellularContext *ctx = create_context_impl(*get_at_handler(fh), apn);

features/cellular/framework/AT/AT_CellularDevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class AT_CellularDevice : public CellularDevice {
4646

4747
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL);
4848

49+
virtual CellularContext *create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin = NC, bool active_high = false);
50+
4951
virtual void delete_context(CellularContext *context);
5052

5153
virtual CellularNetwork *open_network(FileHandle *fh = NULL);

features/cellular/framework/device/CellularContext.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ MBED_WEAK CellularContext *CellularContext::get_default_instance()
2626
return NULL;
2727
}
2828
static CellularContext *context = dev->create_context();
29+
#if defined(MDMDCD) && defined(MDM_PIN_POLARITY)
30+
context->set_file_handle(static_cast<UARTSerial *>(&dev->get_file_handle()), MDMDCD, MDM_PIN_POLARITY);
31+
#endif // #if defined(MDMDCD) && defined(MDM_PIN_POLARITY)
2932
return context;
3033
}
3134
#else

features/cellular/framework/device/CellularDevice.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "CellularLog.h"
2222
#include "CellularTargets.h"
2323
#include "EventQueue.h"
24-
#include "UARTSerial.h"
2524

2625
#ifdef CELLULAR_DEVICE
2726
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
@@ -52,6 +51,7 @@ MBED_WEAK CellularDevice *CellularDevice::get_default_instance()
5251
CellularDevice::CellularDevice(FileHandle *fh) : _network_ref_count(0), _sms_ref_count(0), _power_ref_count(0),
5352
_info_ref_count(0), _fh(fh), _queue(5 * EVENTS_EVENT_SIZE), _state_machine(0), _nw(0), _status_cb(0)
5453
{
54+
MBED_ASSERT(fh);
5555
set_sim_pin(NULL);
5656
set_plmn(NULL);
5757
}
@@ -66,6 +66,11 @@ void CellularDevice::stop()
6666
_state_machine->stop();
6767
}
6868

69+
FileHandle &CellularDevice::get_file_handle() const
70+
{
71+
return *_fh;
72+
}
73+
6974
events::EventQueue *CellularDevice::get_queue()
7075
{
7176
return &_queue;

0 commit comments

Comments
 (0)