Skip to content

Fix power pulse & reset issue #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions examples/Tools/SerialSARAPassthrough/SerialSARAPassthrough.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,28 @@
Circuit:
- MKR NB 1500 board
- Antenna
- 1500 mAh or higher lipo battery connected
- SIM card

Make sure the Serial Monitor's line ending is set to "Both NL and CR"
Make sure the Serial Monitor's line ending is set to "Both NL and CR" or "Carriage Return"

create 11 December 2017
created 11 December 2017
Sandeep Mistry
*/

// baud rate used for both Serial ports
unsigned long baud = 115200;

void setup() {
// enable the POW_ON pin
pinMode(SARA_PWR_ON, OUTPUT);
digitalWrite(SARA_PWR_ON, HIGH);

// reset the ublox module
// NEVER EVER use RESET_N
pinMode(SARA_RESETN, OUTPUT);
digitalWrite(SARA_RESETN, HIGH);
delay(100);
digitalWrite(SARA_RESETN, LOW);

// Send Poweron pulse
pinMode(SARA_PWR_ON, OUTPUT);
digitalWrite(SARA_PWR_ON, HIGH);
delay(150);
digitalWrite(SARA_PWR_ON, LOW);

Serial.begin(baud);
SerialSARA.begin(baud);
}
Expand Down
68 changes: 54 additions & 14 deletions src/Modem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
ModemUrcHandler* ModemClass::_urcHandlers[MAX_URC_HANDLERS] = { NULL };
Print* ModemClass::_debugPrint = NULL;

ModemClass::ModemClass(Uart& uart, unsigned long baud, int resetPin, int powerOnPin) :
ModemClass::ModemClass(Uart& uart, unsigned long baud, int resetPin, int powerOnPin, int vIntPin) :
_uart(&uart),
_baud(baud),
_resetPin(resetPin),
_powerOnPin(powerOnPin),
_vIntPin(vIntPin),
_lastResponseOrUrcMillis(0),
_atCommandState(AT_COMMAND_IDLE),
_ready(1),
Expand All @@ -37,19 +38,42 @@ ModemClass::ModemClass(Uart& uart, unsigned long baud, int resetPin, int powerOn
_buffer.reserve(64);
}

void ModemClass::setVIntPin(int vIntPin)
{
// Allow setting only if unset, used to track state
if (_vIntPin==SARA_VINT_OFF || _vIntPin==SARA_VINT_ON) {
_vIntPin=vIntPin;
}
}

int ModemClass::isPowerOn()
{
if (_vIntPin==SARA_VINT_OFF) {
return 0;
} else if (_vIntPin==SARA_VINT_ON) {
return 1;
}
return digitalRead(_vIntPin);
}

int ModemClass::begin(bool restart)
{
// datasheet warns not to use _resetPin, this may lead to an unrecoverable state
digitalWrite(_resetPin, LOW);

if (restart) {
shutdown();
end();
}

_uart->begin(_baud > 115200 ? 115200 : _baud);

// power on module
pinMode(_powerOnPin, OUTPUT);
digitalWrite(_powerOnPin, HIGH);

if (_resetPin > -1 && restart) {
pinMode(_resetPin, OUTPUT);
digitalWrite(_resetPin, HIGH);
delay(100);
digitalWrite(_resetPin, LOW);
if (!isPowerOn()) {
digitalWrite(_powerOnPin, HIGH);
delay(150); // Datasheet says power-on pulse should be >=150ms, <=3200ms
digitalWrite(_powerOnPin, LOW);
setVIntPin(SARA_VINT_ON);
} else {
if (!autosense()) {
return 0;
Expand Down Expand Up @@ -78,13 +102,29 @@ int ModemClass::begin(bool restart)
return 1;
}

int ModemClass::shutdown()
{
// AT command shutdown
if (isPowerOn()) {
send("AT+CPWROFF");
if (waitForResponse(40000) != 1) {
return 0;
}
setVIntPin(SARA_VINT_OFF);
}
return 1;
}

void ModemClass::end()
{
_uart->end();
digitalWrite(_resetPin, HIGH);

// power off module
digitalWrite(_powerOnPin, LOW);
// Hardware pin power off
if (isPowerOn()) {
digitalWrite(_powerOnPin, HIGH);
delay(1500); // Datasheet says power-off pulse should be >=1500ms
digitalWrite(_powerOnPin, LOW);
setVIntPin(SARA_VINT_OFF);
}
}

void ModemClass::debug()
Expand Down Expand Up @@ -340,4 +380,4 @@ void ModemClass::setBaudRate(unsigned long baud)
_baud = baud;
}

ModemClass MODEM(SerialSARA, 115200, SARA_RESETN, SARA_PWR_ON);
ModemClass MODEM(SerialSARA, 115200, SARA_RESETN, SARA_PWR_ON, SARA_VINT);
18 changes: 17 additions & 1 deletion src/Modem.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,26 @@

#include <Arduino.h>

/* The NB 1500 does not connect the SARA V_INT pin so that it can be monitored.
The below constants and associated code enables connecting SARA_VINT to a digital input
using a level shifter (1.8V to 5V) or simply a MOS transistor, say a 2N7000.
The code does rudimentary tracking of the on/off state if this is not available.
*/
#define SARA_VINT_OFF (-1)
#define SARA_VINT_ON (-2)

#ifndef SARA_VINT
#define SARA_VINT SARA_VINT_OFF
#endif

class ModemUrcHandler {
public:
virtual void handleUrc(const String& urc) = 0;
};

class ModemClass {
public:
ModemClass(Uart& uart, unsigned long baud, int resetPin, int powerOnPin);
ModemClass(Uart& uart, unsigned long baud, int resetPin, int powerOnPin, int vIntPin=SARA_VINT);

int begin(bool restart = false);
void end();
Expand All @@ -45,6 +57,9 @@ class ModemClass {

int noop();
int reset();
int shutdown();
int isPowerOn();
void setVIntPin(int vIntPin);

size_t write(uint8_t c);
size_t write(const uint8_t*, size_t);
Expand All @@ -69,6 +84,7 @@ class ModemClass {
unsigned long _baud;
int _resetPin;
int _powerOnPin;
int _vIntPin;
unsigned long _lastResponseOrUrcMillis;

enum {
Expand Down
12 changes: 6 additions & 6 deletions src/NB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,17 @@ int NB::isAccessAlive()

bool NB::shutdown()
{
if (_state == NB_READY) {
MODEM.send("AT+CPWROFF");
MODEM.waitForResponse(40000);
// Attempt AT command shutdown
if (_state == NB_READY && MODEM.shutdown()) {
_state = NB_OFF;
return true;
}
MODEM.end();
_state = NB_OFF;
return true;
return false;
}

bool NB::secureShutdown()
{
// Hardware power off
MODEM.end();
_state = NB_OFF;
return true;
Expand Down
3 changes: 1 addition & 2 deletions src/NBFileUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ bool NBFileUtils::begin(const bool restart)
{
int status;

if (restart)
MODEM.begin();
MODEM.begin(restart);

if (_debug) {
MODEM.debug();
Expand Down