diff --git a/.gitignore b/.gitignore index 85e9c40c1d..9231e33021 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ # Build directory ###################### build/ +build-*/ # Test failure outputs ###################### @@ -50,3 +51,6 @@ secure-bootloader-key.bin flash_encryption_key.bin .DS_Store +org.eclipse.cdt.ui.prefs +org.eclipse.cdt.core.prefs +language.settings.xml diff --git a/Jenkinsfile b/Jenkinsfile index 8b720154a3..488d276e97 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,15 +1,13 @@ def buildVersion def boards_to_build = ["WiPy", "LoPy", "SiPy", "GPy", "FiPy", "LoPy4"] -def boards_to_test = ["Pycom_Expansion3_Py00ec5f", "Pycom_Expansion3_Py9f8bf5"] +def boards_to_test = ["1b6fa1", "00ec51"] node { // get pycom-esp-idf source stage('Checkout') { checkout scm sh 'rm -rf esp-idf' - sh 'git clone --recursive -b master https://github.com/pycom/pycom-esp-idf.git esp-idf' - sh 'git -C esp-idf checkout 4eab4e1b0e47c73b858c6b29d357f3d30a69c074' - sh 'git -C esp-idf submodule update' + sh 'git clone --depth=1 --recursive -b master https://github.com/pycom/pycom-esp-idf.git esp-idf' } PYCOM_VERSION=get_version() @@ -119,11 +117,12 @@ def testBuild(short_name) { dir('tests') { timeout(30) { // As some tests are randomly failing... enforce script always returns 0 (OK) - sh './run-tests --target=esp32-' + board_name_u + ' --device ' + device_name + ' || exit 0' - } + sh '''export PATH=$PATH:/usr/local/bin; + ./run-tests --target=esp32-''' + board_name_u + ' --device ' + device_name + ' || exit 0' } - sh 'python esp32/tools/pypic.py --port ' + device_name +' --enter' - sh 'python esp32/tools/pypic.py --port ' + device_name +' --exit' + } + sh 'python esp32/tools/pypic.py --port ' + device_name +' --enter' + sh 'python esp32/tools/pypic.py --port ' + device_name +' --exit' } } } @@ -150,6 +149,6 @@ def get_remote_name(short_name) { } def get_device_name(short_name) { - return "/dev/serial/by-id/usb-" + short_name + "-if00" + return "/dev/tty.usbmodemPy" + short_name + " " } diff --git a/README.md b/README.md index 0c016f48c6..d1bcd2fc10 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ Expansion Board 2.0 users, please connect ``P2`` to ``GND`` and then reset the b ### Prerequisites - $ export $IDF_PATH= + $ export IDF_PATH= $ cd esp32 Hold valid keys for Flash Encryption and Secure Boot; they can be generated randomly with the following commands: diff --git a/docs/license.rst b/docs/license.rst index 1d1e4f9504..7ceb8116c5 100644 --- a/docs/license.rst +++ b/docs/license.rst @@ -23,7 +23,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Copyright (c) 2016, Pycom Limited. +Copyright (c) 2018, Pycom Limited. This software is licensed under the GNU GPL version 3 or any later version, with permitted additional terms. For more information diff --git a/drivers/sx127x/sx1272/sx1272.c b/drivers/sx127x/sx1272/sx1272.c index b029cd0bdf..c25d3c42a2 100644 --- a/drivers/sx127x/sx1272/sx1272.c +++ b/drivers/sx127x/sx1272/sx1272.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence @@ -234,7 +234,6 @@ bool SX1272IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh { bool status = true; int16_t rssi = 0; - uint32_t carrierSenseTime = 0; SX1272SetModem( modem ); @@ -242,9 +241,7 @@ bool SX1272IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh SX1272SetOpMode( RF_OPMODE_RECEIVER ); - DelayMs( 2 ); - - carrierSenseTime = TimerGetCurrentTime( ); + DelayMs( 1 ); // Perform carrier sense for maxCarrierSenseTime do { @@ -254,7 +251,9 @@ bool SX1272IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh status = false; break; } - } while( TimerGetElapsedTime( carrierSenseTime ) < maxCarrierSenseTime ); + DelayMs( 1 ); + maxCarrierSenseTime -= 1; + } while( maxCarrierSenseTime > 0 ); SX1272SetSleep( ); return status; } diff --git a/drivers/sx127x/sx1276/sx1276.c b/drivers/sx127x/sx1276/sx1276.c index d4c8c5b50c..6822dec248 100755 --- a/drivers/sx127x/sx1276/sx1276.c +++ b/drivers/sx127x/sx1276/sx1276.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence @@ -255,7 +255,6 @@ bool SX1276IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh { bool status = true; int16_t rssi = 0; - uint32_t carrierSenseTime = 0; SX1276SetModem( modem ); @@ -263,9 +262,7 @@ bool SX1276IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh SX1276SetOpMode( RF_OPMODE_RECEIVER ); - DelayMs( 2 ); - - carrierSenseTime = TimerGetCurrentTime( ); + DelayMs( 1 ); // Perform carrier sense for maxCarrierSenseTime do { @@ -275,7 +272,9 @@ bool SX1276IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh status = false; break; } - } while( TimerGetElapsedTime( carrierSenseTime ) < maxCarrierSenseTime ); + DelayMs( 1 ); + maxCarrierSenseTime -= 1; + } while( maxCarrierSenseTime > 0 ); SX1276SetSleep( ); return status; } diff --git a/esp32/application.mk b/esp32/application.mk index e2f3b07589..b86e6cf50e 100644 --- a/esp32/application.mk +++ b/esp32/application.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/boards/FIPY/mpconfigboard.h b/esp32/boards/FIPY/mpconfigboard.h index 9f427ac5a4..22d8aaa3f5 100644 --- a/esp32/boards/FIPY/mpconfigboard.h +++ b/esp32/boards/FIPY/mpconfigboard.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/boards/GPY/mpconfigboard.h b/esp32/boards/GPY/mpconfigboard.h index 65f87c0530..1b1d8b7f31 100644 --- a/esp32/boards/GPY/mpconfigboard.h +++ b/esp32/boards/GPY/mpconfigboard.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/boards/LOPY/mpconfigboard.h b/esp32/boards/LOPY/mpconfigboard.h index d22217d9a4..6e3d207b45 100644 --- a/esp32/boards/LOPY/mpconfigboard.h +++ b/esp32/boards/LOPY/mpconfigboard.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/boards/LOPY4/mpconfigboard.h b/esp32/boards/LOPY4/mpconfigboard.h index 35e431dc55..fc4c39e947 100644 --- a/esp32/boards/LOPY4/mpconfigboard.h +++ b/esp32/boards/LOPY4/mpconfigboard.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/boards/SIPY/mpconfigboard.h b/esp32/boards/SIPY/mpconfigboard.h index 917a2ee5eb..1d89c4bc6c 100644 --- a/esp32/boards/SIPY/mpconfigboard.h +++ b/esp32/boards/SIPY/mpconfigboard.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/boards/SIPY/pins.csv b/esp32/boards/SIPY/pins.csv index 9790084d1c..cc1d184271 100644 --- a/esp32/boards/SIPY/pins.csv +++ b/esp32/boards/SIPY/pins.csv @@ -11,8 +11,8 @@ G16,GPIO12,P9 G17,GPIO13,P10 G22,GPIO22,P11 G28,GPIO21,P12 -G5,GPI37,P13 -G4,GPI36,P14 +G5,GPI36,P13 +G4,GPI37,P14 G0,GPI38,P15 G3,GPI39,P16 G31,GPI35,P17 diff --git a/esp32/boards/WIPY/mpconfigboard.h b/esp32/boards/WIPY/mpconfigboard.h index 795b102a99..938af89b91 100644 --- a/esp32/boards/WIPY/mpconfigboard.h +++ b/esp32/boards/WIPY/mpconfigboard.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/boards/esp32_prefix.c b/esp32/boards/esp32_prefix.c index 1a02a64cca..8658d04c0f 100644 --- a/esp32/boards/esp32_prefix.c +++ b/esp32/boards/esp32_prefix.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/boards/make-pins.py b/esp32/boards/make-pins.py index 4d541b0c44..9add53f7c1 100644 --- a/esp32/boards/make-pins.py +++ b/esp32/boards/make-pins.py @@ -2,7 +2,7 @@ # This file is derived from the MicroPython project, http://micropython.org/ # -# Copyright (c) 2016, Pycom Limited and its licensors. +# Copyright (c) 2018, Pycom Limited and its licensors. # # This software is licensed under the GNU GPL version 3 or any later version, # with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/bootloader/bootmgr.c b/esp32/bootloader/bootmgr.c index a037edcdb8..1b30f1e4e6 100644 --- a/esp32/bootloader/bootmgr.c +++ b/esp32/bootloader/bootmgr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/bootloader/bootmgr.h b/esp32/bootloader/bootmgr.h index 868cbd8666..a41bedea2d 100644 --- a/esp32/bootloader/bootmgr.h +++ b/esp32/bootloader/bootmgr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/bootloader/mperror.c b/esp32/bootloader/mperror.c index 0134ad4ee0..003f5e649b 100644 --- a/esp32/bootloader/mperror.c +++ b/esp32/bootloader/mperror.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information @@ -60,6 +60,8 @@ void mperror_init0 (void) { gpio_config(&gpioconf); mperror_heart_beat.enabled = true; + //delay introduced to separate last falling edge of signal and next color code + ets_delay_us(300); mperror_heartbeat_switch_off(); } diff --git a/esp32/fatfs/src/drivers/sd_diskio.c b/esp32/fatfs/src/drivers/sd_diskio.c index baeaa567fc..3aa4ef9418 100644 --- a/esp32/fatfs/src/drivers/sd_diskio.c +++ b/esp32/fatfs/src/drivers/sd_diskio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/fatfs/src/drivers/sd_diskio.h b/esp32/fatfs/src/drivers/sd_diskio.h index 69a9fa6b37..cd36bde369 100644 --- a/esp32/fatfs/src/drivers/sd_diskio.h +++ b/esp32/fatfs/src/drivers/sd_diskio.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/frozen/LTE/sqnsbr.py b/esp32/frozen/LTE/sqnsbr.py index 530584de18..ad5ad83aac 100644 --- a/esp32/frozen/LTE/sqnsbr.py +++ b/esp32/frozen/LTE/sqnsbr.py @@ -1,3 +1,10 @@ +# Copyright (c) 2018, Pycom Limited. +# +# This software is licensed under the GNU GPL version 3 or any +# later version, with permitted additional terms. For more information +# see the Pycom Licence v1.0 document supplied with this file, or +# available at https://www.pycom.io/opensource/licensing + class bootrom(object): import binascii diff --git a/esp32/frozen/LTE/sqnstp.py b/esp32/frozen/LTE/sqnstp.py old mode 100644 new mode 100755 index 8301bd1c3c..31280cf056 --- a/esp32/frozen/LTE/sqnstp.py +++ b/esp32/frozen/LTE/sqnstp.py @@ -1,5 +1,22 @@ #!/usr/bin/env python - +################################################################# +# +# Copyright (c) 2011 SEQUANS Communications. +# All rights reserved. +# +# This is confidential and proprietary source code of SEQUANS +# Communications. The use of the present source code and all +# its derived forms is exclusively governed by the restricted +# terms and conditions set forth in the SEQUANS +# Communications' EARLY ADOPTER AGREEMENT and/or LICENCE +# AGREEMENT. The present source code and all its derived +# forms can ONLY and EXCLUSIVELY be used with SEQUANS +# Communications' products. The distribution/sale of the +# present source code and all its derived forms is EXCLUSIVELY +# RESERVED to regular LICENCE holder and otherwise STRICTLY +# PROHIBITED. +# +################################################################# import struct import time import os @@ -59,9 +76,9 @@ def hexdump(src, length=32): lines = [] for c in range(0, len(src), length): chars = src[c:c+length] - hex = ' '.join(['%02x' % x for x in chars]) - printable = ''.join(['%s' % ((x <= 127 and FILTER[x]) or '.') for x in chars]) - lines.append('%04x %-*s %s\n' % (c, length*3, hex, printable)) + hex = ' '.join(["%02x" % ord(x) for x in chars]) + printable = ''.join(["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.') for x in chars]) + lines.append("%04x %-*s %s\n" % (c, length*3, hex, printable)) print(''.join(lines)) diff --git a/esp32/frozen/LTE/sqnsupgrade.py b/esp32/frozen/LTE/sqnsupgrade.py index 678142a228..8040f8d015 100644 --- a/esp32/frozen/LTE/sqnsupgrade.py +++ b/esp32/frozen/LTE/sqnsupgrade.py @@ -1,4 +1,14 @@ #!/usr/bin/env python +VERSION = "1.2.1" + +# Copyright (c) 2018, Pycom Limited. +# +# This software is licensed under the GNU GPL version 3 or any +# later version, with permitted additional terms. For more information +# see the Pycom Licence v1.0 document supplied with this file, or +# available at https://www.pycom.io/opensource/licensing + + import struct import time import os @@ -6,28 +16,26 @@ import sqnscrc as crc import sqnstp as stp +release = None try: sysname = os.uname().sysname + if 'FiPy' in sysname or 'GPy' in sysname: + release = os.uname().release except: sysname = 'Windows' if 'FiPy' in sysname or 'GPy' in sysname: from machine import UART from machine import SD + from network import LTE + + def reconnect_uart(): + if hasattr(LTE, 'reconnect_uart'): + LTE.reconnect_uart() else: # this is a computer import serial - -FFF_FMT = "<4sIIIIIIIHHIHHIHHHH" -FFF_SLIM_FMT = "<4sIIIIIIIHHHH" -FFF_FEATURES_SLIM = 1 << 0 -FFF_MAGIC = "FFF!" - -SFFF_MAGIC = "SFFF" # Firmware -SUFF_MAGIC = "SUFF" # Updater -TEST_MAGIC = "TEST" # Test -DIFF_MAGIC = "DIFF" # Diff Upgrade -UPGR_MAGIC = "UPGR" # Generic raw upgrade -RASR_MAGIC = "RASR" # Generic raw rasterize + def reconnect_uart(): + pass class sqnsupgrade: @@ -39,6 +47,15 @@ def __init__(self): self.__pins = None self.__connected = False self.__sdpath = None + self.__resp_921600 = False + self.__serial = None + self.__kill_ppp_ok = False + + if 'GPy' in self.__sysname: + self.__pins = ('P5', 'P98', 'P7', 'P99') + else: + self.__pins = ('P20', 'P18', 'P19', 'P17') + def special_print(self, msg, flush=None, end='\n'): if 'FiPy' in self.__sysname or 'GPy' in self.__sysname: @@ -72,7 +89,7 @@ def read_rsp(self, size=None, timeout=-1): def print_pretty_response(self, rsp, flush=False): lines = rsp.decode('ascii').split('\r\n') for line in lines: - if 'OK' not in line: + if 'OK' not in line and line!='': self.special_print(line, flush=flush) @@ -84,20 +101,31 @@ def return_pretty_response(self, rsp): ret_str += line return ret_str - def return_code(self, rsp): + def return_upgrade_response(self, rsp): + pretty = self.return_pretty_response(rsp) + if "+SMUPGRADE:" in pretty: + try: + return pretty.split(':')[1].strip() + except: + pass + return None + + def return_code(self, rsp, debug=False): ret_str = b'' lines = rsp.decode('ascii').split('\r\n') for line in lines: - if 'OK' not in line: - ret_str += line - try: - return int(ret_str) - except: - return -1 + if 'OK' not in line and len(line) >0: + try: + if debug: print('Converting response: {} to int...'.format(line)) + return int(line) + except: + pass + raise OSError('Could not decode modem state') - def wait_for_modem(self, send=True, expected=b'OK'): + def wait_for_modem(self, send=True, expected=b'OK', echo_char=None): rsp = b'' + start = time.time() while True: if send: self.__serial.write(b"AT\r\n") @@ -105,20 +133,28 @@ def wait_for_modem(self, send=True, expected=b'OK'): if r: rsp += r if expected in rsp: - print() + if echo_char is not None: + print() break else: - self.special_print('.', end='', flush=True) + if echo_char is not None: + self.special_print(echo_char, end='', flush=True) time.sleep(0.5) + if time.time() - start >= 300: + raise OSError('Timeout waiting for modem to respond!') def __check_file(self, file_path, debug=False): if 'FiPy' in self.__sysname or 'GPy' in self.__sysname: if file_path[0] == '/' and not 'flash' in file_path and not file_path.split('/')[1] in os.listdir('/'): if self.__sdpath is None: self.__sdpath = file_path.split('/')[1] - sd = SD() - time.sleep(0.5) - os.mount(sd, '/{}'.format(self.__sdpath)) + try: + sd = SD() + time.sleep(0.5) + os.mount(sd, '/{}'.format(self.__sdpath)) + except Exception as ex: + print('Unable to mount SD card!') + return False else: print('SD card already mounted on {}!'.format(self.__sdpath)) return False @@ -127,7 +163,7 @@ def __check_file(self, file_path, debug=False): if debug: print('File {} has size {}'.format(file_path, size)) return True except Exception as ex: - print('Exception when checking file... wrong file name?') + print('Exception when checking file {}... wrong file name?'.format(file_path)) print('{}'.format(ex)) return False return False @@ -142,67 +178,164 @@ def check_files(self, ffile, mfile=None, debug=False): else: return self.__check_file(ffile, debug) - def detect_modem_state(self, retry=10, initial_delay=5): - if 'FiPy' or 'GPy' in self.__sysname: - if 'GPy' in self.__sysname: - pins = ('P5', 'P98', 'P7', 'P99') - else: - pins = ('P20', 'P18', 'P19', 'P17') + def __check_resp(self, resp, kill_ppp=False): + if resp is not None: + self.__resp_921600 = b'OK' in resp or b'ERROR' in resp + self.__kill_ppp_ok = self.__kill_ppp_ok or (kill_ppp and b'OK' in resp) + + def __hangup_modem(self, delay, debug): + self.__serial.read() + if not self.__kill_ppp_ok: + self.__serial.write(b"+++") + time.sleep_ms(delay) + resp = self.__serial.read() + if debug: print('Response (+++ #1): {}'.format(resp)) + self.__check_resp(resp, True) + self.__serial.write(b"AT\r\n") + time.sleep_ms(delay) + resp = self.__serial.read() + if debug: print('Response (AT #1) {}'.format(resp)) + self.__check_resp(resp) + if resp is not None: + if b'OK' not in resp and not self.__kill_ppp_ok: + self.__serial.write(b"AT\r\n") + time.sleep_ms(delay) + resp = self.__serial.read() + if debug: print('Response (AT #2) {}'.format(resp)) + self.__check_resp(resp) + if resp is not None and b'OK' in resp: + return True + self.__serial.write(b"+++") + time.sleep_ms(delay) + resp = self.__serial.read() + if debug: print('Response (+++ #2): {}'.format(resp)) + self.__check_resp(resp, True) + if resp is not None and b'OK' in resp: + # self.__serial.write(b"ATH\r\n") + # time.sleep_ms(delay) + # resp = self.__serial.read() + # if debug: print('Response (ATH #1) {}'.format(resp)) + # self.__check_resp(resp) + self.__serial.write(b"AT\r\n") + time.sleep_ms(delay) + resp = self.__serial.read() + if debug: print('Response (AT #2) {}'.format(resp)) + self.__check_resp(resp) + if resp is not None and b'OK' in resp: + return True + return False + + + def detect_modem_state(self, retry=3, initial_delay=1000, debug=False): count = 0 + self.__serial = UART(1, baudrate=921600, pins=self.__pins, timeout_chars=1) + self.__serial.read() while count < retry: count += 1 delay = initial_delay * count - s = UART(1, baudrate=921600, pins=pins, timeout_chars=10) - s.read() - s.write(b"AT\r\n") - time.sleep_ms(delay) - resp = s.read() - s.write(b"AT\r\n") - time.sleep_ms(delay) - resp = s.read() - if resp is not None and b'OK' in resp: - s.write(b"AT+SMOD?\r\n") + if debug: print("The current delay is {}".format(delay)) + self.__serial = UART(1, baudrate=921600, pins=self.__pins, timeout_chars=10) + #if True: + if self.__hangup_modem(initial_delay, debug): + self.__serial.write(b"AT+SMOD?\r\n") time.sleep_ms(delay) - resp = s.read() + resp = self.__serial.read() + if debug: print('Response (AT+SMOD?) {}'.format(resp)) try: - return self.return_code(resp) + return self.return_code(resp, debug) except: - continue + pass else: - s = UART(1, baudrate=115200, pins=pins, timeout_chars=10) - s.write(b"AT\r\n") + self.__serial = UART(1, baudrate=921600, pins=self.__pins, timeout_chars=1) + self.__serial.read() + self.__serial.write(b"AT\r\n") time.sleep_ms(delay) - resp = s.read() - s.write(b"AT\r\n") + resp = self.__serial.read() + self.__check_resp(resp) + if debug: print('Response (AT #3) {}'.format(resp)) + if resp is not None and b'OK' in resp: + self.__serial.write(b"AT+SMOD?\r\n") + time.sleep_ms(delay) + resp = self.__serial.read() + try: + if debug: print('Response (AT+SMOD?) {}'.format(resp)) + return self.return_code(resp, debug) + except: + pass + self.__serial.write(b"AT\r\n") time.sleep_ms(delay) - resp = s.read() + resp = self.__serial.read() + self.__check_resp(resp) + if debug: print('Response (AT #4) {}'.format(resp)) if resp is not None and b'OK' in resp: - s.write(b"AT+SMOD?\r\n") + self.__serial.write(b"AT+SMOD?\r\n") time.sleep_ms(delay) - resp = s.read() + resp = self.__serial.read() try: - return self.return_code(resp) + return self.return_code(resp, debug) + if debug: print('Response (AT+SMOD?) {}'.format(resp)) except: - continue + pass + else: + if not self.__resp_921600: + self.__serial = UART(1, baudrate=115200, pins=self.__pins, timeout_chars=10) + self.__serial.write(b"AT\r\n") + time.sleep_ms(delay) + resp = self.__serial.read() + if debug: print('Response (AT #1 @ 115200) {}'.format(resp)) + if resp is not None and b'OK' in resp: + self.__serial.write(b"AT+SMOD?\r\n") + time.sleep_ms(delay) + resp = self.__serial.read() + try: + if debug: print('Response (AT+SMOD?) {}'.format(resp)) + return self.return_code(resp, debug) + except: + pass + self.__serial.write(b"AT\r\n") + time.sleep_ms(delay) + resp = self.__serial.read() + if debug: print('Response (AT #2 @ 115200) {}'.format(resp)) + if resp is not None and b'OK' in resp: + self.__serial.write(b"AT+SMOD?\r\n") + time.sleep_ms(delay) + resp = self.__serial.read() + try: + if debug: print('Response (AT+SMOD?) {}'.format(resp)) + return self.return_code(resp, debug) + except: + pass + return None + + def __get_power_warning(self): + return "<<<=== DO NOT DISCONNECT POWER ===>>>" + + def __get_wait_msg(self, load_fff=True): + if not self.__wait_msg: + self.__wait_msg = True + if load_fff: + return "Waiting for modem to finish the update...\nThis might take several minutes!\n" + self.__get_power_warning() + else: + return "Waiting for modem to finish the update...\n" + self.__get_power_warning() + return None - def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_ffh=False, mirror=False, switch_ffh=False, bootrom=False, rgbled=0x050505, debug=False, pkgdebug=False, atneg=True, max_try=10, direct=True, atneg_only=False, version_only=False): + + def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_ffh=False, mirror=False, switch_ffh=False, bootrom=False, rgbled=0x050505, debug=False, pkgdebug=False, atneg=True, max_try=10, direct=True, atneg_only=False, version_only=False, expected_smod=None, verbose=False, load_fff=False): + self.__wait_msg = False mirror = True if atneg_only else mirror recover = True if atneg_only else load_ffh resume = True if mirror or recover or atneg_only or version_only else resume - if debug: print('mirror? {} recover? {} resume? {} direct? {} atneg_only? {} bootrom? {} '.format(mirror, recover, resume, direct, atneg_only, bootrom)) + verbose = True if debug else verbose + load_fff = False if bootrom and switch_ffh else load_fff + if debug: print('mirror? {} recover? {} resume? {} direct? {} atneg_only? {} bootrom? {} load_fff? {}'.format(mirror, recover, resume, direct, atneg_only, bootrom, load_fff)) abort = True external = False self.__serial = None if 'FiPy' in self.__sysname or 'GPy' in self.__sysname: - if 'GPy' in self.__sysname: - self.__pins = ('P5', 'P98', 'P7', 'P99') - else: - self.__pins = ('P20', 'P18', 'P19', 'P17') - self.__serial = UART(1, baudrate=115200 if recover else baudrate, pins=self.__pins, timeout_chars=100) self.__serial.read() else: @@ -216,26 +349,45 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f self.__serial.reset_input_buffer() self.__serial.reset_output_buffer() - if debug: print('Initial prepartion complete...') - if version_only: self.__serial.read() - self.__serial.write(b"AT!=\"showver\"\r\n") + self.__serial.write(b'AT\r\n') + self.__serial.write(b'AT\r\n') + self.__serial.read() + if verbose: + self.__serial.write(b"AT!=\"showver\"\r\n") + else: + self.__serial.write(b"ATI1\r\n") time.sleep(.5) shver = self.read_rsp(2000) if shver is not None: self.print_pretty_response(shver) return True + if debug: print('Initial prepartion complete...') + if not mirror: if bootrom: - if debug: print('Loading built-in recovery bootrom') - from sqnsbr import bootrom + if debug: print('Loading built-in recovery bootrom...') + try: + # try compressed bootrom first + from sqnsbrz import bootrom + except: + # fallback to uncompressed + from sqnsbr import bootrom blob = bootrom() blobsize = blob.get_size() else: if debug: print('Loading {}'.format(file_path)) blobsize = os.stat(file_path)[6] + if blobsize < 10240: + print('Firmware file is too small!') + reconnect_uart() + sys.exit(1) + if blobsize > 4194304: + if load_fff: + print("Firmware file is too big to load via FFF method. Using ON_THE_FLY") + load_fff = False blob = open(file_path, "rb") if not load_ffh: @@ -249,19 +401,37 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f response = self.read_rsp(size=6) self.__serial.read(100) - if debug: print('Entering recovery mode') + if debug: print('Entering upgrade mode...') self.__serial.write(b"AT+SMOD?\r\n") response = self.return_pretty_response(self.read_rsp(size=7)) self.__serial.read(100) if debug: print("AT+SMOD? returned {}".format(response)) - if not bootrom: + self.__serial.write(b"AT+SQNSUPGRADENTF=\"started\"\r\n") + self.wait_for_modem() + if not load_fff: self.__serial.write(b"AT+SMSWBOOT=3,1\r\n") - time.sleep(2) + resp = self.read_rsp(100) + if debug: print('AT+SMSWBOOT=3,1 returned: {}'.format(resp)) + if b'ERROR' in resp: + time.sleep(5) + self.__serial.write(b"AT+SMSWBOOT=3,0\r\n") + resp = self.read_rsp(100) + if debug: print('AT+SMSWBOOT=3,0 returned: {}'.format(resp)) + if b'OK' in resp: + self.__serial.write(b"AT^RESET\r\n") + resp = self.read_rsp(100) + if debug: print('AT^RESET returned: {}'.format(resp)) + else: + print('Received ERROR from AT+SMSWBOOT=3,1! Aborting!') + reconnect_uart() + sys.exit(1) + time.sleep(3) + resp = self.__serial.read() + if debug: print("Response after reset: {}".format(resp)) self.wait_for_modem() self.__serial.write(b"AT\r\n") - self.__serial.write(b"AT\r\n") else: self.__serial.read(100) @@ -283,13 +453,22 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f self.uart_mirror(rgbled) elif bootrom: - print('Starting STP (DO NOT DISCONNECT POWER!!!)') - + if verbose: print('Starting STP') else: - print('Starting STP ON_THE_FLY') + if verbose: + if load_fff: + print('Starting STP [FFF]') + else: + print('Starting STP ON_THE_FLY') self.__serial.read(100) - self.__serial.write(b'AT+SMSTPU=\"ON_THE_FLY\"\r\n') + if load_fff: + if debug: print("Sending AT+SMSTPU") + self.__serial.write(b'AT+SMSTPU\r\n') + else: + if debug: print("Sending AT+SMSTPU=\"ON_THE_FLY\"") + self.__serial.write(b'AT+SMSTPU=\"ON_THE_FLY\"\r\n') + response = self.read_rsp(size=4) if response != b'OK\r\n' and response != b'\r\nOK' and response != b'\nOK': raise OSError("Invalid answer '%s' from the device" % response) @@ -312,6 +491,7 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f response = self.read_rsp(size=6) if not b'OK' in response: print('Failed to start STP mode!') + reconnect_uart() sys.exit(1) else: print('AT auto-negotiation failed! Exiting.') @@ -322,23 +502,25 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f response = self.read_rsp(size=6) if not b'OK' in response: print('Failed to start STP mode!') + reconnect_uart() sys.exit(1) try: if debug: - print('Starting STP code upload') + if verbose: print('Starting STP code upload') if stp.start(blob, blobsize, self.__serial, baudrate, AT=False, debug=debug, pkgdebug=pkgdebug): blob.close() + self.__serial.read() if switch_ffh: - print('Bootrom updated successfully, switching to upgrade mode') + if verbose: print('Bootrom updated successfully, switching to recovery mode') abort = False elif load_ffh: - if not self.wakeup_modem(baudrate, port, 100, 1, debug): + if not self.wakeup_modem(baudrate, port, 100, 1, debug,'Waiting for updater to load...'): return False - print('Upgrader loaded successfully, modem is in upgrade mode') + if verbose: print('Upgrader loaded successfully, modem is in update mode') return True else: - print('Code download done, returning to user mode') + if verbose: print('Code download done, returning to user mode') abort = recover else: blob.close() @@ -355,34 +537,147 @@ def __run(self, file_path=None, baudrate=921600, port=None, resume=False, load_f self.__serial.read() if switch_ffh: self.__serial.write(b"AT+SMSWBOOT=0,1\r\n") + resp = self.read_rsp(100) + if debug: print("AT+SMSWBOOT=0,1 returned {}".format(resp)) + if b"ERROR" in resp: + time.sleep(5) + self.__serial.write(b"AT+SMSWBOOT=0,0\r\n") + resp = self.read_rsp(100) + if debug: print('AT+SMSWBOOT=0,0 returned: {}'.format(resp)) + if b'OK' in resp: + self.__serial.write(b"AT^RESET\r\n") + resp = self.read_rsp(100) + if debug: print('AT^RESET returned: {}'.format(resp)) + return True + else: + print('Received ERROR from AT+SMSWBOOT=0,0! Aborting!') + return False return True else: - self.special_print('Resetting (DO NOT DISCONNECT POWER!!!).', end='', flush=True) - self.__serial.write(b"AT+SMSWBOOT=1,1\r\n") - self.wait_for_modem(send=False, expected=b'+SYSSTART') + if load_fff: + self.__serial.write(b"AT+SMUPGRADE\r\n") + if not self.wakeup_modem(baudrate, port, 100, 1, debug, self.__get_wait_msg(load_fff=load_fff)): + print("Timeout while waiting for modem to finish updating!") + reconnect_uart() + sys.exit(1) + + start = time.time() + while True: + self.__serial.read() + self.__serial.write(b"AT+SMUPGRADE?\r\n") + resp = self.read_rsp(1024) + if debug: print("AT+SMUPGRADE? returned {} [timeout: {}]".format(resp, time.time() - start)) + + if resp == b'\x00' or resp == b'': + time.sleep(2) + + if b'No report' in resp or b'on-going' in resp: + time.sleep(1) + + if b'success' in resp or b'fail' in resp: + break + + if time.time() - start >= 300: + raise OSError('Timeout waiting for modem to respond!') + + self.__serial.write(b"AT+SMSWBOOT?\r\n") + resp = self.read_rsp(100) + if debug: print("AT+SMSWBOOT? returned {}".format(resp)) + start = time.time() + while (b"RECOVERY" not in resp) and (b"FFH" not in resp) and (b"FFF" not in resp): + if debug: print("Timeout: {}".format(time.time() - start)) + if time.time() - start >= 300: + reconnect_uart() + raise OSError('Timeout waiting for modem to respond!') + time.sleep(2) + if not self.wakeup_modem(baudrate, port, 100, 1, debug, self.__get_wait_msg(load_fff=load_fff)): + reconnect_uart() + raise OSError('Timeout while waiting for modem to finish updating!') + self.__serial.read() + self.__serial.write(b"AT+SMSWBOOT?\r\n") + resp = self.read_rsp(100) + if debug: print("AT+SMSWBOOT? returned {}".format(resp)) + self.__serial.read() + self.__serial.write(b"AT+SMUPGRADE?\r\n") + resp = self.read_rsp(1024) + if debug: print("AT+SMUPGRADE? returned {}".format(resp)) + sqnup_result = self.return_upgrade_response(resp) + if debug: print('This is my result: {}'.format(sqnup_result)) + if 'success' in sqnup_result: + if not load_fff: + self.special_print('Resetting.', end='', flush=True) + self.__serial.write(b"AT+SMSWBOOT=1,1\r\n") + if debug: print("AT+SMSWBOOT=1,1 returned {}".format(resp)) + if b"ERROR" in resp: + time.sleep(5) + self.__serial.write(b"AT+SMSWBOOT=1,0\r\n") + resp = self.read_rsp(100) + if debug: print('AT+SMSWBOOT=1,0 returned: {}'.format(resp)) + if b'OK' in resp: + self.__serial.write(b"AT^RESET\r\n") + resp = self.read_rsp(100) + if debug: print('AT^RESET returned: {}'.format(resp)) + return True + else: + print('Received ERROR from AT+SMSWBOOT=1,0! Aborting!') + return False + self.wait_for_modem(send=False, echo_char='.', expected=b'+SYSSTART') + + elif sqnup_result is not None: + print('Upgrade failed with result {}!'.format(sqnup_result)) + print('Please check your firmware file(s)') + else: + print("Invalid response after upgrade... aborting.") + reconnect_uart() + sys.exit(1) self.__serial.write(b"AT\r\n") self.__serial.write(b"AT\r\n") time.sleep(0.5) - self.__serial.read() - print('Upgrade completed!') - print("Here's the current firmware version:") - time.sleep(0.5) - self.__serial.read() - self.__serial.write(b"AT!=\"showver\"\r\n") - time.sleep(.5) - shver = self.read_rsp(2000) - if shver is not None: - self.print_pretty_response(shver) - return True + + if 'success' in sqnup_result: + self.__serial.write(b"AT+SQNSUPGRADENTF=\"success\"\r\n") + self.__serial.read() + return True + elif sqnup_result is None: + print('Modem upgrade was unsucessfull. Please check your firmware file(s)') + return False + + def __check_br(self, br_only=False, verbose=False, debug=False): + old_br = None + old_sw = None + if debug: print("Checking bootrom & application") + self.__serial.write(b"AT!=\"showver\"\r\n") + time.sleep(.5) + shver = self.read_rsp(2000) + if shver is not None: + for line in shver.decode('ascii').split('\n'): + if debug: print('Checking line {}'.format(line)) + if "Bootloader0" in line: + old_br = "[33080]" in line + if debug: print("old_br: {}".format(old_br)) + + if "Software" in line: + old_sw = "[33080]" in line + if debug: print("old_sw: {}".format(old_sw)) + if old_br is None or old_sw is None: + if debug: print("Returning: None") + return None + if old_br and (br_only or not old_sw): + if debug: print("Returning: True") + return True + if debug: print("Returning: False") return False - def wakeup_modem(self, baudrate, port, max_try, delay, debug): + + + def wakeup_modem(self, baudrate, port, max_try, delay, debug, msg='Attempting AT wakeup...'): if 'FiPy' in self.__sysname or 'GPy' in self.__sysname: self.__serial = UART(1, baudrate=baudrate, pins=self.__pins, timeout_chars=1) MAX_TRY = max_try count = 0 - print('Attempting AT wakeup...') + if msg is not None: + print(msg) self.__serial.read() self.__serial.write(b"AT\r\n") response = self.read_rsp(size=6) @@ -457,21 +752,29 @@ def uart_mirror(self, color): pycom.heartbeat(False) time.sleep(.5) pycom.rgbled(color) - from network import LTE LTE.modem_upgrade_mode() - def upgrade_sd(self, ffile, mfile=None, baudrate=921600, retry=False, resume=False, debug=False, pkgdebug=False): - print('<<< Welcome to the SQN3330 firmware updater >>>') + def success_message(self, port=None, verbose=False, debug=False): + print("Your modem has been successfully updated.") + print("Here is the current firmware version:\n") + self.show_version(port=port, verbose=verbose, debug=debug) + + def upgrade(self, ffile, mfile=None, baudrate=921600, retry=False, resume=False, debug=False, pkgdebug=False, verbose=False, load_fff=True): success = True if not retry and mfile is not None: - success = False - success = self.__run(bootrom=True, resume=resume, switch_ffh=True, direct=False, debug=debug, pkgdebug=pkgdebug) - time.sleep(1) + if resume or self.__check_br(br_only=True, verbose=verbose, debug=debug): + success = False + success = self.__run(bootrom=True, resume=resume, switch_ffh=True, direct=False, debug=debug, pkgdebug=pkgdebug, verbose=verbose) + time.sleep(1) + else: + print('{} is not required. Resumining normal upgrade.'.format(mfile)) + mfile=None + success=True if debug: print('Success1? {}'.format(success)) if success: if mfile is not None: success = False - success = self.__run(file_path=mfile, load_ffh=True, direct=False, baudrate=baudrate, debug=debug, pkgdebug=pkgdebug) + success = self.__run(file_path=mfile, load_ffh=True, direct=False, baudrate=baudrate, debug=debug, pkgdebug=pkgdebug, verbose=verbose) time.sleep(1) else: success = True @@ -479,131 +782,149 @@ def upgrade_sd(self, ffile, mfile=None, baudrate=921600, retry=False, resume=Fal print('Unable to upgrade bootrom.') if debug: print('Success2? {}'.format(success)) if success: - self.__run(file_path=ffile, resume=True if mfile is not None else resume, baudrate=baudrate, direct=False, debug=debug, pkgdebug=pkgdebug) + if self.__run(file_path=ffile, resume=True if mfile is not None else resume, baudrate=baudrate, direct=False, debug=debug, pkgdebug=pkgdebug, verbose=verbose, load_fff=False if mfile else load_fff): + if self.__check_br(verbose=verbose, debug=debug): + self.__run(bootrom=True, debug=debug, direct=False, pkgdebug=pkgdebug, verbose=verbose, load_fff=True) + self.success_message(verbose=verbose, debug=debug) else: print('Unable to load updater from {}'.format(mfile)) - def upgrade_uart(self, ffh_mode=False, mfile=None, retry=False, resume=False, color=0x050505, debug=False, pkgdebug=False): - success = True + def upgrade_uart(self, ffh_mode=False, mfile=None, retry=False, resume=False, color=0x050505, debug=False, pkgdebug=False, verbose=False, load_fff=True): + success = False + try: + success = hasattr(LTE,'modem_upgrade_mode') + except: + success = False + if not success: + print('Firmware does not support LTE.modem_upgrade_mode()!') + reconnect_uart() + sys.exit(1) print('Preparing modem for upgrade...') if not retry and ffh_mode: success = False - success = self.__run(bootrom=True, resume=resume, switch_ffh=True, direct=False, debug=debug, pkgdebug=pkgdebug) + success = self.__run(bootrom=True, resume=resume, switch_ffh=True, direct=False, debug=debug, pkgdebug=pkgdebug, verbose=verbose) time.sleep(1) if success: if mfile is not None: success = False - success = self.__run(file_path=mfile, load_ffh=True, direct=False, debug=debug, pkgdebug=pkgdebug) + success = self.__run(file_path=mfile, load_ffh=True, direct=False, debug=debug, pkgdebug=pkgdebug, verbose=verbose) if debug: print('Success2? {}'.format(success)) if success: - self.__run(mirror=True, load_ffh=False, direct=False, rgbled=color, debug=debug) + self.__run(mirror=True, load_ffh=False, direct=False, rgbled=color, debug=debug, verbose=verbose) else: print('Unable to load updater from {}'.format(mfile)) else: - self.__run(mirror=True, load_ffh=ffh_mode, direct=False, rgbled=color, debug=debug) + self.__run(mirror=True, load_ffh=ffh_mode, direct=False, rgbled=color, debug=debug, verbose=verbose) else: print('Unable to upgrade bootrom.') - def show_version(self, port=None, debug=False): - self.__run(port=port, debug=debug, version_only=True) + def show_version(self, port=None, debug=False, verbose=False): + self.__run(port=port, debug=debug, version_only=True, verbose=verbose) - def upgrade_ext(self, port, ffile, mfile, resume=False, debug=False, pkgdebug=False): + def upgrade_ext(self, port, ffile, mfile, resume=False, debug=False, pkgdebug=False, verbose=False, load_fff=True): success = True - print('<<< Welcome to the SQN3330 firmware updater >>>') if mfile is not None: success = False - success = self.__run(file_path=mfile, load_ffh=True, port=port, debug=debug, pkgdebug=pkgdebug) + success = self.__run(file_path=mfile, load_ffh=True, port=port, debug=debug, pkgdebug=pkgdebug, verbose=verbose) if success: - self.__run(file_path=ffile, resume=True if mfile is not None else resume, direct=False, port=port, debug=debug, pkgdebug=pkgdebug) + if self.__run(file_path=ffile, resume=True if mfile is not None else resume, direct=False, port=port, debug=debug, pkgdebug=pkgdebug, verbose=verbose, load_fff=load_fff): + self.success_message(port=port, verbose=verbose, debug=debug) else: print('Unable to load updater from {}'.format(mfile)) - def recover_ext(self, port, mfile, debug=False, pkgdebug=False): - print('<<< Welcome to the SQN3330 recovery firmware updater >>>') - success = self.__run(atneg_only = True, direct= False, port=port, debug=debug, pkgdebug=pkgdebug) - #success = True - if debug: print('Success1? {}'.format(success)) - if success: - success = False - success = self.__run(file_path=mfile, load_ffh=True, direct=True, port=port, debug=debug, pkgdebug=pkgdebug) - if debug: print('Success2? {}'.format(success)) - if success: - self.__run(bootrom=True, switch_ffh=True, resume=True, direct=False, port=port, debug=debug, pkgdebug=pkgdebug) - else: - print('Unable to load updater from {}'.format(mfile)) - else: - print('Failed to perform AT auto-negotiation') +def detect_error(): + print('Could not detect your modem!') + print('Please try to power off your device and restart in safeboot mode.') + reconnect_uart() + sys.exit(1) + +def print_welcome(): + print('<<< Welcome to the SQN3330 firmware updater [{}] >>>'.format(VERSION)) + if release is not None: + print('>>> {} with firmware version {}'.format(sysname,release)) + if 'FiPy' in sysname or 'GPy' in sysname: - def run(ffile, mfile=None, baudrate=921600, retry=False, resume=False, debug=False): - fretry = False - fresume = False + + def run(ffile, mfile=None, baudrate=921600, verbose=False, debug=False, load_fff=True): + print_welcome() + retry = False + resume = False sqnup = sqnsupgrade() if sqnup.check_files(ffile, mfile, debug): - state = sqnup.detect_modem_state(initial_delay = 10) + state = sqnup.detect_modem_state(debug=debug) if debug: print('Modem state: {}'.format(state)) - if (not retry) and (not resume): - if state == 0: - fretry = True - if mfile is None: - print('Your modem is in recovery mode. Please specify updater.elf file') - sys.exit(1) - elif state == 4: - fresume = True - elif state == -1: - print('Cannot detect modem state...Resuming regardless') - promt = input("please Enter 0 to Retry or 1 to Resume operation\n") - if promt: - fresume = True - else: - fretry = True - if debug: print('Resume: {} Retry: {}'.format(fresume, fretry)) - else: - fretry = retry - fresume = resume - - sqnup.upgrade_sd(ffile, mfile, baudrate, fretry, fresume, debug, False) - - def uart(ffh_mode=False, mfile=None, retry=False, resume=False, color=0x050505, debug=False): - fretry = False - fresume = False + if state is None: + detect_error() + elif state == 0: + retry = True + if mfile is None: + print('Your modem is in recovery mode. Please specify updater.elf file') + reconnect_uart() + sys.exit(1) + elif state == 4: + resume = True + elif state == -1: + detect_error() + sqnup.upgrade(ffile=ffile, mfile=mfile, baudrate=baudrate, retry=retry, resume=resume, debug=debug, pkgdebug=False, verbose=verbose, load_fff=load_fff) + reconnect_uart() + + def uart(ffh_mode=False, mfile=None, color=0x050505, verbose=False, debug=False): + print_welcome() + retry = False + resume = False + sqnup = sqnsupgrade() + state = sqnup.detect_modem_state(debug=debug) + if state is None: + detect_error() + elif state == 0: + print('Your modem is in recovery mode. You will need to use firmware.dup and updater.elf file to upgrade.') + retry = True + ffh_mode = True + elif state == 4: + resume = True + elif state == -1: + detect_error() + sqnup.upgrade_uart(ffh_mode, mfile, retry, resume, color, debug, False, verbose) + + def info(verbose=False, debug=False, retry=5): + print_welcome() + import pycom + count = 0 sqnup = sqnsupgrade() - state = sqnup.detect_modem_state(initial_delay = 10) - if (not retry) and (not resume): - if state == 0: - print('Your modem is in recovery mode. You will need to use updater.elf file to upgrade.') - fretry = True + while count < retry: + count += 1 + if verbose: print('Trying to detect modem state [{}/{}]'.format(count, retry)) + state = sqnup.detect_modem_state(debug=debug) + if debug: print('State: {} at count: {}'.format(state, count)) + if state is not None: break + + if state is not None: + if state == 2: + print('Your modem is in application mode. Here is the current version:') + sqnup.show_version(verbose=verbose, debug=debug) + elif state == 1: + print('Your modem is in mTools mode.') + elif state == 0: + print('Your modem is in recovery mode! Use firmware.dup and updater.elf to flash new firmware.') elif state == 4: - fresume = True + print('Your modem is in upgrade mode! Use firmware.dup to flash new firmware.') elif state == -1: - print('Cannot detect modem state...Resuming regardless') - promt = input("please Enter 0 to Retry or 1 to Resume operation\n") - if promt: - fresume = True - else: - fretry = True - if debug: print('Resume: {} Retry: {}'.format(fresume, fretry)) + print('Cannot determine modem state!') + if hasattr(pycom, 'lte_modem_en_on_boot') and verbose: + print('LTE autostart {}.'.format('enabled' if pycom.lte_modem_en_on_boot() else 'disabled')) else: - fretry = retry - fresume = resume - - sqnup.upgrade_uart(ffh_mode, mfile, fretry, fresume, color, debug, False) - - def version(debug=False): - sqnup = sqnsupgrade() - sqnup.show_version(None, debug) + print('Cannot determine modem state!') + reconnect_uart() else: - def run(port, ffile, mfile=None, resume=False, debug=False): + def run(port, ffile, mfile=None, resume=False, debug=False, verbose=False, load_fff=True): + print_welcome() sqnup = sqnsupgrade() if sqnup.check_files(ffile, mfile, debug): - sqnup.upgrade_ext(port, ffile, mfile, resume, debug, False) - - def recover(port, mfile, debug=False): - sqnup = sqnsupgrade() - sqnup.recover_ext(port, mfile, debug, False) + sqnup.upgrade_ext(port=port, ffile=ffile, mfile=mfile, resume=resume, debug=debug, pkgdebug=False, verbose=verbose, load_fff=load_fff) - def version(port, debug=False): + def version(port, verbose=False, debug=False): sqnup = sqnsupgrade() - sqnup.show_version(port, debug) + sqnup.show_version(port=port, debug=debug, verbose=verbose) diff --git a/esp32/ftp/ftp.c b/esp32/ftp/ftp.c index a16267148c..9a97daacd7 100644 --- a/esp32/ftp/ftp.c +++ b/esp32/ftp/ftp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/ftp/ftp.h b/esp32/ftp/ftp.h index 01cd78c123..b72b0f0e7f 100644 --- a/esp32/ftp/ftp.h +++ b/esp32/ftp/ftp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/ftp/updater.c b/esp32/ftp/updater.c index 41e9629188..3a79885741 100644 --- a/esp32/ftp/updater.c +++ b/esp32/ftp/updater.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/ftp/updater.h b/esp32/ftp/updater.h index bc1882799a..64bc6b10ff 100644 --- a/esp32/ftp/updater.h +++ b/esp32/ftp/updater.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/hal/esp32_mphal.c b/esp32/hal/esp32_mphal.c index c9b8480171..e45e99343c 100644 --- a/esp32/hal/esp32_mphal.c +++ b/esp32/hal/esp32_mphal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/hal/esp32_mphal.h b/esp32/hal/esp32_mphal.h index 9038d6cad1..569985da57 100644 --- a/esp32/hal/esp32_mphal.h +++ b/esp32/hal/esp32_mphal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information @@ -27,6 +27,7 @@ uint64_t mp_hal_ticks_ms_non_blocking(void); uint64_t mp_hal_ticks_us_non_blocking(void); void mp_hal_delay_ms(uint32_t delay); void mp_hal_set_interrupt_char(int c); +void mp_hal_set_reset_char(int c); void mp_hal_reset_safe_and_boot(bool reset); #endif // _INCLUDED_MPHAL_H_ diff --git a/esp32/lora/board.c b/esp32/lora/board.c index 802c15ca1f..eab07474a4 100644 --- a/esp32/lora/board.c +++ b/esp32/lora/board.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/lora/board.h b/esp32/lora/board.h index 80459c4ac9..6be75c58df 100644 --- a/esp32/lora/board.h +++ b/esp32/lora/board.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/lora/gpio-board.c b/esp32/lora/gpio-board.c index 18ff558e20..3dfa33375c 100644 --- a/esp32/lora/gpio-board.c +++ b/esp32/lora/gpio-board.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/lora/gpio-board.h b/esp32/lora/gpio-board.h index f68a3f6bbd..d0a43215e0 100644 --- a/esp32/lora/gpio-board.h +++ b/esp32/lora/gpio-board.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/lora/pinName-board.h b/esp32/lora/pinName-board.h index 050d85508f..60e313e017 100644 --- a/esp32/lora/pinName-board.h +++ b/esp32/lora/pinName-board.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/lora/spi-board.c b/esp32/lora/spi-board.c index ce1dca73a4..783e2e6bd9 100644 --- a/esp32/lora/spi-board.c +++ b/esp32/lora/spi-board.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/lora/spi-board.h b/esp32/lora/spi-board.h index 17a0d71ba2..9b0dba7660 100644 --- a/esp32/lora/spi-board.h +++ b/esp32/lora/spi-board.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/lora/timer-board.c b/esp32/lora/timer-board.c index 3f34ed4ec8..1fff52d0b6 100644 --- a/esp32/lora/timer-board.c +++ b/esp32/lora/timer-board.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/lora/timer-board.h b/esp32/lora/timer-board.h index 9c503bc856..a27851be8a 100644 --- a/esp32/lora/timer-board.h +++ b/esp32/lora/timer-board.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/lte/lteppp.c b/esp32/lte/lteppp.c index 8268ffe621..41b07c07b3 100644 --- a/esp32/lte/lteppp.c +++ b/esp32/lte/lteppp.c @@ -52,6 +52,7 @@ static uart_dev_t* lteppp_uart_reg; static QueueHandle_t xCmdQueue; static QueueHandle_t xRxQueue; static lte_state_t lteppp_lte_state; +static lte_legacy_t lteppp_lte_legacy; static SemaphoreHandle_t xLTESem; static ppp_pcb *lteppp_pcb; // PPP control block struct netif lteppp_netif; // PPP net interface @@ -65,6 +66,8 @@ static bool lteppp_init_complete = false; static bool lteppp_enabled = false; +static bool ltepp_ppp_conn_up = false; + /****************************************************************************** DECLARE PRIVATE FUNCTIONS ******************************************************************************/ @@ -78,6 +81,64 @@ static uint32_t lteppp_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void /****************************************************************************** DEFINE PUBLIC FUNCTIONS ******************************************************************************/ +void connect_lte_uart (void) { + +// bool success = uart_driver_delete(LTE_UART_ID); +// vTaskDelay(5 / portTICK_RATE_MS); +// printf("Driver deleted? %d\n", success); + + // initialize the UART interface + uart_config_t config; + config.baud_rate = MICROPY_LTE_UART_BAUDRATE; + config.data_bits = UART_DATA_8_BITS; + config.parity = UART_PARITY_DISABLE; + config.stop_bits = UART_STOP_BITS_1; + config.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS; + config.rx_flow_ctrl_thresh = 64; + uart_param_config(LTE_UART_ID, &config); + +// //deassign LTE Uart pins +// pin_deassign(MICROPY_LTE_TX_PIN); +// gpio_pullup_dis(MICROPY_LTE_TX_PIN->pin_number); +// +// pin_deassign(MICROPY_LTE_RX_PIN); +// gpio_pullup_dis(MICROPY_LTE_RX_PIN->pin_number); +// +// pin_deassign(MICROPY_LTE_CTS_PIN); +// gpio_pullup_dis(MICROPY_LTE_CTS_PIN->pin_number); +// +// pin_deassign(MICROPY_LTE_RTS_PIN); +// gpio_pullup_dis(MICROPY_LTE_RTS_PIN->pin_number); +// +// vTaskDelay(5 / portTICK_RATE_MS); + + // configure the UART pins + pin_config(MICROPY_LTE_TX_PIN, -1, U2TXD_OUT_IDX, GPIO_MODE_OUTPUT, MACHPIN_PULL_NONE, 1); + pin_config(MICROPY_LTE_RX_PIN, U2RXD_IN_IDX, -1, GPIO_MODE_INPUT, MACHPIN_PULL_NONE, 1); + pin_config(MICROPY_LTE_RTS_PIN, -1, U2RTS_OUT_IDX, GPIO_MODE_OUTPUT, MACHPIN_PULL_NONE, 1); + pin_config(MICROPY_LTE_CTS_PIN, U2CTS_IN_IDX, -1, GPIO_MODE_INPUT, MACHPIN_PULL_NONE, 1); + + vTaskDelay(5 / portTICK_RATE_MS); + + // install the UART driver + uart_driver_install(LTE_UART_ID, LTE_UART_BUFFER_SIZE, LTE_UART_BUFFER_SIZE, 0, NULL, 0, NULL); + lteppp_uart_reg = &UART2; + + // disable the delay between transfers + lteppp_uart_reg->idle_conf.tx_idle_num = 0; + + // configure the rx timeout threshold + lteppp_uart_reg->conf1.rx_tout_thrhd = 20 & UART_RX_TOUT_THRHD_V; + + uart_set_hw_flow_ctrl(LTE_UART_ID, UART_HW_FLOWCTRL_DISABLE, 0); + uart_set_rts(LTE_UART_ID, false); + vTaskDelay(5 / portTICK_RATE_MS); + uart_set_hw_flow_ctrl(LTE_UART_ID, UART_HW_FLOWCTRL_CTS_RTS, 64); + vTaskDelay(5 / portTICK_RATE_MS); + +} + + void lteppp_init(void) { lteppp_lte_state = E_LTE_INIT; @@ -115,6 +176,12 @@ void lteppp_set_state(lte_state_t state) { xSemaphoreGive(xLTESem); } +void lteppp_set_legacy(lte_legacy_t legacy) { + xSemaphoreTake(xLTESem, portMAX_DELAY); + lteppp_lte_legacy = legacy; + xSemaphoreGive(xLTESem); +} + void lteppp_connect (void) { uart_flush(LTE_UART_ID); vTaskDelay(25); @@ -133,9 +200,18 @@ void lteppp_send_at_command (lte_task_cmd_data_t *cmd, lte_task_rsp_data_t *rsp) xQueueReceive(xRxQueue, rsp, (TickType_t)portMAX_DELAY); } +void lteppp_send_at_command_delay (lte_task_cmd_data_t *cmd, lte_task_rsp_data_t *rsp, TickType_t delay) { + xQueueSend(xCmdQueue, (void *)cmd, (TickType_t)portMAX_DELAY); + vTaskDelay(delay); + xQueueReceive(xRxQueue, rsp, (TickType_t)portMAX_DELAY); +} + bool lteppp_wait_at_rsp (const char *expected_rsp, uint32_t timeout, bool from_mp) { + uint32_t rx_len = 0; + //printf("Expected Response: %s\n", expected_rsp); + // wait until characters start arriving do { // being called from the MicroPython interpreter @@ -149,22 +225,24 @@ bool lteppp_wait_at_rsp (const char *expected_rsp, uint32_t timeout, bool from_m if (timeout > 0) { timeout--; } + //printf("Timeout: %d, rx_len: %d\n", timeout, rx_len); } while (timeout > 0 && 0 == rx_len); memset(lteppp_trx_buffer, 0, sizeof(lteppp_trx_buffer)); - if (rx_len > 0) { + while (rx_len > 0) { // try to read up to the size of the buffer minus null terminator (minus 2 because we store the OK status in the last byte) rx_len = uart_read_bytes(LTE_UART_ID, (uint8_t *)lteppp_trx_buffer, sizeof(lteppp_trx_buffer) - 2, LTE_TRX_WAIT_MS(sizeof(lteppp_trx_buffer)) / portTICK_RATE_MS); if (rx_len > 0) { // NULL terminate the string lteppp_trx_buffer[rx_len] = '\0'; - // printf("%s\n", lteppp_trx_buffer); + //printf("%s\n", lteppp_trx_buffer); if (expected_rsp != NULL) { if (strstr(lteppp_trx_buffer, expected_rsp) != NULL) { + //printf("RESP: %s\n", lteppp_trx_buffer); return true; } } - return false; + uart_get_buffered_data_len(LTE_UART_ID, &rx_len); } } return false; @@ -178,7 +256,19 @@ lte_state_t lteppp_get_state(void) { return state; } +lte_legacy_t lteppp_get_legacy(void) { + lte_legacy_t legacy; + xSemaphoreTake(xLTESem, portMAX_DELAY); + legacy = lteppp_lte_legacy; + xSemaphoreGive(xLTESem); + return legacy; +} + void lteppp_deinit (void) { + + // enable airplane low power mode + lteppp_send_at_cmd("AT!=\"setlpm airplane=1 enable=1\"", LTE_RX_TIMEOUT_MAX_MS); + uart_set_hw_flow_ctrl(LTE_UART_ID, UART_HW_FLOWCTRL_DISABLE, 0); uart_set_rts(LTE_UART_ID, false); xSemaphoreTake(xLTESem, portMAX_DELAY); @@ -194,6 +284,10 @@ bool lteppp_task_ready(void) { return lteppp_init_complete; } +bool ltepp_is_ppp_conn_up(void) +{ + return ltepp_ppp_conn_up; +} /****************************************************************************** DEFINE PRIVATE FUNCTIONS ******************************************************************************/ @@ -202,37 +296,7 @@ static void TASK_LTE (void *pvParameters) { lte_task_cmd_data_t *lte_task_cmd = (lte_task_cmd_data_t *)lteppp_trx_buffer; lte_task_rsp_data_t *lte_task_rsp = (lte_task_rsp_data_t *)lteppp_trx_buffer; - // initialize the UART interface - uart_config_t config; - config.baud_rate = MICROPY_LTE_UART_BAUDRATE; - config.data_bits = UART_DATA_8_BITS; - config.parity = UART_PARITY_DISABLE; - config.stop_bits = UART_STOP_BITS_1; - config.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS; - config.rx_flow_ctrl_thresh = 64; - uart_param_config(LTE_UART_ID, &config); - - // configure the UART pins - pin_config(MICROPY_LTE_TX_PIN, -1, U2TXD_OUT_IDX, GPIO_MODE_OUTPUT, MACHPIN_PULL_NONE, 1); - pin_config(MICROPY_LTE_RX_PIN, U2RXD_IN_IDX, -1, GPIO_MODE_INPUT, MACHPIN_PULL_NONE, 1); - pin_config(MICROPY_LTE_RTS_PIN, -1, U2RTS_OUT_IDX, GPIO_MODE_OUTPUT, MACHPIN_PULL_NONE, 1); - pin_config(MICROPY_LTE_CTS_PIN, U2CTS_IN_IDX, -1, GPIO_MODE_INPUT, MACHPIN_PULL_NONE, 1); - - // install the UART driver - uart_driver_install(LTE_UART_ID, LTE_UART_BUFFER_SIZE, LTE_UART_BUFFER_SIZE, 0, NULL, 0, NULL); - lteppp_uart_reg = &UART2; - - // disable the delay between transfers - lteppp_uart_reg->idle_conf.tx_idle_num = 0; - - // configure the rx timeout threshold - lteppp_uart_reg->conf1.rx_tout_thrhd = 20 & UART_RX_TOUT_THRHD_V; - - uart_set_hw_flow_ctrl(LTE_UART_ID, UART_HW_FLOWCTRL_DISABLE, 0); - uart_set_rts(LTE_UART_ID, false); - vTaskDelay(5 / portTICK_RATE_MS); - uart_set_hw_flow_ctrl(LTE_UART_ID, UART_HW_FLOWCTRL_CTS_RTS, 64); - vTaskDelay(5 / portTICK_RATE_MS); + connect_lte_uart(); while (!lteppp_enabled) { @@ -249,7 +313,7 @@ static void TASK_LTE (void *pvParameters) { } } - lteppp_send_at_cmd("ATH", LTE_RX_TIMEOUT_MIN_MS); + //lteppp_send_at_cmd("ATH", LTE_RX_TIMEOUT_MIN_MS); while (true) { vTaskDelay(LTE_RX_TIMEOUT_MIN_MS); if (lteppp_send_at_cmd("AT", LTE_RX_TIMEOUT_MIN_MS)) { @@ -276,7 +340,7 @@ static void TASK_LTE (void *pvParameters) { break; } } - lteppp_send_at_cmd("ATH", LTE_RX_TIMEOUT_MIN_MS); + //lteppp_send_at_cmd("ATH", LTE_RX_TIMEOUT_MIN_MS); while (true) { vTaskDelay(LTE_RX_TIMEOUT_MIN_MS); if (lteppp_send_at_cmd("AT", LTE_RX_TIMEOUT_MIN_MS)) { @@ -325,6 +389,19 @@ static void TASK_LTE (void *pvParameters) { lte_state_t state = lteppp_get_state(); if (state == E_LTE_PPP) { uint32_t rx_len; + // check for IP connection + if(lteppp_ipv4() > 0) + { + ltepp_ppp_conn_up = true; + } + else + { + if(ltepp_ppp_conn_up == true) + { + ltepp_ppp_conn_up = false; + lteppp_set_state(E_LTE_ATTACHED); + } + } // wait for characters received uart_get_buffered_data_len(LTE_UART_ID, &rx_len); if (rx_len > 0) { @@ -336,15 +413,20 @@ static void TASK_LTE (void *pvParameters) { } } } + else + { + ltepp_ppp_conn_up = false; + } } } } + static bool lteppp_send_at_cmd_exp (const char *cmd, uint32_t timeout, const char *expected_rsp) { uint32_t cmd_len = strlen(cmd); // char tmp_buf[128]; - // printf("cmd: %s\n", cmd); + //printf("at_cmd_exp: %s\n", cmd); // flush the rx buffer first uart_flush(LTE_UART_ID); @@ -388,62 +470,62 @@ static void lteppp_status_cb (ppp_pcb *pcb, int err_code, void *ctx) { switch (err_code) { case PPPERR_NONE: - // printf("status_cb: Connected\n"); +// printf("status_cb: Connected\n"); #if PPP_IPV4_SUPPORT lte_gw = pppif->gw.u_addr.ip4.addr; lte_netmask = pppif->netmask.u_addr.ip4.addr; lte_ipv4addr = pppif->ip_addr.u_addr.ip4.addr; - // printf("ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr)); - // printf("gateway = %s\n", ipaddr_ntoa(&pppif->gw)); - // printf("netmask = %s\n", ipaddr_ntoa(&pppif->netmask)); +// printf("ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr)); +// printf("gateway = %s\n", ipaddr_ntoa(&pppif->gw)); +// printf("netmask = %s\n", ipaddr_ntoa(&pppif->netmask)); #endif #if PPP_IPV6_SUPPORT memcpy(lte_ipv6addr.addr, netif_ip6_addr(pppif, 0), sizeof(lte_ipv4addr)); - // printf("ip6addr = %s\n", ip6addr_ntoa(netif_ip6_addr(pppif, 0))); +// printf("ip6addr = %s\n", ip6addr_ntoa(netif_ip6_addr(pppif, 0))); #endif break; case PPPERR_PARAM: - // printf("status_cb: Invalid parameter\n"); +// printf("status_cb: Invalid parameter\n"); break; case PPPERR_OPEN: - // printf("status_cb: Unable to open PPP session\n"); +// printf("status_cb: Unable to open PPP session\n"); break; case PPPERR_DEVICE: - // printf("status_cb: Invalid I/O device for PPP\n"); +// printf("status_cb: Invalid I/O device for PPP\n"); break; case PPPERR_ALLOC: - // printf("status_cb: Unable to allocate resources\n"); +// printf("status_cb: Unable to allocate resources\n"); break; case PPPERR_USER: - // printf("status_cb: User interrupt (disconnected)\n"); +// printf("status_cb: User interrupt (disconnected)\n"); lte_ipv4addr = 0; memset(lte_ipv6addr.addr, 0, sizeof(lte_ipv4addr)); break; case PPPERR_CONNECT: - // printf("status_cb: Connection lost\n"); +// printf("status_cb: Connection lost\n"); lte_ipv4addr = 0; memset(lte_ipv6addr.addr, 0, sizeof(lte_ipv4addr)); break; case PPPERR_AUTHFAIL: - // printf("status_cb: Failed authentication challenge\n"); +// printf("status_cb: Failed authentication challenge\n"); break; case PPPERR_PROTOCOL: - // printf("status_cb: Failed to meet protocol\n"); +// printf("status_cb: Failed to meet protocol\n"); break; case PPPERR_PEERDEAD: - // printf("status_cb: Connection timeout\n"); +// printf("status_cb: Connection timeout\n"); break; case PPPERR_IDLETIMEOUT: - // printf("status_cb: Idle Timeout\n"); +// printf("status_cb: Idle Timeout\n"); break; case PPPERR_CONNECTTIME: - // printf("status_cb: Max connect time reached\n"); +// printf("status_cb: Max connect time reached\n"); break; case PPPERR_LOOPBACK: - // printf("status_cb: Loopback detected\n"); +// printf("status_cb: Loopback detected\n"); break; default: - // printf("status_cb: Unknown error code %d\n", err_code); +// printf("status_cb: Unknown error code %d\n", err_code); lte_ipv4addr = 0; memset(lte_ipv6addr.addr, 0, sizeof(lte_ipv4addr)); break; diff --git a/esp32/lte/lteppp.h b/esp32/lte/lteppp.h index 475e92231a..acfda30900 100644 --- a/esp32/lte/lteppp.h +++ b/esp32/lte/lteppp.h @@ -39,9 +39,15 @@ typedef enum { E_LTE_IDLE, E_LTE_ATTACHING, E_LTE_ATTACHED, - E_LTE_PPP + E_LTE_PPP, + E_LTE_SUSPENDED } lte_state_t; +typedef enum { + E_LTE_NORMAL = 0, + E_LTE_LEGACY, +} lte_legacy_t; + typedef enum { E_LTE_CMD_AT = 0, E_LTE_CMD_PPP_ENTER, @@ -67,18 +73,24 @@ extern void lteppp_start (void); extern void lteppp_set_state(lte_state_t state); +extern void lteppp_set_legacy(lte_legacy_t legacy); + extern void lteppp_connect(void); extern void lteppp_disconnect(void); extern lte_state_t lteppp_get_state(void); +extern lte_legacy_t lteppp_get_legacy(void); + extern uint32_t lteppp_ipv4(void); extern void lteppp_deinit (void); extern void lteppp_send_at_command (lte_task_cmd_data_t *cmd, lte_task_rsp_data_t *rsp); +extern void lteppp_send_at_command_delay (lte_task_cmd_data_t *cmd, lte_task_rsp_data_t *rsp, TickType_t delay); + extern bool lteppp_wait_at_rsp (const char *expected_rsp, uint32_t timeout, bool from_mp); extern bool lteppp_task_ready(void); @@ -87,4 +99,8 @@ void lteppp_connect_modem (void); bool lteppp_is_modem_connected(void); +extern void connect_lte_uart (void); + +extern bool ltepp_is_ppp_conn_up(void); + #endif // _LTEPPP_H_ diff --git a/esp32/main.c b/esp32/main.c index da28bfe65c..e91e29ee4f 100644 --- a/esp32/main.c +++ b/esp32/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/lwipsocket.c b/esp32/mods/lwipsocket.c index f9f37f1d22..ee009d1345 100644 --- a/esp32/mods/lwipsocket.c +++ b/esp32/mods/lwipsocket.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/lwipsocket.h b/esp32/mods/lwipsocket.h index a3ccfd320d..d379619003 100644 --- a/esp32/mods/lwipsocket.h +++ b/esp32/mods/lwipsocket.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machcan.c b/esp32/mods/machcan.c index ab2cdb0aee..9d7b31813f 100644 --- a/esp32/mods/machcan.c +++ b/esp32/mods/machcan.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machcan.h b/esp32/mods/machcan.h index dcda79b185..7fdaac4527 100644 --- a/esp32/mods/machcan.h +++ b/esp32/mods/machcan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machine_i2c.c b/esp32/mods/machine_i2c.c index ffe41834fd..f95d9cef22 100644 --- a/esp32/mods/machine_i2c.c +++ b/esp32/mods/machine_i2c.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/mods/machine_i2c.h b/esp32/mods/machine_i2c.h index 56d1580520..e0190bcfa5 100644 --- a/esp32/mods/machine_i2c.h +++ b/esp32/mods/machine_i2c.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/mods/machpin.c b/esp32/mods/machpin.c index 6a8a71c51e..1b595378a5 100644 --- a/esp32/mods/machpin.c +++ b/esp32/mods/machpin.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence @@ -114,6 +114,7 @@ void pin_preinit(void) { void pin_init0(void) { // initialize all pins as inputs with pull downs enabled mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_module_pins_locals_dict); + for (uint i = 0; i < named_map->used - 1; i++) { pin_obj_t *self = (pin_obj_t *)named_map->table[i].value; if (self != &PIN_MODULE_P1) { // temporal while we remove all the IDF logs @@ -132,6 +133,16 @@ void pin_init0(void) { continue; } #endif + /* exclude the antenna switch pin from initialization as it is already initialized */ + if((micropy_hw_antenna_diversity_pin_num == MICROPY_SECOND_GEN_ANT_SELECT_PIN_NUM) && (self == &PIN_MODULE_P12)) + { + continue; + } + /* exclude RGB led from initialization as it is already initialized by mperror */ + if (self == &PIN_MODULE_P2) + { + continue; + } pin_config(self, -1, -1, GPIO_MODE_INPUT, MACHPIN_PULL_DOWN, 0); } } diff --git a/esp32/mods/machpin.h b/esp32/mods/machpin.h index 3d3e9b24d4..486495974c 100644 --- a/esp32/mods/machpin.h +++ b/esp32/mods/machpin.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machpwm.c b/esp32/mods/machpwm.c index c4f0cf4ea4..83dd83258a 100644 --- a/esp32/mods/machpwm.c +++ b/esp32/mods/machpwm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machpwm.h b/esp32/mods/machpwm.h index 5c581c27a3..72c9526341 100644 --- a/esp32/mods/machpwm.h +++ b/esp32/mods/machpwm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machrtc.c b/esp32/mods/machrtc.c index c4e3f5ea48..9e935576c9 100644 --- a/esp32/mods/machrtc.c +++ b/esp32/mods/machrtc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machrtc.h b/esp32/mods/machrtc.h index 04b34a55d0..6833dd590e 100644 --- a/esp32/mods/machrtc.h +++ b/esp32/mods/machrtc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machspi.c b/esp32/mods/machspi.c index 3cafb054eb..542cbfb662 100644 --- a/esp32/mods/machspi.c +++ b/esp32/mods/machspi.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/mods/machspi.h b/esp32/mods/machspi.h index b9ee5d3e34..80a95ba2b4 100644 --- a/esp32/mods/machspi.h +++ b/esp32/mods/machspi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machtimer.c b/esp32/mods/machtimer.c index 423722a54f..135134e204 100644 --- a/esp32/mods/machtimer.c +++ b/esp32/mods/machtimer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machtimer.h b/esp32/mods/machtimer.h index 71cc70d0e9..fe8a5947e6 100644 --- a/esp32/mods/machtimer.h +++ b/esp32/mods/machtimer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/machuart.c b/esp32/mods/machuart.c index 216061163d..9f2a53ba8d 100644 --- a/esp32/mods/machuart.c +++ b/esp32/mods/machuart.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information @@ -162,6 +162,7 @@ bool uart_tx_strn(mach_uart_obj_t *self, const char *str, uint len) { // make it UART Tx pin->value = 1; pin_deassign(pin); + pin->mode = GPIO_MODE_OUTPUT; pin->af_out = mach_uart_pin_af[self->uart_id][0]; gpio_matrix_out(pin->pin_number, pin->af_out, false, false); // clear the Tx FIFO empty flag @@ -186,7 +187,7 @@ bool uart_tx_strn(mach_uart_obj_t *self, const char *str, uint len) { // make it an input again pin_deassign(pin); pin->af_in = mach_uart_pin_af[self->uart_id][1]; - gpio_matrix_in(pin->pin_number, pin->af_in, false); + pin_config(pin, pin->af_in, -1, GPIO_MODE_INPUT, MACHPIN_PULL_UP, 1); MICROPY_END_ATOMIC_SECTION(isrmask); self->uart_reg->int_clr.tx_done = 1; } @@ -306,7 +307,7 @@ STATIC IRAM_ATTR void UARTRxCallback(int uart_id, int rx_byte) { if (mp_interrupt_char == rx_byte) { // raise an exception when interrupts are finished mp_keyboard_interrupt(); - } else if (CHAR_CTRL_F == rx_byte) { + } else if (mp_reset_char == rx_byte) { servers_reset_and_safe_boot(); } } diff --git a/esp32/mods/machuart.h b/esp32/mods/machuart.h index de851f9516..fe7037f373 100644 --- a/esp32/mods/machuart.h +++ b/esp32/mods/machuart.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/modbt.c b/esp32/mods/modbt.c index 702e7e2fd3..aa3a9aa9e5 100644 --- a/esp32/mods/modbt.c +++ b/esp32/mods/modbt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/modbt.h b/esp32/mods/modbt.h index a485a7c34f..6e7cbbed21 100644 --- a/esp32/mods/modbt.h +++ b/esp32/mods/modbt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/modlora.c b/esp32/mods/modlora.c index caf98b87b3..92de17a8b4 100644 --- a/esp32/mods/modlora.c +++ b/esp32/mods/modlora.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/modlora.h b/esp32/mods/modlora.h index d5ffaf21b2..3d99476ded 100644 --- a/esp32/mods/modlora.h +++ b/esp32/mods/modlora.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/modlte.c b/esp32/mods/modlte.c index 96aa8fed91..eec2e3bda2 100644 --- a/esp32/mods/modlte.c +++ b/esp32/mods/modlte.c @@ -65,6 +65,8 @@ #include "driver/uart.h" #include "driver/gpio.h" +#include "pycom_config.h" + /****************************************************************************** DEFINE TYPES ******************************************************************************/ @@ -72,8 +74,8 @@ /****************************************************************************** DEFINE CONSTANTS ******************************************************************************/ -#define LTE_NUM_UARTS 2 -#define UART_TRANSFER_MAX_LEN 1 +#define LTE_NUM_UARTS 2 +#define UART_TRANSFER_MAX_LEN 1 /****************************************************************************** DECLARE PRIVATE DATA ******************************************************************************/ @@ -91,6 +93,7 @@ extern TaskHandle_t svTaskHandle; #if defined(FIPY) extern TaskHandle_t xLoRaTaskHndl; extern TaskHandle_t xSigfoxTaskHndl; +//extern TaskHandle_t xMeshTaskHndl; #endif extern TaskHandle_t xLTETaskHndl; @@ -107,8 +110,9 @@ static void lte_pause_ppp(void); static bool lte_check_attached(void); static void lte_check_init(void); static bool lte_check_sim_present(void); +STATIC mp_obj_t lte_suspend(mp_obj_t self_in); -STATIC mp_obj_t lte_deinit(mp_obj_t self_in); +STATIC mp_obj_t lte_deinit(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); STATIC mp_obj_t lte_disconnect(mp_obj_t self_in); /****************************************************************************** @@ -128,11 +132,28 @@ static bool lte_push_at_command_ext (char *cmd_str, uint32_t timeout, const char .timeout = timeout }; memcpy(cmd.data, cmd_str, strlen(cmd_str)); - // printf("%s\n", cmd_str); + //printf("[CMD] %s\n", cmd_str); lteppp_send_at_command (&cmd, &modlte_rsp); if (strstr(modlte_rsp.data, expected_rsp) != NULL) { + //printf("[OK] %s\n", modlte_rsp.data); + return true; + } + //printf("[FAIL] %s\n", modlte_rsp.data); + return false; +} + +static bool lte_push_at_command_delay_ext (char *cmd_str, uint32_t timeout, const char *expected_rsp, TickType_t delay) { + lte_task_cmd_data_t cmd = { + .timeout = timeout + }; + memcpy(cmd.data, cmd_str, strlen(cmd_str)); + //printf("%s\n", cmd_str); + lteppp_send_at_command_delay (&cmd, &modlte_rsp, delay); + if (strstr(modlte_rsp.data, expected_rsp) != NULL) { + //printf("%s\n", modlte_rsp.data); return true; } + //printf("%s\n", modlte_rsp.data); return false; } @@ -140,12 +161,28 @@ static bool lte_push_at_command (char *cmd_str, uint32_t timeout) { return lte_push_at_command_ext(cmd_str, timeout, LTE_OK_RSP); } +static bool lte_push_at_command_delay (char *cmd_str, uint32_t timeout, TickType_t delay) { + return lte_push_at_command_delay_ext(cmd_str, timeout, LTE_OK_RSP, delay); +} + static void lte_pause_ppp(void) { mp_hal_delay_ms(LTE_PPP_BACK_OFF_TIME_MS); if (!lte_push_at_command("+++", LTE_PPP_BACK_OFF_TIME_MS)) { mp_hal_delay_ms(LTE_PPP_BACK_OFF_TIME_MS); - if (!lte_push_at_command("+++", LTE_PPP_BACK_OFF_TIME_MS)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MIN_MS)) { + mp_hal_delay_ms(LTE_PPP_BACK_OFF_TIME_MS); + if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MIN_MS)) { + mp_hal_delay_ms(LTE_PPP_BACK_OFF_TIME_MS); + if (!lte_push_at_command("+++", LTE_PPP_BACK_OFF_TIME_MS)) { + mp_hal_delay_ms(LTE_PPP_BACK_OFF_TIME_MS); + if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MIN_MS)) { + mp_hal_delay_ms(LTE_PPP_BACK_OFF_TIME_MS); + if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MIN_MS)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + } + } + } + } } } } @@ -153,36 +190,69 @@ static void lte_pause_ppp(void) { static bool lte_check_attached(void) { char *pos; bool attached = false; - - if (lteppp_get_state() == E_LTE_PPP) { + bool cgatt = false; + if (lteppp_get_state() == E_LTE_PPP && lteppp_ipv4() > 0) { attached = true; } else { + if (lteppp_get_state() == E_LTE_PPP) { + lte_pause_ppp(); + while (true) { + mp_hal_delay_ms(LTE_RX_TIMEOUT_MIN_MS); + if (lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS)) { + break; + } + } + } + lte_push_at_command("AT", LTE_RX_TIMEOUT_MIN_MS); + lte_push_at_command("AT+CGATT?", LTE_RX_TIMEOUT_MIN_MS); + if (((pos = strstr(modlte_rsp.data, "+CGATT")) && (strlen(pos) >= 7) && (pos[7] == '1' || pos[8] == '1'))) { + cgatt = true; + } lte_push_at_command("AT+CEREG?", LTE_RX_TIMEOUT_MIN_MS); - if (((pos = strstr(modlte_rsp.data, "+CEREG: 2,1,")) || (pos = strstr(modlte_rsp.data, "+CEREG: 2,5,"))) - && (strlen(pos) >= 31) && pos[30] == '7') { - if (lteppp_get_state() != E_LTE_PPP) { - lteppp_set_state(E_LTE_ATTACHED); + if (!cgatt) { + if (((pos = strstr(modlte_rsp.data, "+CEREG: 2,1,")) || (pos = strstr(modlte_rsp.data, "+CEREG: 2,5,"))) + && (strlen(pos) >= 31) && (pos[30] == '7' || pos[30] == '9')) { + attached = true; } - attached = true; } else { - lte_push_at_command("AT+CFUN?", LTE_RX_TIMEOUT_MIN_MS); - if (E_LTE_ATTACHING == lteppp_get_state()) { - // for some reason the modem has crashed, enabled the radios again... - if (!strstr(modlte_rsp.data, "+CFUN: 1")) { - lte_push_at_command("AT+CFUN=1", LTE_RX_TIMEOUT_MIN_MS); - } + if ((pos = strstr(modlte_rsp.data, "+CEREG: 2,1,")) || (pos = strstr(modlte_rsp.data, "+CEREG: 2,5,"))) { + attached = true; } else { - if (strstr(modlte_rsp.data, "+CFUN: 1")) { - lteppp_set_state(E_LTE_ATTACHING); - } else { - lteppp_set_state(E_LTE_IDLE); - } + attached = false; + } + } + lte_push_at_command("AT+CFUN?", LTE_RX_TIMEOUT_MIN_MS); + if (lteppp_get_state() == E_LTE_ATTACHING) { + // for some reason the modem has crashed, enabled the radios again... + if (!strstr(modlte_rsp.data, "+CFUN: 1")) { + lte_push_at_command("AT+CFUN=1", LTE_RX_TIMEOUT_MIN_MS); + } + } else { + if (strstr(modlte_rsp.data, "+CFUN: 1")) { + lteppp_set_state(E_LTE_ATTACHING); + } else { + lteppp_set_state(E_LTE_IDLE); } } } + if (attached && lteppp_get_state() < E_LTE_PPP) { + lteppp_set_state(E_LTE_ATTACHED); + } + //printf("This is our current LTE state: %d\n", lteppp_get_state()); + //printf("This is check_attached returning %d\n", attached); return attached; } +static bool lte_check_legacy_version(void) { + if (lte_push_at_command("ATI1", LTE_RX_TIMEOUT_MAX_MS)) { + return strstr(modlte_rsp.data, "LR5.1.1.0-33080"); + } else { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "LTE modem version not read")); + } + return true; +} + + static void lte_check_init(void) { if (!lte_obj.init) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "LTE modem not initialized")); @@ -195,6 +265,12 @@ static void lte_check_inppp(void) { } } +static void lte_check_connected(void) { + if (lteppp_get_state() == E_LTE_PPP) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "LTE modem is already connected!")); + } +} + static bool lte_check_sim_present(void) { lte_push_at_command("AT+CPIN?", LTE_RX_TIMEOUT_MAX_MS); if (strstr(modlte_rsp.data, "ERROR")) { @@ -204,70 +280,80 @@ static bool lte_check_sim_present(void) { } } -static void TASK_LTE_UPGRADE (void *pvParameters) { +static void TASK_LTE_UPGRADE(void *pvParameters){ - size_t len = 0; - uint8_t rx_buff[UART_TRANSFER_MAX_LEN]; - // Suspend All tasks - vTaskSuspend(mpTaskHandle); - vTaskSuspend(svTaskHandle); + size_t len = 0; + uint8_t rx_buff[UART_TRANSFER_MAX_LEN]; + // Suspend All tasks + vTaskSuspend(mpTaskHandle); + vTaskSuspend(svTaskHandle); #if defined(FIPY) - vTaskSuspend(xLoRaTaskHndl); - vTaskSuspend(xSigfoxTaskHndl); + vTaskSuspend(xLoRaTaskHndl); + vTaskSuspend(xSigfoxTaskHndl); +// vTaskSuspend(xMeshTaskHndl); #endif - vTaskSuspend(xLTETaskHndl); - - for(;;) - { - uart_get_buffered_data_len(0, &len); - - if(len) - { - if(len > UART_TRANSFER_MAX_LEN) - { - len = UART_TRANSFER_MAX_LEN; - } - uart_read_bytes(0,rx_buff,len,0); - uart_write_bytes(1,(char*)(rx_buff),len); - } - - len = 0; - uart_get_buffered_data_len(1, &len); - - if(len) - { - if(len > UART_TRANSFER_MAX_LEN) - { - len = UART_TRANSFER_MAX_LEN; - } - uart_read_bytes(1,rx_buff,len,0); - uart_write_bytes(0,(char*)(rx_buff),len); - } - } + vTaskSuspend(xLTETaskHndl); + + for (;;) { + uart_get_buffered_data_len(0, &len); + + if (len) { + if (len > UART_TRANSFER_MAX_LEN) { + len = UART_TRANSFER_MAX_LEN; + } + uart_read_bytes(0, rx_buff, len, 0); + uart_write_bytes(1, (char*) (rx_buff), len); + } + + len = 0; + uart_get_buffered_data_len(1, &len); + + if (len) { + if (len > UART_TRANSFER_MAX_LEN) { + len = UART_TRANSFER_MAX_LEN; + } + uart_read_bytes(1, rx_buff, len, 0); + uart_write_bytes(0, (char*) (rx_buff), len); + } + } } /******************************************************************************/ // Micro Python bindings; LTE class static mp_obj_t lte_init_helper(lte_obj_t *self, const mp_arg_val_t *args) { + //printf("This is lte_init_helper()\n"); char at_cmd[LTE_AT_CMD_SIZE_MAX - 4]; - + mod_network_register_nic(<e_obj); + connect_lte_uart(); // wake up the radio if (!lte_obj.init) { + //printf("lteppp_start()\n"); lteppp_start(); } else { - lte_deinit(self); + //printf("All done since we were already initialised.\n"); + return mp_const_none; } + vTaskDelay(1500); lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); - lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); + if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS)) { + lte_pause_ppp(); + } + // disable PSM if enabled by default + lte_push_at_command("AT+CPSMS?", LTE_RX_TIMEOUT_MAX_MS); + if (!strstr(modlte_rsp.data, "+CPSMS: 0")) { + lte_push_at_command("AT+CPSMS=0", LTE_RX_TIMEOUT_MIN_MS); + } + lte_push_at_command("AT!=\"setlpm airplane=1 enable=1\"", LTE_RX_TIMEOUT_MIN_MS); lte_push_at_command("AT+CFUN?", LTE_RX_TIMEOUT_MIN_MS); if (strstr(modlte_rsp.data, "+CFUN: 0")) { const char *carrier = "standard"; lte_obj.carrier = false; if (args[0].u_obj != mp_const_none) { carrier = mp_obj_str_get_str(args[0].u_obj); - if ((!strstr(carrier, "standard")) && (!strstr(carrier, "verizon")) && (!strstr(carrier, "at&t"))) { + lte_push_at_command("AT+SQNCTM=?", LTE_RX_TIMEOUT_MIN_MS); + if (!strstr(modlte_rsp.data, carrier)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid carrier %s", carrier)); } else if (!strstr(carrier, "standard")) { lte_obj.carrier = true; @@ -307,16 +393,15 @@ static mp_obj_t lte_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uin mp_arg_val_t args[MP_ARRAY_SIZE(lte_init_args)]; mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), lte_init_args, args); - if (!lteppp_is_modem_connected()) { - //Enable Lte modem connection - lteppp_connect_modem(); - } + if (!lteppp_is_modem_connected()) { + //Enable Lte modem connection + lteppp_connect_modem(); + } - while(!lteppp_is_modem_connected()) - { - //wait till modem is start-up - vTaskDelay(1/portTICK_PERIOD_MS); - } + while (!lteppp_is_modem_connected()) { + //wait till modem is start-up + vTaskDelay(1 / portTICK_PERIOD_MS); + } // setup the object lte_obj_t *self = <e_obj; @@ -341,37 +426,96 @@ STATIC mp_obj_t lte_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *k } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(lte_init_obj, 1, lte_init); -STATIC mp_obj_t lte_deinit(mp_obj_t self_in) { - lte_check_init(); - lte_obj_t *self = self_in; - if (lteppp_get_state() == E_LTE_PPP) { - lte_disconnect(self); - } +STATIC mp_obj_t lte_deinit(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - if (lte_check_sim_present()) { - if (!lte_push_at_command("AT+CFUN=4", LTE_RX_TIMEOUT_MAX_MS)) { - goto error; + STATIC const mp_arg_t allowed_args[] = { + { MP_QSTR_dettach, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true}}, + { MP_QSTR_reset, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false}}, + }; + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (lte_obj.init) { + lte_obj_t *self = (lte_obj_t*)pos_args[0]; + if (lteppp_get_state() == E_LTE_PPP && (lteppp_get_legacy() == E_LTE_LEGACY || args[0].u_bool)) { + lte_disconnect(self); + } else { + if (lteppp_get_state() == E_LTE_PPP) { + lte_suspend(self); + } + if (!args[0].u_bool) { + vTaskDelay(100); + lte_push_at_command("AT!=\"setlpm airplane=1 enable=1\"", LTE_RX_TIMEOUT_MAX_MS); + lteppp_deinit(); + lte_obj.init = false; + vTaskDelay(100); + return mp_const_none; + } } - } else { - if (!lte_push_at_command("AT+CFUN=0", LTE_RX_TIMEOUT_MAX_MS)) { - goto error; + + if (lte_check_sim_present()) { + if (args[1].u_bool) { + if (lte_push_at_command("AT+CFUN=4,1", LTE_RX_TIMEOUT_MAX_MS)) { + lteppp_wait_at_rsp("+S", LTE_RX_TIMEOUT_MAX_MS, true); + mp_hal_delay_ms(LTE_RX_TIMEOUT_MIN_MS); + if (!lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true)) { + lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true); + } + lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); + if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + } else { + lte_push_at_command("AT!=\"setlpm airplane=1 enable=1\"", LTE_RX_TIMEOUT_MAX_MS); + } + } + } else { + if (!lte_push_at_command("AT+CFUN=4", LTE_RX_TIMEOUT_MAX_MS)) { + goto error; + } + } + } else { + if (args[1].u_bool) { + if (lte_push_at_command("AT+CFUN=0,1", LTE_RX_TIMEOUT_MAX_MS)) { + lteppp_wait_at_rsp("+S", LTE_RX_TIMEOUT_MAX_MS, true); + mp_hal_delay_ms(LTE_RX_TIMEOUT_MIN_MS); + if (!lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true)) { + lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true); + } + lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); + if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + } else { + lte_push_at_command("AT!=\"setlpm airplane=1 enable=1\"", LTE_RX_TIMEOUT_MAX_MS); + } + } + } else { + if (!lte_push_at_command("AT+CFUN=0", LTE_RX_TIMEOUT_MAX_MS)) { + goto error; + } + } } + lte_obj.init = false; } - - lte_obj.init = false; lteppp_deinit(); + mod_network_deregister_nic(<e_obj); return mp_const_none; error: + lteppp_deinit(); nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_deinit_obj, lte_deinit); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(lte_deinit_obj, 1, lte_deinit); STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { lte_check_init(); STATIC const mp_arg_t allowed_args[] = { { MP_QSTR_band, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_apn, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_log, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_false} }, }; // parse args @@ -387,6 +531,8 @@ STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t if (!lte_obj.carrier) { lte_push_at_command("AT!=\"RRC::addScanBand band=3\"", LTE_RX_TIMEOUT_MIN_MS); lte_push_at_command("AT!=\"RRC::addScanBand band=4\"", LTE_RX_TIMEOUT_MIN_MS); + lte_push_at_command("AT!=\"RRC::addScanBand band=5\"", LTE_RX_TIMEOUT_MIN_MS); + lte_push_at_command("AT!=\"RRC::addScanBand band=8\"", LTE_RX_TIMEOUT_MIN_MS); lte_push_at_command("AT!=\"RRC::addScanBand band=12\"", LTE_RX_TIMEOUT_MIN_MS); lte_push_at_command("AT!=\"RRC::addScanBand band=13\"", LTE_RX_TIMEOUT_MIN_MS); lte_push_at_command("AT!=\"RRC::addScanBand band=20\"", LTE_RX_TIMEOUT_MIN_MS); @@ -398,6 +544,10 @@ STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t lte_push_at_command("AT!=\"RRC::addScanBand band=3\"", LTE_RX_TIMEOUT_MIN_MS); } else if (band == 4) { lte_push_at_command("AT!=\"RRC::addScanBand band=4\"", LTE_RX_TIMEOUT_MIN_MS); + } else if (band == 5) { + lte_push_at_command("AT!=\"RRC::addScanBand band=5\"", LTE_RX_TIMEOUT_MIN_MS); + } else if (band == 8) { + lte_push_at_command("AT!=\"RRC::addScanBand band=8\"", LTE_RX_TIMEOUT_MIN_MS); } else if (band == 12) { lte_push_at_command("AT!=\"RRC::addScanBand band=12\"", LTE_RX_TIMEOUT_MIN_MS); } else if (band == 13) { @@ -410,6 +560,17 @@ STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "band %d not supported", band)); } } + if (args[1].u_obj != mp_const_none) { + const char *apn = mp_obj_str_get_str(args[1].u_obj); + char at_cmd[LTE_AT_CMD_SIZE_MAX - 4]; + sprintf(at_cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn); + lte_push_at_command(at_cmd, LTE_RX_TIMEOUT_MIN_MS); + } + if (args[2].u_obj == mp_const_false) { + lte_push_at_command("AT!=\"disablelog 1\"", LTE_RX_TIMEOUT_MIN_MS); + } else { + lte_push_at_command("AT!=\"disablelog 0\"", LTE_RX_TIMEOUT_MIN_MS); + } lteppp_set_state(E_LTE_ATTACHING); if (!lte_push_at_command("AT+CFUN=1", LTE_RX_TIMEOUT_MAX_MS)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); @@ -419,19 +580,61 @@ STATIC mp_obj_t lte_attach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(lte_attach_obj, 1, lte_attach); -mp_obj_t lte_dettach(mp_obj_t self_in) { +mp_obj_t lte_dettach(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { lte_check_init(); - lte_obj_t *self = self_in; + + STATIC const mp_arg_t allowed_args[] = { + { MP_QSTR_reset, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false}}, + }; + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + lte_obj_t *self = (lte_obj_t*)pos_args[0]; + if (lteppp_get_state() == E_LTE_PPP) { lte_disconnect(self); } if (lte_check_sim_present()) { - if (!lte_push_at_command("AT+CFUN=4", LTE_RX_TIMEOUT_MAX_MS)) { - goto error; + if (args[0].u_bool) { + if (lte_push_at_command("AT+CFUN=4,1", LTE_RX_TIMEOUT_MAX_MS)) { + lteppp_wait_at_rsp("+S", LTE_RX_TIMEOUT_MAX_MS, true); + mp_hal_delay_ms(LTE_RX_TIMEOUT_MIN_MS); + if (!lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true)) { + lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true); + } + lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); + if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + } else { + lte_push_at_command("AT!=\"setlpm airplane=1 enable=1\"", LTE_RX_TIMEOUT_MAX_MS); + } + } + } else { + if (!lte_push_at_command("AT+CFUN=4", LTE_RX_TIMEOUT_MAX_MS)) { + goto error; + } } } else { - if (!lte_push_at_command("AT+CFUN=0", LTE_RX_TIMEOUT_MAX_MS)) { - goto error; + if (args[0].u_bool) { + if (lte_push_at_command("AT+CFUN=0,1", LTE_RX_TIMEOUT_MAX_MS)) { + lteppp_wait_at_rsp("+S", LTE_RX_TIMEOUT_MAX_MS, true); + mp_hal_delay_ms(LTE_RX_TIMEOUT_MIN_MS); + if (!lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true)) { + lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true); + } + lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); + if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + } else { + lte_push_at_command("AT!=\"setlpm airplane=1 enable=1\"", LTE_RX_TIMEOUT_MAX_MS); + } + } + } else { + if (!lte_push_at_command("AT+CFUN=0", LTE_RX_TIMEOUT_MAX_MS)) { + goto error; + } } } lteppp_set_state(E_LTE_IDLE); @@ -439,8 +642,36 @@ mp_obj_t lte_dettach(mp_obj_t self_in) { error: nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_dettach_obj, lte_dettach); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(lte_dettach_obj, 1, lte_dettach); + +STATIC mp_obj_t lte_suspend(mp_obj_t self_in) { + + if (lteppp_get_legacy() == E_LTE_LEGACY) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "modem firmware not supported")); + } + lte_check_init(); + if (lteppp_get_state() == E_LTE_PPP) { + //printf("Pausing ppp...\n"); + lte_pause_ppp(); + //printf("Pausing ppp done...\n"); + lteppp_set_state(E_LTE_SUSPENDED); + while (true) { + mp_hal_delay_ms(LTE_RX_TIMEOUT_MIN_MS); + //printf("Sending AT...\n"); + if (lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS)) { + //printf("OK\n"); + break; + } + } + lte_check_attached(); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_suspend_obj, lte_suspend); + + STATIC mp_obj_t lte_isattached(mp_obj_t self_in) { lte_check_init(); @@ -453,27 +684,85 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_isattached_obj, lte_isattached); STATIC mp_obj_t lte_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { lte_check_init(); + lte_check_connected(); STATIC const mp_arg_t allowed_args[] = { { MP_QSTR_cid, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + { MP_QSTR_legacy, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_obj = mp_const_none} }, + }; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + if (args[1].u_obj == mp_const_none) { + args[1].u_bool = lte_check_legacy_version(); + } + lte_check_attached(); + lteppp_set_legacy(args[1].u_bool); + + if (args[1].u_bool) { + lte_push_at_command("ATH", LTE_RX_TIMEOUT_MIN_MS); + while (true) { + mp_hal_delay_ms(LTE_RX_TIMEOUT_MIN_MS); + if (lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS)) { + break; + } + } + } + + if (lteppp_get_state() == E_LTE_ATTACHED || (args[1].u_bool && lteppp_get_state() == E_LTE_SUSPENDED)) { + if (args[1].u_bool || !lte_push_at_command_ext("ATO", LTE_RX_TIMEOUT_MAX_MS, LTE_CONNECT_RSP)) { + char at_cmd[LTE_AT_CMD_SIZE_MAX - 4]; + lte_obj.cid = args[0].u_int; + sprintf(at_cmd, "AT+CGDATA=\"PPP\",%d", lte_obj.cid); + // set the PPP state in advance, to avoid CEREG? to be sent right after PPP is entered + if (!lte_push_at_command_ext(at_cmd, LTE_RX_TIMEOUT_MAX_MS, LTE_CONNECT_RSP)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + } + } + lteppp_connect(); + lteppp_set_state(E_LTE_PPP); + vTaskDelay(1000); + } else if (lteppp_get_state() == E_LTE_PPP) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "modem already connected")); + } else if (lteppp_get_state() == E_LTE_SUSPENDED) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "modem is suspended")); + } else { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "modem not attached")); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(lte_connect_obj, 1, lte_connect); + +STATIC mp_obj_t lte_resume(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + lte_check_init(); + STATIC const mp_arg_t allowed_args[] = { + { MP_QSTR_cid, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + }; + + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if (lteppp_get_state() == E_LTE_ATTACHED) { - char at_cmd[LTE_AT_CMD_SIZE_MAX - 4]; + if (lteppp_get_state() == E_LTE_PPP) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } + lte_check_attached(); + + if (lteppp_get_state() == E_LTE_SUSPENDED || lteppp_get_state() == E_LTE_ATTACHED) { + if (lteppp_get_state() == E_LTE_ATTACHED && lteppp_get_legacy() == E_LTE_LEGACY) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } +// char at_cmd[LTE_AT_CMD_SIZE_MAX - 4]; lte_obj.cid = args[0].u_int; - sprintf(at_cmd, "AT+CGDATA=\"PPP\",%d", lte_obj.cid); - // set the PPP state in advance, to avoid CEREG? to be sent right after PPP is entered - if (lte_push_at_command_ext(at_cmd, LTE_RX_TIMEOUT_MAX_MS, LTE_CONNECT_RSP)) { + if (lte_push_at_command_ext("ATO", LTE_RX_TIMEOUT_MAX_MS, LTE_CONNECT_RSP)) { lteppp_connect(); lteppp_set_state(E_LTE_PPP); - vTaskDelay(750); + vTaskDelay(1500); } else { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable)); } } else if (lteppp_get_state() == E_LTE_PPP) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "modem already connected")); @@ -482,18 +771,20 @@ STATIC mp_obj_t lte_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(lte_connect_obj, 1, lte_connect); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(lte_resume_obj, 1, lte_resume); STATIC mp_obj_t lte_disconnect(mp_obj_t self_in) { lte_check_init(); - if (lteppp_get_state() == E_LTE_PPP) { + if (lteppp_get_state() == E_LTE_PPP || lteppp_get_state() == E_LTE_SUSPENDED) { lteppp_disconnect(); - lte_pause_ppp(); + if (lteppp_get_state() == E_LTE_PPP) { + lte_pause_ppp(); + } lteppp_set_state(E_LTE_ATTACHED); lte_push_at_command("ATH", LTE_RX_TIMEOUT_MIN_MS); while (true) { mp_hal_delay_ms(LTE_RX_TIMEOUT_MIN_MS); - if (lte_push_at_command("AT", LTE_RX_TIMEOUT_MIN_MS)) { + if (lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS)) { break; } } @@ -505,10 +796,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_disconnect_obj, lte_disconnect); STATIC mp_obj_t lte_isconnected(mp_obj_t self_in) { lte_check_init(); - if (lteppp_get_state() == E_LTE_PPP && lteppp_ipv4() > 0) { + if (ltepp_is_ppp_conn_up()) { return mp_const_true; } - return mp_const_false; + else + { + return mp_const_false; + } } STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_isconnected_obj, lte_isconnected); @@ -522,24 +816,83 @@ STATIC mp_obj_t lte_send_raw_at(mp_obj_t self_in, mp_obj_t cmd_o) { strcpy(vstr.buf, modlte_rsp.data); return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(lte_send_raw_at_obj, lte_send_raw_at); +//STATIC MP_DEFINE_CONST_FUN_OBJ_2(lte_send_raw_at_obj, lte_send_raw_at); + +STATIC mp_obj_t lte_send_at_cmd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + lte_check_init(); + lte_check_inppp(); + STATIC const mp_arg_t allowed_args[] = { + { MP_QSTR_cmd, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_delay, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + }; + // parse args + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + if (args[0].u_obj == mp_const_none) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "the command must be specified!")); + } + const char *cmd = mp_obj_str_get_str(args[0].u_obj); + lte_push_at_command_delay((char *)cmd, LTE_RX_TIMEOUT_MAX_MS, args[1].u_int); + vstr_t vstr; + vstr_init_len(&vstr, strlen(modlte_rsp.data)); + strcpy(vstr.buf, modlte_rsp.data); + return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(lte_send_at_cmd_obj, 1, lte_send_at_cmd); + STATIC mp_obj_t lte_imei(mp_obj_t self_in) { + lte_check_init(); + lte_check_inppp(); char *pos; vstr_t vstr; + char *resp; vstr_init_len(&vstr, strlen("AT+CGSN")); strcpy(vstr.buf, "AT+CGSN"); lte_send_raw_at(MP_OBJ_NULL, mp_obj_new_str_from_vstr(&mp_type_str, &vstr)); - if ((pos = strstr(modlte_rsp.data, "35434")) && (strlen(pos) > 20)) { + resp = modlte_rsp.data; + if (strcmp(resp, "000000000000000") == 0) { + vstr_init_len(&vstr, 5); + memcpy(vstr.buf, "UNSET", 5); + return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + } + if ((pos = strstr(resp, "35434")) && (strlen(pos) > 20)) { vstr_init_len(&vstr, 15); memcpy(vstr.buf, pos, 15); return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); } + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_imei_obj, lte_imei); +STATIC mp_obj_t lte_time(mp_obj_t self_in) { + lte_check_init(); + lte_check_inppp(); + char *pos; + vstr_t vstr; + char *resp; + vstr_init_len(&vstr, strlen("AT+CCLK?")); + strcpy(vstr.buf, "AT+CCLK?"); + lte_send_raw_at(MP_OBJ_NULL, mp_obj_new_str_from_vstr(&mp_type_str, &vstr)); + resp = modlte_rsp.data; + if ((pos = strstr(resp, "+CCLK:")) && (strlen(pos) > 20)) { + char *start_pos; + char *end_pos; + start_pos = strstr(pos,"\""); + end_pos = strstr(pos,"\r\n"); + vstr_init_len(&vstr, strlen(start_pos) - strlen(end_pos) - 2); + memcpy(vstr.buf, &start_pos[1], strlen(pos) - strlen(end_pos) - 2); + return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_time_obj, lte_time); + STATIC mp_obj_t lte_iccid(mp_obj_t self_in) { + lte_check_init(); + lte_check_inppp(); char *pos; vstr_t vstr; vstr_init_len(&vstr, strlen("AT+SQNCCID?")); @@ -557,11 +910,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(lte_iccid_obj, lte_iccid); STATIC mp_obj_t lte_reset(mp_obj_t self_in) { lte_check_init(); lte_disconnect(self_in); - lte_push_at_command("AT^RESET", LTE_RX_TIMEOUT_MIN_MS); + lte_push_at_command("AT^RESET", LTE_RX_TIMEOUT_MAX_MS); lteppp_set_state(E_LTE_IDLE); mp_hal_delay_ms(LTE_RX_TIMEOUT_MIN_MS); - lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true); - if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MIN_MS)) { + if (!lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true)) { + lteppp_wait_at_rsp("+SYSSTART", LTE_RX_TIMEOUT_MAX_MS, true); + } + lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS); + if (!lte_push_at_command("AT", LTE_RX_TIMEOUT_MAX_MS)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); } return mp_const_none; @@ -572,12 +928,14 @@ STATIC mp_obj_t lte_upgrade_mode(void) { if(lte_obj.init) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Modem not disabled")); + //nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Modem not disabled")); + lte_obj.init = false; } // uninstall the driver uart_driver_delete(0); uart_driver_delete(1); + uart_driver_delete(2); // initialize the UART interface lte_uart_config1.baud_rate = MICROPY_LTE_UART_BAUDRATE; @@ -608,7 +966,7 @@ STATIC mp_obj_t lte_upgrade_mode(void) { pin_config(MICROPY_LTE_CTS_PIN, U1CTS_IN_IDX, -1, GPIO_MODE_INPUT, MACHPIN_PULL_NONE, 1); // install the UART driver - uart_driver_install(1, LTE_UART_BUFFER_SIZE, 4096, 0, NULL, 0, NULL); + uart_driver_install(1, 8192, 8192, 0, NULL, 0, NULL); uart_driver_lte = &UART1; // disable the delay between transfers @@ -619,19 +977,19 @@ STATIC mp_obj_t lte_upgrade_mode(void) { lte_uart_config0.baud_rate = MICROPY_LTE_UART_BAUDRATE; - lte_uart_config0.data_bits = UART_DATA_8_BITS; - lte_uart_config0.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; - lte_uart_config0.parity = UART_PARITY_DISABLE; - lte_uart_config0.rx_flow_ctrl_thresh = 64; - lte_uart_config0.stop_bits = 1.0; + lte_uart_config0.data_bits = UART_DATA_8_BITS; + lte_uart_config0.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; + lte_uart_config0.parity = UART_PARITY_DISABLE; + lte_uart_config0.rx_flow_ctrl_thresh = 64; + lte_uart_config0.stop_bits = 1.0; - uart_param_config(0, <e_uart_config0); + uart_param_config(0, <e_uart_config0); pin_config(&PIN_MODULE_P1, -1, U0TXD_OUT_IDX, GPIO_MODE_OUTPUT, MACHPIN_PULL_NONE, 1); pin_config(&PIN_MODULE_P0, U0RXD_IN_IDX, -1, GPIO_MODE_INPUT, MACHPIN_PULL_NONE, 1); // install the UART driver - uart_driver_install(0, LTE_UART_BUFFER_SIZE, 4096, 0, NULL, 0, NULL); + uart_driver_install(0, 8192, 8192, 0, NULL, 0, NULL); // disable the delay between transfers uart_driver_0->idle_conf.tx_idle_num = 0; @@ -645,6 +1003,14 @@ STATIC mp_obj_t lte_upgrade_mode(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(lte_upgrade_mode_obj, lte_upgrade_mode); +STATIC mp_obj_t lte_reconnect_uart (void) { + connect_lte_uart(); + lteppp_disconnect(); + lte_obj.init = false; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(lte_reconnect_uart_obj, lte_reconnect_uart); + STATIC const mp_map_elem_t lte_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)<e_init_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)<e_deinit_obj }, @@ -653,12 +1019,16 @@ STATIC const mp_map_elem_t lte_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_isattached), (mp_obj_t)<e_isattached_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)<e_connect_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_disconnect), (mp_obj_t)<e_disconnect_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_pppsuspend), (mp_obj_t)<e_suspend_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_pppresume), (mp_obj_t)<e_resume_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)<e_time_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_isconnected), (mp_obj_t)<e_isconnected_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_imei), (mp_obj_t)<e_imei_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_iccid), (mp_obj_t)<e_iccid_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_send_at_cmd), (mp_obj_t)<e_send_raw_at_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_send_at_cmd), (mp_obj_t)<e_send_at_cmd_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)<e_reset_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_modem_upgrade_mode), (mp_obj_t)<e_upgrade_mode_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_modem_upgrade_mode), (mp_obj_t)<e_upgrade_mode_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_reconnect_uart), (mp_obj_t)<e_reconnect_uart_obj }, // class constants }; @@ -686,4 +1056,5 @@ const mod_network_nic_type_t mod_network_nic_type_lte = { .n_setsockopt = lwipsocket_socket_setsockopt, .n_bind = lwipsocket_socket_bind, .n_ioctl = lwipsocket_socket_ioctl, + .inf_up = ltepp_is_ppp_conn_up, }; diff --git a/esp32/mods/modmachine.c b/esp32/mods/modmachine.c index 8959bf1470..4ef1eaed2b 100644 --- a/esp32/mods/modmachine.c +++ b/esp32/mods/modmachine.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence @@ -191,7 +191,7 @@ STATIC mp_obj_t machine_deepsleep (uint n_args, const mp_obj_t *arg) { bt_deinit(NULL); wlan_deinit(NULL); #if defined(FIPY) || defined(GPY) - while (!lteppp_task_ready()) { + while (config_get_lte_modem_enable_on_boot() && !lteppp_task_ready()) { mp_hal_delay_ms(2); } lteppp_deinit(); diff --git a/esp32/mods/modmachine.h b/esp32/mods/modmachine.h index 4ae5ca846e..85663f2745 100644 --- a/esp32/mods/modmachine.h +++ b/esp32/mods/modmachine.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/mods/modnetwork.c b/esp32/mods/modnetwork.c index 5ca4ec4918..d4bfc8c8bf 100644 --- a/esp32/mods/modnetwork.c +++ b/esp32/mods/modnetwork.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence @@ -83,6 +83,14 @@ void mod_network_register_nic(mp_obj_t nic) { mp_obj_list_append(&MP_STATE_PORT(mod_network_nic_list), nic); } +void mod_network_deregister_nic(mp_obj_t nic) { + for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { + if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) { + mp_obj_list_remove(&MP_STATE_PORT(mod_network_nic_list), nic); + } + } +} + mp_obj_t mod_network_find_nic(const mod_network_socket_obj_t *s, const uint8_t *ip) { // find a NIC that is suited to a given IP address for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { diff --git a/esp32/mods/modnetwork.h b/esp32/mods/modnetwork.h index 33f7676ecf..511b1017d6 100644 --- a/esp32/mods/modnetwork.h +++ b/esp32/mods/modnetwork.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence @@ -70,6 +70,9 @@ typedef struct _mod_network_nic_type_t { int (*n_setsockopt)(struct _mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno); int (*n_settimeout)(struct _mod_network_socket_obj_t *socket, mp_int_t timeout_ms, int *_errno); int (*n_ioctl)(struct _mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno); + + // Interface status + bool (*inf_up)(void); } mod_network_nic_type_t; typedef struct _mod_network_socket_base_t { @@ -108,6 +111,7 @@ extern const mod_network_nic_type_t mod_network_nic_type_lte; ******************************************************************************/ void mod_network_init0(void); void mod_network_register_nic(mp_obj_t nic); +void mod_network_deregister_nic(mp_obj_t nic); mp_obj_t mod_network_find_nic(const mod_network_socket_obj_t *s, const uint8_t *ip); #endif // MODNETWORK_H_ diff --git a/esp32/mods/modpycom.c b/esp32/mods/modpycom.c index c85db88be0..c441e1d091 100644 --- a/esp32/mods/modpycom.c +++ b/esp32/mods/modpycom.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/modsigfox_api.c b/esp32/mods/modsigfox_api.c index 2d2fc8f007..2bc928c88a 100644 --- a/esp32/mods/modsigfox_api.c +++ b/esp32/mods/modsigfox_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/moducrypto.c b/esp32/mods/moducrypto.c index 5d1c91624c..f36b4f4462 100644 --- a/esp32/mods/moducrypto.c +++ b/esp32/mods/moducrypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/moduhashlib.c b/esp32/mods/moduhashlib.c index 538f5db2d8..27f2d028c8 100644 --- a/esp32/mods/moduhashlib.c +++ b/esp32/mods/moduhashlib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/moduos.c b/esp32/mods/moduos.c index e52ad07b6d..7842be1634 100644 --- a/esp32/mods/moduos.c +++ b/esp32/mods/moduos.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/mods/moduos.h b/esp32/mods/moduos.h index 7ef9155425..d9891e7caf 100644 --- a/esp32/mods/moduos.h +++ b/esp32/mods/moduos.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/mods/moduqueue.c b/esp32/mods/moduqueue.c index 4ea9bde421..3ddc73ec81 100644 --- a/esp32/mods/moduqueue.c +++ b/esp32/mods/moduqueue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/moduqueue.h b/esp32/mods/moduqueue.h index d5b4e17ffa..03800491f9 100644 --- a/esp32/mods/moduqueue.h +++ b/esp32/mods/moduqueue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/moduselect.c b/esp32/mods/moduselect.c index bbd6950760..1a4be80ea4 100644 --- a/esp32/mods/moduselect.c +++ b/esp32/mods/moduselect.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/mods/modusocket.c b/esp32/mods/modusocket.c index c4b297d2d7..6bbc72b1bc 100644 --- a/esp32/mods/modusocket.c +++ b/esp32/mods/modusocket.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence @@ -650,30 +650,47 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) { mp_uint_t hlen; const char *host = mp_obj_str_get_data(host_in, &hlen); mp_int_t port = mp_obj_get_int(port_in); + bool is_inf_down = false; // find a nic that can do a name lookup for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) { mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i]; mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic); - if (nic_type->n_gethostbyname != NULL) { - // ipv4 only - uint8_t out_ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE]; - int32_t result = nic_type->n_gethostbyname(host, hlen, out_ip, AF_INET); - if (result < 0) { - // negate result as it contains the error code which must be positive - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-result))); - } - mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL); - tuple->items[0] = MP_OBJ_NEW_SMALL_INT(AF_INET); - tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SOCK_STREAM); - tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); - tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_); - tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG); - return mp_obj_new_list(1, (mp_obj_t*)&tuple); + if (nic_type->n_gethostbyname != NULL && nic_type->inf_up != NULL) + { + if (nic_type->inf_up()) { + + is_inf_down = false; + // ipv4 only + uint8_t out_ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE]; + int32_t result = nic_type->n_gethostbyname(host, hlen, out_ip, AF_INET); + if (result < 0) { + // negate result as it contains the error code which must be positive + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-result))); + } + mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL); + tuple->items[0] = MP_OBJ_NEW_SMALL_INT(AF_INET); + tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SOCK_STREAM); + tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); + tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_); + tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG); + return mp_obj_new_list(1, (mp_obj_t*)&tuple); + } + else + { + is_inf_down = true; + continue; + } } } - - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC")); + if(is_inf_down) + { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Avialable Interfaces are down")); + } + else + { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC")); + } } STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo); diff --git a/esp32/mods/modusocket.h b/esp32/mods/modusocket.h index e7965a358d..c932af1f98 100644 --- a/esp32/mods/modusocket.h +++ b/esp32/mods/modusocket.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/mods/modussl.c b/esp32/mods/modussl.c index 18a0e5ea89..5bd0f1c57e 100644 --- a/esp32/mods/modussl.c +++ b/esp32/mods/modussl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/modussl.h b/esp32/mods/modussl.h index 3b45daea10..c157cd4dc2 100644 --- a/esp32/mods/modussl.h +++ b/esp32/mods/modussl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/modutime.c b/esp32/mods/modutime.c index 9cb4149cfb..f8ce6ee7d6 100644 --- a/esp32/mods/modutime.c +++ b/esp32/mods/modutime.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/mods/modwlan.c b/esp32/mods/modwlan.c index ff5563823f..d71063cd09 100644 --- a/esp32/mods/modwlan.c +++ b/esp32/mods/modwlan.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information @@ -119,6 +119,8 @@ static EventGroupHandle_t wifi_event_group; // Event bits const int CONNECTED_BIT = BIT0; +STATIC bool is_inf_up = false; + /****************************************************************************** DECLARE PUBLIC DATA ******************************************************************************/ @@ -239,6 +241,11 @@ void wlan_off_on (void) { // DEFINE STATIC FUNCTIONS //***************************************************************************** +STATIC bool wlan_is_inf_up(void) +{ + return is_inf_up; +} + STATIC esp_err_t wlan_event_handler(void *ctx, system_event_t *event) { switch(event->event_id) { case SYSTEM_EVENT_STA_START: @@ -253,10 +260,12 @@ STATIC esp_err_t wlan_event_handler(void *ctx, system_event_t *event) { break; case SYSTEM_EVENT_STA_GOT_IP: xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + is_inf_up = true; break; case SYSTEM_EVENT_STA_DISCONNECTED: xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); system_event_sta_disconnected_t *disconn = &event->event_info.disconnected; + is_inf_up = false; switch (disconn->reason) { case WIFI_REASON_AUTH_FAIL: wlan_obj.disconnected = true; @@ -725,6 +734,7 @@ mp_obj_t wlan_deinit(mp_obj_t self_in) { if (wlan_obj.started) { esp_wifi_stop(); wlan_obj.started = false; + mod_network_deregister_nic(&wlan_obj); } return mp_const_none; } @@ -1188,6 +1198,7 @@ const mod_network_nic_type_t mod_network_nic_type_wlan = { .n_setsockopt = lwipsocket_socket_setsockopt, .n_settimeout = lwipsocket_socket_settimeout, .n_ioctl = lwipsocket_socket_ioctl, + .inf_up = wlan_is_inf_up }; //STATIC const mp_irq_methods_t wlan_irq_methods = { diff --git a/esp32/mods/modwlan.h b/esp32/mods/modwlan.h index d22f0a0214..d6a87afdaf 100644 --- a/esp32/mods/modwlan.h +++ b/esp32/mods/modwlan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/pybadc.c b/esp32/mods/pybadc.c index 3230bf1666..9737119c56 100644 --- a/esp32/mods/pybadc.c +++ b/esp32/mods/pybadc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/pybadc.h b/esp32/mods/pybadc.h index 32d45e6846..b23d50dbdc 100644 --- a/esp32/mods/pybadc.h +++ b/esp32/mods/pybadc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/pybdac.c b/esp32/mods/pybdac.c index 01ae286354..cb4b2cd3ad 100644 --- a/esp32/mods/pybdac.c +++ b/esp32/mods/pybdac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/pybdac.h b/esp32/mods/pybdac.h index 1d593d1c56..89e1f61dcf 100644 --- a/esp32/mods/pybdac.h +++ b/esp32/mods/pybdac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/pybsd.c b/esp32/mods/pybsd.c index 619a4df202..fbf5612dcd 100644 --- a/esp32/mods/pybsd.c +++ b/esp32/mods/pybsd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mods/pybsd.h b/esp32/mods/pybsd.h index c67ecbaf29..909d94f66e 100644 --- a/esp32/mods/pybsd.h +++ b/esp32/mods/pybsd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mpconfigport.h b/esp32/mpconfigport.h index 1c6d326457..5ed95fd22d 100644 --- a/esp32/mpconfigport.h +++ b/esp32/mpconfigport.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/mptask.c b/esp32/mptask.c index e1e0d72aaa..8765462068 100644 --- a/esp32/mptask.c +++ b/esp32/mptask.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mptask.h b/esp32/mptask.h index 21e1d00cea..31ed0472a5 100644 --- a/esp32/mptask.h +++ b/esp32/mptask.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/mpthreadport.c b/esp32/mpthreadport.c index c8004eabe1..0fabea0623 100644 --- a/esp32/mpthreadport.c +++ b/esp32/mpthreadport.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence @@ -50,6 +50,10 @@ #include "freertos/semphr.h" #include "freertos/queue.h" +#include "py/gc.h" + +#include "mpirq.h" + #if MICROPY_PY_THREAD #define MP_THREAD_MIN_STACK_SIZE (5 * 1024) @@ -243,7 +247,7 @@ void vPortCleanUpTCB (void *tcb) { mp_obj_thread_lock_t *mp_thread_new_thread_lock(void) { mp_obj_thread_lock_t *self = m_new_obj(mp_obj_thread_lock_t); - self->mutex = heap_caps_malloc(sizeof(mp_thread_mutex_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + self->mutex = gc_alloc(sizeof(mp_thread_mutex_t), false); if (NULL == self->mutex) { nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError, "can't create lock")); } diff --git a/esp32/mpthreadport.h b/esp32/mpthreadport.h index 9a070cc8cf..142452be51 100644 --- a/esp32/mpthreadport.h +++ b/esp32/mpthreadport.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/pycom_config.c b/esp32/pycom_config.c index d7f19492f8..8e1c7ab411 100644 --- a/esp32/pycom_config.c +++ b/esp32/pycom_config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/pycom_config.h b/esp32/pycom_config.h index de6d55a419..4f8c2ec698 100644 --- a/esp32/pycom_config.h +++ b/esp32/pycom_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/pycom_version.h b/esp32/pycom_version.h index f2bb437140..dea2fa4d3b 100644 --- a/esp32/pycom_version.h +++ b/esp32/pycom_version.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information @@ -10,7 +10,7 @@ #ifndef VERSION_H_ #define VERSION_H_ -#define SW_VERSION_NUMBER "1.18.1.r1" +#define SW_VERSION_NUMBER "1.18.1.r7" #define LORAWAN_VERSION_NUMBER "1.0.2" diff --git a/esp32/qstrdefsport.h b/esp32/qstrdefsport.h index 68aef976d0..89c2fe3f08 100644 --- a/esp32/qstrdefsport.h +++ b/esp32/qstrdefsport.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/serverstask.c b/esp32/serverstask.c index de321ebbf7..c0fd827ece 100644 --- a/esp32/serverstask.c +++ b/esp32/serverstask.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/serverstask.h b/esp32/serverstask.h index 2fd59ca44a..f050e9a763 100644 --- a/esp32/serverstask.h +++ b/esp32/serverstask.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/sigfox/modsigfox.h b/esp32/sigfox/modsigfox.h index 31ccbcfcd1..e95058326f 100644 --- a/esp32/sigfox/modsigfox.h +++ b/esp32/sigfox/modsigfox.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/telnet/telnet.c b/esp32/telnet/telnet.c index aebd6c6d05..ee88f695da 100644 --- a/esp32/telnet/telnet.c +++ b/esp32/telnet/telnet.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information @@ -534,10 +534,10 @@ static void telnet_parse_input (uint8_t *str, int32_t *len) { // in this case the server is not operating in binary mode if (ch > 127 || ch == 0 || (telnet_data.state == E_TELNET_STE_LOGGED_IN && - (ch == mp_interrupt_char || ch == CHAR_CTRL_F))) { + (ch == mp_interrupt_char || ch == mp_reset_char))) { if (ch == mp_interrupt_char) { mp_keyboard_interrupt(); - } else if (ch == CHAR_CTRL_F) { + } else if (ch == mp_reset_char) { *str++ = CHAR_CTRL_D; mp_hal_reset_safe_and_boot(false); _str++; diff --git a/esp32/telnet/telnet.h b/esp32/telnet/telnet.h index c0632d1cd3..e256397645 100644 --- a/esp32/telnet/telnet.h +++ b/esp32/telnet/telnet.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/tools/appsign.sh b/esp32/tools/appsign.sh index fd1977efed..d031d2f2ba 100644 --- a/esp32/tools/appsign.sh +++ b/esp32/tools/appsign.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/flasher.py b/esp32/tools/flasher.py index c1f6c17190..88b9739b1e 100644 --- a/esp32/tools/flasher.py +++ b/esp32/tools/flasher.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/lopy_final_test_board_script.py b/esp32/tools/lopy_final_test_board_script.py index 3cf7362104..7188f22da3 100644 --- a/esp32/tools/lopy_final_test_board_script.py +++ b/esp32/tools/lopy_final_test_board_script.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/lopy_initial_test_board_script.py b/esp32/tools/lopy_initial_test_board_script.py index 878421141b..51cfb2773b 100644 --- a/esp32/tools/lopy_initial_test_board_script.py +++ b/esp32/tools/lopy_initial_test_board_script.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/lopy_qa_test_board_script.py b/esp32/tools/lopy_qa_test_board_script.py index 25798f7d95..85f4649a19 100644 --- a/esp32/tools/lopy_qa_test_board_script.py +++ b/esp32/tools/lopy_qa_test_board_script.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/lora/actility/actility.py b/esp32/tools/lora/actility/actility.py index a5b23229e8..1c4525585f 100644 --- a/esp32/tools/lora/actility/actility.py +++ b/esp32/tools/lora/actility/actility.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/lora/certification/certification.py b/esp32/tools/lora/certification/certification.py index 08f2a645d3..97bc54a574 100644 --- a/esp32/tools/lora/certification/certification.py +++ b/esp32/tools/lora/certification/certification.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information @@ -13,6 +13,7 @@ import binascii import socket import struct +import machine APP_EUI = 'AD A4 DA E3 AC 12 67 6B' @@ -37,21 +38,32 @@ def __init__(self, activation=LoRa.OTAA): def _join(self): if self.activation == LoRa.OTAA: - app_eui = binascii.unhexlify(APP_EUI.replace(' ','')) - app_key = binascii.unhexlify(APP_KEY.replace(' ','')) - self.lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) + dev_eui = binascii.unhexlify(DEV_EUI.replace(' ', '')) + app_eui = binascii.unhexlify(APP_EUI.replace(' ', '')) + app_key = binascii.unhexlify(APP_KEY.replace(' ', '')) + self.lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) else: - dev_addr = struct.unpack(">l", binascii.unhexlify(DEV_ADDR.replace(' ','')))[0] - nwk_swkey = binascii.unhexlify(NWK_SWKEY.replace(' ','')) - app_swkey = binascii.unhexlify(APP_SWKEY.replace(' ','')) + dev_addr = struct.unpack('>l', binascii.unhexlify(DEV_ADDR.replace(' ', '')))[0] + nwk_swkey = binascii.unhexlify(NWK_SWKEY.replace(' ', '')) + app_swkey = binascii.unhexlify(APP_SWKEY.replace(' ', '')) self.lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey)) # wait until the module has joined the network + print('Joining.', end='', flush=True) + time.sleep(0.1) while not self.lora.has_joined(): time.sleep(5) print("Joining...") - print("Network joined!") + print('') + print('Network joined!') + + self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) + self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, 2) + self.s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, False) + self.s.setblocking(True) + + print('Waiting for test activation...') def run(self): while True: @@ -67,8 +79,8 @@ def run(self): self.lora.compliance_test().downlink_counter & 0xFF]) while self.lora.compliance_test().running: - - if self.lora.compliance_test().state < 6: # re-join + # re-join + if self.lora.compliance_test().state < 6: try: self.s.send(self.tx_payload) time.sleep(2) @@ -92,5 +104,17 @@ def run(self): self.tx_payload = bytes([(self.lora.compliance_test().downlink_counter >> 8) & 0xFF, self.lora.compliance_test().downlink_counter & 0xFF]) else: - time.sleep(2) + self.rejoined = True + time.sleep(3.5) self._join() + + # The test has been disabled, send one more message in order to signal that test mode + # has been deactivated and then wait a few seconds before trying to join again + time.sleep(3) + self.s.send(ACTIVATE_MSG) + if self.activation == LoRa.OTAA: + time.sleep(3) + else: + time.sleep(5) + if not self.rejoined: + machine.deepsleep(1000) diff --git a/esp32/tools/lora/certification/main.py b/esp32/tools/lora/certification/main.py index 7acad3d994..147f254946 100644 --- a/esp32/tools/lora/certification/main.py +++ b/esp32/tools/lora/certification/main.py @@ -1,8 +1,88 @@ import time from network import LoRa from certification import Compliance +import pycom +import machine +import os + +# disable WiFi +if pycom.wifi_on_boot(): + pycom.wifi_on_boot(False) + +# disable LTE +try: + if 'FiPy' in os.uname().machine: + from network import LTE + LTE().deinit() +except: + pass time.sleep(5) -compliance = Compliance(activation=LoRa.OTAA) +regions_str = ['EU868', 'AS923', 'US915', 'AU915'] +activations_str = ['OTAA', 'ABP'] + +region = None +activation = None + +region_in = -1 +activation_in = -1 + +print('<<< Device ready for LoRaWAN certification testing >>>') + +if machine.reset_cause() == machine.DEEPSLEEP_RESET: + region_in = pycom.nvs_get('cert_region') + activation_in = pycom.nvs_get('cert_activation') + +if region_in < 0 or activation_in < 0: + print('Press ENTER to continue') + print('') + input() + + while True: + print('Please select the region:') + print(' (1) EU868') + print(' (2) AS923') + print(' (3) US915') + print(' (4) AU915') + + try: + region_in = int(input()) - 1 + except Exception: + region_in = -1 + + if region_in >= 0: + try: + region = regions[region_in] + break + except Exception: + pass + + while True: + print('Please select an activation method:') + print(' (1) OTAA') + print(' (2) ABP') + + try: + activation_in = int(input()) - 1 + except Exception: + activation_in = -1 + + if activation_in >= 0: + try: + activation = activations[activation_in] + break + except Exception: + pass + + pycom.nvs_set('cert_region', region_in) + pycom.nvs_set('cert_activation', activation_in) +else: + region = regions[region_in] + activation = activations[activation_in] + +print('<<< Certification test started for region {} using {} >>>'.format(regions_str[region_in], activations_str[activation_in])) +print('') + +compliance = Compliance(region=region, activation=activation) compliance.run() diff --git a/esp32/tools/run_final_lopy_test.py b/esp32/tools/run_final_lopy_test.py index dc8e1fb115..4374f7e164 100644 --- a/esp32/tools/run_final_lopy_test.py +++ b/esp32/tools/run_final_lopy_test.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/run_initial_lopy_test.py b/esp32/tools/run_initial_lopy_test.py index 1c8970a1a8..ce5cb47cd6 100644 --- a/esp32/tools/run_initial_lopy_test.py +++ b/esp32/tools/run_initial_lopy_test.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/run_initial_wipy_test.py b/esp32/tools/run_initial_wipy_test.py index d89c2ddb34..417d460f50 100644 --- a/esp32/tools/run_initial_wipy_test.py +++ b/esp32/tools/run_initial_wipy_test.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/run_qa_lopy_test.py b/esp32/tools/run_qa_lopy_test.py index fb47cf826a..04b2f5b3b7 100644 --- a/esp32/tools/run_qa_lopy_test.py +++ b/esp32/tools/run_qa_lopy_test.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/run_qa_wipy_test.py b/esp32/tools/run_qa_wipy_test.py index 576081a39f..08c53dc560 100644 --- a/esp32/tools/run_qa_wipy_test.py +++ b/esp32/tools/run_qa_wipy_test.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/wipy_initial_test_board_script.py b/esp32/tools/wipy_initial_test_board_script.py index d8313dcacf..110b5e25e9 100644 --- a/esp32/tools/wipy_initial_test_board_script.py +++ b/esp32/tools/wipy_initial_test_board_script.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/tools/wipy_qa_test_board_script.py b/esp32/tools/wipy_qa_test_board_script.py index e06cc9692d..285e55f624 100644 --- a/esp32/tools/wipy_qa_test_board_script.py +++ b/esp32/tools/wipy_qa_test_board_script.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Pycom Limited. +# Copyright (c) 2018, Pycom Limited. # # This software is licensed under the GNU GPL version 3 or any # later version, with permitted additional terms. For more information diff --git a/esp32/util/antenna.c b/esp32/util/antenna.c index 1e640b439c..a5e87e7bfc 100644 --- a/esp32/util/antenna.c +++ b/esp32/util/antenna.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information @@ -53,15 +53,44 @@ void antenna_init0(void) { } void antenna_select (antenna_type_t _antenna) { + static bool init_done = false; + if (micropy_hw_antenna_diversity_pin_num < 32) { // set the pin value if (_antenna == ANTENNA_TYPE_EXTERNAL) { + // config the pin for first time if is the second generation as it was already ulled down by default + if((micropy_hw_antenna_diversity_pin_num == MICROPY_SECOND_GEN_ANT_SELECT_PIN_NUM) && (!init_done)) + { + gpio_config_t gpioconf = {.pin_bit_mask = 1ull << MICROPY_SECOND_GEN_ANT_SELECT_PIN_NUM, + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE}; + if(ESP_OK == gpio_config(&gpioconf)) + { + init_done = true; + } + } + GPIO_REG_WRITE(GPIO_OUT_W1TS_REG, 1 << micropy_hw_antenna_diversity_pin_num); } else if (_antenna == ANTENNA_TYPE_INTERNAL) { GPIO_REG_WRITE(GPIO_OUT_W1TC_REG, 1 << micropy_hw_antenna_diversity_pin_num); } } else { if (_antenna == ANTENNA_TYPE_EXTERNAL) { + // config the pin for first time if is the second generation as it was already ulled down by default + if((micropy_hw_antenna_diversity_pin_num == MICROPY_SECOND_GEN_ANT_SELECT_PIN_NUM) && (!init_done)) + { + gpio_config_t gpioconf = {.pin_bit_mask = 1ull << (MICROPY_SECOND_GEN_ANT_SELECT_PIN_NUM & 31), + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE}; + if(ESP_OK == gpio_config(&gpioconf)) + { + init_done = true; + } + } GPIO_REG_WRITE(GPIO_OUT1_W1TS_REG, 1 << (micropy_hw_antenna_diversity_pin_num & 31)); } else if (_antenna == ANTENNA_TYPE_INTERNAL) { GPIO_REG_WRITE(GPIO_OUT1_W1TC_REG, 1 << (micropy_hw_antenna_diversity_pin_num & 31)); diff --git a/esp32/util/antenna.h b/esp32/util/antenna.h index 6c028a39b0..af7e1f0ad2 100644 --- a/esp32/util/antenna.h +++ b/esp32/util/antenna.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/fifo.c b/esp32/util/fifo.c index e5815ea748..eb25ee29dd 100644 --- a/esp32/util/fifo.c +++ b/esp32/util/fifo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/fifo.h b/esp32/util/fifo.h index 8a7d5ca63f..8d5ffd5633 100644 --- a/esp32/util/fifo.h +++ b/esp32/util/fifo.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/gccollect.c b/esp32/util/gccollect.c index 953fb9e245..18ac8cf3fa 100644 --- a/esp32/util/gccollect.c +++ b/esp32/util/gccollect.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/util/gccollect.h b/esp32/util/gccollect.h index d8e3a5ebf3..eaa0e6daa0 100644 --- a/esp32/util/gccollect.h +++ b/esp32/util/gccollect.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/util/help.c b/esp32/util/help.c index 47ac71283e..cdba5c84b4 100644 --- a/esp32/util/help.c +++ b/esp32/util/help.c @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/esp32/util/mperror.c b/esp32/util/mperror.c index b6de5a5055..f000e9d026 100644 --- a/esp32/util/mperror.c +++ b/esp32/util/mperror.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/mperror.h b/esp32/util/mperror.h index 790504ec4d..079148c966 100644 --- a/esp32/util/mperror.h +++ b/esp32/util/mperror.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/mpexception.c b/esp32/util/mpexception.c index f29897f8aa..d8894622ac 100644 --- a/esp32/util/mpexception.c +++ b/esp32/util/mpexception.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/mpexception.h b/esp32/util/mpexception.h index 3e06a45385..f664dd77f1 100644 --- a/esp32/util/mpexception.h +++ b/esp32/util/mpexception.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/mpirq.c b/esp32/util/mpirq.c index e0f08f776f..3f6611a743 100644 --- a/esp32/util/mpirq.c +++ b/esp32/util/mpirq.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/mpirq.h b/esp32/util/mpirq.h index 759cc6bc73..68b5f1b9fc 100644 --- a/esp32/util/mpirq.h +++ b/esp32/util/mpirq.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/mpsleep.c b/esp32/util/mpsleep.c index 7f1cc79944..c5ccd3ef0b 100644 --- a/esp32/util/mpsleep.c +++ b/esp32/util/mpsleep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/mpsleep.h b/esp32/util/mpsleep.h index 22f3e32209..338243fc65 100644 --- a/esp32/util/mpsleep.h +++ b/esp32/util/mpsleep.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/random.c b/esp32/util/random.c index d05a28c935..95a37e2494 100644 --- a/esp32/util/random.c +++ b/esp32/util/random.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/random.h b/esp32/util/random.h index c48cba559c..fdef238ec7 100644 --- a/esp32/util/random.h +++ b/esp32/util/random.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/socketfifo.c b/esp32/util/socketfifo.c index dfffb5bb07..f880750947 100644 --- a/esp32/util/socketfifo.c +++ b/esp32/util/socketfifo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/esp32/util/socketfifo.h b/esp32/util/socketfifo.h index ac998b4739..67a8d5c073 100644 --- a/esp32/util/socketfifo.h +++ b/esp32/util/socketfifo.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Pycom Limited. + * Copyright (c) 2018, Pycom Limited. * * This software is licensed under the GNU GPL version 3 or any * later version, with permitted additional terms. For more information diff --git a/lib/lora/mac/LoRaMac.c b/lib/lora/mac/LoRaMac.c index d978ca63e1..8ffc3f89e0 100644 --- a/lib/lora/mac/LoRaMac.c +++ b/lib/lora/mac/LoRaMac.c @@ -1128,7 +1128,7 @@ static void OnRadioRxError( void ) } MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; - if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) + if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay + 50) { LoRaMacFlags.Bits.MacDone = 1; } @@ -1163,7 +1163,7 @@ static void OnRadioRxTimeout( void ) } MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; - if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) + if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay + 50) { LoRaMacFlags.Bits.MacDone = 1; } @@ -1933,8 +1933,8 @@ static LoRaMacStatus_t ScheduleTx( void ) if( IsLoRaMacNetworkJoined == false ) { - RxWindow1Delay = LoRaMacParams.JoinAcceptDelay1 + RxWindow1Config.WindowOffset; - RxWindow2Delay = LoRaMacParams.JoinAcceptDelay2 + RxWindow2Config.WindowOffset; + RxWindow1Delay = LoRaMacParams.JoinAcceptDelay1 + RxWindow1Config.WindowOffset - 2; + RxWindow2Delay = LoRaMacParams.JoinAcceptDelay2 + RxWindow2Config.WindowOffset - 3; } else { @@ -1942,8 +1942,8 @@ static LoRaMacStatus_t ScheduleTx( void ) { return LORAMAC_STATUS_LENGTH_ERROR; } - RxWindow1Delay = LoRaMacParams.ReceiveDelay1 + RxWindow1Config.WindowOffset; - RxWindow2Delay = LoRaMacParams.ReceiveDelay2 + RxWindow2Config.WindowOffset; + RxWindow1Delay = LoRaMacParams.ReceiveDelay1 + RxWindow1Config.WindowOffset - 1; + RxWindow2Delay = LoRaMacParams.ReceiveDelay2 + RxWindow2Config.WindowOffset - 2; } // Schedule transmission of frame diff --git a/lib/lora/mac/region/RegionAS923.c b/lib/lora/mac/region/RegionAS923.c index 8ec1c09171..bfc36038d9 100644 --- a/lib/lora/mac/region/RegionAS923.c +++ b/lib/lora/mac/region/RegionAS923.c @@ -585,6 +585,7 @@ void RegionAS923ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols } RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + rxConfigParams->WindowTimeout = rxConfigParams->WindowTimeout * 3; } bool RegionAS923RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) diff --git a/lib/lora/mac/region/RegionAU915.c b/lib/lora/mac/region/RegionAU915.c index 5e2486b51a..e1a63135cb 100644 --- a/lib/lora/mac/region/RegionAU915.c +++ b/lib/lora/mac/region/RegionAU915.c @@ -499,6 +499,7 @@ void RegionAU915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesAU915[rxConfigParams->Datarate], BandwidthsAU915[rxConfigParams->Datarate] ); RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + rxConfigParams->WindowTimeout = rxConfigParams->WindowTimeout * 3; } bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) diff --git a/lib/lora/mac/region/RegionEU868.c b/lib/lora/mac/region/RegionEU868.c index fae75413b8..d9f7b0341b 100644 --- a/lib/lora/mac/region/RegionEU868.c +++ b/lib/lora/mac/region/RegionEU868.c @@ -557,6 +557,7 @@ void RegionEU868ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols } RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + rxConfigParams->WindowTimeout = rxConfigParams->WindowTimeout * 3; } bool RegionEU868RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) diff --git a/lib/lora/mac/region/RegionUS915.c b/lib/lora/mac/region/RegionUS915.c index 09c232700a..aa5b8bd91e 100644 --- a/lib/lora/mac/region/RegionUS915.c +++ b/lib/lora/mac/region/RegionUS915.c @@ -507,6 +507,7 @@ void RegionUS915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesUS915[rxConfigParams->Datarate], BandwidthsUS915[rxConfigParams->Datarate] ); RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + rxConfigParams->WindowTimeout = rxConfigParams->WindowTimeout * 3; } bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) diff --git a/lib/lora/system/gpio.h b/lib/lora/system/gpio.h index 2af2170cd9..65fa41e216 100644 --- a/lib/lora/system/gpio.h +++ b/lib/lora/system/gpio.h @@ -1,7 +1,7 @@ /* * This file is derived from the MicroPython project, http://micropython.org/ * - * Copyright (c) 2016, Pycom Limited and its licensors. + * Copyright (c) 2018, Pycom Limited and its licensors. * * This software is licensed under the GNU GPL version 3 or any later version, * with permitted additional terms. For more information see the Pycom Licence diff --git a/lib/utils/interrupt_char.c b/lib/utils/interrupt_char.c index 3133d5c068..60681cbe51 100644 --- a/lib/utils/interrupt_char.c +++ b/lib/utils/interrupt_char.c @@ -27,7 +27,10 @@ #include "py/obj.h" #include "py/mpstate.h" +#if MICROPY_KBD_EXCEPTION + int mp_interrupt_char; +int mp_reset_char; void mp_hal_set_interrupt_char(int c) { if (c != -1) { @@ -36,6 +39,11 @@ void mp_hal_set_interrupt_char(int c) { mp_interrupt_char = c; } +void mp_hal_set_reset_char(int c) { + mp_reset_char = c; +} + void mp_keyboard_interrupt(void) { MP_STATE_VM(mp_pending_exception) = MP_STATE_PORT(mp_kbd_exception); } +#endif diff --git a/lib/utils/interrupt_char.h b/lib/utils/interrupt_char.h index ae0bf57e8a..f2accdab83 100644 --- a/lib/utils/interrupt_char.h +++ b/lib/utils/interrupt_char.h @@ -25,5 +25,7 @@ */ extern int mp_interrupt_char; +extern int mp_reset_char; void mp_hal_set_interrupt_char(int c); +void mp_hal_set_reset_char(int c); void mp_keyboard_interrupt(void); diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c index 72c609af3b..ea929cf2ca 100644 --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -88,6 +88,7 @@ STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind, start = mp_hal_ticks_ms(); mp_call_function_0(module_fun); mp_hal_set_interrupt_char(-1); // disable interrupt + mp_hal_set_reset_char(CHAR_CTRL_F); // enable reset char nlr_pop(); ret = 1; if (exec_flags & EXEC_FLAG_PRINT_EOF) { @@ -97,6 +98,7 @@ STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind, // uncaught exception // FIXME it could be that an interrupt happens just before we disable it here mp_hal_set_interrupt_char(-1); // disable interrupt + mp_hal_set_reset_char(CHAR_CTRL_F); // enable reset char, might be wrong here // print EOF after normal output if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); diff --git a/py/modmicropython.c b/py/modmicropython.c index ab5954f6ca..9da7eb1eea 100644 --- a/py/modmicropython.c +++ b/py/modmicropython.c @@ -130,11 +130,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_alloc_emergency_exception_buf_obj, mp_alloc_ #endif #if MICROPY_KBD_EXCEPTION -STATIC mp_obj_t mp_micropython_kbd_intr(mp_obj_t int_chr_in) { - mp_hal_set_interrupt_char(mp_obj_get_int(int_chr_in)); +STATIC mp_obj_t mp_micropython_kbd_intr(size_t n_args, const mp_obj_t *args) { + int c = mp_obj_get_int(args[0]); + mp_hal_set_interrupt_char(c); + if (n_args == 1) { + if (c == -1) { + mp_hal_set_reset_char(-1); + } + } else { + mp_hal_set_reset_char(mp_obj_get_int(args[1])); + } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_micropython_kbd_intr_obj, mp_micropython_kbd_intr); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_micropython_kbd_intr_obj, 1, 2, mp_micropython_kbd_intr); #endif STATIC const mp_rom_map_elem_t mp_module_micropython_globals_table[] = { @@ -163,6 +171,9 @@ STATIC const mp_rom_map_elem_t mp_module_micropython_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_heap_lock), MP_ROM_PTR(&mp_micropython_heap_lock_obj) }, { MP_ROM_QSTR(MP_QSTR_heap_unlock), MP_ROM_PTR(&mp_micropython_heap_unlock_obj) }, #endif + #if MICROPY_KBD_EXCEPTION + { MP_ROM_QSTR(MP_QSTR_kbd_intr), MP_ROM_PTR(&mp_micropython_kbd_intr_obj) }, + #endif }; STATIC MP_DEFINE_CONST_DICT(mp_module_micropython_globals, mp_module_micropython_globals_table);