Skip to content

Commit e4faeb4

Browse files
committed
Merge pull request #195 from mazgch/master
Update of cellular modem
2 parents f47daa9 + db13fa3 commit e4faeb4

File tree

6 files changed

+154
-59
lines changed

6 files changed

+154
-59
lines changed

libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/serial_api.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ serial_t stdio_uart;
7676
struct serial_global_data_s {
7777
uint32_t serial_irq_id;
7878
gpio_t sw_rts, sw_cts;
79-
uint8_t rx_irq_set_flow, rx_irq_set_api;
79+
uint8_t count, rx_irq_set_flow, rx_irq_set_api;
8080
};
8181

8282
static struct serial_global_data_s uart_data[UART_NUM];
@@ -357,17 +357,24 @@ int serial_getc(serial_t *obj) {
357357
void serial_putc(serial_t *obj, int c) {
358358
while (!serial_writable(obj));
359359
obj->uart->THR = c;
360+
uart_data[obj->index].count++;
360361
}
361362

362363
int serial_readable(serial_t *obj) {
363364
return obj->uart->LSR & 0x01;
364365
}
365366

366367
int serial_writable(serial_t *obj) {
368+
int isWritable = 1;
367369
if (NC != uart_data[obj->index].sw_cts.pin)
368-
return (gpio_read(&uart_data[obj->index].sw_cts) == 0) && (obj->uart->LSR & 0x40); //If flow control: writable if CTS low + UART done
369-
else
370-
return obj->uart->LSR & 0x20; //No flow control: writable if space in holding register
370+
isWritable = (gpio_read(&uart_data[obj->index].sw_cts) == 0) && (obj->uart->LSR & 0x40);
371+
else {
372+
if (obj->uart->LSR & 0x20)
373+
uart_data[obj->index].count = 0;
374+
else if (uart_data[obj->index].count >= 16)
375+
isWritable = 0;
376+
}
377+
return isWritable;
371378
}
372379

373380
void serial_clear(serial_t *obj) {

libraries/net/cellular/CellularModem/at/ATCommandsInterface.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ using std::memmove;
3232
#include "ATCommandsInterface.h"
3333

3434
ATCommandsInterface::ATCommandsInterface(IOStream* pStream) :
35-
m_pStream(pStream), m_open(false), m_env2AT(), m_AT2Env(), m_processingMtx(),
35+
m_pStream(pStream), m_open(false), m_transactionState(IDLE), m_env2AT(), m_AT2Env(), m_processingMtx(),
3636
m_processingThread(&ATCommandsInterface::staticCallback, this, (osPriority)AT_THREAD_PRIORITY, 4*192),
3737
m_eventsMgmtMtx(), m_eventsProcessingMtx()
3838
{
@@ -270,6 +270,7 @@ int ATCommandsInterface::executeInternal(const char* command, IATCommandsProcess
270270
} while(msgResult != AT_TIMEOUT);
271271

272272
WARN("Command returned no message");
273+
WARN("Command \"%s\" returned no message", command);
273274
return NET_TIMEOUT;
274275
}
275276
DBG("Command returned with message %d", *msg);
@@ -285,6 +286,7 @@ int ATCommandsInterface::executeInternal(const char* command, IATCommandsProcess
285286
if(ret != OK)
286287
{
287288
WARN("Command returned AT result %d with code %d", m_transactionResult.result, m_transactionResult.code);
289+
WARN("Command \"%s\" returned AT result %d with code %d", command, m_transactionResult.result, m_transactionResult.code);
288290
}
289291

290292
DBG("Command returned successfully");
@@ -751,12 +753,13 @@ void ATCommandsInterface::enableEvents()
751753
{
752754
m_eventsHandlers[i]->onDispatchStart();
753755
//Enable this kind of events
754-
if(m_eventsHandlers[i]->getEventsEnableCommand() != NULL)
756+
const char* cmd = m_eventsHandlers[i]->getEventsEnableCommand();
757+
if(cmd != NULL)
755758
{
756-
int ret = executeInternal(m_eventsHandlers[i]->getEventsEnableCommand(), this, NULL); //Execute enable command
759+
int ret = executeInternal(cmd, this, NULL); //Execute enable command
757760
if(ret)
758761
{
759-
WARN("Events enabling command failed");
762+
WARN("Events enabling command \"%s\" failed", cmd);
760763
}
761764
}
762765
}
@@ -775,12 +778,13 @@ void ATCommandsInterface::disableEvents()
775778
{
776779
m_eventsHandlers[i]->onDispatchStart();
777780
//Disable this kind of events
778-
if(m_eventsHandlers[i]->getEventsDisableCommand() != NULL)
781+
const char* cmd = m_eventsHandlers[i]->getEventsDisableCommand();
782+
if(cmd != NULL)
779783
{
780-
int ret = executeInternal(m_eventsHandlers[i]->getEventsDisableCommand(), this, NULL); //Execute disable command
784+
int ret = executeInternal(cmd, this, NULL); //Execute disable command
781785
if(ret)
782786
{
783-
WARN("Events disabling command failed");
787+
WARN("Events disabling command \"%s\" failed", cmd);
784788
}
785789
}
786790
}

libraries/net/cellular/CellularModem/link/LinkMonitor.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ int LinkMonitor::init(bool gsm)
5858
/*virtual*/ int LinkMonitor::onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
5959
{
6060
DBG("Line is %s", line);
61+
char n[32] = "";
62+
char s[32] = "";
6163
int v;
6264
if( sscanf(line, "+CREG: %*d,%d", &v) >= 1 ) //Reg state is valid
6365
{
@@ -127,6 +129,13 @@ int LinkMonitor::init(bool gsm)
127129
m_rssi = -113 + 2*v;
128130
}
129131
}
132+
else if ( (sscanf(line, "+CNUM: \"%[^\"]\",\"%[^\"]\",%d", n, s, &v) == 3) ||
133+
(sscanf(line, "+CNUM: \"\",\"%[^\"]\",%d", s, &v) == 2) )
134+
{
135+
if (*s && ((v == 145/*number includes + */) || (v == 129/*otherwise*/))) {
136+
strcpy(m_phoneNumber, s);
137+
}
138+
}
130139
return OK;
131140
}
132141

@@ -150,3 +159,17 @@ int LinkMonitor::getState(int* pRssi, REGISTRATION_STATE* pRegistrationState, BE
150159
*pBearer = m_bearer;
151160
return OK;
152161
}
162+
163+
int LinkMonitor::getPhoneNumber(char* phoneNumber)
164+
{
165+
*m_phoneNumber = '\0';
166+
if (m_gsm) {
167+
int ret = m_pIf->execute("AT+CNUM", this, NULL, DEFAULT_TIMEOUT);
168+
if(ret != OK)
169+
{
170+
return NET_PROTOCOL;
171+
}
172+
}
173+
strcpy(phoneNumber, m_phoneNumber);
174+
return OK;
175+
}

libraries/net/cellular/CellularModem/link/LinkMonitor.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ class LinkMonitor : protected IATCommandsProcessor
7373
*/
7474
int getState(int* pRssi, REGISTRATION_STATE* pRegistrationState, BEARER* pBearer);
7575

76+
/** Get my phone number
77+
@param phoneNumber pointer to store the current phoneNumber
78+
@return 0 on success, error code on failure
79+
*/
80+
int getPhoneNumber(char* phoneNumber);
7681
protected:
7782
//IATCommandsProcessor
7883
virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line);
@@ -85,7 +90,7 @@ class LinkMonitor : protected IATCommandsProcessor
8590
bool m_gsm;
8691
REGISTRATION_STATE m_registrationState;
8792
BEARER m_bearer;
88-
93+
char m_phoneNumber[16];
8994
};
9095

