Skip to content

Commit

Permalink
Merge branch 'time_hardware_pulse_us' into PWM_and_Time_hardware_puls…
Browse files Browse the repository at this point in the history
…e_and_Test
  • Loading branch information
IhorNehrutsa committed Dec 19, 2024
2 parents 824b5ee + b6bcf72 commit 9895881
Show file tree
Hide file tree
Showing 32 changed files with 671 additions and 171 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/ports_zephyr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,26 @@ jobs:
docker-images: false
swap-storage: false
- uses: actions/checkout@v4
- id: versions
name: Read Zephyr version
run: source tools/ci.sh && echo "ZEPHYR=$ZEPHYR_VERSION" | tee "$GITHUB_OUTPUT"
- name: Cached Zephyr Workspace
id: cache_workspace
uses: actions/cache@v4
with:
# note that the Zephyr CI docker image is 15GB. At time of writing
# GitHub caches are limited to 10GB total for a project. So we only
# cache the "workspace"
path: ./zephyrproject
key: zephyr-workspace-${{ steps.versions.outputs.ZEPHYR }}
- name: ccache
uses: hendrikmuhs/[email protected]
with:
key: zephyr
- name: Install packages
run: source tools/ci.sh && ci_zephyr_setup
- name: Install Zephyr
if: steps.cache_workspace.outputs.cache-hit != 'true'
run: source tools/ci.sh && ci_zephyr_install
- name: Build
run: source tools/ci.sh && ci_zephyr_build
Expand Down
13 changes: 8 additions & 5 deletions docs/library/machine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -181,19 +181,22 @@ Miscellaneous functions
varies by hardware (so use substring of a full value if you expect a short
ID). In some MicroPython ports, ID corresponds to the network MAC address.

.. function:: time_pulse_us(pin, pulse_level, timeout_us=1000000, /)
.. function:: time_pulse_us(pin, pulse_level, timeout_us=1000000, wait_opposite=false, /)

Time a pulse on the given *pin*, and return the duration of the pulse in
microseconds. The *pulse_level* argument should be 0 to time a low pulse
or 1 to time a high pulse.

If the current input value of the pin is different to *pulse_level*,
the function first (*) waits until the pin input becomes equal to *pulse_level*,
then (**) times the duration that the pin is equal to *pulse_level*.
If *wait_opposite* is true, if the pin is initially equal to *pulse_level* then first
waits until the pin input becomes different from *pulse_level* (***).
Then if the current input value of the pin is different to *pulse_level*,
the function first (**) waits until the pin input becomes equal to *pulse_level*,
then (*) times the duration that the pin is equal to *pulse_level*.
If the pin is already equal to *pulse_level* then timing starts straight away.

The function returns -3 if there was timeout waiting for condition marked (***) above.
The function will return -2 if there was timeout waiting for condition marked
(*) above, and -1 if there was timeout during the main measurement, marked (**)
(**) above, and -1 if there was timeout during the main measurement, marked (*)
above. The timeout is the same for both cases and given by *timeout_us* (which
is in microseconds).

Expand Down
4 changes: 2 additions & 2 deletions extmod/moductypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ static mp_obj_t uctypes_struct_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
uint agg_type = GET_TYPE(offset, AGG_TYPE_BITS);
if (agg_type == PTR) {
byte *p = *(void **)self->addr;
return mp_obj_new_int((mp_int_t)(uintptr_t)p);
return mp_obj_new_int_from_uint((uintptr_t)p);
}
}
MP_FALLTHROUGH
Expand All @@ -629,7 +629,7 @@ static mp_int_t uctypes_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo,
static mp_obj_t uctypes_struct_addressof(mp_obj_t buf) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
return mp_obj_new_int((mp_int_t)(uintptr_t)bufinfo.buf);
return mp_obj_new_int_from_uint((uintptr_t)bufinfo.buf);
}
MP_DEFINE_CONST_FUN_OBJ_1(uctypes_struct_addressof_obj, uctypes_struct_addressof);

Expand Down
2 changes: 1 addition & 1 deletion ports/esp8266/modmachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
);

