From 1969a453747b838fa36896a664fb946b3c7ae5ab Mon Sep 17 00:00:00 2001 From: Mason Date: Thu, 17 Oct 2024 14:06:40 +0900 Subject: [PATCH 1/6] Add WIZnet W55RP20-EVB-Pico board --- boards.txt | 229 +++++ libraries/lwIP_Ethernet/src/EthernetCompat.h | 1 + .../WiFiClient-W55RP20/WiFiClient-W55RP20.ino | 89 ++ libraries/lwIP_w550rp20/keywords.txt | 18 + libraries/lwIP_w550rp20/library.properties | 10 + libraries/lwIP_w550rp20/src/W55RP20lwIP.h | 8 + .../lwIP_w550rp20/src/utility/w55rp20.cpp | 393 +++++++++ libraries/lwIP_w550rp20/src/utility/w55rp20.h | 787 ++++++++++++++++++ libraries/lwIP_w550rp20/src/wiznet_pio_spi.c | 376 +++++++++ libraries/lwIP_w550rp20/src/wiznet_pio_spi.h | 52 ++ .../lwIP_w550rp20/src/wiznet_pio_spi.pio | 25 + .../lwIP_w550rp20/src/wiznet_pio_spi.pio.h | 50 ++ tools/json/wiznet_55rp20_evb_pico.json | 55 ++ tools/makeboards.py | 1 + .../wiznet_55rp20_evb_pico/pins_arduino.h | 1 + 15 files changed, 2095 insertions(+) create mode 100644 libraries/lwIP_w550rp20/examples/WiFiClient-W55RP20/WiFiClient-W55RP20.ino create mode 100644 libraries/lwIP_w550rp20/keywords.txt create mode 100644 libraries/lwIP_w550rp20/library.properties create mode 100644 libraries/lwIP_w550rp20/src/W55RP20lwIP.h create mode 100644 libraries/lwIP_w550rp20/src/utility/w55rp20.cpp create mode 100644 libraries/lwIP_w550rp20/src/utility/w55rp20.h create mode 100644 libraries/lwIP_w550rp20/src/wiznet_pio_spi.c create mode 100644 libraries/lwIP_w550rp20/src/wiznet_pio_spi.h create mode 100644 libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio create mode 100644 libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio.h create mode 100644 tools/json/wiznet_55rp20_evb_pico.json create mode 100644 variants/wiznet_55rp20_evb_pico/pins_arduino.h diff --git a/boards.txt b/boards.txt index 4fcb74f2f..f625b5e00 100644 --- a/boards.txt +++ b/boards.txt @@ -29240,6 +29240,235 @@ wiznet_5500_evb_pico.menu.uploadmethod.picoprobe_cmsis_dap.upload.maximum_data_s wiznet_5500_evb_pico.menu.uploadmethod.picoprobe_cmsis_dap.upload.tool=picoprobe_cmsis_dap wiznet_5500_evb_pico.menu.uploadmethod.picoprobe_cmsis_dap.upload.tool.default=picoprobe_cmsis_dap +# ----------------------------------- +# WIZnet W55RP20-EVB-Pico +# ----------------------------------- +wiznet_55rp20_evb_pico.name=WIZnet W55RP20-EVB-Pico +wiznet_55rp20_evb_pico.vid.0=0x2e8a +wiznet_55rp20_evb_pico.pid.0=0x1029 +wiznet_55rp20_evb_pico.vid.1=0x2e8a +wiznet_55rp20_evb_pico.pid.1=0x1129 +wiznet_55rp20_evb_pico.vid.2=0x2e8a +wiznet_55rp20_evb_pico.pid.2=0x5029 +wiznet_55rp20_evb_pico.vid.3=0x2e8a +wiznet_55rp20_evb_pico.pid.3=0x5129 +wiznet_55rp20_evb_pico.vid.4=0x2e8a +wiznet_55rp20_evb_pico.pid.4=0x9029 +wiznet_55rp20_evb_pico.vid.5=0x2e8a +wiznet_55rp20_evb_pico.pid.5=0x9129 +wiznet_55rp20_evb_pico.vid.6=0x2e8a +wiznet_55rp20_evb_pico.pid.6=0xd029 +wiznet_55rp20_evb_pico.vid.7=0x2e8a +wiznet_55rp20_evb_pico.pid.7=0xd129 +wiznet_55rp20_evb_pico.upload_port.0.vid=0x2e8a +wiznet_55rp20_evb_pico.upload_port.0.pid=0x1029 +wiznet_55rp20_evb_pico.upload_port.1.vid=0x2e8a +wiznet_55rp20_evb_pico.upload_port.1.pid=0x1129 +wiznet_55rp20_evb_pico.upload_port.2.vid=0x2e8a +wiznet_55rp20_evb_pico.upload_port.2.pid=0x5029 +wiznet_55rp20_evb_pico.upload_port.3.vid=0x2e8a +wiznet_55rp20_evb_pico.upload_port.3.pid=0x5129 +wiznet_55rp20_evb_pico.upload_port.4.vid=0x2e8a +wiznet_55rp20_evb_pico.upload_port.4.pid=0x9029 +wiznet_55rp20_evb_pico.upload_port.5.vid=0x2e8a +wiznet_55rp20_evb_pico.upload_port.5.pid=0x9129 +wiznet_55rp20_evb_pico.upload_port.6.vid=0x2e8a +wiznet_55rp20_evb_pico.upload_port.6.pid=0xd029 +wiznet_55rp20_evb_pico.upload_port.7.vid=0x2e8a +wiznet_55rp20_evb_pico.upload_port.7.pid=0xd129 +wiznet_55rp20_evb_pico.build.usbvid=-DUSBD_VID=0x2e8a +wiznet_55rp20_evb_pico.build.usbpid=-DUSBD_PID=0x1029 +wiznet_55rp20_evb_pico.build.usbpwr=-DUSBD_MAX_POWER_MA=250 +wiznet_55rp20_evb_pico.build.board=WIZNET_55RP20_EVB_PICO +wiznet_55rp20_evb_pico.build.chip=rp2040 +wiznet_55rp20_evb_pico.build.toolchain=arm-none-eabi +wiznet_55rp20_evb_pico.build.toolchainpkg=pqt-gcc +wiznet_55rp20_evb_pico.build.toolchainopts=-march=armv6-m -mcpu=cortex-m0plus -mthumb +wiznet_55rp20_evb_pico.build.uf2family=--family rp2040 +wiznet_55rp20_evb_pico.build.variant=wiznet_55rp20_evb_pico +wiznet_55rp20_evb_pico.upload.maximum_size=2097152 +wiznet_55rp20_evb_pico.upload.wait_for_upload_port=true +wiznet_55rp20_evb_pico.upload.erase_cmd= +wiznet_55rp20_evb_pico.serial.disableDTR=false +wiznet_55rp20_evb_pico.serial.disableRTS=false +wiznet_55rp20_evb_pico.build.f_cpu=125000000 +wiznet_55rp20_evb_pico.build.led= +wiznet_55rp20_evb_pico.build.core=rp2040 +wiznet_55rp20_evb_pico.build.ldscript=memmap_default.ld +wiznet_55rp20_evb_pico.build.boot2=boot2_w25q080_2_padded_checksum +wiznet_55rp20_evb_pico.build.usb_manufacturer="WIZnet" +wiznet_55rp20_evb_pico.build.usb_product="W55RP20-EVB-Pico" +wiznet_55rp20_evb_pico.menu.flash.2097152_0=2MB (no FS) +wiznet_55rp20_evb_pico.menu.flash.2097152_0.upload.maximum_size=2093056 +wiznet_55rp20_evb_pico.menu.flash.2097152_0.build.flash_total=2097152 +wiznet_55rp20_evb_pico.menu.flash.2097152_0.build.flash_length=2093056 +wiznet_55rp20_evb_pico.menu.flash.2097152_0.build.eeprom_start=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_0.build.fs_start=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_0.build.fs_end=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_65536=2MB (Sketch: 1984KB, FS: 64KB) +wiznet_55rp20_evb_pico.menu.flash.2097152_65536.upload.maximum_size=2027520 +wiznet_55rp20_evb_pico.menu.flash.2097152_65536.build.flash_total=2097152 +wiznet_55rp20_evb_pico.menu.flash.2097152_65536.build.flash_length=2027520 +wiznet_55rp20_evb_pico.menu.flash.2097152_65536.build.eeprom_start=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_65536.build.fs_start=270462976 +wiznet_55rp20_evb_pico.menu.flash.2097152_65536.build.fs_end=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_131072=2MB (Sketch: 1920KB, FS: 128KB) +wiznet_55rp20_evb_pico.menu.flash.2097152_131072.upload.maximum_size=1961984 +wiznet_55rp20_evb_pico.menu.flash.2097152_131072.build.flash_total=2097152 +wiznet_55rp20_evb_pico.menu.flash.2097152_131072.build.flash_length=1961984 +wiznet_55rp20_evb_pico.menu.flash.2097152_131072.build.eeprom_start=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_131072.build.fs_start=270397440 +wiznet_55rp20_evb_pico.menu.flash.2097152_131072.build.fs_end=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_262144=2MB (Sketch: 1792KB, FS: 256KB) +wiznet_55rp20_evb_pico.menu.flash.2097152_262144.upload.maximum_size=1830912 +wiznet_55rp20_evb_pico.menu.flash.2097152_262144.build.flash_total=2097152 +wiznet_55rp20_evb_pico.menu.flash.2097152_262144.build.flash_length=1830912 +wiznet_55rp20_evb_pico.menu.flash.2097152_262144.build.eeprom_start=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_262144.build.fs_start=270266368 +wiznet_55rp20_evb_pico.menu.flash.2097152_262144.build.fs_end=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_524288=2MB (Sketch: 1536KB, FS: 512KB) +wiznet_55rp20_evb_pico.menu.flash.2097152_524288.upload.maximum_size=1568768 +wiznet_55rp20_evb_pico.menu.flash.2097152_524288.build.flash_total=2097152 +wiznet_55rp20_evb_pico.menu.flash.2097152_524288.build.flash_length=1568768 +wiznet_55rp20_evb_pico.menu.flash.2097152_524288.build.eeprom_start=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_524288.build.fs_start=270004224 +wiznet_55rp20_evb_pico.menu.flash.2097152_524288.build.fs_end=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_1048576=2MB (Sketch: 1MB, FS: 1MB) +wiznet_55rp20_evb_pico.menu.flash.2097152_1048576.upload.maximum_size=1044480 +wiznet_55rp20_evb_pico.menu.flash.2097152_1048576.build.flash_total=2097152 +wiznet_55rp20_evb_pico.menu.flash.2097152_1048576.build.flash_length=1044480 +wiznet_55rp20_evb_pico.menu.flash.2097152_1048576.build.eeprom_start=270528512 +wiznet_55rp20_evb_pico.menu.flash.2097152_1048576.build.fs_start=269479936 +wiznet_55rp20_evb_pico.menu.flash.2097152_1048576.build.fs_end=270528512 +wiznet_55rp20_evb_pico.menu.freq.133=133 MHz +wiznet_55rp20_evb_pico.menu.freq.133.build.f_cpu=133000000L +wiznet_55rp20_evb_pico.menu.freq.50=50 MHz +wiznet_55rp20_evb_pico.menu.freq.50.build.f_cpu=50000000L +wiznet_55rp20_evb_pico.menu.freq.100=100 MHz +wiznet_55rp20_evb_pico.menu.freq.100.build.f_cpu=100000000L +wiznet_55rp20_evb_pico.menu.freq.120=120 MHz +wiznet_55rp20_evb_pico.menu.freq.120.build.f_cpu=120000000L +wiznet_55rp20_evb_pico.menu.freq.125=125 MHz +wiznet_55rp20_evb_pico.menu.freq.125.build.f_cpu=125000000L +wiznet_55rp20_evb_pico.menu.freq.128=128 MHz +wiznet_55rp20_evb_pico.menu.freq.128.build.f_cpu=128000000L +wiznet_55rp20_evb_pico.menu.freq.150=150 MHz (Overclock) +wiznet_55rp20_evb_pico.menu.freq.150.build.f_cpu=150000000L +wiznet_55rp20_evb_pico.menu.freq.175=175 MHz (Overclock) +wiznet_55rp20_evb_pico.menu.freq.175.build.f_cpu=175000000L +wiznet_55rp20_evb_pico.menu.freq.200=200 MHz (Overclock) +wiznet_55rp20_evb_pico.menu.freq.200.build.f_cpu=200000000L +wiznet_55rp20_evb_pico.menu.freq.225=225 MHz (Overclock) +wiznet_55rp20_evb_pico.menu.freq.225.build.f_cpu=225000000L +wiznet_55rp20_evb_pico.menu.freq.240=240 MHz (Overclock) +wiznet_55rp20_evb_pico.menu.freq.240.build.f_cpu=240000000L +wiznet_55rp20_evb_pico.menu.freq.250=250 MHz (Overclock) +wiznet_55rp20_evb_pico.menu.freq.250.build.f_cpu=250000000L +wiznet_55rp20_evb_pico.menu.freq.275=275 MHz (Overclock) +wiznet_55rp20_evb_pico.menu.freq.275.build.f_cpu=275000000L +wiznet_55rp20_evb_pico.menu.freq.300=300 MHz (Overclock) +wiznet_55rp20_evb_pico.menu.freq.300.build.f_cpu=300000000L +wiznet_55rp20_evb_pico.menu.opt.Small=Small (-Os) (standard) +wiznet_55rp20_evb_pico.menu.opt.Small.build.flags.optimize=-Os +wiznet_55rp20_evb_pico.menu.opt.Optimize=Optimize (-O) +wiznet_55rp20_evb_pico.menu.opt.Optimize.build.flags.optimize=-O +wiznet_55rp20_evb_pico.menu.opt.Optimize2=Optimize More (-O2) +wiznet_55rp20_evb_pico.menu.opt.Optimize2.build.flags.optimize=-O2 +wiznet_55rp20_evb_pico.menu.opt.Optimize3=Optimize Even More (-O3) +wiznet_55rp20_evb_pico.menu.opt.Optimize3.build.flags.optimize=-O3 +wiznet_55rp20_evb_pico.menu.opt.Fast=Fast (-Ofast) (maybe slower) +wiznet_55rp20_evb_pico.menu.opt.Fast.build.flags.optimize=-Ofast +wiznet_55rp20_evb_pico.menu.opt.Debug=Debug (-Og) +wiznet_55rp20_evb_pico.menu.opt.Debug.build.flags.optimize=-Og +wiznet_55rp20_evb_pico.menu.rtti.Disabled=Disabled +wiznet_55rp20_evb_pico.menu.rtti.Disabled.build.flags.rtti=-fno-rtti +wiznet_55rp20_evb_pico.menu.rtti.Enabled=Enabled +wiznet_55rp20_evb_pico.menu.rtti.Enabled.build.flags.rtti= +wiznet_55rp20_evb_pico.menu.stackprotect.Disabled=Disabled +wiznet_55rp20_evb_pico.menu.stackprotect.Disabled.build.flags.stackprotect= +wiznet_55rp20_evb_pico.menu.stackprotect.Enabled=Enabled +wiznet_55rp20_evb_pico.menu.stackprotect.Enabled.build.flags.stackprotect=-fstack-protector +wiznet_55rp20_evb_pico.menu.exceptions.Disabled=Disabled +wiznet_55rp20_evb_pico.menu.exceptions.Disabled.build.flags.exceptions=-fno-exceptions +wiznet_55rp20_evb_pico.menu.exceptions.Disabled.build.flags.libstdcpp=-lstdc++ +wiznet_55rp20_evb_pico.menu.exceptions.Enabled=Enabled +wiznet_55rp20_evb_pico.menu.exceptions.Enabled.build.flags.exceptions=-fexceptions +wiznet_55rp20_evb_pico.menu.exceptions.Enabled.build.flags.libstdcpp=-lstdc++-exc +wiznet_55rp20_evb_pico.menu.dbgport.Disabled=Disabled +wiznet_55rp20_evb_pico.menu.dbgport.Disabled.build.debug_port= +wiznet_55rp20_evb_pico.menu.dbgport.Serial=Serial +wiznet_55rp20_evb_pico.menu.dbgport.Serial.build.debug_port=-DDEBUG_RP2040_PORT=Serial +wiznet_55rp20_evb_pico.menu.dbgport.Serial1=Serial1 +wiznet_55rp20_evb_pico.menu.dbgport.Serial1.build.debug_port=-DDEBUG_RP2040_PORT=Serial1 +wiznet_55rp20_evb_pico.menu.dbgport.Serial2=Serial2 +wiznet_55rp20_evb_pico.menu.dbgport.Serial2.build.debug_port=-DDEBUG_RP2040_PORT=Serial2 +wiznet_55rp20_evb_pico.menu.dbglvl.None=None +wiznet_55rp20_evb_pico.menu.dbglvl.None.build.debug_level= +wiznet_55rp20_evb_pico.menu.dbglvl.Core=Core +wiznet_55rp20_evb_pico.menu.dbglvl.Core.build.debug_level=-DDEBUG_RP2040_CORE +wiznet_55rp20_evb_pico.menu.dbglvl.SPI=SPI +wiznet_55rp20_evb_pico.menu.dbglvl.SPI.build.debug_level=-DDEBUG_RP2040_SPI +wiznet_55rp20_evb_pico.menu.dbglvl.Wire=Wire +wiznet_55rp20_evb_pico.menu.dbglvl.Wire.build.debug_level=-DDEBUG_RP2040_WIRE +wiznet_55rp20_evb_pico.menu.dbglvl.Bluetooth=Bluetooth +wiznet_55rp20_evb_pico.menu.dbglvl.Bluetooth.build.debug_level=-DDEBUG_RP2040_BLUETOOTH +wiznet_55rp20_evb_pico.menu.dbglvl.All=All +wiznet_55rp20_evb_pico.menu.dbglvl.All.build.debug_level=-DDEBUG_RP2040_WIRE -DDEBUG_RP2040_SPI -DDEBUG_RP2040_CORE -DDEBUG_RP2040_BLUETOOTH +wiznet_55rp20_evb_pico.menu.dbglvl.NDEBUG=NDEBUG +wiznet_55rp20_evb_pico.menu.dbglvl.NDEBUG.build.debug_level=-DNDEBUG +wiznet_55rp20_evb_pico.menu.usbstack.picosdk=Pico SDK +wiznet_55rp20_evb_pico.menu.usbstack.picosdk.build.usbstack_flags= +wiznet_55rp20_evb_pico.menu.usbstack.tinyusb=Adafruit TinyUSB +wiznet_55rp20_evb_pico.menu.usbstack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino" +wiznet_55rp20_evb_pico.menu.usbstack.tinyusb_host=Adafruit TinyUSB Host (native) +wiznet_55rp20_evb_pico.menu.usbstack.tinyusb_host.build.usbstack_flags=-DUSE_TINYUSB -DUSE_TINYUSB_HOST "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino" +wiznet_55rp20_evb_pico.menu.usbstack.nousb=No USB +wiznet_55rp20_evb_pico.menu.usbstack.nousb.build.usbstack_flags="-DNO_USB -DDISABLE_USB_SERIAL -I{runtime.platform.path}/tools/libpico" +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4only=IPv4 Only +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4only.build.libpicow=libipv4.a +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4only.build.libpicowdefs=-DLWIP_IPV6=0 -DLWIP_IPV4=1 +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6=IPv4 + IPv6 +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6.build.libpicow=libipv4-ipv6.a +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6.build.libpicowdefs=-DLWIP_IPV6=1 -DLWIP_IPV4=1 +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4btcble=IPv4 + Bluetooth +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4btcble.build.libpicow=libipv4-bt.a +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4btcble.build.libpicowdefs=-DLWIP_IPV6=0 -DLWIP_IPV4=1 -DENABLE_CLASSIC=1 -DENABLE_BLE=1 +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6btcble=IPv4 + IPv6 + Bluetooth +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6btcble.build.libpicow=libipv4-ipv6-bt.a +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6btcble.build.libpicowdefs=-DLWIP_IPV6=1 -DLWIP_IPV4=1 -DENABLE_CLASSIC=1 -DENABLE_BLE=1 +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4onlybig=IPv4 Only - 32K +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4onlybig.build.libpicow=libipv4-big.a +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4onlybig.build.libpicowdefs=-DLWIP_IPV6=0 -DLWIP_IPV4=1 -D__LWIP_MEMMULT=2 +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6big=IPv4 + IPv6 - 32K +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6big.build.libpicow=libipv4-ipv6-big.a +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6big.build.libpicowdefs=-DLWIP_IPV6=1 -DLWIP_IPV4=1 -D__LWIP_MEMMULT=2 +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4btcblebig=IPv4 + Bluetooth - 32K +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4btcblebig.build.libpicow=libipv4-bt-big.a +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4btcblebig.build.libpicowdefs=-DLWIP_IPV6=0 -DLWIP_IPV4=1 -DENABLE_CLASSIC=1 -DENABLE_BLE=1 -D__LWIP_MEMMULT=2 +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6btcblebig=IPv4 + IPv6 + Bluetooth - 32K +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6btcblebig.build.libpicow=libipv4-ipv6-bt-big.a +wiznet_55rp20_evb_pico.menu.ipbtstack.ipv4ipv6btcblebig.build.libpicowdefs=-DLWIP_IPV6=1 -DLWIP_IPV4=1 -DENABLE_CLASSIC=1 -DENABLE_BLE=1 -D__LWIP_MEMMULT=2 +wiznet_55rp20_evb_pico.menu.uploadmethod.default=Default (UF2) +wiznet_55rp20_evb_pico.menu.uploadmethod.default.build.ram_length=256k +wiznet_55rp20_evb_pico.menu.uploadmethod.default.build.debugscript=picoprobe_cmsis_dap.tcl +wiznet_55rp20_evb_pico.menu.uploadmethod.default.upload.maximum_data_size=262144 +wiznet_55rp20_evb_pico.menu.uploadmethod.default.upload.tool=uf2conv +wiznet_55rp20_evb_pico.menu.uploadmethod.default.upload.tool.default=uf2conv +wiznet_55rp20_evb_pico.menu.uploadmethod.default.upload.tool.network=uf2conv-network +wiznet_55rp20_evb_pico.menu.uploadmethod.picotool=Picotool +wiznet_55rp20_evb_pico.menu.uploadmethod.picotool.build.ram_length=256k +wiznet_55rp20_evb_pico.menu.uploadmethod.picotool.build.debugscript=picoprobe.tcl +wiznet_55rp20_evb_pico.menu.uploadmethod.picotool.build.picodebugflags=-DENABLE_PICOTOOL_USB +wiznet_55rp20_evb_pico.menu.uploadmethod.picotool.upload.maximum_data_size=262144 +wiznet_55rp20_evb_pico.menu.uploadmethod.picotool.upload.tool=picotool +wiznet_55rp20_evb_pico.menu.uploadmethod.picotool.upload.tool.default=picotool +wiznet_55rp20_evb_pico.menu.uploadmethod.picoprobe_cmsis_dap=Picoprobe/Debugprobe (CMSIS-DAP) +wiznet_55rp20_evb_pico.menu.uploadmethod.picoprobe_cmsis_dap.build.ram_length=256k +wiznet_55rp20_evb_pico.menu.uploadmethod.picoprobe_cmsis_dap.build.debugscript=picoprobe_cmsis_dap.tcl +wiznet_55rp20_evb_pico.menu.uploadmethod.picoprobe_cmsis_dap.upload.maximum_data_size=262144 +wiznet_55rp20_evb_pico.menu.uploadmethod.picoprobe_cmsis_dap.upload.tool=picoprobe_cmsis_dap +wiznet_55rp20_evb_pico.menu.uploadmethod.picoprobe_cmsis_dap.upload.tool.default=picoprobe_cmsis_dap + # ----------------------------------- # Generic RP2040 # ----------------------------------- diff --git a/libraries/lwIP_Ethernet/src/EthernetCompat.h b/libraries/lwIP_Ethernet/src/EthernetCompat.h index 4291ce293..2b3bf7142 100644 --- a/libraries/lwIP_Ethernet/src/EthernetCompat.h +++ b/libraries/lwIP_Ethernet/src/EthernetCompat.h @@ -97,4 +97,5 @@ class ArduinoEthernet : public LwipIntfDev { using ArduinoWiznet5500lwIP = ArduinoEthernet; using ArduinoWiznet5100lwIP = ArduinoEthernet; +using ArduinoWiznet55rp20lwIP = ArduinoEthernet; using ArduinoENC28J60lwIP = ArduinoEthernet; diff --git a/libraries/lwIP_w550rp20/examples/WiFiClient-W55RP20/WiFiClient-W55RP20.ino b/libraries/lwIP_w550rp20/examples/WiFiClient-W55RP20/WiFiClient-W55RP20.ino new file mode 100644 index 000000000..61c7c8c29 --- /dev/null +++ b/libraries/lwIP_w550rp20/examples/WiFiClient-W55RP20/WiFiClient-W55RP20.ino @@ -0,0 +1,89 @@ +/* + This sketch establishes a TCP connection to a "quote of the day" service. + It sends a "hello" message, and then prints received data. +*/ + +#include + +const char* host = "djxmmx.net"; +const uint16_t port = 17; + +Wiznet55rp20lwIP eth(1 /* chip select */); + +void setup() { + Serial.begin(115200); + delay(5000); + Serial.println(); + Serial.println(); + Serial.println("Starting Ethernet port"); + + // Start the Ethernet port + if (!eth.begin()) { + Serial.println("No wired Ethernet hardware detected. Check pinouts, wiring."); + while (1) { + delay(1000); + } + } + + while (!eth.connected()) { + Serial.print("."); + delay(500); + } + + Serial.println(""); + Serial.println("Ethernet connected"); + Serial.println("IP address: "); + Serial.println(eth.localIP()); +} + +void loop() { + static bool wait = false; + + Serial.print("connecting to "); + Serial.print(host); + Serial.print(':'); + Serial.println(port); + + // Use WiFiClient class to create TCP connections + WiFiClient client; + if (!client.connect(host, port)) { + Serial.println("connection failed"); + delay(5000); + return; + } + + // This will send a string to the server + Serial.println("sending data to server"); + if (client.connected()) { + client.println("hello from RP2040"); + } + + // wait for data to be available + unsigned long timeout = millis(); + while (client.available() == 0) { + if (millis() - timeout > 5000) { + Serial.println(">>> Client Timeout !"); + client.stop(); + delay(60000); + return; + } + } + + // Read all the lines of the reply from server and print them to Serial + Serial.println("receiving from remote server"); + // not testing 'client.connected()' since we do not need to send data here + while (client.available()) { + char ch = static_cast(client.read()); + Serial.print(ch); + } + + // Close the connection + Serial.println(); + Serial.println("closing connection"); + client.stop(); + + if (wait) { + delay(300000); // execute once every 5 minutes, don't flood remote service + } + wait = true; +} diff --git a/libraries/lwIP_w550rp20/keywords.txt b/libraries/lwIP_w550rp20/keywords.txt new file mode 100644 index 000000000..b777489b7 --- /dev/null +++ b/libraries/lwIP_w550rp20/keywords.txt @@ -0,0 +1,18 @@ +####################################### +# Syntax Coloring Map +####################################### + +####################################### +# Library (KEYWORD1) +####################################### + +W55RP20lwIP KEYWORD1 +Wiznet55rp20lwIP KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/lwIP_w550rp20/library.properties b/libraries/lwIP_w550rp20/library.properties new file mode 100644 index 000000000..3f0bb38b6 --- /dev/null +++ b/libraries/lwIP_w550rp20/library.properties @@ -0,0 +1,10 @@ +name=lwIP_w55rp20 +version=1 +author=Nicholas Humfrey +maintainer=esp8266/Arduino +sentence=Ethernet driver +paragraph=Wiznet55rp20 ethernet drivers for lwIP and esp8266 Arduino from https://github.com/njh/W5500MacRaw +category=Communication +url=https://github.com/esp8266/Arduino +architectures=rp2040 +dot_a_linkage=true diff --git a/libraries/lwIP_w550rp20/src/W55RP20lwIP.h b/libraries/lwIP_w550rp20/src/W55RP20lwIP.h new file mode 100644 index 000000000..72de7a94a --- /dev/null +++ b/libraries/lwIP_w550rp20/src/W55RP20lwIP.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include +#include +#include + +using Wiznet55rp20lwIP = LwipIntfDev; diff --git a/libraries/lwIP_w550rp20/src/utility/w55rp20.cpp b/libraries/lwIP_w550rp20/src/utility/w55rp20.cpp new file mode 100644 index 000000000..c116d81cc --- /dev/null +++ b/libraries/lwIP_w550rp20/src/utility/w55rp20.cpp @@ -0,0 +1,393 @@ +/* + Copyright (c) 2024, WIZnet Co., Ltd. + Copyright (c) 2016, Nicholas Humfrey + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +// original sources: https://github.com/njh/W5500MacRaw + +#include +#include "wiznet_pio_spi.h" +#include "w55rp20.h" +#include + +wiznet_pio_spi_config_t wiznet_pio_spi_config; +wiznet_pio_spi_handle_t wiznet_pio_spi_handle = NULL; + +uint8_t Wiznet55rp20::wizchip_read(uint8_t block, uint16_t address) { + uint8_t ret; + uint8_t spi_data[3]; + + wizchip_cs_select(); + + block |= AccessModeRead; + + spi_data[0] = (address & 0x00FF00) >> 8; + spi_data[1] = (address & 0x0000FF) >> 0; + spi_data[2] = block; + (*wiznet_pio_spi_handle)->write_buffer(spi_data, 3); + ret = (*wiznet_pio_spi_handle)->read_byte(); + + wizchip_cs_deselect(); + return ret; +} + +uint16_t Wiznet55rp20::wizchip_read_word(uint8_t block, uint16_t address) { + return ((uint16_t)wizchip_read(block, address) << 8) + wizchip_read(block, address + 1); +} + +void Wiznet55rp20::wizchip_read_buf(uint8_t block, uint16_t address, uint8_t* pBuf, uint16_t len) { + uint16_t i; + uint8_t spi_data[3]; + + wizchip_cs_select(); + + block |= AccessModeRead; + + spi_data[0] = (address & 0x00FF00) >> 8; + spi_data[1] = (address & 0x0000FF) >> 0; + spi_data[2] = block; + (*wiznet_pio_spi_handle)->write_buffer(spi_data, 3); + (*wiznet_pio_spi_handle)->read_buffer(pBuf, len); + + wizchip_cs_deselect(); +} + +void Wiznet55rp20::wizchip_write(uint8_t block, uint16_t address, uint8_t wb) { + uint8_t spi_data[4]; + + wizchip_cs_select(); + + block |= AccessModeWrite; + + spi_data[0] = (address & 0x00FF00) >> 8; + spi_data[1] = (address & 0x0000FF) >> 0; + spi_data[2] = block; + spi_data[3] = wb; + (*wiznet_pio_spi_handle)->write_buffer(spi_data, 4); + + wizchip_cs_deselect(); +} + +void Wiznet55rp20::wizchip_write_word(uint8_t block, uint16_t address, uint16_t word) { + wizchip_write(block, address, (uint8_t)(word >> 8)); + wizchip_write(block, address + 1, (uint8_t)word); +} + +void Wiznet55rp20::wizchip_write_buf(uint8_t block, uint16_t address, const uint8_t* pBuf, + uint16_t len) { + uint16_t i; + uint8_t spi_data[3]; + + wizchip_cs_select(); + + block |= AccessModeWrite; + + spi_data[0] = (address & 0x00FF00) >> 8; + spi_data[1] = (address & 0x0000FF); + spi_data[2] = block; + (*wiznet_pio_spi_handle)->write_buffer(spi_data, 3); + (*wiznet_pio_spi_handle)->write_buffer(pBuf, len); + + wizchip_cs_deselect(); +} + +void Wiznet55rp20::setSn_CR(uint8_t cr) { + // Write the command to the Command Register + wizchip_write(BlockSelectSReg, Sn_CR, cr); + + // Now wait for the command to complete + while (wizchip_read(BlockSelectSReg, Sn_CR)) + ; +} + +uint16_t Wiznet55rp20::getSn_TX_FSR() { + uint16_t val = 0, val1 = 0; + do { + val1 = wizchip_read_word(BlockSelectSReg, Sn_TX_FSR); + if (val1 != 0) { + val = wizchip_read_word(BlockSelectSReg, Sn_TX_FSR); + } + } while (val != val1); + return val; +} + +uint16_t Wiznet55rp20::getSn_RX_RSR() { + uint16_t val = 0, val1 = 0; + do { + val1 = wizchip_read_word(BlockSelectSReg, Sn_RX_RSR); + if (val1 != 0) { + val = wizchip_read_word(BlockSelectSReg, Sn_RX_RSR); + } + } while (val != val1); + return val; +} + +void Wiznet55rp20::wizchip_send_data(const uint8_t* wizdata, uint16_t len) { + uint16_t ptr = 0; + + if (len == 0) { + return; + } + ptr = getSn_TX_WR(); + wizchip_write_buf(BlockSelectTxBuf, ptr, wizdata, len); + + ptr += len; + + setSn_TX_WR(ptr); +} + +void Wiznet55rp20::wizchip_recv_data(uint8_t* wizdata, uint16_t len) { + uint16_t ptr; + + if (len == 0) { + return; + } + ptr = getSn_RX_RD(); + wizchip_read_buf(BlockSelectRxBuf, ptr, wizdata, len); + ptr += len; + + setSn_RX_RD(ptr); +} + +void Wiznet55rp20::wizchip_recv_ignore(uint16_t len) { + uint16_t ptr; + + ptr = getSn_RX_RD(); + ptr += len; + setSn_RX_RD(ptr); +} + +void Wiznet55rp20::wizchip_sw_reset() { + setMR(MR_RST); + getMR(); // for delay + + setSHAR(_mac_address); +} + +int8_t Wiznet55rp20::wizphy_getphylink() { + int8_t tmp; + if (getPHYCFGR() & PHYCFGR_LNK_ON) { + tmp = PHY_LINK_ON; + } else { + tmp = PHY_LINK_OFF; + } + return tmp; +} + +int8_t Wiznet55rp20::wizphy_getphypmode() { + int8_t tmp = 0; + if (getPHYCFGR() & PHYCFGR_OPMDC_PDOWN) { + tmp = PHY_POWER_DOWN; + } else { + tmp = PHY_POWER_NORM; + } + return tmp; +} + +void Wiznet55rp20::wizphy_reset() { + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +int8_t Wiznet55rp20::wizphy_setphypmode(uint8_t pmode) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + if ((tmp & PHYCFGR_OPMD) == 0) { + return -1; + } + tmp &= ~PHYCFGR_OPMDC_ALLA; + if (pmode == PHY_POWER_DOWN) { + tmp |= PHYCFGR_OPMDC_PDOWN; + } else { + tmp |= PHYCFGR_OPMDC_ALLA; + } + setPHYCFGR(tmp); + wizphy_reset(); + tmp = getPHYCFGR(); + if (pmode == PHY_POWER_DOWN) { + if (tmp & PHYCFGR_OPMDC_PDOWN) { + return 0; + } + } else { + if (tmp & PHYCFGR_OPMDC_ALLA) { + return 0; + } + } + return -1; +} + +Wiznet55rp20::Wiznet55rp20(int8_t cs, SPIClass& spi, int8_t intr) : _spi(spi), _cs(cs), _intr(intr) { +} + +bool Wiznet55rp20::begin(const uint8_t* mac_address, netif *net) { + wiznet_pio_spi_config.clock_div_major = 4; + wiznet_pio_spi_config.clock_div_minor = 0; + wiznet_pio_spi_config.data_in_pin = WIZNET_PIO_SPI_MISO_PIN; + wiznet_pio_spi_config.data_out_pin = WIZNET_PIO_SPI_MOSI_PIN; + wiznet_pio_spi_config.clock_pin = WIZNET_PIO_SPI_SCK_PIN; + + if (wiznet_pio_spi_handle != NULL) + wiznet_pio_spi_close(wiznet_pio_spi_handle); + wiznet_pio_spi_handle = wiznet_pio_spi_open(&wiznet_pio_spi_config); + (*wiznet_pio_spi_handle)->set_active(wiznet_pio_spi_handle); + + _netif = net; + memcpy(_mac_address, mac_address, 6); + + pinMode(WIZNET_PIO_SPI_CS_PIN, OUTPUT); + wizchip_cs_deselect(); + + wizchip_sw_reset(); + + // Use the full 16Kb of RAM for Socket 0 + setSn_RXBUF_SIZE(16); + setSn_TXBUF_SIZE(16); + + // Set our local MAC address + setSHAR(_mac_address); + + // Open Socket 0 in MACRaw mode + setSn_MR(Sn_MR_MACRAW); + setSn_CR(Sn_CR_OPEN); + if (getSn_SR() != SOCK_MACRAW) { + // Failed to put socket 0 into MACRaw mode + return false; + } + + if (_intr >= 0) { + setSn_IR(0xff); // Clear everything + setSIMR(1); + } + + // Success + return true; +} + +void Wiznet55rp20::end() { + setSn_CR(Sn_CR_CLOSE); + + // clear all interrupt of the socket + setSn_IR(0xFF); + + // Wait for socket to change to closed + while (getSn_SR() != SOCK_CLOSED) + ; +} + +uint16_t Wiznet55rp20::readFrame(uint8_t* buffer, uint16_t bufsize) { + uint16_t data_len = readFrameSize(); + + if (data_len == 0) { + return 0; + } + + if (data_len > bufsize) { + // Packet is bigger than buffer - drop the packet + discardFrame(data_len); + return 0; + } + + return readFrameData(buffer, data_len); +} + +uint16_t Wiznet55rp20::readFrameSize() { + setSn_IR(Sn_IR_RECV); + + uint16_t len = getSn_RX_RSR(); + + if (len == 0) { + return 0; + } + + uint8_t head[2]; + uint16_t data_len = 0; + + wizchip_recv_data(head, 2); + setSn_CR(Sn_CR_RECV); + + data_len = head[0]; + data_len = (data_len << 8) + head[1]; + data_len -= 2; + + return data_len; +} + +void Wiznet55rp20::discardFrame(uint16_t framesize) { + wizchip_recv_ignore(framesize); + setSn_CR(Sn_CR_RECV); +} + +uint16_t Wiznet55rp20::readFrameData(uint8_t* buffer, uint16_t framesize) { + wizchip_recv_data(buffer, framesize); + setSn_CR(Sn_CR_RECV); + + // let lwIP deal with mac address filtering + return framesize; +} + +uint16_t Wiznet55rp20::sendFrame(const uint8_t* buf, uint16_t len) { + ethernet_arch_lwip_gpio_mask(); // So we don't fire an IRQ and interrupt the send w/a receive! + + // Wait for space in the transmit buffer + while (1) { + uint16_t freesize = getSn_TX_FSR(); + if (getSn_SR() == SOCK_CLOSED) { + ethernet_arch_lwip_gpio_unmask(); + return -1; + } + if (len <= freesize) { + break; + } + }; + + wizchip_send_data(buf, len); + setSn_CR(Sn_CR_SEND); + + while (1) { + uint8_t tmp = getSn_IR(); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(Sn_IR_SENDOK); + // Packet sent ok + break; + } else if (tmp & Sn_IR_TIMEOUT) { + setSn_IR(Sn_IR_TIMEOUT); + // There was a timeout + ethernet_arch_lwip_gpio_unmask(); + return -1; + } + } + + ethernet_arch_lwip_gpio_unmask(); + return len; +} diff --git a/libraries/lwIP_w550rp20/src/utility/w55rp20.h b/libraries/lwIP_w550rp20/src/utility/w55rp20.h new file mode 100644 index 000000000..74071d62b --- /dev/null +++ b/libraries/lwIP_w550rp20/src/utility/w55rp20.h @@ -0,0 +1,787 @@ +/* + Copyright (c) 2024, WIZnet Co., Ltd. + Copyright (c) 2016, Nicholas Humfrey + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +// original sources: https://github.com/njh/W5500MacRaw + +#ifndef W55RP20_H +#define W55RP20_H + +#include +#include +#include +#include + +#define WIZNET_PIO_SPI_MOSI_PIN 23 +#define WIZNET_PIO_SPI_MISO_PIN 22 +#define WIZNET_PIO_SPI_SCK_PIN 21 +#define WIZNET_PIO_SPI_CS_PIN 20 + +class Wiznet55rp20 { +public: + /** + Constructor that uses the default hardware SPI pins + @param cs the Arduino Chip Select / Slave Select pin (default 10) + */ + Wiznet55rp20(int8_t cs = SS, SPIClass& spi = SPI, int8_t intr = -1); + //Wiznet55rp20(); + + /** + Initialise the Ethernet controller + Must be called before sending or receiving Ethernet frames + + @param address the local MAC address for the Ethernet interface + @return Returns true if setting up the Ethernet interface was successful + */ + bool begin(const uint8_t* address, netif *net); + + /** + Shut down the Ethernet controlled + */ + void end(); + + /** + Send an Ethernet frame + @param data a pointer to the data to send + @param datalen the length of the data in the packet + @return the number of bytes transmitted + */ + uint16_t sendFrame(const uint8_t* data, uint16_t datalen); + + /** + Read an Ethernet frame + @param buffer a pointer to a buffer to write the packet to + @param bufsize the available space in the buffer + @return the length of the received packet + or 0 if no packet was received + */ + uint16_t readFrame(uint8_t* buffer, uint16_t bufsize); + + /** + Check physical link + @return true when physical link is up + */ + bool isLinked() { + ethernet_arch_lwip_gpio_mask(); + ethernet_arch_lwip_begin(); + auto ret = wizphy_getphylink() == PHY_LINK_ON; + ethernet_arch_lwip_end(); + ethernet_arch_lwip_gpio_unmask(); + return ret; + } + + /** + Report whether ::isLinked() API is implemented + @return true when ::isLinked() API is implemented + */ + constexpr bool isLinkDetectable() const { + return true; + } + + constexpr bool needsSPI() const { + return true; + } + +protected: + static constexpr bool interruptIsPossible() { + return true; + } + + static constexpr PinStatus interruptMode() { + return LOW; + } + + /** + Read an Ethernet frame size + @return the length of data do receive + or 0 if no frame was received + */ + uint16_t readFrameSize(); + + /** + discard an Ethernet frame + @param framesize readFrameSize()'s result + */ + void discardFrame(uint16_t framesize); + + /** + Read an Ethernet frame data + readFrameSize() must be called first, + its result must be passed into framesize parameter + @param buffer a pointer to a buffer to write the frame to + @param framesize readFrameSize()'s result + @return the length of the received frame + or 0 if a problem occurred + */ + uint16_t readFrameData(uint8_t* frame, uint16_t framesize); + +private: + //< SPI interface Read operation in Control Phase + static const uint8_t AccessModeRead = (0x00 << 2); + + //< SPI interface Read operation in Control Phase + static const uint8_t AccessModeWrite = (0x01 << 2); + + //< Common register block in Control Phase + static const uint8_t BlockSelectCReg = (0x00 << 3); + + //< Socket 0 register block in Control Phase + static const uint8_t BlockSelectSReg = (0x01 << 3); + + //< Socket 0 Tx buffer address block + static const uint8_t BlockSelectTxBuf = (0x02 << 3); + + //< Socket 0 Rx buffer address block + static const uint8_t BlockSelectRxBuf = (0x03 << 3); + + SPIClass& _spi; + int8_t _cs; + int8_t _intr; + uint8_t _mac_address[6]; + + /** + Default function to select chip. + @note This function help not to access wrong address. If you do not describe this function + or register any functions, null function is called. + */ + inline void wizchip_cs_select() { + digitalWrite(WIZNET_PIO_SPI_CS_PIN, LOW); + } + + /** + Default function to deselect chip. + @note This function help not to access wrong address. If you do not describe this function + or register any functions, null function is called. + */ + inline void wizchip_cs_deselect() { + //digitalWrite(_cs, HIGH); + digitalWrite(WIZNET_PIO_SPI_CS_PIN, HIGH); + } + + /** + Default function to read in SPI interface. + @note This function help not to access wrong address. If you do not describe this function + or register any functions, null function is called. + */ + inline uint8_t wizchip_spi_read_byte() { + //return _spi.transfer(0); + return 0; + } + + /** + Default function to write in SPI interface. + @note This function help not to access wrong address. If you do not describe this function + or register any functions, null function is called. + */ + inline void wizchip_spi_write_byte(uint8_t wb) { + //_spi.transfer(wb); + } + + /** + Read a 1 byte value from a register. + @param address Register address + @return The value of register + */ + uint8_t wizchip_read(uint8_t block, uint16_t address); + + /** + Reads a 2 byte value from a register. + @param address Register address + @return The value of register + */ + uint16_t wizchip_read_word(uint8_t block, uint16_t address); + + /** + It reads sequence data from registers. + @param address Register address + @param pBuf Pointer buffer to read data + @param len Data length + */ + void wizchip_read_buf(uint8_t block, uint16_t address, uint8_t* pBuf, uint16_t len); + + /** + Write a 1 byte value to a register. + @param address Register address + @param wb Write data + @return void + */ + void wizchip_write(uint8_t block, uint16_t address, uint8_t wb); + + /** + Write a 2 byte value to a register. + @param address Register address + @param wb Write data + @return void + */ + void wizchip_write_word(uint8_t block, uint16_t address, uint16_t word); + + /** + It writes sequence data to registers. + @param address Register address + @param pBuf Pointer buffer to write data + @param len Data length + */ + void wizchip_write_buf(uint8_t block, uint16_t address, const uint8_t* pBuf, uint16_t len); + + /** + Get @ref Sn_TX_FSR register + @return uint16_t. Value of @ref Sn_TX_FSR. + */ + uint16_t getSn_TX_FSR(); + + /** + Get @ref Sn_RX_RSR register + @return uint16_t. Value of @ref Sn_RX_RSR. + */ + uint16_t getSn_RX_RSR(); + + /** + Reset WIZCHIP by softly. + */ + void wizchip_sw_reset(); + + /** + Get the link status of phy in WIZCHIP + */ + int8_t wizphy_getphylink(); + + /** + Get the power mode of PHY in WIZCHIP + */ + int8_t wizphy_getphypmode(); + + /** + Reset Phy + */ + void wizphy_reset(); + + /** + set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in + W5200 + @param pmode Setting value of power down mode. + */ + int8_t wizphy_setphypmode(uint8_t pmode); + + /** + It copies data to internal TX memory + + @details This function reads the Tx write pointer register and after that, + it copies the wizdata(pointer buffer) of the length of len(variable) bytes to + internal TX memory and updates the Tx write pointer register. This function is being called + by send() and sendto() function also. + + @param wizdata Pointer buffer to write data + @param len Data length + @sa wizchip_recv_data() + */ + void wizchip_send_data(const uint8_t* wizdata, uint16_t len); + + /** + It copies data to your buffer from internal RX memory + + @details This function read the Rx read pointer register and after that, + it copies the received data from internal RX memory + to wizdata(pointer variable) of the length of len(variable) bytes. + This function is being called by recv() also. + + @param wizdata Pointer buffer to read data + @param len Data length + @sa wizchip_send_data() + */ + void wizchip_recv_data(uint8_t* wizdata, uint16_t len); + + /** + It discard the received data in RX memory. + @details It discards the data of the length of len(variable) bytes in internal RX + memory. + @param len Data length + */ + void wizchip_recv_ignore(uint16_t len); + + /** Common registers */ + enum { + MR = 0x0000, ///< Mode Register address (R/W) + SHAR = 0x0009, ///< Source MAC Register address (R/W) + INTLEVEL = 0x0013, ///< Set Interrupt low level timer register address (R/W) + IR = 0x0015, ///< Interrupt Register (R/W) + _IMR_ = 0x0016, ///< Interrupt mask register (R/W) + SIR = 0x0017, ///< Socket Interrupt Register (R/W) + _SIMR_ = 0x0018, ///< Socket Interrupt Mask Register (R/W) + _RTR_ = 0x0019, ///< Timeout register address (1 is 100us) (R/W) + _RCR_ = 0x001B, ///< Retry count register (R/W) + UIPR = 0x0028, ///< Unreachable IP register address in UDP mode (R) + UPORTR = 0x002C, ///< Unreachable Port register address in UDP mode (R) + PHYCFGR = 0x002E, ///< PHY Status Register (R/W) + VERSIONR = 0x0039, ///< Chip version register address (R) + }; + + /** Socket registers */ + enum { + Sn_MR = 0x0000, ///< Socket Mode register (R/W) + Sn_CR = 0x0001, ///< Socket command register (R/W) + Sn_IR = 0x0002, ///< Socket interrupt register (R) + Sn_SR = 0x0003, ///< Socket status register (R) + Sn_PORT = 0x0004, ///< Source port register (R/W) + Sn_DHAR = 0x0006, ///< Peer MAC register address (R/W) + Sn_DIPR = 0x000C, ///< Peer IP register address (R/W) + Sn_DPORT = 0x0010, ///< Peer port register address (R/W) + Sn_MSSR = 0x0012, ///< Maximum Segment Size(Sn_MSSR0) register address (R/W) + Sn_TOS = 0x0015, ///< IP Type of Service(TOS) Register (R/W) + Sn_TTL = 0x0016, ///< IP Time to live(TTL) Register (R/W) + Sn_RXBUF_SIZE = 0x001E, ///< Receive memory size register (R/W) + Sn_TXBUF_SIZE = 0x001F, ///< Transmit memory size register (R/W) + Sn_TX_FSR = 0x0020, ///< Transmit free memory size register (R) + Sn_TX_RD = 0x0022, ///< Transmit memory read pointer register address (R) + Sn_TX_WR = 0x0024, ///< Transmit memory write pointer register address (R/W) + Sn_RX_RSR = 0x0026, ///< Received data size register (R) + Sn_RX_RD = 0x0028, ///< Read point of Receive memory (R/W) + Sn_RX_WR = 0x002A, ///< Write point of Receive memory (R) + Sn_IMR = 0x002C, ///< Socket interrupt mask register (R) + Sn_FRAG = 0x002D, ///< Fragment field value in IP header register (R/W) + Sn_KPALVTR = 0x002F, ///< Keep Alive Timer register (R/W) + }; + + /** Mode register values */ + enum { + MR_RST = 0x80, ///< Reset + MR_WOL = 0x20, ///< Wake on LAN + MR_PB = 0x10, ///< Ping block + MR_PPPOE = 0x08, ///< Enable PPPoE + MR_FARP = 0x02, ///< Enable UDP_FORCE_ARP CHECK + }; + + /* Interrupt Register values */ + enum { + IR_CONFLICT = 0x80, ///< Check IP conflict + IR_UNREACH = 0x40, ///< Get the destination unreachable message in UDP sending + IR_PPPoE = 0x20, ///< Get the PPPoE close message + IR_MP = 0x10, ///< Get the magic packet interrupt + }; + + /* Interrupt Mask Register values */ + enum { + IM_IR7 = 0x80, ///< IP Conflict Interrupt Mask + IM_IR6 = 0x40, ///< Destination unreachable Interrupt Mask + IM_IR5 = 0x20, ///< PPPoE Close Interrupt Mask + IM_IR4 = 0x10, ///< Magic Packet Interrupt Mask + }; + + /** Socket Mode Register values @ref Sn_MR */ + enum { + Sn_MR_CLOSE = 0x00, ///< Unused socket + Sn_MR_TCP = 0x01, ///< TCP + Sn_MR_UDP = 0x02, ///< UDP + Sn_MR_MACRAW = 0x04, ///< MAC LAYER RAW SOCK + Sn_MR_UCASTB = 0x10, ///< Unicast Block in UDP Multicasting + Sn_MR_ND = 0x20, ///< No Delayed Ack(TCP), Multicast flag + Sn_MR_BCASTB = 0x40, ///< Broadcast block in UDP Multicasting + Sn_MR_MULTI = 0x80, ///< Support UDP Multicasting + Sn_MR_MIP6B = 0x10, ///< IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + Sn_MR_MMB = 0x20, ///< Multicast Blocking in @ref Sn_MR_MACRAW mode + Sn_MR_MFEN = 0x80, ///< MAC filter enable in @ref Sn_MR_MACRAW mode + }; + + /** Socket Command Register values */ + enum { + Sn_CR_OPEN = 0x01, ///< Initialise or open socket + Sn_CR_LISTEN = 0x02, ///< Wait connection request in TCP mode (Server mode) + Sn_CR_CONNECT = 0x04, ///< Send connection request in TCP mode (Client mode) + Sn_CR_DISCON = 0x08, ///< Send closing request in TCP mode + Sn_CR_CLOSE = 0x10, ///< Close socket + Sn_CR_SEND = 0x20, ///< Update TX buffer pointer and send data + Sn_CR_SEND_MAC = 0x21, ///< Send data with MAC address, so without ARP process + Sn_CR_SEND_KEEP = 0x22, ///< Send keep alive message + Sn_CR_RECV = 0x40, ///< Update RX buffer pointer and receive data + }; + + /** Socket Interrupt register values */ + enum { + Sn_IR_CON = 0x01, ///< CON Interrupt + Sn_IR_DISCON = 0x02, ///< DISCON Interrupt + Sn_IR_RECV = 0x04, ///< RECV Interrupt + Sn_IR_TIMEOUT = 0x08, ///< TIMEOUT Interrupt + Sn_IR_SENDOK = 0x10, ///< SEND_OK Interrupt + }; + + /** Socket Status Register values */ + enum { + SOCK_CLOSED = 0x00, ///< Closed + SOCK_INIT = 0x13, ///< Initiate state + SOCK_LISTEN = 0x14, ///< Listen state + SOCK_SYNSENT = 0x15, ///< Connection state + SOCK_SYNRECV = 0x16, ///< Connection state + SOCK_ESTABLISHED = 0x17, ///< Success to connect + SOCK_FIN_WAIT = 0x18, ///< Closing state + SOCK_CLOSING = 0x1A, ///< Closing state + SOCK_TIME_WAIT = 0x1B, ///< Closing state + SOCK_CLOSE_WAIT = 0x1C, ///< Closing state + SOCK_LAST_ACK = 0x1D, ///< Closing state + SOCK_UDP = 0x22, ///< UDP socket + SOCK_MACRAW = 0x42, ///< MAC raw mode socket + }; + + /* PHYCFGR register value */ + enum { + PHYCFGR_RST = ~(1 << 7), //< For PHY reset, must operate AND mask. + PHYCFGR_OPMD = (1 << 6), // Configure PHY with OPMDC value + PHYCFGR_OPMDC_ALLA = (7 << 3), + PHYCFGR_OPMDC_PDOWN = (6 << 3), + PHYCFGR_OPMDC_NA = (5 << 3), + PHYCFGR_OPMDC_100FA = (4 << 3), + PHYCFGR_OPMDC_100F = (3 << 3), + PHYCFGR_OPMDC_100H = (2 << 3), + PHYCFGR_OPMDC_10F = (1 << 3), + PHYCFGR_OPMDC_10H = (0 << 3), + PHYCFGR_DPX_FULL = (1 << 2), + PHYCFGR_DPX_HALF = (0 << 2), + PHYCFGR_SPD_100 = (1 << 1), + PHYCFGR_SPD_10 = (0 << 1), + PHYCFGR_LNK_ON = (1 << 0), + PHYCFGR_LNK_OFF = (0 << 0), + }; + + enum { + PHY_SPEED_10 = 0, ///< Link Speed 10 + PHY_SPEED_100 = 1, ///< Link Speed 100 + PHY_DUPLEX_HALF = 0, ///< Link Half-Duplex + PHY_DUPLEX_FULL = 1, ///< Link Full-Duplex + PHY_LINK_OFF = 0, ///< Link Off + PHY_LINK_ON = 1, ///< Link On + PHY_POWER_NORM = 0, ///< PHY power normal mode + PHY_POWER_DOWN = 1, ///< PHY power down mode + }; + + /** + Set Mode Register + @param (uint8_t)mr The value to be set. + @sa getMR() + */ + inline void setMR(uint8_t mode) { + wizchip_write(BlockSelectCReg, MR, mode); + } + + /** + Get Mode Register + @return uint8_t. The value of Mode register. + @sa setMR() + */ + inline uint8_t getMR() { + return wizchip_read(BlockSelectCReg, MR); + } + + /** + Set local MAC address + @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 + bytes. + @sa getSHAR() + */ + inline void setSHAR(const uint8_t* macaddr) { + wizchip_write_buf(BlockSelectCReg, SHAR, macaddr, 6); + } + + /** + Get local MAC address + @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 + bytes. + @sa setSHAR() + */ + inline void getSHAR(uint8_t* macaddr) { + wizchip_read_buf(BlockSelectCReg, SHAR, macaddr, 6); + } + + /** + Set @ref IR register + @param (uint8_t)ir Value to set @ref IR register. + @sa getIR() + */ + inline void setIR(uint8_t ir) { + wizchip_write(BlockSelectCReg, IR, (ir & 0xF0)); + } + + /** + Get @ref IR register + @return uint8_t. Value of @ref IR register. + @sa setIR() + */ + inline uint8_t getIR() { + return wizchip_read(BlockSelectCReg, IR) & 0xF0; + } + + /** + Set @ref SIR register + @param (uint8_t)ir Value to set @ref SIR register. + @sa getSIR() + */ + inline void setSIR(uint8_t ir) { + wizchip_write(BlockSelectCReg, SIR, ir); + } + + /** + Get @ref SIR register + @return uint8_t. Value of @ref SIR register. + @sa setSIR() + */ + inline uint8_t getSIR() { + return wizchip_read(BlockSelectCReg, SIR); + } + + /** + Set @ref _IMR_ register + @param (uint8_t)imr Value to set @ref _IMR_ register. + @sa getIMR() + */ + inline void setIMR(uint8_t imr) { + wizchip_write(BlockSelectCReg, _IMR_, imr); + } + + /** + Get @ref _IMR_ register + @return uint8_t. Value of @ref _IMR_ register. + @sa setIMR() + */ + inline uint8_t getIMR() { + return wizchip_read(BlockSelectCReg, _IMR_); + } + + /** + Set @ref _SIMR_ register + @param (uint8_t)imr Value to set @ref _SIMR_ register. + @sa getIMR() + */ + inline void setSIMR(uint8_t imr) { + wizchip_write(BlockSelectCReg, _SIMR_, imr); + } + + /** + Get @ref _SIMR_ register + @return uint8_t. Value of @ref _SIMR_ register. + @sa setSIMR() + */ + inline uint8_t getSIMR() { + return wizchip_read(BlockSelectCReg, _SIMR_); + } + + /** + Set @ref PHYCFGR register + @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + @sa getPHYCFGR() + */ + inline void setPHYCFGR(uint8_t phycfgr) { + wizchip_write(BlockSelectCReg, PHYCFGR, phycfgr); + } + + /** + Get @ref PHYCFGR register + @return uint8_t. Value of @ref PHYCFGR register. + @sa setPHYCFGR() + */ + inline uint8_t getPHYCFGR() { + return wizchip_read(BlockSelectCReg, PHYCFGR); + } + + /** + Get @ref VERSIONR register + @return uint8_t. Value of @ref VERSIONR register. + */ + inline uint8_t getVERSIONR() { + return wizchip_read(BlockSelectCReg, VERSIONR); + } + + /** + Set @ref Sn_MR register + @param (uint8_t)mr Value to set @ref Sn_MR + @sa getSn_MR() + */ + inline void setSn_MR(uint8_t mr) { + wizchip_write(BlockSelectSReg, Sn_MR, mr); + } + + /** + Get @ref Sn_MR register + @return uint8_t. Value of @ref Sn_MR. + @sa setSn_MR() + */ + inline uint8_t getSn_MR() { + return wizchip_read(BlockSelectSReg, Sn_MR); + } + + /** + Set @ref Sn_CR register, then wait for the command to execute + @param (uint8_t)cr Value to set @ref Sn_CR + @sa getSn_CR() + */ + void setSn_CR(uint8_t cr); + + /** + Get @ref Sn_CR register + @return uint8_t. Value of @ref Sn_CR. + @sa setSn_CR() + */ + inline uint8_t getSn_CR() { + return wizchip_read(BlockSelectSReg, Sn_CR); + } + + /** + Set @ref Sn_IR register + @param (uint8_t)ir Value to set @ref Sn_IR + @sa getSn_IR() + */ + inline void setSn_IR(uint8_t ir) { + wizchip_write(BlockSelectSReg, Sn_IR, (ir & 0x1F)); + } + + /** + Get @ref Sn_IR register + @return uint8_t. Value of @ref Sn_IR. + @sa setSn_IR() + */ + inline uint8_t getSn_IR() { + return (wizchip_read(BlockSelectSReg, Sn_IR) & 0x1F); + } + + /** + Set @ref Sn_IMR register + @param (uint8_t)imr Value to set @ref Sn_IMR + @sa getSn_IMR() + */ + inline void setSn_IMR(uint8_t imr) { + wizchip_write(BlockSelectSReg, Sn_IMR, (imr & 0x1F)); + } + + /** + Get @ref Sn_IMR register + @return uint8_t. Value of @ref Sn_IMR. + @sa setSn_IMR() + */ + inline uint8_t getSn_IMR() { + return (wizchip_read(BlockSelectSReg, Sn_IMR) & 0x1F); + } + + /** + Get @ref Sn_SR register + @return uint8_t. Value of @ref Sn_SR. + */ + inline uint8_t getSn_SR() { + return wizchip_read(BlockSelectSReg, Sn_SR); + } + + /** + Set @ref Sn_RXBUF_SIZE register + @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + @sa getSn_RXBUF_SIZE() + */ + inline void setSn_RXBUF_SIZE(uint8_t rxbufsize) { + wizchip_write(BlockSelectSReg, Sn_RXBUF_SIZE, rxbufsize); + } + + /** + Get @ref Sn_RXBUF_SIZE register + @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + @sa setSn_RXBUF_SIZE() + */ + inline uint8_t getSn_RXBUF_SIZE() { + return wizchip_read(BlockSelectSReg, Sn_RXBUF_SIZE); + } + + /** + Set @ref Sn_TXBUF_SIZE register + @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + @sa getSn_TXBUF_SIZE() + */ + inline void setSn_TXBUF_SIZE(uint8_t txbufsize) { + wizchip_write(BlockSelectSReg, Sn_TXBUF_SIZE, txbufsize); + } + + /** + Get @ref Sn_TXBUF_SIZE register + @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + @sa setSn_TXBUF_SIZE() + */ + inline uint8_t getSn_TXBUF_SIZE() { + return wizchip_read(BlockSelectSReg, Sn_TXBUF_SIZE); + } + + /** + Get @ref Sn_TX_RD register + @return uint16_t. Value of @ref Sn_TX_RD. + */ + inline uint16_t getSn_TX_RD() { + return wizchip_read_word(BlockSelectSReg, Sn_TX_RD); + } + + /** + Set @ref Sn_TX_WR register + @param (uint16_t)txwr Value to set @ref Sn_TX_WR + @sa GetSn_TX_WR() + */ + inline void setSn_TX_WR(uint16_t txwr) { + wizchip_write_word(BlockSelectSReg, Sn_TX_WR, txwr); + } + + /** + Get @ref Sn_TX_WR register + @return uint16_t. Value of @ref Sn_TX_WR. + @sa setSn_TX_WR() + */ + inline uint16_t getSn_TX_WR() { + return wizchip_read_word(BlockSelectSReg, Sn_TX_WR); + } + + /** + Set @ref Sn_RX_RD register + @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + @sa getSn_RX_RD() + */ + inline void setSn_RX_RD(uint16_t rxrd) { + wizchip_write_word(BlockSelectSReg, Sn_RX_RD, rxrd); + } + + /** + Get @ref Sn_RX_RD register + @return uint16_t. Value of @ref Sn_RX_RD. + @sa setSn_RX_RD() + */ + inline uint16_t getSn_RX_RD() { + return wizchip_read_word(BlockSelectSReg, Sn_RX_RD); + } + + /** + Get @ref Sn_RX_WR register + @return uint16_t. Value of @ref Sn_RX_WR. + */ + inline uint16_t getSn_RX_WR() { + return wizchip_read_word(BlockSelectSReg, Sn_RX_WR); + } + + netif *_netif; +}; + +#endif // W5500_H diff --git a/libraries/lwIP_w550rp20/src/wiznet_pio_spi.c b/libraries/lwIP_w550rp20/src/wiznet_pio_spi.c new file mode 100644 index 000000000..9b30bbe29 --- /dev/null +++ b/libraries/lwIP_w550rp20/src/wiznet_pio_spi.c @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2024, WIZnet Co., Ltd. + * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "pico/stdlib.h" +#include "pico/error.h" + +#include "hardware/dma.h" +#include "hardware/clocks.h" + +#include "wiznet_pio_spi.h" +#include "wiznet_pio_spi.pio.h" + +#ifndef PIO_SPI_PREFERRED_PIO +#define PIO_SPI_PREFERRED_PIO 1 +#endif + +#define PADS_DRIVE_STRENGTH PADS_BANK0_GPIO0_DRIVE_VALUE_12MA +#define IRQ_SAMPLE_DELAY_NS 100 + +#define WIZNET_PIO_SPI_PROGRAM_NAME wiznet_pio_spi_write_read +#define WIZNET_PIO_SPI_PROGRAM_FUNC __CONCAT(WIZNET_PIO_SPI_PROGRAM_NAME, _program) +#define WIZNET_PIO_SPI_PROGRAM_GET_DEFAULT_CONFIG_FUNC __CONCAT(WIZNET_PIO_SPI_PROGRAM_NAME, _program_get_default_config) +#define WIZNET_PIO_SPI_OFFSET_WRITE_BITS __CONCAT(WIZNET_PIO_SPI_PROGRAM_NAME, _offset_write_bits) +#define WIZNET_PIO_SPI_OFFSET_WRITE_END __CONCAT(WIZNET_PIO_SPI_PROGRAM_NAME, _offset_write_end) +#define WIZNET_PIO_SPI_OFFSET_READ_END __CONCAT(WIZNET_PIO_SPI_PROGRAM_NAME, _offset_read_end) + +// All wiznet spi operations must start with writing a 3 byte header +#define WIZNET_PIO_SPI_HEADER_LEN 3 + +#ifndef WIZNET_PICO_PIO_SPI_INSTANCE_COUNT +#define WIZNET_PICO_PIO_SPI_INSTANCE_COUNT 1 +#endif + +typedef struct wiznet_pio_spi_state { + wiznet_pio_spi_funcs_t *funcs; + const wiznet_pio_spi_config_t *spi_config; + pio_hw_t *pio; + uint8_t pio_func_sel; + int8_t pio_offset; + int8_t pio_sm; + int8_t dma_out; + int8_t dma_in; + uint8_t spi_header[WIZNET_PIO_SPI_HEADER_LEN]; + uint8_t spi_header_count; +} wiznet_pio_spi_state_t; +static wiznet_pio_spi_state_t wiznet_pio_spi_state[WIZNET_PICO_PIO_SPI_INSTANCE_COUNT]; +static wiznet_pio_spi_state_t *active_state; + +static wiznet_pio_spi_funcs_t *get_wiznet_pio_spi_impl(void); + +// Initialise our gpios +static void wiznet_pio_spi_gpio_setup(wiznet_pio_spi_state_t *state) { + + // Setup MOSI, MISO and IRQ + gpio_init(state->spi_config->data_out_pin); + gpio_set_dir(state->spi_config->data_out_pin, GPIO_OUT); + gpio_put(state->spi_config->data_out_pin, false); + + // Setup CS + gpio_init(state->spi_config->cs_pin); + gpio_set_dir(state->spi_config->cs_pin, GPIO_OUT); + gpio_put(state->spi_config->cs_pin, true); + + // Setup IRQ + gpio_init(state->spi_config->irq_pin); + gpio_set_dir(state->spi_config->irq_pin, GPIO_IN); + gpio_set_pulls(state->spi_config->irq_pin, false, false); +} + +wiznet_pio_spi_handle_t wiznet_pio_spi_open(const wiznet_pio_spi_config_t *wiznet_pio_spi_config) { + wiznet_pio_spi_state_t *state; + for(int i = 0; i < count_of(wiznet_pio_spi_state); i++) { + if (!wiznet_pio_spi_state[i].funcs) { + state = &wiznet_pio_spi_state[i]; + break; + } + } + assert(state); + //if (!state) return NULL; + state->spi_config = wiznet_pio_spi_config; + state->funcs = get_wiznet_pio_spi_impl(); + + wiznet_pio_spi_gpio_setup(state); + + pio_hw_t *pios[2] = {pio0, pio1}; + uint pio_index = PIO_SPI_PREFERRED_PIO; + + if (!pio_can_add_program(pios[pio_index], &WIZNET_PIO_SPI_PROGRAM_FUNC)) { + pio_index ^= 1; + if (!pio_can_add_program(pios[pio_index], &WIZNET_PIO_SPI_PROGRAM_FUNC)) { + return NULL; + } + } + + state->pio = pios[pio_index]; + state->dma_in = -1; + state->dma_out = -1; + + static_assert(GPIO_FUNC_PIO1 == GPIO_FUNC_PIO0 + 1, ""); + state->pio_func_sel = GPIO_FUNC_PIO0 + pio_index; + state->pio_sm = (int8_t)pio_claim_unused_sm(state->pio, false); + if (state->pio_sm < 0) { + wiznet_pio_spi_close(&state->funcs); + return NULL; + } + + state->pio_offset = pio_add_program(state->pio, &WIZNET_PIO_SPI_PROGRAM_FUNC); + + pio_sm_config sm_config = WIZNET_PIO_SPI_PROGRAM_GET_DEFAULT_CONFIG_FUNC(state->pio_offset); + + sm_config_set_clkdiv_int_frac(&sm_config, state->spi_config->clock_div_major, state->spi_config->clock_div_minor); + hw_write_masked(&pads_bank0_hw->io[state->spi_config->clock_pin], + (uint)PADS_DRIVE_STRENGTH << PADS_BANK0_GPIO0_DRIVE_LSB, + PADS_BANK0_GPIO0_DRIVE_BITS + ); + hw_write_masked(&pads_bank0_hw->io[state->spi_config->clock_pin], + (uint)1 << PADS_BANK0_GPIO0_SLEWFAST_LSB, + PADS_BANK0_GPIO0_SLEWFAST_BITS + ); + + sm_config_set_out_pins(&sm_config, state->spi_config->data_out_pin, 1); + sm_config_set_in_pins(&sm_config, state->spi_config->data_in_pin); + sm_config_set_set_pins(&sm_config, state->spi_config->data_out_pin, 1); + sm_config_set_sideset(&sm_config, 1, false, false); + sm_config_set_sideset_pins(&sm_config, state->spi_config->clock_pin); + + sm_config_set_in_shift(&sm_config, false, true, 8); + sm_config_set_out_shift(&sm_config, false, true, 8); + hw_set_bits(&state->pio->input_sync_bypass, 1u << state->spi_config->data_in_pin); + pio_sm_set_config(state->pio, state->pio_sm, &sm_config); + pio_sm_set_consecutive_pindirs(state->pio, state->pio_sm, state->spi_config->clock_pin, 1, true); + gpio_set_function(state->spi_config->data_out_pin, state->pio_func_sel); + gpio_set_function(state->spi_config->clock_pin, state->pio_func_sel); + + // Set data pin to pull down and schmitt + gpio_set_pulls(state->spi_config->data_in_pin, false, true); + gpio_set_input_hysteresis_enabled(state->spi_config->data_in_pin, true); + + pio_sm_exec(state->pio, state->pio_sm, pio_encode_set(pio_pins, 1)); + + state->dma_out = (int8_t) dma_claim_unused_channel(false); // todo: Should be able to use one dma channel? + state->dma_in = (int8_t) dma_claim_unused_channel(false); + if (state->dma_out < 0 || state->dma_in < 0) { + wiznet_pio_spi_close(&state->funcs); + return NULL; + } + return &state->funcs; +} + +void wiznet_pio_spi_close(wiznet_pio_spi_handle_t handle) { + wiznet_pio_spi_state_t *state = (wiznet_pio_spi_state_t *)handle; + if (state) { + if (state->pio_sm >= 0) { + if (state->pio_offset != -1) + pio_remove_program(state->pio, &WIZNET_PIO_SPI_PROGRAM_FUNC, state->pio_offset); + + pio_sm_unclaim(state->pio, state->pio_sm); + } + if (state->dma_out >= 0) { + dma_channel_unclaim(state->dma_out); + state->dma_out = -1; + } + if (state->dma_in >= 0) { + dma_channel_unclaim(state->dma_in); + state->dma_in = -1; + } + state->funcs = NULL; + } +} + +static void cs_set(wiznet_pio_spi_state_t *state, bool value) { + gpio_put(state->spi_config->cs_pin, value); +} + +static __noinline void ns_delay(uint32_t ns) { + // cycles = ns * clk_sys_hz / 1,000,000,000 + uint32_t cycles = ns * (clock_get_hz(clk_sys) >> 16u) / (1000000000u >> 16u); + busy_wait_at_least_cycles(cycles); +} + +static void wiznet_pio_spi_frame_start(void) { + assert(active_state); + + gpio_set_function(active_state->spi_config->data_out_pin, active_state->pio_func_sel); + gpio_set_function(active_state->spi_config->clock_pin, active_state->pio_func_sel); + gpio_pull_down(active_state->spi_config->clock_pin); + + // Pull CS low + cs_set(active_state, false); +} + +static void wiznet_pio_spi_frame_end(void) { + assert(active_state); + + // from this point a positive edge will cause an IRQ to be pending + cs_set(active_state, true); + + // we need to wait a bit in case the irq line is incorrectly high +#ifdef IRQ_SAMPLE_DELAY_NS + ns_delay(IRQ_SAMPLE_DELAY_NS); +#endif +} + +// send tx then receive rx +// rx can be null if you just want to send, but tx and tx_length must be valid +bool wiznet_pio_spi_transfer(const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length) { + const wiznet_pio_spi_state_t *state = active_state; + if (!state || (tx == NULL)) { + return false; + } + + if (rx != NULL && tx != NULL) { + assert(tx && tx_length && rx_length); + + pio_sm_set_enabled(state->pio, state->pio_sm, false); // disable sm + pio_sm_set_wrap(state->pio, state->pio_sm, state->pio_offset + WIZNET_PIO_SPI_OFFSET_WRITE_BITS, state->pio_offset + WIZNET_PIO_SPI_OFFSET_READ_END - 1); + pio_sm_clear_fifos(state->pio, state->pio_sm); // clear fifos from previous run + pio_sm_set_pindirs_with_mask(state->pio, state->pio_sm, 1u << state->spi_config->data_out_pin, 1u << state->spi_config->data_out_pin); + pio_sm_restart(state->pio, state->pio_sm); + pio_sm_clkdiv_restart(state->pio, state->pio_sm); + pio_sm_put(state->pio, state->pio_sm, tx_length * 8 - 1); // set x + pio_sm_exec(state->pio, state->pio_sm, pio_encode_out(pio_x, 32)); + pio_sm_put(state->pio, state->pio_sm, rx_length - 1); // set y + pio_sm_exec(state->pio, state->pio_sm, pio_encode_out(pio_y, 32)); + pio_sm_exec(state->pio, state->pio_sm, pio_encode_jmp(state->pio_offset)); // setup pc + dma_channel_abort(state->dma_out); + dma_channel_abort(state->dma_in); + + dma_channel_config out_config = dma_channel_get_default_config(state->dma_out); + channel_config_set_dreq(&out_config, pio_get_dreq(state->pio, state->pio_sm, true)); + channel_config_set_transfer_data_size(&out_config, DMA_SIZE_8); + dma_channel_configure(state->dma_out, &out_config, &state->pio->txf[state->pio_sm], tx, tx_length, true); + + dma_channel_config in_config = dma_channel_get_default_config(state->dma_in); + channel_config_set_dreq(&in_config, pio_get_dreq(state->pio, state->pio_sm, false)); + channel_config_set_write_increment(&in_config, true); + channel_config_set_read_increment(&in_config, false); + channel_config_set_transfer_data_size(&in_config, DMA_SIZE_8); + dma_channel_configure(state->dma_in, &in_config, rx, &state->pio->rxf[state->pio_sm], rx_length, true); + + pio_sm_set_enabled(state->pio, state->pio_sm, true); + __compiler_memory_barrier(); + + dma_channel_wait_for_finish_blocking(state->dma_out); + dma_channel_wait_for_finish_blocking(state->dma_in); + + __compiler_memory_barrier(); + } else if (tx != NULL) { + assert(tx_length); + + pio_sm_set_enabled(state->pio, state->pio_sm, false); + pio_sm_set_wrap(state->pio, state->pio_sm, state->pio_offset + WIZNET_PIO_SPI_OFFSET_WRITE_BITS, state->pio_offset + WIZNET_PIO_SPI_OFFSET_WRITE_END - 1); + pio_sm_clear_fifos(state->pio, state->pio_sm); + pio_sm_restart(state->pio, state->pio_sm); + pio_sm_clkdiv_restart(state->pio, state->pio_sm); + pio_sm_put(state->pio, state->pio_sm, tx_length * 8 - 1); + pio_sm_exec(state->pio, state->pio_sm, pio_encode_out(pio_x, 32)); + pio_sm_put(state->pio, state->pio_sm, tx_length - 1); + pio_sm_exec(state->pio, state->pio_sm, pio_encode_out(pio_y, 32)); + pio_sm_exec(state->pio, state->pio_sm, pio_encode_set(pio_pins, 0)); + pio_sm_set_consecutive_pindirs(state->pio, state->pio_sm, state->spi_config->data_out_pin, 1, true); + pio_sm_exec(state->pio, state->pio_sm, pio_encode_jmp(state->pio_offset + WIZNET_PIO_SPI_OFFSET_WRITE_BITS)); + dma_channel_abort(state->dma_out); + + dma_channel_config out_config = dma_channel_get_default_config(state->dma_out); + channel_config_set_dreq(&out_config, pio_get_dreq(state->pio, state->pio_sm, true)); + + channel_config_set_transfer_data_size(&out_config, DMA_SIZE_8); + dma_channel_configure(state->dma_out, &out_config, &state->pio->txf[state->pio_sm], tx, tx_length, true); + + const uint32_t fDebugTxStall = 1u << (PIO_FDEBUG_TXSTALL_LSB + state->pio_sm); + state->pio->fdebug = fDebugTxStall; + pio_sm_set_enabled(state->pio, state->pio_sm, true); + while (!(state->pio->fdebug & fDebugTxStall)) { + tight_loop_contents(); // todo timeout + } + __compiler_memory_barrier(); + pio_sm_set_enabled(state->pio, state->pio_sm, false); + pio_sm_set_consecutive_pindirs(state->pio, state->pio_sm, state->spi_config->data_in_pin, 1, false); + } else if (rx != NULL) { + panic_unsupported(); // shouldn't be used + } + pio_sm_exec(state->pio, state->pio_sm, pio_encode_mov(pio_pins, pio_null)); // for next time we turn output on + + return true; +} + +// To read a byte we must first have been asked to write a 3 byte spi header +static uint8_t wiznet_pio_spi_read_byte(void) { + assert(active_state); + assert(active_state->spi_header_count == WIZNET_PIO_SPI_HEADER_LEN); + uint8_t ret; + if (!wiznet_pio_spi_transfer(active_state->spi_header, active_state->spi_header_count, &ret, 1)) { + panic("spi failed read"); + } + active_state->spi_header_count = 0; + return ret; +} + +// This is not used when the burst functions are provided +static void wiznet_pio_spi_write_byte(uint8_t wb) { + panic_unsupported(); // shouldn't be used +} + +// To read a buffer we must first have been asked to write a 3 byte spi header +void wiznet_pio_spi_read_buffer(uint8_t* pBuf, uint16_t len) { + + assert(active_state); + assert(active_state->spi_header_count == WIZNET_PIO_SPI_HEADER_LEN); + if (!wiznet_pio_spi_transfer(active_state->spi_header, active_state->spi_header_count, pBuf, len)) { + panic("spi failed reading buffer"); + } + active_state->spi_header_count = 0; +} + +// If we have been asked to write a spi header already, then write it and the rest of the buffer +// or else if we've been given enough data for just the spi header, save it until the next call +// or we're writing a byte in which case we're given a buffer including the spi header +void wiznet_pio_spi_write_buffer(const uint8_t* pBuf, uint16_t len) { + assert(active_state); + if (len == WIZNET_PIO_SPI_HEADER_LEN && active_state->spi_header_count == 0) { + memcpy(active_state->spi_header, pBuf, WIZNET_PIO_SPI_HEADER_LEN); // expect another call + active_state->spi_header_count = WIZNET_PIO_SPI_HEADER_LEN; + } else { + if (active_state->spi_header_count == WIZNET_PIO_SPI_HEADER_LEN) { + if (!wiznet_pio_spi_transfer(active_state->spi_header, WIZNET_PIO_SPI_HEADER_LEN, NULL, 0)) { + panic("spi failed writing header"); + } + active_state->spi_header_count = 0; + } + assert(active_state->spi_header_count == 0); + if (!wiznet_pio_spi_transfer(pBuf, len, NULL, 0)) { + panic("spi failed writing buffer"); + } + } +} + +static void wiznet_pio_spi_set_active(wiznet_pio_spi_handle_t handle) { + active_state = (wiznet_pio_spi_state_t *)handle; +} + +static void wiznet_pio_spi_set_inactive(void) { + active_state = NULL; +} + +static void wiznet_pio_spi_reset(wiznet_pio_spi_handle_t handle) { + wiznet_pio_spi_state_t *state = (wiznet_pio_spi_state_t *)handle; + gpio_set_dir(state->spi_config->reset_pin, GPIO_OUT); + gpio_put(state->spi_config->reset_pin, 0); + sleep_ms(100); + gpio_put(state->spi_config->reset_pin, 1); + sleep_ms(100); +} + +static wiznet_pio_spi_funcs_t *get_wiznet_pio_spi_impl(void) { + static wiznet_pio_spi_funcs_t funcs = { + .close = wiznet_pio_spi_close, + .set_active = wiznet_pio_spi_set_active, + .set_inactive = wiznet_pio_spi_set_inactive, + .frame_start = wiznet_pio_spi_frame_start, + .frame_end = wiznet_pio_spi_frame_end, + .read_byte = wiznet_pio_spi_read_byte, + .write_byte = wiznet_pio_spi_write_byte, + .read_buffer = wiznet_pio_spi_read_buffer, + .write_buffer = wiznet_pio_spi_write_buffer, + .reset = wiznet_pio_spi_reset, + }; + return &funcs; +} \ No newline at end of file diff --git a/libraries/lwIP_w550rp20/src/wiznet_pio_spi.h b/libraries/lwIP_w550rp20/src/wiznet_pio_spi.h new file mode 100644 index 000000000..ca14e6f37 --- /dev/null +++ b/libraries/lwIP_w550rp20/src/wiznet_pio_spi.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 WIZnet Co., Ltd. + * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _WIZNET_PIO_SPI_H_ +#define _WIZNET_PIO_SPI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct wiznet_pio_spi_config { + uint8_t data_in_pin; + uint8_t data_out_pin; + uint8_t cs_pin; + uint8_t clock_pin; + uint8_t irq_pin; + uint8_t reset_pin; + uint16_t clock_div_major; + uint8_t clock_div_minor; + uint8_t spi_hw_instance; +} wiznet_pio_spi_config_t; + +typedef struct wiznet_pio_spi_funcs** wiznet_pio_spi_handle_t; + +typedef struct wiznet_pio_spi_funcs { + void (*close)(wiznet_pio_spi_handle_t funcs); + void (*set_active)(wiznet_pio_spi_handle_t funcs); + void (*set_inactive)(void); + void (*frame_start)(void); + void (*frame_end)(void); + uint8_t (*read_byte)(void); + void (*write_byte)(uint8_t tx_data); + void (*read_buffer)(uint8_t *pBuf, uint16_t len); + void (*write_buffer)(const uint8_t *pBuf, uint16_t len); + void (*reset)(wiznet_pio_spi_handle_t funcs); +} wiznet_pio_spi_funcs_t; + +wiznet_pio_spi_handle_t wiznet_pio_spi_open(const wiznet_pio_spi_config_t *pio_spi_config); +void wiznet_pio_spi_close(wiznet_pio_spi_handle_t handle); +bool wiznet_pio_spi_transfer(const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length); +void wiznet_pio_spi_read_buffer(uint8_t* pBuf, uint16_t len); +void wiznet_pio_spi_write_buffer(const uint8_t* pBuf, uint16_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio b/libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio new file mode 100644 index 000000000..224dac8c0 --- /dev/null +++ b/libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio @@ -0,0 +1,25 @@ +; +; Copyright (c) 2024 WIZnet Co., Ltd. +; Copyright (c) 2023 Raspberry Pi (Trading) Ltd. +; +; SPDX-License-Identifier: BSD-3-Clause +; + +.program wiznet_pio_spi_write_read +.side_set 1 + +public write_bits: + out pins, 1 side 0 + jmp x-- write_bits side 1 + set pins 0 side 0 +public write_end: +read_byte_delay: + set pindirs 0 side 0 +read_byte: + set x 6 side 1 +read_bits: + in pins, 1 side 0 + jmp x-- read_bits side 1 + in pins, 1 side 0 + jmp y-- read_byte side 0 +public read_end: \ No newline at end of file diff --git a/libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio.h b/libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio.h new file mode 100644 index 000000000..f7cc6af66 --- /dev/null +++ b/libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio.h @@ -0,0 +1,50 @@ +// -------------------------------------------------- // +// This file is autogenerated by pioasm; do not edit! // +// -------------------------------------------------- // + +#pragma once + +#if !PICO_NO_HARDWARE +#include "hardware/pio.h" +#endif + +// ------------------------- // +// wiznet_pio_spi_write_read // +// ------------------------- // + +#define wiznet_pio_spi_write_read_wrap_target 0 +#define wiznet_pio_spi_write_read_wrap 8 + +#define wiznet_pio_spi_write_read_offset_write_bits 0u +#define wiznet_pio_spi_write_read_offset_write_end 3u +#define wiznet_pio_spi_write_read_offset_read_end 9u + +static const uint16_t wiznet_pio_spi_write_read_program_instructions[] = { + // .wrap_target + 0x6001, // 0: out pins, 1 side 0 + 0x1040, // 1: jmp x--, 0 side 1 + 0xe000, // 2: set pins, 0 side 0 + 0xe080, // 3: set pindirs, 0 side 0 + 0xf026, // 4: set x, 6 side 1 + 0x4001, // 5: in pins, 1 side 0 + 0x1045, // 6: jmp x--, 5 side 1 + 0x4001, // 7: in pins, 1 side 0 + 0x0084, // 8: jmp y--, 4 side 0 + // .wrap +}; + +#if !PICO_NO_HARDWARE +static const struct pio_program wiznet_pio_spi_write_read_program = { + .instructions = wiznet_pio_spi_write_read_program_instructions, + .length = 9, + .origin = -1, +}; + +static inline pio_sm_config wiznet_pio_spi_write_read_program_get_default_config(uint offset) { + pio_sm_config c = pio_get_default_sm_config(); + sm_config_set_wrap(&c, offset + wiznet_pio_spi_write_read_wrap_target, offset + wiznet_pio_spi_write_read_wrap); + sm_config_set_sideset(&c, 1, false, false); + return c; +} +#endif + diff --git a/tools/json/wiznet_55rp20_evb_pico.json b/tools/json/wiznet_55rp20_evb_pico.json new file mode 100644 index 000000000..7f3426396 --- /dev/null +++ b/tools/json/wiznet_55rp20_evb_pico.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "earlephilhower": { + "boot2_source": "boot2_w25q080_2_padded_checksum.S", + "usb_vid": "0x2E8A", + "usb_pid": "0x1029" + } + }, + "core": "earlephilhower", + "cpu": "cortex-m0plus", + "extra_flags": "-DARDUINO_WIZNET_55RP20_EVB_PICO -DARDUINO_ARCH_RP2040 -DUSBD_MAX_POWER_MA=250 ", + "f_cpu": "133000000L", + "hwids": [ + [ + "0x2E8A", + "0x00C0" + ], + [ + "0x2E8A", + "0x1029" + ] + ], + "mcu": "rp2040", + "variant": "wiznet_55rp20_evb_pico" + }, + "debug": { + "jlink_device": "RP2040_M0_0", + "openocd_target": "rp2040.cfg", + "svd_path": "rp2040.svd" + }, + "frameworks": [ + "arduino" + ], + "name": "W55RP20-EVB-Pico", + "upload": { + "maximum_ram_size": 262144, + "maximum_size": 2097152, + "require_upload_port": true, + "native_usb": true, + "use_1200bps_touch": true, + "wait_for_upload_port": false, + "protocol": "picotool", + "protocols": [ + "blackmagic", + "cmsis-dap", + "jlink", + "raspberrypi-swd", + "picotool", + "picoprobe" + ] + }, + "url": "https://www.raspberrypi.org/products/raspberry-pi-pico/", + "vendor": "WIZnet" +} \ No newline at end of file diff --git a/tools/makeboards.py b/tools/makeboards.py index f90092618..2d4de6e40 100755 --- a/tools/makeboards.py +++ b/tools/makeboards.py @@ -659,6 +659,7 @@ def MakeBoardJSON(name, chip, vendor_name, product_name, vid, pid, pwr, boarddef MakeBoard("wiznet_5100s_evb_pico", "rp2040", "WIZnet", "W5100S-EVB-Pico", "0x2e8a", "0x1027", 250, "WIZNET_5100S_EVB_PICO", 2, 0, "boot2_w25q080_2_padded_checksum") MakeBoard("wiznet_wizfi360_evb_pico", "rp2040", "WIZnet", "WizFi360-EVB-Pico", "0x2e8a", "0x1028", 250, "WIZNET_WIZFI360_EVB_PICO", 2, 0, "boot2_w25q080_2_padded_checksum") MakeBoard("wiznet_5500_evb_pico", "rp2040", "WIZnet", "W5500-EVB-Pico", "0x2e8a", "0x1029", 250, "WIZNET_5500_EVB_PICO", 2, 0, "boot2_w25q080_2_padded_checksum") +MakeBoard("wiznet_55rp20_evb_pico", "rp2040", "WIZnet", "W55RP20-EVB-Pico", "0x2e8a", "0x1029", 250, "WIZNET_55RP20_EVB_PICO", 2, 0, "boot2_w25q080_2_padded_checksum") # Generic MakeBoard("generic", "rp2040", "Generic", "RP2040", "0x2e8a", "0xf00a", 250, "GENERIC_RP2040", 16, 0, "boot2_generic_03h_4_padded_checksum") diff --git a/variants/wiznet_55rp20_evb_pico/pins_arduino.h b/variants/wiznet_55rp20_evb_pico/pins_arduino.h new file mode 100644 index 000000000..41d8bda5a --- /dev/null +++ b/variants/wiznet_55rp20_evb_pico/pins_arduino.h @@ -0,0 +1 @@ +#include "../generic/pins_arduino.h" From 8d440f4aa9c659a56d6c41b51a89efffba4de84d Mon Sep 17 00:00:00 2001 From: Mason Date: Wed, 23 Oct 2024 09:25:28 +0900 Subject: [PATCH 2/6] Fixed directory type, add restyle lwIP_w55rp20 path --- .../examples/WiFiClient-W55RP20/WiFiClient-W55RP20.ino | 0 libraries/{lwIP_w550rp20 => lwIP_w55rp20}/keywords.txt | 0 libraries/{lwIP_w550rp20 => lwIP_w55rp20}/library.properties | 0 libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/W55RP20lwIP.h | 0 .../{lwIP_w550rp20 => lwIP_w55rp20}/src/utility/w55rp20.cpp | 0 libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/utility/w55rp20.h | 0 libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/wiznet_pio_spi.c | 0 libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/wiznet_pio_spi.h | 0 .../{lwIP_w550rp20 => lwIP_w55rp20}/src/wiznet_pio_spi.pio | 0 .../{lwIP_w550rp20 => lwIP_w55rp20}/src/wiznet_pio_spi.pio.h | 0 tests/restyle.sh | 2 +- 11 files changed, 1 insertion(+), 1 deletion(-) rename libraries/{lwIP_w550rp20 => lwIP_w55rp20}/examples/WiFiClient-W55RP20/WiFiClient-W55RP20.ino (100%) rename libraries/{lwIP_w550rp20 => lwIP_w55rp20}/keywords.txt (100%) rename libraries/{lwIP_w550rp20 => lwIP_w55rp20}/library.properties (100%) rename libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/W55RP20lwIP.h (100%) rename libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/utility/w55rp20.cpp (100%) rename libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/utility/w55rp20.h (100%) rename libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/wiznet_pio_spi.c (100%) rename libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/wiznet_pio_spi.h (100%) rename libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/wiznet_pio_spi.pio (100%) rename libraries/{lwIP_w550rp20 => lwIP_w55rp20}/src/wiznet_pio_spi.pio.h (100%) diff --git a/libraries/lwIP_w550rp20/examples/WiFiClient-W55RP20/WiFiClient-W55RP20.ino b/libraries/lwIP_w55rp20/examples/WiFiClient-W55RP20/WiFiClient-W55RP20.ino similarity index 100% rename from libraries/lwIP_w550rp20/examples/WiFiClient-W55RP20/WiFiClient-W55RP20.ino rename to libraries/lwIP_w55rp20/examples/WiFiClient-W55RP20/WiFiClient-W55RP20.ino diff --git a/libraries/lwIP_w550rp20/keywords.txt b/libraries/lwIP_w55rp20/keywords.txt similarity index 100% rename from libraries/lwIP_w550rp20/keywords.txt rename to libraries/lwIP_w55rp20/keywords.txt diff --git a/libraries/lwIP_w550rp20/library.properties b/libraries/lwIP_w55rp20/library.properties similarity index 100% rename from libraries/lwIP_w550rp20/library.properties rename to libraries/lwIP_w55rp20/library.properties diff --git a/libraries/lwIP_w550rp20/src/W55RP20lwIP.h b/libraries/lwIP_w55rp20/src/W55RP20lwIP.h similarity index 100% rename from libraries/lwIP_w550rp20/src/W55RP20lwIP.h rename to libraries/lwIP_w55rp20/src/W55RP20lwIP.h diff --git a/libraries/lwIP_w550rp20/src/utility/w55rp20.cpp b/libraries/lwIP_w55rp20/src/utility/w55rp20.cpp similarity index 100% rename from libraries/lwIP_w550rp20/src/utility/w55rp20.cpp rename to libraries/lwIP_w55rp20/src/utility/w55rp20.cpp diff --git a/libraries/lwIP_w550rp20/src/utility/w55rp20.h b/libraries/lwIP_w55rp20/src/utility/w55rp20.h similarity index 100% rename from libraries/lwIP_w550rp20/src/utility/w55rp20.h rename to libraries/lwIP_w55rp20/src/utility/w55rp20.h diff --git a/libraries/lwIP_w550rp20/src/wiznet_pio_spi.c b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.c similarity index 100% rename from libraries/lwIP_w550rp20/src/wiznet_pio_spi.c rename to libraries/lwIP_w55rp20/src/wiznet_pio_spi.c diff --git a/libraries/lwIP_w550rp20/src/wiznet_pio_spi.h b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.h similarity index 100% rename from libraries/lwIP_w550rp20/src/wiznet_pio_spi.h rename to libraries/lwIP_w55rp20/src/wiznet_pio_spi.h diff --git a/libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.pio similarity index 100% rename from libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio rename to libraries/lwIP_w55rp20/src/wiznet_pio_spi.pio diff --git a/libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio.h b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.pio.h similarity index 100% rename from libraries/lwIP_w550rp20/src/wiznet_pio_spi.pio.h rename to libraries/lwIP_w55rp20/src/wiznet_pio_spi.pio.h diff --git a/tests/restyle.sh b/tests/restyle.sh index 77fbd51f0..2a1b41dcf 100755 --- a/tests/restyle.sh +++ b/tests/restyle.sh @@ -13,7 +13,7 @@ for dir in ./cores/rp2040 ./libraries/EEPROM ./libraries/I2S ./libraries/SingleF ./libraries/JoystickBT ./libraries/KeyboardBT ./variants ./libraries/BTstackLib \ ./libraries/MouseBT ./libraries/SerialBT ./libraries/HID_Bluetooth \ ./libraries/JoystickBLE ./libraries/KeyboardBLE ./libraries/MouseBLE \ - ./libraries/lwIP_w5500 ./libraries/lwIP_w5100 ./libraries/lwIP_enc28j60 \ + ./libraries/lwIP_w55rp20 ./libraries/lwIP_w5500 ./libraries/lwIP_w5100 ./libraries/lwIP_enc28j60 \ ./libraries/SPISlave ./libraries/lwIP_ESPHost ./libraries/FatFS\ ./libraries/FatFSUSB ./libraries/BluetoothAudio ./libraries/BluetoothHCI \ ./libraries/BluetoothHIDMaster ./libraries/NetBIOS ./libraries/Ticker \ From 349648f89273e428426079d59a3ea81c6ee171ce Mon Sep 17 00:00:00 2001 From: Mason Date: Wed, 23 Oct 2024 10:26:45 +0900 Subject: [PATCH 3/6] Apply restyle.sh --- .../lwIP_w55rp20/src/utility/w55rp20.cpp | 33 ++++++++++--------- libraries/lwIP_w55rp20/src/wiznet_pio_spi.c | 23 ++++++------- libraries/lwIP_w55rp20/src/wiznet_pio_spi.h | 10 +++--- .../lwIP_w55rp20/src/wiznet_pio_spi.pio.h | 22 ++++++------- 4 files changed, 45 insertions(+), 43 deletions(-) diff --git a/libraries/lwIP_w55rp20/src/utility/w55rp20.cpp b/libraries/lwIP_w55rp20/src/utility/w55rp20.cpp index c116d81cc..7a5caeefa 100644 --- a/libraries/lwIP_w55rp20/src/utility/w55rp20.cpp +++ b/libraries/lwIP_w55rp20/src/utility/w55rp20.cpp @@ -48,9 +48,9 @@ uint8_t Wiznet55rp20::wizchip_read(uint8_t block, uint16_t address) { block |= AccessModeRead; - spi_data[0] = (address & 0x00FF00) >> 8; - spi_data[1] = (address & 0x0000FF) >> 0; - spi_data[2] = block; + spi_data[0] = (address & 0x00FF00) >> 8; + spi_data[1] = (address & 0x0000FF) >> 0; + spi_data[2] = block; (*wiznet_pio_spi_handle)->write_buffer(spi_data, 3); ret = (*wiznet_pio_spi_handle)->read_byte(); @@ -70,9 +70,9 @@ void Wiznet55rp20::wizchip_read_buf(uint8_t block, uint16_t address, uint8_t* pB block |= AccessModeRead; - spi_data[0] = (address & 0x00FF00) >> 8; - spi_data[1] = (address & 0x0000FF) >> 0; - spi_data[2] = block; + spi_data[0] = (address & 0x00FF00) >> 8; + spi_data[1] = (address & 0x0000FF) >> 0; + spi_data[2] = block; (*wiznet_pio_spi_handle)->write_buffer(spi_data, 3); (*wiznet_pio_spi_handle)->read_buffer(pBuf, len); @@ -87,8 +87,8 @@ void Wiznet55rp20::wizchip_write(uint8_t block, uint16_t address, uint8_t wb) { block |= AccessModeWrite; spi_data[0] = (address & 0x00FF00) >> 8; - spi_data[1] = (address & 0x0000FF) >> 0; - spi_data[2] = block; + spi_data[1] = (address & 0x0000FF) >> 0; + spi_data[2] = block; spi_data[3] = wb; (*wiznet_pio_spi_handle)->write_buffer(spi_data, 4); @@ -101,7 +101,7 @@ void Wiznet55rp20::wizchip_write_word(uint8_t block, uint16_t address, uint16_t } void Wiznet55rp20::wizchip_write_buf(uint8_t block, uint16_t address, const uint8_t* pBuf, - uint16_t len) { + uint16_t len) { uint16_t i; uint8_t spi_data[3]; @@ -110,10 +110,10 @@ void Wiznet55rp20::wizchip_write_buf(uint8_t block, uint16_t address, const uint block |= AccessModeWrite; spi_data[0] = (address & 0x00FF00) >> 8; - spi_data[1] = (address & 0x0000FF); - spi_data[2] = block; - (*wiznet_pio_spi_handle)->write_buffer(spi_data, 3); - (*wiznet_pio_spi_handle)->write_buffer(pBuf, len); + spi_data[1] = (address & 0x0000FF); + spi_data[2] = block; + (*wiznet_pio_spi_handle)->write_buffer(spi_data, 3); + (*wiznet_pio_spi_handle)->write_buffer(pBuf, len); wizchip_cs_deselect(); } @@ -257,8 +257,9 @@ bool Wiznet55rp20::begin(const uint8_t* mac_address, netif *net) { wiznet_pio_spi_config.data_out_pin = WIZNET_PIO_SPI_MOSI_PIN; wiznet_pio_spi_config.clock_pin = WIZNET_PIO_SPI_SCK_PIN; - if (wiznet_pio_spi_handle != NULL) + if (wiznet_pio_spi_handle != NULL) { wiznet_pio_spi_close(wiznet_pio_spi_handle); + } wiznet_pio_spi_handle = wiznet_pio_spi_open(&wiznet_pio_spi_config); (*wiznet_pio_spi_handle)->set_active(wiznet_pio_spi_handle); @@ -267,13 +268,13 @@ bool Wiznet55rp20::begin(const uint8_t* mac_address, netif *net) { pinMode(WIZNET_PIO_SPI_CS_PIN, OUTPUT); wizchip_cs_deselect(); - + wizchip_sw_reset(); // Use the full 16Kb of RAM for Socket 0 setSn_RXBUF_SIZE(16); setSn_TXBUF_SIZE(16); - + // Set our local MAC address setSHAR(_mac_address); diff --git a/libraries/lwIP_w55rp20/src/wiznet_pio_spi.c b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.c index 9b30bbe29..dd00cf790 100644 --- a/libraries/lwIP_w55rp20/src/wiznet_pio_spi.c +++ b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 2024, WIZnet Co., Ltd. - * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ + Copyright (c) 2024, WIZnet Co., Ltd. + Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + + SPDX-License-Identifier: BSD-3-Clause +*/ #include #include @@ -76,7 +76,7 @@ static void wiznet_pio_spi_gpio_setup(wiznet_pio_spi_state_t *state) { wiznet_pio_spi_handle_t wiznet_pio_spi_open(const wiznet_pio_spi_config_t *wiznet_pio_spi_config) { wiznet_pio_spi_state_t *state; - for(int i = 0; i < count_of(wiznet_pio_spi_state); i++) { + for (int i = 0; i < count_of(wiznet_pio_spi_state); i++) { if (!wiznet_pio_spi_state[i].funcs) { state = &wiznet_pio_spi_state[i]; break; @@ -119,11 +119,11 @@ wiznet_pio_spi_handle_t wiznet_pio_spi_open(const wiznet_pio_spi_config_t *wizne hw_write_masked(&pads_bank0_hw->io[state->spi_config->clock_pin], (uint)PADS_DRIVE_STRENGTH << PADS_BANK0_GPIO0_DRIVE_LSB, PADS_BANK0_GPIO0_DRIVE_BITS - ); + ); hw_write_masked(&pads_bank0_hw->io[state->spi_config->clock_pin], (uint)1 << PADS_BANK0_GPIO0_SLEWFAST_LSB, PADS_BANK0_GPIO0_SLEWFAST_BITS - ); + ); sm_config_set_out_pins(&sm_config, state->spi_config->data_out_pin, 1); sm_config_set_in_pins(&sm_config, state->spi_config->data_in_pin); @@ -158,8 +158,9 @@ void wiznet_pio_spi_close(wiznet_pio_spi_handle_t handle) { wiznet_pio_spi_state_t *state = (wiznet_pio_spi_state_t *)handle; if (state) { if (state->pio_sm >= 0) { - if (state->pio_offset != -1) + if (state->pio_offset != -1) { pio_remove_program(state->pio, &WIZNET_PIO_SPI_PROGRAM_FUNC, state->pio_offset); + } pio_sm_unclaim(state->pio, state->pio_sm); } @@ -220,7 +221,7 @@ bool wiznet_pio_spi_transfer(const uint8_t *tx, size_t tx_length, uint8_t *rx, s assert(tx && tx_length && rx_length); pio_sm_set_enabled(state->pio, state->pio_sm, false); // disable sm - pio_sm_set_wrap(state->pio, state->pio_sm, state->pio_offset + WIZNET_PIO_SPI_OFFSET_WRITE_BITS, state->pio_offset + WIZNET_PIO_SPI_OFFSET_READ_END - 1); + pio_sm_set_wrap(state->pio, state->pio_sm, state->pio_offset + WIZNET_PIO_SPI_OFFSET_WRITE_BITS, state->pio_offset + WIZNET_PIO_SPI_OFFSET_READ_END - 1); pio_sm_clear_fifos(state->pio, state->pio_sm); // clear fifos from previous run pio_sm_set_pindirs_with_mask(state->pio, state->pio_sm, 1u << state->spi_config->data_out_pin, 1u << state->spi_config->data_out_pin); pio_sm_restart(state->pio, state->pio_sm); @@ -294,7 +295,7 @@ bool wiznet_pio_spi_transfer(const uint8_t *tx, size_t tx_length, uint8_t *rx, s // To read a byte we must first have been asked to write a 3 byte spi header static uint8_t wiznet_pio_spi_read_byte(void) { - assert(active_state); + assert(active_state); assert(active_state->spi_header_count == WIZNET_PIO_SPI_HEADER_LEN); uint8_t ret; if (!wiznet_pio_spi_transfer(active_state->spi_header, active_state->spi_header_count, &ret, 1)) { diff --git a/libraries/lwIP_w55rp20/src/wiznet_pio_spi.h b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.h index ca14e6f37..a00a58a41 100644 --- a/libraries/lwIP_w55rp20/src/wiznet_pio_spi.h +++ b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.h @@ -1,9 +1,9 @@ /* - * Copyright (c) 2024 WIZnet Co., Ltd. - * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ + Copyright (c) 2024 WIZnet Co., Ltd. + Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + + SPDX-License-Identifier: BSD-3-Clause +*/ #ifndef _WIZNET_PIO_SPI_H_ #define _WIZNET_PIO_SPI_H_ diff --git a/libraries/lwIP_w55rp20/src/wiznet_pio_spi.pio.h b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.pio.h index f7cc6af66..dff1d9c29 100644 --- a/libraries/lwIP_w55rp20/src/wiznet_pio_spi.pio.h +++ b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.pio.h @@ -20,17 +20,17 @@ #define wiznet_pio_spi_write_read_offset_read_end 9u static const uint16_t wiznet_pio_spi_write_read_program_instructions[] = { - // .wrap_target - 0x6001, // 0: out pins, 1 side 0 - 0x1040, // 1: jmp x--, 0 side 1 - 0xe000, // 2: set pins, 0 side 0 - 0xe080, // 3: set pindirs, 0 side 0 - 0xf026, // 4: set x, 6 side 1 - 0x4001, // 5: in pins, 1 side 0 - 0x1045, // 6: jmp x--, 5 side 1 - 0x4001, // 7: in pins, 1 side 0 - 0x0084, // 8: jmp y--, 4 side 0 - // .wrap + // .wrap_target + 0x6001, // 0: out pins, 1 side 0 + 0x1040, // 1: jmp x--, 0 side 1 + 0xe000, // 2: set pins, 0 side 0 + 0xe080, // 3: set pindirs, 0 side 0 + 0xf026, // 4: set x, 6 side 1 + 0x4001, // 5: in pins, 1 side 0 + 0x1045, // 6: jmp x--, 5 side 1 + 0x4001, // 7: in pins, 1 side 0 + 0x0084, // 8: jmp y--, 4 side 0 + // .wrap }; #if !PICO_NO_HARDWARE From a913600470580cfee0b82ad37fad6baf3a4e6cca Mon Sep 17 00:00:00 2001 From: Mason Date: Wed, 23 Oct 2024 11:27:40 +0900 Subject: [PATCH 4/6] Fixed package/package_pico_index.template.json file --- package/package_pico_index.template.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package/package_pico_index.template.json b/package/package_pico_index.template.json index 8709562db..262b1a430 100644 --- a/package/package_pico_index.template.json +++ b/package/package_pico_index.template.json @@ -332,6 +332,9 @@ { "name": "WIZnet W5500-EVB-Pico" }, + { + "name": "WIZnet W55RP20-EVB-Pico" + }, { "name": "Generic RP2040" }, From dc1d818cf6cf45df17f67d5320d392c3ea56610f Mon Sep 17 00:00:00 2001 From: Mason Date: Wed, 23 Oct 2024 13:28:15 +0900 Subject: [PATCH 5/6] Fixed EthernetLibCompatible example error --- libraries/lwIP_Ethernet/src/EthernetCompat.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/lwIP_Ethernet/src/EthernetCompat.h b/libraries/lwIP_Ethernet/src/EthernetCompat.h index 2b3bf7142..4291ce293 100644 --- a/libraries/lwIP_Ethernet/src/EthernetCompat.h +++ b/libraries/lwIP_Ethernet/src/EthernetCompat.h @@ -97,5 +97,4 @@ class ArduinoEthernet : public LwipIntfDev { using ArduinoWiznet5500lwIP = ArduinoEthernet; using ArduinoWiznet5100lwIP = ArduinoEthernet; -using ArduinoWiznet55rp20lwIP = ArduinoEthernet; using ArduinoENC28J60lwIP = ArduinoEthernet; From ed80fc617dc77496f1cf9bb13241eacec1d5d7ac Mon Sep 17 00:00:00 2001 From: Mason Date: Tue, 29 Oct 2024 08:54:56 +0900 Subject: [PATCH 6/6] Fixed compiler warnings --- libraries/lwIP_w55rp20/src/utility/w55rp20.cpp | 2 -- libraries/lwIP_w55rp20/src/wiznet_pio_spi.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/lwIP_w55rp20/src/utility/w55rp20.cpp b/libraries/lwIP_w55rp20/src/utility/w55rp20.cpp index 7a5caeefa..332d470ba 100644 --- a/libraries/lwIP_w55rp20/src/utility/w55rp20.cpp +++ b/libraries/lwIP_w55rp20/src/utility/w55rp20.cpp @@ -63,7 +63,6 @@ uint16_t Wiznet55rp20::wizchip_read_word(uint8_t block, uint16_t address) { } void Wiznet55rp20::wizchip_read_buf(uint8_t block, uint16_t address, uint8_t* pBuf, uint16_t len) { - uint16_t i; uint8_t spi_data[3]; wizchip_cs_select(); @@ -102,7 +101,6 @@ void Wiznet55rp20::wizchip_write_word(uint8_t block, uint16_t address, uint16_t void Wiznet55rp20::wizchip_write_buf(uint8_t block, uint16_t address, const uint8_t* pBuf, uint16_t len) { - uint16_t i; uint8_t spi_data[3]; wizchip_cs_select(); diff --git a/libraries/lwIP_w55rp20/src/wiznet_pio_spi.c b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.c index dd00cf790..394cda108 100644 --- a/libraries/lwIP_w55rp20/src/wiznet_pio_spi.c +++ b/libraries/lwIP_w55rp20/src/wiznet_pio_spi.c @@ -76,7 +76,7 @@ static void wiznet_pio_spi_gpio_setup(wiznet_pio_spi_state_t *state) { wiznet_pio_spi_handle_t wiznet_pio_spi_open(const wiznet_pio_spi_config_t *wiznet_pio_spi_config) { wiznet_pio_spi_state_t *state; - for (int i = 0; i < count_of(wiznet_pio_spi_state); i++) { + for (unsigned int i = 0; i < count_of(wiznet_pio_spi_state); i++) { if (!wiznet_pio_spi_state[i].funcs) { state = &wiznet_pio_spi_state[i]; break;