diff --git a/boards/microchip/pic32cxsg41_cult/Kconfig.defconfig b/boards/microchip/pic32cxsg41_cult/Kconfig.defconfig new file mode 100644 index 0000000000000..e6c29d2e55a71 --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/Kconfig.defconfig @@ -0,0 +1,27 @@ +# PIC32CX SG41 Curiosity Ultra board configuration +# +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +if ETH_SAM_GMAC + +# Read MAC address from AT24MAC402 EEPROM + +config ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS + default 0x9A + +config ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS_SIZE + default 1 + +config ETH_SAM_GMAC_MAC_I2C_EEPROM + default y + select I2C + +endif # ETH_SAM_GMAC + +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING diff --git a/boards/microchip/pic32cxsg41_cult/Kconfig.pic32cxsg41_cult b/boards/microchip/pic32cxsg41_cult/Kconfig.pic32cxsg41_cult new file mode 100644 index 0000000000000..2f6a9521a3a46 --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/Kconfig.pic32cxsg41_cult @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PIC32CXSG41_CULT + select SOC_PIC32CX1025SG41128 diff --git a/boards/microchip/pic32cxsg41_cult/board.cmake b/boards/microchip/pic32cxsg41_cult/board.cmake new file mode 100644 index 0000000000000..9d42d88af586e --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +board_finalize_runner_args(jlink "--device=pic32cx1025sg41128") diff --git a/boards/microchip/pic32cxsg41_cult/board.yml b/boards/microchip/pic32cxsg41_cult/board.yml new file mode 100644 index 0000000000000..c364f93b059a1 --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/board.yml @@ -0,0 +1,6 @@ +board: + name: pic32cxsg41_cult + full_name: PIC32CX SG41 Curiosity Ultra Evaluation Kit + vendor: microchip + socs: + - name: pic32cx1025sg41128 diff --git a/boards/microchip/pic32cxsg41_cult/board_jlink.cmake b/boards/microchip/pic32cxsg41_cult/board_jlink.cmake new file mode 100644 index 0000000000000..137148574e63e --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/board_jlink.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +board_finalize_runner_args(jlink "--device=pic32cx1025sg41128") diff --git a/boards/microchip/pic32cxsg41_cult/doc/img/PIC32CXSG41-pinout1.webp b/boards/microchip/pic32cxsg41_cult/doc/img/PIC32CXSG41-pinout1.webp new file mode 100644 index 0000000000000..132f032433e50 Binary files /dev/null and b/boards/microchip/pic32cxsg41_cult/doc/img/PIC32CXSG41-pinout1.webp differ diff --git a/boards/microchip/pic32cxsg41_cult/doc/img/PIC32CXSG41-pinout2.webp b/boards/microchip/pic32cxsg41_cult/doc/img/PIC32CXSG41-pinout2.webp new file mode 100644 index 0000000000000..b037c7debc94a Binary files /dev/null and b/boards/microchip/pic32cxsg41_cult/doc/img/PIC32CXSG41-pinout2.webp differ diff --git a/boards/microchip/pic32cxsg41_cult/doc/img/PIC32CXSG41-pinout3.webp b/boards/microchip/pic32cxsg41_cult/doc/img/PIC32CXSG41-pinout3.webp new file mode 100644 index 0000000000000..38fe02c560832 Binary files /dev/null and b/boards/microchip/pic32cxsg41_cult/doc/img/PIC32CXSG41-pinout3.webp differ diff --git a/boards/microchip/pic32cxsg41_cult/doc/index.rst b/boards/microchip/pic32cxsg41_cult/doc/index.rst new file mode 100644 index 0000000000000..8ff67167bd1de --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/doc/index.rst @@ -0,0 +1,166 @@ +.. zephyr:board:: pic32cxsg41_cult + +Overview +******** + +The PIC32CX SG41 Curiosity Ultra evaluation kit is ideal for evaluation and +prototyping with the PIC32CX SG Cortex®-M4F processor-based +microcontrollers. The kit includes Microchip’s Embedded Debugger (EDBG), +which provides a full debug interface without the need for additional +hardware. + +Hardware +******** + +- PIC32CX1025SG41 ARM Cortex-M4F processor at 120 MHz +- 32.768 kHz crystal oscillator +- 12 MHz crystal oscillator +- 1024 KiB flash memory and 256 KiB of RAM +- Two yellow user LEDs +- Two mechanical user push buttons +- One reset button +- On-board USB based EDBG unit with serial console +- Embedded Debugger MCU (PKoB4) +- 64 Mbit QSPI Flash +- AT24MAC402 serial EEPROM with EUI-48™ MAC address +- Ethernet transceiver 10/100 Mbps Ethernet MAC, + compatible with the IEEE 802.3 standard. +- Arduino Uno header connectors +- X32 Audio Interface Headers +- mikroBUS header connectors +- DAC Output header +- USB interface, host, and device +- SD/SDIO card connector + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Pin Mapping +=========== + +The Microchip PIC32CXSG41 Curiosity Ultra evaluation kit has 4 GPIO controllers. These +controllers are responsible for pin muxing, input/output, pull-up, etc. + +For more details please refer to `Microchip PIC32CX SG41-SG60-SG61 Family Datasheet`_. + +.. image:: img/PIC32CXSG41-pinout1.webp + :align: center + :alt: PIC32CXSG41-CULT-pinout1 + +.. image:: img/PIC32CXSG41-pinout2.webp + :align: center + :alt: PIC32CXSG41-CULT-pinout2 + +.. image:: img/PIC32CXSG41-pinout3.webp + :align: center + :alt: PIC32CXSG41-CULT-pinout3 + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- SERCOM2 USART TX : PB13 +- SERCOM2 USART RX : PB12 +- GPIO/PWM LED1 : PC21 +- GPIO/PWM LED2 : PA16 +- GPIO SW1 : PD00 +- GPIO SW2 : PD01 +- GMAC RMII REFCK : PA14 +- GMAC RMII TXEN : PA17 +- GMAC RMII TXD0 : PA18 +- GMAC RMII TXD1 : PA19 +- GMAC RMII CRSDV : PC20 +- GMAC RMII RXD0 : PA13 +- GMAC RMII RXD1 : PA12 +- GMAC RMII RXER : PA15 +- GMAC MDIO MDC : PC11 +- GMAC MDIO MDIO : PC12 +- SERCOM0 SPI SCK : PB24 +- SERCOM0 SPI MOSI : PB25 +- SERCOM0 SPI MISO : PC25 +- SERCOM0 SPI SS : PC24 +- SERCOM7 I2C SDA : PD08 +- SERCOM7 I2C SCL : PD09 +- USB DP : PA25 +- USB DM : PA24 + +System Clock +============ + +The PIC32CXSG41 MCU is configured to use the 32.768 kHz external oscillator +with the on-chip PLL generating the 48 MHz system clock. + +Serial Port +=========== + +The PIC32CXSG41 MCU has 8 SERCOM based USARTs with one configured as USARTs in this BSP. +- SERCOM4 is the default Zephyr console. + +- SERCOM4 115200 8n1 connected to the onboard Microchip Embedded Debugger (EDBG). + +The PIC32CXSG41 MCU has 8 SERCOM based SPIs. + +The PIC32CXSG41 MCU has 5 SERCOM based I2Cs. On the Microchip PIC32CXSG41 Curiosity Ultra, +SERCOM7 is connected to a AT24MAC402 EEPROM. + +Programming and Debugging +========================= + +.. zephyr:board-supported-runners:: + +The Microchip PIC32CXSG41 Curiosity Ultra comes with a Microchip Embedded Debugger (EDBG). +This provides a debug interface to the PIC32CXSG41 chip and is supported by OpenOCD. + +Flashing +======== + +#. Build the Zephyr kernel and the ``hello_world`` sample application: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: pic32cxsg41_cult + :goals: build + :compact: + +Connect the Microchip PIC32CXSG41 Curiosity Ultra to your host computer using the USB debug port. + +Run your favorite terminal program to listen for output. Under Linux thet terminal should be. + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 -o + +The -o option tells minicom not to send the modem initialization string. +Connection should be configured as follows: + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + +To flash an image: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: pic32cxsg41_cult + :goals: flash + :compact: + +You should see "Hello World! pic32cxsg41_cult" in your terminal. + +Debugging +========= + +SVD files are included in hal_microchip/pic32c/pic32cxsg/include/pic32cxsg41/svd. + +References +********** + +.. target-notes:: + +.. _Microchip website: + https://www.microchip.com/en-us/development-tool/EV06X38A + +.. _Microchip PIC32CX SG41-SG60-SG61 Family Datasheet: + https://ww1.microchip.com/downloads/aemDocuments/documents/MCU32/ProductDocuments/DataSheets/PIC32CX-SG41-SG60-SG61-Family-Data-Sheet-DS60001715.pdf diff --git a/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult-pinctrl.dtsi b/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult-pinctrl.dtsi new file mode 100644 index 0000000000000..1015fa4b63bb1 --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult-pinctrl.dtsi @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Microchip + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + pwm_default: pwm_default { + group1 { + pinmux = ; + }; + }; + + gmac_rmii: gmac_rmii { + group1 { + pinmux = , + , + , + , + , + , + , + ; + }; + }; + + mdio_default: mdio_default { + group1 { + pinmux = , + ; + }; + }; + + sercom7_i2c_default: sercom7_i2c_default { + group1 { + pinmux = , + ; + }; + }; + + sercom0_spi_default: sercom0_spi_default { + group1 { + pinmux = , + , + ; + }; + }; + + sercom4_uart_default: sercom4_uart_default { + group1 { + pinmux = , + ; + }; + }; + + usb_dc_default: usb_dc_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult.dts b/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult.dts new file mode 100644 index 0000000000000..e3fc49b42ab76 --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult.dts @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "pic32cxsg41_cult-pinctrl.dtsi" +#include + +/ { + model = "PIC32CX SG41 Curiosity Ultra"; + + compatible = "pic32cxsg41,cult", "microchip,pic32cx1025sg41128", "microchip,pic32cxsg"; + + chosen { + zephyr,console = &sercom4; + zephyr,shell-uart = &sercom4; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + /* These aliases are provided for compatibility with samples */ + + aliases { + userled1 = &led1; + userled2 = &led2; + pwm-led1 = &pwm_led1; + sw1 = &button1; + sw2 = &button2; + i2c-0 = &sercom7; + }; + + leds { + compatible = "gpio-leds"; + + led1: led_1 { + gpios = <&portc 21 GPIO_ACTIVE_LOW>; + label = "Yellow LED 1"; + }; + + led2: led_2 { + gpios = <&porta 16 GPIO_ACTIVE_LOW>; + label = "Yellow LED 2"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + pwm_led1: pwm_led_1 { + pwms = <&tcc0 2 PWM_MSEC(20)>; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button1: button_1 { + gpios = <&portd 00 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW1"; + zephyr,code = ; + }; + + button2: button_2 { + gpios = <&portd 01 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2"; + zephyr,code = ; + }; + }; +}; + +&cpu0 { + clock-frequency = <120000000>; +}; + +&tcc0 { + compatible = "atmel,sam0-tcc-pwm"; + + /* Gives a maximum period of 1.1s for 120MHz main clock */ + + prescaler = <8>; + + #pwm-cells = <2>; + + pinctrl-0 = <&pwm_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&sercom4 { + compatible = "atmel,sam0-uart"; + + current-speed = <115200>; + rxpo = <1>; + txpo = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <&sercom4_uart_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&sercom0 { + compatible = "atmel,sam0-spi"; + + dipo = <3>; + dopo = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <&sercom0_spi_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&sercom7 { + compatible = "atmel,sam0-i2c"; + + clock-frequency = ; + + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <&sercom7_i2c_default>; + pinctrl-names = "default"; + status = "okay"; + + eeprom: eeprom@5e { + compatible = "atmel,24mac402"; + + reg = <0x5e>; + }; +}; + +&adc0 { + status = "okay"; +}; + +zephyr_udc0: &usb0 { + pinctrl-0 = <&usb_dc_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&gmac { + pinctrl-0 = <&gmac_rmii>; + pinctrl-names = "default"; + mac-eeprom = <&eeprom>; + phy-handle = <&phy>; + status = "okay"; +}; + +&mdio { + pinctrl-0 = <&mdio_default>; + pinctrl-names = "default"; + status = "okay"; + + phy: ethernet-phy@0 { + compatible = "ethernet-phy"; + + reg = <0>; + status = "okay"; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + + #address-cells = <1>; + #size-cells = <1>; + + /* + * The final 16 KiB is reserved for the application. + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + + storage_partition: partition@fc000 { + label = "storage"; + reg = <0x000fc000 0x00004000>; + }; + }; +}; + +&osc32kctrl { + status = "okay"; +}; diff --git a/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult.yaml b/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult.yaml new file mode 100644 index 0000000000000..0851cf5e3a856 --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 +identifier: pic32cxsg41_cult +name: PIC32CX SG41 Curiosity Ultra +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +flash: 1024 +ram: 256 +supported: + - uart +testing: + ignore_tags: + - posix + - bluetooth + - net + - usb + - led +vendor: microchip diff --git a/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult_defconfig b/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult_defconfig new file mode 100644 index 0000000000000..8dba601092c16 --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/pic32cxsg41_cult_defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BUILD_OUTPUT_HEX=y + +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/boards/microchip/pic32cxsg41_cult/pre_dt_board.cmake b/boards/microchip/pic32cxsg41_cult/pre_dt_board.cmake new file mode 100644 index 0000000000000..d60aac1adec60 --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/pre_dt_board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "unique_unit_address_if_enabled" to handle the following overlaps: +# - /soc/pinmux@41004400 & /soc/gpio@41004400 +# - /soc/pinmux@41004480 & /soc/gpio@41004480 +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/microchip/pic32cxsg41_cult/support/openocd.cfg b/boards/microchip/pic32cxsg41_cult/support/openocd.cfg new file mode 100644 index 0000000000000..1765e28ac7283 --- /dev/null +++ b/boards/microchip/pic32cxsg41_cult/support/openocd.cfg @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +source [find interface/cmsis-dap.cfg] +transport select swd + +# chip name +set CHIPNAME pic32cx1025sg41 +set ENDIAN little +set CPUTAPID 0x61870500 + +source [find target/pic32cxsg41.cfg] + +reset_config none +cortex_m reset_config sysresetreq + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index 7346578e75d03..fd01852d90dc7 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_RPI_PICO pinctrl_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SAM pinctrl_sam.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SAM0 pinctrl_sam0.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SAM_PIO4 pinctrl_sam_pio4.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_PIC32CXSG pinctrl_sam0.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_STM32 pinctrl_stm32.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NXP_PORT pinctrl_nxp_port.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCHP_XEC pinctrl_mchp_xec.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e13c4e427ff71..905d968fc58f0 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -50,6 +50,7 @@ source "drivers/pinctrl/Kconfig.mspm0" source "drivers/pinctrl/Kconfig.rpi_pico" source "drivers/pinctrl/Kconfig.sam" source "drivers/pinctrl/Kconfig.sam0" +source "drivers/pinctrl/Kconfig.pic32cxsg" source "drivers/pinctrl/Kconfig.stm32" source "drivers/pinctrl/Kconfig.nxp_port" source "drivers/pinctrl/Kconfig.xec" diff --git a/drivers/pinctrl/Kconfig.pic32cxsg b/drivers/pinctrl/Kconfig.pic32cxsg new file mode 100644 index 0000000000000..c7840b1179d12 --- /dev/null +++ b/drivers/pinctrl/Kconfig.pic32cxsg @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Microchip +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_PIC32CXSG + bool "Microchip PIC32CXSG pin controller driver" + default y + depends on DT_HAS_MICROCHIP_PIC32CXSG_PINCTRL_ENABLED + help + Microchip pin controller driver is used on PIC32CXSG SoC series diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index d2e05081316d8..a37e3f0d9baac 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -64,6 +64,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_NUMICRO uart_numicro.c) zephyr_library_sources_ifdef(CONFIG_UART_NXP_S32_LINFLEXD uart_nxp_s32_linflexd.c) zephyr_library_sources_ifdef(CONFIG_UART_OPENTITAN uart_opentitan.c) zephyr_library_sources_ifdef(CONFIG_UART_PDL_INFINEON_CAT1 uart_ifx_cat1_pdl.c) +zephyr_library_sources_ifdef(CONFIG_UART_PIC32CXSG uart_sam0.c) zephyr_library_sources_ifdef(CONFIG_UART_PIPE uart_pipe.c) zephyr_library_sources_ifdef(CONFIG_UART_PL011 uart_pl011.c) zephyr_library_sources_ifdef(CONFIG_UART_PSOC6 uart_psoc6.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ea3fbed123bac..142d3759f0184 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -207,6 +207,7 @@ rsource "Kconfig.numaker" rsource "Kconfig.numicro" rsource "Kconfig.nxp_s32" rsource "Kconfig.opentitan" +rsource "Kconfig.pic32cxsg" rsource "Kconfig.pl011" rsource "Kconfig.psoc6" rsource "Kconfig.ql_usbserialport_s3b" diff --git a/drivers/serial/Kconfig.pic32cxsg b/drivers/serial/Kconfig.pic32cxsg new file mode 100644 index 0000000000000..ac5d529b2add3 --- /dev/null +++ b/drivers/serial/Kconfig.pic32cxsg @@ -0,0 +1,18 @@ +# Microchip PIC32CXSG SERCOM configuration options + +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +config UART_PIC32CXSG + bool "Microchip PIC32CXSG series SERCOM USART driver" + default y + depends on DT_HAS_MICROCHIP_PIC32CXSG_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + help + This option enables the SERCOMx USART driver for Microchip PIC32CXSG MCUs. + +config UART_PIC32CXSG_ASYNC + bool "Async UART support for Microchip PIC32CXSG series" + depends on UART_PIC32CXSG + depends on UART_ASYNC_API diff --git a/dts/arm/microchip/pic32c/pic32cx_sg/pic32cx1025sg.dtsi b/dts/arm/microchip/pic32c/pic32cx_sg/pic32cx1025sg.dtsi new file mode 100644 index 0000000000000..99d01edd212d8 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cx_sg/pic32cx1025sg.dtsi @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + nvmctrl@41004000 { + flash0: flash@0 { + reg = <0x0 DT_SIZE_K(1024)>; + }; + }; + + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(256)>; + }; + }; +}; diff --git a/dts/arm/microchip/pic32c/pic32cx_sg/pic32cxsg.dtsi b/dts/arm/microchip/pic32c/pic32cx_sg/pic32cxsg.dtsi new file mode 100644 index 0000000000000..f635a7dc3f368 --- /dev/null +++ b/dts/arm/microchip/pic32c/pic32cx_sg/pic32cxsg.dtsi @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +/ { + aliases { + adc-0 = &adc0; + adc-1 = &adc1; + + port-a = &porta; + port-b = &portb; + port-c = &portc; + port-d = &portd; + + sercom-0 = &sercom0; + sercom-1 = &sercom1; + sercom-2 = &sercom2; + sercom-3 = &sercom3; + sercom-4 = &sercom4; + sercom-5 = &sercom5; + sercom-6 = &sercom6; + sercom-7 = &sercom7; + + tc-0 = &tc0; + tc-2 = &tc2; + tc-4 = &tc4; + tc-6 = &tc6; + + tcc-0 = &tcc0; + tcc-1 = &tcc1; + tcc-2 = &tcc2; + tcc-3 = &tcc3; + tcc-4 = &tcc4; + + watchdog0 = &wdog; + }; + + chosen { + zephyr,entropy = &trng; + zephyr,flash-controller = &nvmctrl; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-m4f"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + device_type = "cpu"; + + mpu: mpu@e000ed90 { + compatible = "arm,armv7m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + soc { + id: device_id@8061fc { + compatible = "atmel,sam0-id"; + reg = <0x008061FC 0x4>, + <0x00806010 0x4>, + <0x00806014 0x4>, + <0x00806018 0x4>; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 0x40000>; + }; + + mclk: mclk@40000800 { + compatible = "atmel,sam0-mclk"; + reg = <0x40000800 0x400>; + #clock-cells = <2>; + }; + + osc32kctrl: osc32kctrl@40001400 { + compatible = "atmel,sam0-osc32kctrl"; + reg = <0x40001400 0x400>; + #clock-cells = <0>; + #atmel,assigned-clock-cells = <1>; + }; + + gclk: gclk@40001c00 { + compatible = "atmel,sam0-gclk"; + reg = <0x40001c00 0x400>; + #clock-cells = <1>; + #atmel,assigned-clock-cells = <1>; + }; + + wdog: watchdog@40002000 { + compatible = "atmel,sam0-watchdog"; + reg = <0x40002000 13>; + interrupts = <10 0>; + status = "disabled"; + }; + + eic: eic@40002800 { + compatible = "atmel,sam0-eic"; + reg = <0x40002800 0x38>; + interrupts = <12 0>, <13 0>, <14 0>, <15 0>, + <16 0>, <17 0>, <18 0>, <19 0>, + <20 0>, <21 0>, <22 0>, <23 0>, + <24 0>, <25 0>, <26 0>, <27 0>; + status = "disabled"; + }; + + sercom0: sercom@40003000 { + compatible = "microchip,pic32cxsg-sercom"; + reg = <0x40003000 0x40>; + interrupts = <46 0>, <47 0>, <48 0>, <49 0>; + clocks = <&gclk 7>, <&mclk 0x14 12>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + sercom1: sercom@40003400 { + compatible = "microchip,pic32cxsg-sercom"; + reg = <0x40003400 0x40>; + interrupts = <50 0>, <51 0>, <52 0>, <53 0>; + clocks = <&gclk 8>, <&mclk 0x14 13>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + usb0: usb@41000000 { + compatible = "atmel,sam0-usb"; + reg = <0x41000000 0x1000>; + interrupts = <80 0>, <81 0>, <82 0>, <83 0>; + status = "disabled"; + num-bidir-endpoints = <8>; + }; + + nvmctrl: nvmctrl@41004000 { + compatible = "atmel,sam0-nvmctrl"; + reg = <0x41004000 0x22>; + interrupts = <29 0>, <30 0>; + #address-cells = <1>; + #size-cells = <1>; + lock-regions = <32>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + write-block-size = <8>; + }; + }; + + pinmux_a: pinmux@41008000 { + compatible = "atmel,sam0-pinmux"; + reg = <0x41008000 0x80>; + }; + + pinmux_b: pinmux@41008080 { + compatible = "atmel,sam0-pinmux"; + reg = <0x41008080 0x80>; + }; + + pinmux_c: pinmux@41008100 { + compatible = "atmel,sam0-pinmux"; + reg = <0x41008100 0x80>; + }; + + pinmux_d: pinmux@41008180 { + compatible = "atmel,sam0-pinmux"; + reg = <0x41008180 0x80>; + }; + + pinctrl: pinctrl@41008000 { + compatible = "atmel,sam0-pinctrl"; + ranges = <0x41008000 0x41008000 0x200>; + #address-cells = <1>; + #size-cells = <1>; + + porta: gpio@41008000 { + compatible = "atmel,sam0-gpio"; + reg = <0x41008000 0x80>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + gpio-controller; + }; + + portb: gpio@41008080 { + compatible = "atmel,sam0-gpio"; + reg = <0x41008080 0x80>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + gpio-controller; + }; + + portc: gpio@41008100 { + compatible = "atmel,sam0-gpio"; + reg = <0x41008100 0x80>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + gpio-controller; + }; + + portd: gpio@41008180 { + compatible = "atmel,sam0-gpio"; + reg = <0x41008180 0x80>; + #atmel,pin-cells = <2>; + #gpio-cells = <2>; + gpio-controller; + }; + }; + + dmac: dmac@4100a000 { + compatible = "atmel,sam0-dmac"; + reg = <0x4100A000 0x50>; + interrupts = <31 0>, <32 0>, <33 0>, <34 0>, <35 0>; + status = "disabled"; + #dma-cells = <2>; + }; + + rtc: rtc@40002400 { + compatible = "atmel,sam0-rtc"; + reg = <0x40002400 0x40>; + interrupts = <11 0>; + clocks = <&osc32kctrl>, <&mclk 0x14 9>; + clock-names = "OSC32KCTRL", "MCLK"; + atmel,assigned-clocks = <&osc32kctrl 0>; + atmel,assigned-clock-names = "OSC32KCTRL"; + status = "disabled"; + }; + + tc0: tc@40003800 { + compatible = "atmel,sam0-tc32"; + reg = <0x40003800 0x34>; + interrupts = <107 0>; + clocks = <&gclk 9>, <&mclk 0x14 14>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + sercom2: sercom@41012000 { + compatible = "microchip,pic32cxsg-sercom"; + reg = <0x41012000 0x40>; + interrupts = <54 0>, <55 0>, <56 0>, <57 0>; + clocks = <&gclk 23>, <&mclk 0x18 9>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + sercom3: sercom@41014000 { + compatible = "microchip,pic32cxsg-sercom"; + reg = <0x41014000 0x40>; + interrupts = <58 0>, <59 0>, <60 0>, <61 0>; + clocks = <&gclk 24>, <&mclk 0x18 10>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + tcc0: tcc@41016000 { + compatible = "atmel,sam0-tcc"; + reg = <0x41016000 0x2000>; + interrupts = <85 0>, <86 0>, <87 0>, <88 0>, <89 0>, + <90 0>, <91 0>; + clocks = <&gclk 25>, <&mclk 0x18 11>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + channels = <6>; + counter-size = <24>; + }; + + tcc1: tcc@41018000 { + compatible = "atmel,sam0-tcc"; + reg = <0x41018000 0x2000>; + interrupts = <92 0>, <93 0>, <94 0>, <95 0>, <96 0>; + clocks = <&gclk 25>, <&mclk 0x18 12>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + channels = <4>; + counter-size = <24>; + }; + + tc2: tc@4101a000 { + compatible = "atmel,sam0-tc32"; + reg = <0x4101A000 0x34>; + interrupts = <109 0>; + clocks = <&gclk 26>, <&mclk 0x18 13>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + can0: can@42000000 { + compatible = "atmel,sam0-can"; + reg = <0x42000000 0x400>; + interrupts = <78 0>, <78 0>; + interrupt-names = "int0", "int1"; + clocks = <&gclk 27>, <&mclk 0x10 17>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; + divider = <12>; + }; + + can1: can@42000400 { + compatible = "atmel,sam0-can"; + reg = <0x42000400 0x400>; + interrupts = <79 0>, <79 0>; + interrupt-names = "int0", "int1"; + clocks = <&gclk 28>, <&mclk 0x10 18>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; + divider = <12>; + }; + + gmac: ethernet@42000800 { + compatible = "atmel,sam0-gmac"; + reg = <0x42000800 0x400>; + interrupts = <84 0>; + interrupt-names = "gmac"; + status = "disabled"; + num-queues = <1>; + local-mac-address = [00 00 00 00 00 00]; + }; + + mdio: mdio@42000800 { + compatible = "atmel,sam-mdio"; + reg = <0x42000800 0x400>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + tcc2: tcc@42000c00 { + compatible = "atmel,sam0-tcc"; + reg = <0x42000c00 0x400>; + interrupts = <97 0>, <98 0>, <99 0>, <100 0>; + clocks = <&gclk 29>, <&mclk 0x1c 3>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + channels = <3>; + counter-size = <16>; + }; + + tcc3: tcc@42001000 { + compatible = "atmel,sam0-tcc"; + reg = <0x42001000 0x400>; + interrupts = <101 0>, <102 0>, <103 0>; + clocks = <&gclk 29>, <&mclk 0x1c 4>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + channels = <2>; + counter-size = <16>; + }; + + tc4: tc@42001400 { + compatible = "atmel,sam0-tc32"; + reg = <0x42001400 0x34>; + interrupts = <111 0>; + clocks = <&gclk 30>, <&mclk 0x1c 5>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + trng: random@42002800 { + compatible = "atmel,sam-trng"; + reg = <0x42002800 0x1e>; + interrupts = <131 0>; + status = "disabled"; + }; + + sercom4: sercom@43000000 { + compatible = "microchip,pic32cxsg-sercom"; + reg = <0x43000000 0x40>; + interrupts = <62 0>, <63 0>, <64 0>, <65 0>; + clocks = <&gclk 34>, <&mclk 0x20 0>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + sercom5: sercom@43000400 { + compatible = "microchip,pic32cxsg-sercom"; + reg = <0x43000400 0x40>; + interrupts = <66 0>, <67 0>, <68 0>, <69 0>; + clocks = <&gclk 35>, <&mclk 0x20 1>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + sercom6: sercom@43000800 { + compatible = "microchip,pic32cxsg-sercom"; + reg = <0x43000800 0x40>; + interrupts = <70 0>, <71 0>, <72 0>, <73 0>; + clocks = <&gclk 36>, <&mclk 0x20 2>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + sercom7: sercom@43000c00 { + compatible = "microchip,pic32cxsg-sercom"; + reg = <0x43000C00 0x40>; + interrupts = <74 0>, <75 0>, <76 0>, <77 0>; + clocks = <&gclk 37>, <&mclk 0x20 3>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + tcc4: tcc@43001000 { + compatible = "atmel,sam0-tcc"; + reg = <0x43001000 0x400>; + interrupts = <104 0>, <105 0>, <106 0>; + clocks = <&gclk 38>, <&mclk 0x20 4>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + channels = <2>; + counter-size = <16>; + }; + + tc6: tc@43001400 { + compatible = "atmel,sam0-tc32"; + reg = <0x43001400 0x34>; + interrupts = <113 0>; + clocks = <&gclk 39>, <&mclk 0x20 5>; + clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + }; + + adc0: adc@43001c00 { + compatible = "atmel,sam0-adc"; + reg = <0x43001C00 0x4A>; + interrupts = <118 0>, <119 0>; + interrupt-names = "overrun", "resrdy"; + clocks = <&gclk 40>, <&mclk 0x20 7>; + clock-names = "GCLK", "MCLK"; + /* + * 16 MHz is ADC max clock, source clock must not exceed 100 MHz. + * - table 54-8, section 54.6, page 2020 + * - table 54-24, section 54.10.4, page 2031 + * 48 MHz GCLK / 4 = 12 MHz + * Generator 2: DFLL48M / 4 + */ + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + #io-channel-cells = <1>; + prescaler = <4>; + calib-offset = <0>; + }; + + adc1: adc@43002000 { + compatible = "atmel,sam0-adc"; + reg = <0x43002000 0x4A>; + interrupts = <120 0>, <121 0>; + interrupt-names = "overrun", "resrdy"; + clocks = <&gclk 41>, <&mclk 0x20 8>; + clock-names = "GCLK", "MCLK"; + /* + * 16 MHz is ADC max clock, source clock must not exceed 100 MHz. + * - table 54-8, section 54.6, page 2020 + * - table 54-24, section 54.10.4, page 2031 + * 48 MHz GCLK / 4 = 12 MHz + * Generator 2: DFLL48M / 4 + */ + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + #io-channel-cells = <1>; + prescaler = <4>; + calib-offset = <14>; + }; + + backup0: memory@47000000 { + compatible = "mmio-sram"; + reg = <0x47000000 0x2000>; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/dts/bindings/arm/microchip,pic32cxsg-sercom.yaml b/dts/bindings/arm/microchip,pic32cxsg-sercom.yaml new file mode 100644 index 0000000000000..ffc220a75cec5 --- /dev/null +++ b/dts/bindings/arm/microchip,pic32cxsg-sercom.yaml @@ -0,0 +1,17 @@ +description: Microchip PIC32CXSG multi-protocol (UART, SPI, I2C) SERCOM unit + +compatible: "microchip,pic32cxsg-sercom" + +include: + - name: base.yaml + - name: atmel,assigned-clocks.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true diff --git a/dts/bindings/pinctrl/microchip,pic32cxsg-pinctrl.yaml b/dts/bindings/pinctrl/microchip,pic32cxsg-pinctrl.yaml new file mode 100644 index 0000000000000..7c898c611bb44 --- /dev/null +++ b/dts/bindings/pinctrl/microchip,pic32cxsg-pinctrl.yaml @@ -0,0 +1,121 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +description: | + Microchip PIC32CXSG Pinctrl container node + + The Microchip PIC32CXSG pin controller is a singleton node responsible for controlling + pin function selection and pin properties. For example, you can use this node + to route SERCOM0 as UART were RX to pin PAD1 and enable the pull-up resistor + on the pin. + + The node has the 'pinctrl' node label set in your SoC's devicetree, so you can + modify it like this: + + &pinctrl { + /* your modifications go here */ + }; + + All device pin configurations should be placed in child nodes of the 'pinctrl' + node, as shown in this example: + + /** You can put this in places like a -pinctrl.dtsi file in + * your board directory, or a devicetree overlay in your application. + */ + + /** include pre-defined combinations for the SoC variant used by the board */ + #include + + &pinctrl { + /* configuration for the usart0 "default" state */ + sercom0_uart_default: sercom0_uart_default { + /* group 1 */ + group1 { + /* configure PA6 as USART0 TX and PA8 as USART0 CTS */ + pinmux = , ; + }; + /* group 2 */ + group2 { + /* configure PA5 as USART0 RX and PA7 as USART0 RTS */ + pinmux = , ; + /* both PA5 and PA7 have pull-up enabled */ + bias-pull-up; + }; + }; + }; + + The 'usart0_default' child node encodes the pin configurations for a + particular state of a device; in this case, the default (that is, active) + state. + + As shown, pin configurations are organized in groups within each child node. + Each group can specify a list of pin function selections in the 'pinmux' + property. + + A group can also specify shared pin properties common to all the specified + pins, such as the 'bias-pull-up' property in group 2. Here is a list of + supported standard pin properties: + + - bias-pull-up: Enable pull-up resistor. + - bias-pull-down: Enable pull-down resistor. + - drive-strength: Increase sink current. + - input-enable: Enable input on pin. + - output-enable: Enable output on a pin without actively driving it. + + To link pin configurations with a device, use a pinctrl-N property for some + number N, like this example you could place in your board's DTS file: + + #include "board-pinctrl.dtsi" + + &usart0 { + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + }; + +compatible: "microchip,pic32cxsg-pinctrl" + +include: base.yaml + +properties: + "#address-cells": + required: true + const: 1 + "#size-cells": + required: true + const: 1 + +child-binding: + description: | + Each child node defines the configuration for a particular state. + child-binding: + description: | + The grandchild nodes group pins that share the pic32cxsg pin configuration. + + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-pull-up + - bias-pull-down + - drive-strength + - input-enable + - output-enable + + properties: + pinmux: + required: true + type: array + description: | + An array of pins sharing the pic32cxsg group properties. The pins should + be defined using pre-defined macros or, alternatively, using the + SAM_PINCTRL utility macros depending on the pinmux model used by the + SoC series. + drive-strength: + enum: + - 0 + - 1 + default: 0 + description: | + The drive strength controls the output driver strength of an I/O pin + configured as an output. + 0: Pin drive strength is set to normal drive strength. + 1: Pin drive strength is set to stronger drive strength. diff --git a/dts/bindings/pinctrl/microchip,pic32cxsg-pinmux.yaml b/dts/bindings/pinctrl/microchip,pic32cxsg-pinmux.yaml new file mode 100644 index 0000000000000..990405fd8eb88 --- /dev/null +++ b/dts/bindings/pinctrl/microchip,pic32cxsg-pinmux.yaml @@ -0,0 +1,13 @@ +description: Microchip PIC32CXSG PINMUX + +compatible: "microchip,pic32cxsg-pinmux" + +include: base.yaml + +properties: + reg: + required: true + +pinmux-cells: + - pin + - function diff --git a/dts/bindings/serial/microchip,pic32cxsg-uart.yaml b/dts/bindings/serial/microchip,pic32cxsg-uart.yaml new file mode 100644 index 0000000000000..d1f9c8aea3e20 --- /dev/null +++ b/dts/bindings/serial/microchip,pic32cxsg-uart.yaml @@ -0,0 +1,93 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +description: Microchip PIC32CXSG SERCOM UART driver + +compatible: "microchip,pic32cxsg-uart" + +include: + - name: uart-controller.yaml + - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true + + clock-names: + required: true + + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + + rxpo: + type: int + required: true + description: | + Receive Data Pinout. An enumeration with the following values: + + +-------+---------------+ + | Value | RX Pin | + +-------+---------------+ + | 0 | SERCOM_PAD[0] | + +-------+---------------+ + | 1 | SERCOM_PAD[1] | + +-------+---------------+ + | 2 | SERCOM_PAD[2] | + +-------+---------------+ + | 3 | SERCOM_PAD[3] | + +-------+---------------+ + + + txpo: + type: int + required: true + description: | + Transmit Data Pinout. An enumeration with values that depend on the + hardware being used. This controls both the transmit pins and if + hardware flow control is used. + + PIC32CXSG: + + +-------+---------------+---------------+---------------+ + | Value | TX Pin | RTS | CTS | + +-------+---------------+---------------+---------------+ + | 0 | SERCOM_PAD[0] | N/A | N/A | + +-------+---------------+---------------+---------------+ + | 1 | Reserved | + +-------+---------------+---------------+---------------+ + | 2 | SERCOM_PAD[0] | SERCOM_PAD[2] | SERCOM_PAD[3] | + +-------+---------------+---------------+---------------+ + | 3 | SERCOM_PAD[0] | SERCOM_PAD[2] | N/A | + +-------+---------------+---------------+---------------+ + + + collision-detection: + type: boolean + description: Enable collision detection for half-duplex mode. + + dmas: + description: | + Optional TX & RX dma specifiers. Each specifier will have a phandle + reference to the dmac controller, the channel number, and peripheral + trigger source. + + For example dmas for TX, RX on SERCOM3 + dmas = <&dmac 0 0xb>, <&dmac 0 0xa>; + + dma-names: + description: | + Required if the dmas property exists. This should be "tx" and "rx" + to match the dmas property. + + For example + dma-names = "tx", "rx"; diff --git a/include/zephyr/drivers/pinctrl/pinctrl_soc_pic32cxsg_common.h b/include/zephyr/drivers/pinctrl/pinctrl_soc_pic32cxsg_common.h new file mode 100644 index 0000000000000..2808e2f32fe2e --- /dev/null +++ b/include/zephyr/drivers/pinctrl/pinctrl_soc_pic32cxsg_common.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * Microchip PIC32CXSG SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_PIC32CXSG_COMMON_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_PIC32CXSG_COMMON_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +/** @brief Type for PIC32CXSG pin. + * + * Bits: + * - 0-15: PIC32CXSG pinmux bit field (@ref SAM_PINMUX). + * - 16-21: Pin flags bit field (@ref PIC32CXSG_PINFLAGS). + * - 22-31: Reserved. + */ +typedef uint32_t pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +/* (CONFIG_SOC_FAMILY_MICROCHIP_PIC32CXSG) */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + ((DT_PROP_BY_IDX(node_id, prop, idx) << SAM_PINCTRL_PINMUX_POS) | \ + (DT_PROP(node_id, bias_pull_up) << SAM_PINCTRL_PULLUP_POS) | \ + (DT_PROP(node_id, bias_pull_down) << SAM_PINCTRL_PULLDOWN_POS) | \ + (DT_PROP(node_id, input_enable) << SAM_PINCTRL_INPUTENABLE_POS) | \ + (DT_PROP(node_id, output_enable) << SAM_PINCTRL_OUTPUTENABLE_POS) | \ + (DT_ENUM_IDX(node_id, drive_strength) << SAM_PINCTRL_DRIVESTRENGTH_POS)), + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +/** @endcond */ + +/** + * @brief Pin flags/attributes + * @anchor PIC32CXSG_PINFLAGS + * + * @{ + */ + +#define SAM_PINCTRL_FLAGS_DEFAULT (0U) +#define SAM_PINCTRL_FLAGS_POS (0U) +#define SAM_PINCTRL_FLAGS_MASK (0x3F << SAM_PINCTRL_FLAGS_POS) +#define SAM_PINCTRL_FLAG_MASK (1U) +#define SAM_PINCTRL_PULLUP_POS (SAM_PINCTRL_FLAGS_POS) +#define SAM_PINCTRL_PULLUP (1U << SAM_PINCTRL_PULLUP_POS) +#define SAM_PINCTRL_PULLDOWN_POS (SAM_PINCTRL_PULLUP_POS + 1U) +#define SAM_PINCTRL_PULLDOWN (1U << SAM_PINCTRL_PULLDOWN_POS) +#define SAM_PINCTRL_OPENDRAIN_POS (SAM_PINCTRL_PULLDOWN_POS + 1U) +#define SAM_PINCTRL_OPENDRAIN (1U << SAM_PINCTRL_OPENDRAIN_POS) +#define SAM_PINCTRL_INPUTENABLE_POS (SAM_PINCTRL_OPENDRAIN_POS + 1U) +#define SAM_PINCTRL_INPUTENABLE (1U << SAM_PINCTRL_INPUTENABLE_POS) +#define SAM_PINCTRL_OUTPUTENABLE_POS (SAM_PINCTRL_INPUTENABLE_POS + 1U) +#define SAM_PINCTRL_OUTPUTENABLE (1U << SAM_PINCTRL_OUTPUTENABLE_POS) +#define SAM_PINCTRL_DRIVESTRENGTH_POS (SAM_PINCTRL_OUTPUTENABLE_POS + 1U) +#define SAM_PINCTRL_DRIVESTRENGTH (1U << SAM_PINCTRL_DRIVESTRENGTH_POS) + +/** @} */ + +/** + * Obtain Flag value from pinctrl_soc_pin_t configuration. + * + * @param pincfg pinctrl_soc_pin_t bit field value. + * @param pos attribute/flags bit position (@ref PIC32CXSG_PINFLAGS). + */ +#define SAM_PINCTRL_FLAG_GET(pincfg, pos) (((pincfg) >> pos) & SAM_PINCTRL_FLAG_MASK) + +#define SAM_PINCTRL_FLAGS_GET(pincfg) (((pincfg) >> SAM_PINCTRL_FLAGS_POS) & SAM_PINCTRL_FLAGS_MASK) + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_PIC32CXSG_COMMON_H_ */ diff --git a/modules/Kconfig.microchip b/modules/Kconfig.microchip index 7497d99ead0a5..20befa5b6c7fb 100644 --- a/modules/Kconfig.microchip +++ b/modules/Kconfig.microchip @@ -1,4 +1,5 @@ # Microchip MEC HAL drivers configuration +# Microchip PIC32C HAL drivers configuration # SPDX-License-Identifier: Apache-2.0 @@ -10,3 +11,15 @@ config HAS_MPFS_HAL config HAS_MEC5_HAL bool "Microchip MEC5 HAL drivers support" + +config HAS_PIC32C_HAL + bool "Microchip PIC32C HAL drivers support" + +config PIC32C + bool + select HAS_CMSIS_CORE + +config HAS_PIC32CXSG_HAL + bool "Microchip PIC32CXSG HAL drivers support" + select HAS_CMSIS_CORE + depends on SOC_FAMILY_MICROCHIP_PIC32CXSG diff --git a/soc/microchip/pic32cxsg/CMakeLists.txt b/soc/microchip/pic32cxsg/CMakeLists.txt new file mode 100644 index 0000000000000..acc6bac9044ad --- /dev/null +++ b/soc/microchip/pic32cxsg/CMakeLists.txt @@ -0,0 +1,9 @@ +# Makefile - Microchip PIC32CXSG MCU family + +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(${ZEPHYR_BASE}/drivers) + +add_subdirectory(common) +add_subdirectory(${SOC_SERIES}) diff --git a/soc/microchip/pic32cxsg/Kconfig b/soc/microchip/pic32cxsg/Kconfig new file mode 100644 index 0000000000000..30b03d9a237e0 --- /dev/null +++ b/soc/microchip/pic32cxsg/Kconfig @@ -0,0 +1,14 @@ +# Microchip PIC32CXSG MCU family configuration options +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_MICROCHIP_PIC32CXSG + select PIC32C + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + +if SOC_FAMILY_MICROCHIP_PIC32CXSG + +rsource "common/Kconfig.pic32cxsg" +rsource "*/Kconfig" + +endif # SOC_FAMILY_MICROCHIP_PIC32CXSG diff --git a/soc/microchip/pic32cxsg/Kconfig.defconfig b/soc/microchip/pic32cxsg/Kconfig.defconfig new file mode 100644 index 0000000000000..65659c2313391 --- /dev/null +++ b/soc/microchip/pic32cxsg/Kconfig.defconfig @@ -0,0 +1,24 @@ +# Microchip PIC32CXSG MCU family default configuration options + +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_MICROCHIP_PIC32CXSG + +rsource "*/Kconfig.defconfig" + +config GPIO + default y + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +if USB_DEVICE_DRIVER + +config HEAP_MEM_POOL_ADD_SIZE_SOC + def_int 1024 + +endif # USB_DEVICE_DRIVER + +endif # SOC_FAMILY_MICROCHIP_PIC32CXSG diff --git a/soc/microchip/pic32cxsg/Kconfig.soc b/soc/microchip/pic32cxsg/Kconfig.soc new file mode 100644 index 0000000000000..8ef8beb3da8b7 --- /dev/null +++ b/soc/microchip/pic32cxsg/Kconfig.soc @@ -0,0 +1,13 @@ +# Microchip PIC32CXSG MCU family + +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_MICROCHIP_PIC32CXSG + bool + +config SOC_FAMILY + default "microchip_pic32cxsg" if SOC_FAMILY_MICROCHIP_PIC32CXSG + +rsource "*/Kconfig.soc" diff --git a/soc/microchip/pic32cxsg/common/CMakeLists.txt b/soc/microchip/pic32cxsg/common/CMakeLists.txt new file mode 100644 index 0000000000000..f4b41e71492b0 --- /dev/null +++ b/soc/microchip/pic32cxsg/common/CMakeLists.txt @@ -0,0 +1,14 @@ +# Makefile - Microchip PIC32CXSG MCU family +# +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(soc_port.c) + +zephyr_sources_ifdef(CONFIG_BOOTLOADER_BOSSA bossa.c) + +zephyr_sources_ifdef(CONFIG_SOC_FAMILY_MICROCHIP_PIC32CXSG soc_pic32cxsg.c) + +zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/microchip/pic32cxsg/common/Kconfig.pic32cxsg b/soc/microchip/pic32cxsg/common/Kconfig.pic32cxsg new file mode 100644 index 0000000000000..4c5cf3869277e --- /dev/null +++ b/soc/microchip/pic32cxsg/common/Kconfig.pic32cxsg @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_MICROCHIP_PIC32CXSG + +config SOC_MICROCHIP_PIC32CXSG_XOSC32K + bool "The external 32 kHz crystal oscillator" + default y if DT_HAS_ATMEL_SAM0_OSC32KCTRL_ENABLED + help + Enable gclk device tree node to use 32K crystal + as clock source. If not enabled the soc will be + configured for internal oscillator. + +endif diff --git a/soc/microchip/pic32cxsg/common/microchip_pic32cxsg_dt.h b/soc/microchip/pic32cxsg/common/microchip_pic32cxsg_dt.h new file mode 100644 index 0000000000000..2b1cf5afa55f6 --- /dev/null +++ b/soc/microchip/pic32cxsg/common/microchip_pic32cxsg_dt.h @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Microchip PIC32CXSG MCU family devicetree helper macros + */ + +#ifndef _MICROCHIP_PIC32CXSG_DT_H_ +#define _MICROCHIP_PIC32CXSG_DT_H_ + +/* clang-format off */ + +#define ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, cell) \ + (volatile uint32_t *) \ + (DT_REG_ADDR(DT_INST_PHANDLE_BY_NAME(n, clocks, cell)) + \ + DT_INST_CLOCKS_CELL_BY_NAME(n, cell, offset)) + +#define ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, name, cell) \ + BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, name, cell)) + +/* Helper macro to get register address that control peripheral clock + * enable bit. + */ +#define ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mclk)), \ + (ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, mclk)), \ + (ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, pm))) + +/* Helper macro to get peripheral clock bit mask. + */ +#define ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, cell) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mclk)), \ + (ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, mclk, cell)), \ + (ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, pm, cell))) + +/* Helper macros for use with Microchip PIC32CXSG DMAC controller + * return 0xff as default value if there is no 'dmas' property + */ +#define ATMEL_SAM0_DT_INST_DMA_CELL(n, name, cell) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \ + (DT_INST_DMAS_CELL_BY_NAME(n, name, cell)), \ + (0xff)) +#define ATMEL_SAM0_DT_INST_DMA_TRIGSRC(n, name) \ + ATMEL_SAM00_DT_INST_DMA_CELL(n, name, trigsrc) +#define ATMEL_SAM0_DT_INST_DMA_CHANNEL(n, name) \ + ATMEL_SAM00_DT_INST_DMA_CELL(n, name, channel) +#define ATMEL_SAM0_DT_INST_DMA_CTLR(n, name) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \ + (DT_INST_DMAS_CTLR_BY_NAME(n, name)), \ + (DT_INVALID_NODE)) + + +/* Use to check if a sercom 'n' is enabled for a given 'compat' */ +#define ATMEL_SAM0_DT_SERCOM_CHECK(n, compat) \ + DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(sercom##n), compat, okay) + +/* Use to check if TCC 'n' is enabled for a given 'compat' */ +#define ATMEL_SAM0_DT_TCC_CHECK(n, compat) \ + DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(tcc##n), compat, okay) + +/* Common macro for use to set HCLK_FREQ_HZ */ +#define ATMEL_SAM0_DT_CPU_CLK_FREQ_HZ \ + DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) + +/** + * @brief Test if a node has a atmel,assigned-clocks phandle-array property at + * a given index. + * + * This expands to 1 if the given index is valid atmel,assigned-clocks property + * phandle-array index. Otherwise, it expands to 0. + * + * Example devicetree fragment: + * + * n1: node-1 { + * atmel,assigned-clocks = <...>, <...>; + * }; + * + * n2: node-2 { + * atmel,assigned-clocks = <...>; + * }; + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(DT_NODELABEL(n1), 0) - 1 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(DT_NODELABEL(n1), 1) - 1 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(DT_NODELABEL(n1), 2) - 0 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(DT_NODELABEL(n2), 1) - 0 + * + * @param node_id node identifier; may or may not have any atmel,assigned-clocks + * property + * @param idx index of a atmel,assigned-clocks property phandle-array whose + * existence to check + * @return 1 if the index exists, 0 otherwise + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(node_id, idx) \ + DT_PROP_HAS_IDX(node_id, atmel_assigned_clocks, idx) + +/** + * @brief Test if a node has a clock-names array property holds a given name + * + * This expands to 1 if the name is available as atmel,assigned-clocks-name array + * property cell. Otherwise, it expands to 0. + * + * Example devicetree fragment: + * + * n1: node-1 { + * atmel,assigned-clocks = <...>, <...>; + * atmel,assigned-clock-names = "alpha", "beta"; + * }; + * + * n2: node-2 { + * atmel,assigned-clocks = <...>; + * atmel,assigned-clock-names = "alpha"; + * }; + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_NAME(DT_NODELABEL(n1), alpha) - 1 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_NAME(DT_NODELABEL(n1), beta) - 1 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_NAME(DT_NODELABEL(n2), beta) - 0 + * + * @param node_id node identifier; may or may not have any clock-names property. + * @param name lowercase-and-underscores clock-names cell value name to check + * @return 1 if the atmel,assigned-clock name exists, 0 otherwise + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_NAME(node_id, name) \ + DT_PROP_HAS_NAME(node_id, atmel_assigned_clocks, name) + +/** + * @brief Get the number of elements in a atmel,assigned-clocks property + * + * Example devicetree fragment: + * + * n1: node-1 { + * atmel,assigned-clocks = <&foo>, <&bar>; + * }; + * + * n2: node-2 { + * atmel,assigned-clocks = <&foo>; + * }; + * + * Example usage: + * + * ATMEL_SAM0_DT_NUM_ASSIGNED_CLOCKS(DT_NODELABEL(n1)) - 2 + * ATMEL_SAM0_DT_NUM_ASSIGNED_CLOCKS(DT_NODELABEL(n2)) - 1 + * + * @param node_id node identifier with a atmel,assigned-clocks property + * @return number of elements in the property + */ +#define ATMEL_SAM0_DT_NUM_ASSIGNED_CLOCKS(node_id) \ + DT_PROP_LEN(node_id, atmel_assigned_clocks) + + +/** + * @brief Get the node identifier for the controller phandle from a + * "atmel,assigned-clocks" phandle-array property at an index + * + * Example devicetree fragment: + * + * clk1: clock-controller@... { ... }; + * + * clk2: clock-controller@... { ... }; + * + * n: node { + * atmel,assigned-clocks = <&clk1 10 20>, <&clk2 30 40>; + * }; + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(DT_NODELABEL(n), 0)) - DT_NODELABEL(clk1) + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(DT_NODELABEL(n), 1)) - DT_NODELABEL(clk2) + * + * @param node_id node identifier + * @param idx logical index into "atmel,assigned-clocks" + * @return the node identifier for the clock controller referenced at index "idx" + * @see DT_PHANDLE_BY_IDX() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(node_id, idx) \ + DT_PHANDLE_BY_IDX(node_id, atmel_assigned_clocks, idx) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(node_id, 0) + * @param node_id node identifier + * @return a node identifier for the atmel,assigned-clocks controller at index 0 + * in "atmel,assigned-clocks" + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR(node_id) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(node_id, 0) + +/** + * @brief Get the node identifier for the controller phandle from a + * atmel,assigned-clocks phandle-array property by name + * + * Example devicetree fragment: + * + * clk1: clock-controller@... { ... }; + * + * clk2: clock-controller@... { ... }; + * + * n: node { + * atmel,assigned-clocks = <&clk1 10 20>, <&clk2 30 40>; + * atmel,assigned-clock-names = "alpha", "beta"; + * }; + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_NAME(DT_NODELABEL(n), beta) - DT_NODELABEL(clk2) + * + * @param node_id node identifier + * @param name lowercase-and-underscores name of a atmel,assigned-clocks element + * as defined by the node's clock-names property + * @return the node identifier for the clock controller referenced by name + * @see DT_PHANDLE_BY_NAME() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_NAME(node_id, name) \ + DT_PHANDLE_BY_NAME(node_id, atmel_assigned_clocks, name) + +/** + * @brief Get a atmel,assigned-clock specifier's cell value at an index + * + * Example devicetree fragment: + * + * clk1: clock-controller@... { + * compatible = "vnd,clock"; + * #atmel,assigned-clock-cells = < 2 >; + * }; + * + * n: node { + * atmel,assigned-clocks = < &clk1 10 20 >, < &clk1 30 40 >; + * }; + * + * Bindings fragment for the vnd,clock compatible: + * + * atmel,assigned-clock-cells: + * - bus + * - bits + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(DT_NODELABEL(n), 0, bus) - 10 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(DT_NODELABEL(n), 1, bits) - 40 + * + * @param node_id node identifier for a node with a atmel,assigned-clocks property + * @param idx logical index into atmel,assigned-clocks property + * @param cell lowercase-and-underscores cell name + * @return the cell value at index "idx" + * @see DT_PHA_BY_IDX() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(node_id, idx, cell) \ + DT_PHA_BY_IDX(node_id, atmel_assigned_clocks, idx, cell) + +/** + * @brief Get a atmel,assigned-clock specifier's cell value by name + * + * Example devicetree fragment: + * + * clk1: clock-controller@... { + * compatible = "vnd,clock"; + * #atmel,assigned-clock-cells = < 2 >; + * }; + * + * n: node { + * atmel,assigned-clocks = < &clk1 10 20 >, < &clk1 30 40 >; + * clock-names = "alpha", "beta"; + * }; + * + * Bindings fragment for the vnd,clock compatible: + * + * atmel,assigned-clock-cells: + * - bus + * - bits + * + * Example usage: + * + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_NAME(DT_NODELABEL(n), alpha, bus) - 10 + * ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_NAME(DT_NODELABEL(n), beta, bits) - 40 + * + * @param node_id node identifier for a node with a atmel,assigned-clocks property + * @param name lowercase-and-underscores name of a atmel,assigned-clocks element + * as defined by the node's clock-names property + * @param cell lowercase-and-underscores cell name + * @return the cell value in the specifier at the named element + * @see DT_PHA_BY_NAME() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_NAME(node_id, name, cell) \ + DT_PHA_BY_NAME(node_id, atmel_assigned_clocks, name, cell) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(node_id, 0, cell) + * @param node_id node identifier for a node with a atmel,assigned-clocks property + * @param cell lowercase-and-underscores cell name + * @return the cell value at index 0 + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX() + */ +#define ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL(node_id, cell) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(node_id, 0, cell) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_IDX(DT_DRV_INST(inst), idx) + * @param inst DT_DRV_COMPAT instance number; may or may not have any + * atmel,assigned-clocks property + * @param idx index of a atmel,assigned-clocks property phandle-array whose existence + * to check + * @return 1 if the index exists, 0 otherwise + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_HAS_IDX(inst, idx) \ + DT_ASSIGNED_CLOCKS_HAS_IDX(DT_DRV_INST(inst), idx) + +/** + * @brief Equivalent to DT_CLOCK_HAS_NAME(DT_DRV_INST(inst), name) + * @param inst DT_DRV_COMPAT instance number; may or may not have any + * atmel,clock-names property. + * @param name lowercase-and-underscores clock-names cell value name to check + * @return 1 if the atmel,assigned-clock name exists, 0 otherwise + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_HAS_NAME(inst, name) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_HAS_NAME(DT_DRV_INST(inst), name) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_NUM_ASSIGNED_CLOCKS(DT_DRV_INST(inst)) + * @param inst instance number + * @return number of elements in the atmel,assigned-clocks property + */ +#define ATMEL_SAM0_DT_INST_NUM_ASSIGNED_CLOCKS(inst) \ + ATMEL_SAM0_DT_NUM_ASSIGNED_CLOCKS(DT_DRV_INST(inst)) + +/** + * @brief Get the node identifier for the controller phandle from a + * "atmel,assigned-clocks" phandle-array property at an index + * + * @param inst instance number + * @param idx logical index into "atmel,assigned-clocks" + * @return the node identifier for the clock controller referenced at + * index "idx" + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX() + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CTLR_BY_IDX(inst, idx) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_IDX(DT_DRV_INST(inst), idx) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CTLR_BY_IDX(inst, 0) + * @param inst instance number + * @return a node identifier for the atmel,assigned-clocks controller at index 0 + * in "atmel,assigned-clocks" + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR() + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CTLR(inst) \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CTLR_BY_IDX(inst, 0) + +/** + * @brief Get the node identifier for the controller phandle from a + * atmel,assigned-clocks phandle-array property by name + * + * @param inst instance number + * @param name lowercase-and-underscores name of a atmel,assigned-clocks element + * as defined by the node's atmel,assigned-clock-names property + * @return the node identifier for the clock controller referenced by + * the named element + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_NAME() + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CTLR_BY_NAME(inst, name) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CTLR_BY_NAME(DT_DRV_INST(inst), name) + +/** + * @brief Get a DT_DRV_COMPAT instance's atmel,assigned-clock specifier's cell + * value at an index + * @param inst DT_DRV_COMPAT instance number + * @param idx logical index into atmel,assigned-clocks property + * @param cell lowercase-and-underscores cell name + * @return the cell value at index "idx" + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX() + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_IDX(inst, idx, cell) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_IDX(DT_DRV_INST(inst), idx, cell) + +/** + * @brief Get a DT_DRV_COMPAT instance's atmel,assigned-clock specifier's cell + * value by name + * @param inst DT_DRV_COMPAT instance number + * @param name lowercase-and-underscores name of a atmel,assigned-clocks element + * as defined by the node's atmel,assigned-clock-names property + * @param cell lowercase-and-underscores cell name + * @return the cell value in the specifier at the named element + * @see ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_NAME() + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME(inst, name, cell) \ + ATMEL_SAM0_DT_ASSIGNED_CLOCKS_CELL_BY_NAME(DT_DRV_INST(inst), name, cell) + +/** + * @brief Equivalent to ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_IDX(inst, 0, cell) + * @param inst DT_DRV_COMPAT instance number + * @param cell lowercase-and-underscores cell name + * @return the value of the cell inside the specifier at index 0 + */ +#define ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL(inst, cell) \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_IDX(inst, 0, cell) + +/* clang-format on */ + +#endif /* _MICROCHIP_PIC32CXSG_DT_H_ */ diff --git a/soc/microchip/pic32cxsg/common/pinctrl_soc.h b/soc/microchip/pic32cxsg/common/pinctrl_soc.h new file mode 100644 index 0000000000000..504f5e7437522 --- /dev/null +++ b/soc/microchip/pic32cxsg/common/pinctrl_soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * Microchip PIC32CXSG SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_SOC_ARM_MICROCHIP_PIC32CXSG_COMMON_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_MICROCHIP_PIC32CXSG_COMMON_PINCTRL_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_ARM_MICROCHIP_PIC32CXSG_COMMON_PINCTRL_SOC_H_ */ diff --git a/soc/microchip/pic32cxsg/common/soc_pic32cxsg.c b/soc/microchip/pic32cxsg/common/soc_pic32cxsg.c new file mode 100644 index 0000000000000..ae87343e22bdd --- /dev/null +++ b/soc/microchip/pic32cxsg/common/soc_pic32cxsg.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Micorchip PIC32CXSG MCU series initialization code + */ + +#include +#include +#include +#include + +#define PIC32CXSG_DFLL_FREQ_HZ (48000000U) +#define PIC32CXSG_DPLL_FREQ_MIN_HZ (96000000U) +#define PIC32CXSG_DPLL_FREQ_MAX_HZ (200000000U) +#define PIC32CXSG_XOSC32K_STARTUP_TIME (6) /* Microchip - was 7 which is a reserved value */ + +#if CONFIG_SOC_MICROCHIP_PIC32CXSG_XOSC32K +static void osc32k_init(void) +{ + gclk_registers_t *gregs = (gclk_registers_t *)DT_REG_ADDR(DT_NODELABEL(gclk)); + osc32kctrl_registers_t *oregs = + (osc32kctrl_registers_t *)DT_REG_ADDR(DT_NODELABEL(osc32kctrl)); + + oregs->OSC32KCTRL_XOSC32K = OSC32KCTRL_XOSC32K_ENABLE(1) | OSC32KCTRL_XOSC32K_XTALEN(1) | + OSC32KCTRL_XOSC32K_EN32K(1) | OSC32KCTRL_XOSC32K_RUNSTDBY(1) | + OSC32KCTRL_XOSC32K_STARTUP(PIC32CXSG_XOSC32K_STARTUP_TIME); + + while ((oregs->OSC32KCTRL_STATUS & BIT(OSC32KCTRL_STATUS_XOSC32KRDY_Pos)) == 0) { + } + + gregs->GCLK_GENCTRL[1] = GCLK_GENCTRL_SRC(GCLK_SOURCE_XOSC32K) | GCLK_GENCTRL_RUNSTDBY(1) | + GCLK_GENCTRL_GENEN(1); +} +#else +static void osc32k_init(void) +{ + gclk_registers_t *gregs = (gclk_registers_t *)DT_REG_ADDR(DT_NODELABEL(gclk)); + + gregs->GCLK_GENCTRL[1] = GCLK_GENCTRL_SRC(GCLK_SOURCE_OSCULP32K) | + GCLK_GENCTRL_RUNSTDBY(1) | GCLK_GENCTRL_GENEN(1); +} +#endif + +static void dpll_init(uint8_t n, uint32_t f_cpu) +{ + gclk_registers_t *gregs = (gclk_registers_t *)DT_REG_ADDR(DT_NODELABEL(gclk)); + oscctrl_registers_t *oscc_regs = (oscctrl_registers_t *)(OSCCTRL_BASE_ADDRESS); + /* We source the DPLL from 32kHz GCLK1 */ + const uint32_t ldr = ((f_cpu << 5) / SOC_MICROCHIP_PIC32CXSG_OSC32K_FREQ_HZ); + uint32_t dpll_rdy_msk = + BIT(OSCCTRL_DPLLSTATUS_CLKRDY_Pos) | BIT(OSCCTRL_DPLLSTATUS_LOCK_Pos); + + /* disable the DPLL before changing the configuration */ + oscc_regs->DPLL[n].OSCCTRL_DPLLCTRLA &= ~BIT(OSCCTRL_DPLLCTRLA_ENABLE_Pos); + + while (oscc_regs->DPLL[n].OSCCTRL_DPLLSYNCBUSY != 0) { + } + + /* set DPLL clock source to 32kHz GCLK1 */ + gregs->GCLK_PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + n] = + (GCLK_PCHCTRL_GEN(1) | BIT(GCLK_PCHCTRL_CHEN_Pos)); + + while ((gregs->GCLK_PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + n] & BIT(GCLK_PCHCTRL_CHEN_Pos)) == + 0) { + }; + + oscc_regs->DPLL[n].OSCCTRL_DPLLRATIO = + OSCCTRL_DPLLRATIO_LDRFRAC(ldr & 0x1F) | OSCCTRL_DPLLRATIO_LDR((ldr >> 5) - 1); + + /* Without LBYPASS, startup takes very long, see errata section 2.13. */ + oscc_regs->DPLL[n].OSCCTRL_DPLLCTRLB = OSCCTRL_DPLLCTRLB_REFCLK_GCLK | + OSCCTRL_DPLLCTRLB_WUF(1) | + OSCCTRL_DPLLCTRLB_LBYPASS(1); + + oscc_regs->DPLL[n].OSCCTRL_DPLLCTRLA = OSCCTRL_DPLLCTRLA_ENABLE(1); + + while (oscc_regs->DPLL[n].OSCCTRL_DPLLSYNCBUSY != 0) { + } + + while ((oscc_regs->DPLL[n].OSCCTRL_DPLLSTATUS & dpll_rdy_msk) != dpll_rdy_msk) { + } +} + +static void dfll_init(void) +{ + oscctrl_registers_t *oscc_regs = (oscctrl_registers_t *)(OSCCTRL_BASE_ADDRESS); + uint32_t reg = OSCCTRL_DFLLCTRLB_QLDIS(1) +#ifdef OSCCTRL_DFLLCTRLB_WAITLOCK + | OSCCTRL_DFLLCTRLB_WAITLOCK(1) +#endif + ; + + oscc_regs->OSCCTRL_DFLLCTRLB = reg; + oscc_regs->OSCCTRL_DFLLCTRLA = OSCCTRL_DFLLCTRLA_ENABLE(1); + + while ((oscc_regs->OSCCTRL_STATUS & BIT(OSCCTRL_STATUS_DFLLRDY_Pos)) == 0) { + } +} + +static void gclk_reset(void) +{ + gclk_registers_t *gregs = (gclk_registers_t *)DT_REG_ADDR(DT_NODELABEL(gclk)); + + gregs->GCLK_CTRLA |= BIT(GCLK_CTRLA_SWRST_Pos); + + while ((gregs->GCLK_SYNCBUSY & BIT(GCLK_SYNCBUSY_SWRST_Pos)) != 0) { + } +} + +static void gclk_connect(uint8_t gclk, uint8_t src, uint8_t div) +{ + gclk_registers_t *gregs = (gclk_registers_t *)DT_REG_ADDR(DT_NODELABEL(gclk)); + + gregs->GCLK_GENCTRL[gclk] = + (GCLK_GENCTRL_SRC(src) | GCLK_GENCTRL_DIV(div) | GCLK_GENCTRL_GENEN(1)); +} + +void soc_reset_hook(void) +{ + cmcc_registers_t *cmcc_regs = (cmcc_registers_t *)(CMCC_BASE_ADDRESS); + uint8_t dfll_div = 1; + + if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC < PIC32CXSG_DFLL_FREQ_HZ) { + dfll_div = 3; + } else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC < PIC32CXSG_DPLL_FREQ_MIN_HZ) { + dfll_div = 2; + } else { + dfll_div = 1; + } + + /* + * Force Cortex M Cache Controller disabled + * + * It is not clear if regular Cortex-M instructions can be used to + * perform cache maintenance or this is a proprietary cache controller + * that require special SoC support. + */ + cmcc_regs->CMCC_CTRL &= ~BIT(CMCC_CTRL_CEN_Pos); + + gclk_reset(); + osc32k_init(); + dfll_init(); + dpll_init(0, dfll_div * CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); + + /* use DPLL for main clock */ + gclk_connect(0, GCLK_SOURCE_DPLL0, dfll_div); + + /* connect GCLK2 to 48 MHz DFLL for USB */ + gclk_connect(2, GCLK_SOURCE_DFLL48M, 0); +} diff --git a/soc/microchip/pic32cxsg/common/soc_port.c b/soc/microchip/pic32cxsg/common/soc_port.c new file mode 100644 index 0000000000000..22be73f1f45f9 --- /dev/null +++ b/soc/microchip/pic32cxsg/common/soc_port.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016 Piotr Mienkowski + * Copyright (c) 2018 Google LLC. + * Copyright (c) 2021 Gerson Fernando Budke + * Copyright (c) 2024 Microchip + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Microchip PIC32CSXSG MCU family I/O Pin Controller (PORT) + */ + +#include + +#include "soc_port.h" + +int soc_port_pinmux_set(PortGroup *pg, uint32_t pin, uint32_t func) +{ + bool is_odd = pin & 1; + int idx = pin / 2U; + + /* Each pinmux register holds the config for two pins. The + * even numbered pin goes in the bits 0..3 and the odd + * numbered pin in bits 4..7. + */ + if (is_odd) { + pg->PMUX[idx].bit.PMUXO = func; + } else { + pg->PMUX[idx].bit.PMUXE = func; + } + pg->PINCFG[pin].bit.PMUXEN = 1; + + return 0; +} + +void soc_port_configure(const struct soc_port_pin *pin) +{ + PortGroup *pg = pin->regs; + uint32_t flags = pin->flags; + uint32_t func = (pin->flags & SOC_PORT_FUNC_MASK) >> SOC_PORT_FUNC_POS; + PORT_PINCFG_Type pincfg = {.reg = 0}; + + /* Reset or analog I/O: all digital disabled */ + pg->PINCFG[pin->pinum] = pincfg; + pg->DIRCLR.reg = (1 << pin->pinum); + pg->OUTCLR.reg = (1 << pin->pinum); + + if (flags & SOC_PORT_PMUXEN_ENABLE) { + soc_port_pinmux_set(pg, pin->pinum, func); + return; + } + + if (flags & (SOC_PORT_PULLUP | SOC_PORT_PULLDOWN)) { + if (flags & SOC_PORT_PULLUP) { + pg->OUTSET.reg = (1 << pin->pinum); + } + + pincfg.bit.PULLEN = 1; + } + + if (flags & SOC_PORT_INPUT_ENABLE) { + pincfg.bit.INEN = 1; + } + + if (flags & SOC_PORT_OUTPUT_ENABLE) { + pg->DIRSET.reg = (1 << pin->pinum); + } + + if (flags & SOC_PORT_STRENGTH_STRONGER) { + pincfg.bit.DRVSTR = 1; + } + + pg->PINCFG[pin->pinum] = pincfg; +} + +void soc_port_list_configure(const struct soc_port_pin pins[], unsigned int size) +{ + for (int i = 0; i < size; i++) { + soc_port_configure(&pins[i]); + } +} diff --git a/soc/microchip/pic32cxsg/common/soc_port.h b/soc/microchip/pic32cxsg/common/soc_port.h new file mode 100644 index 0000000000000..6e743062ed577 --- /dev/null +++ b/soc/microchip/pic32cxsg/common/soc_port.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Microchip PIC32CXSG MCU family I/O Pin Controller (PORT) + */ + +#ifndef MICROCHIP_PIC32CXSG_SOC_PORT_H_ +#define MICROCHIP_PIC32CXSG_SOC_PORT_H_ + +#include + +/* + * Pin flags/attributes + */ +#define SOC_PORT_DEFAULT (0) + +#define SOC_PORT_FLAGS_POS (0) +#define SOC_PORT_FLAGS_MASK (0x7B << SOC_PORT_FLAGS_POS) +#define SOC_PORT_PULLUP_POS (SOC_PORT_FLAGS_POS) +#define SOC_PORT_PULLUP (1 << SOC_PORT_PULLUP_POS) +#define SOC_PORT_PULLDOWN_POS (SOC_PORT_PULLUP_POS + 1U) +#define SOC_PORT_PULLDOWN (1 << SOC_PORT_PULLDOWN_POS) +/* Open-Drain is a reserved entry at pinctrl driver */ +#define SOC_GPIO_OPENDRAIN_POS (SOC_PORT_PULLDOWN_POS + 1U) +/* Input-Enable means Input-Buffer, see dts/pinctrl/pincfg-node.yaml */ +#define SOC_PORT_INPUT_ENABLE_POS (SOC_GPIO_OPENDRAIN_POS + 1U) +#define SOC_PORT_INPUT_ENABLE (1 << SOC_PORT_INPUT_ENABLE_POS) +/* Output-Enable, see dts/pinctrl/pincfg-node.yaml */ +#define SOC_PORT_OUTPUT_ENABLE_POS (SOC_PORT_INPUT_ENABLE_POS + 1U) +#define SOC_PORT_OUTPUT_ENABLE (1 << SOC_PORT_OUTPUT_ENABLE_POS) +/* Drive-Strength, 0mA means normal, any other value means stronger */ +#define SOC_PORT_STRENGTH_STRONGER_POS (SOC_PORT_OUTPUT_ENABLE_POS + 1U) +#define SOC_PORT_STRENGTH_STRONGER (1 << SOC_PORT_STRENGTH_STRONGER_POS) +/* Peripheral Multiplexer Enable */ +#define SOC_PORT_PMUXEN_ENABLE_POS (SOC_PORT_STRENGTH_STRONGER_POS + 1U) +#define SOC_PORT_PMUXEN_ENABLE (1 << SOC_PORT_PMUXEN_ENABLE_POS) + +/* Bit field: SOC_PORT_FUNC */ +#define SOC_PORT_FUNC_POS (16U) +#define SOC_PORT_FUNC_MASK (0xF << SOC_PORT_FUNC_POS) + +/** Connect pin to peripheral A. */ +#define SOC_PORT_FUNC_A (0x0 << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral B. */ +#define SOC_PORT_FUNC_B (0x1 << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral C. */ +#define SOC_PORT_FUNC_C (0x2 << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral D. */ +#define SOC_PORT_FUNC_D (0x3 << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral E. */ +#define SOC_PORT_FUNC_E (0x4 << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral F. */ +#define SOC_PORT_FUNC_F (0x5 << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral G. */ +#define SOC_PORT_FUNC_G (0x6 << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral H. */ +#define SOC_PORT_FUNC_H (0x7 << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral I. */ +#define SOC_PORT_FUNC_I (0x8 << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral J. */ +#define SOC_PORT_FUNC_J (0x9 << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral K. */ +#define SOC_PORT_FUNC_K (0xa << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral L. */ +#define SOC_PORT_FUNC_L (0xb << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral M. */ +#define SOC_PORT_FUNC_M (0xc << SOC_PORT_FUNC_POS) +/** Connect pin to peripheral N. */ +#define SOC_PORT_FUNC_N (0xd << SOC_PORT_FUNC_POS) + +struct soc_port_pin { + PortGroup *regs; /** pointer to registers of the I/O Pin Controller */ + uint32_t pinum; /** pin number */ + uint32_t flags; /** pin flags/attributes */ +}; + +/** + * @brief Configure PORT pin muxing. + * + * Configure one pin muxing belonging to some PORT. + * + * @param pg PortGroup register + * @param pin Pin number + * @param func Pin Function + */ +int soc_port_pinmux_set(PortGroup *pg, uint32_t pin, uint32_t func); + +/** + * @brief Configure PORT pin. + * + * Configure one pin belonging to some PORT. + * Example scenarios: + * - configure pin(s) as input. + * - connect pin(s) to a peripheral B and enable pull-up. + * + * @remark During Reset, all PORT lines are configured as inputs with input + * buffers, output buffers and pull disabled. When the device is set to the + * BACKUP sleep mode, even if the PORT configuration registers and input + * synchronizers will lose their contents (these will not be restored when + * PORT is powered up again), the latches in the pads will keep their current + * configuration, such as the output value and pull settings. Refer to the + * Power Manager documentation for more features related to the I/O lines + * configuration in and out of BACKUP mode. The PORT peripheral will continue + * operating in any Sleep mode where its source clock is running. + * + * @param pin pin's configuration data such as pin mask, pin attributes, etc. + */ +void soc_port_configure(const struct soc_port_pin *pin); + +/** + * @brief Configure a list of PORT pin(s). + * + * Configure an arbitrary amount of pins in an arbitrary way. Each + * configuration entry is a single item in an array passed as an argument to + * the function. + * + * @param pins an array where each item contains pin's configuration data. + * @param size size of the pin list. + */ +void soc_port_list_configure(const struct soc_port_pin pins[], unsigned int size); + +#endif /* MICROCHIP_PIC32CXSG_SOC_PORT_H_ */ diff --git a/soc/microchip/pic32cxsg/pic32cxsg41/CMakeLists.txt b/soc/microchip/pic32cxsg/pic32cxsg41/CMakeLists.txt new file mode 100644 index 0000000000000..a7bdea6c18973 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg41/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) diff --git a/soc/microchip/pic32cxsg/pic32cxsg41/Kconfig b/soc/microchip/pic32cxsg/pic32cxsg41/Kconfig new file mode 100644 index 0000000000000..efc48a981a887 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg41/Kconfig @@ -0,0 +1,13 @@ +# Microchip PIC32CXSG MCU series + +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC32CXSG41 + select ARM + select CPU_CORTEX_M4 + select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU + select SOC_RESET_HOOK diff --git a/soc/microchip/pic32cxsg/pic32cxsg41/Kconfig.defconfig b/soc/microchip/pic32cxsg/pic32cxsg41/Kconfig.defconfig new file mode 100644 index 0000000000000..9edcc65db5a59 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg41/Kconfig.defconfig @@ -0,0 +1,15 @@ +# Microchip PIC32CXSG MCU series configuration options + +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_PIC32CXSG41 + +config NUM_IRQS + default 137 + +config ROM_START_OFFSET + default 0x400 if BOOTLOADER_MCUBOOT + +endif # SOC_SERIES_PIC32CXSG41 diff --git a/soc/microchip/pic32cxsg/pic32cxsg41/Kconfig.soc b/soc/microchip/pic32cxsg/pic32cxsg41/Kconfig.soc new file mode 100644 index 0000000000000..18ca99879d514 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg41/Kconfig.soc @@ -0,0 +1,36 @@ +# Microchip PIC29CXSG41 MCU series + +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC32CXSG41 + bool + select SOC_FAMILY_MICROCHIP_PIC32CXSG + help + Enable support for Microchip PIC32CXSG Cortex-M4F microcontrollers. + +config SOC_SERIES + default "pic32cxsg41" if SOC_SERIES_PIC32CXSG41 + +config SOC_PIC32CX1025SG41064 + bool + select SOC_SERIES_PIC32CXSG41 + +config SOC_PIC32CX1025SG41080 + bool + select SOC_SERIES_PIC32CXSG41 + +config SOC_PIC32CX1025SG41100 + bool + select SOC_SERIES_PIC32CXSG41 + +config SOC_PIC32CX1025SG41128 + bool + select SOC_SERIES_PIC32CXSG41 + +config SOC + default "pic32cx1025sg41064" if SOC_PIC32CX1025SG41064 + default "pic32cx1025sg41080" if SOC_PIC32CX1025SG41080 + default "pic32cx1025sg41100" if SOC_PIC32CX1025SG41100 + default "pic32cx1025sg41128" if SOC_PIC32CX1025SG41128 diff --git a/soc/microchip/pic32cxsg/pic32cxsg41/soc.h b/soc/microchip/pic32cxsg/pic32cxsg41/soc.h new file mode 100644 index 0000000000000..184ebf3a70cb7 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg41/soc.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_MICROCHIP_PIC32CXSG41_SOC_H_ +#define _SOC_MICROCHIP_PIC32CXSG41_SOC_H_ + +#ifndef _ASMLANGUAGE + +#define DONT_USE_CMSIS_INIT + +#include + +#if defined(CONFIG_SOC_PIC32CX1025SG41064) +#include +#elif defined(CONFIG_SOC_PIC32CX1025SG41080) +#include +#elif defined(CONFIG_SOC_PIC32CX1025SG41100) +#include +#elif defined(CONFIG_SOC_PIC32CX1025SG41128) +#include + +#else +#error Library does not support the specified device. +#endif + +#endif /* _ASMLANGUAGE */ + +#include +#include "../common/microchip_pic32cxsg_dt.h" + +#define SOC_MICROCHIP_PIC32CXSG_OSC32K_FREQ_HZ 32768 +#define SOC_MICROCHIP_PIC32CXSG_DFLL48_FREQ_HZ 48000000 + +/** Processor Clock (HCLK) Frequency */ +#define SOC_MICROCHIP_PIC32CXSG_HCLK_FREQ_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC +/** Master Clock (MCK) Frequency */ +#define SOC_MICROCHIP_PIC32CXSG_MCK_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_HCLK_FREQ_HZ +#define SOC_MICROCHIP_PIC32CXSG_GCLK0_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_MCK_FREQ_HZ +#define SOC_MICROCHIP_PIC32CXSG_GCLK2_FREQ_HZ 48000000 + +#define SOC_ATMEL_SAM0_HCLK_FREQ_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC +#define SOC_ATMEL_SAM0_MCK_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_HCLK_FREQ_HZ +#define SOC_ATMEL_SAM0_GCLK0_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_MCK_FREQ_HZ +#define SOC_ATMEL_SAM0_GCLK2_FREQ_HZ 48000000 + +/* PIC32CXSG is using the original Atmel SAM0 UART driver. + * The driver uses MCLK to select different GCLK register structures. + * We define GCLK pointer using a HAL define fixup structure matching the MCLK + * version of global clock registers. + * Once PIC32CXSG has Microchip DFP compliant driver these will no longer be required. + */ +#define MCLK (DT_REG_ADDR(DT_NODELABEL(mclk))) +#define GCLK ((Gclk *)(DT_REG_ADDR(DT_NODELABEL(gclk)))) + +#endif /* _SOC_MICROCHIP_PIC32CXSG41_SOC_H_ */ diff --git a/soc/microchip/pic32cxsg/pic32cxsg60/CMakeLists.txt b/soc/microchip/pic32cxsg/pic32cxsg60/CMakeLists.txt new file mode 100644 index 0000000000000..a7bdea6c18973 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg60/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) diff --git a/soc/microchip/pic32cxsg/pic32cxsg60/Kconfig b/soc/microchip/pic32cxsg/pic32cxsg60/Kconfig new file mode 100644 index 0000000000000..7c94de92c88b0 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg60/Kconfig @@ -0,0 +1,12 @@ +# Microchip PIC32CXSG MCU series + +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC32CXSG60 + select ARM + select CPU_CORTEX_M4 + select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU + select SOC_RESET_HOOK diff --git a/soc/microchip/pic32cxsg/pic32cxsg60/Kconfig.defconfig b/soc/microchip/pic32cxsg/pic32cxsg60/Kconfig.defconfig new file mode 100644 index 0000000000000..86b25e34f635c --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg60/Kconfig.defconfig @@ -0,0 +1,15 @@ +# Microchip PIC32CXSG MCU series configuration options + +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_PIC32CXSG60 + +config NUM_IRQS + default 137 + +config ROM_START_OFFSET + default 0x400 if BOOTLOADER_MCUBOOT + +endif # SOC_SERIES_PIC32CXSG60 diff --git a/soc/microchip/pic32cxsg/pic32cxsg60/Kconfig.soc b/soc/microchip/pic32cxsg/pic32cxsg60/Kconfig.soc new file mode 100644 index 0000000000000..5665679cb3085 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg60/Kconfig.soc @@ -0,0 +1,26 @@ +# Microchip PIC32CXSG60 MCU series + +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC32CXSG60 + bool + select SOC_FAMILY_MICROCHIP_PIC32CXSG + help + Enable support for Microchip PIC32CXSG Cortex-M4F microcontrollers. + +config SOC_SERIES + default "pic32cxsg60" if SOC_SERIES_PIC32CXSG60 + +config SOC_PIC32CX1025SG60100 + bool + select SOC_SERIES_PIC32CXSG60 + +config SOC_PIC32CX1025SG60128 + bool + select SOC_SERIES_PIC32CXSG60 + +config SOC + default "pic32cx1025sg60100" if SOC_PIC32CX1025SG60100 + default "pic32cx1025sg60128" if SOC_PIC32CX1025SG60128 diff --git a/soc/microchip/pic32cxsg/pic32cxsg60/soc.h b/soc/microchip/pic32cxsg/pic32cxsg60/soc.h new file mode 100644 index 0000000000000..f1534204dd26a --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg60/soc.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_MICROCHIP_PIC32CXSG60_SOC_H_ +#define _SOC_MICROCHIP_PIC32CXSG60_SOC_H_ + +#ifndef _ASMLANGUAGE + +#define DONT_USE_CMSIS_INIT + +#include + +#if defined(CONFIG_SOC_PIC32CX1025SG60100) +#include +#elif defined(CONFIG_SOC_PIC32CX1025SG60128) +#include + +#else +#error Library does not support the specified device. +#endif + +#endif /* _ASMLANGUAGE */ + +#include +#include "../common/microchip_pic32cxsg_dt.h" + +#define SOC_MICROCHIP_PIC32CXSG_OSC32K_FREQ_HZ 32768 +#define SOC_MICROCHIP_PIC32CXSG_DFLL48_FREQ_HZ 48000000 + +/** Processor Clock (HCLK) Frequency */ +#define SOC_MICROCHIP_PIC32CXSG_HCLK_FREQ_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC +/** Master Clock (MCK) Frequency */ +#define SOC_MICROCHIP_PIC32CXSG_MCK_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_HCLK_FREQ_HZ +#define SOC_MICROCHIP_PIC32CXSG_GCLK0_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_MCK_FREQ_HZ +#define SOC_MICROCHIP_PIC32CXSG_GCLK2_FREQ_HZ 48000000 + +#define SOC_ATMEL_SAM0_HCLK_FREQ_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC +#define SOC_ATMEL_SAM0_MCK_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_HCLK_FREQ_HZ +#define SOC_ATMEL_SAM0_GCLK0_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_MCK_FREQ_HZ +#define SOC_ATMEL_SAM0_GCLK2_FREQ_HZ 48000000 + +/* PIC32CXSG is using the original Atmel SAM0 UART driver. + * The driver uses MCLK to select different GCLK register structures. + * We define GCLK pointer using a HAL define fixup structure matching the MCLK + * version of global clock registers. + * Once PIC32CXSG has Microchip DFP compliant driver these will no longer be required. + */ +#define MCLK (DT_REG_ADDR(DT_NODELABEL(mclk))) +#define GCLK ((Gclk *)(DT_REG_ADDR(DT_NODELABEL(gclk)))) + +#endif /* _SOC_MICROCHIP_PIC32CXSG41_SOC_H_ */ diff --git a/soc/microchip/pic32cxsg/pic32cxsg61/CMakeLists.txt b/soc/microchip/pic32cxsg/pic32cxsg61/CMakeLists.txt new file mode 100644 index 0000000000000..a7bdea6c18973 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg61/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microchip +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) diff --git a/soc/microchip/pic32cxsg/pic32cxsg61/Kconfig b/soc/microchip/pic32cxsg/pic32cxsg61/Kconfig new file mode 100644 index 0000000000000..c7fda07db11c0 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg61/Kconfig @@ -0,0 +1,13 @@ +# Microchip PIC32CXSG MCU series + +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC32CXSG61 + select ARM + select CPU_CORTEX_M4 + select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU + select SOC_RESET_HOOK diff --git a/soc/microchip/pic32cxsg/pic32cxsg61/Kconfig.defconfig b/soc/microchip/pic32cxsg/pic32cxsg61/Kconfig.defconfig new file mode 100644 index 0000000000000..8c006547df9ef --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg61/Kconfig.defconfig @@ -0,0 +1,15 @@ +# Microchip PIC32CXSG MCU series configuration options + +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_PIC32CXSG61 + +config NUM_IRQS + default 137 + +config ROM_START_OFFSET + default 0x400 if BOOTLOADER_MCUBOOT + +endif # SOC_SERIES_PIC32CXSG61 diff --git a/soc/microchip/pic32cxsg/pic32cxsg61/Kconfig.soc b/soc/microchip/pic32cxsg/pic32cxsg61/Kconfig.soc new file mode 100644 index 0000000000000..3d32e6e4a02ce --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg61/Kconfig.soc @@ -0,0 +1,26 @@ +# Microchip PIC32CXSG61 MCU series + +# Copyright (c) 2024 Microchip + +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC32CXSG61 + bool + select SOC_FAMILY_MICROCHIP_PIC32CXSG + help + Enable support for Microchip PIC32CXSG Cortex-M4F microcontrollers. + +config SOC_SERIES + default "pic32cxsg61" if SOC_SERIES_PIC32CXSG61 + +config SOC_PIC32CX1025SG61100 + bool + select SOC_SERIES_PIC32CXSG61 + +config SOC_PIC32CX1025SG61128 + bool + select SOC_SERIES_PIC32CXSG61 + +config SOC + default "pic32cx1025sg61100" if SOC_PIC32CX1025SG61100 + default "pic32cx1025sg61128" if SOC_PIC32CX1025SG61128 diff --git a/soc/microchip/pic32cxsg/pic32cxsg61/soc.h b/soc/microchip/pic32cxsg/pic32cxsg61/soc.h new file mode 100644 index 0000000000000..d8d1f7021c523 --- /dev/null +++ b/soc/microchip/pic32cxsg/pic32cxsg61/soc.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Microchip + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_MICROCHIP_PIC32CXSG61_SOC_H_ +#define _SOC_MICROCHIP_PIC32CXSG61_SOC_H_ + +#ifndef _ASMLANGUAGE + +#define DONT_USE_CMSIS_INIT + +#include + +#if defined(CONFIG_SOC_PIC32CX1025SG61100) +#include +#elif defined(CONFIG_SOC_PIC32CX1025SG61128) +#include + +#else +#error Library does not support the specified device. +#endif + +#endif /* _ASMLANGUAGE */ + +#include +#include "../common/microchip_pic32cxsg_dt.h" + +#define SOC_MICROCHIP_PIC32CXSG_OSC32K_FREQ_HZ 32768 +#define SOC_MICROCHIP_PIC32CXSG_DFLL48_FREQ_HZ 48000000 + +/** Processor Clock (HCLK) Frequency */ +#define SOC_MICROCHIP_PIC32CXSG_HCLK_FREQ_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC +/** Master Clock (MCK) Frequency */ +#define SOC_MICROCHIP_PIC32CXSG_MCK_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_HCLK_FREQ_HZ +#define SOC_MICROCHIP_PIC32CXSG_GCLK0_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_MCK_FREQ_HZ +#define SOC_MICROCHIP_PIC32CXSG_GCLK2_FREQ_HZ 48000000 + +#define SOC_ATMEL_SAM0_HCLK_FREQ_HZ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC +#define SOC_ATMEL_SAM0_MCK_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_HCLK_FREQ_HZ +#define SOC_ATMEL_SAM0_GCLK0_FREQ_HZ SOC_MICROCHIP_PIC32CXSG_MCK_FREQ_HZ +#define SOC_ATMEL_SAM0_GCLK2_FREQ_HZ 48000000 + +/* PIC32CXSG is using the original Atmel SAM0 UART driver. + * The driver uses MCLK to select different GCLK register structures. + * We define GCLK pointer using a HAL define fixup structure matching the MCLK + * version of global clock registers. + * Once PIC32CXSG has Microchip DFP compliant driver these will no longer be required. + */ +#define MCLK (DT_REG_ADDR(DT_NODELABEL(mclk))) +#define GCLK ((Gclk *)(DT_REG_ADDR(DT_NODELABEL(gclk)))) + +#endif /* _SOC_MICROCHIP_PIC32CXSG41_SOC_H_ */ diff --git a/soc/microchip/pic32cxsg/soc.yml b/soc/microchip/pic32cxsg/soc.yml new file mode 100644 index 0000000000000..787388f435a42 --- /dev/null +++ b/soc/microchip/pic32cxsg/soc.yml @@ -0,0 +1,17 @@ +family: +- name: microchip_pic32cxsg + series: + - name: pic32cxsg41 + socs: + - name: pic32cx1025sg41064 + - name: pic32cx1025sg41080 + - name: pic32cx1025sg41100 + - name: pic32cx1025sg41128 + - name: pic32cxsg60 + socs: + - name: pic32cx1025sg60100 + - name: pic32cx1025sg60128 + - name: pic32cxsg61 + socs: + - name: pic32cx1025sg61100 + - name: pic32cx1025sg61128