// Custom version of this function that feeds system WDT if necessary
mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us) {
mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us, bool wait_opposite) {
int nchanges = 2;
uint32_t start = system_get_time(); // in microseconds
for (;;) {
Expand Down
4 changes: 0 additions & 4 deletions ports/qemu/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ void gc_collect(void) {
gc_collect_end();
}

mp_lexer_t *mp_lexer_new_from_file(qstr filename) {
mp_raise_OSError(MP_ENOENT);
}

void nlr_jump_fail(void *val) {
mp_printf(&mp_plat_print, "uncaught NLR\n");
exit(1);
Expand Down
3 changes: 2 additions & 1 deletion ports/qemu/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,14 @@
#endif

#define MICROPY_MALLOC_USES_ALLOCATED_SIZE (1)
#define MICROPY_PERSISTENT_CODE_LOAD (1)
#define MICROPY_MEM_STATS (1)
#define MICROPY_READER_VFS (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
#define MICROPY_WARNINGS (1)
#define MICROPY_PY_IO_IOBASE (0)
#define MICROPY_PY_SYS_PLATFORM "qemu"
#define MICROPY_PY_SYS_STDIO_BUFFER (0)
#define MICROPY_PY_SELECT (0)
Expand Down
12 changes: 6 additions & 6 deletions ports/stm32/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -640,15 +640,15 @@ $(BUILD)/%_$(BOARD).c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(HEADER_
--output-source $(GEN_PINS_SRC) --output-header $(GEN_PINS_HDR) \
--output-af-const $(GEN_PINS_AF_CONST) --output-af-defs $(GEN_PINS_AF_DEFS)

powerctrl.c: $(GEN_PLLFREQTABLE_HDR)
$(GEN_PLLFREQTABLE_HDR): $(PLLVALUES) | $(HEADER_BUILD)
$(BUILD)/powerctrl.o: $(GEN_PLLFREQTABLE_HDR)
$(GEN_PLLFREQTABLE_HDR): $(PLLVALUES) | $(HEADER_BUILD)/qstr.i.last
$(ECHO) "GEN $@"
$(Q)$(PYTHON) $(PLLVALUES) -c -m $(CMSIS_MCU_LOWER) file:$(BOARD_DIR)/stm32$(MCU_SERIES)xx_hal_conf.h > $@
$(Q)$(PYTHON) $(PLLVALUES) -c -m $(CMSIS_MCU_LOWER) file:$(HEADER_BUILD)/qstr.i.last > $@

$(TOP)/extmod/machine_i2s.c: $(GEN_PLLI2STABLE_HDR)
$(GEN_PLLI2STABLE_HDR): $(PLLI2SVALUES) | $(HEADER_BUILD)
$(BUILD)/extmod/machine_i2s.o: $(GEN_PLLI2STABLE_HDR)
$(GEN_PLLI2STABLE_HDR): $(PLLI2SVALUES) | $(HEADER_BUILD)/qstr.i.last
$(ECHO) "GEN $@"
$(Q)$(PYTHON) $(PLLI2SVALUES) -c -m $(CMSIS_MCU_LOWER) hse:$(BOARD_DIR)/stm32$(MCU_SERIES)xx_hal_conf.h pllm:$(BOARD_DIR)/mpconfigboard.h > $@
$(Q)$(PYTHON) $(PLLI2SVALUES) -c -m $(CMSIS_MCU_LOWER) file:$(HEADER_BUILD)/qstr.i.last > $@

$(BUILD)/modstm.o: $(GEN_STMCONST_HDR)
$(HEADER_BUILD)/modstm_const.h: $(CMSIS_MCU_HDR) make-stmconst.py | $(HEADER_BUILD)
Expand Down
55 changes: 55 additions & 0 deletions ports/stm32/boards/WEACT_F411_BLACKPILL/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
WeAct F411 'blackpill'
======================

The WeAct F411 blackpill board comes in a number of versions and variants.
All have a footprint for a SPI flash chip on the back, though the board is
often sold without any flash chip loaded.

At the time of writing (Sep 2024) v3.1 is the current version.
This version is sold with both 25Mhz HSE crystal (same as previous versions) and also
with a 8Mhz crystal. The end user should be careful to confirm which variant is
purchased and/or read the markings on the crystal to know which variant build to load.

The previous v2.0 boards had changed the MCU pinout for the spi flash chip so requires
soft-spi support enabled in the variant settings, unlike v3.1 or v1.3 which is
compatible with the hardware spi peripheral.

The original v1.3 boards did not include a user switch on the top, it only has
"BOOT0" and "NRST" switches to load bootloader and reset the board respectively.

For more information see: https://github.com/WeActStudio/WeActStudio.MiniSTM32F4x1

Note: The pins used by features like spiflash and USB are also broken out to the
gpio headers on the sides of the board.
If these peripherals / features are enabled then these external pins must be avoided to ensure
there are no conflicts. [pins.csv](pins.csv) should be consulted to check all pins assigned
to alternate functions on the board.

Customising the build
---------------------

After purchasing a board without any spiflash chip loaded the user can solder on
their own of any desired size. Most brands of spiflash in SO8 pinout are compatible
however some do have a slightly different protocol so may not work out of the box
with micropython. Brand compatibility is outide the scope of this doc.

Once a custom spiflash chip has been loaded onto the board micropython should
be built with the flash size specified. After doing so the spiflash chip will
be used for the FAT/LFS main filesystem.

Examples:

For a v3.1 / 25Mhz (default version) board with 16MiB flash chip loaded:
``` bash
make -C ports/stm32 BOARD=WEACT_F411_BLACKPILL SPI_FLASH_SIZE_MB=16
```

For a v3.1 / 8Mhz board with 4MiB flash chip loaded:
``` bash
make -C ports/stm32 BOARD=WEACT_F411_BLACKPILL BOARD_VARIANT=V31_XTAL_8M SPI_FLASH_SIZE_MB=4
```

For a v1.3 board with 2MiB flash chip loaded and XTAL manually replaced with 8Mhz:
``` bash
make -C ports/stm32 BOARD=WEACT_F411_BLACKPILL BOARD_VARIANT=V13 SPI_FLASH_SIZE_MB=2 XTAL_FREQ_MHZ=8
```
45 changes: 45 additions & 0 deletions ports/stm32/boards/WEACT_F411_BLACKPILL/bdev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "storage.h"
#include "spi.h"
#include "py/mpconfig.h"

#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE

#if WEACT_F411_V20
// External SPI flash uses SPI interface, but not on all HW spi pins.
static const mp_soft_spi_obj_t spi_bus = {
.delay_half = MICROPY_HW_SOFTSPI_MIN_DELAY,
.polarity = 0,
.phase = 0,
.sck = MICROPY_HW_SPIFLASH_SCK,
.mosi = MICROPY_HW_SPIFLASH_MOSI,
.miso = MICROPY_HW_SPIFLASH_MISO,
};

#else // WEACT_F411_V1.3 or WEACT_F411_V3.1
static const spi_proto_cfg_t spi_bus = {
.spi = &spi_obj[0], // SPI1
.baudrate = 25000000,
.polarity = 0,
.phase = 0,
.bits = 8,
.firstbit = SPI_FIRSTBIT_MSB,
};
#endif

#if MICROPY_HW_SPIFLASH_ENABLE_CACHE
static mp_spiflash_cache_t spi_bdev_cache;
#endif

const mp_spiflash_config_t spiflash_config = {
.bus_kind = MP_SPIFLASH_BUS_SPI,
.bus.u_spi.cs = MICROPY_HW_SPIFLASH_CS,
.bus.u_spi.data = (void *)&spi_bus,
.bus.u_spi.proto = &spi_proto,
#if MICROPY_HW_SPIFLASH_ENABLE_CACHE
.cache = &spi_bdev_cache,
#endif
};

spi_bdev_t spi_bdev;

#endif
22 changes: 22 additions & 0 deletions ports/stm32/boards/WEACT_F411_BLACKPILL/board.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"deploy": [
"../PYBV10/deploy.md"
],
"docs": "",
"features": [],
"images": [
"WEACTV20_F411.jpg"
],
"mcu": "stm32f411",
"product": "WeAct F411 'blackpill'. Default variant is v3.1 with no SPI Flash.",
"thumbnail": "",
"url": "https://github.com/WeActStudio/WeActStudio.MiniSTM32F4x1",
"variants": {
"V13": "v1.3 board with no SPI Flash",
"V13_FLASH_4M": "v1.3 board with 4MB SPI Flash",
"V20_FLASH_4M": "v2.0 board with 4MB SPI Flash",
"V31_FLASH_8M": "v3.1 board with 8MB SPI Flash",
"V31_XTAL_8M": "v3.1 board with 8MHz crystal"
},
"vendor": "WeAct Studio"
}
112 changes: 112 additions & 0 deletions ports/stm32/boards/WEACT_F411_BLACKPILL/mpconfigboard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// based off the following two repositories:
// * https://github.com/mcauser/WEACT_F411CEU6
// * https://github.com/YXZhu/micropython

#define MICROPY_HW_BOARD_NAME "WEACT_F411_BLACKPILL"
#define MICROPY_HW_MCU_NAME "STM32F411CE"
#define MICROPY_HW_FLASH_FS_LABEL "WEACT_F411_BLACKPILL"

// some users having issues with FLASH_LATENCY_2, so set to 3
// from https://forum.micropython.org/viewtopic.php?t=7154
#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_3

#define MICROPY_HW_HAS_FLASH (1)
#define MICROPY_HW_ENABLE_RTC (1)
#define MICROPY_HW_ENABLE_USB (1)
#define MICROPY_HW_USB_FS (1)

// Switch
#if WEACT_F411_V13
#define MICROPY_HW_HAS_SWITCH (0)
#else
#define MICROPY_HW_HAS_SWITCH (1)
#define MICROPY_HW_USRSW_PIN (pyb_pin_SW)
#define MICROPY_HW_USRSW_PULL (GPIO_PULLUP)
#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING)
#define MICROPY_HW_USRSW_PRESSED (0)
#endif

// LEDs
#define MICROPY_HW_LED1 (pyb_pin_LED_BLUE)
#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin))
#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin))

// RTC
#define MICROPY_HW_RTC_USE_LSE (1)
#define MICROPY_HW_RTC_USE_US (0)
#define MICROPY_HW_RTC_USE_CALOUT (1)

// Set PLLM same as HSE in MHZ.
#define MICROPY_HW_CLK_PLLM (MICROPY_HW_HSE_SPEED_MHZ)
// Configure PLL for final CPU freq of 96MHz
#define MICROPY_HW_CLK_PLLN (192)
#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2)
#define MICROPY_HW_CLK_PLLQ (4)

// UART config
#define MICROPY_HW_UART1_TX (pin_A9)
#define MICROPY_HW_UART1_RX (pin_A10)

#define MICROPY_HW_UART2_TX (pin_A2)
#define MICROPY_HW_UART2_RX (pin_A3)

#define MICROPY_HW_UART_REPL (PYB_UART_1)
#define MICROPY_HW_UART_REPL_BAUD (115200)

// I2C bus
#define MICROPY_HW_I2C1_SCL (pin_B6)
#define MICROPY_HW_I2C1_SDA (pin_B7)
#define MICROPY_HW_I2C2_SCL (pin_B10)
#define MICROPY_HW_I2C2_SDA (pin_B9)
#define MICROPY_HW_I2C3_SCL (pin_A8)
#define MICROPY_HW_I2C3_SDA (pin_B8)

// SPI bus
// SPI 1 is generally used for the SPI flash if enabled below.
#define MICROPY_HW_SPI1_NSS (pin_A4)
#define MICROPY_HW_SPI1_SCK (pin_A5)
#define MICROPY_HW_SPI1_MISO (pin_A6)
#define MICROPY_HW_SPI1_MOSI (pin_A7)

#define MICROPY_HW_SPI2_NSS (pin_B12)
#define MICROPY_HW_SPI2_SCK (pin_B13)
#define MICROPY_HW_SPI2_MISO (pin_B14)
#define MICROPY_HW_SPI2_MOSI (pin_B15)

// SPI 3 is not accessible if SPI flash module is used on V2.0 (PB4 conflict)
#define MICROPY_HW_SPI3_NSS (pin_A15)
#define MICROPY_HW_SPI3_SCK (pin_B3)
#define MICROPY_HW_SPI3_MISO (pin_B4)
#define MICROPY_HW_SPI3_MOSI (pin_B5)

// External SPI Flash configuration

#if !MICROPY_HW_SPIFLASH_SIZE_BYTES
// Use internal filesystem if spiflash not enabled.
#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1)

#else
// Disable internal filesystem to use spiflash.
#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0)

// SPI flash pins
#define MICROPY_HW_SPIFLASH_CS (pyb_pin_FLASH_CS)
#define MICROPY_HW_SPIFLASH_SCK (pyb_pin_FLASH_SCK)
#define MICROPY_HW_SPIFLASH_MOSI (pyb_pin_FLASH_MOSI)
#if WEACT_F411_V13
#define MICROPY_HW_SPIFLASH_MISO (pyb_pin_FLASH_MISO_V13)
#elif WEACT_F411_V20
#define MICROPY_HW_SPIFLASH_MISO (pyb_pin_FLASH_MISO_V20)
#else
#define MICROPY_HW_SPIFLASH_MISO (pyb_pin_FLASH_MISO_V31)
#endif

extern const struct _mp_spiflash_config_t spiflash_config;
extern struct _spi_bdev_t spi_bdev;
#define MICROPY_HW_SPIFLASH_ENABLE_CACHE (1)
#define MICROPY_HW_BDEV_SPIFLASH (&spi_bdev)
#define MICROPY_HW_BDEV_SPIFLASH_CONFIG (&spiflash_config)
#define MICROPY_HW_BDEV_SPIFLASH_SIZE_BYTES (MICROPY_HW_SPIFLASH_SIZE_BITS / 8)
#define MICROPY_HW_BDEV_SPIFLASH_EXTENDED (&spi_bdev) // for extended block protocol
#define MICROPY_HW_SPIFLASH_SIZE_BITS (MICROPY_HW_SPIFLASH_SIZE_BYTES * 8)
#endif
Loading

0 comments on commit 9895881

Please sign in to comment.