From 2ef61530474d439d178d99e4aa291910250b3c44 Mon Sep 17 00:00:00 2001 From: "Daniel P. Carvalho" Date: Sat, 3 Oct 2026 13:44:56 -0300 Subject: [PATCH] boards/mips/pic32mz: add Microchip EV49N51A board. Add the Microchip EV49N51A Ethernet to Wi-Fi Bridge board, built around the WFI32E01PE module (PIC32MZ-W1) with a LAN8720A Ethernet PHY. The nsh configuration runs SYSCLK at 200 MHz with the console on UART1 (dedicated pins RA8/RA9, header J203, 115200 8N1) and drives the red and green user LEDs on RK1/RK3. It selects PGC2/PGD2 as the debug channel. The SST26VF032B serial flash on SPI1 (dedicated pins, CS on RA1) is exported as /dev/mtdblock0. Its SPI frequency is set to 20 MHz: the SST26 driver's 64 MHz default is above PBCLK3/2 (25 MHz), which pic32mz_spi.c does not handle. mips-debug.ld is used with every toolchain. It has no OUTPUT_FORMAT, because XC32 and Pinguino name their little-endian ELF targets differently; the board passes -EL to the linker instead. With XC32 the board builds with -mno-dsp -mno-dspr2: NuttX does not enable or save the DSP ASE state. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Daniel P. Carvalho --- .../mips/pic32mz/boards/ev49n51a/ev49n51a.jpg | Bin 0 -> 44913 bytes .../mips/pic32mz/boards/ev49n51a/index.rst | 283 ++++++++++++++++ .../platforms/mips/pic32mz/index.rst | 13 + boards/Kconfig | 14 + boards/mips/pic32mz/ev49n51a/Kconfig | 8 + .../pic32mz/ev49n51a/configs/nsh/defconfig | 43 +++ boards/mips/pic32mz/ev49n51a/include/board.h | 194 +++++++++++ .../mips/pic32mz/ev49n51a/scripts/Make.defs | 66 ++++ .../pic32mz/ev49n51a/scripts/mips-debug.ld | 305 ++++++++++++++++++ boards/mips/pic32mz/ev49n51a/src/Makefile | 35 ++ boards/mips/pic32mz/ev49n51a/src/ev49n51a.h | 95 ++++++ .../pic32mz/ev49n51a/src/pic32mz_autoleds.c | 88 +++++ .../mips/pic32mz/ev49n51a/src/pic32mz_boot.c | 81 +++++ .../pic32mz/ev49n51a/src/pic32mz_bringup.c | 99 ++++++ .../mips/pic32mz/ev49n51a/src/pic32mz_spi.c | 98 ++++++ 15 files changed, 1422 insertions(+) create mode 100644 Documentation/platforms/mips/pic32mz/boards/ev49n51a/ev49n51a.jpg create mode 100644 Documentation/platforms/mips/pic32mz/boards/ev49n51a/index.rst create mode 100644 boards/mips/pic32mz/ev49n51a/Kconfig create mode 100644 boards/mips/pic32mz/ev49n51a/configs/nsh/defconfig create mode 100644 boards/mips/pic32mz/ev49n51a/include/board.h create mode 100644 boards/mips/pic32mz/ev49n51a/scripts/Make.defs create mode 100644 boards/mips/pic32mz/ev49n51a/scripts/mips-debug.ld create mode 100644 boards/mips/pic32mz/ev49n51a/src/Makefile create mode 100644 boards/mips/pic32mz/ev49n51a/src/ev49n51a.h create mode 100644 boards/mips/pic32mz/ev49n51a/src/pic32mz_autoleds.c create mode 100644 boards/mips/pic32mz/ev49n51a/src/pic32mz_boot.c create mode 100644 boards/mips/pic32mz/ev49n51a/src/pic32mz_bringup.c create mode 100644 boards/mips/pic32mz/ev49n51a/src/pic32mz_spi.c diff --git a/Documentation/platforms/mips/pic32mz/boards/ev49n51a/ev49n51a.jpg b/Documentation/platforms/mips/pic32mz/boards/ev49n51a/ev49n51a.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4850780a3cda372ffcc380a96e0ba43c535f692e GIT binary patch literal 44913 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 PIbp9O|8L)-|C#@932@UU literal 0 HcmV?d00001 diff --git a/Documentation/platforms/mips/pic32mz/boards/ev49n51a/index.rst b/Documentation/platforms/mips/pic32mz/boards/ev49n51a/index.rst new file mode 100644 index 00000000000..fb9510cf642 --- /dev/null +++ b/Documentation/platforms/mips/pic32mz/boards/ev49n51a/index.rst @@ -0,0 +1,283 @@ +================================================ +Microchip EV49N51A (Ethernet to Wi-Fi Bridge) +================================================ + +.. tags:: arch:mips, chip:pic32mz, vendor:microchip + +.. figure:: ev49n51a.jpg + :figwidth: 40% + :align: center + :alt: The Microchip EV49N51A Ethernet to Wi-Fi Bridge board + + The Microchip EV49N51A Ethernet to Wi-Fi Bridge board + +This page documents the NuttX port to the Microchip EV49N51A, the +"Ethernet to Wi-Fi Bridge" reference design built around the WFI32E01PE +Wi-Fi module. The module contains a PIC32MZ1025W104132 (PIC32MZ-W1 +family) microcontroller. + +Features +======== + +* WFI32E01PE module (PCB antenna) with a PIC32MZ1025W104132: + + * MIPS32 M-Class core at 200 MHz + * 1 MB program flash, 256 KB data RAM + * 40 MHz crystal inside the module + * 2.4 GHz IEEE 802.11 b/g/n Wi-Fi (not supported by NuttX) + +* SST26VF032B 32 Mbit (4 MB) SPI serial flash (U202) +* LAN8720A 10/100 Ethernet PHY (U301, RMII) with RJ45 connector J301 +* USB Type-C connector J202 (5 V power input only; the data lines are + not connected) and MCP1727 3.3 V regulator +* Debug UART header J203 +* Two user LEDs and one user button +* ICSP header J204 (not fitted on the kit) + +Supported hardware +================== + +========================= ======= ==================================== +Peripheral Status Notes +========================= ======= ==================================== +UART1 Yes NSH console on J203 +Timers Yes System tick +GPIO Yes +SPI1 Yes SST26VF032B; reads tested only +I2C1/I2C2 Build Not tested; no I2C device on board +Ethernet No +Wi-Fi No +========================= ======= ==================================== + +Pin mapping +=========== + +Module pads and chip pins as wired on the EV49N51A (schematic 02-01134 +Rev 2): + +============== ================ ============================================= +Pin Signal Notes +============== ================ ============================================= +RA8 U1RX Debug UART, dedicated pin (not PPS) +RA9 U1TX Debug UART, dedicated pin (not PPS) +RK1 LED D201 (red) Active high +RK3 LED D202 (green) Active high +RA10 SW202 User button, low when pressed +RA1 SST26 CS GPIO, active low +RPC6 SPI1 SCK Dedicated SPI1 pin (``DEVCFG1.HSSPIEN``) +RPC7 SPI1 SDI Dedicated SPI1 pin +RPC8 SPI1 SDO Dedicated SPI1 pin +RB4 / RB5 PGC2 / PGD2 ICSP (J204), debug channel 2 +RA4 / RA5 I2C1 GPIO header footprint (not fitted) +============== ================ ============================================= + +The Ethernet PHY uses RPC9-RPC15, RPK6, RPK12-RPK14 and RPA14, but there +is no Ethernet driver yet. + +Buttons and LEDs +================ + +The board has two user LEDs, both active high: + +* D201 (red): RK1 +* D202 (green): RK3 + +D203 (red) is the power LED and cannot be controlled by software. + +When ``CONFIG_ARCH_LEDS`` is selected (the default), the LEDs are used by +the OS as follows: + +================ ======================= ======= ======= +SYMBOL MEANING GREEN RED +================ ======================= ======= ======= +LED_STARTED NuttX has been started OFF OFF +LED_HEAPALLOCATE Heap has been allocated OFF OFF +LED_IRQSENABLED Interrupts enabled OFF OFF +LED_STACKCREATED Idle stack created ON OFF +LED_INIRQ In an interrupt N/C GLOW +LED_SIGNAL In a signal handler N/C GLOW +LED_ASSERTION An assertion failed N/C GLOW +LED_PANIC The system has crashed N/C FLASH +================ ======================= ======= ======= + +The user button SW202 (RA10) and the reset button SW203 (MCLR) are +present on the board, but there is no button driver yet. + +Clocking +======== + +Unlike the PIC32MZ EC/EF families, the PIC32MZ-W1 does not configure its +PLLs from the configuration words. At boot, ``pic32mz_wfi32_pwrclk.c``: + +#. On B0 silicon, after a power-on or brown-out reset, switches the + power management unit (PMU) from its power-on MLDO mode to buck mode, + using the factory trim values stored in the device. + ``CONFIG_PIC32MZ_W1_PMU_MLDO=y`` skips this step and keeps the PMU in + MLDO mode. +#. Starts the 40 MHz primary oscillator inside the module. +#. Programs the system PLL (40 MHz / 5 * 150 / 6 = 200 MHz) and the + Ethernet/Wi-Fi PLL, and switches SYSCLK to the system PLL. + +The peripheral bus clocks are set in ``include/board.h``: + +======= ======= ========= ===================================== +Clock Divider Frequency Used by +======= ======= ========= ===================================== +PBCLK1 5 40 MHz Timers, UART3 +PBCLK2 2 100 MHz I/O ports, I2C1, ADC, CAN +PBCLK3 4 50 MHz UART1/2, SPI1/2, I2C2 +PBCLK4 10 20 MHz RTCC, DSCON +PBCLK5 2 100 MHz Flash, crypto, SQI +======= ======= ========= ===================================== + +PBCLK6 clocks the CPU on PIC32MZ-W1 and is not changed. + +The program flash uses ``CONFIG_PIC32MZ_W1_FLASH_WAITSTATES`` wait states +(5 by default at 200 MHz). + +Configuration words +------------------- + +The build places the configuration words (DEVCFG0/1/2/4, FBCFG0, FCPN0 and +FSIGN0) in ``nuttx.hex``, so no separate configuration step is needed when +flashing. They are set through Kconfig (``PIC32MZ_*`` options in +``arch/mips/src/pic32mz/Kconfig``). The ``nsh`` configuration selects ICSP +channel 2 (``CONFIG_PIC32MZ_ICESEL_CH2``) and keeps the secondary +oscillator disabled: the 32.768 kHz crystal X401 is not fitted on the kit. + +Toolchains +========== + +The port builds with two toolchains: + +* ``CONFIG_MIPS32_TOOLCHAIN_PINGUINOL``: the Pinguino p32-gcc toolchain, + also used by the NuttX CI for all MIPS boards. It can be downloaded from + https://github.com/PinguinoIDE/pinguino-compilers: + + .. code:: console + + $ curl -sSL -O https://github.com/PinguinoIDE/pinguino-compilers/releases/download/v20.10/pinguino-linux64-p32.zip + $ unzip pinguino-linux64-p32.zip + $ export PATH=$PWD/p32/bin:$PATH + +* ``CONFIG_MIPS32_TOOLCHAIN_MICROCHIPL_XC32``: Microchip MPLAB XC32 for + Linux (tested with v6.00), selected by the ``nsh`` defconfig. + +XC32 v6 and later no longer include device support and need the +`PIC32MZ-W Device Family Pack +`_ (DFP). Extract the +``Microchip.PIC32MZ-W_DFP`` ``.atpack`` file (a zip archive) to +``~/microchip/WFI32-W_DFP``, or point ``WFI32E01_DFP_DIR`` at another +location: + +.. code:: console + + $ make WFI32E01_DFP_DIR=/path/to/PIC32MZ-W_DFP + +Flashing +======== + +The EV49N51A has no on-board programmer. The flash is programmed through +the ICSP header J204 (MCLR, PGC2/RB4, PGD2/RB5, 3.3 V, GND), which is not +fitted on the kit, using a Microchip programmer and MPLAB IPE. The port was +tested with a PICkit 3: + +.. code:: console + + $ cd /opt/microchip/mplabx/v6.20/mplab_platform/mplab_ipe + $ ./ipecmd.sh -P32MZ1025W104132 -TPPK3 -M -F/path/to/nuttx/nuttx.hex -Y -OL + +``-M`` programs the whole device, ``-Y`` verifies it and ``-OL`` releases +the device from reset. For other programmers, change ``-TPPK3`` (for +example ``-TPPK4`` for a PICkit 4). + +.. warning:: + + Programming erases the factory firmware. Read it back first with + MPLAB IPE if you want to restore it later. + +.. note:: + + Debugging through a PICkit 3 does not work with this device + (MPLAB X marks PICkit 3 support for it as beta). Programming works. + For early boot problems, use ``CONFIG_PIC32MZ_W1_BOOTTRACE`` (see + below). + +Configurations +============== + +Each configuration is built with: + +.. code:: console + + $ ./tools/configure.sh -l ev49n51a: + $ make + +To build with the Pinguino toolchain instead of XC32: + +.. code:: console + + $ ./tools/configure.sh -l ev49n51a:nsh + $ kconfig-tweak --disable MIPS32_TOOLCHAIN_MICROCHIPL_XC32 \ + --enable MIPS32_TOOLCHAIN_PINGUINOL + $ make olddefconfig + $ make + +nsh +--- + +Basic NuttShell configuration with the console on UART1. Connect a 3.3 V +USB-to-serial adapter to J203: + +========== ============ ===================== +J203 pin Signal Adapter +========== ============ ===================== +1 U1RX (RA8) TX +2 U1TX (RA9) RX +3 GND GND +========== ============ ===================== + +and open it at 115200 8N1, without flow control. + +The SST26VF032B serial flash is registered as ``/dev/mtdblock0``. + +.. code:: console + + nsh> uname -a + NuttX 13.0.1-RC1 ec7277eeba Oct 3 2026 17:10:38 mips ev49n51a + nsh> ls -l /dev + /dev: + crw-rw-rw- 0 console + brw-rw-rw- 4194304 mtdblock0 + crw-rw-rw- 0 null + crw-rw-rw- 0 ttyS0 + crw-rw-rw- 0 zero + +Boot trace +========== + +``CONFIG_PIC32MZ_W1_BOOTTRACE=y`` prints one character on UART1 for each +PMU and clock bring-up step, before the PLLs are running. UART1 is clocked +from the internal FRC during this phase, so the baud rate is about +117647 instead of 115200; most terminals still read it. The normal console +takes over once the clocks are up. + +Silicon tested: WFI32E01PE, revision B0 (DEVID 0x0A400000). + +Limitations +=========== + +* No Ethernet or Wi-Fi driver. +* I2C1/I2C2 build but are not tested. +* SPI flash: only reads were tested (JEDEC ID and data), not writes or + erases. +* UART3 is not wired up. +* No button driver. + +References +========== + +* `PIC32MZ W1 and WFI32E01 Family Data Sheet (DS70005425) + `_ +* `EV49N51A Ethernet to Wi-Fi Bridge + `_ diff --git a/Documentation/platforms/mips/pic32mz/index.rst b/Documentation/platforms/mips/pic32mz/index.rst index d6fcd8a05d2..9c48777b6fb 100644 --- a/Documentation/platforms/mips/pic32mz/index.rst +++ b/Documentation/platforms/mips/pic32mz/index.rst @@ -60,6 +60,19 @@ This was a collaborative effort between Kristopher Tate, David Sidrane and myself. The basic port is functional and a NuttShell (NSH) configuration is available. +Microchip PIC32MZ-W1 +-------------------- + +PIC32MZ-W1 family (MIPS32 M-Class core with 2.4 GHz Wi-Fi), including the +WFI32E01 module. A port is available for the Microchip EV49N51A (Ethernet +to Wi-Fi Bridge) board, based on the WFI32E01PE module +(PIC32MZ1025W104132). + +The W1 special function register layout and clock tree differ from the +EC/EF families, and software must start the oscillator, the PLLs and the +power management unit at boot. Supported: UART, timers, GPIO and SPI +(tested), I2C (build only). Ethernet and Wi-Fi are not supported. + Supported Boards ================ diff --git a/boards/Kconfig b/boards/Kconfig index 3df775a7ff6..bf6fdbc6386 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -805,6 +805,16 @@ config ARCH_BOARD_CHIPKIT_WIFIRE board is a chipKIT Arduino-compatible board. This board features the Microchip PIC32MZ2048EFG100 MCU running at 200 MHz. +config ARCH_BOARD_EV49N51A + bool "Microchip EV49N51A Ethernet to Wi-Fi Bridge (WFI32E01PE)" + depends on ARCH_CHIP_WFI32E01 + select ARCH_HAVE_LEDS + ---help--- + This option selects the Microchip EV49N51A Ethernet to Wi-Fi + Bridge board, built around the WFI32E01PE module (PIC32MZ-W1 + family, MIPS32 M-Class core with integrated 802.11n Wi-Fi) + running at 200 MHz, with a LAN8720A Ethernet PHY. + config ARCH_BOARD_FLIPNCLICK_PIC32MZ bool "Mikroe Flip&Click PIC32MZ" depends on ARCH_CHIP_PIC32MZ2048EFH @@ -4047,6 +4057,7 @@ config ARCH_BOARD default "ez80f910200zco" if ARCH_BOARD_EZ80F910200ZCO default "fire-stm32v2" if ARCH_BOARD_FIRE_STM32 default "chipkit-wifire" if ARCH_BOARD_CHIPKIT_WIFIRE + default "ev49n51a" if ARCH_BOARD_EV49N51A default "flipnclick-pic32mz" if ARCH_BOARD_FLIPNCLICK_PIC32MZ default "flipnclick-sam3x" if ARCH_BOARD_FLIPNCLICK_SAM3X default "freedom-k28f" if ARCH_BOARD_FREEDOM_K28F @@ -5334,6 +5345,9 @@ endif if ARCH_BOARD_CHIPKIT_WIFIRE source "boards/mips/pic32mz/chipkit-wifire/Kconfig" endif +if ARCH_BOARD_EV49N51A +source "boards/mips/pic32mz/ev49n51a/Kconfig" +endif if ARCH_BOARD_FLIPNCLICK_PIC32MZ source "boards/mips/pic32mz/flipnclick-pic32mz/Kconfig" endif diff --git a/boards/mips/pic32mz/ev49n51a/Kconfig b/boards/mips/pic32mz/ev49n51a/Kconfig new file mode 100644 index 00000000000..657dad2fecd --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_BOARD_EV49N51A + +endif # ARCH_BOARD_EV49N51A diff --git a/boards/mips/pic32mz/ev49n51a/configs/nsh/defconfig b/boards/mips/pic32mz/ev49n51a/configs/nsh/defconfig new file mode 100644 index 00000000000..e0a67eab8eb --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/configs/nsh/defconfig @@ -0,0 +1,43 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_RAMFUNCS is not set +CONFIG_ARCH="mips" +CONFIG_ARCH_BOARD="ev49n51a" +CONFIG_ARCH_BOARD_EV49N51A=y +CONFIG_ARCH_CHIP="pic32mz" +CONFIG_ARCH_CHIP_PIC32MZ=y +CONFIG_ARCH_CHIP_PIC32MZW1=y +CONFIG_ARCH_CHIP_WFI32E01=y +CONFIG_ARCH_MIPS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=7245 +CONFIG_BUILTIN=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LINE_MAX=64 +CONFIG_MIPS32_TOOLCHAIN_MICROCHIPL_XC32=y +CONFIG_MTD=y +CONFIG_MTD_SST26=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PIC32MZ_ICESEL_CH2=y +CONFIG_PIC32MZ_SPI1=y +CONFIG_PIC32MZ_UART1=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0xa0000000 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=2 +CONFIG_START_MONTH=10 +CONFIG_START_YEAR=2026 +CONFIG_SYSTEM_NSH=y +CONFIG_UART1_SERIAL_CONSOLE=y diff --git a/boards/mips/pic32mz/ev49n51a/include/board.h b/boards/mips/pic32mz/ev49n51a/include/board.h new file mode 100644 index 00000000000..d3333273292 --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/include/board.h @@ -0,0 +1,194 @@ +/**************************************************************************** + * boards/mips/pic32mz/ev49n51a/include/board.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_MIPS_PIC32MZ_EV49N51A_INCLUDE_BOARD_H +#define __BOARDS_MIPS_PIC32MZ_EV49N51A_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Clocking ***************************************************************** + * + * Unlike EC/EF, PIC32MZ-W1's system PLL is NOT configured from these + * BOARD_PLL_* macros by pic32mz_lowinit.c - it is configured directly by + * pic32mz_wfi32_pwrclk.c (a fixed, hardcoded SPLLCON value, matching + * Microchip's own reference firmware for this chip/board family). The + * macros below exist only so that: + * + * 1. pic32mz_lowinit.c's self-consistency sanity check + * (CALC_SYSCLOCK == BOARD_CPU_CLOCK) passes. + * 2. pic32mz_prefetch() picks the correct number of flash wait states + * for the real CPU clock. + * + * They were derived by decoding the actual SPLLCON value + * (WFI32_SPLLCON_VALUE in pic32mz_wfi32_pwrclk.c) field-by-field + * (SPLLREFDIV=5, SPLLFBDIV=150, SPLLPOSTDIV1=6), combined with the + * documented CPU_CLOCK_FREQUENCY=200000000 from Microchip's reference + * firmware (definitions.h) to solve for the crystal frequency - NOT + * taken from a schematic. If pic32mz_wfi32_pwrclk.c's SPLLCON value ever + * changes, these must be recomputed to match. + */ + +#define BOARD_POSC_FREQ 40000000 /* Primary OSC XTAL frequency (derived, see above) */ + +#define BOARD_PLL_INPUT BOARD_POSC_FREQ +#define BOARD_PLL_IDIV 5 /* SPLLREFDIV */ +#define BOARD_PLL_MULT 150 /* SPLLFBDIV */ +#define BOARD_PLL_ODIV 6 /* SPLLPOSTDIV1 */ + +#define BOARD_CPU_CLOCK 200000000 /* CPU clock: 200MHz, per Microchip's + * reference firmware for this chip */ + +/* Peripheral clocks. + * + * Only PBCLK4 is set explicitly by pic32mz_wfi32_pwrclk.c (to divide-by-10, + * i.e. 20MHz, the value used by Microchip's example firmware); + * pic32mz_pbclk() will then apply the same BOARD_PB4DIV value redundantly + * (harmless, see pic32mz_lowinit.c). PBCLK1-3/5 divisors below are this + * NuttX port's own choice, chosen conservatively; they can be tuned later + * once real peripherals are exercised. Peripheral to bus assignments are + * from DS70005425 Table 11-1. + */ + +#define BOARD_PB1DIV 5 /* Divider = 5 */ +#define BOARD_PBCLK1 40000000 /* PBCLK1 = 200MHz/5 = 40MHz (Timers, UART3) */ + +#define BOARD_PBCLK2_ENABLE 1 +#define BOARD_PB2DIV 2 /* Divider = 2 */ +#define BOARD_PBCLK2 100000000 /* PBCLK2 = 200MHz/2 = 100MHz (Ports, I2C1, ADC, CAN) */ + +#define BOARD_PBCLK3_ENABLE 1 +#define BOARD_PB3DIV 4 /* Divider = 4 */ +#define BOARD_PBCLK3 50000000 /* PBCLK3 = 200MHz/4 = 50MHz (UART1/2, SPI, I2C2, IC, OC) */ + +#define BOARD_PBCLK4_ENABLE 1 +#define BOARD_PB4DIV 10 /* Divider = 10 (matches pic32mz_wfi32_pwrclk.c) */ +#define BOARD_PBCLK4 20000000 /* PBCLK4 = 200MHz/10 = 20MHz (RTCC, DSCON) */ + +#define BOARD_PBCLK5_ENABLE 1 +#define BOARD_PB5DIV 2 /* Divider = 2 */ +#define BOARD_PBCLK5 100000000 /* PBCLK5 = 200MHz/2 = 100MHz (Flash, Crypto, SQI) */ + +#undef BOARD_PBCLK6_ENABLE + +/* PIC32MZ-W1 has no PB7/PB8 bus - leave both undefined (see + * pic32mz_lowinit.c/hardware/pic32mz_osc.h for why these must stay + * undefined on this chip). + */ + +#undef BOARD_PBCLK7_ENABLE +#undef BOARD_PBCLK8_ENABLE + +/* Watchdog pre-scaler (not yet used - WDT is left disabled by the + * reference config; revisit if/when WDT support is added for this chip). + */ + +#define BOARD_WD_PRESCALER 1048576 + +/* LED definitions ********************************************************** + * + * Two user LEDs (EV49N51A schematic 02-01134 rev 2), both active high + * (anode on the pin, 330R to GND): + * + * D201 red - RK1 (module pad 34) + * D202 green - RK3 (module pad 35) + * + * When CONFIG_ARCH_LEDS is defined, they are used by the OS as follows: + * + * SYMBOL Meaning GREEN RED + * ----------------- ----------------------- ------- ------- + * LED_STARTED NuttX has been started OFF OFF + * LED_HEAPALLOCATE Heap has been allocated OFF OFF + * LED_IRQSENABLED Interrupts enabled OFF OFF + * LED_STACKCREATED Idle stack created ON OFF + * LED_INIRQ In an interrupt N/C GLOW + * LED_SIGNAL In a signal handler N/C GLOW + * LED_ASSERTION An assertion failed N/C GLOW + * LED_PANIC The system has crashed N/C FLASH + */ + +#define BOARD_LED_RED 0 +#define BOARD_LED_GREEN 1 +#define BOARD_NLEDS 2 + +#define BOARD_LED_RED_BIT (1 << BOARD_LED_RED) +#define BOARD_LED_GREEN_BIT (1 << BOARD_LED_GREEN) + +#define LED_STARTED 0 +#define LED_HEAPALLOCATE 1 +#define LED_IRQSENABLED 2 +#define LED_STACKCREATED 3 +#define LED_INIRQ 4 +#define LED_SIGNAL 4 +#define LED_ASSERTION 4 +#define LED_PANIC 4 + +/* UARTS ******************************************************************** + * + * The console is UART1 on 3-pin header J203 (1=U1RX, 2=U1TX, 3=GND); an + * external 3.3V USB-UART adapter is required, there is no on-board + * debugger/USB-UART bridge. J203 is wired to module pads 29 (U1TX, RA9) + * and 30 (U1RX, RA8), which are UART1's dedicated, non-PPS pins (RA8/RA9 + * have no RPn function). BOARD_U1RX_PPS/BOARD_U1TX_PPS are therefore + * intentionally left undefined so that no PPS routing is programmed. + */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_MIPS_PIC32MZ_EV49N51A_INCLUDE_BOARD_H */ diff --git a/boards/mips/pic32mz/ev49n51a/scripts/Make.defs b/boards/mips/pic32mz/ev49n51a/scripts/Make.defs new file mode 100644 index 00000000000..3d558c5ede9 --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/scripts/Make.defs @@ -0,0 +1,66 @@ +############################################################################ +# boards/mips/pic32mz/ev49n51a/scripts/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/.config +include $(TOPDIR)/tools/Config.mk +include $(TOPDIR)/tools/pic32/Config.mk +include $(TOPDIR)/arch/mips/src/mips32/Toolchain.defs + +# mips-debug.ld is plain GNU ld syntax and works with every supported +# toolchain (XC32, Pinguino, generic mips-elf), so override the +# per-toolchain default from Toolchain.defs. + +LDSCRIPT = mips-debug.ld + +# MPLAB XC32 (Linux). XC32 v6+ requires an explicit Device Family Pack +# (DFP) path via -mdfp - it no longer bundles device support. Point +# WFI32E01_DFP_DIR at an extracted Microchip PIC32MZ-W_DFP +# (packs.download.microchip.com) if it is not already at this default +# path. + +ifeq ($(CONFIG_MIPS32_TOOLCHAIN_MICROCHIPL_XC32),y) + MIPS_MPROCESSOR = WFI32E01 + WFI32E01_DFP_DIR ?= $(HOME)/microchip/WFI32-W_DFP + ARCHCPUFLAGS += -mdfp=$(WFI32E01_DFP_DIR) + + # -mprocessor=WFI32E01 lets XC32 emit DSP ASE instructions (e.g. lwx). + # They trap unless CP0 Status.MX is set, which NuttX's head.S does not + # do, and NuttX's MIPS context switch does not save the DSP state, so + # keep the compiler away from the DSP ASE (verified on hardware: the + # first lwx hung the boot). + + ARCHCPUFLAGS += -mno-dsp -mno-dspr2 +endif + +ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) + +# The linker is invoked directly, not through gcc, so it does not see the +# -EL from ARCHCPUFLAGS (see the note in mips-debug.ld). + +LDFLAGS += -EL + +CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS := $(CFLAGS) -D__ASSEMBLY__ diff --git a/boards/mips/pic32mz/ev49n51a/scripts/mips-debug.ld b/boards/mips/pic32mz/ev49n51a/scripts/mips-debug.ld new file mode 100644 index 00000000000..687043f05a4 --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/scripts/mips-debug.ld @@ -0,0 +1,305 @@ +/**************************************************************************** + * boards/mips/pic32mz/ev49n51a/scripts/mips-debug.ld + * + * Adapted from boards/mips/pic32mz/flipnclick-pic32mz/scripts/mips-debug.ld + * for the WFI32E01 (PIC32MZ-W1). Memory region addresses/sizes were + * cross-checked against Microchip's PIC32MZ-W_DFP (WFI32E01.atdf) and its + * reference linker script (xc32/WFI32E01/pWFI32E01.ld) - WFI32E01's + * program flash lives at a different physical base (0x10000000) than + * EC/EF (0x1d000000); do not assume EC/EF addresses apply. + * + * The MIPS32 microAptiv exception vector layout (reset/TLB-refill/cache + * error/general/interrupt/EJTAG offsets from EBase) is core-architecture + * defined, not PIC32-family specific, so that part is unchanged from + * EC/EF. + * + * The boot-flash configuration words (.devcfg at 0xbfc55f88, plus FCPN0 + * and FSIGN0) are emitted by pic32mz_head.S; see + * hardware/pic32mzw1_features.h. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* Memory Regions ***********************************************************/ + +MEMORY +{ + /* WFI32E01 has 1024Kb (1MB) of program FLASH at physical address + * 0x10000000, always accessed at KSEG0 address 0x9000:0000. + */ + + kseg0_progmem (rx) : ORIGIN = 0x90000000, LENGTH = 1024K + + /* Exception vectors and startup trampoline, in boot flash + * (0xbfc00000, KSEG1). Offsets below the vectors are defined by the + * MIPS32 microAptiv core architecture (EBase-relative), same as on + * PIC32MZ-EC/EF: + * + * REGION PHYSICAL KSEG SIZE + * DESCRIPTION START ADDR (BYTES) + * ------------- ---------- ------ ---------------------- + * Reset 0x1fc00000 KSEG1 512 + * TLB Refill 0x1fc00200 KSEG1 256 + * Cache Error 0x1fc00300 KSEG1 128 + * Others 0x1fc00380 KSEG1 128 + * Interrupt 0x1fc00400 KSEG1 128 + * JTAG 0x1fc00480 KSEG1 16 + * + * Exceptions assume STATUS:BEV=0/1,EXL=0; CAUSE:IV=1; multi-vector + * support disabled - same configuration pic32mz_head.S sets up for + * EC/EF. + */ + + kseg1_reset (rx) : ORIGIN = 0xbfc00000, LENGTH = 384 + kseg1_genexcpt (rx) : ORIGIN = 0xbfc00180, LENGTH = 128 + kseg1_ebexcpt (rx) : ORIGIN = 0xbfc00200, LENGTH = 128 + kseg1_bevexcpt (rx) : ORIGIN = 0xbfc00380, LENGTH = 128 + kseg1_intexcpt (rx) : ORIGIN = 0xbfc00400, LENGTH = 128 + kseg1_dbgexcpt (rx) : ORIGIN = 0xbfc00480, LENGTH = 16 + kseg0_bootmem (rx) : ORIGIN = 0x9fc004ac, LENGTH = 8192-1196 + kseg1_dbgcode (rx) : ORIGIN = 0xbfc02000, LENGTH = 4096-16 + + /* Boot-flash configuration words (primary copy) */ + + kseg1_devcfg (r) : ORIGIN = 0xbfc55f88, LENGTH = 24 + kseg1_devcp (r) : ORIGIN = 0xbfc55fbc, LENGTH = 4 + kseg1_devsign (r) : ORIGIN = 0xbfc55fdc, LENGTH = 4 + + /* WFI32E01 has 256Kb of data memory at physical address 0x00000000, + * always accessed through KSEG1 (no data cache). 640 bytes are set + * aside at the start, matching the margin EC/EF boards reserve. + */ + + kseg1_datamem (rw!x) : ORIGIN = 0xa0000200, LENGTH = 256K - 640 +} + +/* No OUTPUT_FORMAT: XC32 names its little-endian ELF target + * elf32-tradlittlemips while Pinguino's binutils only know + * elf32-littlemips. Make.defs passes -EL instead, so each linker + * picks its own little-endian format. + */ + +OUTPUT_ARCH(mips) +ENTRY(__start) + +SECTIONS +{ + /* Boot FLASH sections */ + + .reset : + { + KEEP (*(.reset)) + } > kseg1_reset + + /* KSEG1 exception handler "trampolines" */ + + .gen_excpt : + { + KEEP (*(.gen_excpt)) + } > kseg1_genexcpt + + .ebase_excpt : + { + KEEP (*(.ebase_excpt)) + } > kseg1_ebexcpt + + .bev_excpt : + { + KEEP (*(.bev_excpt)) + } > kseg1_bevexcpt + + .int_excpt : + { + KEEP (*(.int_excpt)) + } > kseg1_intexcpt + + .dbg_excpt = ORIGIN(kseg1_dbgexcpt); + + .start : + { + /* KSEG0 Reset startup logic */ + + *(.start) + + /* KSEG0 exception handlers */ + + *(.nmi_handler) + *(.bev_handler) + *(.int_handler) + } > kseg0_bootmem + + .dbg_code = ORIGIN(kseg1_dbgcode); + + .devcfg : + { + KEEP (*(.devcfg)) + } > kseg1_devcfg + + .devcfg_cp : + { + KEEP (*(.devcfg_cp)) + } > kseg1_devcp + + .devcfg_sign : + { + KEEP (*(.devcfg_sign)) + } > kseg1_devsign + + /* ABI flags note: not needed in the image; discard it so it is not + * placed as an orphan into the configuration regions above. + */ + + /DISCARD/ : { *(.MIPS.abiflags) } + + /* Program FLASH sections */ + + .text : + { + _stext = ABSOLUTE(.); + *(.text .text.*) + *(.stub) + KEEP (*(.text.*personality*)) + *(.gnu.linkonce.t.*) + *(.gnu.warning) + *(.mips16.fn.*) + *(.mips16.call.*) + + /* Read-only data is included in the text section */ + + *(.rodata .rodata.*) + *(.rodata1) + *(.gnu.linkonce.r.*) + + /* Small initialized constant global and static data */ + + *(.sdata2 .sdata2.*) + *(.gnu.linkonce.s2.*) + + /* Uninitialized constant global and static data */ + + *(.sbss2 .sbss2.*) + *(.gnu.linkonce.sb2.*) + _etext = ABSOLUTE(.); + } > kseg0_progmem + + /* Initialization data begins here in progmem */ + + _data_loaddr = LOADADDR(.data); + + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + + .data : + { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + *(.data1) + } > kseg1_datamem AT > kseg0_progmem + + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + _gp = ALIGN(16) + 0x7FF0 ; + + .got : + { + *(.got.plt) *(.got) + } > kseg1_datamem AT > kseg0_progmem + + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } > kseg1_datamem AT > kseg0_progmem + + .lit8 : + { + *(.lit8) + } > kseg1_datamem AT > kseg0_progmem + + .lit4 : + { + *(.lit4) + . = ALIGN(4); + _edata = ABSOLUTE(.); + } >kseg1_datamem AT>kseg0_progmem + + .sbss : + { + . = ALIGN(16); + _sbss = ABSOLUTE(.); + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } >kseg1_datamem + + .bss : + { + *(.dynbss) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(16); + _ebss = ABSOLUTE(.); + } > kseg1_datamem + + /* Stabs debugging sections */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* DWARF debug sections */ + /* DWARF 1 */ + + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF 1 extensions */ + + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + /* DWARF 2 */ + + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /* SGI/MIPS DWARF 2 extensions */ + + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/boards/mips/pic32mz/ev49n51a/src/Makefile b/boards/mips/pic32mz/ev49n51a/src/Makefile new file mode 100644 index 00000000000..f12af7dadd4 --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/src/Makefile @@ -0,0 +1,35 @@ +############################################################################ +# boards/mips/pic32mz/ev49n51a/src/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/Make.defs + +CSRCS = pic32mz_boot.c pic32mz_bringup.c + +ifeq ($(CONFIG_PIC32MZ_SPI1),y) +CSRCS += pic32mz_spi.c +endif + +ifeq ($(CONFIG_ARCH_LEDS),y) +CSRCS += pic32mz_autoleds.c +endif + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/mips/pic32mz/ev49n51a/src/ev49n51a.h b/boards/mips/pic32mz/ev49n51a/src/ev49n51a.h new file mode 100644 index 00000000000..2e2f0e1ddda --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/src/ev49n51a.h @@ -0,0 +1,95 @@ +/**************************************************************************** + * boards/mips/pic32mz/ev49n51a/src/ev49n51a.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_MIPS_PIC32MZ_EV49N51A_SRC_EV49N51A_H +#define __BOARDS_MIPS_PIC32MZ_EV49N51A_SRC_EV49N51A_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "pic32mz_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* LEDs: D201 red on RK1, D202 green on RK3, both active high (see + * include/board.h). + */ + +#define GPIO_LED_RED (GPIO_OUTPUT | GPIO_VALUE_ZERO | GPIO_PORTK | GPIO_PIN1) +#define GPIO_LED_GREEN (GPIO_OUTPUT | GPIO_VALUE_ZERO | GPIO_PORTK | GPIO_PIN3) + +/* SST26VF032B serial flash (U202) on SPI1: chip select on RA1, active low, + * initially deselected. + */ + +#define GPIO_SST26_CS (GPIO_OUTPUT | GPIO_VALUE_ONE | GPIO_PORTA | GPIO_PIN1) + +/* SST26 MTD partition is exported as /dev/mtdblock */ + +#define SST26_MTD_MINOR 0 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_bringup + * + * Description: + * Bring up board features. + * + ****************************************************************************/ + +int pic32mz_bringup(void); + +/**************************************************************************** + * Name: pic32mz_led_initialize + * + * Description: + * Configure on-board LED GPIO for output (CONFIG_ARCH_LEDS only). + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_LEDS +void pic32mz_led_initialize(void); +#endif + +/**************************************************************************** + * Name: pic32mz_spidev_initialize + * + * Description: + * Configure the SPI chip select GPIOs. + * + ****************************************************************************/ + +#ifdef CONFIG_PIC32MZ_SPI1 +void pic32mz_spidev_initialize(void); +#endif + +#endif /* __BOARDS_MIPS_PIC32MZ_EV49N51A_SRC_EV49N51A_H */ diff --git a/boards/mips/pic32mz/ev49n51a/src/pic32mz_autoleds.c b/boards/mips/pic32mz/ev49n51a/src/pic32mz_autoleds.c new file mode 100644 index 00000000000..a78ca9d9cb2 --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/src/pic32mz_autoleds.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * boards/mips/pic32mz/ev49n51a/src/pic32mz_autoleds.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "mips_internal.h" +#include "pic32mz_gpio.h" +#include "ev49n51a.h" + +#ifdef CONFIG_ARCH_LEDS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_led_initialize + ****************************************************************************/ + +void pic32mz_led_initialize(void) +{ + pic32mz_configgpio(GPIO_LED_RED); + pic32mz_configgpio(GPIO_LED_GREEN); +} + +/**************************************************************************** + * Name: board_autoled_on + ****************************************************************************/ + +void board_autoled_on(int led) +{ + switch (led) + { + case LED_STACKCREATED: + pic32mz_gpiowrite(GPIO_LED_GREEN, true); + break; + + case LED_INIRQ: + pic32mz_gpiowrite(GPIO_LED_RED, true); + break; + + default: + break; + } +} + +/**************************************************************************** + * Name: board_autoled_off + ****************************************************************************/ + +void board_autoled_off(int led) +{ + if (led == LED_INIRQ) + { + pic32mz_gpiowrite(GPIO_LED_RED, false); + } +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/mips/pic32mz/ev49n51a/src/pic32mz_boot.c b/boards/mips/pic32mz/ev49n51a/src/pic32mz_boot.c new file mode 100644 index 00000000000..3186911c1f5 --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/src/pic32mz_boot.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * boards/mips/pic32mz/ev49n51a/src/pic32mz_boot.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "ev49n51a.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_boardinitialize + * + * Description: + * All PIC32MZ architectures must provide the following entry point. + * This entry point is called early in the initialization -- after all + * memory has been configured and mapped but before any devices have been + * initialized. + * + ****************************************************************************/ + +void pic32mz_boardinitialize(void) +{ +#ifdef CONFIG_PIC32MZ_SPI1 + pic32mz_spidev_initialize(); +#endif + +#ifdef CONFIG_ARCH_LEDS + pic32mz_led_initialize(); +#endif +} + +/**************************************************************************** + * Name: board_late_initialize + * + * Description: + * If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional + * initialization call will be performed in the boot-up sequence to a + * function called board_late_initialize(). board_late_initialize() will + * be called immediately after up_initialize() is called and just before + * the initial application is started. This additional initialization + * phase may be used, for example, to initialize board-specific device + * drivers. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARD_LATE_INITIALIZE +void board_late_initialize(void) +{ + /* Perform board initialization */ + + pic32mz_bringup(); +} +#endif /* CONFIG_BOARD_LATE_INITIALIZE */ diff --git a/boards/mips/pic32mz/ev49n51a/src/pic32mz_bringup.c b/boards/mips/pic32mz/ev49n51a/src/pic32mz_bringup.c new file mode 100644 index 00000000000..0d15ab279b6 --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/src/pic32mz_bringup.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * boards/mips/pic32mz/ev49n51a/src/pic32mz_bringup.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#ifdef CONFIG_MTD_SST26 +# include +# include "pic32mz_spi.h" +#endif + +#include "ev49n51a.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_bringup + * + * Description: + * Bring up board features + * + ****************************************************************************/ + +int pic32mz_bringup(void) +{ + int ret = OK; + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = nx_mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to mount procfs at /proc: %d\n", + ret); + } +#endif + +#if defined(CONFIG_MTD_SST26) && defined(CONFIG_PIC32MZ_SPI1) + struct spi_dev_s *spi; + struct mtd_dev_s *mtd; + + /* SST26VF032B serial flash on SPI1 */ + + spi = pic32mz_spibus_initialize(1); + if (spi == NULL) + { + syslog(LOG_ERR, "ERROR: Failed to initialize SPI1\n"); + } + else + { + mtd = sst26_initialize_spi(spi, 0); + if (mtd == NULL) + { + syslog(LOG_ERR, "ERROR: Failed to bind SPI1 to the SST26\n"); + } + else + { + ret = ftl_initialize(SST26_MTD_MINOR, mtd); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: ftl_initialize() failed: %d\n", ret); + } + } + } +#endif + + UNUSED(ret); + return OK; +} diff --git a/boards/mips/pic32mz/ev49n51a/src/pic32mz_spi.c b/boards/mips/pic32mz/ev49n51a/src/pic32mz_spi.c new file mode 100644 index 00000000000..7863baae66b --- /dev/null +++ b/boards/mips/pic32mz/ev49n51a/src/pic32mz_spi.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * boards/mips/pic32mz/ev49n51a/src/pic32mz_spi.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "pic32mz_gpio.h" +#include "pic32mz_spi.h" + +#include "ev49n51a.h" + +#ifdef CONFIG_PIC32MZ_SPI1 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_spidev_initialize + * + * Description: + * Configure the SPI chip select GPIOs. SPI1 itself uses its dedicated + * pins (SCK1 RC6, SDI1 RC7, SDO1 RC8), selected by DEVCFG1.HSSPIEN. + * + ****************************************************************************/ + +void pic32mz_spidev_initialize(void) +{ + pic32mz_configgpio(GPIO_SST26_CS); +} + +/**************************************************************************** + * Name: pic32mz_spi1select, pic32mz_spi1status and pic32mz_spi1cmddata + * + * Description: + * Board-specific select, status and cmddata methods of the SPI1 + * interface (see include/nuttx/spi/spi.h). The only device on SPI1 is + * the SST26VF032B serial flash. + * + ****************************************************************************/ + +void pic32mz_spi1select(struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ + spiinfo("devid: %08" PRIx32 " CS: %s\n", + devid, selected ? "assert" : "de-assert"); + + if (devid == SPIDEV_FLASH(0)) + { + /* CS is active low */ + + pic32mz_gpiowrite(GPIO_SST26_CS, !selected); + } +} + +uint8_t pic32mz_spi1status(struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} + +#ifdef CONFIG_SPI_CMDDATA +int pic32mz_spi1cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + return -ENODEV; +} +#endif + +#endif /* CONFIG_PIC32MZ_SPI1 */