Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/port/pic32mz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Build artifacts
*.o
app.elf
app.hex
app.map
# MDB / IPE transient files
mdb_flash.cmd
MPLABXLog.*
log.*
102 changes: 102 additions & 0 deletions src/port/pic32mz/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# wolfIP PIC32MZ EF port - build with Microchip XC32
#
# Copyright (C) 2026 wolfSSL Inc. Part of the wolfIP TCP/IP stack (GPLv3).
#
# Phase 0: clocks + UART2 console + heartbeat.
# Phase 1: wolfCrypt PIC32MZ hardware TRNG self-test.
# Phase 2: MDIO + LAN8740 PHY link bring-up.
# (Full Ethernet RX/TX driver + wolfIP core are added in later phases.)
#
# Usage:
# make # build app.hex
# make flash # program over the on-board debugger (v6.20 IPE)
# make clean
# Overridable:
# XC32_BIN= XC32 bin dir (default /opt/microchip/xc32/v5.10/bin)
# DFP= device family pack version dir
# DEVICE= 32MZ2048EFM144
# WOLFSSL_ROOT= path to wolfssl checkout (used from Phase 1 on)
# MDB= MPLAB X MDB CLI (default v6.20; v6.30 dropped the EF SK debugger)

XC32_BIN ?= /opt/microchip/xc32/v5.10/bin
DFP ?= /opt/microchip/mplabx/v6.30/packs/Microchip/PIC32MZ-EF_DFP/1.5.173
DEVICE ?= 32MZ2048EFM144

CC := $(XC32_BIN)/xc32-gcc
BIN2HEX := $(XC32_BIN)/xc32-bin2hex
SIZE := $(XC32_BIN)/xc32-size

# Flashing over the EF Starter Kit's on-board debugger.
# Use MPLAB X v6.20's MDB (Microchip DeBugger CLI): the stripped headless
# ipecmd cannot resolve the device pack ("Unable to locate DFP"), but MDB
# launches the full platform and resolves packs like the IDE/IPE GUI does.
# v6.30 dropped support for this on-board debugger, so v6.20 is required.
# MDB enumerates the on-board debugger as tool type "sk" (Starter Kit).
MDB ?= /opt/microchip/mplabx/v6.20/mplab_platform/bin/mdb.sh
MDB_DEVICE ?= PIC32MZ2048EFM144
MDB_TOOL ?= sk

ROOT := ../../..
WOLFSSL_ROOT ?= /home/davidgarske/GitHub/wolfssl

Comment on lines +39 to +41
# -O1 is available in the free XC32 edition (-O2/-Os/-O3 need a PRO license).
CFLAGS := -mprocessor=$(DEVICE) -mdfp="$(DFP)"
CFLAGS += -O1 -g -Wall -Wextra -ffunction-sections -fdata-sections
CFLAGS += -I. -I$(ROOT) -I$(ROOT)/src
CFLAGS += -DWOLFSSL_USER_SETTINGS -I$(WOLFSSL_ROOT)
CFLAGS += $(EXTRA_CFLAGS)

# Heap for the Hash-DRBG (wc_InitRng allocates the DRBG state).
LDFLAGS := -mprocessor=$(DEVICE) -mdfp="$(DFP)"
LDFLAGS += -Wl,--defsym,_min_heap_size=0x8000
LDFLAGS += -Wl,--gc-sections -Wl,-Map=app.map,--cref

# Port + application sources (strict warnings)
APP_SRCS := device_config.c clock_init.c uart_console.c timebase.c \
wolf_compat.c rng_selftest.c pic32mz_eth.c phy_lan8740.c main.c
APP_OBJS := $(patsubst %.c,%.o,$(APP_SRCS))

# wolfcrypt sources for the RNG self-test (compiled with relaxed warnings).
# Pulled directly from the sibling wolfssl checkout, no copy.
WC_SRC := $(WOLFSSL_ROOT)/wolfcrypt/src
WC_NAMES := random sha256 hash wc_port logging memory error
WC_OBJS := $(addsuffix .o,$(addprefix wc_,$(WC_NAMES)))
CFLAGS_WC := -mprocessor=$(DEVICE) -mdfp="$(DFP)" -O1 -g \
-ffunction-sections -fdata-sections \
-DWOLFSSL_USER_SETTINGS -I. -I$(WOLFSSL_ROOT) -w
Comment on lines +64 to +66

ALL_OBJS := $(APP_OBJS) $(WC_OBJS)

all: app.hex
@echo "Built PIC32MZ wolfIP port (Phase 0+1+2)"
@$(SIZE) app.elf

app.elf: $(ALL_OBJS)
$(CC) $(CFLAGS) $(ALL_OBJS) $(LDFLAGS) -o $@

app.hex: app.elf
$(BIN2HEX) $<

%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@

wc_%.o: $(WC_SRC)/%.c
$(CC) $(CFLAGS_WC) -c $< -o $@