9196
#endif /* LINKMONITOR_H_ */

libraries/net/cellular/UbloxUSBModem/UbloxModem.cpp

Lines changed: 87 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -41,39 +41,37 @@ UbloxModem::UbloxModem(IOStream* atStream, IOStream* pppStream) :
4141
m_linkMonitorInit(false), // LinkMonitor subsystem starts un-initialised
4242
m_atOpen(false), // ATCommandsInterface starts in a closed state
4343
m_onePort(pppStream == NULL),
44-
m_gsm(true)
44+
m_type(UNKNOWN)
4545
{
4646
}
4747

4848

49-
class AtiProcessor : public IATCommandsProcessor
50-
{
51-
public:
52-
AtiProcessor()
53-
{
49+
genericAtProcessor::genericAtProcessor()
50+
{
5451
i = 0;
5552
str[0] = '\0';
56-
}
57-
const char* getInfo(void) { return str; }
58-
private:
59-
virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
60-
{
53+
}
54+
55+
const char* genericAtProcessor::getResponse(void)
56+
{
57+
return str;
58+
}
59+
60+
int genericAtProcessor::onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
61+
{
6162
int l = strlen(line);
6263
if (i + l + 2 > sizeof(str))
6364
return NET_OVERFLOW;
6465
if (i) str[i++] = ',';
6566
strcat(&str[i], line);
6667
i += l;
6768
return OK;
68-
}
69-
virtual int onNewEntryPrompt(ATCommandsInterface* pInst)
70-
{
69+
}
70+
71+
int genericAtProcessor::onNewEntryPrompt(ATCommandsInterface* pInst)
72+
{
7173
return OK;
72-
}
73-
protected:
74-
char str[256];
75-
int i;
76-
};
74+
}
7775

