|
| 1 | +# wolfIP LPC54S018M-EVK Port |
| 2 | + |
| 3 | +Bare-metal port of wolfIP for the NXP LPCXpresso54S018M development board, featuring an Ethernet driver and TCP/IP echo server example. |
| 4 | + |
| 5 | +## Quick Start |
| 6 | + |
| 7 | +1. **Install pyocd target pack** (one-time): |
| 8 | + ```bash |
| 9 | + pyocd pack install lpc54s018j4met180 |
| 10 | + ``` |
| 11 | + |
| 12 | +2. **Build for SPIFI flash boot:** |
| 13 | + ```bash |
| 14 | + cd src/port/lpc54s018 |
| 15 | + make |
| 16 | + ``` |
| 17 | + |
| 18 | +3. **Program SPIFI flash and reset:** |
| 19 | + ```bash |
| 20 | + bash flash.sh |
| 21 | + ``` |
| 22 | + |
| 23 | +4. **Monitor UART output** (115200 baud on /dev/ttyACM0): |
| 24 | + ```bash |
| 25 | + screen /dev/ttyACM0 115200 |
| 26 | + ``` |
| 27 | + Get the device IP address from the DHCP output. |
| 28 | + |
| 29 | +5. **Test** (replace `<device-ip>` with IP from step 4): |
| 30 | + ```bash |
| 31 | + # TCP Echo |
| 32 | + echo "Hello" | nc <device-ip> 7 |
| 33 | + |
| 34 | + # Ping |
| 35 | + ping <device-ip> |
| 36 | + ``` |
| 37 | + |
| 38 | +## Hardware Requirements |
| 39 | + |
| 40 | +- LPCXpresso54S018M development board (NXP OM40003) |
| 41 | +- Ethernet connection (RMII, RJ45 at J4) |
| 42 | +- USB cable for debug (J8, on-board Link2 CMSIS-DAP) |
| 43 | + |
| 44 | +## Software Requirements |
| 45 | + |
| 46 | +- ARM GCC toolchain (`arm-none-eabi-gcc`) |
| 47 | +- pyocd (`pip install pyocd`) |
| 48 | +- Serial terminal (screen, minicom, picocom) |
| 49 | + |
| 50 | +### Installing Dependencies (Ubuntu/Debian) |
| 51 | + |
| 52 | +```bash |
| 53 | +sudo apt install gcc-arm-none-eabi |
| 54 | +pip install pyocd |
| 55 | +``` |
| 56 | + |
| 57 | +## Building |
| 58 | + |
| 59 | +```bash |
| 60 | +cd src/port/lpc54s018 |
| 61 | +make |
| 62 | +``` |
| 63 | + |
| 64 | +This produces `app.elf` and `app.bin`. |
| 65 | + |
| 66 | +### Checking Memory Usage |
| 67 | + |
| 68 | +```bash |
| 69 | +make size |
| 70 | +``` |
| 71 | + |
| 72 | +``` |
| 73 | + text data bss dec hex filename |
| 74 | + 52000 1732 53076 106808 1a138 app.elf |
| 75 | +``` |
| 76 | + |
| 77 | +## Flashing |
| 78 | + |
| 79 | +### SPIFI Flash Boot (Recommended) |
| 80 | + |
| 81 | +```bash |
| 82 | +bash flash.sh |
| 83 | +``` |
| 84 | + |
| 85 | +The flash script programs `app.bin` to SPIFI flash at `0x10000000` via pyocd |
| 86 | +using the `lpc54s018j4met180` target pack, then resets the board so the |
| 87 | +boot ROM runs and jumps into our firmware. The boot ROM validates the |
| 88 | +enhanced boot header at offset `0x160` and the vector checksum at `0x1C` |
| 89 | +(both written by `fix_checksum.py`). |
| 90 | + |
| 91 | +### SRAM-Loaded Build (Development) |
| 92 | + |
| 93 | +For fast iteration without re-programming SPIFI flash: |
| 94 | + |
| 95 | +```bash |
| 96 | +make ram # Build with target_ram.ld |
| 97 | +bash flash_ram.sh |
| 98 | +``` |
| 99 | + |
| 100 | +This loads the firmware into SRAM via pyocd and starts execution from |
| 101 | +`0x20000181`. UART may be unreliable in this mode because the boot ROM |
| 102 | +clock setup is bypassed; use SPIFI flash boot for verified UART operation. |
| 103 | + |
| 104 | +## Notes |
| 105 | + |
| 106 | +### LPC54S018 PRESETCTRL register polarity |
| 107 | + |
| 108 | +The LPC54018/LPC54S018 PRESETCTRL registers use this convention (matches |
| 109 | +the NXP MCUXpresso SDK `fsl_reset.c`): |
| 110 | + |
| 111 | +- Bit = **1** means peripheral is **in reset** (asserted) |
| 112 | +- Bit = **0** means peripheral is **out of reset** (released) |
| 113 | + |
| 114 | +Therefore: `PRESETCTRLSET` (bit -> 1) **asserts** reset, and |
| 115 | +`PRESETCTRLCLR` (bit -> 0) **deasserts** reset. |
| 116 | + |
| 117 | +### DHCP / Link Behavior |
| 118 | + |
| 119 | +The PHY (LAN8742A on the LPCXpresso54S018M-EVK) is held in reset via GPIO |
| 120 | +P2.26 and needs ~167ms after release before its REF_CLK stabilizes and MDIO |
| 121 | +is reliable. The port waits 200ms then runs PHY auto-negotiation. |
| 122 | + |
| 123 | +After ETH init the firmware prints PHY diagnostics: |
| 124 | +``` |
| 125 | +PHY: addr=0 ID=0007:c130 BSR=786d autoneg=OK link=UP |
| 126 | +``` |
| 127 | +- `ID` = `PHY_ID1:PHY_ID2`. LAN8742A reports `0007:c130`. |
| 128 | +- `BSR` = full Basic Status Register value (raw). |
| 129 | +- `autoneg`/`link` are decoded from BSR bit 5 / bit 2. |
| 130 | + |
| 131 | +Before starting DHCP the firmware waits up to 5s for link UP. If the cable |
| 132 | +is plugged in later, DHCP DISCOVER is re-issued every 10s only when the PHY |
| 133 | +reports link UP — this avoids flooding the network with discovers when the |
| 134 | +cable is unplugged. After 30s total, it falls back to the static IP defined |
| 135 | +in `config.h`. |
| 136 | + |
| 137 | +## Serial Console |
| 138 | + |
| 139 | +Connect to the USB serial port at 115200 baud: |
| 140 | + |
| 141 | +```bash |
| 142 | +screen /dev/ttyACM0 115200 |
| 143 | +``` |
| 144 | + |
| 145 | +## Example Output |
| 146 | + |
| 147 | +``` |
| 148 | +=== wolfIP LPC54S018M-EVK === |
| 149 | +PHY addr=0 link=UP |
| 150 | +Starting DHCP... |
| 151 | +Ready! ping <ip> / echo test | nc <ip> 7 |
| 152 | +DHCP bound: 192.168.0.138 |
| 153 | +``` |
| 154 | + |
| 155 | +## Network Configuration |
| 156 | + |
| 157 | +### DHCP (Default) |
| 158 | + |
| 159 | +DHCP is enabled by default. The board obtains its IP automatically and prints it to UART. Falls back to static IP after 30 seconds if no DHCP server responds. |
| 160 | + |
| 161 | +### Static IP |
| 162 | + |
| 163 | +Set `WOLFIP_ENABLE_DHCP` to `0` in `config.h`: |
| 164 | + |
| 165 | +```c |
| 166 | +#define WOLFIP_ENABLE_DHCP 0 |
| 167 | +#define WOLFIP_IP "192.168.1.10" |
| 168 | +#define WOLFIP_NETMASK "255.255.255.0" |
| 169 | +#define WOLFIP_GW "192.168.1.1" |
| 170 | +``` |
| 171 | + |
| 172 | +## Testing TCP Echo Server |
| 173 | + |
| 174 | +```bash |
| 175 | +# Test ICMP |
| 176 | +ping <device-ip> |
| 177 | + |
| 178 | +# Test TCP echo (port 7) |
| 179 | +echo "Hello wolfIP!" | nc <device-ip> 7 |
| 180 | + |
| 181 | +# Interactive |
| 182 | +nc <device-ip> 7 |
| 183 | +``` |
| 184 | + |
| 185 | +## Jumper Settings |
| 186 | + |
| 187 | +| Jumper | Position | Function | |
| 188 | +|--------|----------|----------| |
| 189 | +| JP11 | 1-2 (default) | Ethernet TXD/RXD | |
| 190 | +| JP12 | 1-2 (default) | Ethernet TXD/RXD | |
| 191 | +| JP14 | 1-2 (EN) | ENET MDC | |
| 192 | +| JP15 | 1-2 (EN) | ENET MDIO | |
| 193 | +| JP5 | Open (default) | Link2 normal boot | |
| 194 | + |
| 195 | +## Files |
| 196 | + |
| 197 | +| File | Description | |
| 198 | +|------|-------------| |
| 199 | +| `main.c` | Application entry, wolfIP init, echo server | |
| 200 | +| `../lpc_enet/lpc_enet.c` | Ethernet MAC/DMA driver (shared) | |
| 201 | +| `../lpc_enet/lpc_enet.h` | Ethernet driver header (shared) | |
| 202 | +| `lpc54s018_eth.h` | Board-specific ENET parameters | |
| 203 | +| `startup.c` | Startup code and data initialization | |
| 204 | +| `ivt.c` | Interrupt vector table + SPIFI config | |
| 205 | +| `syscalls.c` | Newlib syscall stubs | |
| 206 | +| `target.ld` | Linker script (SPIFI flash boot - default) | |
| 207 | +| `target_ram.ld` | Linker script (RAM execution - dev only) | |
| 208 | +| `flash.sh` | Program SPIFI flash and reset (recommended) | |
| 209 | +| `flash_ram.sh` | Load firmware to SRAM and run (dev only, no UART) | |
| 210 | +| `config.h` | wolfIP stack configuration | |
| 211 | +| `fix_checksum.py` | LPC boot ROM vector checksum tool | |
| 212 | +| `Makefile` | Build system | |
| 213 | + |
| 214 | +## Troubleshooting |
| 215 | + |
| 216 | +### No Serial Output |
| 217 | +- Check J8 (USB Debug-Link) is connected, not J1 |
| 218 | +- Check JP5 is open (not shunted) |
| 219 | +- Verify baud rate is 115200 |
| 220 | + |
| 221 | +### Ethernet Not Responding |
| 222 | +- Verify cable is in J4, check RJ45 link LEDs are lit |
| 223 | +- Check JP14 and JP15 are both in EN position |
| 224 | +- If using static IP, ensure host is on the same subnet |
| 225 | + |
| 226 | +### pyocd Cannot Find Target |
| 227 | +- Use `-t lpc54608` as target type |
| 228 | +- Add udev rule: `SUBSYSTEM=="usb", ATTR{idVendor}=="1fc9", MODE="0666"` |
| 229 | + |
| 230 | +## License |
| 231 | + |
| 232 | +This code is part of wolfIP and is licensed under GPLv3. See the LICENSE file in the repository root for details. |
| 233 | + |
| 234 | +Copyright (C) 2026 wolfSSL Inc. |
0 commit comments