summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriabdalkader <i.abdalkader@gmail.com>2025-01-09 19:58:25 +0100
committerDamien George <damien@micropython.org>2025-04-09 00:22:32 +1000
commit82bae652eb43ac3ce8226d08c1ce0047ffa76191 (patch)
tree7be4a3685ec08274d7182785a72c6888cd446393
parent039df0c884ef0169257b3ab31255be8cd45caacf (diff)
alif: Add support for pin alternate function selection.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
-rw-r--r--ports/alif/alif.mk2
-rw-r--r--ports/alif/mcu/ensemble_pin_alt.csv130
-rwxr-xr-xports/alif/mcu/make-pins.py28
-rw-r--r--ports/alif/mphalport.c50
-rw-r--r--ports/alif/mphalport.h41
5 files changed, 242 insertions, 9 deletions
diff --git a/ports/alif/alif.mk b/ports/alif/alif.mk
index 35f316cae..b338e67c6 100644
--- a/ports/alif/alif.mk
+++ b/ports/alif/alif.mk
@@ -51,6 +51,7 @@ INC += -Itinyusb_port
GEN_PIN_MKPINS = mcu/make-pins.py
GEN_PIN_PREFIX = mcu/pins_prefix.c
GEN_PINS_BOARD_CSV = $(BOARD_DIR)/pins.csv
+GEN_PINS_MCU_CSV = mcu/ensemble_pin_alt.csv
GEN_PINS_SRC = $(BUILD)/pins_board.c
GEN_PINS_HDR = $(HEADER_BUILD)/pins_board.h
@@ -263,6 +264,7 @@ $(BUILD)/firmware.bin: $(BUILD)/firmware.elf
$(BUILD)/%_board.c $(HEADER_BUILD)/%_board.h: $(BOARD_DIR)/%.csv $(GEN_PIN_MKPINS) $(GEN_PIN_PREFIX) | $(HEADER_BUILD)
$(ECHO) "GEN $@"
$(Q)$(PYTHON) $(GEN_PIN_MKPINS) \
+ --af-csv $(GEN_PINS_MCU_CSV) \
--board-csv $(GEN_PINS_BOARD_CSV) \
--prefix $(GEN_PIN_PREFIX) \
--output-source $(GEN_PINS_SRC) \
diff --git a/ports/alif/mcu/ensemble_pin_alt.csv b/ports/alif/mcu/ensemble_pin_alt.csv
new file mode 100644
index 000000000..10bfedc9a
--- /dev/null
+++ b/ports/alif/mcu/ensemble_pin_alt.csv
@@ -0,0 +1,130 @@
+Pin,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7
+P0_0,,OSPI,UART,I3C,UT,LPCAM,CAM,ANA
+P0_1,,OSPI,UART,I3C,UT,LPCAM,CAM,ANA
+P0_2,,OSPI,UART,I2C,UT,LPCAM,CAM,ANA
+P0_3,,OSPI,UART,I2C,UT,LPCAM,CAM,ANA
+P0_4,,OSPI,UART,PDM,I2C,UT,,ANA
+P0_5,,OSPI,UART,PDM,I2C,UT,,ANA
+P0_6,,OSPI,UART,PDM,I2C,UT,,ANA
+P0_7,,OSPI,UART,PDM,I2C,UT,CDC,ANA
+P1_0,,UART,SPI,I2C,UT,LPCAM,ETH,ANA
+P1_1,,UART,SPI,I2C,UT,LPCAM,ETH,ANA
+P1_2,,UART,SPI,I3C,UT,LPCAM,ETH,ANA
+P1_3,,UART,SPI,I3C,UT,LPCAM,ETH,ANA
+P1_4,,OSPI,UART,SPI,UT,LPCAM,ETH,ANA
+P1_5,,OSPI,UART,SPI,UT,LPCAM,ETH,ANA
+P1_6,,OSPI,UART,I2S,UT,LPCAM,ETH,ANA
+P1_7,,OSPI,UART,I2S,UT,LPCAM,ETH,ANA
+P2_0,,OSPI,UART,LPPDM,UT,LPCAM,ETH,ANA
+P2_1,,OSPI,UART,LPPDM,UT,LPCAM,ETH,ANA
+P2_2,,OSPI,UART,LPPDM,UT,LPCAM,ETH,ANA
+P2_3,,OSPI,UART,LPPDM,UT,LPCAM,CDC,ANA
+P2_4,,OSPI,LPI2S,SPI,UT,LPCAM,CAM,ANA
+P2_5,,OSPI,LPI2S,SPI,UT,LPCAM,CAM,ANA
+P2_6,,OSPI,LPI2S,SPI,UT,LPCAM,CAM,ANA
+P2_7,,OSPI,LPI2S,SPI,UT,LPCAM,CAM,ANA
+P3_0,,OSPI,UART,PDM,I2S,QEC,LPCAM,CAM
+P3_1,,OSPI,UART,PDM,I2S,QEC,LPCAM,CAM
+P3_2,,OSPI,PDM,I2S,I3C,QEC,LPCAM,CAM
+P3_3,,OSPI,PDM,I2S,I3C,QEC,LPCAM,CAM
+P3_4,,OSPI,UART,LPPDM,I2S,I2C,QEC,CAM
+P3_5,,OSPI,UART,LPPDM,SPI,I2C,QEC,CAM
+P3_6,,HFXO,LPUART,LPPDM,SPI,I2C,QEC,CAM
+P3_7,,JTAG,LPUART,LPPDM,SPI,I2C,QEC,CAM
+P4_0,,JTAG,,I2S,SPI,QEC,CDC,CAM
+P4_1,,JTAG,I2S,SPI,QEC,SD,CDC,CAM
+P4_2,,JTAG,,I2S,SPI,QEC,SD,CAM
+P4_3,,JTAG,,I2S,SPI,QEC,SD,CAM
+P4_4,,JTAG,I2S,SPI,FAULT,,,
+P4_5,,JTAG,SPI,FAULT,,,,
+P4_6,,JTAG,SPI,FAULT,,,,
+P4_7,,JTAG,SPI,FAULT,,,,
+P5_0,,OSPI,UART,PDM,SPI,I2C,UT,SD
+P5_1,,OSPI,UART,PDM,SPI,I2C,UT,SD
+P5_2,,OSPI,UART,PDM,SPI,LPI2C,UT,SD
+P5_3,,OSPI,UART,SPI,LPI2C,UT,SD,CDC
+P5_4,,OSPI,UART,PDM,SPI,UT,SD,CDC
+P5_5,,OSPI,UART,PDM,UT,SD,ETH,CDC
+# P5_6 doesn't really have OSPI on AF1 but it's needed for P10_7 to be in OSPI mode
+P5_6,,OSPI,UART,I2C,UT,SD,ETH,CDC
+P5_7,,OSPI,UART,I2C,UT,SD,ETH,
+P6_0,,OSPI,UART,PDM,UT,SD,ETH,
+P6_1,,OSPI,UART,PDM,UT,SD,ETH,
+P6_2,,OSPI,UART,,PDM,UT,SD,ETH
+P6_3,,OSPI,UART,,PDM,UT,SD,ETH
+P6_4,,OSPI,UART,,SPI,UT,SD,ETH
+P6_5,,OSPI,UART,,SPI,UT,SD,ETH
+P6_6,,OSPI,UART,,SPI,UT,SD,ETH
+P6_7,,OSPI,UART,PDM,SPI,UT,SD,ETH
+P7_0,,,CMP,SPI,I2C,UT,SD,
+P7_1,,,CMP,SPI,I2C,UT,SD,
+P7_2,,,UART,CMP,SPI,I2C,UT,SD
+P7_3,,,UART,CMP,SPI,I2C,UT,
+P7_4,,,LPUART,LPPDM,LPSPI,LPI2C,UT,
+P7_5,,,LPUART,,LPPDM,LPSPI,LPI2C,UT
+P7_6,,,LPUART,,LPPDM,LPSPI,I3C,UT
+P7_7,,,LPUART,,LPPDM,LPSPI,I3C,UT
+P8_0,,OSPI,AUDIO,FAULT,LPCAM,SD,CDC,CAM
+P8_1,,I2S,FAULT,LPCAM,SD,CDC,CAM,
+P8_2,,I2S,SPI,FAULT,LPCAM,SD,CDC,CAM
+P8_3,,I2S,SPI,FAULT,LPCAM,SD,CDC,CAM
+P8_4,,I2S,SPI,QEC,LPCAM,SD,CDC,CAM
+P8_5,,,SPI,QEC,LPCAM,SD,CDC,CAM
+P8_6,,,I2S,QEC,LPCAM,SD,CDC,CAM
+P8_7,,,I2S,QEC,LPCAM,SD,CDC,CAM
+P9_0,,,I2S,QEC,SD,CDC,CAM,
+P9_1,,LPUART,I2S,QEC,SD,CDC,CAM,
+P9_2,,LPUART,I2S,SPI,QEC,SD,CDC,CAM
+P9_3,,HFXO,UART,I2S,SPI,QEC,CDC,CAM
+P9_4,,UART,I2S,SPI,I2C,QEC,CDC,CAM
+P9_5,,OSPI,I2S,SPI,I2C,QEC,CDC,CAM
+P9_6,,OSPI,AUDIO,SPI,I2C,QEC,CDC,CAM
+P9_7,,OSPI,UART,SPI,I2C,QEC,CDC,CAM
+P10_0,,OSPI,UART,SPI,UT,LPCAM,CDC,CAM
+P10_1,,OSPI,,LPI2S,UT,LPCAM,CDC,CAM
+P10_2,,OSPI,,LPI2S,UT,LPCAM,CDC,CAM
+P10_3,,OSPI,,LPI2S,UT,LPCAM,CDC,CAM
+P10_4,,OSPI,,LPI2S,I2C,UT,ETH,CDC
+P10_5,,UART,I2S,SPI,I2C,UT,ETH,CDC
+P10_6,,UART,I2S,SPI,I2C,UT,ETH,CDC
+P10_7,,UART,I2S,SPI,I2C,UT,CDC,OSPI
+P11_0,,OSPI,UART,I2S,SPI,UT,ETH,CDC
+P11_1,,OSPI,UART,SPI,UT,ETH,CDC,
+P11_2,,OSPI,UART,LPPDM,SPI,UT,ETH,CDC
+P11_3,,OSPI,UART,LPPDM,SPI,UT,ETH,CDC
+P11_4,,OSPI,UART,PDM,LPSPI,UT,ETH,CDC
+P11_5,,OSPI,UART,PDM,LPSPI,UT,ETH,CDC
+P11_6,,OSPI,UART,LPPDM,LPSPI,UT,ETH,CDC
+P11_7,,OSPI,UART,LPPDM,LPSPI,UT,ETH,CDC
+P12_0,,OSPI,AUDIO,I2S,UT,CDC,,
+P12_1,,OSPI,UART,I2S,UT,CDC,,
+P12_2,,OSPI,UART,I2S,UT,CDC,,
+P12_3,,OSPI,UART,I2S,UT,CDC,,
+P12_4,,OSPI,SPI,UT,,CDC,,
+P12_5,,,SPI,UT,,CDC,,
+P12_6,,,SPI,UT,,CDC,,
+P12_7,,OSPI,,SPI,UT,CDC,,
+P13_0,,OSPI,,SPI,QEC,SD,CDC,
+P13_1,,OSPI,SPI,QEC,SD,CDC,,
+P13_2,,OSPI,SPI,QEC,SD,CDC,,
+P13_3,,OSPI,SPI,QEC,SD,CDC,,
+P13_4,,OSPI,LPI2S,QEC,SD,CDC,,
+P13_5,,OSPI,LPI2S,QEC,SD,CDC,,
+P13_6,,OSPI,LPI2S,QEC,SD,CDC,,
+P13_7,,OSPI,LPI2S,QEC,SD,CDC,,
+P14_0,,OSPI,UART,QEC,SD,,,
+P14_1,,OSPI,UART,,QEC,SD,,
+P14_2,,OSPI,UART,,QEC,SD,,
+P14_3,,OSPI,UART,,QEC,,,
+P14_4,,CMP,SPI,FAULT,,,,
+P14_5,,CMP,SPI,FAULT,,,,
+P14_6,,CMP,SPI,FAULT,,,,
+P14_7,,CMP,SPI,FAULT,,,,
+P15_0,,LPTMR,,,,,,
+P15_1,,LPTMR,,,,,,
+P15_2,,LPTMR,,,,,,
+P15_3,,LPTMR,,,,,,
+P15_4,,,,,,,,
+P15_5,,,,,,,,
+P15_6,,,,,,,,
+P15_7,,,,,,,,
diff --git a/ports/alif/mcu/make-pins.py b/ports/alif/mcu/make-pins.py
index d4fbf5d8b..fb0000826 100755
--- a/ports/alif/mcu/make-pins.py
+++ b/ports/alif/mcu/make-pins.py
@@ -34,26 +34,36 @@ ADC12_ANA_MAP = {
class AlifPin(boardgen.Pin):
+ def __init__(self, cpu_pin_name):
+ super().__init__(cpu_pin_name)
+ self._afs = ["MP_HAL_PIN_ALT_NONE"] * 8
+
+ # Called for each AF defined in the csv file for this pin.
+ def add_af(self, af_idx, af_name, af):
+ self._afs[af_idx] = f"MP_HAL_PIN_ALT_{af}"
+
# Emit the struct which contains the pin instance.
def definition(self):
port, pin = self.name()[1:].split("_")
adc12_periph, adc12_channel = ADC12_ANA_MAP.get(self.name(), (3, 7))
base = "LPGPIO_BASE" if port == "15" else "GPIO{}_BASE".format(port)
return (
- "{{ "
- ".base = {{ .type = &machine_pin_type }}, "
- ".gpio = (GPIO_Type *){base}, "
- ".port = PORT_{port}, "
- ".pin = PIN_{pin}, "
- ".adc12_periph = {adc12_periph}, "
- ".adc12_channel = {adc12_channel}, "
- ".name = MP_QSTR_P{port}_{pin} "
+ "{{\n"
+ " .name = MP_QSTR_P{port}_{pin},\n"
+ " .base = {{ .type = &machine_pin_type }},\n"
+ " .gpio = (GPIO_Type *){base},\n"
+ " .port = PORT_{port},\n"
+ " .pin = PIN_{pin},\n"
+ " .adc12_periph = {adc12_periph},\n"
+ " .adc12_channel = {adc12_channel},\n"
+ " .alt = {{{alt}}},\n"
"}}".format(
port=port,
pin=pin,
base=base,
adc12_periph=adc12_periph,
adc12_channel=adc12_channel,
+ alt=", ".join([f"{af}" for af in self._afs]),
)
)
@@ -76,7 +86,7 @@ class AlifPin(boardgen.Pin):
class AlifPinGenerator(boardgen.PinGenerator):
def __init__(self):
# Use custom pin type above.
- super().__init__(pin_type=AlifPin)
+ super().__init__(pin_type=AlifPin, enable_af=True)
# Pre-define the pins (i.e. don't require them to be listed in pins.csv).
for i in range(NUM_PORTS):
diff --git a/ports/alif/mphalport.c b/ports/alif/mphalport.c
index 5e3dad141..1a6136c31 100644
--- a/ports/alif/mphalport.c
+++ b/ports/alif/mphalport.c
@@ -169,6 +169,56 @@ uint64_t mp_hal_time_ns(void) {
return 0;
}
+void mp_hal_pin_config(const machine_pin_obj_t *pin, uint32_t mode,
+ uint32_t pull, uint32_t speed, uint32_t drive, uint32_t alt, bool ren) {
+ uint8_t alt_func = PINMUX_ALTERNATE_FUNCTION_0;
+ uint8_t pad_ctrl = drive | speed | (ren ? PADCTRL_READ_ENABLE : 0);
+
+ // Configure pull-up or pull-down.
+ if (pull & MP_HAL_PIN_PULL_UP) {
+ pad_ctrl |= PADCTRL_DRIVER_DISABLED_PULL_UP;
+ }
+
+ if (pull & MP_HAL_PIN_PULL_DOWN) {
+ pad_ctrl |= PADCTRL_DRIVER_DISABLED_PULL_DOWN;
+ }
+
+ // Configure open-drain mode.
+ if (mode == MP_HAL_PIN_MODE_OPEN_DRAIN) {
+ pad_ctrl |= PADCTRL_DRIVER_OPEN_DRAIN;
+ }
+
+ // For ALT mode, find alternate function.
+ if (mode == MP_HAL_PIN_MODE_ALT) {
+ for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(pin->alt); i++) {
+ if (alt == pin->alt[i]) {
+ alt_func = i;
+ break;
+ }
+ }
+ if (alt_func == PINMUX_ALTERNATE_FUNCTION_0) {
+ mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin af: %d"), alt);
+ }
+ }
+
+ // Set pad config.
+ pinconf_set(pin->port, pin->pin, alt_func, pad_ctrl);
+
+ // For INPUT/OUTPUT/OD modes, set the GPIO direction.
+ switch (mode) {
+ case MP_HAL_PIN_MODE_INPUT:
+ gpio_set_direction_input(pin->gpio, pin->pin);
+ break;
+ case MP_HAL_PIN_MODE_OUTPUT:
+ case MP_HAL_PIN_MODE_OPEN_DRAIN:
+ gpio_set_direction_output(pin->gpio, pin->pin);
+ break;
+ default:
+ break;
+ }
+}
+
+
void system_tick_schedule_callback(void) {
pendsv_schedule_dispatch(PENDSV_DISPATCH_SOFT_TIMER, soft_timer_handler);
}
diff --git a/ports/alif/mphalport.h b/ports/alif/mphalport.h
index 7b054b671..3b23cb6a2 100644
--- a/ports/alif/mphalport.h
+++ b/ports/alif/mphalport.h
@@ -74,12 +74,49 @@ extern ringbuf_t stdin_ringbuf;
#define MP_HAL_PIN_MODE_INPUT (0)
#define MP_HAL_PIN_MODE_OUTPUT (1)
#define MP_HAL_PIN_MODE_OPEN_DRAIN (2)
+#define MP_HAL_PIN_MODE_ALT (3)
#define MP_HAL_PIN_PULL_NONE (0)
#define MP_HAL_PIN_PULL_UP (1)
#define MP_HAL_PIN_PULL_DOWN (2)
+#define MP_HAL_PIN_DRIVE_2MA (PADCTRL_OUTPUT_DRIVE_STRENGTH_2MA)
+#define MP_HAL_PIN_DRIVE_4MA (PADCTRL_OUTPUT_DRIVE_STRENGTH_4MA)
+#define MP_HAL_PIN_DRIVE_8MA (PADCTRL_OUTPUT_DRIVE_STRENGTH_8MA)
+#define MP_HAL_PIN_DRIVE_12MA (PADCTRL_OUTPUT_DRIVE_STRENGTH_12MA)
+#define MP_HAL_PIN_SPEED_LOW (0)
+#define MP_HAL_PIN_SPEED_HIGH (PADCTRL_SLEW_RATE_FAST)
#define mp_hal_pin_obj_t const machine_pin_obj_t *
+enum {
+ MP_HAL_PIN_ALT_NONE = 0,
+ MP_HAL_PIN_ALT_ANA,
+ MP_HAL_PIN_ALT_AUDIO,
+ MP_HAL_PIN_ALT_CAM,
+ MP_HAL_PIN_ALT_CDC,
+ MP_HAL_PIN_ALT_CMP,
+ MP_HAL_PIN_ALT_ETH,
+ MP_HAL_PIN_ALT_FAULT,
+ MP_HAL_PIN_ALT_HFXO,
+ MP_HAL_PIN_ALT_I2C,
+ MP_HAL_PIN_ALT_I2S,
+ MP_HAL_PIN_ALT_I3C,
+ MP_HAL_PIN_ALT_JTAG,
+ MP_HAL_PIN_ALT_LPCAM,
+ MP_HAL_PIN_ALT_LPI2C,
+ MP_HAL_PIN_ALT_LPI2S,
+ MP_HAL_PIN_ALT_LPPDM,
+ MP_HAL_PIN_ALT_LPSPI,
+ MP_HAL_PIN_ALT_LPTMR,
+ MP_HAL_PIN_ALT_LPUART,
+ MP_HAL_PIN_ALT_OSPI,
+ MP_HAL_PIN_ALT_PDM,
+ MP_HAL_PIN_ALT_QEC,
+ MP_HAL_PIN_ALT_SD,
+ MP_HAL_PIN_ALT_SPI,
+ MP_HAL_PIN_ALT_UART,
+ MP_HAL_PIN_ALT_UT,
+};
+
typedef struct _machine_pin_obj_t {
mp_obj_base_t base;
GPIO_Type *gpio;
@@ -88,6 +125,7 @@ typedef struct _machine_pin_obj_t {
uint8_t adc12_periph : 2;
uint8_t adc12_channel : 3;
qstr name;
+ const uint8_t alt[8];
} machine_pin_obj_t;
mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t pin_in);
@@ -149,5 +187,8 @@ static inline void mp_hal_wake_main_task_from_isr(void) {
// Defined for tinyusb support, nothing needs to be done here.
}
+void mp_hal_pin_config(const machine_pin_obj_t *pin, uint32_t mode,
+ uint32_t pull, uint32_t speed, uint32_t drive, uint32_t alt, bool ren);
+
// Include all the pin definitions.
#include "genhdr/pins_board.h"