7876
class CREGProcessor : public IATCommandsProcessor
7977
{
@@ -130,7 +128,7 @@ int UbloxModem::connect(const char* apn, const char* user, const char* password)
130128
m_ipInit = true;
131129
m_ppp.init();
132130
}
133-
m_ppp.setup(user, password, m_gsm ? DEFAULT_MSISDN_GSM : DEFAULT_MSISDN_CDMA);
131+
m_ppp.setup(user, password, (m_type != LISA_C200) ? DEFAULT_MSISDN_GSM : DEFAULT_MSISDN_CDMA);
134132

135133
int ret = init();
136134
if(ret)
@@ -231,8 +229,8 @@ int UbloxModem::sendSM(const char* number, const char* message)
231229
}
232230

233231
ISMSInterface* sms;
234-
if (m_gsm) sms = &m_GsmSms;
235-
else sms = &m_CdmaSms;
232+
if (m_type == LISA_C200) sms = &m_CdmaSms;
233+
else sms = &m_GsmSms;
236234
if(!m_smsInit)
237235
{
238236
ret = sms->init();
@@ -261,8 +259,8 @@ int UbloxModem::getSM(char* number, char* message, size_t maxLength)
261259
}
262260

263261
ISMSInterface* sms;
264-
if (m_gsm) sms = &m_GsmSms;
265-
else sms = &m_CdmaSms;
262+
if (m_type == LISA_C200) sms = &m_CdmaSms;
263+
else sms = &m_GsmSms;
266264
if(!m_smsInit)
267265
{
268266
ret = sms->init();
@@ -291,8 +289,8 @@ int UbloxModem::getSMCount(size_t* pCount)
291289
}
292290

