Compare commits
3 Commits
main
...
feature/li
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da4cbd989f | ||
|
|
9ec3001410 | ||
|
|
31419eeb80 |
2
.github/workflows/micropython.yml
vendored
2
.github/workflows/micropython.yml
vendored
@ -20,6 +20,8 @@ jobs:
|
|||||||
- name: pimoroni_plasma2350
|
- name: pimoroni_plasma2350
|
||||||
- name: pimoroni_tiny2350
|
- name: pimoroni_tiny2350
|
||||||
- name: pimoroni_pico_plus2
|
- name: pimoroni_pico_plus2
|
||||||
|
- name: pimoroni_pico_lipo2
|
||||||
|
- name: pimoroni_pico_lipo2xl_w
|
||||||
|
|
||||||
env:
|
env:
|
||||||
# MicroPython version will be contained in github.event.release.tag_name for releases
|
# MicroPython version will be contained in github.event.release.tag_name for releases
|
||||||
|
|||||||
8
boards/pimoroni_pico_lipo2/manifest.py
Normal file
8
boards/pimoroni_pico_lipo2/manifest.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
include("$(PORT_DIR)/boards/manifest.py")
|
||||||
|
|
||||||
|
require("bundle-networking")
|
||||||
|
|
||||||
|
# Bluetooth
|
||||||
|
require("aioble")
|
||||||
|
|
||||||
|
include("../manifest_pico2.py")
|
||||||
19
boards/pimoroni_pico_lipo2/mpconfigboard.cmake
Normal file
19
boards/pimoroni_pico_lipo2/mpconfigboard.cmake
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# cmake file for Pimoroni Pico LiPo
|
||||||
|
set(PICO_BOARD "pimoroni_pico_lipo2")
|
||||||
|
set(PICO_PLATFORM "rp2350")
|
||||||
|
|
||||||
|
set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
# To change the gpio count for QFN-80
|
||||||
|
set(PICO_NUM_GPIOS 48)
|
||||||
|
|
||||||
|
# Links micropy_lib_lwip and sets MICROPY_PY_LWIP = 1
|
||||||
|
# Picked up and expanded upon in mpconfigboard.h
|
||||||
|
set(MICROPY_PY_LWIP ON)
|
||||||
|
|
||||||
|
include(enable_cyw43.cmake)
|
||||||
|
|
||||||
|
# Board specific version of the frozen manifest
|
||||||
|
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake)
|
||||||
18
boards/pimoroni_pico_lipo2/mpconfigboard.h
Normal file
18
boards/pimoroni_pico_lipo2/mpconfigboard.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Board and hardware specific configuration
|
||||||
|
#define MICROPY_HW_BOARD_NAME "Pimoroni Pico LiPo 2"
|
||||||
|
#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - 1024 * 1024 * 2)
|
||||||
|
|
||||||
|
#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "PicoLiPo2"
|
||||||
|
|
||||||
|
// Enable PPP
|
||||||
|
#define MICROPY_PY_NETWORK_PPP_LWIP (1)
|
||||||
|
|
||||||
|
#include "enable_cyw43.h"
|
||||||
|
|
||||||
|
#undef MICROPY_HW_PIN_RESERVED
|
||||||
|
#define MICROPY_HW_PIN_RESERVED(i) (false)
|
||||||
|
|
||||||
|
// PSRAM Settings
|
||||||
|
#define MICROPY_HW_ENABLE_PSRAM (1)
|
||||||
|
#define MICROPY_HW_PSRAM_CS_PIN PIMORONI_PICO_LIPO2_PSRAM_CS_PIN
|
||||||
|
#define MICROPY_GC_SPLIT_HEAP (1)
|
||||||
163
boards/pimoroni_pico_lipo2/pimoroni_pico_lipo2.h
Normal file
163
boards/pimoroni_pico_lipo2/pimoroni_pico_lipo2.h
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
|
||||||
|
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// This header may be included by other board headers as "boards/pimoroni_pico_lipo2.h"
|
||||||
|
|
||||||
|
// pico_cmake_set PICO_PLATFORM=rp2350
|
||||||
|
// pico_cmake_set PICO_CYW43_SUPPORTED = 1
|
||||||
|
|
||||||
|
#ifndef _BOARDS_PICO2_W_H
|
||||||
|
#define _BOARDS_PICO2_W_H
|
||||||
|
|
||||||
|
// For board detection
|
||||||
|
#define PIMORONI_PICO_LIPO2_RP2350
|
||||||
|
|
||||||
|
// --- BOARD SPECIFIC ---
|
||||||
|
#define SPICE_SPI 0
|
||||||
|
#define SPICE_TX_MISO_PIN 32
|
||||||
|
#define SPICE_RX_CS_PIN 33
|
||||||
|
#define SPICE_NETLIGHT_SCK_PIN 34
|
||||||
|
#define SPICE_RESET_MOSI_PIN 35
|
||||||
|
#define SPICE_PWRKEY_BL_PIN 36
|
||||||
|
|
||||||
|
#define PIMORONI_PICO_LIPO2_USER_SW_PIN 45
|
||||||
|
#define PIMORONI_PICO_LIPO2_PSRAM_CS_PIN 47
|
||||||
|
|
||||||
|
// --- RP2350 VARIANT ---
|
||||||
|
// not PICO_RP2350A
|
||||||
|
|
||||||
|
// --- UART ---
|
||||||
|
#ifndef PICO_DEFAULT_UART
|
||||||
|
#define PICO_DEFAULT_UART 0
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_UART_TX_PIN
|
||||||
|
#define PICO_DEFAULT_UART_TX_PIN SPICE_TX_MISO_PIN
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_UART_RX_PIN
|
||||||
|
#define PICO_DEFAULT_UART_RX_PIN SPICE_RX_CS_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- LED ---
|
||||||
|
// no PICO_DEFAULT_LED_PIN - LED is on Wireless chip
|
||||||
|
// no PICO_DEFAULT_WS2812_PIN
|
||||||
|
|
||||||
|
// --- I2C ---
|
||||||
|
#ifndef PICO_DEFAULT_I2C
|
||||||
|
#define PICO_DEFAULT_I2C 0
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_I2C_SDA_PIN
|
||||||
|
#define PICO_DEFAULT_I2C_SDA_PIN 4
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_I2C_SCL_PIN
|
||||||
|
#define PICO_DEFAULT_I2C_SCL_PIN 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- SPI ---
|
||||||
|
#ifndef PICO_DEFAULT_SPI
|
||||||
|
#define PICO_DEFAULT_SPI 0
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_SCK_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_SCK_PIN SPICE_NETLIGHT_SCK_PIN
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_TX_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_TX_PIN SPICE_RESET_MOSI_PIN
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_RX_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_RX_PIN SPICE_TX_MISO_PIN
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_CSN_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_CSN_PIN SPICE_RX_CS_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- FLASH ---
|
||||||
|
|
||||||
|
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
|
||||||
|
|
||||||
|
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||||
|
#define PICO_FLASH_SPI_CLKDIV 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024)
|
||||||
|
#ifndef PICO_FLASH_SIZE_BYTES
|
||||||
|
#define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024)
|
||||||
|
#endif
|
||||||
|
// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
|
||||||
|
// note the SMSP mode pin is on WL_GPIO1
|
||||||
|
|
||||||
|
#ifndef CYW43_WL_GPIO_COUNT
|
||||||
|
#define CYW43_WL_GPIO_COUNT 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_WL_GPIO_LED_PIN
|
||||||
|
// no CYW43_WL_GPIO_LED_PIN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If CYW43_WL_GPIO_VBUS_PIN is defined then a CYW43 GPIO has to be used to read VBUS.
|
||||||
|
// This can be passed to cyw43_arch_gpio_get to determine if the device is battery powered.
|
||||||
|
// PICO_VBUS_PIN and CYW43_WL_GPIO_VBUS_PIN should not both be defined.
|
||||||
|
#ifndef CYW43_WL_GPIO_VBUS_PIN
|
||||||
|
// no CYW43_WL_GPIO_VBUS_PIN 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If CYW43_USES_VSYS_PIN is defined then CYW43 uses the VSYS GPIO (defined by PICO_VSYS_PIN) for other purposes.
|
||||||
|
// If this is the case, to use the VSYS GPIO it's necessary to ensure CYW43 is not using it.
|
||||||
|
// This can be achieved by wrapping the use of the VSYS GPIO in cyw43_thread_enter / cyw43_thread_exit.
|
||||||
|
#ifndef CYW43_USES_VSYS_PIN
|
||||||
|
// no CYW43_USES_VSYS_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The GPIO Pin used to monitor VSYS. Typically you would use this with ADC.
|
||||||
|
// There is an example in adc/read_vsys in pico-examples.
|
||||||
|
#ifndef PICO_VSYS_PIN
|
||||||
|
// no PICO_VSYS_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1
|
||||||
|
#ifndef PICO_RP2350_A2_SUPPORTED
|
||||||
|
#define PICO_RP2350_A2_SUPPORTED 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// cyw43 SPI pins can't be changed at runtime
|
||||||
|
#ifndef CYW43_PIN_WL_DYNAMIC
|
||||||
|
#define CYW43_PIN_WL_DYNAMIC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio pin to power up the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_REG_ON
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_REG_ON SPICE_TX_MISO_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio pin for spi data out to the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_DATA_OUT
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_DATA_OUT SPICE_RESET_MOSI_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio pin for spi data in from the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_DATA_IN
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_DATA_IN SPICE_RESET_MOSI_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio (irq) pin for the irq line from the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_HOST_WAKE
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_HOST_WAKE SPICE_RESET_MOSI_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio pin for the spi clock line to the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_CLOCK
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_CLOCK SPICE_NETLIGHT_SCK_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio pin for the spi chip select to the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_CS
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_CS SPICE_RX_CS_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
57
boards/pimoroni_pico_lipo2/pins.csv
Normal file
57
boards/pimoroni_pico_lipo2/pins.csv
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
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
|
||||||
|
GP29,GPIO29
|
||||||
|
GP30,GPIO30
|
||||||
|
GP31,GPIO31
|
||||||
|
GP32,GPIO32
|
||||||
|
GP33,GPIO33
|
||||||
|
GP34,GPIO34
|
||||||
|
GP35,GPIO35
|
||||||
|
GP36,GPIO36
|
||||||
|
GP37,GPIO37
|
||||||
|
GP38,GPIO38
|
||||||
|
GP39,GPIO39
|
||||||
|
GP40,GPIO40
|
||||||
|
GP41,GPIO41
|
||||||
|
GP42,GPIO42
|
||||||
|
GP43,GPIO43
|
||||||
|
GP44,GPIO44
|
||||||
|
GP45,GPIO45
|
||||||
|
GP46,GPIO46
|
||||||
|
GP47,GPIO47
|
||||||
|
WL_GPIO0,EXT_GPIO0
|
||||||
|
WL_GPIO1,EXT_GPIO1
|
||||||
|
WL_GPIO2,EXT_GPIO2
|
||||||
|
VBAT_SENSE,GPIO24
|
||||||
|
LED,GPIO25
|
||||||
|
SPICE_TX_MISO,GPIO32
|
||||||
|
SPICE_RX_CS,GPIO33
|
||||||
|
SPICE_NETLIGHT_SCK,GPIO34
|
||||||
|
SPICE_RESET_MOSI,GPIO35
|
||||||
|
SPICE_PWRKEY_BL,GPIO36
|
||||||
|
PSRAM_CS,GPIO47
|
||||||
|
10
boards/pimoroni_pico_lipo2/usermodules.cmake
Normal file
10
boards/pimoroni_pico_lipo2/usermodules.cmake
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../")
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../")
|
||||||
|
|
||||||
|
# Wakeup module for early GPIO latch
|
||||||
|
include(modules/c/wakeup/micropython)
|
||||||
|
|
||||||
|
# Powman example for low power sleep
|
||||||
|
include(modules/c/powman/micropython)
|
||||||
|
|
||||||
|
include(usermod-common)
|
||||||
8
boards/pimoroni_pico_lipo2xl_w/manifest.py
Normal file
8
boards/pimoroni_pico_lipo2xl_w/manifest.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
include("$(PORT_DIR)/boards/manifest.py")
|
||||||
|
|
||||||
|
require("bundle-networking")
|
||||||
|
|
||||||
|
# Bluetooth
|
||||||
|
require("aioble")
|
||||||
|
|
||||||
|
include("../manifest_pico2.py")
|
||||||
19
boards/pimoroni_pico_lipo2xl_w/mpconfigboard.cmake
Normal file
19
boards/pimoroni_pico_lipo2xl_w/mpconfigboard.cmake
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# cmake file for Pimoroni Pico LiPo
|
||||||
|
set(PICO_BOARD "pimoroni_pico_lipo2xl_w")
|
||||||
|
set(PICO_PLATFORM "rp2350")
|
||||||
|
|
||||||
|
set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|
||||||
|
# To change the gpio count for QFN-80
|
||||||
|
set(PICO_NUM_GPIOS 48)
|
||||||
|
|
||||||
|
# Links micropy_lib_lwip and sets MICROPY_PY_LWIP = 1
|
||||||
|
# Picked up and expanded upon in mpconfigboard.h
|
||||||
|
set(MICROPY_PY_LWIP ON)
|
||||||
|
|
||||||
|
include(enable_cyw43.cmake)
|
||||||
|
|
||||||
|
# Board specific version of the frozen manifest
|
||||||
|
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake)
|
||||||
15
boards/pimoroni_pico_lipo2xl_w/mpconfigboard.h
Normal file
15
boards/pimoroni_pico_lipo2xl_w/mpconfigboard.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Board and hardware specific configuration
|
||||||
|
#define MICROPY_HW_BOARD_NAME "Pimoroni Pico LiPo 2XL W"
|
||||||
|
#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - 1024 * 1024 * 2)
|
||||||
|
|
||||||
|
#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "PicoLiPo2XLW"
|
||||||
|
|
||||||
|
// Enable PPP
|
||||||
|
#define MICROPY_PY_NETWORK_PPP_LWIP (1)
|
||||||
|
|
||||||
|
#include "enable_cyw43.h"
|
||||||
|
|
||||||
|
// PSRAM Settings
|
||||||
|
#define MICROPY_HW_ENABLE_PSRAM (1)
|
||||||
|
#define MICROPY_HW_PSRAM_CS_PIN PIMORONI_PICO_LIPO2_PSRAM_CS_PIN
|
||||||
|
#define MICROPY_GC_SPLIT_HEAP (1)
|
||||||
163
boards/pimoroni_pico_lipo2xl_w/pimoroni_pico_lipo2xl_w.h
Normal file
163
boards/pimoroni_pico_lipo2xl_w/pimoroni_pico_lipo2xl_w.h
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
|
||||||
|
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// This header may be included by other board headers as "boards/pimoroni_pico_lipo2xl_w.h"
|
||||||
|
|
||||||
|
// pico_cmake_set PICO_PLATFORM=rp2350
|
||||||
|
// pico_cmake_set PICO_CYW43_SUPPORTED = 1
|
||||||
|
|
||||||
|
#ifndef _BOARDS_PICO2_W_H
|
||||||
|
#define _BOARDS_PICO2_W_H
|
||||||
|
|
||||||
|
// For board detection
|
||||||
|
#define PIMORONI_PICO_LIPO2_RP2350
|
||||||
|
|
||||||
|
// --- BOARD SPECIFIC ---
|
||||||
|
#define SPICE_SPI 0
|
||||||
|
#define SPICE_TX_MISO_PIN 32
|
||||||
|
#define SPICE_RX_CS_PIN 33
|
||||||
|
#define SPICE_NETLIGHT_SCK_PIN 34
|
||||||
|
#define SPICE_RESET_MOSI_PIN 35
|
||||||
|
#define SPICE_PWRKEY_BL_PIN 36
|
||||||
|
|
||||||
|
#define PIMORONI_PICO_LIPO2_USER_SW_PIN 30
|
||||||
|
#define PIMORONI_PICO_LIPO2_PSRAM_CS_PIN 47
|
||||||
|
|
||||||
|
// --- RP2350 VARIANT ---
|
||||||
|
// not PICO_RP2350A
|
||||||
|
|
||||||
|
// --- UART ---
|
||||||
|
#ifndef PICO_DEFAULT_UART
|
||||||
|
#define PICO_DEFAULT_UART 0
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_UART_TX_PIN
|
||||||
|
#define PICO_DEFAULT_UART_TX_PIN SPICE_TX_MISO_PIN
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_UART_RX_PIN
|
||||||
|
#define PICO_DEFAULT_UART_RX_PIN SPICE_RX_CS_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- LED ---
|
||||||
|
// no PICO_DEFAULT_LED_PIN - LED is on Wireless chip
|
||||||
|
// no PICO_DEFAULT_WS2812_PIN
|
||||||
|
|
||||||
|
// --- I2C ---
|
||||||
|
#ifndef PICO_DEFAULT_I2C
|
||||||
|
#define PICO_DEFAULT_I2C 0
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_I2C_SDA_PIN
|
||||||
|
#define PICO_DEFAULT_I2C_SDA_PIN 4
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_I2C_SCL_PIN
|
||||||
|
#define PICO_DEFAULT_I2C_SCL_PIN 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- SPI ---
|
||||||
|
#ifndef PICO_DEFAULT_SPI
|
||||||
|
#define PICO_DEFAULT_SPI 0
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_SCK_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_SCK_PIN SPICE_NETLIGHT_SCK_PIN
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_TX_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_TX_PIN SPICE_RESET_MOSI_PIN
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_RX_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_RX_PIN SPICE_TX_MISO_PIN
|
||||||
|
#endif
|
||||||
|
#ifndef PICO_DEFAULT_SPI_CSN_PIN
|
||||||
|
#define PICO_DEFAULT_SPI_CSN_PIN SPICE_RX_CS_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --- FLASH ---
|
||||||
|
|
||||||
|
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
|
||||||
|
|
||||||
|
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||||
|
#define PICO_FLASH_SPI_CLKDIV 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024)
|
||||||
|
#ifndef PICO_FLASH_SIZE_BYTES
|
||||||
|
#define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024)
|
||||||
|
#endif
|
||||||
|
// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
|
||||||
|
// note the SMSP mode pin is on WL_GPIO1
|
||||||
|
|
||||||
|
#ifndef CYW43_WL_GPIO_COUNT
|
||||||
|
#define CYW43_WL_GPIO_COUNT 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CYW43_WL_GPIO_LED_PIN
|
||||||
|
#define CYW43_WL_GPIO_LED_PIN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If CYW43_WL_GPIO_VBUS_PIN is defined then a CYW43 GPIO has to be used to read VBUS.
|
||||||
|
// This can be passed to cyw43_arch_gpio_get to determine if the device is battery powered.
|
||||||
|
// PICO_VBUS_PIN and CYW43_WL_GPIO_VBUS_PIN should not both be defined.
|
||||||
|
#ifndef CYW43_WL_GPIO_VBUS_PIN
|
||||||
|
#define CYW43_WL_GPIO_VBUS_PIN 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If CYW43_USES_VSYS_PIN is defined then CYW43 uses the VSYS GPIO (defined by PICO_VSYS_PIN) for other purposes.
|
||||||
|
// If this is the case, to use the VSYS GPIO it's necessary to ensure CYW43 is not using it.
|
||||||
|
// This can be achieved by wrapping the use of the VSYS GPIO in cyw43_thread_enter / cyw43_thread_exit.
|
||||||
|
#ifndef CYW43_USES_VSYS_PIN
|
||||||
|
// no CYW43_USES_VSYS_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The GPIO Pin used to monitor VSYS. Typically you would use this with ADC.
|
||||||
|
// There is an example in adc/read_vsys in pico-examples.
|
||||||
|
#ifndef PICO_VSYS_PIN
|
||||||
|
// no PICO_VSYS_PIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// pico_cmake_set_default PICO_RP2350_A2_SUPPORTED = 1
|
||||||
|
#ifndef PICO_RP2350_A2_SUPPORTED
|
||||||
|
#define PICO_RP2350_A2_SUPPORTED 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// cyw43 SPI pins can't be changed at runtime
|
||||||
|
#ifndef CYW43_PIN_WL_DYNAMIC
|
||||||
|
#define CYW43_PIN_WL_DYNAMIC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio pin to power up the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_REG_ON
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_REG_ON 23
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio pin for spi data out to the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_DATA_OUT
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_DATA_OUT 24
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio pin for spi data in from the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_DATA_IN
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_DATA_IN 24
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio (irq) pin for the irq line from the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_HOST_WAKE
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_HOST_WAKE 24
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio pin for the spi clock line to the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_CLOCK
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_CLOCK 29
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// gpio pin for the spi chip select to the cyw43 chip
|
||||||
|
#ifndef CYW43_DEFAULT_PIN_WL_CS
|
||||||
|
#define CYW43_DEFAULT_PIN_WL_CS 25
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
58
boards/pimoroni_pico_lipo2xl_w/pins.csv
Normal file
58
boards/pimoroni_pico_lipo2xl_w/pins.csv
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
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
|
||||||
|
GP29,GPIO29
|
||||||
|
GP30,GPIO30
|
||||||
|
GP31,GPIO31
|
||||||
|
GP32,GPIO32
|
||||||
|
GP33,GPIO33
|
||||||
|
GP34,GPIO34
|
||||||
|
GP35,GPIO35
|
||||||
|
GP36,GPIO36
|
||||||
|
GP37,GPIO37
|
||||||
|
GP38,GPIO38
|
||||||
|
GP39,GPIO39
|
||||||
|
GP40,GPIO40
|
||||||
|
GP41,GPIO41
|
||||||
|
GP42,GPIO42
|
||||||
|
GP43,GPIO43
|
||||||
|
GP44,GPIO44
|
||||||
|
GP45,GPIO45
|
||||||
|
GP46,GPIO46
|
||||||
|
GP47,GPIO47
|
||||||
|
WL_GPIO0,EXT_GPIO0
|
||||||
|
WL_GPIO1,EXT_GPIO1
|
||||||
|
WL_GPIO2,EXT_GPIO2
|
||||||
|
LED,EXT_GPIO0
|
||||||
|
VBUS_SENSE,EXT_GPIO2
|
||||||
|
SPICE_TX_MISO,GPIO32
|
||||||
|
SPICE_RX_CS,GPIO33
|
||||||
|
SPICE_NETLIGHT_SCK,GPIO34
|
||||||
|
SPICE_RESET_MOSI,GPIO35
|
||||||
|
SPICE_PWRKEY_BL,GPIO36
|
||||||
|
VBAT_SENSE,GPIO43
|
||||||
|
PSRAM_CS,GPIO47
|
||||||
|
10
boards/pimoroni_pico_lipo2xl_w/usermodules.cmake
Normal file
10
boards/pimoroni_pico_lipo2xl_w/usermodules.cmake
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../")
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../")
|
||||||
|
|
||||||
|
# Wakeup module for early GPIO latch
|
||||||
|
include(modules/c/wakeup/micropython)
|
||||||
|
|
||||||
|
# Powman example for low power sleep
|
||||||
|
include(modules/c/powman/micropython)
|
||||||
|
|
||||||
|
include(usermod-common)
|
||||||
150
modules/c/powman/bindings.c
Normal file
150
modules/c/powman/bindings.c
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/util/datetime.h"
|
||||||
|
#include "powman.h"
|
||||||
|
|
||||||
|
#include "mphalport.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "shared/timeutils/timeutils.h"
|
||||||
|
|
||||||
|
#define GPIO_I2C_POWER 2
|
||||||
|
#define GPIO_WAKE 3
|
||||||
|
#define GPIO_EXT_CLK 12
|
||||||
|
#define GPIO_LED_A 10
|
||||||
|
|
||||||
|
enum {
|
||||||
|
WAKE_BUTTON_A = 0x00,
|
||||||
|
WAKE_BUTTON_B,
|
||||||
|
WAKE_BUTTON_C,
|
||||||
|
WAKE_TIMER = 0xf0,
|
||||||
|
WAKE_UNKNOWN = 0xff,
|
||||||
|
};
|
||||||
|
|
||||||
|
mp_obj_t _sleep_get_wake_reason(void) {
|
||||||
|
uint8_t wake_reason = powman_get_wake_reason();
|
||||||
|
if(wake_reason & POWMAN_WAKE_ALARM) {
|
||||||
|
return MP_ROM_INT(WAKE_TIMER);
|
||||||
|
}
|
||||||
|
if(wake_reason & POWMAN_WAKE_PWRUP0) return MP_ROM_INT(WAKE_BUTTON_A);
|
||||||
|
if(wake_reason & POWMAN_WAKE_PWRUP1) return MP_ROM_INT(WAKE_BUTTON_B);
|
||||||
|
if(wake_reason & POWMAN_WAKE_PWRUP2) return MP_ROM_INT(WAKE_BUTTON_C);
|
||||||
|
return MP_ROM_INT(WAKE_UNKNOWN);
|
||||||
|
}
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_0(_sleep_get_wake_reason_obj, _sleep_get_wake_reason);
|
||||||
|
|
||||||
|
/*! \brief Send system to sleep until the specified GPIO changes
|
||||||
|
*
|
||||||
|
* \param gpio_pin The pin to provide the wake up
|
||||||
|
* \param edge true for leading edge, false for trailing edge
|
||||||
|
* \param high true for active high, false for active low
|
||||||
|
* \param timeout wakeup after timeout milliseconds if no edge occurs
|
||||||
|
*/
|
||||||
|
mp_obj_t _sleep_goto_dormant_until_pin(size_t n_args, const mp_obj_t *args) {
|
||||||
|
enum { ARG_pin, ARG_edge, ARG_high, ARG_timeout };
|
||||||
|
|
||||||
|
uint pin = UINT16_MAX;
|
||||||
|
if(args[ARG_pin] != mp_const_none) {
|
||||||
|
pin = mp_hal_get_pin_obj(args[ARG_pin]);
|
||||||
|
}
|
||||||
|
bool edge = mp_obj_is_true(args[ARG_edge]);
|
||||||
|
bool high = mp_obj_is_true(args[ARG_high]);
|
||||||
|
uint64_t timeout_ms = 0;
|
||||||
|
|
||||||
|
if (n_args == 4) {
|
||||||
|
timeout_ms = (uint64_t)mp_obj_get_float(args[ARG_timeout]) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
powman_init();
|
||||||
|
|
||||||
|
if (pin != UINT16_MAX) {
|
||||||
|
powman_setup_gpio_wakeup(POWMAN_WAKE_PWRUP0_CH, pin, edge, high, 1000);
|
||||||
|
} else {
|
||||||
|
int err = 0;
|
||||||
|
err = powman_setup_gpio_wakeup(POWMAN_WAKE_PWRUP0_CH, 12, edge, high, 1000); // Tufty Button A
|
||||||
|
if (err == -1) {mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Timeout waiting for Button A"));}
|
||||||
|
err = powman_setup_gpio_wakeup(POWMAN_WAKE_PWRUP1_CH, 13, edge, high, 1000); // Tufty Button B
|
||||||
|
if (err == -1) {mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Timeout waiting for Button B"));}
|
||||||
|
err = powman_setup_gpio_wakeup(POWMAN_WAKE_PWRUP2_CH, 14, edge, high, 1000); // Tufty Button C
|
||||||
|
if (err == -1) {mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Timeout waiting for Button C"));}
|
||||||
|
}
|
||||||
|
|
||||||
|
// power off
|
||||||
|
int rc = 0;
|
||||||
|
if (timeout_ms > 0) {
|
||||||
|
absolute_time_t timeout = make_timeout_time_ms(timeout_ms);
|
||||||
|
rc = powman_off_until_time(timeout);
|
||||||
|
} else {
|
||||||
|
rc = powman_off();
|
||||||
|
}
|
||||||
|
hard_assert(rc == PICO_OK);
|
||||||
|
hard_assert(false); // should never get here!
|
||||||
|
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(_sleep_goto_dormant_until_pin_obj, 3, 4, _sleep_goto_dormant_until_pin);
|
||||||
|
|
||||||
|
/*! \brief Send system to dormant until the specified time, note for RP2040 the RTC must be driven by an external clock
|
||||||
|
*
|
||||||
|
* \param ts The time to wake up
|
||||||
|
* \param callback Function to call on wakeup.
|
||||||
|
*/
|
||||||
|
mp_obj_t _sleep_goto_dormant_until(mp_obj_t absolute_time_in) {
|
||||||
|
// Borrowed from https://github.com/micropython/micropython/blob/master/ports/rp2/machine_rtc.c#L83C1-L96
|
||||||
|
mp_obj_t *items;
|
||||||
|
mp_obj_get_array_fixed_n(absolute_time_in, 8, &items);
|
||||||
|
timeutils_struct_time_t tm = {
|
||||||
|
.tm_year = mp_obj_get_int(items[0]),
|
||||||
|
.tm_mon = mp_obj_get_int(items[1]),
|
||||||
|
.tm_mday = mp_obj_get_int(items[2]),
|
||||||
|
.tm_hour = mp_obj_get_int(items[4]),
|
||||||
|
.tm_min = mp_obj_get_int(items[5]),
|
||||||
|
.tm_sec = mp_obj_get_int(items[6]),
|
||||||
|
};
|
||||||
|
struct timespec ts = { 0, 0 };
|
||||||
|
ts.tv_sec = timeutils_seconds_since_epoch(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||||
|
|
||||||
|
int rc = powman_off_until_time(timespec_to_ms(&ts));
|
||||||
|
hard_assert(rc == PICO_OK);
|
||||||
|
hard_assert(false); // should never get here!
|
||||||
|
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_1(_sleep_goto_dormant_until_obj, _sleep_goto_dormant_until);
|
||||||
|
|
||||||
|
/*! \brief Send system to dormant until the specified time, note for RP2040 the RTC must be driven by an external clock
|
||||||
|
*
|
||||||
|
* \param ts The time to wake up
|
||||||
|
* \param callback Function to call on wakeup.
|
||||||
|
*/
|
||||||
|
mp_obj_t _sleep_goto_dormant_for(mp_obj_t time_seconds_in) {
|
||||||
|
uint64_t ms = (uint64_t)(mp_obj_get_float(time_seconds_in) * 1000);
|
||||||
|
int rc = powman_off_for_ms(ms);
|
||||||
|
hard_assert(rc == PICO_OK);
|
||||||
|
hard_assert(false); // should never get here!
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_1(_sleep_goto_dormant_for_obj, _sleep_goto_dormant_for);
|
||||||
|
|
||||||
|
static const mp_map_elem_t sleep_globals_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_powman) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_goto_dormant_until_pin), MP_ROM_PTR(&_sleep_goto_dormant_until_pin_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_goto_dormant_until), MP_ROM_PTR(&_sleep_goto_dormant_until_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_goto_dormant_for), MP_ROM_PTR(&_sleep_goto_dormant_for_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_get_wake_reason), MP_ROM_PTR(&_sleep_get_wake_reason_obj) },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_WAKE_BUTTON_A), MP_ROM_INT(WAKE_BUTTON_A) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_WAKE_BUTTON_B), MP_ROM_INT(WAKE_BUTTON_B) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_WAKE_BUTTON_C), MP_ROM_INT(WAKE_BUTTON_C) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_WAKE_TIMER), MP_ROM_INT(WAKE_TIMER) }, // TODO: Rename to ALARM?
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_WAKE_UNKNOWN), MP_ROM_INT(WAKE_UNKNOWN) },
|
||||||
|
};
|
||||||
|
static MP_DEFINE_CONST_DICT(mp_module_sleep_globals, sleep_globals_table);
|
||||||
|
|
||||||
|
const mp_obj_module_t sleep_user_cmodule = {
|
||||||
|
.base = { &mp_type_module },
|
||||||
|
.globals = (mp_obj_dict_t*)&mp_module_sleep_globals,
|
||||||
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_powman, sleep_user_cmodule);
|
||||||
27
modules/c/powman/micropython.cmake
Normal file
27
modules/c/powman/micropython.cmake
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
add_library(usermod_sleep INTERFACE)
|
||||||
|
|
||||||
|
target_sources(usermod_sleep INTERFACE
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/bindings.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/powman.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/rosc.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(usermod_sleep INTERFACE
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(usermod_sleep INTERFACE hardware_powman hardware_gpio)
|
||||||
|
|
||||||
|
target_link_libraries(usermod INTERFACE usermod_sleep)
|
||||||
|
|
||||||
|
#set_source_files_properties(
|
||||||
|
# ${CMAKE_CURRENT_LIST_DIR}/sleep.c
|
||||||
|
# PROPERTIES COMPILE_FLAGS
|
||||||
|
# "-Wno-maybe-uninitialized"
|
||||||
|
#)
|
||||||
|
|
||||||
|
set_source_files_properties(
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/bindings.c
|
||||||
|
PROPERTIES COMPILE_FLAGS
|
||||||
|
"-Wno-discarded-qualifiers"
|
||||||
|
)
|
||||||
150
modules/c/powman/powman.c
Normal file
150
modules/c/powman/powman.c
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
|
||||||
|
#include "powman.h"
|
||||||
|
|
||||||
|
static powman_power_state off_state;
|
||||||
|
static powman_power_state on_state;
|
||||||
|
|
||||||
|
//#define DEBUG
|
||||||
|
|
||||||
|
uint8_t powman_get_wake_reason(void) {
|
||||||
|
// 0 = chip reset, for the source of the last reset see POWMAN_CHIP_RESET
|
||||||
|
// 1 = pwrup0 (GPIO interrupt 0)
|
||||||
|
// 2 = pwrup1 (GPIO interrupt 1)
|
||||||
|
// 3 = pwrup2 (GPIO interrupt 2)
|
||||||
|
// 4 = pwrup3 (GPIO interrupt 3)
|
||||||
|
// 5 = coresight_pwrup
|
||||||
|
// 6 = alarm_pwrup (timeout or alarm wakeup)
|
||||||
|
return powman_hw->last_swcore_pwrup & 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void powman_init() {
|
||||||
|
uint64_t abs_time_ms = 1746057600000; // 2025/05/01 - Milliseconds since epoch
|
||||||
|
|
||||||
|
// Run everything from pll_usb pll and stop pll_sys
|
||||||
|
set_sys_clock_48mhz();
|
||||||
|
|
||||||
|
// Use the 32768 Hz clockout from the RTC to keep time accurately
|
||||||
|
//clock_configure_gpin(clk_ref, 12, 32.768f * KHZ, 32.768f * KHZ);
|
||||||
|
//clock_configure_gpin(clk_sys, 12, 32.768f * KHZ, 32.768f * KHZ);
|
||||||
|
//clock_configure_undivided(clk_peri, 0, CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS, 32.768f * KHZ);
|
||||||
|
//powman_timer_set_1khz_tick_source_lposc_with_hz(32768);
|
||||||
|
|
||||||
|
powman_timer_set_1khz_tick_source_lposc();
|
||||||
|
pll_deinit(pll_sys);
|
||||||
|
|
||||||
|
// Set all pins to input (as far as SIO is concerned)
|
||||||
|
gpio_set_dir_all_bits(0);
|
||||||
|
for (int i = 0; i < NUM_BANK0_GPIOS; ++i) {
|
||||||
|
gpio_set_function(i, GPIO_FUNC_SIO);
|
||||||
|
if (i > NUM_BANK0_GPIOS - NUM_ADC_CHANNELS) {
|
||||||
|
gpio_disable_pulls(i);
|
||||||
|
gpio_set_input_enabled(i, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock the VREG control interface
|
||||||
|
hw_set_bits(&powman_hw->vreg_ctrl, POWMAN_PASSWORD_BITS | POWMAN_VREG_CTRL_UNLOCK_BITS);
|
||||||
|
|
||||||
|
// Turn off USB PHY and apply pull downs on DP & DM
|
||||||
|
usb_hw->phy_direct = USB_USBPHY_DIRECT_TX_PD_BITS | USB_USBPHY_DIRECT_RX_PD_BITS | USB_USBPHY_DIRECT_DM_PULLDN_EN_BITS | USB_USBPHY_DIRECT_DP_PULLDN_EN_BITS;
|
||||||
|
|
||||||
|
usb_hw->phy_direct_override = USB_USBPHY_DIRECT_RX_DM_BITS | USB_USBPHY_DIRECT_RX_DP_BITS | USB_USBPHY_DIRECT_RX_DD_BITS |
|
||||||
|
USB_USBPHY_DIRECT_OVERRIDE_TX_DIFFMODE_OVERRIDE_EN_BITS | USB_USBPHY_DIRECT_OVERRIDE_DM_PULLUP_OVERRIDE_EN_BITS | USB_USBPHY_DIRECT_OVERRIDE_TX_FSSLEW_OVERRIDE_EN_BITS |
|
||||||
|
USB_USBPHY_DIRECT_OVERRIDE_TX_PD_OVERRIDE_EN_BITS | USB_USBPHY_DIRECT_OVERRIDE_RX_PD_OVERRIDE_EN_BITS | USB_USBPHY_DIRECT_OVERRIDE_TX_DM_OVERRIDE_EN_BITS |
|
||||||
|
USB_USBPHY_DIRECT_OVERRIDE_TX_DP_OVERRIDE_EN_BITS | USB_USBPHY_DIRECT_OVERRIDE_TX_DM_OE_OVERRIDE_EN_BITS | USB_USBPHY_DIRECT_OVERRIDE_TX_DP_OE_OVERRIDE_EN_BITS |
|
||||||
|
USB_USBPHY_DIRECT_OVERRIDE_DM_PULLDN_EN_OVERRIDE_EN_BITS | USB_USBPHY_DIRECT_OVERRIDE_DP_PULLDN_EN_OVERRIDE_EN_BITS | USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_EN_OVERRIDE_EN_BITS |
|
||||||
|
USB_USBPHY_DIRECT_OVERRIDE_DM_PULLUP_HISEL_OVERRIDE_EN_BITS | USB_USBPHY_DIRECT_OVERRIDE_DP_PULLUP_HISEL_OVERRIDE_EN_BITS;
|
||||||
|
|
||||||
|
// start powman and set the time
|
||||||
|
powman_timer_start();
|
||||||
|
powman_timer_set_ms(abs_time_ms);
|
||||||
|
|
||||||
|
// Allow power down when debugger connected
|
||||||
|
powman_set_debug_power_request_ignored(true);
|
||||||
|
|
||||||
|
// Power states
|
||||||
|
powman_power_state P1_7 = POWMAN_POWER_STATE_NONE;
|
||||||
|
|
||||||
|
powman_power_state P0_3 = POWMAN_POWER_STATE_NONE;
|
||||||
|
P0_3 = powman_power_state_with_domain_on(P0_3, POWMAN_POWER_DOMAIN_SWITCHED_CORE);
|
||||||
|
P0_3 = powman_power_state_with_domain_on(P0_3, POWMAN_POWER_DOMAIN_XIP_CACHE);
|
||||||
|
|
||||||
|
off_state = P1_7;
|
||||||
|
on_state = P0_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initiate power off
|
||||||
|
int __no_inline_not_in_flash_func(powman_off)(void) {
|
||||||
|
// Set power states
|
||||||
|
bool valid_state = powman_configure_wakeup_state(off_state, on_state);
|
||||||
|
if (!valid_state) {
|
||||||
|
return PICO_ERROR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reboot to main
|
||||||
|
powman_hw->boot[0] = 0;
|
||||||
|
powman_hw->boot[1] = 0;
|
||||||
|
powman_hw->boot[2] = 0;
|
||||||
|
powman_hw->boot[3] = 0;
|
||||||
|
|
||||||
|
// Switch to required power state
|
||||||
|
int rc = powman_set_power_state(off_state);
|
||||||
|
if (rc != PICO_OK) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Power down
|
||||||
|
while (true) __wfi();
|
||||||
|
}
|
||||||
|
|
||||||
|
int powman_setup_gpio_wakeup(int hw_wakeup, int gpio, bool edge, bool high, uint64_t timeout_ms) {
|
||||||
|
gpio_init(gpio);
|
||||||
|
gpio_set_dir(gpio, false);
|
||||||
|
gpio_set_input_enabled(gpio, true);
|
||||||
|
|
||||||
|
// Must set pulls here, or our pin may never go into its idle state
|
||||||
|
gpio_set_pulls(gpio, !high, high);
|
||||||
|
|
||||||
|
// If the pin is currently in a triggered state, wait for idle
|
||||||
|
absolute_time_t timeout = make_timeout_time_ms(timeout_ms);
|
||||||
|
if (gpio_get(gpio) == high) {
|
||||||
|
while(gpio_get(gpio) == high) {
|
||||||
|
sleep_ms(10);
|
||||||
|
if(time_reached(timeout)) return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
powman_enable_gpio_wakeup(hw_wakeup, gpio, edge, high);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Power off until a gpio goes high
|
||||||
|
int powman_off_until_gpio_high(int gpio, bool edge, bool high, uint64_t timeout_ms) {
|
||||||
|
powman_init();
|
||||||
|
|
||||||
|
powman_setup_gpio_wakeup(POWMAN_WAKE_PWRUP0_CH, gpio, edge, high, 1000);
|
||||||
|
|
||||||
|
if (timeout_ms > 0) {
|
||||||
|
uint64_t ms = powman_timer_get_ms();
|
||||||
|
return powman_off_until_time(ms + timeout_ms);
|
||||||
|
} else {
|
||||||
|
return powman_off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Power off until an absolute time
|
||||||
|
int powman_off_until_time(uint64_t absolute_time_ms) {
|
||||||
|
powman_init();
|
||||||
|
|
||||||
|
// Start powman timer and turn off
|
||||||
|
powman_enable_alarm_wakeup_at_ms(absolute_time_ms);
|
||||||
|
return powman_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Power off for a number of milliseconds
|
||||||
|
int powman_off_for_ms(uint64_t duration_ms) {
|
||||||
|
powman_init();
|
||||||
|
|
||||||
|
uint64_t ms = powman_timer_get_ms();
|
||||||
|
return powman_off_until_time(ms + duration_ms);
|
||||||
|
}
|
||||||
37
modules/c/powman/powman.h
Normal file
37
modules/c/powman/powman.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "pico/stdio.h"
|
||||||
|
#include "pico/sync.h"
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#include "hardware/powman.h"
|
||||||
|
#include "hardware/clocks.h"
|
||||||
|
#include "hardware/pll.h"
|
||||||
|
#include "hardware/adc.h"
|
||||||
|
#include "hardware/structs/usb.h"
|
||||||
|
#include "hardware/structs/xosc.h"
|
||||||
|
#include "hardware/vreg.h"
|
||||||
|
#include "hardware/flash.h"
|
||||||
|
#include "hardware/structs/qmi.h"
|
||||||
|
|
||||||
|
#define POWMAN_WAKE_PWRUP0_CH 0
|
||||||
|
#define POWMAN_WAKE_PWRUP1_CH 1
|
||||||
|
#define POWMAN_WAKE_PWRUP2_CH 2
|
||||||
|
|
||||||
|
#define POWMAN_WAKE_RESET 0b00000001
|
||||||
|
#define POWMAN_WAKE_PWRUP0 0b00000010
|
||||||
|
#define POWMAN_WAKE_PWRUP1 0b00000100
|
||||||
|
#define POWMAN_WAKE_PWRUP2 0b00001000
|
||||||
|
#define POWMAN_WAKE_PWRUP3 0b00010000
|
||||||
|
#define POWMAN_WAKE_CORESI 0b00100000
|
||||||
|
#define POWMAN_WAKE_ALARM 0b01000000
|
||||||
|
|
||||||
|
int powman_off_until_gpio_high(int gpio, bool edge, bool high, uint64_t timeout_ms);
|
||||||
|
int powman_off_until_time(uint64_t absolute_time_ms);
|
||||||
|
int powman_off_for_ms(uint64_t duration_ms);
|
||||||
|
uint8_t powman_get_wake_reason(void);
|
||||||
|
|
||||||
|
void powman_init();
|
||||||
|
int powman_setup_gpio_wakeup(int hw_wakeup, int gpio, bool edge, bool high, uint64_t timeout_ms);
|
||||||
|
int powman_off(void);
|
||||||
71
modules/c/powman/rosc.c
Normal file
71
modules/c/powman/rosc.c
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Vendored from: https://github.com/raspberrypi/pico-extras/blob/4ccfef6fe068bbae8106d0d1f072c7f997472040/src/rp2_common/hardware_rosc/rosc.c
|
||||||
|
|
||||||
|
#include "pico.h"
|
||||||
|
|
||||||
|
// For MHZ definitions etc
|
||||||
|
#include "hardware/clocks.h"
|
||||||
|
#include "rosc.h"
|
||||||
|
|
||||||
|
// Given a ROSC delay stage code, return the next-numerically-higher code.
|
||||||
|
// Top result bit is set when called on maximum ROSC code.
|
||||||
|
uint32_t next_rosc_code(uint32_t code) {
|
||||||
|
return ((code | 0x08888888u) + 1u) & 0xf7777777u;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint rosc_find_freq(uint32_t low_mhz, uint32_t high_mhz) {
|
||||||
|
// TODO: This could be a lot better
|
||||||
|
rosc_set_div(1);
|
||||||
|
for (uint32_t code = 0; code <= 0x77777777u; code = next_rosc_code(code)) {
|
||||||
|
rosc_set_freq(code);
|
||||||
|
uint rosc_mhz = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC) / 1000;
|
||||||
|
if ((rosc_mhz >= low_mhz) && (rosc_mhz <= high_mhz)) {
|
||||||
|
return rosc_mhz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rosc_set_div(uint32_t div) {
|
||||||
|
assert(div <= 31 && div >= 1);
|
||||||
|
rosc_write(&rosc_hw->div, ROSC_DIV_VALUE_PASS + div);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rosc_set_freq(uint32_t code) {
|
||||||
|
rosc_write(&rosc_hw->freqa, (ROSC_FREQA_PASSWD_VALUE_PASS << ROSC_FREQA_PASSWD_LSB) | (code & 0xffffu));
|
||||||
|
rosc_write(&rosc_hw->freqb, (ROSC_FREQA_PASSWD_VALUE_PASS << ROSC_FREQA_PASSWD_LSB) | (code >> 16u));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rosc_set_range(uint range) {
|
||||||
|
// Range should use enumvals from the headers and thus have the password correct
|
||||||
|
rosc_write(&rosc_hw->ctrl, (ROSC_CTRL_ENABLE_VALUE_ENABLE << ROSC_CTRL_ENABLE_LSB) | range);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rosc_disable(void) {
|
||||||
|
uint32_t tmp = rosc_hw->ctrl;
|
||||||
|
tmp &= (~ROSC_CTRL_ENABLE_BITS);
|
||||||
|
tmp |= (ROSC_CTRL_ENABLE_VALUE_DISABLE << ROSC_CTRL_ENABLE_LSB);
|
||||||
|
rosc_write(&rosc_hw->ctrl, tmp);
|
||||||
|
// Wait for stable to go away
|
||||||
|
while(rosc_hw->status & ROSC_STATUS_STABLE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rosc_set_dormant(void) {
|
||||||
|
// WARNING: This stops the rosc until woken up by an irq
|
||||||
|
rosc_write(&rosc_hw->dormant, ROSC_DORMANT_VALUE_DORMANT);
|
||||||
|
// Wait for it to become stable once woken up
|
||||||
|
while(!(rosc_hw->status & ROSC_STATUS_STABLE_BITS));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rosc_enable(void) {
|
||||||
|
//Re-enable the rosc
|
||||||
|
rosc_write(&rosc_hw->ctrl, ROSC_CTRL_ENABLE_BITS);
|
||||||
|
|
||||||
|
//Wait for it to become stable once restarted
|
||||||
|
while (!(rosc_hw->status & ROSC_STATUS_STABLE_BITS));
|
||||||
|
}
|
||||||
94
modules/c/powman/rosc.h
Normal file
94
modules/c/powman/rosc.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Vendored from: https://github.com/raspberrypi/pico-extras/blob/4ccfef6fe068bbae8106d0d1f072c7f997472040/src/rp2_common/hardware_rosc/include/hardware/rosc.h
|
||||||
|
|
||||||
|
#ifndef _HARDWARE_ROSC_H_
|
||||||
|
#define _HARDWARE_ROSC_H_
|
||||||
|
|
||||||
|
#include "pico.h"
|
||||||
|
#include "hardware/structs/rosc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \file rosc.h
|
||||||
|
* \defgroup hardware_rosc hardware_rosc
|
||||||
|
*
|
||||||
|
* Ring Oscillator (ROSC) API
|
||||||
|
*
|
||||||
|
* A Ring Oscillator is an on-chip oscillator that requires no external crystal. Instead, the output is generated from a series of
|
||||||
|
* inverters that are chained together to create a feedback loop. RP2040 boots from the ring oscillator initially, meaning the
|
||||||
|
* first stages of the bootrom, including booting from SPI flash, will be clocked by the ring oscillator. If your design has a
|
||||||
|
* crystal oscillator, you’ll likely want to switch to this as your reference clock as soon as possible, because the frequency is
|
||||||
|
* more accurate than the ring oscillator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \brief Set frequency of the Ring Oscillator
|
||||||
|
* \ingroup hardware_rosc
|
||||||
|
*
|
||||||
|
* \param code The drive strengths. See the RP2040 datasheet for information on this value.
|
||||||
|
*/
|
||||||
|
void rosc_set_freq(uint32_t code);
|
||||||
|
|
||||||
|
/*! \brief Set range of the Ring Oscillator
|
||||||
|
* \ingroup hardware_rosc
|
||||||
|
*
|
||||||
|
* Frequency range. Frequencies will vary with Process, Voltage & Temperature (PVT).
|
||||||
|
* Clock output will not glitch when changing the range up one step at a time.
|
||||||
|
*
|
||||||
|
* \param range 0x01 Low, 0x02 Medium, 0x03 High, 0x04 Too High.
|
||||||
|
*/
|
||||||
|
void rosc_set_range(uint range);
|
||||||
|
|
||||||
|
/*! \brief Disable the Ring Oscillator
|
||||||
|
* \ingroup hardware_rosc
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void rosc_disable(void);
|
||||||
|
|
||||||
|
/*! \brief Put Ring Oscillator in to dormant mode.
|
||||||
|
* \ingroup hardware_rosc
|
||||||
|
*
|
||||||
|
* The ROSC supports a dormant mode,which stops oscillation until woken up up by an asynchronous interrupt.
|
||||||
|
* This can either come from the RTC, being clocked by an external clock, or a GPIO pin going high or low.
|
||||||
|
* If no IRQ is configured before going into dormant mode the ROSC will never restart.
|
||||||
|
*
|
||||||
|
* PLLs should be stopped before selecting dormant mode.
|
||||||
|
*/
|
||||||
|
void rosc_set_dormant(void);
|
||||||
|
|
||||||
|
// FIXME: Add doxygen
|
||||||
|
|
||||||
|
uint32_t next_rosc_code(uint32_t code);
|
||||||
|
|
||||||
|
uint rosc_find_freq(uint32_t low_mhz, uint32_t high_mhz);
|
||||||
|
|
||||||
|
void rosc_set_div(uint32_t div);
|
||||||
|
|
||||||
|
inline static void rosc_clear_bad_write(void) {
|
||||||
|
hw_clear_bits(&rosc_hw->status, ROSC_STATUS_BADWRITE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static bool rosc_write_okay(void) {
|
||||||
|
return !(rosc_hw->status & ROSC_STATUS_BADWRITE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void rosc_write(io_rw_32 *addr, uint32_t value) {
|
||||||
|
rosc_clear_bad_write();
|
||||||
|
assert(rosc_write_okay());
|
||||||
|
*addr = value;
|
||||||
|
assert(rosc_write_okay());
|
||||||
|
};
|
||||||
|
|
||||||
|
void rosc_enable(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
18
modules/c/wakeup/micropython.cmake
Normal file
18
modules/c/wakeup/micropython.cmake
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
add_library(usermod_wakeup INTERFACE)
|
||||||
|
|
||||||
|
target_sources(usermod_wakeup INTERFACE
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/wakeup.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/wakeup.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(usermod_wakeup INTERFACE
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(usermod INTERFACE usermod_wakeup)
|
||||||
|
|
||||||
|
set_source_files_properties(
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/wakeup.c
|
||||||
|
PROPERTIES COMPILE_FLAGS
|
||||||
|
"-Wno-discarded-qualifiers"
|
||||||
|
)
|
||||||
21
modules/c/wakeup/wakeup.c
Normal file
21
modules/c/wakeup/wakeup.c
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "wakeup.h"
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#include "pico/runtime_init.h"
|
||||||
|
|
||||||
|
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_1(Wakeup_get_gpio_state_obj, Wakeup_get_gpio_state);
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_0(Wakeup_reset_gpio_state_obj, Wakeup_reset_gpio_state);
|
||||||
|
|
||||||
|
static const mp_map_elem_t wakeup_globals_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wakeup) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_get_gpio_state), MP_ROM_PTR(&Wakeup_get_gpio_state_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_reset_gpio_state), MP_ROM_PTR(&Wakeup_reset_gpio_state_obj) },
|
||||||
|
};
|
||||||
|
static MP_DEFINE_CONST_DICT(mp_module_wakeup_globals, wakeup_globals_table);
|
||||||
|
|
||||||
|
const mp_obj_module_t wakeup_user_cmodule = {
|
||||||
|
.base = { &mp_type_module },
|
||||||
|
.globals = (mp_obj_dict_t*)&mp_module_wakeup_globals,
|
||||||
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_wakeup, wakeup_user_cmodule);
|
||||||
27
modules/c/wakeup/wakeup.cpp
Normal file
27
modules/c/wakeup/wakeup.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
|
||||||
|
|
||||||
|
uint64_t gpio_state = 0;
|
||||||
|
|
||||||
|
static void __attribute__((constructor(101))) latch_inputs() {
|
||||||
|
gpio_set_function_masked64(0xffffffffffffffff, GPIO_FUNC_SIO);
|
||||||
|
gpio_state = gpio_get_all64();
|
||||||
|
sleep_ms(5);
|
||||||
|
gpio_state |= gpio_get_all64();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "wakeup.h"
|
||||||
|
|
||||||
|
mp_obj_t Wakeup_get_gpio_state(mp_obj_t button_in) {
|
||||||
|
int button = mp_obj_get_int(button_in);
|
||||||
|
return (gpio_state & (1 << button)) ? mp_const_true : mp_const_false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t Wakeup_reset_gpio_state() {
|
||||||
|
gpio_state = 0;
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
5
modules/c/wakeup/wakeup.h
Normal file
5
modules/c/wakeup/wakeup.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "py/runtime.h"
|
||||||
|
#include "py/objstr.h"
|
||||||
|
|
||||||
|
extern mp_obj_t Wakeup_get_gpio_state(mp_obj_t button_in);
|
||||||
|
extern mp_obj_t Wakeup_reset_gpio_state();
|
||||||
Loading…
Reference in New Issue
Block a user