# Program the hex over the on-board debugger via MDB. Close/disconnect the
# MPLAB X IPE/IDE GUI first so it isn't holding the tool. The command script:
# set programoptions.eraseb4program true -> full chip erase before program
# hwtool sk -p -> connect Starter Kit for programming
# program <app.hex> -> erase + program, then release
# If there is more than one "sk" tool, append the index (e.g. "hwtool sk -p 0").
# If "Failed to get Device ID" with the board visibly booting, the PKOB is
# losing MCLR (USB comms) -- move it to a direct/powered USB port and retry.
flash: app.hex
@printf 'device %s\nset programoptions.eraseb4program true\nhwtool %s -p\nprogram %s\nquit\n' \
"$(MDB_DEVICE)" "$(MDB_TOOL)" "$(CURDIR)/app.hex" > mdb_flash.cmd
cd $(dir $(MDB)) && sh ./mdb.sh $(CURDIR)/mdb_flash.cmd

clean:
rm -f *.o app.elf app.hex app.map mdb_flash.cmd MPLABXLog.* log.*

.PHONY: all clean flash
38 changes: 38 additions & 0 deletions src/port/pic32mz/board.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* board.h
*
* Board constants for the PIC32MZ EF Starter Kit (DM320007) + LAN8740 PHY DB.
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfIP TCP/IP stack.
*
* wolfIP is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfIP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef PIC32MZ_BOARD_H
#define PIC32MZ_BOARD_H

/* Clock tree (set by DEVCFG config words at reset; see device_config.c) */
#define SYS_CLK_FREQ 200000000ul /* SYSCLK from SPLL */
#define PBCLK2_FREQ 100000000ul /* peripheral bus 2 (UART) = SYSCLK/2 */
#define PBCLK5_FREQ 100000000ul /* peripheral bus 5 (EMAC) = SYSCLK/2 */

Check failure on line 29 in src/port/pic32mz/board.h

View workflow job for this annotation

GitHub Actions / Check spelling

EMAC ==> EMACS

/* Console UART: U2TX on RPB14, U2RX on RPG6 (external MCP2221 USB-UART) */
#define CONSOLE_BAUD 115200u

/* On-board LEDs LED1/LED2/LED3 on RH0/RH1/RH2 (active high) */
#define LED_MASK 0x0007u
#define LED_HEARTBEAT 0x0001u /* LED1 = RH0 */

#endif /* PIC32MZ_BOARD_H */
51 changes: 51 additions & 0 deletions src/port/pic32mz/cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* cache.h
*
* MIPS KSEG segment helpers for DMA-coherent access on PIC32MZ.
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfIP TCP/IP stack.
*
* wolfIP is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfIP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef PIC32MZ_CACHE_H
#define PIC32MZ_CACHE_H

#include <stdint.h>

/* The PIC32MZ Ethernet controller (EMAC) is not cache-coherent and programs

Check failure on line 28 in src/port/pic32mz/cache.h

View workflow job for this annotation

GitHub Actions / Check spelling

EMAC ==> EMACS
* its descriptor base/buffer pointers with PHYSICAL addresses. The simplest
* coherent scheme on MIPS is to access all descriptor rings and DMA buffers
* through KSEG1 (uncached) virtual aliases and hand the EMAC the physical

Check failure on line 31 in src/port/pic32mz/cache.h

View workflow job for this annotation

GitHub Actions / Check spelling

EMAC ==> EMACS
* address. This avoids per-operation cache clean/invalidate entirely.
*
* Equivalent to XC32 <sys/kmem.h> KVA0_TO_KVA1 / KVA_TO_PA / PA_TO_KVA1, but
* kept self-contained so the early bare-metal layer can be lifted into
* wolfBoot without pulling in the XC32 system headers.
*/

/* Cached KSEG0 virtual address -> uncached KSEG1 virtual address */
#define PIC32_KVA0_TO_KVA1(v) (((uint32_t)(v)) | 0x20000000u)

/* Any KSEG0/KSEG1 virtual address -> physical address (for the EMAC) */

Check failure on line 42 in src/port/pic32mz/cache.h

View workflow job for this annotation

GitHub Actions / Check spelling

EMAC ==> EMACS
#define PIC32_KVA_TO_PA(v) (((uint32_t)(v)) & 0x1FFFFFFFu)

/* Physical address -> uncached KSEG1 virtual address */
#define PIC32_PA_TO_KVA1(pa) (((uint32_t)(pa)) | 0xA0000000u)

/* Pointer helper: uncached view of a normally-allocated object */
#define PIC32_UNCACHED(p) ((void *)PIC32_KVA0_TO_KVA1(p))

#endif /* PIC32MZ_CACHE_H */
37 changes: 37 additions & 0 deletions src/port/pic32mz/clock_init.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* clock_init.c
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfIP TCP/IP stack.
*
* wolfIP is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfIP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <xc.h>
#include "clock_init.h"