293291
ISMSInterface* sms;
294-
if (m_gsm) sms = &m_GsmSms;
295-
else sms = &m_CdmaSms;
292+
if (m_type == LISA_C200) sms = &m_CdmaSms;
293+
else sms = &m_GsmSms;
296294
if(!m_smsInit)
297295
{
298296
ret = sms->init();
@@ -337,25 +335,40 @@ int UbloxModem::init()
337335
{
338336
return ret;
339337
}
340-
338+
339+
341340
ATCommandsInterface::ATResult result;
342-
AtiProcessor atiProcessor;
343-
do
344-
{
345-
ret = m_at.execute("ATI", &atiProcessor, &result);
341+
genericAtProcessor atiProcessor;
342+
ret = m_at.execute("ATI", &atiProcessor, &result);
343+
if (OK != ret)
344+
return ret;
345+
const char* info = atiProcessor.getResponse();
346+
INFO("Modem Identification [%s]", info);
347+
if (strstr(info, "LISA-C200")) {
348+
m_type = LISA_C200;
349+
m_onePort = true; // force use of only one port
346350
}
347-
while (ret != OK);
348-
{
349-
const char* info = atiProcessor.getInfo();
350-
DBG("Modem Identification [%s]", info);
351-
if (strstr(info, "LISA-C200"))
352-
{
353-
m_gsm = false; // it is CDMA modem
354-
m_onePort = true; // force use of only one port
355-
}
351+
else if (strstr(info, "LISA-U200")) {
352+
m_type = LISA_U200;
356353
}
354+
else if (strstr(info, "SARA-G350")) {
355+
m_type = SARA_G350;
356+
}
357+
358+
// enable the network indicator
359+
if (m_type == SARA_G350) {
360+
m_at.executeSimple("AT+UGPIOC=16,2", &result);
361+
}
362+
else if (m_type == LISA_U200) {
363+
m_at.executeSimple("AT+UGPIOC=20,2", &result);
364+
}
365+
else if (m_type == LISA_C200) {
366+
// LISA-C200 02S/22S : GPIO1 do not support network status indication
367+
// m_at.executeSimple("AT+UGPIOC=20,2", &result);
368+
}
369+
INFO("Modem Identification [%s]", info);
357370

358-
CREGProcessor cregProcessor(m_gsm);
371+
CREGProcessor cregProcessor(m_type != LISA_C200);
359372
//Wait for network registration
360373
do
361374
{
@@ -438,8 +451,7 @@ int UbloxModem::getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegis
438451

439452
if(!m_linkMonitorInit)
440453
{
441-
ret = m_linkMonitor.init();
442-
ret = m_linkMonitor.init(m_gsm);
454+
ret = m_linkMonitor.init(m_type != LISA_C200);
443455
if(ret)
444456
{
445457
return ret;
@@ -456,6 +468,33 @@ int UbloxModem::getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegis
456468
return OK;
457469
}
458470

471+
int UbloxModem::getPhoneNumber(char* phoneNumber)
472+
{
473+
int ret = init();
474+
if(ret)
475+
{
476+
return ret;
477+
}
478+
479+
if(!m_linkMonitorInit)
480+
{
481+
ret = m_linkMonitor.init(m_type != LISA_C200);
482+
if(ret)
483+
{
484+
return ret;
485+
}
486+
m_linkMonitorInit = true;
487+
}
488+
489+
ret = m_linkMonitor.getPhoneNumber(phoneNumber);
490+
if(ret)
491+
{
492+
return ret;
493+
}
494+
495+
return OK;
496+
}
497+
459498
#include "USBHost.h"
460499
#include "UbloxGSMModemInitializer.h"
461500
#include "UbloxCDMAModemInitializer.h"
@@ -485,11 +524,12 @@ int UbloxUSBModem::init()
485524
if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAU200)
486525
{
487526
INFO("Using a u-blox LISA-U200 3G/WCDMA Modem");
527+
m_type = LISA_U200;
488528
}
489529
else if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_UBLOX_LISAC200)
490530
{
491531
INFO("Using a u-blox LISA-C200 CDMA Modem");
492-
m_gsm = false;
532+
m_type = LISA_C200;
493533
m_onePort = true;
494534
}
495535
else
@@ -510,9 +550,10 @@ int UbloxUSBModem::cleanup()
510550

511551
UbloxSerModem::UbloxSerModem() :
512552
UbloxModem(&m_atStream, NULL),
513-
m_Serial(P0_15,P0_16),
553+
m_Serial(P0_15/*MDMTXD*/,P0_16/*MDMRXD*/),
514554
m_atStream(m_Serial)
515555
{
516-
m_Serial.baud(115200);
556+
m_Serial.baud(115200/*MDMBAUD*/);
557+
m_Serial.set_flow_control(SerialBase::RTSCTS, P0_22/*MDMRTS*/, P0_17/*MDMCTS*/);
517558
}
518559

0 commit comments

Comments
 (0)