From d24c2225ca3bceef90b1b30c56dc4de7066abf9d Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 3 Jun 2024 15:35:22 +0100 Subject: [PATCH 1/6] CI: PPP-enabled Pico build. --- .github/workflows/micropython.yml | 2 ++ micropython/board/RPI_PICO_PPP/board.json | 20 +++++++++++++ micropython/board/RPI_PICO_PPP/manifest.py | 5 ++++ .../board/RPI_PICO_PPP/mpconfigboard.cmake | 9 ++++++ .../board/RPI_PICO_PPP/mpconfigboard.h | 16 +++++++++++ micropython/board/RPI_PICO_PPP/pins.csv | 28 +++++++++++++++++++ .../modules/micropython-pico_ppp.cmake | 13 +++++++++ 7 files changed, 93 insertions(+) create mode 100644 micropython/board/RPI_PICO_PPP/board.json create mode 100644 micropython/board/RPI_PICO_PPP/manifest.py create mode 100644 micropython/board/RPI_PICO_PPP/mpconfigboard.cmake create mode 100644 micropython/board/RPI_PICO_PPP/mpconfigboard.h create mode 100644 micropython/board/RPI_PICO_PPP/pins.csv create mode 100644 micropython/modules/micropython-pico_ppp.cmake diff --git a/.github/workflows/micropython.yml b/.github/workflows/micropython.yml index 42386ddd5..f9b44b063 100644 --- a/.github/workflows/micropython.yml +++ b/.github/workflows/micropython.yml @@ -22,6 +22,8 @@ jobs: board: RPI_PICO - name: pico_usb board: RPI_PICO_USB + - name: pico_ppp + board: RPI_PICO_PPP - name: picow board: RPI_PICO_W - name: tiny2040_8mb diff --git a/micropython/board/RPI_PICO_PPP/board.json b/micropython/board/RPI_PICO_PPP/board.json new file mode 100644 index 000000000..5a67a25e3 --- /dev/null +++ b/micropython/board/RPI_PICO_PPP/board.json @@ -0,0 +1,20 @@ +{ + "deploy": [ + "../deploy.md" + ], + "docs": "", + "features": [ + "Breadboard friendly", + "Castellated Pads", + "Micro USB" + ], + "id": "rp2-pico", + "images": [ + "rp2-pico.jpg" + ], + "mcu": "rp2040", + "product": "Pico", + "thumbnail": "", + "url": "https://www.raspberrypi.com/products/raspberry-pi-pico/", + "vendor": "Raspberry Pi" +} \ No newline at end of file diff --git a/micropython/board/RPI_PICO_PPP/manifest.py b/micropython/board/RPI_PICO_PPP/manifest.py new file mode 100644 index 000000000..f8ee3f936 --- /dev/null +++ b/micropython/board/RPI_PICO_PPP/manifest.py @@ -0,0 +1,5 @@ +include("$(PORT_DIR)/boards/manifest.py") + +require("bundle-networking") + +include("../manifest_pico.py") \ No newline at end of file diff --git a/micropython/board/RPI_PICO_PPP/mpconfigboard.cmake b/micropython/board/RPI_PICO_PPP/mpconfigboard.cmake new file mode 100644 index 000000000..1aeeff208 --- /dev/null +++ b/micropython/board/RPI_PICO_PPP/mpconfigboard.cmake @@ -0,0 +1,9 @@ +# cmake file for Raspberry Pi Pico +set(PICO_BOARD "pico") + +set(MICROPY_PY_LWIP ON) + +# Board specific version of the frozen manifest +set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) + +set(MICROPY_C_HEAP_SIZE 4096) \ No newline at end of file diff --git a/micropython/board/RPI_PICO_PPP/mpconfigboard.h b/micropython/board/RPI_PICO_PPP/mpconfigboard.h new file mode 100644 index 000000000..a64e28938 --- /dev/null +++ b/micropython/board/RPI_PICO_PPP/mpconfigboard.h @@ -0,0 +1,16 @@ +// Board and hardware specific configuration +#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico" +#define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024) + +// Enable networking. +#define MICROPY_PY_NETWORK 1 +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "Pico" + +#define MICROPY_PY_NETWORK_PPP_LWIP 1 + +#define MICROPY_HW_NIC_PPP { MP_ROM_QSTR(MP_QSTR_PINT), MP_ROM_PTR(&mp_network_ppp_lwip_type) }, + +#define MICROPY_BOARD_NETWORK_INTERFACES \ + MICROPY_HW_NIC_PPP + +#define MICROPY_PY_SOCKET_EXTENDED_STATE 1 \ No newline at end of file diff --git a/micropython/board/RPI_PICO_PPP/pins.csv b/micropython/board/RPI_PICO_PPP/pins.csv new file mode 100644 index 000000000..9c40b41c9 --- /dev/null +++ b/micropython/board/RPI_PICO_PPP/pins.csv @@ -0,0 +1,28 @@ +GP0,GPIO0 +GP1,GPIO1 +GP2,GPIO2 +GP3,GPIO3 +GP4,GPIO4 +GP5,GPIO5 +GP6,GPIO6 +GP7,GPIO7 +GP8,GPIO8 +GP9,GPIO9 +GP10,GPIO10 +GP11,GPIO11 +GP12,GPIO12 +GP13,GPIO13 +GP14,GPIO14 +GP15,GPIO15 +GP16,GPIO16 +GP17,GPIO17 +GP18,GPIO18 +GP19,GPIO19 +GP20,GPIO20 +GP21,GPIO21 +GP22,GPIO22 +GP25,GPIO25 +GP26,GPIO26 +GP27,GPIO27 +GP28,GPIO28 +LED,GPIO25 \ No newline at end of file diff --git a/micropython/modules/micropython-pico_ppp.cmake b/micropython/modules/micropython-pico_ppp.cmake new file mode 100644 index 000000000..bb5b677fd --- /dev/null +++ b/micropython/modules/micropython-pico_ppp.cmake @@ -0,0 +1,13 @@ +include_directories(${CMAKE_CURRENT_LIST_DIR}/../../) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../") + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +include(micropython-common) + +# C++ Magic Memory +include(cppmem/micropython) From 81455d129d07d2c113dea041f0d889a5aa8fe194 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 3 Jun 2024 18:49:21 +0100 Subject: [PATCH 2/6] RPI_PICO_PPP: Tweak flash/fw alloc to fit PPP support. --- micropython/board/RPI_PICO_PPP/mpconfigboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/micropython/board/RPI_PICO_PPP/mpconfigboard.h b/micropython/board/RPI_PICO_PPP/mpconfigboard.h index a64e28938..27e43a5aa 100644 --- a/micropython/board/RPI_PICO_PPP/mpconfigboard.h +++ b/micropython/board/RPI_PICO_PPP/mpconfigboard.h @@ -1,6 +1,6 @@ // Board and hardware specific configuration #define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico" -#define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024) +#define MICROPY_HW_FLASH_STORAGE_BYTES (1024 * 1024) // Enable networking. #define MICROPY_PY_NETWORK 1 From 6cfcd80037b774cde6cb83d0e7d4a977b8a68184 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 16 Jul 2024 11:00:29 +0100 Subject: [PATCH 3/6] PPP: This old chestnut. --- micropython/modules/micropython-pico_ppp.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/micropython/modules/micropython-pico_ppp.cmake b/micropython/modules/micropython-pico_ppp.cmake index bb5b677fd..d4cb4fb99 100644 --- a/micropython/modules/micropython-pico_ppp.cmake +++ b/micropython/modules/micropython-pico_ppp.cmake @@ -11,3 +11,6 @@ include(micropython-common) # C++ Magic Memory include(cppmem/micropython) + +# Disable build-busting C++ exceptions +include(micropython-disable-exceptions) From a05a225262e9178ca14b5663b4347c3b1a673f75 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 17 Sep 2024 14:52:25 +0100 Subject: [PATCH 4/6] Wakeup: Move wakeup pin assert and latch out of patches. --- micropython/modules/micropython-enviro.cmake | 3 ++ .../modules/micropython-inky_frame.cmake | 3 ++ micropython/modules/wakeup/micropython.cmake | 1 - micropython/modules/wakeup/wakeup.S | 36 ------------------- micropython/modules/wakeup/wakeup.cpp | 24 +++++++++---- 5 files changed, 24 insertions(+), 43 deletions(-) delete mode 100644 micropython/modules/wakeup/wakeup.S diff --git a/micropython/modules/micropython-enviro.cmake b/micropython/modules/micropython-enviro.cmake index d305caf77..331e7a6bd 100644 --- a/micropython/modules/micropython-enviro.cmake +++ b/micropython/modules/micropython-enviro.cmake @@ -31,6 +31,9 @@ include(wakeup/micropython) # Configure wakeup for Enviro target_compile_definitions(usermod_wakeup INTERFACE -DWAKEUP_HAS_RTC=1 + -DWAKEUP_PIN_MASK=0b01000100 + -DWAKEUP_PIN_DIR=0b01000100 + -DWAKEUP_PIN_VALUE=0b01000100 ) # LEDs & Matrices diff --git a/micropython/modules/micropython-inky_frame.cmake b/micropython/modules/micropython-inky_frame.cmake index 6cd210380..3c568afa4 100644 --- a/micropython/modules/micropython-inky_frame.cmake +++ b/micropython/modules/micropython-inky_frame.cmake @@ -33,6 +33,9 @@ include(wakeup/micropython) target_compile_definitions(usermod_wakeup INTERFACE -DWAKEUP_HAS_RTC=1 -DWAKEUP_HAS_SHIFT_REGISTER=1 + -DWAKEUP_PIN_MASK=0b01000100 + -DWAKEUP_PIN_DIR=0b01000100 + -DWAKEUP_PIN_VALUE=0b01000100 ) # LEDs & Matrices diff --git a/micropython/modules/wakeup/micropython.cmake b/micropython/modules/wakeup/micropython.cmake index d5e781ea3..4be8830f1 100644 --- a/micropython/modules/wakeup/micropython.cmake +++ b/micropython/modules/wakeup/micropython.cmake @@ -5,7 +5,6 @@ add_library(usermod_${MOD_NAME} INTERFACE) target_sources(usermod_${MOD_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp - #${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.S ) target_include_directories(usermod_${MOD_NAME} INTERFACE diff --git a/micropython/modules/wakeup/wakeup.S b/micropython/modules/wakeup/wakeup.S deleted file mode 100644 index 4e7620498..000000000 --- a/micropython/modules/wakeup/wakeup.S +++ /dev/null @@ -1,36 +0,0 @@ - -.syntax unified -.cpu cortex-m0plus -.thumb - -#include "pico/asm_helper.S" - -// This macro tells the pico runtime to call __wakeup_gpio_latch very early in boot -__pre_init __wakeup_gpio_latch, 00000 - -.section .data.wakeup_gpio_latch -.global wakeup_gpio_state -.align 4 -wakeup_gpio_state: -.word 0x00000000 - -.section .text -.thumb_func -__wakeup_gpio_latch: - // Read GPIO state for front buttons and store - movs r3, 0xd0 // Load 0xd0 into r3 - lsls r3, r3, 24 // Shift left 24 to get 0xd0000000 - ldr r1, [r3, 4] // Load GPIO state (0xd0000004) into r1 - ldr r2, =wakeup_gpio_state // Load output var addr into r2 - str r1, [r2] // Store r1 to r2 - - // Enable 3v3 pin on the badger - ldr r1, =0x40014054 // GPIO control register 10 - movs r2, 5 // SIO function - str r2, [r1] // Set Enable 3v3 to SIO // https://github.com/raspberrypi/pico-sdk/blob/2e6142b15b8a75c1227dd3edbe839193b2bf9041/src/rp2_common/hardware_gpio/include/hardware/gpio.h#L96 - str r2, [r1, 120] // Also set LED (25) to SIO - ldr r2, =0x02000400 // Pins 25 and 10 - str r2, [r3, 36] // Enable pins out - str r2, [r3, 20] // Set pins high - - bx lr // Return diff --git a/micropython/modules/wakeup/wakeup.cpp b/micropython/modules/wakeup/wakeup.cpp index e5127526f..703e6367c 100644 --- a/micropython/modules/wakeup/wakeup.cpp +++ b/micropython/modules/wakeup/wakeup.cpp @@ -1,18 +1,30 @@ #include "hardware/gpio.h" #include "wakeup.config.hpp" -extern uint32_t runtime_wakeup_gpio_state; namespace { struct Wakeup { public: uint8_t shift_register_state = 0b0; + uint32_t gpio_state = 0; Wakeup() { // Assert wakeup pins (indicator LEDs, VSYS hold etc) - //gpio_init_mask(WAKEUP_PIN_MASK); - //gpio_set_dir_masked(WAKEUP_PIN_MASK, WAKEUP_PIN_DIR); - //gpio_put_masked(WAKEUP_PIN_MASK, WAKEUP_PIN_VALUE); + gpio_init_mask(WAKEUP_PIN_MASK); + gpio_set_dir_masked(WAKEUP_PIN_MASK, WAKEUP_PIN_DIR); + gpio_put_masked(WAKEUP_PIN_MASK, WAKEUP_PIN_VALUE); + + // Init all GPIOS not specified in the wakeup mask +#if PICO_RP2350 + gpio_init_mask(~WAKEUP_PIN_MASK); + gpio_set_dir_in_masked(~WAKEUP_PIN_MASK); +#endif + gpio_state = gpio_get_all(); + sleep_ms(5); + gpio_state |= gpio_get_all(); +#if PICO_RP2350 + gpio_init_mask(~WAKEUP_PIN_MASK); +#endif #if WAKEUP_HAS_RTC==1 // Set up RTC I2C pins and send reset command @@ -59,11 +71,11 @@ extern "C" { #include "wakeup.h" mp_obj_t Wakeup_get_gpio_state() { - return mp_obj_new_int(runtime_wakeup_gpio_state); + return mp_obj_new_int(wakeup.gpio_state); } mp_obj_t Wakeup_reset_gpio_state() { - runtime_wakeup_gpio_state = 0; + wakeup.gpio_state = 0; return mp_const_none; } From a1be7a6327fc9fa4945564ff6c61ed3fd58a970b Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 27 Sep 2024 09:50:07 +0100 Subject: [PATCH 5/6] RPI_PICO_PPP: Add lte module. --- micropython/board/RPI_PICO_PPP/manifest.py | 4 +- micropython/modules_py/lte.py | 215 +++++++++++++++++++++ 2 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 micropython/modules_py/lte.py diff --git a/micropython/board/RPI_PICO_PPP/manifest.py b/micropython/board/RPI_PICO_PPP/manifest.py index f8ee3f936..6eae8974d 100644 --- a/micropython/board/RPI_PICO_PPP/manifest.py +++ b/micropython/board/RPI_PICO_PPP/manifest.py @@ -2,4 +2,6 @@ require("bundle-networking") -include("../manifest_pico.py") \ No newline at end of file +include("../manifest_pico.py") + +freeze("../../modules_py", "lte.py") \ No newline at end of file diff --git a/micropython/modules_py/lte.py b/micropython/modules_py/lte.py new file mode 100644 index 000000000..5340650f1 --- /dev/null +++ b/micropython/modules_py/lte.py @@ -0,0 +1,215 @@ +from machine import UART, Pin +from network import PPP +from micropython import const +import time + + +DEFAULT_PIN_RST = 35 +DEFAULT_PIN_NETLIGHT = 34 +DEFAULT_PIN_RX = 33 +DEFAULT_PIN_TX = 32 +DEFAULT_UART_ID = 0 + +DEFAULT_UART_TIMEOUT = const(1) +DEFAULT_UART_TIMEOUT_CHAR = const(1) +DEFAULT_UART_RXBUF = const(1024) +DEFAULT_UART_STARTUP_BAUD = const(115200) +DEFAULT_UART_BAUD = const(460800) + + +class CellularError(Exception): + def __init__(self, message=None): + self.message = "CellularError: " + message + + +class LTE(): + def __init__(self, apn, uart=None, reset_pin=None, netlight_pin=None, netlight_led=None, skip_reset=False): + self._apn = apn + self._reset = reset_pin or Pin(DEFAULT_PIN_RST, Pin.OUT) + self._uart = uart or UART( + DEFAULT_UART_ID, + tx=Pin(DEFAULT_PIN_TX, Pin.OUT), + rx=Pin(DEFAULT_PIN_RX, Pin.OUT)) + + # Set PPP timeouts and rxbuf + self._uart.init( + timeout=DEFAULT_UART_TIMEOUT, + timeout_char=DEFAULT_UART_TIMEOUT_CHAR, + rxbuf=DEFAULT_UART_RXBUF) + + if not skip_reset: + self._reset.value(0) + time.sleep(1.0) + self._reset.value(1) + + if netlight_led: + self._led = netlight_led + self._netlight = netlight_pin or Pin(DEFAULT_PIN_NETLIGHT, Pin.IN) + self._netlight.irq(self._netlight_irq) + + def _netlight_irq(self, pin): + self._led.value(pin.value()) + + def ipconfig(self, *args, **kwargs): + if len(args): + return self._ppp.ipconfig(*args) + else: + return self._ppp.ipconfig(**kwargs) + + def iccid(self): + try: + return self._send_at_command("AT+CICCID", 1) + except CellularError: + return None + + def status(self): + lte_status = self._send_at_command("AT+CEREG?", 1) + gsm_status = self._send_at_command("AT+CGREG?", 1) + return lte_status, gsm_status + + def signal_quality(self): + try: + response = self._send_at_command("AT+CSQ", 1) + quality = int(response.split(":")[1].split(",")[0]) + db = -113 + (2 * quality) # conversion as per AT command set datasheet + return db + except CellularError: + pass + return None + + def stop_ppp(self): + self._ppp.disconnect() + self._send_at_command(f"AT+IPR={DEFAULT_UART_STARTUP_BAUD}") + self._flush_uart() + + def start_ppp(self, baudrate=DEFAULT_UART_BAUD, connect=True): + self._wait_ready(poll_time=1.0, timeout=30) + + # Switch to a faster baudrate + self._send_at_command(f"AT+IPR={baudrate}") + self._flush_uart() + self._uart.init( + baudrate=baudrate, + timeout=DEFAULT_UART_TIMEOUT, + timeout_char=DEFAULT_UART_TIMEOUT_CHAR, + rxbuf=DEFAULT_UART_RXBUF) + self._wait_ready(poll_time=1.0) + + # Connect! + if connect: + self.connect() + + # This will just always time out!? + # try: + # self._send_at_command("ATD*99#", timeout=300) + # except CellularError as e: + # print(e) + + # Force PPP to use modem's default settings... + #time.sleep(2.0) + self._flush_uart() + self._uart.write("ATD*99#\r") + self._uart.flush() + #time.sleep(2.0) + + self._ppp = PPP(self._uart) + self._ppp.connect() + while self._ppp.status() != 4: + time.sleep(1.0) + + return self._ppp.ifconfig() + + def connect(self, timeout=60): + print(" - setting up cellular uart") + # connect to and flush the uart + # consume any unsolicited messages first, we don't need those + self._flush_uart() + + print(" - waiting for cellular module to be ready") + + # wait for the cellular module to respond to AT commands + self._wait_ready() + + self._send_at_command("ATE0") # disable local echo + self._send_at_command(f"AT+CGDCONT=1,\"IP\",\"{self._apn}\"") # set apn and activate pdp context + + # wait for roaming lte connection to be established + giveup = time.time() + timeout + status = None + while status != "+CEREG: 0,5" and status != "+CEREG: 0,1": + status = self._send_at_command("AT+CEREG?", 1) + time.sleep(0.25) + if time.time() > giveup: + raise CellularError("timed out getting network registration") + + # disable server and client certification validation + self._send_at_command("AT+CSSLCFG=\"authmode\",0,0") + self._send_at_command("AT+CSSLCFG=\"enableSNI\",0,1") + + print(f" - SIM ICCID is {self.iccid()}") + + def _wait_ready(self, poll_time=0.25, timeout=10): + giveup = time.time() + timeout + while time.time() <= giveup: + try: + self._send_at_command("AT") + return # if __send_at_command doesn't throw an exception then we're good! + except CellularError as e: + print(e) + time.sleep(poll_time) + + raise CellularError("timed out waiting for AT response") + + def _flush_uart(self): + self._uart.flush() + time.sleep(0.25) + while self._uart.any(): + self._uart.read(self._uart.any()) + time.sleep(0.25) + + def _send_at_command(self, command, result_lines=0, timeout=5.0): + # consume any unsolicited messages first, we don't need those + self._flush_uart() + + self._uart.write(command + "\r") + #print(f" - tx: {command}") + self._uart.flush() + status, data = self._read_result(result_lines, timeout=timeout) + + print(" -", command, status, data) + + if status == "TIMEOUT": + #print.error(" !", command, status, data) + raise CellularError(f"cellular module timed out for command {command}") + + if status not in ["OK", "DOWNLOAD"]: + #print(" !", command, status, data) + raise CellularError(f"non 'OK' or 'DOWNLOAD' result for command {command}") + + if result_lines == 1: + return data[0] + if result_lines > 1: + return data + return None + + def _read_result(self, result_lines, timeout=1.0): + status = None + result = [] + start = time.ticks_ms() + timeout *= 1000 + while len(result) < result_lines or status is None: + if (time.ticks_ms() - start) > timeout: + return "TIMEOUT", [] + + line = self._uart.readline() + + if line: + line = line.strip() + if line in [b"OK", b"ERROR", b"DOWNLOAD"]: + status = line.decode("ascii") + elif line != b"": + result.append(str(line, "ascii")) + start = time.ticks_ms() + + return status, result + From ef936ba907e0d735627e2d64a70449dd0c1169c4 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 27 Sep 2024 10:04:30 +0100 Subject: [PATCH 6/6] RPI_PICO_PPP: Lint lte module. --- micropython/modules_py/lte.py | 64 +++++++++++++++-------------------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/micropython/modules_py/lte.py b/micropython/modules_py/lte.py index 5340650f1..c64abb7cd 100644 --- a/micropython/modules_py/lte.py +++ b/micropython/modules_py/lte.py @@ -1,8 +1,9 @@ +import time + from machine import UART, Pin from network import PPP -from micropython import const -import time +from micropython import const DEFAULT_PIN_RST = 35 DEFAULT_PIN_NETLIGHT = 34 @@ -18,8 +19,8 @@ class CellularError(Exception): - def __init__(self, message=None): - self.message = "CellularError: " + message + def __init__(self, message=None): + self.message = "CellularError: " + message class LTE(): @@ -30,13 +31,13 @@ def __init__(self, apn, uart=None, reset_pin=None, netlight_pin=None, netlight_l DEFAULT_UART_ID, tx=Pin(DEFAULT_PIN_TX, Pin.OUT), rx=Pin(DEFAULT_PIN_RX, Pin.OUT)) - + # Set PPP timeouts and rxbuf self._uart.init( timeout=DEFAULT_UART_TIMEOUT, timeout_char=DEFAULT_UART_TIMEOUT_CHAR, rxbuf=DEFAULT_UART_RXBUF) - + if not skip_reset: self._reset.value(0) time.sleep(1.0) @@ -46,7 +47,7 @@ def __init__(self, apn, uart=None, reset_pin=None, netlight_pin=None, netlight_l self._led = netlight_led self._netlight = netlight_pin or Pin(DEFAULT_PIN_NETLIGHT, Pin.IN) self._netlight.irq(self._netlight_irq) - + def _netlight_irq(self, pin): self._led.value(pin.value()) @@ -60,23 +61,24 @@ def iccid(self): try: return self._send_at_command("AT+CICCID", 1) except CellularError: - return None + return None def status(self): lte_status = self._send_at_command("AT+CEREG?", 1) gsm_status = self._send_at_command("AT+CGREG?", 1) return lte_status, gsm_status - + def signal_quality(self): try: response = self._send_at_command("AT+CSQ", 1) quality = int(response.split(":")[1].split(",")[0]) - db = -113 + (2 * quality) # conversion as per AT command set datasheet + # Conversion as per AT command set datasheet + db = -113 + (2 * quality) return db except CellularError: pass return None - + def stop_ppp(self): self._ppp.disconnect() self._send_at_command(f"AT+IPR={DEFAULT_UART_STARTUP_BAUD}") @@ -99,18 +101,10 @@ def start_ppp(self, baudrate=DEFAULT_UART_BAUD, connect=True): if connect: self.connect() - # This will just always time out!? - # try: - # self._send_at_command("ATD*99#", timeout=300) - # except CellularError as e: - # print(e) - # Force PPP to use modem's default settings... - #time.sleep(2.0) self._flush_uart() self._uart.write("ATD*99#\r") self._uart.flush() - #time.sleep(2.0) self._ppp = PPP(self._uart) self._ppp.connect() @@ -121,29 +115,29 @@ def start_ppp(self, baudrate=DEFAULT_UART_BAUD, connect=True): def connect(self, timeout=60): print(" - setting up cellular uart") - # connect to and flush the uart - # consume any unsolicited messages first, we don't need those + # Connect to and flush the uart + # Discard any unsolicited messages first, we don't need those self._flush_uart() print(" - waiting for cellular module to be ready") - # wait for the cellular module to respond to AT commands - self._wait_ready() + # Wait for the cellular module to respond to AT commands + self._wait_ready() - self._send_at_command("ATE0") # disable local echo - self._send_at_command(f"AT+CGDCONT=1,\"IP\",\"{self._apn}\"") # set apn and activate pdp context + self._send_at_command("ATE0") # Disable local echo + self._send_at_command(f"AT+CGDCONT=1,\"IP\",\"{self._apn}\"") # Set apn and activate pdp context - # wait for roaming lte connection to be established + # Wait for roaming lte connection to be established giveup = time.time() + timeout status = None while status != "+CEREG: 0,5" and status != "+CEREG: 0,1": status = self._send_at_command("AT+CEREG?", 1) time.sleep(0.25) if time.time() > giveup: - raise CellularError("timed out getting network registration") + raise CellularError("timed out getting network registration") - # disable server and client certification validation - self._send_at_command("AT+CSSLCFG=\"authmode\",0,0") + # Disable server and client certification validation + self._send_at_command("AT+CSSLCFG=\"authmode\",0,0") self._send_at_command("AT+CSSLCFG=\"enableSNI\",0,1") print(f" - SIM ICCID is {self.iccid()}") @@ -153,12 +147,12 @@ def _wait_ready(self, poll_time=0.25, timeout=10): while time.time() <= giveup: try: self._send_at_command("AT") - return # if __send_at_command doesn't throw an exception then we're good! + return # If __send_at_command doesn't throw an exception then we're good! except CellularError as e: print(e) time.sleep(poll_time) - raise CellularError("timed out waiting for AT response") + raise CellularError("timed out waiting for AT response") def _flush_uart(self): self._uart.flush() @@ -168,28 +162,25 @@ def _flush_uart(self): time.sleep(0.25) def _send_at_command(self, command, result_lines=0, timeout=5.0): - # consume any unsolicited messages first, we don't need those + # Discard any unsolicited messages first, we don't need those self._flush_uart() self._uart.write(command + "\r") - #print(f" - tx: {command}") self._uart.flush() status, data = self._read_result(result_lines, timeout=timeout) print(" -", command, status, data) if status == "TIMEOUT": - #print.error(" !", command, status, data) raise CellularError(f"cellular module timed out for command {command}") if status not in ["OK", "DOWNLOAD"]: - #print(" !", command, status, data) raise CellularError(f"non 'OK' or 'DOWNLOAD' result for command {command}") if result_lines == 1: return data[0] if result_lines > 1: - return data + return data return None def _read_result(self, result_lines, timeout=1.0): @@ -212,4 +203,3 @@ def _read_result(self, result_lines, timeout=1.0): start = time.ticks_ms() return status, result -