void clock_init(void)
{
/* Flash wait-states + prefetch for 200 MHz SYSCLK.
* PFMWS = 2 wait-states is required above ~134 MHz on PIC32MZ EF.
* PREFEN = 3 enables predictive prefetch for cacheable and
* non-cacheable regions. PRECON is not lock-protected. */
PRECONbits.PFMWS = 2;
PRECONbits.PREFEN = 3;

/* Peripheral buses PBCLK2 (UART) and PBCLK5 (EMAC) remain at their

Check failure on line 33 in src/port/pic32mz/clock_init.c

View workflow job for this annotation

GitHub Actions / Check spelling

EMAC ==> EMACS
* reset default of SYSCLK/2 = 100 MHz, which is what this port targets.
* The L1 cache and KSEG0 coherency are enabled by the XC32 reset
* startup code, so nothing is done here for v1. */
}
30 changes: 30 additions & 0 deletions src/port/pic32mz/clock_init.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* clock_init.h
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfIP TCP/IP stack.
*
* wolfIP is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfIP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef PIC32MZ_CLOCK_INIT_H
#define PIC32MZ_CLOCK_INIT_H

/* Configure flash wait-states / prefetch for 200 MHz operation.
* The PLL itself is brought up at reset from the DEVCFG config words
* (FNOSC=SPLL), so by the time main() runs SYSCLK is already 200 MHz.
* Bare-metal reusable (intended to be lifted into a future wolfBoot port). */
void clock_init(void);

#endif /* PIC32MZ_CLOCK_INIT_H */
89 changes: 89 additions & 0 deletions src/port/pic32mz/device_config.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* device_config.c
*
* PIC32MZ2048EFM144 device configuration words (DEVCFG0-3).
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfIP TCP/IP stack.
*
* wolfIP is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfIP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

/* Config-word settings for the PIC32MZ EF Starter Kit (DM320007).
*
* Clock: POSC = 24 MHz external clock (EC). SPLL multiplies to 200 MHz SYSCLK:
* 24 MHz / FPLLIDIV(3) = 8 MHz -> FPLLMULT(50) = 400 MHz -> FPLLODIV(2) = 200 MHz.
* Peripheral buses default to SYSCLK/2 = 100 MHz (PBCLK2 UART, PBCLK5 EMAC).

Check failure on line 28 in src/port/pic32mz/device_config.c

View workflow job for this annotation

GitHub Actions / Check spelling

EMAC ==> EMACS
*
* Values mirror the known-good Harmony-derived settings in
* wolfssl/mplabx/PIC32MZ-serial.h, EXCEPT FMIIEN is OFF here: this port drives
* the LAN8740 PHY daughter board over RMII, not MII.
*/

/*** DEVCFG0 ***/
#pragma config DEBUG = OFF
#pragma config JTAGEN = OFF
#pragma config ICESEL = ICS_PGx2
#pragma config TRCEN = OFF
#pragma config BOOTISA = MIPS32
#pragma config FECCCON = OFF_UNLOCKED
#pragma config FSLEEP = OFF
#pragma config DBGPER = PG_ALL
#pragma config SMCLR = MCLR_NORM
#pragma config SOSCGAIN = GAIN_2X
#pragma config SOSCBOOST = ON
#pragma config POSCGAIN = GAIN_2X
#pragma config POSCBOOST = ON
#pragma config EJTAGBEN = NORMAL
#pragma config CP = OFF

/*** DEVCFG1 ***/
#pragma config FNOSC = SPLL
#pragma config DMTINTV = WIN_127_128
#pragma config FSOSCEN = OFF
#pragma config IESO = OFF
#pragma config POSCMOD = EC
#pragma config OSCIOFNC = OFF
#pragma config FCKSM = CSECME
#pragma config WDTPS = PS1048576
#pragma config WDTSPGM = STOP
#pragma config FWDTEN = OFF
#pragma config WINDIS = NORMAL
#pragma config FWDTWINSZ = WINSZ_25
#pragma config DMTCNT = DMT31
#pragma config FDMTEN = OFF

/*** DEVCFG2 ***/
#pragma config FPLLIDIV = DIV_3
#pragma config FPLLRNG = RANGE_5_10_MHZ
#pragma config FPLLICLK = PLL_POSC
#pragma config FPLLMULT = MUL_50
#pragma config FPLLODIV = DIV_2
#pragma config UPLLFSEL = FREQ_24MHZ

/*** DEVCFG3 ***/
#pragma config USERID = 0xffff
#pragma config FMIIEN = OFF /* RMII (LAN8740 PHY daughter board) */
#pragma config FETHIO = ON /* default Ethernet I/O pin set */
#pragma config PGL1WAY = ON
#pragma config PMDL1WAY = ON
#pragma config IOL1WAY = ON
#pragma config FUSBIDIO = ON

/*** BF1SEQ0 ***/
#pragma config TSEQ = 0x0000
#pragma config CSEQ = 0xffff

#include <xc.h>
Loading
Loading