diff --git a/CMakeLists.txt b/CMakeLists.txt index 32588a7..9551912 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,13 +11,31 @@ pico_sdk_init() add_executable(picomap picomap.cpp + lib/w6300/wizchip_spi.c + lib/w6300/wizchip_qspi_pio.c + lib/w6300/ioLibrary/wizchip_conf.c + lib/w6300/ioLibrary/W6300/w6300.c + lib/w6300/ioLibrary/socket.c ) -target_include_directories(picomap PRIVATE include) +target_include_directories(picomap PRIVATE + include + lib/w6300 + lib/w6300/ioLibrary + lib/w6300/ioLibrary/W6300 +) + +target_compile_definitions(picomap PRIVATE + _WIZCHIP_=W6300 + DEVICE_BOARD_NAME=W6300_EVB_PICO2 + _WIZCHIP_QSPI_MODE_=QSPI_QUAD_MODE +) + +pico_generate_pio_header(picomap ${CMAKE_CURRENT_LIST_DIR}/lib/w6300/wizchip_qspi_pio.pio) pico_enable_stdio_usb(picomap 1) pico_enable_stdio_uart(picomap 0) pico_add_extra_outputs(picomap) -target_link_libraries(picomap pico_stdlib) +target_link_libraries(picomap pico_stdlib hardware_pio hardware_spi hardware_dma hardware_clocks) diff --git a/lib/w6300/board_list.h b/lib/w6300/board_list.h new file mode 100644 index 0000000..f8ffe80 --- /dev/null +++ b/lib/w6300/board_list.h @@ -0,0 +1,11 @@ +/* Board list */ +#define WIZnet_Ethernet_HAT 0 +#define W5100S_EVB_PICO 1 +#define W5500_EVB_PICO 2 +#define W55RP20_EVB_PICO 3 +#define W5100S_EVB_PICO2 4 +#define W5500_EVB_PICO2 5 +#define W6100_EVB_PICO 6 +#define W6100_EVB_PICO2 7 +#define W6300_EVB_PICO 8 +#define W6300_EVB_PICO2 9 \ No newline at end of file diff --git a/lib/w6300/ioLibrary/W6300/w6300.c b/lib/w6300/ioLibrary/W6300/w6300.c new file mode 100644 index 0000000..1c8192a --- /dev/null +++ b/lib/w6300/ioLibrary/W6300/w6300.c @@ -0,0 +1,273 @@ +//***************************************************************************** +// +//! \file W6300.c +//! \brief W6300 HAL Implements file. +//! \version 1.0.0 +//! \date 2019/01/01 +//! \par Revision history +//! <2019/01/01> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2019, WIZnet Co., LTD. +//! +//! Permission is hereby granted, free of charge, to any person obtaining a copy +//! of this software and associated documentation files (the "Software"), to deal +//! in the Software without restriction, including without limitation the rights +//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//! copies of the Software, and to permit persons to whom the Software is +//! furnished to do so, subject to the following conditions: +//! +//! The above copyright notice and this permission notice shall be included in +//! all copies or substantial portions of the Software. +//! +//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +//! SOFTWARE. +//! +//***************************************************************************** + +#include "w6300.h" + + +#if 0 +#define _WIZCHIP_SPI_VDM_OP_ 0x00 +#define _WIZCHIP_SPI_FDM_LEN1_ 0x01 +#define _WIZCHIP_SPI_FDM_LEN2_ 0x02 +#define _WIZCHIP_SPI_FDM_LEN4_ 0x03 +#endif +// +// If you want to use SPI FDM mode, Feel free contact to WIZnet. +// http://forum.wiznet.io +// + +#if _WIZCHIP_ == 6300 +//////////////////////////////////////////////////////////////////////////////////////// + + +#define _W6300_SPI_OP_ _WIZCHIP_SPI_VDM_OP_ +#define _W6300_SPI_READ_ (0x00 << 5) ///< SPI interface Read operation in Control Phase +#define _W6300_SPI_WRITE_ (0x01 << 5) ///< SPI interface Write operation in Control Phase + +////////////////////////////////////////////////// +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) { + + uint8_t opcode = 0; + uint16_t ADDR = 0; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if (_WIZCHIP_IO_MODE_ & 0xff00) & _WIZCHIP_IO_MODE_BUS_ + uint8_t tAD[4]; + tAD[0] = (uint8_t)((AddrSel & 0x00FF0000) >> 16); + tAD[1] = (uint8_t)((AddrSel & 0x0000FF00) >> 8); + tAD[2] = (uint8_t)(AddrSel & 0x000000ff); + tAD[3] = wb; + WIZCHIP.IF.BUS._write_data_buf(IDM_AR0, tAD, 4, 1); +#else //w6300 QSPI MODE + opcode = (uint8_t)((AddrSel & 0x000000FF) | (_W6300_SPI_WRITE_) | (_WIZCHIP_QSPI_MODE_)); + ADDR = (uint16_t)((AddrSel & 0x00ffff00) >> 8); + WIZCHIP.IF.QSPI._write_qspi(opcode, ADDR, &wb, 1); +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +uint8_t WIZCHIP_READ(uint32_t AddrSel) { + //uint8_t ret; + uint8_t ret[2] = {0,}; + uint8_t opcode = 0; + uint16_t ADDR = 0; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if (_WIZCHIP_IO_MODE_ & 0xff00) & _WIZCHIP_IO_MODE_BUS_ + uint8_t tAD[3]; + tAD[0] = (uint8_t)((AddrSel & 0x00FF0000) >> 16); + tAD[1] = (uint8_t)((AddrSel & 0x0000FF00) >> 8); + tAD[2] = (uint8_t)(AddrSel & 0x000000ff); + WIZCHIP.IF.BUS._write_data_buf(IDM_AR0, tAD, 3, 1); + ret[0] = WIZCHIP.IF.BUS._read_data(IDM_DR); +#else + opcode = (uint8_t)((AddrSel & 0x000000FF) | (_W6300_SPI_READ_) | (_WIZCHIP_QSPI_MODE_)); + ADDR = (uint16_t)((AddrSel & 0x00ffff00) >> 8); + WIZCHIP.IF.QSPI._read_qspi(opcode, ADDR, ret, 1); +#endif + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret[0]; +} + + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, datasize_t len) { + + uint8_t opcode = 0; + uint16_t ADDR = 0; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if (_WIZCHIP_IO_MODE_ & 0xff00) & _WIZCHIP_IO_MODE_BUS_ + uint8_t tAD[3]; + tAD[0] = (uint8_t)((AddrSel & 0x00FF0000) >> 16); + tAD[1] = (uint8_t)((AddrSel & 0x0000FF00) >> 8); + tAD[2] = (uint8_t)(AddrSel & 0x000000ff); + WIZCHIP.IF.BUS._write_data_buf(IDM_AR0, tAD, 3, 1); + WIZCHIP.IF.BUS._write_data_buf(IDM_DR, pBuf, len, 0); +#else + opcode = (uint8_t)((AddrSel & 0x000000FF) | (_W6300_SPI_WRITE_) | (_WIZCHIP_QSPI_MODE_)); + ADDR = (uint16_t)((AddrSel & 0x00ffff00) >> 8); + WIZCHIP.IF.QSPI._write_qspi(opcode, ADDR, pBuf, len);//by_lihan + //qspi_write_buf(opcode, ADDR, pBuf, len); + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +#endif +} + +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t* pBuf, datasize_t len) { + + uint8_t ret; + uint8_t opcode = 0; + uint16_t ADDR = 0; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ + uint8_t tAD[3]; + tAD[0] = (uint8_t)((AddrSel & 0x00FF0000) >> 16); + tAD[1] = (uint8_t)((AddrSel & 0x0000FF00) >> 8); + tAD[2] = (uint8_t)(AddrSel & 0x000000ff); + WIZCHIP.IF.BUS._write_data_buf(IDM_AR0, tAD, 3, 1); + WIZCHIP.IF.BUS._read_data_buf(IDM_DR, pBuf, len, 0); +#else + opcode = (uint8_t)((AddrSel & 0x000000FF) | (_W6300_SPI_READ_) | (_WIZCHIP_QSPI_MODE_)); + ADDR = (uint16_t)((AddrSel & 0x00ffff00) >> 8); + WIZCHIP.IF.QSPI._read_qspi(opcode, ADDR, pBuf, len);//by_lihan + //qspi_read_buf(opcode, ADDR, pBuf, len); + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +#endif +} + +uint16_t getSn_TX_FSR(uint8_t sn) { + uint16_t prev_val = -1, val = 0; + do { + prev_val = val; + val = WIZCHIP_READ(_Sn_TX_FSR_(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_TX_FSR_(sn), 1)); + } while (val != prev_val); + return val; +} + +uint16_t getSn_RX_RSR(uint8_t sn) { + uint16_t prev_val = -1, val = 0; + do { + prev_val = val; + val = WIZCHIP_READ(_Sn_RX_RSR_(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_RX_RSR_(sn), 1)); + } while (val != prev_val); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + ptr = getSn_TX_WR(sn); + addrsel = ((uint32_t)ptr << 8) + WIZCHIP_TXBUF_BLOCK(sn); + WIZCHIP_WRITE_BUF(addrsel, wizdata, len); + ptr += len; + setSn_TX_WR(sn, ptr); +} + +#if 0 +#define ETHERNET_BUF_MAX_SIZE_TEMP (1024 * 32 ) +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + if (len == 0) { + return; + } + ptr = getSn_RX_RD(sn); + + if (ptr + len > 0xFFFF) { + addrsel = ((uint32_t)ptr << 8) + WIZCHIP_RXBUF_BLOCK(sn); + uint16_t size = 0xFFFF - ptr; + WIZCHIP_READ_BUF(addrsel, wizdata, size); + wizdata += size; + size = len - size; + addrsel = WIZCHIP_RXBUF_BLOCK(sn); + WIZCHIP_READ_BUF(addrsel, wizdata, size); + } else { + addrsel = ((uint32_t)ptr << 8) + WIZCHIP_RXBUF_BLOCK(sn); + WIZCHIP_READ_BUF(addrsel, wizdata, len); + } + + ptr += len; + ptr %= 0xFFFF ; + + setSn_RX_RD(sn, ptr); +} + + +#else +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + if (len == 0) { + return; + } + ptr = getSn_RX_RD(sn); + addrsel = ((uint32_t)ptr << 8) + WIZCHIP_RXBUF_BLOCK(sn); + WIZCHIP_READ_BUF(addrsel, wizdata, len); + ptr += len; + setSn_RX_RD(sn, ptr); +} +#endif +void wiz_recv_ignore(uint8_t sn, uint16_t len) { + setSn_RX_RD(sn, getSn_RX_RD(sn) + len); +} + +#if 1 +// 20231019 taylor +void wiz_delay_ms(uint32_t milliseconds) { + uint32_t i; + for (i = 0 ; i < milliseconds ; i++) { + //Write any values to clear the TCNTCLKR register + setTCNTRCLR(0xff); + + // Wait until counter register value reaches 10.(10 = 1ms : TCNTR is 100us tick counter register) + while (getTCNTR() < 0x0a) {} + } +} +#endif + +/// @cond DOXY_APPLY_CODE +#if (_PHY_IO_MODE_ == _PHY_IO_MODE_MII_) +/// @endcond +void wiz_mdio_write(uint8_t phyregaddr, uint16_t var) { + setPHYRAR(phyregaddr); + setPHYDIR(var); + setPHYACR(PHYACR_WRITE); + while (getPHYACR()); //wait for command complete +} + +uint16_t wiz_mdio_read(uint8_t phyregaddr) { + setPHYRAR(phyregaddr); + setPHYACR(PHYACR_READ); + while (getPHYACR()); //wait for command complete + return getPHYDOR(); +} +/// @cond DOXY_APPLY_CODE +#endif +/// @endcond + +//////////////////////////////////////////////////////////////////////////////////////// +#endif diff --git a/lib/w6300/ioLibrary/W6300/w6300.h b/lib/w6300/ioLibrary/W6300/w6300.h new file mode 100644 index 0000000..240c7aa --- /dev/null +++ b/lib/w6300/ioLibrary/W6300/w6300.h @@ -0,0 +1,4103 @@ +//* **************************************************************************** +//! \file W6300.h +//! \brief W6300 HAL Header File. +//! \version 1.0.0 +//! \date 2019/01/01 +//! \par Revision history +//! <2019/01/01> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2019, WIZnet Co., LTD. +//! +//! Permission is hereby granted, free of charge, to any person obtaining a copy +//! of this software and associated documentation files (the "Software"), to deal +//! in the Software without restriction, including without limitation the rights +//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//! copies of the Software, and to permit persons to whom the Software is +//! furnished to do so, subject to the following conditions: +//! +//! The above copyright notice and this permission notice shall be included in +//! all copies or substantial portions of the Software. +//! +//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +//! SOFTWARE. +//! +//***************************************************************************** + + +#ifndef _W6300_H_ +#define _W6300_H_ + +#include +#include "wizchip_conf.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/// @cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == W6300) +/// @endcond + +#define _W6300_SPI_READ_ (0x00 << 5) ///< SPI interface Read operation in Control Phase +#define _W6300_SPI_WRITE_ (0x01 << 5) ///< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK (0x00 ) ///< Common register block +#define WIZCHIP_SREG_BLOCK(N) ((1+4*N)) ///< SOCKETn register block +#define WIZCHIP_TXBUF_BLOCK(N) ((2+4*N)) ///< SOCKETn Tx buffer address block +#define WIZCHIP_RXBUF_BLOCK(N) ((3+4*N)) ///< SOCKETn Rx buffer address block + +#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + (N<<8)) ///< Increase offset address + +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) +#define IDM_AR0 ((_WIZCHIP_IO_BASE_ + 0x0000)) ///< Indirect High Address Register +#define IDM_AR1 ((_WIZCHIP_IO_BASE_ + 0x0001)) ///< Indirect Low Address Register +#define IDM_BSR ((_WIZCHIP_IO_BASE_ + 0x0002)) ///< Block Select Register +#define IDM_DR ((_WIZCHIP_IO_BASE_ + 0x0003)) ///< Indirect Data Register +#define _W6300_IO_BASE_ _WIZCHIP_IO_BASE_ +#elif (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_) +#define IDM_AR0 ((_WIZCHIP_IO_BASE_ + 0x0000)) ///< Indirect High Address Register +#define IDM_AR1 ((_WIZCHIP_IO_BASE_ + 0x0001)) ///< Indirect Low Address Register +#define IDM_BSR ((_WIZCHIP_IO_BASE_ + 0x0002)) ///< Block Select Register +#define IDM_DR ((_WIZCHIP_IO_BASE_ + 0x0003)) ///< Indirect Data Register +#define _W6300_IO_BASE_ 0x00000000 +#define _W6100_IO_BASE_ 0x00000000 +#endif + + +//----------- defgroup -------------------------------- + +/** + @defgroup W6300 W6300 + @brief @ref _WIZCHIP_ register defines and I/O functions + @details + - @ref WIZCHIP_register_W6300 : @ref Common_register_group_W6300, @ref Socket_register_group_W6300 + - @ref WIZCHIP_IO_Functions_W6300 : @ref Basic_IO_function_W6300, @ref Common_register_access_function_W6300, @ref Socket_register_access_function_W6300 +*/ + +/** + @defgroup WIZCHIP_register_W6300 WIZCHIP register + @ingroup W6300 + @brief @ref WIZCHIP_register_W6300 defines register group of @b W6300. + @details + - @ref Common_register_group_W6300 : Common register group W6300 + - @ref Socket_register_group_W6300 : SOCKET n register group W6300 +*/ + +/** + @defgroup Basic_IO_function_W6300 Basic I/O function + @ingroup WIZCHIP_IO_Functions_W6300 + @brief These are basic input/output functions to read values from register or write values to register. +*/ + +/** + @defgroup Common_register_access_function_W6300 Common register access functions + @ingroup WIZCHIP_IO_Functions_W6300 + @brief These are functions to access @ref Common_register_group_W6300. +*/ + +/** + @defgroup Socket_register_access_function_W6300 Socket register access functions + @ingroup WIZCHIP_IO_Functions_W6300 + @brief These are functions to access @ref Socket_register_group_W6300. +*/ + +/** + @defgroup WIZCHIP_IO_Functions_W6300 WIZCHIP I/O functions + @ingroup W6300 + @brief @ref WIZCHIP_IO_Functions_W6300 supports the basic I/O functions for @ref WIZCHIP_register_W6300. + @details + - @ref WIZCHIP_IO_Functions_W6300 \n + WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + - @ref Common_register_access_function_W6300 \n + - @ref _WIZCHIP_ Mode \n + getCIDR(), getVER() \n + getSYSR() \n + setCHPLCKR(), setNETLCKR(), setPHYLCKR() \n + setSYCR0(), getSYCR1(), setSYCR1() + - Network Mode \n + getNET4MR(), setNET4MR(), getNET6MR(), setNET6MR(), getNETMR(), setNETMR(), getNETMR2(), setNETMR2() + - Interrupt \n + getIR(), setIRCLR(), getIMR(), setIMR() \n + getSIR(), getSIMR(), setSIMR() \n + getSLIR(), setSLIRCLR(), getSLIMR(), setSLIMR() \n + getINTPTMR(), setINTPTMR() + - Network Information \n + NETLOCK(), NETUNLOCK() \n + getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() \n + getLLAR(), setLLAR(), getGUAR(), setGUAR(), getGA6R(), setGA6R(), getSUB6R(), setSUB6R() \n + getPLR(), getPFR(), getVLTR(), getPLTR(), getPAR() \n + - SOCKET-less Commands for PING, ARP and IPv6 Auto-Configuration \n + getSLCR(), setSLCR() \n + getPINGIDR(), setPINGIDR(), getPINGSEQR(), setPINGSEQR() \n + getSLDHAR(), getSLDIPR(), setSLDIPR(), getSLDIP4R(), setSLDIP4R(), getSLDIP6R(), setSLDIP6R(), getSLHOPR(), setSLHOPR() \n + - Retransmission \n + getRCR(), setRCR() \n + getSLRCR(), setSLRCR(), getSLRTR(), setSLRTR() \n + - ICMP \n + getUIPR(), getUIP6R(), getUPORTR(), getUPORT6R() \n + getICMP6BLKR(), setICMP6BLKR() \n + - PPPoE \n + getPTMR(), setPTMR(), getPMNR(), getPMNR() \n + getPHAR(), setPHAR(), getPSIDR(), setPSIDR(), getPMRUR(), setPMRUR() + - PHY Configuration \n + getPHYSR(), setPHYLCKR(), PHYLOCK(), PHYUNLOCK() \n + setPHYCR0(), getPHYCR1(), setPHYCR1() \n + getPHYRAR(), setPHYRAR(), setPHYDIR(), getPHYDOR(), getPHYACR(), setPHYACR(), getPHYDIVR(), setPHYDIVR() + - etc \n + getTCNTR(), setTCNTRCLR() + - @ref Socket_register_access_function_W6300 \n + - SOCKET control \n + getSn_MR(), setSn_MR(), getSn_MR2(), setSn_MR2(), getSn_PSR(), setSn_PSR(), getSn_CR(), setSn_CR() \n + getSn_IR(), setSn_IRCLR(), getSn_IMR(), setSn_IMR() \n + getSn_RTR(), setSn_RTR(), getSn_RCR(), setSn_RCR(), getSn_KPALVTR(), setSn_KPALVTR() + - SOCKET information \n + getSn_SR(), getSn_ESR() \n + getSn_DHAR(), setSn_DHAR(), getSn_PORTR(), setSn_PORTR(), getSn_DPORTR(), setSn_DPORTR() \n + getSn_DIPR(), setSn_DIPR(), getSn_DIP6R(), setSn_DIP6R() \n + getSn_MSSR(), setSn_MSSR() + - SOCKET communication \n + getSn_RX_BSR(), setSn_RX_BSR(), getSn_TX_BSR(), setSn_TX_BSR() \n + getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + getSn_TX_FSR(), getSn_RX_RSR() + - IP header field \n + getSn_FRGR(), setSn_FRGR(), getSn_TOSR(), setSn_TOSR() \n + getSn_TTLR(), setSn_TTLR() +*/ + +/** + @defgroup Common_register_group_W6300 Common register + @ingroup WIZCHIP_register_W6300 + @brief Common register group \n + @details It set the general configuration such as interrupt, network information, ICMP, and etc. + @sa + + + + + + + + + + + + +
@ref _WIZCHIP_ Information : _CIDR_, _VER_
@ref _WIZCHIP_ Mode : _SYSR_, _SYCR0_, _SYCR1_, _CHPLCKR_, _NETLCKR_, _PHYLCKR_
Network Mode : _NET4MR_, _NET6MR_, _NETMR_, _NETMR2_
Network Information : _GAR_, _SUBR_, _SHAR_, _SIPR_, _GA6R_, _LLAR_, _GUAR_, _SUB6R_
Interrupt : _IR_, _IRCLR_, _IMR_, _SIR_, _SIMR_, _SLIR_, _SLIMR_, _SLIRCLR_, _INTPTMR_
Data retransmission : _RTR_, _RCR_, _SLRTR_, _SLRCR_, _SLHOPR_
PPPoE : _PHAR_, _PSIDR_, _PMRUR_, _PTMR_, _PMNR_
SOCKET-less command : _SLCR_, _SLIR_, _SLDIPR_, _SLDIP4R_, _SLDIP6R_, _SLDHAR_, _PINGIDR_, _PINGSEQR_
ICMP v4 & v6 : _UIPR_, _UPORTR_, _UIP6R_, _UPORT6R_, _ICMP6BLKR_
IPv6 Auto-configuration : _PLR_, _PFR_, _VLTR_, _PAR_
PHY Configuration : _PHYSR_, _PHYCR0_, _PHYCR1_, _PHYRAR_, _PHYDIR_, _PHYDOR_, _PHYACR_, _PHYDIVR_
+*/ + + +/** + @defgroup Socket_register_group_W6300 Socket register + @ingroup WIZCHIP_register_W6300 + @brief Socket register group\n + @details + SOCKETn registers configure and control SOCKETn which is necessary to data communication. + @sa + + + + + + +
SOCKETn Control : _Sn_MR_, _Sn_MR2_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_IMR_, _Sn_PSR_
SOCKETn Information : _Sn_SR_, _Sn_ESR_, _Sn_PORTR_, _Sn_DHAR_, _Sn_DIPR_, _Sn_DIP6R_, _Sn_DPORTR_
SOCKETn Retransmission : _Sn_RTR_, _Sn_RCR_
Internet protocol : _Sn_MSSR_, _Sn_TOSR_, _Sn_TTLR_, _Sn_FRGR_
Data communication : _Sn_RX_BSR_, _Sn_TX_BSR_, _Sn_TX_FSR_, _Sn_TX_RD_, _Sn_TX_WR_, _Sn_RX_RSR_, _Sn_RX_RD_, _Sn_RX_WR_
+*/ + +//----------------------------------------------------------------------------------- + +//----------------------------- W6300 Common Registers IOMAP ----------------------------- + +/** + @addtogroup Common_register_group_W6300 + @{ +*/ + +/** + @brief Chip Identification Register address [RO] [0x6100] + @sa getCIDR() +*/ +#define _CIDR_ (_W6300_IO_BASE_ + (0x0000 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Chip Identification Register address [RO] [0x11] + @sa getRTL() +*/ +#define _RTL_ (_W6300_IO_BASE_ + (0x0004 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Chip Version Register address [RO] [0x4661] + @sa getVER() +*/ +#define _VER_ (_W6300_IO_BASE_ + (0x0002 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief System Status Register address [RO] [0xEU] + @details @ref _SYSR_ shows the information such as CHIP, NET, PHY Locking and Host I/F + + + +
7 6 5 4 ~ 2 1 0
CHPL NETL PHYL Reserved IND SPI
+ - @ref SYSR_CHPL + - @ref SYSR_NETL + - @ref SYSR_PHYL + - @ref SYSR_IND : HOST use Parallel BUS Interface(Indirect Bus Mode) + - @ref SYSR_SPI : HOST use SPI Interface + + @sa _CHPLCKR_, _NETLCKR_, _PHYLCKR_, + @sa getSYSR(), setCHPLCKR(), getCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), setNETLCKR(), getNETLCKR(), NETLOCK(), NETUNLOCK() \n + setPHYLCKR(), getPHYLCKR(), PHYLOCK(), PHYUNLOCK() +*/ +#define _SYSR_ (_W6300_IO_BASE_ + (0x2000 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief System Config Register 0 address [WO][0x80] + @details @ref _SYCR0_ softly reset to _WIZCHIP_. + + + +
7 6 ~ 0
RST Reserved
+ - @ref SYCR0_RST : Software Reset. + + @note It can be accessed only when @ref SYSR_CHPL = 1. + @sa _CHPLCKR_, _SYSR_, SYSR_CHPL + @sa setSYCR0(), setCHPLCKR(), getCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _SYCR0_ (_W6300_IO_BASE_ + (0x2004 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief System Config Register 1 address [R=W][0x80] + @details @ref _SYCR1_ controls the global interrupt enable, and selects the system clock. + + + +
7 6 ~ 1 0
IEN Reserved CLKSEL
+ - @ref SYCR1_IEN + - @ref SYCR1_CLKSEL + + @note SYCR1_CLKSEL bit can be accessed only when @ref SYSR_CHPL = 1. + @sa _CHPLCKR_, _SYSR_, SYSR_CHPL + @sa getSYCR1(), setSYCR1(), setCHPLCKR(), getCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _SYCR1_ (WIZCHIP_OFFSET_INC(_SYCR0_,1)) + +/** + @brief Ticker Counter Register address [RO][0x0000] + @details @ref _TCNTR_ increase by 1 every 100us after _WIZCHIP_ reset. + @sa _TCNTRCLR_ + @sa getTCNTR(), setTCNTRCLR() +*/ +#define _TCNTR_ (_W6300_IO_BASE_ + (0x2016 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Ticker Counter Clear Register address [RO][0x00] + @details @ref _TCNTRCLR_ clear @ref _TCNTR_. + @sa setTCNTRCLR(), getTCNTR() +*/ +#define _TCNTRCLR_ (_W6300_IO_BASE_ + (0x2020 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Interrupt Register address [RO][0x00] + @details @ref _IR_ indicates the interrupt status. + If @ref _IR_ is not equal to x00 INTn PIN is asserted to low until it is x00. + + + + +
7 6 ~ 5 4 3 2 1 0
WOL Reserved UNR6 Reserved IPCONF UNR4 PTERM
+ - @ref IR_WOL : Wake On LAN + - @ref IR_UNR6 : Destination Port Unreachable for IPv6 + - @ref IR_IPCONF : @ref _SIPR_ is Conflict + - @ref IR_UNR4 : Destination Port Unreachable for IPv4 + - @ref IR_PTERM : PPPoE Terminated + + @sa _IMR_, _IRCLR_, SYCR1_IEN, _CHIPLCKR_, _SYSR_, SYSR_CHPL + @sa getIR(), setIRCLR(), getSYCR1(), setSYCR1(), getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _IR_ (_W6300_IO_BASE_ + (0x2100 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET Interrupt Register address [RO][0x00] + @details @ref _SIR_ indicates whether a socket interrupt is occurred or not.\n + Each bit of @ref _SIR_ be still until @ref _Sn_IR_ is cleared by @ref _Sn_IRCLR_ + @sa _SIMR_, _Sn_IR_, _Sn_IRCLR_, _Sn_IMR_, SYCR1_IEN , _CHIPLCKR_, _SYSR_, SYSR_CHPL + @sa getSIR(), getSn_IR(), setSn_IRCLR(), getSIMR(), setSIMR(), getSn_IMR(), setSn_IMR(), getSYCR1(), setSYCR1(), \n + getSYCR1(), setSYCR1(), getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _SIR_ (_W6300_IO_BASE_ + (0x2101 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Interrupt Register address [RO][0x00] + @details @ref _SLIR_ indicates the completion of @ref _SLCR_ or timeout. + + + +
7 6 5 4 3 2 1 0
TOUT ARP4 PING4 ARP6 PING6 NS RS RA
+ - @ref SLIR_TOUT : The timeout occurrence after @ref _SLCR_ is performed + - @ref SLIR_ARP4 : The completion of @ref SLCR_ARP4 + - @ref SLIR_PING4 : The completion of @ref SLCR_PING4 + - @ref SLIR_ARP6 : The completion f @ref SLCR_ARP6 + - @ref SLIR_PING6 : The completion of @ref SLCR_PING6 + - @ref SLIR_NS : The completion of @ref SLCR_NS + - @ref SLIR_RS : The completion of @ref SLIR_RS + - @ref SLIR_RA : The reception from Router Advertisement + + @sa _SLIRCLR_, _SLIMR_, SYCR1_IEN, _CHPLCKR_, _SYSR_, SYSR_CHPL + @sa getSLIR(), setSLIRCLR(), getSLIR(), getSLIMR(), setSLIMR(), \n + getSYCR1(), setSYCR1(), getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _SLIR_ (_W6300_IO_BASE_ + (0x2102 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Interrupt Mask Register address [R=W][0x00] + @details @ref _IMR_ is used to mask interrupts of @ref _IR_.\n + When a bit of @ref _IMR_ and the corresponding bit of @ref _IR_ is set, an interrupt will be issued. + @sa _IR_, SYCR1_IEN, _CHPLCKR_, _SYSR_, SYSR_CHPL + @sa getIMR(), setIMR(), getIR(), setIRCLR(), \n + getSYCR1(), setSYCR1(), getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _IMR_ (_W6300_IO_BASE_ + (0x2104 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief @ref _IR_ Clear Register address [WO][0x00] + @details @ref _IRCLR_ clears @ref _IR_ + @sa _IR_, _IMR_, SYCR1_IEN, _CHPLCKR_, _SYSR_, SYSR_CHPL + @sa setIRCLR(), getIR(), getIMR(), getSYCR1(), setSYCR1(), getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _IRCLR_ (_W6300_IO_BASE_ + (0x2108 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET Interrupt Mask Register address [R=W]][0x00] + @details @ref _SIMR_ is used to mask interrupts of @ref _SIR_.\n + When a bit of @ref _SIMR_ and the corresponding bit of @ref _SIR_ is set, an interrupt will be issued.\n + when @ref _Sn_IR_ is not 0, The N-th bit of @ref _SIR_ is set. Otherwise, this bit is automatically clear.\n + @sa _SIR_, _Sn_IR_, _Sn_IRCLR_, _Sn_IMR_, SYCR1_IEN, _CHPLCKR_, _SYSR_, SYSR_CHPL + @sa getSIMR(), setSIMR(), getSIR(), setSn_IRCLR(), getSn_IMR(), setSn_IMR(), \n + getSYCR1(), setSYCR1(), getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _SIMR_ (_W6300_IO_BASE_ + (0x2114 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Interrupt Mask Register address [R=W][0x00] + @details @ref _SLIMR_ is used to mask interrupts of @ref _SLIR_\n + When a bit of @ref _SLIMR_ and the corresponding bit of @ref _SLIR_ is set, an interrupt will be issued. + @sa _SLIR_, _SLIRCLR_, SYCR1_IEN, _CHPLCKR_, _SYSR_, SYSR_CHPL + @sa getSLIMR(), setSLIMR(), getSLIR(), setSLIRCLR(), \n + getSYCR1(), setSYCR1(), getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _SLIMR_ (_W6300_IO_BASE_ + (0x2124 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Interrupt Clear Register address [WO][0x00] + @details @ref _SLIRCLR_ clears @ref _SLIR_ + @sa _SLIR_, _SLIRCLR_, _SLIMR_, SYCR1_IEN, _CHPLCKR_, _SYSR_, SYSR_CHPL + @sa getSLIR(), setSLIRCLR(), getSLIMR(), setSLIMR(), \n + getSYCR1(), setSYCR1(), getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _SLIRCLR_ (_W6300_IO_BASE_ + (0x2128 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Prefer Source IPv6 Address Register address [R=W][0x00] + @details @ref _SLPSR_ select the Source IPv6 Address to transmit a packet by @ref _SLCR_. + - @ref PSR_AUTO + - @ref PSR_LLA + - @ref PSR_GUA + @sa _SLCR_, _Sn_PSR_ + @sa getSLPSR(), setSLPSR(), getSLCR(), setSLCR(), getSn_PSR(), setSn_PSR() +*/ +#define _SLPSR_ (_W6300_IO_BASE_ + (0x212C << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Command Register address [RW,AC][0x00] + @details @ref _SLCR_ can be request a message such like as ARP, PING, and ICMPv6 without SOCKET. + + + +
7 6 5 4 3 2 1 0
Reserved ARP4 PING4 ARP6 PING6 NS RS UNA
+ - @ref SLCR_ARP4 + - @ref SLCR_PING4 + - @ref SLCR_ARP6 + - @ref SLCR_PING6 + - @ref SLCR_NS + - @ref SLCR_RS + - @ref SLCR_UNA + + @sa _SLIR_, _SLIMR_, _SLDIPR_, _SLDIP4R_, _SLDIP6R_, _SLDHAR_, SYCR1_IEN, _CHPLCKR_, _SYSR_, SYSR_CHPL + @sa getSLCR(), setSLCR(), getSLIR(), setSLIRCLR(), getSLIMR(), setSLIMR(), getSLDIPR(),setSLDIPR(), getSLDIP4R(),setSLDIP4R(), + getSLDIP6R(), setSLDIP6R(), getSLDHAR(), getSYCR1(), setSYCR1(), getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _SLCR_ (_W6300_IO_BASE_ + (0x2130 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PHY Status Register address [RO][0x00] + @details @ref _PHYSR_ shows the operation mode of PHY, the link status and etc. + - @ref PHYSR_CAB : @ref PHYSR_CAB_OFF, @ref PHYSR_CAB_ON + - @ref PHYSR_MODE : @ref PHYSR_MODE_AUTO, @ref PHYSR_MODE_100F, @ref PHYSR_MODE_100H, @ref PHYSR_MODE_10F, @ref PHYSR_MODE_10H + - @ref PHYSR_DPX : @ref PHYSR_DPX_FULL, @ref PHYSR_DPX_HALF + - @ref PHYSR_SPD : @ref PHYSR_SPD_100M, @ref PHYSR_SPD_10M + - @ref PHYSR_LNK : @ref PHYSR_LNK_UP, @ref PHYSR_LNK_DOWN + + @sa _PHYCR0_, _PHYLCKR_, _SYSR_, SYSR_PHYL + @sa getPHYSR(), setPHYCR0(), setPHYLCKR(), getPHYLCKR(), PHYLOCK(), PHYUNLOCK(), getSYSR() +*/ +#define _PHYSR_ (_W6300_IO_BASE_ + (0x3000 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PHY Internal Register Address Register address(R/W) + @details @ref _PHYRAR_ specifies the address of register in the Ethernet PHY. + - @ref PHYRAR_BMCR + - @ref PHYRAR_BMSR + @sa _PHYACR_, _PHYDOR_, _PHYDIR_, _PHYDIVR_ + @sa getPHYACR(), setPHYACR(), getPHYDOR(), setPHYDIR(), getPHYDIVR(), setPHYDIVR() +*/ +#define _PHYRAR_ (_W6300_IO_BASE_ + (0x3008 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PHY Data Input Register address [R=W][0x00] + @details @ref _PHYDIR_ specifies the value to write to the register in PHY + @sa _PHYRAR_, _PHYACR_, _PHYDOR_, _PHYDIVR_ + @sa setPHYDIR(), getPHYRAR(), setPHYRAR(), getPHYACR(), setPHYACR(), getPHYDOR(), setPHYDIR(), getPHYDIVR(), setPHYDIVR() +*/ +#define _PHYDIR_ (_W6300_IO_BASE_ + (0x300C << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PHY Data Output Register address [WO][0x00] + @details @ref _PHYDOR_ read the value from the register in PHY + @sa _PHYRAR_, _PHYACR_, _PHYDIR_, _PHYDIVR_ + @sa getPHYDOR(), getPHYRAR(), setPHYRAR(), getPHYACR(), setPHYACR(), setPHYDIR(), getPHYDIVR(), setPHYDIVR() +*/ +#define _PHYDOR_ (_W6300_IO_BASE_ + (0x3010 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PHY Access Register address [RW,AC][0x00] + @details @ref _PHYACR_ write(read) to(from) the value of register in the Ethernet PHY + - @ref PHYACR_READ + - @ref PHYACR_WRITE + @sa _PHYRAR_, _PHYDOR_, _PHYDIR_, _PHYDIVR_ + @sa getPHYACR(), setPHYACR(), getPHYDOR(), getPHYRAR(), setPHYRAR(), setPHYDIR(), getPHYDIVR(), setPHYDIVR() +*/ +#define _PHYACR_ (_W6300_IO_BASE_ + (0x3014 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PHY's MDC Clock Division Register address [R=W][0x01] + @details @ref _PHYDIVR_ divides the system clock for the MDC clock of Ethernet PHY' + - @ref PHYDIVR_32 + - @ref PHYDIVR_64 + - @ref PHYDIVR_128 + @sa _PHYRAR_, _PHYACR_, _PHYDOR_, _PHYDIR_, _PHYDIVR_ + @sa getPHYDIVR(), setPHYDIVR(), getPHYRAR(), setPHYRAR(), getPHYACR(), setPHYACR(), getPHYDOR(), setPHYDIR() +*/ +#define _PHYDIVR_ (_W6300_IO_BASE_ + (0x3018 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PHY Control Register address [WO][0x00] + @details @ref _PHYCR0_ controls the operation mode of PHY. + The result will be checked by @ref _PHYSR_ after PHY HW reset by @ref PHYCR1_RST. + - @ref PHYCR0_AUTO + - @ref PHYCR0_100F + - @ref PHYCR0_100H + - @ref PHYCR0_10F + - @ref PHYCR0_10H + + @note It can be only accessed when @ref SYSR_PHYL is unlock. + @sa _SYSR_, _PHYCR1_ + @sa setPHYCR0(), getSYSR(), getPHYCR1(), setPHYCR1() +*/ +#define _PHYCR0_ (_W6300_IO_BASE_ + (0x301C << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PHY Control Register address [R=W][0x40] + @details @ref _PHYCR1_ controls the Ethernet PHY function such as HW reset, Power down and etc. + + + +
7 6 5 4 3 2 ~ 1 0
Reserved Always 1 PWDN Reseved TE Reserved RST
+ - @ref PHYCR1_PWDN + - @ref PHYCR1_TE + - @ref PHYCR1_RST + + @note It can be only accessed when @ref SYSR_PHYL is unlock. + @sa _SYSR_, _PHYCR0_ + @sa getPHYCR1(), setPHYCR1(), setPHYCR0(), getSYSR() +*/ +#define _PHYCR1_ WIZCHIP_OFFSET_INC(_PHYCR0_,1) + +/** + @brief Network IPv4 Mode Register address [R=W][0x00] + @details @ref _NET4MR_ can block the transmission such like as unreachable message, TCP reset, and ping relay.\n + It can ARP request before ping relpy. + + + + +
7 ~ 4 3 2 1 0
Reserved UNRB PARP RSTB PB
+ - @ref NETxMR_UNRB + - @ref NETxMR_PARP + - @ref NETxMR_RSTB + - @ref NETxMR_PB + @sa _NET6MR_ + @sa getNET4MR(), setNET4MR(), getNET6MR(), setNET6MR() +*/ +#define _NET4MR_ (_W6300_IO_BASE_ + (0x4000 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Network IPv6 Mode Register address [R=W][0x00] + @details @ref _NET6MR_ can block the transmission such like as unreachable message, TCP reset, and ping relay.\n + It can ARP request before ping reply. + + + + +
7 ~ 4 3 2 1 0
Reserved UNRB PARP RSTB PB
+ - @ref NETxMR_UNRB + - @ref NETxMR_PARP + - @ref NETxMR_RSTB + - @ref NETxMR_PB + @sa _NET4MR_ + @sa getNET6MR(), setNET6MR(), getNET4MR(), setNET4MR() +*/ +#define _NET6MR_ (_W6300_IO_BASE_ + (0x4004 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Network Mode Register address [R=W][0x00] + @details @ref _NETMR_ set WOL(Wake On Lan) mode.\n + It also can block a packet such as \n + IPv6 PING request from an all-node broadcasting, \n + IPv6 PING request from a solicited mulitcasting address,\n + IPv4 packets, \n + and IPv6 packets. + + + + +
7 ~ 6 5 4 3 2 1 0
Reserved ANB M6B Always 0 WOL IP6B IP4B
+ - @ref NETMR_ANB + - @ref NETMR_M6B + - @ref NETMR_WOL + - @ref NETMR_IP6B + - @ref NETMR_IP4B + @sa getNETMR(), setNETMR() + +*/ +#define _NETMR_ (_W6300_IO_BASE_ + (0x4008 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Network Mode Register 2 address [R=W][0x00] + @details @ref _NETMR2_ set PPPoE mode.\n + It also can select the destination hardware address to either Ethernet frame MAC or target MAC in the ARP-reply message + + + +
7 6 ~ 1 0
DHAS 6 ~ 1 PPPoE
+ - @ref NETMR2_DHAS : @ref NETMR2_DHAS_ARP, @ref NETMR2_DHAS_ETH + - @ref NETMR2_PPPoE + @sa getNETMR2(), setNETMR2() +*/ +#define _NETMR2_ (_W6300_IO_BASE_ + (0x4009 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PPP LCP request Timer Register address [R=W][0x28] + @details @ref _PTMR_ sets the time for sending LCP echo request.\n + The unit of time is 25ms. + @sa _PMNR_, _PHAR_, _PSIDR_, _PMRUR_, NETMR2_PPPoE + @sa getPTMR(), setPTMR(), getPMNR(), setPMNR(), getPHAR(), setPHAR(), getPSIDR(), setPSIDR(), getPMRUR(), setPMRUR(), getNETMR2(), setNETMR2() +*/ +#define _PTMR_ (_W6300_IO_BASE_ + (0x4100 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PPP LCP Magic Number Register address [R=W][0x00] + @details @ref _PMNR_ sets the 4bytes magic number to be used in LCP negotiation. + @sa _PTMR_, _PHAR_, _PSIDR_, _PMRUR_, NETMR2_PPPoE + @sa getPMNR(), setPMNR(), getPTMR(), setPTMR(), getPHAR(), setPHAR(), getPSIDR(), setPSIDR(), getPMRUR(), setPMRUR(), getNETMR2(), setNETMR2() +*/ +#define _PMNR_ (_W6300_IO_BASE_ + (0x4104 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PPPoE Hardware Address Register address [R=W][0x00] + @details @ref _PHAR_ sets the PPPoE server hardware address that is acquired during PPPoE connection process. + @sa _PTMR_, _PMNR_, _PSIDR_, _PMRUR_, NETMR2_PPPoE + @sa getPHAR(), setPHAR(), getPTMR(), setPTMR(), getPMNR(), setPMNR(), getPSIDR(), setPSIDR(), getPMRUR(), setPMRUR(), getNETMR2(), setNETMR2() +*/ +#define _PHAR_ (_W6300_IO_BASE_ + (0x4108 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PPP Session ID Register address [R=W][0X0000] + @details @ref _PSIDR_ sets the PPPoE sever session ID acquired during PPPoE connection process. + @sa _PTMR_, _PMNR_, _PHAR_, _PMRUR_, NETMR2_PPPoE + @sa getPSIDR(), setPSIDR(), getPTMR(), setPTMR(), getPMNR(), setPMNR(), getPHAR(), setPHAR(), getPMRUR(), setPMRUR(), getNETMR2(), setNETMR2() +*/ +#define _PSIDR_ (_W6300_IO_BASE_ + (0x4110 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PPP Maximum Receive Unit Register address [R=W][0xFFFF] + @details @ref _PMRUR_ sets the maximum receive unit of PPPoE. + @sa _PTMR_, _PMNR_, _PHAR_, _PSIDR_, NETMR2_PPPoE + @sa getPMRUR(), setPMRUR(), getPTMR(), setPTMR(), getPMNR(), setPMNR(), getPHAR(), setPHAR(), getPSIDR(), setPSIDR(), getNETMR2(), setNETMR2() +*/ +#define _PMRUR_ (_W6300_IO_BASE_ + (0x4114 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Source Hardware Address Register address [R=W][00:00:00:00:00:00] + @details @ref _SHAR_ sets the source hardware address. + @note It can be accessed only when @ref SYSR_NETL is unlock. + @sa SYSR_NETL, _NETLCKR_ + @sa getSHAR(), setSHAR(), getSYSR(), setNETLCKR(), getNETLCKR(), NETLOCK(), NETUNLOCK() +*/ +#define _SHAR_ (_W6300_IO_BASE_ + (0x4120 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief IPv4 Gateway Address Register address [R=W][0.0.0.0] + @details @ref _GAR_ sets the default gateway IPv4 address. + @note It can be accessed only when @ref SYSR_NETL is unlock. + @sa SYSR_NETL, _NETLCKR_, _GA6R_ + @sa getGAR(), setGAR(), getSYSR(), setNETLCKR(), getNETLCKR(), NETLOCK(), NETUNLOCK(), getGA6R(), setGA6R() +*/ +#define _GAR_ (_W6300_IO_BASE_ + (0x4130 << 8) + WIZCHIP_CREG_BLOCK) +#define _GA4R_ (_GAR_) ///< Refer to @ref _GAR_ +/** + @brief IPv4 Subnet Mask Register address [R=W][0.0.0.0] + @details @ref _SUBR_ sets the default subnet mask address of IPv4. + @note It can be accessed only when @ref SYSR_NETL is unlock. + @sa SYSR_NETL, _NETLCKR_, _SUB6R_ + @sa getSUBR(), setSUBR(), getSYSR(), setNETLCKR(), getNETLCKR(), NETLOCK(), NETUNLOCK(), getSUB6R(), setSUB6R() +*/ +#define _SUBR_ (_W6300_IO_BASE_ + (0x4134 << 8) + WIZCHIP_CREG_BLOCK) +#define _SUB4R_ (_SUBR_) ///< Refer to @ref _SUBR_ + +/** + @brief IPv4 Source IP Register address [R=W][0.0.0.0] + @details @ref _SIPR_ sets the source IPv4 address. + @note It can be accessed only when @ref SYSR_NETL is unlock. + @sa SYSR_NETL, _NETLCKR_, _LLAR_, _GUAR_ + @sa getSIPR(), setSIPR(), getSYSR(), setNETLCKR(), getNETLCKR(), NETLOCK(), NETUNLOCK(), getLLAR(), setLLAR(), getGUAR(),setGUAR() +*/ +#define _SIPR_ (_W6300_IO_BASE_ + (0x4138 << 8) + WIZCHIP_CREG_BLOCK) +#define _SIP4R_ (_SIPR_) ///< Refer to @ref _SIPR_. + +/** + @brief IPv6 LLA(Link Local Address) Register address [R=W][::] + @details @ref _LLAR_ sets the LLA address of IPv6. + @note It can be accessed only when @ref SYSR_NETL is unlock. + @sa SYSR_NETL, _NETLCKR_, _GUAR_, _SIPR_ + @sa getLLAR(), setLLAR(), getSYSR(), setNETLCKR(), getNETLCKR(), NETLOCK(), NETUNLOCK(), getGUAR(),setGUAR(), getSIPR(), setSIPR() +*/ +#define _LLAR_ (_W6300_IO_BASE_ + (0x4140 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief IPv6 GUA(Global Unicast Address) Register address [R=W][::] + @details @ref _GUAR_ sets the GUA address of IPv6. + @note It can be accessed only when @ref SYSR_NETL is unlock. + @sa SYSR_NETL, _NETLCKR_, _LLAR_, _SIPR_ + @sa getGUAR(), setGUAR(), getSYSR(), setNETLCKR(), getNETLCKR(), NETLOCK(), NETUNLOCK(), getLLAR(),setLLAR(), getSIPR(), setSIPR() +*/ +#define _GUAR_ (_W6300_IO_BASE_ + (0x4150 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief IPv6 Subnet Mask Register address [R=W][] + @details @ref _SUB6R_ sets the default subnet mask address of IPv6. + @note It can be accessed only when @ref SYSR_NETL is unlock. + @sa SYSR_NETL, _NETLCKR_, _SUBR_ + @sa getSUB6R(), setSUB6R(), getSYSR(), setNETLCKR(), getNETLCKR(), NETLOCK(), NETUNLOCK(), getSUBR(), setSUBR() +*/ +#define _SUB6R_ (_W6300_IO_BASE_ + (0x4160 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief IPv6 Gateway Address Register address [R/W][::] + @details @ref _GA6R_ sets the default gateway IPv6 address. + @sa _GAR_ + @sa getGA6R(), setGA6R(), getGAR(), setGAR() +*/ +#define _GA6R_ (_W6300_IO_BASE_ + (0x4170 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Peer IPv6 Register address [R=W][::] + @details @ref _SLDIP6R_ sets the destination IP address of @ref _SLCR_. + @sa _SLDIP6R_, _SLCR_, _SLIR_, _SLIRCLR_, _SLIMR_, _SLDHAR_, _SLDIPR_, _SLDIP4R_ + @sa getSLDIP6R(), setSLDIP6R(), getSLCR(), setSLCR(), getSLIR(), setSLIRCLR(), getSLIMR(), setSLIMR(), getSLDHAR(), + getSLDIPR(), setSLDIPR(), getSLDIP4R(), setSLDIP4R() +*/ +#define _SLDIP6R_ (_W6300_IO_BASE_ + (0x4180 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Peer IPv6 Register address [R=W][0.0.0.0] + @details @ref _SLDIPR_(= @ref _SLDIP4R_) sets the destination IPv4 address of @ref _SLCR_. + @sa _SLDIP4R_, _SLCR_, _SLIR_, _SLIRCLR_, _SLIMR_, _SLDHAR_, _SLDIP6R_ + @sa getSLDIPR(), setSLDIPR(), getSLDIP4R(), setSLDIP4R(), getSLCR(), setSLCR(), getSLIR(), setSLIRCLR(), getSLIMR(), setSLIMR(), getSLDHAR(), + getSLDIP6R(), setSLDIP6R() +*/ +#define _SLDIPR_ (_W6300_IO_BASE_ + (0x418C << 8) + WIZCHIP_CREG_BLOCK) +#define _SLDIP4R_ (_SLDIPR_) ///< Refer to @ref _SLDIPR_. + + +/** + @brief SOCKET-less Peer Hardware Address Register address [RO][00:00:00:00:00:00] + @details @ref _SLDHAR_ gets the destination hardware address acquired by of @ref SLCR_ARP4, SLCR_ARP6, SLCR_PING4, and SLCR_PING6. + @sa _SLDIP4R_, _SLDIP6R_, _SLCR_, _SLIR_, _SLIRCLR_, _SLIMR_ + @sa getSLDHAR(), getSLDIP4R(), setSLDIP4R(), getSLDIP6R(), setSLDIP6R(), getSLCR(), setSLCR(), \n + getSLIR(), setSLIRCLR(), getSLIMR(), setSLIMR() +*/ +#define _SLDHAR_ (_W6300_IO_BASE_ + (0x4190 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Ping ID Register address [R=W][0x00] + @details @ref _PINGIDR_ sets the PING-request ID to be sent by @ref SLCR_PING4 or @ref SLCR_PING6. + @sa _SLCR_, _PINGSEQR_, _SLDIPR_, _SLDIP4R_, _SLDIP6R_, _SLDHAR_, _SLIR_, _SLIRCLR_, _SLIMR_ + @sa getPINGIDR(), setPINGIDR(), getSLCR(), setSLCR(), getPINGSEQR(), setPINGSEQR(), getSLDIPR(), setSLDIPR(), + getSLDIP4R(), setSLDIP4R(), getSLDIP6R(), setSLDIP6R(), getSLDHAR(), getSLIR(), setSLIRCLR(), getSLIMR(), setSLIMR() +*/ +#define _PINGIDR_ (_W6300_IO_BASE_ + (0x4198 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less ping Sequence number Register address [R=W][0x0000] + @details @ref _PINGIDR_ sets the PING-request sequence number to be sent by @ref SLCR_PING4 or @ref SLCR_PING6. + @sa _SLCR_, _PINGIDR_, _SLDIPR_, _SLDIP4R_, _SLDIP6R_, _SLDHAR_, _SLIR_, _SLIRCLR_, _SLIMR_ + @sa getPINGSEQR(), setPINGSEQR(), getSLCR(), setSLCR(), getPINGIDR(), setPINGIDR(), getSLDIPR(), setSLDIPR(), getSLDIP4R(), setSLDIP4R(), + getSLDIP6R(), setSLDIP6R(), getSLDHAR(), getSLIR(), setSLIRCLR(), getSLIMR(), setSLIMR() +*/ +#define _PINGSEQR_ (_W6300_IO_BASE_ + (0x419C << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief IPv4 Unreachable Address Register address [RO][0.0.0.0] + @details @ref _UIPR_ is set when a unreachable ICMPv4 message is received. + @sa _UPORTR_, _UIP6R_, _UPORT6R_ + @sa getUIPR(), setUIPR(), getUPORTR(), setUPORTR(), getUIPR6(), setUIPR6(), getUPORT6R(), setUPORT6R() +*/ +#define _UIPR_ (_W6300_IO_BASE_ + (0x41A0 << 8) + WIZCHIP_CREG_BLOCK) +#define _UIP4R_ (_UIPR_) ///< Refer to @ref _UPORTR_ + +/** + @brief IPv4 Unreachable Port number Register address [RO][0x0000] + @details @ref _UPORTR_ is set when a unreachable ICMPv4 message is received. + @sa _UIPR_, _UIP6R_, _UPORT6R_ + @sa getUPORTR(), setUPORTR(), getUIPR(), setUIPR(), getUIPR6(), setUIPR6(), getUPORT6R(), setUPORT6R() +*/ +#define _UPORTR_ (_W6300_IO_BASE_ + (0x41A4 << 8) + WIZCHIP_CREG_BLOCK) +#define _UPORT4R_ (_UPORTR_) ///< Refer to @ref _UPORTR_ +/** + @brief IPv6 Unreachable IP Address Register address [RO][::] + @details @ref _UIP6R_ is set when a unreachable ICMPv6 message is received. + @sa _UIPR_, _UPORTR_, _UIP6R_, _UPORT6R_ + @sa getUIPR6(), setUIPR6(), getUIPR(), setUIPR(), getUPORTR(), setUPORTR(), getUPORT6R(), setUPORT6R() +*/ +#define _UIP6R_ (_W6300_IO_BASE_ + (0x41B0 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief IPv6 Unreachable Port number Register address [RO][0x0000] + @details @ref _UIP6R_ is set when a unreachable ICMPv6 message is received. + @sa _UIPR_, _UPORTR_, _UIP6R_, _UPORT6R_ + @sa getUIPR6(), setUIPR6(), getUIPR(), setUIPR(), getUPORTR(), setUPORTR(), getUPORT6R(), setUPORT6R() +*/ +#define _UPORT6R_ (_W6300_IO_BASE_ + (0x41C0 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Interrupt Pending Time Register address [R=w][0x0000] + @details @ref _INTPTMR_ pends the next interrupt issued by the INTn pin of @ref _WIZCHIP_.\n + It is decreased 1 every 4 SYS_CLK. \n + If it is zero and some interrupt is still remained, the INTn pin is issued. + @sa _IR_, _IRCLR_, _IMR_, _SIR_, _Sn_IRCLR_, _SIMR_, _SLIR_, _SLIRCLR_, _SLIMR_, SYCR_IEN + @sa getINTPTMR(), setINTPTMR(), getIR(), setIRCLR(), getIMR(), setIMR(), getSIR(), setSn_IRCLR(), getSIMR(), setSIMR(), \n + getSLIR(), setSLIRCLR(), getSLIMR(), setSLIMR(), getSYCR1(), setSYCR1() +*/ +#define _INTPTMR_ (_W6300_IO_BASE_ + (0x41C5 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief RA Prefix Length Register address [RO][0x00] + @details @ref _PLR_ is set when RA packet is received from a router. + @sa SLIR_RA, _SLIRCLR_, _PFR_, _VLTR_, _PLTR_, _PAR_ + @sa getPLR(), getSLIR(), setSLIRCLR(), getPFR(), getVLTR(), getPLTR(), getPAR() +*/ +#define _PLR_ (_W6300_IO_BASE_ + (0x41D0 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief RA Prefix Flag Register address [RO][0x00] + @details @ref _PFR_ is set when RA packet is received from a router. + @sa SLIR_RA, _SLIRCLR_, _PLR_, _VLTR_, _PLTR_, _PAR_ + @sa getPFR(), getSLIR(), setSLIRCLR(), getPLR(), getVLTR(), getPLTR(), getPAR() +*/ +#define _PFR_ (_W6300_IO_BASE_ + (0x41D4 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief RA Valid Life Time Register address [RO][0x00000000] + @details @ref _VLTR_ is set when RA packet is received from a router. + @sa SLIR_RA, _SLIRCLR_, _PLR_, _PFR_, _PLTR_, _PAR_ + @sa getVLTR(), getSLIR(), setSLIRCLR(), getPLR(), getPFR(), getPLTR(), getPAR() +*/ +#define _VLTR_ (_W6300_IO_BASE_ + (0x41D8 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief RA Prefered Life Time Register address [RO][0x00000000] + @details @ref _PLTR_ is set when RA packet is received from a router. + @sa SLIR_RA, _SLIRCLR_, _PLR_, _PFR_, _PLTR_, _PAR_ + @sa getPLTR(), getSLIR(), setSLIRCLR(), getPLR(), getPFR(), getVLTR(), getPAR() +*/ +#define _PLTR_ (_W6300_IO_BASE_ + (0x41DC << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief RA Prefix Address Register address[RO][::] + @details @ref _PAR_ is set when RA packet is received from a router. + @sa SLIR_RA, _SLIRCLR_, _PLR_, _PFR_, _VLTR_, _PLTR_, _PAR_ + @sa getPAR(), getPLTR(), getSLIR(), setSLIRCLR(), getPLR(), getPFR(), getVLTR() +*/ +#define _PAR_ (_W6300_IO_BASE_ + (0x41E0 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief ICMPv6 Block Register address [R=W][0x00] + @details @ref _ICMP6BLKR_ can block ICMPv6 message such like as PING, MLD, RA, NS and NA.\n + In this blocked case, @ref Sn_MR_IPRAW6 SOCKET can receive it. + + + +
7 ~ 5 4 3 2 1 0
7 ~ 5 PING6 MLD RA NA NS
+ - @ref ICMP6BLKR_PING6 : The same as @ref NETxMR_PB + - @ref ICMP6BLKR_MLD + - @ref ICMP6BLKR_RA + - @ref ICMP6BLKR_NA + - @ref ICMP6BLKR_NS + + @note The blocked message can be accepted by SOCKETn opened with @ref Sn_MR_IPRAW6. + @sa NETxMR_PB + @sa getICMP6BLKR(), setICMP6BLKR(), getNET6MR(), setNET6MR() +*/ +#define _ICMP6BLKR_ (_W6300_IO_BASE_ + (0x41F0 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Chip configuration Lock Register address [WO][0x00] + @details @ref _CHPLCKR_ can lock or unlock to access @ref _SYCR0_ and @ref _SYCR1_.\n + The lock state can be checked from @ref SYSR_CHPL. + @sa _SYCR0_, _SYCR1_, _SYSR_, SYSR_CHPL + @sa getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define _CHPLCKR_ (_W6300_IO_BASE_ + (0x41F4 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Network configuration Lock Register address [WO][0x00] + @details @ref _NETLCKR_ can lock or unlock to access the network information register such as @ref _SIPR_, @ref _LLAR_, and etc.\n + The lock state can be checked from @ SYSR_NETL. + @sa _SHAR_, _SIPR_, _SUBR_, _GAR_, _LLAR_, _GUAR_, _SUB6R_, _SYSR_, SYSR_NETL + @sa getNETLCKR(), setNETLCKR(), NETLOCK(), NETUNLOCK(), getSHAR(), setSHAR(), getSIPR(), getSIPR(), getSUBR(), setSUBR(), \n + getGAR(), setGAR(), getLLAR(), setLLAR(), getGUAR(), setGUAR(), getSUB6R(), setSUB6R(), getSYSR() +*/ +#define _NETLCKR_ (_W6300_IO_BASE_ + (0x41F5 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief PHY configuration Lock Register address [WO][0x00] + @details @ref _PHYLCKR_ can lock or unlock to access @ref _PHYCR0_ and @ref _PHYCR1_.\n + The lock state can be checked from @ref SYSR_PHYL. + @sa _PHYCR0_, _PHYCR1_, _SYSR_, SYSR_PHYL. + @sa getPHYLCKR(), setPHYLCKR(), PHYLOCK(), PHYUNLOCK(), setPHYCR0(), getPHYCR1(), setPHYCR1(), getSYSR() +*/ +#define _PHYLCKR_ (_W6300_IO_BASE_ + (0x41F6 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Retransmission Time Register address [R=W][0x07D0] + @details @ref _RTR_ sets the default timeout value of @ref _Sn_RTR_.\n + When @ref _Sn_RTR_ is 0, @ref _Sn_RTR_ is reset to @ref _RTR_ after @ref Sn_CR_OPEN. + @sa _Sn_RTR_, _RCR_, _Sn_RCR_, _Sn_CR_, Sn_CR_OPEN, _Sn_IR_, _Sn_IRCLR_, Sn_IR_TIMEOUT + @sa getRTR(), setRTR(), getSn_RTR(), setSn_RTR(), getRCR(), setRCR(), getSn_RCR(), setSn_RCR(), \n + getSn_CR(), getSn_CR(), getSn_IR(), setSn_IRCLR() +*/ +#define _RTR_ (_W6300_IO_BASE_ + (0x4200 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief Retransmission Counter Register address [R=W][0x08] + @details @ref _RCR_ sets the default retransmission count of @ref _Sn_RCR_.\n + When @ref _Sn_RCR_ is 0, @ref _Sn_RCR_ is initialized as @ref _Sn_RTR_ after @ref Sn_CR_OPEN. + @sa _Sn_RCR_, _RTR_, _Sn_RTR_, _Sn_CR_, Sn_CR_OPEN, _Sn_IR_, _Sn_IRCLR_, Sn_IR_TIMEOUT + @sa getRCR(), setRCR(), getSn_RCR(), setSn_RCR(), getRTR(), setRTR(), getSn_RTR(), setSn_RTR(), \n + getSn_CR(), getSn_CR(), getSn_IR(), setSn_IRCLR() +*/ +#define _RCR_ (_W6300_IO_BASE_ + (0x4204 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Retransmission Time Register address [R=W][0x07D0] + @details @ref _SLRTR_ sets the timeout value of packet to be retransmitted by @ref _SLCR_. + @sa _SLRCR_, _SLIR_, _SLIRCLR_, SLIR_TOUT + @sa getSLRTR(), setSLRTR(), getSLRCR(), setSLRCR(), getSLIR(), setSLIRCLR() +*/ +#define _SLRTR_ (_W6300_IO_BASE_ + (0x4208 << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Retransmission Count Register address [R=W][0x00] + @details @ref _SLRCR_ sets the retry counter of packet to be retransmitted by @ref _SLCR_. + @sa _SLRTR_, _SLIR_, _SLIRCLR_, SLIR_TOUT + @sa getSLRCR(), setSLRCR(), getSLRTR(), setSLRTR(), setSLIRCLR(), getSLIR(), setSLIRCLR(), +*/ +#define _SLRCR_ (_W6300_IO_BASE_ + (0x420C << 8) + WIZCHIP_CREG_BLOCK) + +/** + @brief SOCKET-less Hop Limit Register address [R=W][0x80] + @details @ref _SLHOPR_ sets the hop limit value of packet to be transmitted by @ref _SLCR_. + @sa _SLCR_ + @sa getSLHOPR(), setSLHOPR(), getSLCR(), setSLCR() +*/ +#define _SLHOPR_ (_W6300_IO_BASE_ + (0x420F << 8) + WIZCHIP_CREG_BLOCK) + +/** + @} +*/ + +//----------------------------- W6300 Socket Registers ----------------------------- +/** + @addtogroup Socket_register_group_W6300 + @{ +*/ +/** + @brief Socket Mode Register Address [R=W][0x00] + @details @ref _Sn_MR_ sets the option or protocol type of SOCKETn before @ref Sn_CR_OPEN is performed.\n\n + Each bit of @ref _Sn_MR_ is defined as the following. + + + +
7 6 5 4 3 ~ 0
MULTI/MF BRDB/FPSH ND/MC/SMB/MMB UNIB/MMB6 P[3:0]
+ - @ref Sn_MR_MULTI : Support UDP Multicasting + - @ref Sn_MR_MF : Support MAC Filter Enable + - @ref Sn_MR_BRDB : Broadcast Block + - @ref Sn_MR_FPSH : Force PSH flag + - @ref Sn_MR_ND : No Delay ACK flag + - @ref Sn_MR_MC : IGMP ver2, ver1 + - @ref Sn_MR_SMB : Solicited Multicast Block + - @ref Sn_MR_MMB : IPv4 Multicast block + - @ref Sn_MR_UNIB : Unicast Block + - @ref Sn_MR_MMB6 : IPv6 UDP Multicast Block + - P[3:0] + + + + + + + + + + + + +
P[3:0] Protocol Mode
0000 SOCKET Closed
0001 TCP4
0010 UDP4
0011 IPRAW4
0100
MACRAW
1001 TCP6
1010 UDP6
1100 IPRAW6
1101 TCP Dual(TCPD)
1110 UDP Dual (UDPD)
+ - @ref Sn_MR_CLOSE : SOCKET Closed + - @ref Sn_MR_TCP4(= @ref Sn_MR_TCP) : TCP4 mode + - @ref Sn_MR_UDP4(= @ref Sn_MR_UDP) : UDP4 mode + - @ref Sn_MR_IPRAW4(= @ref Sn_MR_IPRAW) : IPRAW4 mode + - @ref Sn_MR_MACRAW : MACRAW mode + - @ref Sn_MR_TCP6 : TCP6 mode + - @ref Sn_MR_UDP6 : UDP6 mode + - @ref Sn_MR_IPRAW6 : IPRAW6 mode + - @ref Sn_MR_TCPD : TCP Dual (TCPD) mode + - @ref Sn_MR_UDPD : UDP Dual (UDPD) mode + + @note MACRAW mode should be only used in Socket 0. + @sa _Sn_CR_, Sn_CR_OPEN, _Sn_SR_, _Sn_MR2_ + @sa getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_SR(), getSn_MR2(), setSn_MR2() +*/ +#define _Sn_MR_(N) (_W6300_IO_BASE_ + (0x0000 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKET n Prefer Source IPv6 Address Register Address [R=W][0x00] + @details @ref _Sn_PSR_ select the Source IPv6 Address to transmit a packet by @ref _Sn_CR_. + This function is same as @ref _SLPSR_. + - @ref PSR_AUTO + - @ref PSR_LLA + - @ref PSR_GUA + @sa _Sn_CR_, _Sn_PSR_, _SLPSR_ + @sa getSn_PSR(), setSn_PSR(), getSLCR(), setSLCR(), getSLPSR(), setSLPSR(), +*/ +#define _Sn_PSR_(N) (_W6300_IO_BASE_ + (0x0004 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief Socket Command Register Address [RW,AC][0x00] + @details @ref _Sn_CR_ is used to set the command for SOCKET n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n + It is automatically cleared to 0x00 after the command is recognized by @ref _WIZCHIP_.\n + Even though @ref _Sn_CR_ is cleared to 0x00, the command is still being processed.\n + To check whether the command is completed or not, please check the @ref _Sn_IR_ or @ref _Sn_SR_. + - @ref Sn_CR_OPEN : Initialize or open socket. + - @ref Sn_CR_LISTEN : Wait connection request on TCP4/TCP6/TCPD mode(Server mode) + - @ref Sn_CR_CONNECT : Send connection request on TCP4/TCPD mode(Client mode) + - @ref Sn_CR_CONNECT6 : Send connection request on TCP6/TCPD mode(Client mode):nohl + - @ref Sn_CR_DISCON : Send closing request on TCP/TCP6/TCPD mode. + - @ref Sn_CR_CLOSE : Close socket. + - @ref Sn_CR_SEND : Update TX buffer pointer and send data in IPv4 socket. + - @ref Sn_CR_SEND6 : Update TX buffer pointer and send data in IPv6 socket. + - @ref Sn_CR_SEND_KEEP : Send keep alive message. + - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + + @note These commands should be exclusive executed.\n That is, the other command can not executed when one command is not cleared yet. + @sa _Sn_IR_, _Sn_IRCLR_, Sn_IMR_, _SIR_, _Sn_SR_ + @sa getSn_CR(), setSn_CR(), getSn_IR(), setSn_IRCLR(), getSn_IMR(), setSn_IMR(), getSIR(), getSn_SR() +*/ +#define _Sn_CR_(N) (_W6300_IO_BASE_ + (0x0010 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Interrupt Register Address [RO][0x00] + @details @ref _Sn_IR_ gets the status of SOCKETn interrupt such as establishment, termination, receiving data, timeout.\n + If SOCKETn interrupt occurs and the n-th bit of @ref _SIMR_ is set, then @ref SIR_INT(n) is set.\n + In order to clear the @ref _Sn_IR_ bit, Set the corresponding bit of _Sn_IRCLR_ to 1.\n + If all @ref _Sn_IR_ bits are cleared, the @ref SIR_INT(n) is automatically cleared. + + + +
7 ~ 5 4 3 2 1 0
Reserved SENDOK TIMEOUT RECV DISCON CON
+ - @ref Sn_IR_SENDOK + - @ref Sn_IR_TIMEOUT + - @ref Sn_IR_RECV + - @ref Sn_IR_DISCON + - @ref Sn_IR_CON + + @sa _Sn_IRCLR_, _Sn_IMR_, _SIR_, _SIMR_ + @sa getSn_IR(), setSn_IRCLR(), getSn_IMR(), setSn_IMR(), getSIR(), getSIMR(), setSIMR() +*/ +#define _Sn_IR_(N) (_W6300_IO_BASE_ + (0x0020 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Interrupt Mask Register Address [R=W][0xFF] + @details @ref _Sn_IMR_ is used to mask interrupts of @ref _Sn_IR_. + @sa _Sn_IR_, _Sn_IRCR_, _SIR_, _SIMR_ + @sa getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IRCLR(), getSIR(), getSIMR(), setSIMR() +*/ +#define _Sn_IMR_(N) (_W6300_IO_BASE_ + (0x0024 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Interrupt Clear Register Address [WO][0x00] + @details @ref _Sn_IRCLR_ clears @ref _Sn_IR_ + @sa _Sn_IR_, _SIR_, _SIMR_ + @sa setSn_IRCLR(), getSn_IR(), getSIR(), getSIMR(), setSIMR() +*/ +#define _Sn_IRCLR_(N) (_W6300_IO_BASE_ + (0x0028 << 8) + WIZCHIP_SREG_BLOCK(N)) + + + +/** + @brief SOCKETn Status Register Address [RO][0x00] + @details @ref _Sn_SR_ indicates the status of SOCKETn.\n + The status of SOCKETn can be changed by @ref _Sn_CR_, some TCP packets such as SYN, FIN, RST packet, or @ref Sn_IR_TIMEOUT. + - Normal status + - @ref SOCK_CLOSED : Closed + - @ref SOCK_INIT : Initiate state + - @ref SOCK_LISTEN : Listen state + - @ref SOCK_ESTABLISHED : Success to connect + - @ref SOCK_CLOSE_WAIT : Closing state + - @ref SOCK_UDP : UDP socket + - @ref SOCK_IPRAW : IPRAW socket + - @ref SOCK_IPRAW6 : IPv6 IPRAW socket + - @ref SOCK_MACRAW : MAC raw mode socket + - Temporary status during changing the status of SOCKETn . + - @ref SOCK_SYNSENT : This indicates SOCKETn sent the connect-request packet (SYN packet) to a peer. + - @ref SOCK_SYNRECV : It indicates SOCKETn successfully received the connect-request packet (SYN packet) from a peer. + - @ref SOCK_FIN_WAIT : Connection state + - @ref SOCK_TIME_WAIT : Closing state + - @ref SOCK_LAST_ACK : Closing state + + @sa _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, Sn_IR_TIMEOUT + @sa getSn_SR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IRCLR() + + + +
@image html SocketStatus.png ""
+ +*/ +#define _Sn_SR_(N) (_W6300_IO_BASE_ + (0x0030 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Extension Status Register Address [RO][0x00] + @details @ref _Sn_ESR_ indicates the connected client IP address information such as IP version, IPv6 address type(LLA or GUA), \n + and TCP operation mode such as TCP SERVER and TCP CLIENT + + + +
7 ~ 3 2 1 0
Reserved TCPM TCPOP IP6T
+ - @ref Sn_ESR_TCPM : @ref Sn_ESR_TCPM_IPV4, @ref Sn_ESR_TCPM_IPV6 + - @ref Sn_ESR_TCPOP : @ref Sn_ESR_TCPOP_SVR, @ref Sn_ESR_TCPOP_CLT + - @ref Sn_ESR_IP6T : @ref Sn_ESR_IP6T_LLA, @ref Sn_ESR_IP6T_GUA + + @note It is valid only on TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_MR_, _Sn_PSR_ + @sa getSn_ESR(), getSn_MR(), setSn_MR(), getSn_PSR(), setSn_PSR() +*/ +#define _Sn_ESR_(N) (_W6300_IO_BASE_ + (0x0031 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn IP Protocol Number(PN) Register Address [R/W][0x0000] + @details \ref _Sn_PNR_ that sets the protocol number/next header field of the IPv4/IPv6 header at the IP layer. + @note It is valid only in IPRAW mode such as @ref Sn_MR_IPRAW4 and @ref Sn_MR_IPRAW6. + @note It is set before @ref Sn_CR_OPEN is performed. + @sa _Sn_NHR_, _Sn_MR_, Sn_CR_OPEN + @sa getSn_PNR(), setSn_PNR(), getSn_NHR(), setSn_NHR(), getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR() +*/ +#define _Sn_PNR_(N) (_W6300_IO_BASE_ + (0x0100 << 8) + WIZCHIP_SREG_BLOCK(N)) +#define _Sn_NHR_(N) (_Sn_PNR_(N)) ///< Refer to @ref _Sn_PNR_. + +/** + @brief SOCKETn IPv4 Type of Service(TOS) Register Address [R=W][0x00] + @details @ref _Sn_TOSR_ sets the TOS(Type Of Service) field in IPv4 Header. + @sa getSn_TOSR(), setSn_TOSR() +*/ +#define _Sn_TOSR_(N) (_W6300_IO_BASE_ + (0x0104 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn IP Time to live(TTL) Register Address [R=W][0x80] + @details @ref _Sn_TTLR_ sets the TTL(Time To Live)/HOP(Hop Limit) field in IPv4/IPv6 header at the IP layer. + @sa _Sn_HOPR_ + @sa getSn_TTLR(), setSn_TTLR(), getSn_HOPR(), setSn_HOPR() +*/ +#define _Sn_TTLR_(N) (_W6300_IO_BASE_ + (0x0108 << 8) + WIZCHIP_SREG_BLOCK(N)) +#define _Sn_HOPR_(N) (_Sn_TTLR_(N)) ///< Refer to @ref _Sn_TTLR_. + +/** + @brief SOCKETn Fragment Register Address [R=W][0x4000] + @details @ref _Sn_FRGR_ sets the fragment flag & offset in IPv4 header. + @note @ref _WIZCHIP_ can not support IP fragment & re-assembly.\n So It is not recommended to set @ref _Sn_FRGR_ to any other value. + @sa getSn_FRGR(), setSn_FRGR() +*/ +#define _Sn_FRGR_(N) (_W6300_IO_BASE_ + (0x010C << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Maximum Segment Size(MSS) Register Address [RW][0x0000] + @details @ref _Sn_MSSR_ sets or gets the MTU(Maximum Transfer Unit) of SOCKETn. \n + The MTU of each protocol is as following. + + + + + + + + + +
@ref _Sn_MR_[3:0] @ref NETMR2_PPPoE = 0 @ref NETMR2_PPPoE = '1'
@ref Sn_MR_TCP4 1 ~ 1460 1 ~ 1452
@ref Sn_MR_TCP6 1 ~ 1440 1 ~ 1432
@ref Sn_MR_UDP4 1 ~ 1472 1 ~ 1464
@ref Sn_MR_UDP6 1 ~ 1452 1 ~ 1444
@ref Sn_MR_IPRAW4 1 ~ 1480 1 ~ 1472
@ref Sn_MR_IPRAW6 1 ~ 1460 1 ~ 1452
@ref Sn_MR_MACRAW 1 ~ 1514
+ + @note It is not set exceeding the MTU for each protocol of SOCKETn even if _Sn_MSSR_ is set over the MTU. + @sa _Sn_MR_, NETMR2_PPPoE + @sa getSn_MSSR(), setSn_MSSR(), getSn_MR(), setSn_MR(), getNETMR2(), setNETMR2() +*/ +#define _Sn_MSSR_(N) (_W6300_IO_BASE_ + (0x0110 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Source Port Register Address [R=W][0x0000] + @details @ref _Sn_PORTR_ sets the source port number of SOCKETn . + @note It is valid in TCP(@ref Sn_MR_TCP4, @ref Sn_MR_TCP6, @ref Sn_MR_TCPD) and UDP(@ref Sn_MR_UDP4, @ref Sn_MR_UDP6, @ref Sn_MR_UDPD) mode. + @note It should be set before @ref Sn_CR_OPEN is performed. + @sa _Sn_MR_, Sn_CR_OPEN + @sa getSn_PORTR(), getSn_PORTR(), getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR() +*/ +#define _Sn_PORTR_(N) (_W6300_IO_BASE_ + (0x0114 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Destination Hardware Address Register Address [RW][00:00:00:00:00:00] + @details @ref _Sn_DHAR_ sets or gets the destination hardware address of SOCKETn.\n + - When @ref Sn_MR2_DHAM = 1 and @ref _Sn_MR_[3:0] != @ref Sn_MR_MACRAW + The destination hardware address is set by @ref _Sn_DHAR_ without ARP processed by @ref Sn_CR_CONNECT, @ref Sn_CR_CONNECT6, @ref Sn_CR_SEND, and @ref Sn_CR_SEND6.\n + Also, when SOCKETn is opened with @ref Sn_MR_UDP4 or @ref Sn_MR_UDP6 and @ref Sn_MR_MULTI is set, @ref _Sn_DHAR_ sets the Multicast Group Hardware address. + - Others + In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD, \n + @ref _Sn_DHAR_ gets the destination hardware address when @ref _Sn_SR_ is @ref SOCK_ESTABLISHED. + @sa _Sn_MR_, _Sn_MR2_, _Sn_CR_, _Sn_SR_ + @sa getSn_DHAR(), setSn_DHAR(), getSn_MR(), setSn_MR(), getSn_MR2(), setSn_MR2(), getSn_CR(), setSn_CR(), getSn_SR() +*/ +#define _Sn_DHAR_(N) (_W6300_IO_BASE_ + (0x0118 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Destination IPv4 Address Register Address [RW][0.0.0.0] + @details @ref _Sn_DIPR_(= @ref _Sn_DIP4R_) sets or gets the destination IPv4 address of SOCKETn. \n + - In TCP mode such as @ref Sn_MR_TCP4, and @ref Sn_MR_TCPD + - TCP CLIENT mode : It sets the IPv4 address of TCP SERVER before @ref Sn_CR_CONNECT is performed. + - TCP SERVER mode : It gets the IPv4 address of TCP CLIENT when @ref _Sn_SR_ is @ref SOCK_ESTABLISHED. + - In UDP(@ref Sn_MR_UDP4, @ref Sn_MR_UDPD) mode & IPRAW4(@ref Sn_MR_IPRAW4) mode + It sets the destination IPv4 address before @ref Sn_CR_SEND is performed. \n + When Sn_MR_MULTI = 1, It sets the multicast group IPv4 address. + @sa _Sn_DIP4R_, _Sn_MR_, _Sn_CR_, _Sn_SR_ + @sa getSn_DIPR(), getSn_DIPR(), getSn_DIP4R(), getSn_DIP4R(), getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_SR() +*/ +#define _Sn_DIPR_(N) (_W6300_IO_BASE_ + (0x0120 << 8) + WIZCHIP_SREG_BLOCK(N)) +#define _Sn_DIP4R_(N) (_Sn_DIPR_(N)) ///< Refer to @ref _Sn_DIPR_. + +/** + @brief SOCKETn Destination IPv6 Address Register Address [RW][::] + @details @ref _Sn_DIP6R_ sets or gets the destination IPv6 address of SOCKETn. + - In TCP mode such as @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD + - TCP CLIENT mode : It sets the IPv6 address of TCP SERVER before @ref Sn_CR_CONNECT6 is performed. + - TCP SERVER mode : It gets the IPv6 address of TCP CLIENT when @ref _Sn_SR_ is @ref SOCK_ESTABLISHED. + - In UDP(@ref Sn_MR_UDP6, @ref Sn_MR_UDPD) mode & IPRAW4(@ref Sn_MR_IPRAW6) mode + It sets the destination IPv6 address before @ref Sn_CR_SEND6 is performed.\n + When Sn_MR_MULTI = 1, It sets the multicast group IPv6 address. + @sa _Sn_MR_, _Sn_CR_, _Sn_SR_ + @sa getSn_DIP6R(), setSn_DIP6R(), getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_SR() +*/ +#define _Sn_DIP6R_(N) (_W6300_IO_BASE_ + (0x0130 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Destination Port Register Address [RW][0x0000] + @details @ref _Sn_DPORTR_ sets or gets the destination port number of SOCKETn. + - In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD + - TCP CLIENT mode : It sets the port number of TCP SERVER before @ref Sn_CR_CONNECT is performed. + - TCP SERVER mode : It gets the port number of TCP CLIENT when @ref _Sn_SR_ is @ref SOCK_ESTABLISHED. + - In UDP mode such as @ref Sn_MR_UDP4, @ref Sn_MR_UDP6, and @ref Sn_MR_UDPD + It sets the destination port number before @ref Sn_CR_SEND is performed. \n + When Sn_MR_MULTI = 1, It sets the multicast group group port number. + + @note It is valid SOCKETn is opened with @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, @ref Sn_MR_TCPD, @ref Sn_MR_UDP4, @ref Sn_MR_UDP4, and @ref Sn_MR_UDPD. + @note It should be set before OPEN command is ordered. + @sa _Sn_MR_, _Sn_CR_, _Sn_SR_ + @sa getSn_DPORTR(), getSn_DPORTR(), getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_SR() +*/ +#define _Sn_DPORTR_(N) (_W6300_IO_BASE_ + (0x0140 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Mode Register 2 Address [R=W][0x00] + @details @ref _Sn_MR2_ sets the option of SOCKETn with @ref _Sn_MR_, before @ref Sn_CR_OPEN is performed.\n + Each bit of @ref _Sn_MR2_ is defined as the following. + + + +
7 ~ 2 1 0
Reserved DHAM FARP
+ - @ref Sn_MR2_DHAM : @ref Sn_MR2_DHAM_AUTO, @ref Sn_MR2_DHAM_MANUAL + - @ref Sn_MR2_FARP + @sa _Sn_MR_, _Sn_CR_ + @sa getSn_MR2(), setSn_MR2(), getSn_MR(), getSn_MR(), getSn_CR() +*/ +#define _Sn_MR2_(N) (_W6300_IO_BASE_ + (0x0144 << 8) + WIZCHIP_SREG_BLOCK(N)) + + +/** + @brief SOCKETn Retransmission Time Register Address [R=W][0x0000] + @details @ref _Sn_RTR_ sets the timeout value of packet to be retransmitted by @ref _SLCR_.\n + @note It should be set before @ref Sn_CR_OPEN is performed.\n + It is initialized as @ref _RTR_ if you do not set it to none-zero value. + @sa _RTR_, _Sn_CR_ + @sa getSn_RTR(), setSn_RTR(), getSn_CR(), setSn_CR() +*/ +#define _Sn_RTR_(N) (_W6300_IO_BASE_ + (0x0180 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Retransmission Count Register Address [R=W][0x00] + @details @ref _Sn_RCR_ sets the retry count value of packet to be retransmitted by @ref _SLCR_.\n + @note It should be set before @ref Sn_CR_OPEN is performed.\n + It is initialized as @ref _RTR_ if you do not set it to any none-zero value. + @sa _RTR_, _Sn_CR_ + @sa getSn_RTR(), setSn_RTR(), getSn_CR(), setSn_CR() +*/ +#define _Sn_RCR_(N) (_W6300_IO_BASE_ + (0x0184 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn Keep Alive Time Register Address [R=W][0x00] + @details @ref _Sn_KPALVTR_ sets the auto-retransmission time of KA(Keep Alive) packet. \n + If the destination can not respond to the KA packet during the time set by @ref _Sn_KPALVTR_,\n + the connection is terminated, @ref Sn_IR_TIMEOUT is set and then @ref _Sn_SR_ is changed @ref SOCK_CLOSED.\n + Before the time is expierd, if the destination sends a KA/ACK packet or any packet, the connection is still valid,\n + @ref _Sn_SR_ remained at @ref SOCK_ESTABLISHED. + @note It is valid only after sending data over 1 byte in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @note If it is set to 0, KA packet can be sent by @ref Sn_CR_SEND_KEEP. + @sa Sn_CR_SEND_KEEP, Sn_IR_TIMEOUT, Sn_IRCLR, Sn_SR, Sn_MR + @sa getSn_KPALVTR(), setSn_KPALVTR(), getSn_IR(), setSn_IRCLR(), getSn_SR(), getSn_MR(), setSn_MR() +*/ +#define _Sn_KPALVTR_(N) (_W6300_IO_BASE_ + (0x0188 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn TX Buffer Size Register Address [R=W][0x02] + @details @ref _Sn_TX_BSR_ sets the TX buffer size of SOCKETn in the 16KB TX memory.\n + It can be set only with 0,1,2,4,8, and 16K bytes. + @note The 16KB TX memory is allocated as many as @ref _Sn_TX_BSR_ sequentially from SOCKET0 to SOCKETn(Here, 0 <= n <= @ref _WIZCHIP_SOCK_NUM_ - 1).\n + The total sum of Sn_TX_BSR can not be exceed 16KB of TX memory. \n + If the total size is exceeded, SOCKETn can't be normally sent data to a destination. + @sa _Sn_RX_BSR_ + @sa getSn_TX_BSR(), setSn_TX_BSR(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE(), getSn_TxMAX(), setSn_TX_BSR(), getSn_RX_BSR(), setSn_RX_BSR() +*/ +#define _Sn_TX_BSR_(N) (_W6300_IO_BASE_ + (0x0200 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn TX Free Buffer Size Register Address [RO][0x0800] + @details @ref _Sn_TX_FSR_ gets the transmittable free size of SOCKETn TX buffer. + @note Data should not be saved bigger than it because the data overwrites the previous saved data not to be sent yet.\n + Therefore, Check it before saving the data to the SOCKETn TX buffer. \n + If the data size is equal or smaller than it, transmit the data with @ref Sn_CR_SEND / @ref Sn_CR_SEND6 after saving the data in SOCKETn TX buffer.\n + If the data size is greater than it, transmit the data after dividing into it and saving in the SOCKETn TX buffer. + @note \n + - In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6 and @ref Sn_MR_TCPD, \n + It is automatically increased by the absolute difference between @ref _Sn_TX_WR_ and interanl TX ACK pointer. + - In other mode \n + It is automatically increased by the absolute difference between @ref _Sn_TX_WR_ and @ref _Sn_TX_RD_. + @sa _Sn_RX_RSR_, _Sn_TX_WR_, _Sn_TX_RD_, _Sn_CR_ + @sa getSn_TX_FSR(), getSn_TX_WR(), getSn_TX_WR(), getSn_TX_RD(), getSn_CR(), setSn_CR() +*/ +#define _Sn_TX_FSR_(N) (_W6300_IO_BASE_ + (0x0204 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKET TX Memory Read Pointer Register Address[R][0x0000] + @details @ref _Sn_TX_RD_ gets the start pointer of data to be sent by @ref Sn_CR_SEND. \n + @ref Sn_CR_SEND / @ref Sn_CR_SEND6 starts to transmit the saved data from @ref _Sn_TX_RD_ to @ref _Sn_TX_WR_ in the SOCKETn TX Buffer,\n + and when @ref Sn_IR_SENDOK is set, It is automatically increased to equal @ref _Sn_TX_WR_. + @note It is initialized by @ref Sn_CR_OPEN, But, In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD,\n + it is re-initialized when the TCP connection is completed. + @note If it exceeds the maximum value 0xFFFF, (that is, it is greater than 0x10000 and the carry bit occurs),\n + then the carry bit is ignored and it automatically is updated with its the lower 16bits value. + @sa _Sn_TX_WR_, _Sn_TX_FSR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_ + @sa getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR(), getSn_TX_FSR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IRCLR(), getSn_MR(), setSn_MR() +*/ +#define _Sn_TX_RD_(N) (_W6300_IO_BASE_ + (0x0208 << 8) + WIZCHIP_SREG_BLOCK(N)) + + +/** + @brief SOCKETn TX Memory Write Pointer Register Address [RW][0x0000] + @details @ref _Sn_TX_WR_ gets the start pointer of data to be saved in the SOCKETn TX buffer, \n + or sets the end pointer of data to be sent by @ref Sn_CR_SEND. \n + If you have completed to save the data to be sent in the SOCKETn TX buffer, + increase it as many as the saved size of data before @ref Sn_CR_SEND is performed.\n + @ref Sn_CR_SEND starts to transmit the saved data from @ref _Sn_TX_RD_ to @ref _Sn_TX_WR_ in the SOCKETn TX Buffer, \n + and when @ref Sn_IR_SENDOK is set, @ref _Sn_TX_RD_ is automatically increased to equal it. + @note It is initialized by @ref Sn_CR_OPEN.\n + But, In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD,\n + it is re-initialized when the TCP connection is completed. + @note The size of data to be saved can't exceed @ref _Sn_TX_FSR_. + @note If it exceeds the maximum value 0xFFFF(that is, it is greater than 0x10000 and the carry bit occurs),\n + then ignore the carry bit and update it with its lower 16bits value. + @sa _Sn_TX_RD_, _Sn_TX_FSR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_ + @sa getSn_TX_WR(), setSn_TX_WR(), getSn_TX_RD(), getSn_TX_FSR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IRCLR(), getSn_MR(), setSn_MR() +*/ +#define _Sn_TX_WR_(N) (_W6300_IO_BASE_ + (0x020C << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn RX Buffer Size Register Address [R=W][0x02] + @details @ref _Sn_RX_BSR_ sets the RX buffer size of SOCKETn in the 16KB RX memory.\n + It can be set only with 0,1,2,4,8, and 16K bytes. + @note The 16KB RX memory is allocated as many as @ref _Sn_RX_BSR_ sequentially from SOCKET0 to SOCKETn(Here, 0 <= n <= @ref _WIZCHIP_SOCK_NUM_ - 1).\n + The total sum of @ref _Sn_RX_BSR_ can not be exceed 16KB of RX memory. \n + If the total size is exceeded, SOCKETn can't be normally received data from a destination. + @sa _Sn_RX_BSR_ + @sa getSn_TX_BSR(), setSn_TX_BSR(), getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_RxMAX(), getSn_RX_BSR(), setSn_RX_BSR() +*/ +#define _Sn_RX_BSR_(N) (_W6300_IO_BASE_ + (0x0220 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn RX Received Size Register Address [RO][0x0000] + @details @ref _Sn_RX_RSR_ gets the received data size of SOCKETn RX buffer. + @note The real received data size maybe smaller than it, \n + because it maybe included the size of 'PACKET NFO' such like as \n + the destination IP address, destination port number and data size of the received DATA PACKET. + @note Do not read bigger data than @ref _Sn_RX_RSR_. + @note It is automatically increased by the absolute difference between @ref _Sn_RX_WR_ and @ref _Sn_RX_RD_ \n + after @ref Sn_CR_RECV is performed. + @sa _Sn_RX_RSR_, _Sn_TX_WR_, _Sn_TX_RD_, _Sn_CR_, _Sn_TX_FSR_ + @sa getSn_RX_RSR(), getSn_TX_WR(), getSn_TX_WR(), getSn_CR(), setSn_CR(), getSn_TX_FSR() +*/ +#define _Sn_RX_RSR_(N) (_W6300_IO_BASE_ + (0x0224 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKET RX Memory Read Pointer Register Address[R][0x0000] + @details @ref _Sn_RX_RD_ gets the start pointer of the received data in the SOCKETn RX buffer,\n + or sets the end data pointer of the read completed data by @ref Sn_CR_RECV. \n + You can read the received data from it to @ref _Sn_RX_WR_ in the SOCKET RX buffer.\n + After completing to read data, you should increase it as many as the read size before @ref Sn_CR_RECV is performed. + @note It is initialized by @ref Sn_CR_OPEN, But, In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD,\n + it is re-initialized when the TCP connection is completed. + @note If it exceeds the maximum value 0xFFFF, (that is, it is greater than 0x10000 and the carry bit occurs),\n + Ignore the carry bit and update with its the lower 16bits value. + @sa _Sn_RX_WR_, _Sn_RX_RSR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_ + @sa getSn_RX_WR(), setSn_RX_RD(), getSn_RX_WR(), getSn_TX_FSR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IRCLR(), getSn_MR(), setSn_MR() +*/ +#define _Sn_RX_RD_(N) (_W6300_IO_BASE_ + (0x0228 << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @brief SOCKETn TX Memory Write Pointer Register Address [RW][0x0000] + @details @ref _Sn_TX_WR_ gets the end pointer of the data that has been completely received in the SOCKETn RX buffer. \n + Whenever a data has been completely received from a destination, \n + It is automatically increased as many as the sum size of the received data and the 'PACKET INFO'. \n + You can read the recevied data from @ref _Sn_RX_RD_ to it in the SOCKET RX buffer. + @note It is initialized by @ref Sn_CR_OPEN. But, In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD,\n + it is re-initialized when the TCP connection is completed. + @note If it exceeds the maximum value 0xFFFF(that is, it is greater than 0x10000 and the carry bit occurs),\n + then ignore the carry bit and update it with its lower 16bits value. + @sa _Sn_TX_RD_, _Sn_TX_FSR_, _Sn_CR_, _Sn_IR_, Sn_IRCLR_, _Sn_MR_ + @sa getSn_TX_WR(), setSn_TX_WR(), getSn_TX_RD(), getSn_TX_FSR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IRCLR(), getSn_MR(), setSn_MR() +*/ +#define _Sn_RX_WR_(N) (_W6300_IO_BASE_ + (0x022C << 8) + WIZCHIP_SREG_BLOCK(N)) + +/** + @} +*/ + +/*----------------------------- W6300 Register values -----------------------------*/ + +/* System Status Register Bit Definition */ +/** + @brief CHIP Lock staus bit of @ref _SYSR_. + @details @ref SYSR_CHPL indicates the lock status of @ref _SYCR0_ and @ref _SYCR1_.\n + 1 : Lock \n + 0 : unlock + @note It is set by only @ref _CHPLCKR_. + @sa _SYSR_, _CHPLCKR_, _SYCR0_, _SYCR1_ + @sa getSYSR(), getCHPLCKR(), setCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), setSYCR0(), setSYCR1() +*/ +#define SYSR_CHPL (1 << 7) + +/** + @brief NET Lock status bit of @ref _SYSR_. + @details @ref SYSR_NETL indicates the lock of network information registers such as + @ref _SHAR_, @ref _GAR_, @ref _SUBR_, @ref _SIPR_, @ref _LLAR_, @ref _GUAR_, and @ref _SUB6R_. \n + 1 : Lock \n + 0 : unlock + @note It is set by only @ref _NETLCKR_. + @note @ref _GA6R_ can be accessed regardless of @ref SYSR_NETL. + @sa _SYSR_, _NETLCKR_, _SHAR_, _GAR_, _SUBR_, _SIPR_, _LLAR_, _GUAR_, _SUB6R_ + @sa getSYSR(), getNETLCKR(), setNETLCKR(), NETLOCK(), NETUNLOCK(),\n + getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), getSIR(), setSIPR(), \n + getLLAR(), setLLAR(), getGUAR(),setGUAR(), getSUB6R(), setSUB6R() +*/ +#define SYSR_NETL (1 << 6) + +/** + @brief PHY Lock status bit of @ref _SYSR_. Refer to @ref _PHYLCKR_. + @details @ref SYSR_PHYL indicates the lock status of @ref _PHYCR0_ and _PHYCR1_.\n + 1 : Lock \n + 0 : unlock + @note It is set by only @ref _PHYLCKR_. + @sa _SYSR_, _PHYCLKR_, _PHYCR0_, _PHYCR1_ + @sa getSYSR(), getPHYLCKR(), setPHYLCKR(), setPHYCR0(), getPHYCR1(), setPHYCR1() +*/ +#define SYSR_PHYL (1 << 5) + +/** + @brief Parallel Bus Mode bit of @ref _SYSR_ + @details @ref SYSR_IND is set when @ref _WIZCHIP_ PIN MODE[3:0] == "010X". + It indicates to use the parallel BUS mode. + @sa _SYSR_, _WIZCHIP_IO_MODE_BUS_ + @sa getSYSR() +*/ +#define SYSR_IND (1 << 5) + +/** + @brief SPI I/F Mode bit of @ref _SYSR_. + @details @ref SYSR_SPI is set when @ref _WIZCHIP_ PIN MODE[3:0] == "000X". + It indicates to use the SPI mode. + @sa _SYSR_, _WIZCHIP_IO_MODE_SPI_ + @sa getSYSR() +*/ +#define SYSR_SPI (1 << 0) + + +/* System Config Register Bit Definition */ +/** + @brief RST bit of @ref _SYCR0_ + @details @ref SYCR0_RST resets to @ref _WIZCHIP_ softly. \n + 0 : Soft reset \n + 1 : Normal operation + @note It can be set only when @ref SYSR_CHPL = 1. + @sa _SYSR0_, _CHPLCKR_, _SYSR_, SYSR_CHPL + @sa setSYCR0(), setCHPLCKR(), getCHPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getSYSR() +*/ +#define SYCR0_RST (0x00) + +/** + @brief IEN bit of @ref _SYCR1_. + @details @ref SYCR1_IEN is globally enable or disable the interrupt of @ref _WIZCHIP_,\n + regardless of the related interrupt mask registers such as @ref _IMR_, @ref _SIMR_, @ref _SLIMR_, and @ref _Sn_IMR_.\n + 1 : Enable \n + 0 : Disable + @sa _SYCR1_, _IR_, _SIR_, _SLIR_, _Sn_IR_, _IRCLR_, _SLIRCLR_, _Sn_IRCLR_ + @sa getSYCR1(), setSYCR1(), getIR(), getSIR(), getSLIR(), getSn_IR(), setIRCLR(), setSLIRCLR(), setSn_IRCLR() +*/ +#define SYCR1_IEN (1 << 7) + +/** + @brief System Clock select mask bit of @ref _SYCR1_. + @details @ref SYCR1_CLKSEL selects a system clock to 100MHz or 25MHz. \n + The masked bit values are as following. + - @ref SYCR1_CLKSEL_25M + - @ref SYCR1_CLKSEL_100M + @note It can be set only when @ref SYSR_CHPL = 1. + @note The system clock is automatically changed to 25MHz while the reset of @ref _WIZCHIP_ H/W reset, the Ethernet PHY H/W reset and power down. \n + On the other hand, the system clock is set by @ref SYCR1_CLKSEL during normal operating. + @sa _SYCR1_, _SYSR_, _CHPLCKR_, SYSL_CHPL, PHYCR1_RST, PHYCR1_PWDN + @sa getSYCR1(), setSYCR1(), getSYSR(), getCHPLCKR(), setCHIPLCKR(), CHIPLOCK(), CHIPUNLOCK(), getPHYCR1(), setPHYCR1() +*/ +#define SYCR1_CLKSEL (1 << 0) + +/** + @brief System Clock - 25MHz + @details @ref SYCR1_CLKSEL_25M selects a system clock to 25MHz. + @note It can be set only when @ref SYSR_CHPL = 1. + @sa _SYCR1_, SYCR1_CLKSEL, SYCR1_CLKSEL_100M + @sa getSYCR1(), setSYCR1(), getSYSR(), getCHPLCKR(), setCHIPLCKR(), CHIPLOCK(), CHIPUNLOCK() +*/ +#define SYCR1_CLKSEL_25M 1 + +/** + @brief System Clock - 100MHz + @details @ref SYCR1_CLKSEL_100M selects a system clock to 100MHz. + @note It can be set only when @ref SYSR_CHPL = 1. + @sa _SYCR1_, SYCR1_CLKSEL, SYCR1_CLKSEL_25M + @sa getSYCR1(), setSYCR1(), getSYSR(), getCHPLCKR(), setCHIPLCKR(), CHIPLOCK(), CHIPUNLOCK() +*/ +#define SYCR1_CLKSEL_100M 0 + + +/* Interrupt Register Bit Definition */ +/** + @brief WOL bit of @ref _IR_ + @details @ref IR_WOL is set when @ref _WIZCHIP_ receives a magic packet of WOL. + @sa _IR_, _IRCLR_, _IMR_ + @sa getIR(), setIRCLR(), getIMR(), setIMR() +*/ +#define IR_WOL (1<<7) + +/** + @brief UNR6 bit of @ref _IR_ + @details @ref IR_UNR6 is set when @ref _WIZCHIP_ receives the unreachable message of ICMPv6. + @sa _IR_, _IRCLR_, _IMR_ + @sa getIR(), setIRCLR(), getIMR(), setIMR() +*/ +#define IR_UNR6 (1<<4) + +/** + @brief IPCONF bit of @ref _IR_ + @details @ref IR_IPCONF is set when @ref _WIZCHIP_ receives a ARP reply with the same IPv4 address as @ref _SIPR_. + @sa _IR_, _IRCLR_, _IMR_ + @sa getIR(), setIRCLR(), getIMR(), setIMR() +*/ +#define IR_IPCONF (1<<2) + +/** + @brief UNR4 bit of @ref _IR_ + @details @ref IR_UNR4 is set when @ref _WIZCHIP_ receives the unreachable message of ICMPv4. + @sa _IR_, _IRCLR_, _IMR_ + @sa getIR(), setIRCLR(), getIMR(), setIMR() +*/ +#define IR_UNR4 (1<<1) + +/** + @brief PTERM bit of @ref _IR_ + @details @ref IR_PTERM is set when @ref _WIZCHIP_ receives the PPP termination packet + @sa _IR_, _IRCLR_, _IMR_ + @sa getIR(), setIRCLR(), getIMR(), setIMR() +*/ +#define IR_PTERM (1<<0) + + +/* SOCKET Interrupt Register Bit Definition */ +/** + @brief N-th INT bit of @@ref _SIR_ + @details @ref SIR_INT(N) is set when @ref _Sn_IR_(N) is not equal to zero. + @sa _SIR_, _Sn_IRCLR_, _SIMR_ + @sa getSIR(), setSn_IRCLR(), getSIMR() +*/ +#define SIR_INT(N) (1<TCP SERVER mode + If the connection request client have a IPv4 address, \n + TCP dual SOCKETn is changed to TCP4 mode and a destination IP address can be checked thru @ref _Sn_DIPR_, \n + else if the client have a IPv6 address, \n + TCP dual SOCKETn is changed to IPv6 mode and destination IP address can be checked by thru @ref _Sn_DIP6R_. + - In SOCKETn is operated as TCP CLIENT mode, + If the IP address type of destination to connect is IPv4, \n + the destination IP address should be set to @ref _Sn_DIPR_ and try to connect by @ref Sn_CR_CONNECT, \n + else if the type is IPv6, \n + the destination IP address should be set to @ref _Sn_DIP6R_ and try to connect by @ref Sn_CR_CONNECT6. \n + + @note In TCP SERVER mode, You can check the IP type of the client with @ref Sn_ESR_TCPM. + @note If the connected client have a IPv6 address, You can check whether the address is LLA or GAU, thru @ref Sn_ESR_IP6T + @sa _Sn_MR_, _Sn_CR_, _Sn_SR_, _Sn_ESR_TCPM_, Sn_MR_TCP4, Sn_MR_TCP6 + @sa getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_SR(), getSn_ESR() +*/ +#define Sn_MR_TCPD (0x0D) + +/** + @brief UDP Dual mode + @details @ref Sn_MR_UDPD sets SOCKETn to both UDP4 & UDP6 mode. \n + It should be set before @ref Sn_CR_OPEN is performed. \n + After @ref Sn_CR_OPEN, SOCKETn is opened as UDP dual mode \n + and @ref _Sn_SR_ is changed from @ref SOCK_CLOSED to @ref SOCK_UDP. + @note In order to send data, \n + You can use both @ref Sn_CR_SEND and @ref Sn_CR_SEND6 as command and both @ref _Sn_DIPR_ and @ref _Sn_DIP6R_ as destination. + @note You can know the destination IP address type is whether IPv6 or IPv4 thru @ref getsockopt() with @ref SO_PACKINFO. + @sa _Sn_MR_, _Sn_CR_, _Sn_SR_, Sn_MR_UDP6, Sn_MR_UDP4 + @sa getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_SR() +*/ +#define Sn_MR_UDPD (0x0E) + +/* SOCKETn Command Register BIt Definition */ +/** + @brief Initialize or Open SOCKETn. + @details SOCKETn is initialized and opened according to the protocol mode selected by @ref _Sn_MR_ and with a source port set by @ref _Sn_PORTR_. \n + The table shows @ref _Sn_SR_ is changed according to @ref _Sn_MR_.\n + + + + + + + + +
@ref _Sn_MR_ (P[3:0]) @ref _Sn_SR_
@ref Sn_MR_CLOSE @ref SOCK_CLOSED
@ref Sn_MR_TCP4, @ref Sn_MR_TCP6, @ref Sn_MR_TCPD @ref SOCK_INIT
@ref Sn_MR_UDP, @ref Sn_MR_UDP6, @ref Sn_MR_UDPD @ref SOCK_UDP
@ref Sn_MR_IPRAW4 @ref SOCK_IPRAW4
@ref Sn_MR_IPRAW6 @ref SOCK_IPRAW6
@ref Sn_MR_MACRAW @ref SOCK_MACRAW
+ + @note If you want to use a SOCKETn option such as Sn_MR_MF, Sn_MR_ND, Sn_MR_MUTIL and etc, \n + these options should be set before @ref Sn_CR_OPEN is performed. + @note If you want to open a multicast UDP mode SOCKETn, \n + You should set the multicast group with @ref _Sn_DIPR_ or @ref _Sn_DIP6R_ and @ref _Sn_DPORTR_ before @ref Sn_CR_OPEN is performed. + @sa _Sn_CR_, _Sn_MR_, _Sn_SR_, _Sn_PORTR_, _Sn_DIPR_, _Sn_DIP6R_, _Sn_DPORTR_, + @sa getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR(), getSn_SR(), getSn_PORTR(), setSn_PORTR(), getSn_DIPR(), setSn_DIPR(), + getSn_DIP6R(), setSn_DIP6R(), getSn_DPORTR(), setSn_DPORTR() +*/ +#define Sn_CR_OPEN (0x01) + +/** + @brief Wait a connection request in TCP SERVER mode + @details SOCKETn operates as a TCP SERVER and waits for a connection-request (SYN packet) \n + with corresponding @ref _Sn_PORTR_ port number from any TCP CLIENT \n + The @ref _Sn_SR_ is changed from @ref SOCK_INIT to @ref SOCK_LISTEN. \n + When a TCP CLIENT connection request is successfully accepted,\n + the @ref _Sn_SR_ is changed from @ref SOCK_LISTEN to @ref SOCK_ESTABLISHED \n + and the @ref Sn_IR_CON is set.\n + But when a TCP CLIENT connection request is failed, \n + @ref Sn_IR_TIMEOUT is set and @ref _Sn_SR_ is changed to SOCK_CLOSED. + @note This is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_CR_, _Sn_MR_, _Sn_SR_, _Sn_PORTR_ + @sa getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR(), getSn_SR(), getSn_PORTR(), setSn_PORTR() +*/ +#define Sn_CR_LISTEN (0x02) + +/** + @brief Send a connection request in TCP CLIENT mode + @details To establish a connection, a connect-request (SYN packet) is sent to TCP SERVER set by @ref _Sn_DIPR_ & @ref _Sn_DPORTR_.\n + If the connect-request is successful accepted by a TCP SERVER, \n + the @ref _Sn_SR_ is changed to @ref SOCK_ESTABLISHED and the @ref Sn_IR_CON is set. \n + The connect-request fails in the following three cases, \n + and @ref _Sn_SR_ is changed to @ref SOCK_CLOSED.\n\n + 1. Until a ARP timeout is occurred (@ref Sn_IR_TIMEOUT = 1), a destination hardware address can not be acquired through the ARP-process.\n + 2. Until a TCP tmeout occurred (@ref Sn_IR_TIMEOUT = 1), a SYN/ACK packet is not received from the server\n + 3. When a RST packet is received instead of a SYN/ACK packet \n + + @note This is valid only in TCP mode such as @ref Sn_MR_TCP4 and @ref Sn_MR_TCPD. + @sa _Sn_CR_, _Sn_MR_, _Sn_SR_, _Sn_DIPR_, _Sn_DPORTR_, Sn_CR_CONNECT6, _Sn_IR_, _Sn_IRCLR_ + @sa getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR(), getSn_SR(), getSn_DIPR(), setSn_DIPR(), getSn_DPORTR(), setSn_DPORTR(), getSn_IR(), setSn_IRCLR() +*/ +#define Sn_CR_CONNECT (0x04) + +/** + @brief Send connection request in TCP CLIENT mode + @details To establish a connection, a connect-request (SYN packet) is sent to TCP SERVER set by @ref _Sn_DIP6R_ & @ref _Sn_DPORTR_.\n + If the connect-request is successful accepted by a TCP SERVER, \n + the @ref _Sn_SR_ is changed to @ref SOCK_ESTABLISHED and the @ref Sn_IR_CON is set. \n + The connect-request fails in the following three cases, and @ref _Sn_SR_ is changed @ref SOCK_CLOSED.\n + 1. Until a ARP timeout is occurred (@ref Sn_IR_TIMEOUT = 1), a destination hardware address can not be acquired through the ARP-process.\n + 2. Until a TCP tmeout occurred (@ref Sn_IR_TIMEOUT = 1), a @b SYN/ACK packet is not received from the server\n + 3. When a RST packet is received instead of a @b SYN/ACK packet \n + + @note This is valid only in TCP mode such as @ref Sn_MR_TCP6 and @ref Sn_MR_TCPD. + @sa _Sn_CR_, _Sn_MR_, _Sn_SR_, _Sn_DIP6R_, _Sn_DPORTR_, Sn_CR_CONNECT, _Sn_IR_, _Sn_IRCLR_ + @sa getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR(), getSn_SR(), getSn_DIP6R(), setSn_DIP6R(), getSn_DPORTR(), setSn_DPORTR(), getSn_IR(), setSn_IRCLR() +*/ +#define Sn_CR_CONNECT6 (0x84) + +/** + @brief Send a disconnect request in TCP mode + @details Regardless of TCP SERVER or TCP CLIENT, \n + @ref Sn_CR_DISCON processes the disconnect-process (Active or Passive close).\n + When the disconnect-process is successful (that is, FIN/ACK packet is received successfully from/to each other),\n + @ref _Sn_SR_ is changed to @ref SOCK_CLOSED.\n + Otherwise, @ref Sn_IR_TIMEOUT is set and then @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. + - Active close + It transmits first a disconnect-request(FIN packet) to the connected peer, and waits to receive two FIN/ACK and FIN packet from the peer. \n + If two FIN/ACK and FIN packet is received successfully, @ref Sn_IR_DISCON is set and @ref _Sn_SR_ is changed @ref SOCK_CLOSED. + - Passive close + When a FIN packet is first received from the peer, the FIN/ACK packet is replied back to the peer and @ref Sn_IR_DISCON is set.\n + And then, a FIN packet is sent by @ref Sn_CR_DISCON to the peer, and waits to receive the FIN/ACK packet from the peer. \n + If the FIN/ACK packet is received successfully from the peer, @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. + + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_CR_, _Sn_MR_, _Sn_SR_, _Sn_IR_, _Sn_IRCLR_, Sn_IR_DISCON, Sn_IR_TIMEOUT + @sa getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR(), getSn_SR(), getSn_IR(), setSn_IRCLR() +*/ +#define Sn_CR_DISCON (0x08) + +/** + @brief Release or Close SOCKETn + @details In TCP mode, @ref Sn_CR_CLOSE force to close a SOCKETn without the disconnect-process.\n + In other SOCKETn mode, @ref Sn_CR_CLOSE just closes a SOCKET.\n + @note @ref _Sn_SR_ can be changed from any status to @ref SOCK_CLOSED by @ref Sn_CR_CLOSE. + @sa _Sn_CR_, _Sn_MR_, _Sn_SR_, Sn_CR_DISCON + @sa getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR(), getSn_SR() +*/ +#define Sn_CR_CLOSE (0x10) + +/** + @brief Send Data + @details @ref Sn_CR_SEND send the saved data from @ref _Sn_TX_RD_ to @ref _Sn_TX_WR_ in the SOCKETn TX buffer \n + to the destination specified by @ref _Sn_DIPR_ or @ref _Sn_DIP6R_, and @ref _Sn_DPORTR_.\n + - TCP mode(@ref Sn_MR_TCP4, @ref Sn_MR_TCP6, @ref Sn_MR_TCPD) + If it starts to be sent the data by @ref Sn_CR_SEND, @ref Sn_IR_SENDOK is set. \n + And after sending the data, if the ACK to the sent data can not be received during @ref _Sn_RTR_, \n + the sent data can be retransmitted as many as @ref _Sn_RCR_. \n + During the retransmission, \n + If the ACK is received, @ref _Sn_TX_FSR_ is increased as many as the sent data size, \n + Otherwise, @ref Sn_IR_TIMEOUT is set and @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. + - UDP mode(@ref Sn_MR_UDP4, @ref Sn_MR_UDPD) & IPRAW mode(@ref Sn_MR_IPRAW4) + It first sends a ARP-request to a destination specified with @ref _Sn_DIPR_ before it starts to be sent data by @ref Sn_CR_SEND. \n + If the ARP-reply can not be received during @ref _Sn_RTR_, the ARP-request can be retransmitted as many as @ref _Sn_RCR_. \n + During the retransmission, \n + If the ARP-reply is received and @ref Sn_IR_SENDOK is set, it starts to send data and then @ref _Sn_TX_FSR_ is increased as many as the sent data size. \n + Otherwise, @ref Sn_IR_TIMEOUT is set but @ref _Sn_SR_ is not changed. + - MACRAW mode(@ref Sn_MR_MACRAW) + It just start to send data and @ref Sn_IR_SENDOK is set. + + @note Data size to be sent is calculated by the absolute difference between @ref _Sn_TX_WR_ and @ref _Sn_TX_RD_. \n + In TCP or UDP mode, It can not be sent bigger data than @ref _Sn_TX_FSR_.\n + In IPRAW or Macraw case, it can not be sent bigger data than MTU(Maximum Transmit Unit). + @note In TCP or MACRAW mode, It can send data to a destination address whether IPv4 or IPv6. \n + In UDP or IPRAW mode, It can send data only to a destination IPv4 address. \n + For Sending to IPv6 address, It can be used with @ref Sn_CR_SEND6. + @sa _Sn_CR_, _Sn_MR_, _Sn_DIPR_, _Sn_DIP6R_, _Sn_DPORTR_, _Sn_IR_, _Sn_IRCLR_, _Sn_TX_FSR_, _Sn_TX_WR_, _Sn_TX_RD_ + @sa getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR(), getSn_SR(), getSn_DIPR(), setSn_DIPR(), getSn_DIP6R(), setSn_DIP6R(), \n + getSn_DPORTR(), setSn_DPORTR(), getSn_IR(), setSn_IRCLR(), getSn_TX_FSR(), getSn_TX_WR(), setSn_TX_WR(), getSn_TX_RD() +*/ +#define Sn_CR_SEND (0x20) + +/** + @brief Send Data + @details @ref Sn_CR_SEND6 sends the saved data from @ref _Sn_TX_RD_ to @ref _Sn_TX_WR_ in the SOCKETn TX buffer \n + to the destination specified by @ref _Sn_DIP6R_, and @ref _Sn_DPORTR_.\n + - TCP mode(@ref Sn_MR_TCP4, @ref Sn_MR_TCP6, @ref Sn_MR_TCPD) & MACRAW mode(@ref Sn_MR_MACRAW) + @ref Sn_CR_SEND6 is not recommended. In this case, Use @ref Sn_CR_SEND. + - UDP mode(@ref Sn_MR_UDP6, @ref Sn_MR_UDPD) & IPRAW mode(@ref Sn_MR_IPRAW6) + It first send a neighbor solicitation NS) of ICMPv6 to a destination specified with @ref _Sn_DIP6R_ \n + before it starts to be sent data by @ref Sn_CR_SEND. \n + If the neighbor advertisement(NA) of ICMPv6 can not be received during @ref _Sn_RTR_, \n + the NS can be retransmitted as many as @ref _Sn_RCR_. \n + During the retransmission, \n + If the NA is received and @ref Sn_IR_SENDOK is set, \n + it starts to send data and then @ref _Sn_TX_FSR_ is increased as many as the sent data size. \n + Otherwise, @ref Sn_IR_TIMEOUT is set but @ref _Sn_SR_ is not changed. + + @note Data size to be sent is calculated by the absolute difference between @ref _Sn_TX_WR_ and @ref _Sn_TX_RD_. \n + In TCP or UDP mode, It can not be sent bigger data than @ref _Sn_TX_FSR_.\n + In IPRAW or Macraw case, it can not be sent bigger data than MTU(Maximum Transmit Unit). + @note In UDP or IPRAW mode, It can send data only to a destination IPv6 address. \n + For Sending to IPv4 address, It can be sent by @ref Sn_CR_SEND. + @sa _Sn_CR_, _Sn_MR_, _Sn_DIP6R_, _Sn_DPORTR_, _Sn_IR_, _Sn_IRCLR_, _Sn_TX_FSR_, _Sn_TX_WR_, _Sn_TX_RD_ + @sa getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR(), getSn_SR(), getSn_DIP6R(), setSn_DIP6R(), getSn_DPORTR(), setSn_DPORTR(), \n + getSn_IR(), setSn_IRCLR(), getSn_TX_FSR(), getSn_TX_WR(), setSn_TX_WR(), getSn_TX_RD() +*/ +#define Sn_CR_SEND6 (0xA0) + +/** + @brief Send keep alive message + @details @ref Sn_CR_SEND_KEEP checks whether the connection is established or not by sending 1 byte KA(Keep Alive) packet.\n + If the destination can not respond to the KA packet during the time set by @ref _Sn_RTR_ and @ref _Sn_RCR_, \n + the connection is terminated, @ref Sn_IR_TIMEOUT is set and then @ref _Sn_SR_ is changed @ref SOCK_CLOSED. + @note It is valid only after sending data over 1 byte in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_CR_, _Sn_MR_, _Sn_SR_, _Sn_IR_, _Sn_IRCLR_, _Sn_RTR_, _Sn_RCR_, _Sn_KPALVTR_ + @sa getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR(), getSn_SR(), getSn_IR(), setSn_IRCLR(), \n + getSn_RTR(), setSn_RTR(), getSn_RCR(), setSn_RCR(), getSn_KPALVTR(), getSn_KPALVTR() +*/ +#define Sn_CR_SEND_KEEP (0x22) + +/** + @brief Receive data + @details @ref Sn_CR_RECV reads the saved from @ref _Sn_RX_RD_ to @ref _Sn_RX_WR_ data in SOCKETn RX buffer.\n + When a data is saved in the SOCKETn RX buffer, \n + @ref Sn_IR_RECV is set and @ref _Sn_RX_RSR_ is increased as many as the saved data size.\n + The total size of saved data is calculated by the absolute difference between @ref _Sn_RX_WR_ and @ref _Sn_RX_RD_,\n + and it can be checked thru @ref _Sn_RX_RSR_.\n + After reading data, @ref _Sn_RX_RD_ should be increased as many as the read size before @ref Sn_CR_RECV is performed.\n + After @ref Sn_CR_RECV, @ref _Sn_RX_RSR_ is decreased as many as the read size.\n + If @ref _Sn_RX_RSR_ is remained still at none-zero, @ref Sn_IR_RECV is set again. + @sa _Sn_CR_, _Sn_MR_, _Sn_IR_, _Sn_IRCLR_, _Sn_RX_RD_, _Sn_RX_WR_, _Sn_RX_RSR_ + @sa getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR(), getSn_IR(), getSn_IRCLR(), \n + getSn_RX_RD(), setSn_RX_RD(), getSn_RX_TX(), getSn_RX_RSR() +*/ +#define Sn_CR_RECV (0x40) + + +/* Sn_IR values */ +/** + @brief SEND OK Interrupt + @details @ref Sn_IR_SENDOK is set when it is started to be sent data by @ref Sn_CR_SEND. + @note Even though @ref Sn_IR_SENDOK is set, it does not means that the destination receives data successfully.\n + - In TCP mode, The sent data maybe still transmitting or retransmitting. \n + - In other modes, The sent data maybe lost by media collision or an other reason such as network traffic. + @sa _Sn_IR_, _Sn_IRCLR_, Sn_CR_SEND + @sa getSn_IR(), setSn_IRCLR(), getSn_CR(), setSn_CR() +*/ +#define Sn_IR_SENDOK (0x10) + +/** + @brief TIMEOUT Interrupt + @details @ref Sn_IR_TIMEOUT is set when a timeout occurs in ARP and ND process or TCP retransmission. + @note In TCP mode, If it is set, @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. \n + In other modes, _Sn_SR_ is still remained at the previous status. + @sa _Sn_IR_, _Sn_IRCLR_, Sn_CR_CONNECT, Sn_CR_CONNECT6, Sn_CR_SEND + @sa getSn_IR(), setSn_IRCLR(), getSn_CR(), setSn_CR() +*/ +#define Sn_IR_TIMEOUT (0x08) + +/** + @brief RECV Interrupt + @details @ref Sn_IR_RECV is set whenever data is received from a peer, \n + or if @ref _Sn_RX_RSR_ is still at none-zero whenever @ref Sn_CR_RECV is performed. + @sa _Sn_IR_, _Sn_IRCLR_, Sn_CR_RECV + @sa getSn_IR(), setSn_IRCLR(), getSn_CR(), setSn_CR() +*/ +#define Sn_IR_RECV (0x04) + +/** + @brief DISCON Interrupt + @details @ref Sn_IR_DISCON is set when a FIN or FIN/ACK packet is received from the connected peer. + @note When first a FIN packet is received from the connected peer and @ref _Sn_SR_ is changed to SOCK_CLOSE_WAIT, \n + you should perform @ref Sn_CR_DISCON for a successful disconnect. \n + If the disconnect-process is completed or failed, @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. + @note It is valild only in TCP mode such as @ref Sn_MR_TCP4, @ ref Sn_MR_TCP6 and @ref Sn_MR_TCPD. + @sa _Sn_IR_, _Sn_IRCLR_, Sn_IR_DISCON, _Sn_SR_ + @sa getSn_IR(), setSn_IRCLR(), getSn_CR(), setSn_CR(), getSn_SR() +*/ +#define Sn_IR_DISCON (0x02) + +/** + @brief CONNECT Interrupt + @details @ref Sn_IR_CON is set once the connection with a peer is established and @ref _Sn_SR_ is changed to @ref SOCK_ESTABLISHED. + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ ref Sn_MR_TCP6 adn @ref Sn_MR_TCPD. + @sa _Sn_IR_, _Sn_IRCLR_, _Sn_SR_ + @sa getSn_IR(), setSn_IRCLR(), getSn_SR() +*/ +#define Sn_IR_CON (0x01) + +/* Sn_SR values */ +/** + @brief SOCKETn Closed status + @details @ref SOCK_CLOSED indicates that SOCKETn is closed and released.\n + It is set when @ref Sn_CR_DISCON , @ref Sn_CR_CLOSE is performed, or when @ref Sn_IR_TIMEOUT is set.\n + It can be changed to @ref SOCK_CLOSED regardless of previous status. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, Sn_IR_TIMEOUT + @sa getSn_SR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IRCLR() +*/ +#define SOCK_CLOSED (0x00) + +/** + @brief TCP SOCKETn initialized status + @details @ref SOCK_INIT indicates SOCKETn is opened with TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCP6.\n + @ref _Sn_SR_ is changed from @ref SOCK_CLOSED to @ref SOCK_INIT when @ref Sn_CR_OPEN is performed in TCP mode.\n + In @ref SOCK_INIT status, @ref Sn_CR_LISTEN for operating a TCP SERVER \n + or @ref Sn_CR_CONNECT / @ref Sn_CR_CONNECT6 for operating a TCP CLIENT can be performed. + @note It is valid only in TCP mode. + @sa _Sn_SR_, _Sn_CR_, _Sn_MR_ + @sa getSn_SR, getSn_CR(), setSn_CR(), getSn_MR(), setSn_MR() +*/ +#define SOCK_INIT (0x13) + +/** + @brief TCP SOCKETn Listen status + @details @ref SOCK_LISTEN indicates SOCKETn is operating as TCP SERVER mode \n + and waiting for connection-request (SYN packet) from a peer (TCP CLIENT).\n + @ref _Sn_SR_ is changed to @ref SOCK_SYNRECV when the connection-request(SYN packet) is successfully accepted \n + and It is changed from @ref SOCK_SYNRECV to @ref SOCK_ESTABLISHED \n + when the SYN/ACK packet is sent successfully to the peer and then the ACK packet of SYN/ACK is received successfully.\n + Otherwise, it is changed to @ref SOCK_CLOSED and @ref Sn_IR_TIMEOUT is set. + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCP6.. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_ + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR() +*/ +#define SOCK_LISTEN (0x14) + +/** + @brief TCP Connection Request status + @details @ref SOCK_SYNSENT indicates TCP SOCKETn sent the connect-request packet(SYN packet)\n + to the peer specified by @ref _Sn_DIPR_ / @ref _Sn_DIP6R_ and @ref _Sn_DPORTR_.\n + It is temporarily shown when @ref _Sn_SR_ is changing from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by @ref Sn_CR_CONNECT or @ref Sn_CR_CONNECT6.\n + When the connect-accept packet (SYN/ACK packet) is received from the peer at @ref SOCK_SYNSENT and the ACK packet of SYN/ACK is sent successfully, \n + @ref _Sn_SR_ is changed to @ref SOCK_ESTABLISHED.\n + Otherwise, it is changed to @ref SOCK_CLOSED and @ref Sn_IR_TIMEOUT is set. + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCP6.. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_ + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR() +*/ +#define SOCK_SYNSENT (0x15) + +/** + @brief TCP Connection Accept status + @details @ref SOCK_SYNRECV indicates TCP SOCKETn is successfully received the connect-request packet (SYN packet) from a peer.\n + It is temporarily shown when @ref _Sn_SR_ is changing from @ref SOCK_LISTEN to @ref SOCK_ESTABLISHED by the SYN packet\n + If SOCKETn sends the response (SYN/ACK packet) to the peer successfully and the ACK packet of SYS/ACK is received successfully,\n + @ref _Sn_SR_ is changed to @ref SOCK_ESTABLISHED. \n + Otherwise, @ref _Sn_SR_ is changed to @ref SOCK_CLOSED and @ref Sn_IR_TIMEOUT is set. + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCP6.. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_ + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR() +*/ +#define SOCK_SYNRECV (0x16) + +/** + @brief TCP SOCKETn Established status + @details @ref SOCK_ESTABLISHED indicates TCP SOCKETn is connected successfully with a peer.\n + when the TCP SERVER processes the SYN packet from the TCP CLIENT during @ref SOCK_LISTEN or \n + when the TCP CLIENT performs successfully @ref Sn_CR_CONNECT or @ref Sn_CR_CONNECT6,\n + @ref _Sn_SR_ is changed to @ref SOCK_ESTABLISHED and @ref Sn_IR_CON is set. \n + During @ref SOCK_ESTABLISHED, a DATA packet can be sent to or received from the peer by @ref Sn_CR_SEND or @ref Sn_CR_RECV. \n + If the DATA/ACK packet is not received from the peer during data re-transmission, @ref Sn_IR_TIMEOUT is set and @ref _Sn_SR_ is changed to @ref SOCK_CLOSED.\n + Otherwise, @ref _Sn_SR_ is still at @ref SOCK_ESTABLISHED. + @note In TCP SERVER, \n + You can check the IPv4/IPv6 address and port number of connected peer thru @ref _Sn_DIPR_, @ref _Sn_DIP6R_, and @ref _Sn_DPORTR_ respectively. + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCP6. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_, _Sn_DIPR_, _Sn_DIP6R_, _Sn_DPORTR_ + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR(), + getSn_DIPR(), setSn_DIPR(), getSn_DIP6R(), setSn_DIP6R(), getSn_DPORTR(), setSn_DPORTR(). +*/ +#define SOCK_ESTABLISHED (0x17) + +/** + @brief TCP SOCKETn Closing status + @details @ref SOCK_FIN_WAIT indicates TCP mode SOCKETn waits until the disconnect-process is completed. \n + It is temporarily shown in disconnect-process such as active-close. \n + When the disconnect-process is successfully completed or when @ref Sn_IR_TIMEOUT is set,\n + @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_, SOCK_TIME_WAIT, SOCK_LAST_ACK + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR() + +*/ +#define SOCK_FIN_WAIT (0x18) + +/** + @brief TCP SOCKETn Closing status + @details @ref SOCK_TIME_WAIT indicates TCP SOCKETn waits until the disconnect-process is completed.\n + It is temporarily shown in disconnect-process such as active-close. \n + When the disconnect-process is successfully completed or when @ref Sn_IR_TIMEOUT is set,\n + @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_, SOCK_FIN_WAIT, SOCK_LAST_ACK + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR() +*/ +#define SOCK_TIME_WAIT (0x1B) + +/** + @brief TCP SOCKETn Half Closing staus + @details @ref SOCK_CLOSE_WAIT indicates TCP SOCKETn receives the disconnect-request (FIN packet) from the connected peer.\n + It is a half-closing status, and a DATA packet can be still sent or received by @ref Sn_CR_SEND or @ref Sn_CR_RECV.\n + If you do not have any more need to send or received a DATA packet, You can perform @ref Sn_CR_DISCON for a full-closing. + @note If you have no need the successful closing, You maybe perform @ref Sn_CR_CLOSE. + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_ + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR() +*/ +#define SOCK_CLOSE_WAIT (0x1C) + +/** + @brief TCP SOCKETn Closing status + @details @ref SOCK_LAST_ACK indicates TCP SOCKETn waits until the disconnect-process is completed.\n + It is temporarily shown in disconnect-process such as active-close and passive-close.\n + When the disconnect-process is successfully completed or when @ref Sn_IR_TIMEOUT is set,\n + @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_, SOCK_FIN_WAIT, SOCK_TIME_WAIT + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR() +*/ +#define SOCK_LAST_ACK (0x1D) + +/** + @brief UDP SOCKETn status + @details @ref SOCK_UDP indicates SOCKETn is opened in UDP mode such as @ref Sn_MR_UDP4, @ref Sn_MR_UDP6, and @ref Sn_MR_UDPD.\n + @ref _Sn_SR_ is changed from @ref SOCK_CLOSED to @ref SOCK_INIT when @ref Sn_CR_OPEN is performed in UDP mode.\n + Unlike TCP mode, during @ref SOCK_UDP, \n + a DATA packet can be sent to or received from a peer by @ref Sn_CR_SEND / @ref Sn_CR_SEND6 or @ref Sn_CR_RECV without a connect-process.\n + Before a DATA packet is sent by @ref Sn_CR_SEND / @ref Sn_CR_SEND6,\n + the ARP is requested to the peer specified by @ref _Sn_DIPR_ / @ref _Sn_DIP6R_.\n + In ARP processing, @ref _Sn_SR_ is stll at @ref SOCK_UDP even if @ref Sn_IR_TIMEOUT is set.\n + If you do not have any more need to send or received a DATA packet, \n + You can perform @ref Sn_CR_CLOSE and @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. + @note It is valid only in UDP mode such as @ref Sn_MR_UDP4, @ref Sn_MR_UDP6, and @ref Sn_MR_UDPD. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_, _Sn_DIPR_, _Sn_DIP6R_ + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR(), + getSn_DIPR(), setSn_DIPR(), getSn_DIP6R(), setSn_DIP6R() +*/ +#define SOCK_UDP (0x22) + +/** + @brief IPRAW4 SOCKETn mode + @details @ref SOCK_IPRAW4(= @ref SOCK_IPRAW) SOCKETn indicates SOCKETn is opened as IPv4 RAW mode.\n + @ref _Sn_SR_ is changed from @ref SOCK_CLOSED to @ref SOCK_IPRAW4 when @ref Sn_CR_OPEN is performed with @ref Sn_MR_IPRAW4. \n + A DATA packet can be send to or received from a peer without a connection like as @ref SOCK_UDP. \n + Before a DATA packet is sent by @ref Sn_CR_SEND, \n + the ARP is requested to the peer specified by @ref _Sn_DIPR_.\n + In ARP processing, @ref _Sn_SR_ is still at @ref SOCK_IPRAW4 even if @ref Sn_IR_TIMEOUT is set.\n + IPRAW4 SOCKETn can receive only the packet specified by @ref _Sn_PNR_, and it discards the others packets.\n + If you do not have any more need to send or received a DATA packet, \n + You can perform @ref Sn_CR_CLOSE and @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. + @note It is valid only in IPRAW4 mode such as @ref Sn_MR_IPRAW4. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_, _Sn_DIPR_, _Sn_PNR_ + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR(), + getSn_DIPR(), setSn_DIPR(), getSn_PNR(), setSn_PNR() +*/ +#define SOCK_IPRAW4 (0x32) +#define SOCK_IPRAW (SOCK_IPRAW4) ///< Refer to @ref SOCK_IPRAW4. + +/** + @brief IPRAW6 SOCKETn mode + @details @ref SOCK_IPRAW6 SOCKETn indicates SOCKETn is opened as IPv6 RAW mode.\n + @ref _Sn_SR_ is changed from @ref SOCK_CLOSED to @ref SOCK_IPRAW6 when @ref Sn_CR_OPEN is performed with @ref Sn_MR_IPRAW6. \n + A DATA packet can be send to or received from a peer without a connection like as @ref SOCK_UDP.\n + Before a DATA packet is sent by @ref Sn_CR_SEND6, \n + the ICMPv6 NS is requested to the peer specified by @ref _Sn_DIPR_ or @ref _Sn_DIP6R_.\n + In ND(Neighbor Discovery) is processing,\n + @ref _Sn_SR_ is still at @ref SOCK_IPRAW6 even if @ref Sn_IR_TIMEOUT is set.\n + IPRAW6 SOCKETn can receive only the packet specified by @ref _Sn_PNR_, and it discards the others packets.\n + If you do not have any more need to send or received a DATA packet, \n + You can perform @ref Sn_CR_CLOSE and @ref _Sn_SR_ is changed to @ref SOCK_CLOSED. + @note It is valid only in IPRAW6 mode such as @ref Sn_MR_IPRAW6. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_, _Sn_DIP6R_, _Sn_PNR_ + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR(), + getSn_DIP6R(), setSn_DIP6R(), getSn_PNR(), setSn_PNR() +*/ +#define SOCK_IPRAW6 (0x33) + +/** + @brief MACRAW SOCKETn mode + @details @ref SOCK_MACRAW indicates SOCKET0 is opened as MACRAW mode.\n + @ref _Sn_SR_ is changed from @ref SOCK_CLOSED to @ref SOCK_MACRAW when @ref Sn_CR_OPEN command is ordered with @ref Sn_MR_MACRAW.\n + MACRAW SOCKET0 can be sent or received a pure Ethernet frame packet to/from any peer. + @note It is valid only in SOCKET0. + @sa _Sn_SR_, _Sn_CR_, _Sn_IR_, _Sn_IRCLR_, _Sn_MR_ + @sa getSn_SR, getSn_CR(), getSn_IR(), setSn_IRCLR(), setSn_CR(), getSn_MR(), setSn_MR(), +*/ +#define SOCK_MACRAW (0x42) + +/* Sn_ESR values */ +/** + @brief SOCKETn Extended Status : TCP Mode + @details @ref Sn_ESR_TCPM masks the TCPM bit of @ref _Sn_ESR_. \n + The masked bit values are as following. \n + - @ref Sn_ESR_TCPM_IPV4 + - @ref Sn_ESR_TCPM_IPV6 + @note It is useful to know the destination IP version when TCPD(@ref Sn_MR_TCPD) mode SOCKETn is operated as TCP SERVER. + @sa _Sn_ESR_ + @sa getSn_ESR() +*/ +#define Sn_ESR_TCPM (1<<2) + +/** + @brief TCP SOCKETn IP version - IPv4 + @details @ref Sn_ESR_TCPM_IPV4 indicates TCP SOCKETn is operated on IPv4 . + @sa _Sn_ESR_, Sn_ESR_TCPM_IPV6 + @sa getSn_ESR() +*/ +#define Sn_ESR_TCPM_IPV4 (0<<2) + +/** + @brief TCP SOCKETn IP version - IPv6 + @details @ref Sn_ESR_TCPM_IPV6 indicates TCP SOCKETn is operated on IPv6 . + @sa _Sn_ESR_, Sn_ESR_TCPM_IPV4 + @sa getSn_ESR() +*/ +#define Sn_ESR_TCPM_IPV6 (1<<2) + +/** + @brief SOCKETn Extended Status : TCP Operation Mode + @details @ref Sn_ESR_TCPOP masks the TCPOP bit of @ref _Sn_ESR_. The masked bit values are as following. \n + - @ref Sn_ESR_TCPOP_SVR + - @ref Sn_ESR_TCPOP_CLT + @note It is useful to check TCP mode SOCKETn is operated as whether TCP SERVER or TCP CLIENT. + @sa _Sn_ESR_ + @sa getSn_ESR() +*/ +#define Sn_ESR_TCPOP (1<<1) + +/** + @brief TCP SOCKETn Operation Mode - TCP SERVER + @details @ref Sn_ESR_TCPOP_SVR indicates TCP mode SOCKET n is operated as TCP SERVER + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_ESR_, Sn_ESR_TCPOP_CLT + @sa getSn_ESR() +*/ +#define Sn_ESR_TCPOP_SVR (0<<1) + +/** + @brief TCP SOCKETn Operation Mode - TCP CLIENT + @details @ref Sn_ESR_TCPOP_SVR indicates TCP mode SOCKET n is operated as TCP CLIENT + @note It is valid only in TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_ESR_, Sn_ESR_TCPOP_SVR + @sa getSn_ESR() +*/ +#define Sn_ESR_TCPOP_CLT (1<<1) + +/** + @brief SOCKETn Extended Status : Source IPv6 Address Type + @details @ref Sn_ESR_IP6T masks the IP6T bit of @ref _Sn_ESR_. \n + The masked bit values are as following. \n + - @ref Sn_ESR_IP6T_LLA + - @ref Sn_ESR_IP6T_GUA + @note It is useful to check whether the connected peer IP address is LLA or GUA. + @note It is valid only in TCP mode such as @ref Sn_MR_TCP6 and @ref Sn_MR_TCPD. + @sa _Sn_ESR_ + @sa getSn_ESR() +*/ +#define Sn_ESR_IP6T (1<<0) + +/** + @brief Source IPv6 Address Type - LLA + @details @ref Sn_ESR_IP6T_LLA indicates the source IPv6 Address is used as @ref _LLAR_ + @note It is valid only in TCP mode such as @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_ESR_, Sn_ESR_IP6T_GUA, _LLAR_ + @sa getSn_ESR(), getLLAR(), setLLAR() +*/ +#define Sn_ESR_IP6T_LLA (0<<0) + +/** + @brief Source IPv6 Address Type - LLA + @details @ref Sn_ESR_IP6T_GUA indicates the source IPv6 Address is used as @ref _GUAR_ + @note It is valid only in TCP mode such as @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD. + @sa _Sn_ESR_, Sn_ESR_IP6T_LLA, _GUAR_ + @sa getSn_ESR(), getGUAR(), setGUAR() +*/ +#define Sn_ESR_IP6T_GUA (1<<0) + +/* Sn_MR2 values */ +/** + @brief Destination Hardware Address Mode + @details @ref Sn_MR2_DHAM masks the DHAM bit of @ref _Sn_MR2_.\n + The masked bit values are as following. + - @ref Sn_MR2_DHAM_AUTO + - @ref Sn_MR2_DHAM_MANUAL + @sa _Sn_MR2_ + @sa getSn_MR2(), setSn_MR2() +*/ +#define Sn_MR2_DHAM (1<<1) + +/** + @brief Destination Hardware Address Mode - AUTO + @details @ref Sn_MR2_DHAM_AUTO sets the destination hardware address as the address acquired by ARP-process. + @sa _Sn_MR2_, Sn_MR_DHAM_MANUAL, NETMR_DHAS + @sa getSn_MR2(), setSn_MR2(), getNETMR(), setNETMR() +*/ +#define Sn_MR2_DHAM_AUTO (0<<1) + +/** + @brief Destination Hardware Address Mode - MANUAL + @details @ref Sn_MR2_DHAM_MANUAL sets the destination hardware address as @ref _Sn_DHAR_. + @sa _Sn_MR2_, Sn_MR_DHAM_MANUAL, NETMR_DHAS + @sa getSn_MR2(), setSn_MR2(), getNETMR(), setNETMR() +*/ +#define Sn_MR2_DHAM_MANUAL (1<<1) + +/** + @brief Force ARP + @details @ref Sn_MR2_FARP force to perform the ARP-process for acquiring the destination hardware address, before data communication\n + 0 : Normal \n + 1 : Force ARP + - In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD + If SOCKETn is operated as TCP SERVER, It sets the destination hardware address as the address + acquired by the forced ARP-process before sending SYN/ACK packet. + - In UDP mode such as @ref Sn_MR_UDP4, @ref Sn_MR_UDP6, and @ref Sn_MR_UDPD + It sets the destination hardware address as the address acquired by the forced ARP-process whenever @ref Sn_CR_SEND or @ref Sn_CR_SEND6. + @note When @ref Sn_MR2_DHAM_MANUAL and @ref Sn_MR2_FARP = '1', It sets the destination hardware address as @ref _Sn_DHAR_ even if the ARP-process is forced. +*/ +#define Sn_MR2_FARP (1<<0) + + +/*----------------------------For PHY Control-------------------------------*/ + +/** + @ingroup Common_register_group_W6300 + @brief Basic Mode Control Register of Ethernet PHY [RW][0x3100] + @details @ref PHYRAR_BMCR can be controlled by MDC/MDIO controller of @ref _WIZCHIP_. \n + Each bit of @ref PHYRAR_BMCR is defined as the following. + + + +
15 14 13 12 11 10 9 8 7 6 ~ 0
RST LB SPD ANE PWDN ISOL RAN DPX COLT Reserved
+ - @ref BMCR_RST + - @ref BMCR_LB + - @ref BMCR_SPD + - @ref BMCR_ANE + - @ref BMCR_PWDN + - @ref BMCR_ISOL : Not supported. + - @ref BMCR_REAN + - @ref BMCR_DPX + - @ref BMCR_COLT + + @note Its some bits have the same function as @ref _PHYCR0_ and @ref _PHYCR1_.\n + It can control the Ethernet PHY with software, while @ref _PHYCR0_ \n + and @ref _PHYCR1_ can control the Ethernet PHY with hardware. + + @sa PHYRAR_BMSR, _PHYRAR_, _PHYDIR_, _PHYDOR_, _PHYACR_, _PHYCR0_, _PHYCR1_ + @sa getPHYRAR(), setPHYRAR(), wiz_mdio_read(), wiz_mdio_write() +*/ +#define PHYRAR_BMCR (0x00) + +//Basic mode status register, basic register +/** + @ingroup Common_register_group_W6300 + @brief Basic Mode Status Register of Ethernet PHY [RO][0x7809] + @details @ref PHYRAR_BMSR gets the status of Ethernet PHY through MDC/MDIO controller of @ref _WIZCHIP_. \n + Each bit of @ref PHYRAR_BMSR is defined as the following. + + + + + +
15 14 13 12 11 10~76 5 4 3 2 1 0
100_T4 100_FDX 100_HDX 10_FDX 10_HDX Reserved MF_SUPANG_COMP REMOTE_FAULT ANG_ABILITY LINK_STATUS JABBER_DETECT EXT_CAPA
+ - @ref BMSR_100_T4 : Not supported. Always 0 + - @ref BMSR_100_FDX + - @ref BMSR_100_HDX + - @ref BMSR_10_FDX + - @ref BMSR_10_HDX + - @ref BMSR_MF_SUP : Not supported. Always 0. + - @ref BMSR_AN_COMP + - @ref BMSR_REMOTE_FAULT : Not supported. Always 0. + - @ref BMSR_AN_ABILITY + - @ref BMSR_LINK_STATUS + - @ref BMSR_JABBER_DETECT + - @ref BMSR_EXT_CAPA : Always 1. If you need a extended register information, send e-mail to support@wiznet.io + + @note Its some bits have the same function as @ref _PHYSR_. + @sa PHYRAR_BMCR, _PHYRAR_, _PHYDIR_, _PHYDOR_, _PHYACR_, _PHYCR0_, _PHYCR1_ + @sa getPHYRAR(), setPHYRAR(), wiz_mdio_read(), wiz_mdio_write() +*/ +#define PHYRAR_BMSR (0x01) + + +/********************/ +/* BMCR & BMSR Bit definitions */ +/********************/ + +/*For BMCR register*/ +/** + @brief Ethernet PHY S/W Reset. + @details 0 - Normal operation \n + 1 - Software reset + @sa PHYRAR_BMCR, PHYCR1_RST + @sa getPHYRAR_BMCR(), setPHYRAR_BMCR() +*/ +#define BMCR_RST (1<<15) + +/** + @brief Ethernet PHY Loopback. + @details 0 - Normal Operation \n + 1 - Loopback Enable + @sa PHYRAR_BMCR + @sa getPHYRAR_BMCR(), setPHYRAR_BMCR() +*/ +#define BMCR_LB (1<<14) ///< Loopback. 0 - Noraml operation, 1 - Loopback enabled + +/** + @brief Ethernet PHY Speed + @details 0 - 10 Mbps \n + 1 - 100 Mbps + @sa PHYCR_BMCR, PHYCR0_100F, PHYCR0_100H, PHYCR0_10F, PHYCR0_10H + @sa getPHYRAR_BMCR(), setPHYRAR_BMCR(), setPHYCR0() +*/ +#define BMCR_SPD (1<<13) + +/** + @brief Ethernet PHY Auto-Negotiation + @details 0 - Disable \n + 1 - Enable + @note When it is set, @ref BMCR_SPD and @ref BMCR_DPX is ignored + @sa PHYCR_BMCR, PHYCR0_AUTO + @sa getPHYRAR_BMCR(), setPHYRAR_BMCR(), setPHYCR0() +*/ +#define BMCR_ANE (1<<12) + +/** + @brief Ethernet PHY Power Down Mode + @details 0 - Normal Operation \n + 1 - Power Down mode + @sa PHYCR_BMCR, PHYCR0_PWDN + @sa getPHYRAR_BMCR(), setPHYRAR_BMCR(), setPHYCR0() +*/ +#define BMCR_PWDN (1<<11) ///< Power-down mode + +/** + @brief Ethernet PHY Isolation Mode + @details 0 - Normal Operation \n + 1 - Isolation Mode + @ Don't set it to '1'. It is not supported. + @sa PHYCR_BMCR + @sa getPHYRAR_BMCR(), setPHYRAR_BMCR() +*/ +#define BMCR_ISOL (1<<10) + +/** + @brief Ethernet PHY Restart Auto-Negotiation + @details 0 - Normal Operation \n + 1 - Restart Auto-Negotiation + @sa PHYCR_BMCR + @sa getPHYRAR_BMCR(), setPHYRAR_BMCR() +*/ +#define BMCR_REAN (1<<9) + +/** + @brief Ethernet PHY Duplex + @details 0 - Half-Duplex \n + 1 - Full-Duplex + @sa PHYCR_BMCR, PHYCR0_100F, PHYCR0_100H, PHYCR0_10F, PHYCR0_10H + @sa getPHYRAR_BMCR(), setPHYRAR_BMCR(), setPHYCR0() +*/ +#define BMCR_DPX (1<<8) + +/** + @brief Ethernet PHY Collision Test + @details 0 - Normal Operation \n + 1 - Collision Test + @sa PHYCR_BMCR + @sa getPHYRAR_BMCR(), setPHYRAR_BMCR() +*/ +#define BMCR_COLT (1<<7) + +/*For BMSR register*/ + +/** + @brief Ethernet PHY 100 Base-T4 capable + @details @ref BMSR_100_T4 is always 0. + @note It is not supported. + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_100_T4 (1<<15) + +/** + @brief Ethernet PHY 100 Base-TX Full-Duplex capable + @details @ref BMSR_100_FDX is always 1. + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_100_FDX (1<<14) + +/** + @brief Ethernet PHY 100 Base-TX Half-Duplex capable + @details @ref BMSR_100_HDX is always 1. + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_100_HDX (1<<13) + +/** + @brief Ethernet PHY 10 Base-T Full-Duplex capable + @details @ref BMSR_10_FDX is always 1. + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_10_FDX (1<<12) + +/** + @brief Ethernet PHY 10 Base-T Half-Duplex capable + @details @ref BMSR_10_HDX is always 1. + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_10_HDX (1<<11) + +/** + @brief Ethernet PHY Management Frame preamble suppression + @details @ref BMSR_MF_SUP is always 0. + @note It is not supported + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_MF_SUP (1<<6) + +/** + @brief Ethernet PHY Auto-Negotiation Complete + @details @ref BMSR_MF_SUP indicates the status of auto-negotiation. \n + 0 - Auto-negotiation process is not completed \n + 1 - Auto-negotiation process is completed + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_AN_COMP (1<<5) + +/** + @brief Ethernet PHY Remote Fault + @details @ref BMSR_REMOTE_FAULT is always 0. + @note It is not supported + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_REMOTE_FAULT (1<<4) + +/** + @brief Ethernet PHY Auto-Negotiation Ability + @details @ref BMSR_AN_ABILITY is always 1. + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_AN_ABILITY (1<<3) + +/** + @brief Ethernet PHY Link Status + @details @ref BMSR_LINK_STATUS indicates the status of link. \n + 0 - Link is not established + 1 - Valid link is established + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_LINK_STATUS (1<<2) + +/** + @brief Ethernet PHY Jabber Detect + @details @ref BMSR_JABBER_DETECT indicates the status of auto-negotiation. \n + 0 - Jabber condition is not detected\n + 1 - Jabber condition is detected + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_JABBER_DETECT (1<<1) + +/** + @brief Ethernet PHY Extended capability + @details @ref BMSR_EXT_CAPA indicates the extended register capability. \n + 0 - Only basic registers are capable\n + 1 - Extended registers are capable + @sa PHYCR_BMSR + @sa getPHYRAR_BMSR() +*/ +#define BMSR_EXT_CAPA (1<<0) + + +/** + @brief Enter a critical section + @details It is provided to protect your shared code and hardware resources against interference. \n + - Non-OS environment + It can be just implemented by disabling whole interrupt. + - OS environment + You can replace it to critical section API supported by OS. + + @note It is callback function that can be replaced it with your code, by calling @ref reg_wizchip_cris_cbfunc(). + @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + @sa WIZCHIP_CRITICAL_EXIT(), reg_wizchip_cris_cbfunc() +*/ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + + +/** + @brief Enter a critical section + @details It exits the protected code and hardware resources against interference. \n + - Non-OS environment + It can be just implemented by enabling whole interrupt.\n + - OS environment + You can replace it to critical section API supported by OS. + + @note It is callback function that can be replaced it with your code, by calling @ref reg_wizchip_cris_cbfunc(). + @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + @sa WIZCHIP_CRITICAL_EXIT(), reg_wizchip_cris_cbfunc() +*/ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + + + +//////////////////////// +// Basic I/O Function // +//////////////////////// +// +// +/** + @ingroup Basic_IO_function_W6300 + @brief It reads 1 byte value from a register. + @param AddrSel Register address + @return The value of register + @sa WIZCHIP_READ_BUF(), reg_wizchip_bus_cbfunc(), reg_wizchip_spi_cbfunc(), WIZCHIP_WRITE() +*/ +uint8_t WIZCHIP_READ(uint32_t AddrSel); + +/** + @ingroup Basic_IO_function_W6300 + @brief It writes 1 byte value to a register. + @param AddrSel Register address + @param wb Write data + @return void + @sa WIZCHIP_WRITE_BUF(), reg_wizchip_bus_cbfunc(), reg_wizchip_spi_cbfunc(), WIZCHIP_READ() +*/ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb); + +/** + @ingroup Basic_IO_function_W6300 + @brief It reads sequentail data from registers. + @param AddrSel Register address + @param pBuf Pointer buffer to read data + @param len Data length + @return void + @sa WIZCHIP_WRITE_BUF(), reg_wizchip_bus_cbfunc(), reg_wizchip_spi_cbfunc(), WIZCHIP_READ() +*/ +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t* pBuf, datasize_t len); + +/** + @ingroup Basic_IO_function_W6300 + @brief It writes sequential data to registers. + @param AddrSel Register address + @param pBuf Pointer buffer to write data + @param len Data length + @return void + @sa WIZCHIP_READ_BUF(), reg_wizchip_bus_cbfunc(), reg_wizchip_spi_cbfunc(), WIZCHIP_WRITE() +*/ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, datasize_t len); + + + +///////////////////////////////// +// Common Register IO function // +///////////////////////////////// +/** + @addtogroup Common_register_access_function_W6300 + @{ +*/ + +#define getRTL() \ + WIZCHIP_READ(_RTL_) + +#define getCIDR() \ + ((((uint16_t)WIZCHIP_READ(_CIDR_)| (((WIZCHIP_READ(_RTL_))&0x0F) << 1)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_CIDR_,1))) + +#define getVER() \ + ((((uint16_t)WIZCHIP_READ(_VER_)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_VER_,1))) + +#define getSYSR() \ + WIZCHIP_READ(_SYSR_) + +#define getSYCR0() \ + WIZCHIP_READ(_SYCR0_) + +#define setSYCR0(sycr0) \ + WIZCHIP_WRITE(_SYCR0_, (sycr0)) + +#define getSYCR1() \ + WIZCHIP_READ(_SYCR1_) + +#define setSYCR1(sycr1) \ + WIZCHIP_WRITE(_SYCR1_, (sycr1)) + +#define getTCNTR() \ + ((((uint16_t)WIZCHIP_READ(_TCNTR_)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_TCNTR_,1))) + +#define setTCNTRCLR(tcntrclr) \ + WIZCHIP_WRITE(_TCNTRCLR_,(tcntrclr)) + +#define getIR() \ + WIZCHIP_READ(_IR_) + +#define getSIR() \ + WIZCHIP_READ(_SIR_) + +#define getSLIR() \ + WIZCHIP_READ(_SLIR_) + +#define setIMR(imr) \ + WIZCHIP_WRITE(_IMR_,(imr)) + +#define getIMR() \ + WIZCHIP_READ(_IMR_) + +#define setIRCLR(irclr) \ + WIZCHIP_WRITE(_IRCLR_,(irclr)) +#define setIR(ir) setIRCLR(ir) + +#define setSIMR(simr) \ + WIZCHIP_WRITE(_SIMR_,(simr)) + +#define getSIMR() \ + WIZCHIP_READ(_SIMR_) + +#define setSLIMR(slimr) \ + WIZCHIP_WRITE(_SLIMR_,(slimr)) + +#define getSLIMR() \ + WIZCHIP_READ(_SLIMR_) + +#define setSLIRCLR(slirclr) \ + WIZCHIP_WRITE(_SLIRCLR_,(slirclr)) +#define setSLIR(slir) setSLIRCLR(slir) + +#define setSLPSR(slpsr) \ + WIZCHIP_WRITE(_SLPSR_,(slpsr)) + +#define getSLPSR() \ + WIZCHIP_READ(_SLPSR_) + +#define setSLCR(slcr) \ + WIZCHIP_WRITE(_SLCR_,(slcr)) + +#define getSLCR() \ + WIZCHIP_READ(_SLCR_) + +#define getPHYSR() \ + WIZCHIP_READ(_PHYSR_) + +#define setPHYRAR(phyrar) \ + WIZCHIP_WRITE(_PHYRAR_,(phyrar)) + +#define getPHYRAR() \ + WIZCHIP_READ(_PHYRAR_) + +#define setPHYDIR(phydir) \ + do{ \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_PHYDIR_,1), (uint8_t)((phydir)>>8)); \ + WIZCHIP_WRITE(_PHYDIR_, (uint8_t)(phydir)); \ + }while(0); + +#define getPHYDOR() \ + ((((uint16_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(_PHYDOR_,1))) << 8) + WIZCHIP_READ(_PHYDOR_)) + +#define setPHYACR(phyacr) \ + WIZCHIP_WRITE(_PHYACR_,(phyacr)) + +#define getPHYACR() \ + WIZCHIP_READ(_PHYACR_) + +#define setPHYDIVR(phydivr) \ + WIZCHIP_WRITE(_PHYDIVR_,(phydivr)) + +#define getPHYDIVR() \ + WIZCHIP_READ(_PHYDIVR_) + +#define setPHYCR0(phycr0) \ + WIZCHIP_WRITE(_PHYCR0_,(phycr0)) + +#define setPHYCR1(phycr1) \ + WIZCHIP_WRITE(_PHYCR1_,(phycr1)) + +#define getPHYCR1() \ + WIZCHIP_READ(_PHYCR1_) + +#define setNET4MR(net4mr) \ + WIZCHIP_WRITE(_NET4MR_,(net4mr)) + +#define setNET6MR(net6mr) \ + WIZCHIP_WRITE(_NET6MR_,(net6mr)) + +#define setNETMR(netmr) \ + WIZCHIP_WRITE(_NETMR_,(netmr)) + +#define setNETMR2(netmr2) \ + WIZCHIP_WRITE(_NETMR2_,(netmr2)) + +#define getNET4MR() \ + WIZCHIP_READ(_NET4MR_) + +#define getNET6MR() \ + WIZCHIP_READ(_NET6MR_) + +#define getNETMR() \ + WIZCHIP_READ(_NETMR_) + +#define getNETMR2() \ + WIZCHIP_READ(_NETMR2_) + +#define setPTMR(ptmr) \ + WIZCHIP_WRITE(_PTMR_, (ptmr)) + +#define getPTMR() \ + WIZCHIP_READ(_PTMR_) + +#define setPMNR(pmnr) \ + WIZCHIP_WRITE(_PMNR_, (pmnr)) + +#define getPMNR() \ + WIZCHIP_READ(_PMNR_) + +#define setPHAR(phar) \ + WIZCHIP_WRITE_BUF(_PHAR_,(phar),6) + +#define getPHAR(phar) \ + WIZCHIP_READ_BUF(_PHAR_,(phar),6) + +#define setPSIDR(psidr) \ + do{ \ + WIZCHIP_WRITE(_PSIDR_,(uint8_t)((psidr) >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_PSIDR_,1),(uint8_t)(psidr)); \ + }while(0); + +#define getPSIDR() \ + ((((uint16_t)WIZCHIP_READ(_PSIDR_)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_PSIDR_,1))) + +#define setPMRUR(pmrur) \ + do{ \ + WIZCHIP_WRITE(_PMRUR_,(uint8_t)((pmrur) >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_PMRUR_,1),(uint8_t)(pmrur)); \ + }while(0); + +#define getPMRUR() \ + ((((uint16_t)WIZCHIP_READ(_PMRUR_)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_PMRUR_,1))) + +#define setSHAR(shar) \ + WIZCHIP_WRITE_BUF(_SHAR_,(shar),6) + +#define getSHAR(shar) \ + WIZCHIP_READ_BUF(_SHAR_,(shar),6) + +#define setGAR(gar) \ + WIZCHIP_WRITE_BUF(_GAR_,(gar),4) + +#define getGAR(gar) \ + WIZCHIP_READ_BUF(_GAR_,(gar),4) + +#define setGA4R(ga4r) setGAR(ga4r) +#define getGA4R(ga4r) getGAR(ga4r) + +#define setSUBR(subr) \ + WIZCHIP_WRITE_BUF(_SUBR_,(subr),4) + +#define getSUBR(subr) \ + WIZCHIP_READ_BUF(_SUBR_,(subr),4) + +#define setSUB4R(sub4r) setSUBR(sub4r) +#define getSUB4R(sub4r) getSUBR(sub4r) + +#define setSIPR(sipr) \ + WIZCHIP_WRITE_BUF(_SIPR_,(sipr),4) + +#define getSIPR(sipr) \ + WIZCHIP_READ_BUF(_SIPR_,(sipr),4) + +#define setLLAR(llar) \ + WIZCHIP_WRITE_BUF(_LLAR_,(llar),16) + +#define getLLAR(llar) \ + WIZCHIP_READ_BUF(_LLAR_,(llar),16) + +#define setGUAR(guar) \ + WIZCHIP_WRITE_BUF(_GUAR_,(guar),16) + +#define getGUAR(guar) \ + WIZCHIP_READ_BUF(_GUAR_,(guar),16) + +#define setSUB6R(sub6r) \ + WIZCHIP_WRITE_BUF(_SUB6R_,(sub6r),16) + +#define getSUB6R(sub6r) \ + WIZCHIP_READ_BUF(_SUB6R_,(sub6r),16) + +#define setGA6R(ga6r) \ + WIZCHIP_WRITE_BUF(_GA6R_,(ga6r),16) + +#define getGA6R(ga6r) \ + WIZCHIP_READ_BUF(_GA6R_,(ga6r),16) + +#define setSLDIPR(sldipr) \ + WIZCHIP_WRITE_BUF(_SLDIPR_,(sldipr),4) +#define setSLDIP4R(sldip4r) setSLDIPR((sldip4r)) + +#define getSLDIPR(sldipr) \ + WIZCHIP_READ_BUF(_SLDIPR_,(sldipr),4) +#define getSLDIP4R(sldip4r) getSLDIPR((sldip4r)) + +#define setSLDIP6R(sldip6r) \ + WIZCHIP_WRITE_BUF(_SLDIP6R_, (sldip6r),16) + +#define getSLDIP6R(sldip6r) \ + WIZCHIP_READ_BUF(_SLDIP6R_,(sldip6r),16) + +#define getSLDHAR(sldhar) \ + WIZCHIP_READ_BUF(_SLDHAR_,(sldhar),6) + +#define setPINGIDR(pingidr) \ + do{ \ + WIZCHIP_WRITE(_PINGIDR_,(uint8_t)((pingidr)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_PINGIDR_,1),(uint8_t)(pingidr)); \ + }while(0); + +#define getPINGIDR() \ + (((int16_t)(WIZCHIP_READ(_PINGIDR_) << 8)) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_PINGIDR_,1))) + +#define setPINGSEQR(pingseqr) \ + do{ \ + WIZCHIP_WRITE(_PINGSEQR_,(uint8_t)((pingseqr)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_PINGSEQR_,1),(uint8_t)(pingseqr)); \ + }while(0); + +#define getPINGSEQR() \ + (((int16_t)(WIZCHIP_READ(_PINGSEQR_) << 8)) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_PINGSEQR_,1))) + +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(_UIPR_, (uipr), 4) + +#define getUIP4R(uip4r) getUIPR(uip4r) + +#define getUPORTR() \ + ((((uint16_t)WIZCHIP_READ(_UPORTR_)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_UPORTR_,1))) + +#define getUPORT4R() getUPORTR() + +#define getUIP6R(uip6r) \ + WIZCHIP_READ_BUF(_UIP6R_,(uip6r),16) + +#define getUPORT6R(uport6r) \ + ((((uint16_t)WIZCHIP_READ(_UPORT6R_)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_UPORT6R_,1))) + +#define setINTPTMR(intptmr) \ + do{ \ + WIZCHIP_WRITE(_INTPTMR_,(uint8_t)((intptmr) >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_INTPTMR_,1),(uint8_t)(intptmr)); \ + }while(0); + +#define getINTPTMR() \ + ((((uint16_t)WIZCHIP_READ(_INTPTMR_)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_INTPTMR_,1))) + +#define getPLR() \ + WIZCHIP_READ(_PLR_) + +#define getPFR() \ + WIZCHIP_READ(_PFR_) + +#define getVLTR() \ + ( (((uint32_t)WIZCHIP_READ(_VLTR_)) << 24) + \ + (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(_VLTR_,1))) << 16) + \ + (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(_VLTR_,2))) << 16) + \ + (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(_VLTR_,3))) << 16) ) + +#define getPLTR() \ + ( (((uint32_t)WIZCHIP_READ(_PLTR_)) << 24) + \ + (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(_PLTR_,1))) << 16) + \ + (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(_PLTR_,2))) << 16) + \ + (((uint32_t)WIZCHIP_READ(WIZCHIP_OFFSET_INC(_PLTR_,3))) << 16) ) + +#define getPAR(par) \ + WIZCHIP_READ_BUF(_PAR_, (par), 16) + +#define setICMP6BLKR(icmp6blkr) \ + WIZCHIP_WRITE(_ICMP6BLKR_,(icmp6blkr)) + +#define getICMP6BLKR() \ + WIZCHIP_READ(_ICMP6BLKR_) + +#define setCHPLCKR(chplckr) \ + WIZCHIP_WRITE(_CHPLCKR_, (chplckr)) + +#define getCHPLCKR() \ + ((getSYSR() & SYSR_CHPL) >> 7) + +#define CHIPLOCK() setCHPLCKR(0xFF) +#define CHIPUNLOCK() setCHPLCKR(0xCE) + +#define setNETLCKR(netlckr) \ + WIZCHIP_WRITE(_NETLCKR_, (netlckr)) + +#define getNETLCKR() \ + ((getSYSR() & SYSR_NETL) >> 6) + +#define NETLOCK() setNETLCKR(0xC5) +#define NETUNLOCK() setNETLCKR(0x3A) + +#define setPHYLCKR(phylckr) \ + WIZCHIP_WRITE(_PHYLCKR_,(phylckr)) + +#define getPHYLCKR() \ + ((getSYSR() & SYSR_PHYL) >> 5) + +#define PHYLOCK() setPHYLCKR(0xFF) +#define PHYUNLOCK() setPHYLCKR(0x53) + +#define setRTR(rtr) \ + do{ \ + WIZCHIP_WRITE(_RTR_,(uint8_t)((rtr)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1),(uint8_t)(rtr)); \ + }while(0); + +#define getRTR() \ + ((((uint16_t)WIZCHIP_READ(_RTR_)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) + +#define setRCR(rcr) \ + WIZCHIP_WRITE(_RCR_,(rcr)) + +#define getRCR() \ + WIZCHIP_READ(_RCR_) + +#define setSLRTR(slrtr) \ + do{ \ + WIZCHIP_WRITE(_SLRTR_,(uint8_t)((slrtr)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_SLRTR_,1),(uint8_t)(slrtr)); \ + }while(0); + +#define getSLRTR() \ + ((((uint16_t)WIZCHIP_READ(_SLRTR_)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_SLRTR_,1))) + +#define setSLRCR(slrcr) \ + WIZCHIP_WRITE(_SLRCR_,(slrcr)) + +#define getSLRCR() \ + WIZCHIP_READ(_SLRCR_) + +#define setSLHOPR(slhopr) \ + WIZCHIP_WRITE(_SLHOPR_,(slhopr)) + +#define getSLHOPR() \ + WIZCHIP_READ(_SLHOPR_) +/** + @} +*/ + + +//////////////////////////////////// +// SOCKETn register I/O function // +//////////////////////////////////// +/** + @addtogroup Socket_register_access_function_W6300 + @{ +*/ +#define setSn_MR(sn,mr) \ + WIZCHIP_WRITE(_Sn_MR_(sn),(mr)) +#define getSn_MR(sn) \ + WIZCHIP_READ(_Sn_MR_(sn)) + +#define setSn_PSR(sn,psr) \ + WIZCHIP_WRITE(_Sn_PSR_(sn),(psr)) +#define getSn_PSR(sn) \ + WIZCHIP_READ(_Sn_PSR_(sn)) + +#define setSn_CR(sn,cr) \ + WIZCHIP_WRITE(_Sn_CR_(sn),(cr)) +#define getSn_CR(sn) \ + WIZCHIP_READ(_Sn_CR_(sn)) + +#define getSn_IR(sn) \ + WIZCHIP_READ(_Sn_IR_(sn)) + +#define setSn_IMR(sn,imr) \ + WIZCHIP_WRITE(_Sn_IMR_(sn),(imr)) +#define getSn_IMR(sn) \ + WIZCHIP_READ(_Sn_IMR_(sn)) + +#define setSn_IRCLR(sn,irclr) \ + WIZCHIP_WRITE(_Sn_IRCLR_(sn),(irclr)) +#define setSn_IR(sn,ir) setSn_IRCLR(sn,(ir)) + +#define getSn_SR(sn) \ + WIZCHIP_READ(_Sn_SR_(sn)) + +#define getSn_ESR(sn) \ + WIZCHIP_READ(_Sn_ESR_(sn)) + +#define setSn_PNR(sn,pnr) \ + WIZCHIP_WRITE(_Sn_PNR_(sn),(pnr)) +#define setSn_NHR(sn,nhr) setSn_PNR(_Sn_PNR_(sn),(nhr)) + +#define getSn_PNR(sn) \ + WIZCHIP_READ(_Sn_PNR_(sn)) +#define getSn_NHR(sn) getSn_PNR(sn) + +#define setSn_TOSR(sn,tosr) \ + WIZCHIP_WRITE(_Sn_TOSR_(sn),(tosr)) +#define getSn_TOSR(sn) \ + WIZCHIP_READ(_Sn_TOSR_(sn)) +#define getSn_TOS(sn) getSn_TOSR(sn) ///< For compatible ioLibrar +#define setSn_TOS(sn,tos) setSn_TOSR(sn,tos) ///< For compatible ioLibrar + + +#define setSn_TTLR(sn,ttlr) \ + WIZCHIP_WRITE(_Sn_TTLR_(sn),(ttlr)) +#define getSn_TTLR(sn) \ + WIZCHIP_READ(_Sn_TTLR_(sn)) +#define setSn_TTL(sn,ttl) setSn_TTLR(sn,ttl) ///< For compatible ioLibrary +#define getSn_TTL(sn) getSn_TTLR(sn) ///< For compatible ioLibrary + +#define setSn_HOPR(sn,hopr) setSn_TTLR(sn),(ttlr)) +#define getSn_HOPR(sn) getSn_TTLR(sn) + +#define setSn_FRGR(sn,frgr) \ + do{ \ + WIZCHIP_WRITE(_Sn_FRGR_(sn),(uint8_t)((frgr)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_Sn_FRGR_(sn),1),(uint8_t)(frgr)); \ + }while(0); +#define getSn_FRGR(sn,frgr) \ + ((((uint16_t)WIZCHIP_READ(_Sn_FRGR_(sn))) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_FRGR_(sn),1))) + +#define setSn_MSSR(sn,mssr) \ + do{ \ + WIZCHIP_WRITE(_Sn_MSSR_(sn),(uint8_t)((mssr)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_Sn_MSSR_(sn),1),(uint8_t)(mssr)); \ + }while(0); +#define getSn_MSSR(sn) \ + ((((uint16_t)WIZCHIP_READ(_Sn_MSSR_(sn))) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_MSSR_(sn),1))) + +#define setSn_PORTR(sn,portr) \ + do{ \ + WIZCHIP_WRITE(_Sn_PORTR_(sn),(uint8_t)((portr)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_Sn_PORTR_(sn),1),(uint8_t)(portr)); \ + }while(0); +#define getSn_PORTR(sn) \ + ((((uint16_t)WIZCHIP_READ(_Sn_PORTR_(sn))) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_PORTR_(sn),1))) + +#define setSn_DHAR(sn,dhar) \ + WIZCHIP_WRITE_BUF(_Sn_DHAR_(sn),(dhar),6) +#define getSn_DHAR(sn,dhar) \ + WIZCHIP_READ_BUF(_Sn_DHAR_(sn),(dhar),6) + +#define setSn_DIPR(sn,dipr) \ + WIZCHIP_WRITE_BUF(_Sn_DIPR_(sn),(dipr),4) +#define getSn_DIPR(sn,dipr) \ + WIZCHIP_READ_BUF(_Sn_DIPR_(sn),(dipr),4) + +#define setSn_DIP4R(sn,dipr) setSn_DIPR(sn,(dipr)) +#define getSn_DIP4R(sn,dipr) getSn_DIPR(sn,(dipr)) + +#define setSn_DIP6R(sn,dip6r) \ + WIZCHIP_WRITE_BUF(_Sn_DIP6R_(sn),(dip6r),16) +#define getSn_DIP6R(sn,dip6r) \ + WIZCHIP_READ_BUF(_Sn_DIP6R_(sn),(dip6r),16) + +#define setSn_DPORTR(sn,dportr) \ + do{ \ + WIZCHIP_WRITE(_Sn_DPORTR_(sn),(uint8_t)((dportr)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_Sn_DPORTR_(sn),1),(uint8_t)(dportr)); \ + }while(0); + + +#define getSn_DPORTR(sn) \ + ((((uint16_t)WIZCHIP_READ(_Sn_DPORTR_(sn))) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_DPORTR_(sn),1))) + +#define getSn_DPORT(sn) getSn_DPORTR(sn) +#define setSn_DPORT(sn,dportr) setSn_DPORTR(sn,dportr) + + +#define setSn_MR2(sn,mr2) \ + WIZCHIP_WRITE(_Sn_MR2_(sn),(mr2)) +#define getSn_MR2(sn) \ + WIZCHIP_READ(_Sn_MR2_(sn)) + +#define setSn_RTR(sn,rtr) \ + do{ \ + WIZCHIP_WRITE(_Sn_RTR_(sn),(uint8_t)((rtr)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_Sn_RTR_(sn),1),(uint8_t)(rtr)); \ + }while(0); +#define getSn_RTR(sn) \ + ((((uint16_t)WIZCHIP_READ(_Sn_RTR_(sn))) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_RTR_(sn),1))) + +#define setSn_RCR(sn,rcr) \ + WIZCHIP_WRITE(_Sn_RCR_(sn),(rcr)) +#define getSn_RCR(sn) \ + WIZCHIP_READ(_Sn_RCR_(sn)) + +#define setSn_KPALVTR(sn,kpalvtr) \ + WIZCHIP_WRITE(_Sn_KPALVTR_(sn),(kpalvtr)) +#define getSn_KPALVTR(sn) \ + WIZCHIP_READ(_Sn_KPALVTR_(sn)) + +#define setSn_TX_BSR(sn, tmsr) \ + WIZCHIP_WRITE(_Sn_TX_BSR_(sn),(tmsr)) +#define setSn_TXBUF_SIZE(sn, tmsr) setSn_TX_BSR(sn,(tmsr)) + +#define getSn_TX_BSR(sn) \ + WIZCHIP_READ(_Sn_TX_BSR_(sn)) +#define getSn_TXBUF_SIZE(sn) getSn_TX_BSR(sn) + +#define getSn_TxMAX(sn) \ + (getSn_TX_BSR(sn) << 10) + +uint16_t getSn_TX_FSR(uint8_t sn); + +#define getSn_TX_RD(sn) \ + ((((uint16_t)WIZCHIP_READ(_Sn_TX_RD_(sn))) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_TX_RD_(sn),1))) + +#define setSn_TX_WR(sn,txwr) \ + do{ \ + WIZCHIP_WRITE(_Sn_TX_WR_(sn), (uint8_t)((txwr)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_Sn_TX_WR_(sn),1), (uint8_t)(txwr)); \ + }while(0); +#define getSn_TX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(_Sn_TX_WR_(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_TX_WR_(sn),1))) + +#define setSn_RX_BSR(sn,rmsr) \ + WIZCHIP_WRITE(_Sn_RX_BSR_(sn),(rmsr)) +#define setSn_RXBUF_SIZE(sn,rmsr) setSn_RX_BSR(sn,(rmsr)) + +#define getSn_RX_BSR(sn) \ + WIZCHIP_READ(_Sn_RX_BSR_(sn)) +#define getSn_RXBUF_SIZE(sn) getSn_RX_BSR(sn) + +#define getSn_RxMAX(sn) \ + (getSn_RX_BSR(sn) <<10) + +uint16_t getSn_RX_RSR(uint8_t s); + +#define setSn_RX_RD(sn,rxrd) \ + do{ \ + WIZCHIP_WRITE(_Sn_RX_RD_(sn), (uint8_t)((rxrd)>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_Sn_RX_RD_(sn),1), (uint8_t)(rxrd)) ; \ + }while(0); + +#define getSn_RX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(_Sn_RX_RD_(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_RX_RD_(sn),1))) + +#define getSn_RX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(_Sn_RX_WR_(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_Sn_RX_WR_(sn),1))) +/** + @} +*/ + + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + @ingroup Basic_IO_function_W6300 + @brief It saves data to be sent in the SOCKETn TX buffer. + @details This function reads first @ref _Sn_TX_WR_ \n + and starts to copy wizdata from @ref _Sn_TX_WR_ address of SOCKETn TX buffer as many as len.\n + After it is completed to copy , \n + It increases @ref _Sn_TX_WR_ as many as len. + @param sn SOCKETn. It should be 0 ~ @ref _WIZCHIP_SOCK_NUM_. + @param wizdata Pointer buffer to write data + @param len Data length + @sa wiz_recv_data() +*/ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + @ingroup Basic_IO_function_W6300 + @brief It reads the received data from the SOCKETn RX buffer and copies the data to your system memory specified by wizdata. + @details This function reads first @ref _Sn_RX_RD_ \n + and starts to copy the received data to wizdata as many as len.\n + After it is completed to copy the received data, \n + It increases @ref _Sn_RX_RD_ as many as len. + @param sn SOCKETn. It should be 0 ~ @ref _WIZCHIP_SOCK_NUM_. + @param wizdata Pointer buffer to read data + @param len Data length + @sa wiz_send_data() +*/ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + @ingroup Basic_IO_function_W6300 + @brief It discards the received data in the SOCKETn RX buffer. + @details This function discards the received data by increasing @ref _Sn_RX_RD_ as manay as len without coping the data. + @param sn SOCKETn. It should be 0 ~ @ref _WIZCHIP_SOCK_NUM_. + @param len Data length +*/ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +#if 1 +// 20231019 taylor +/** + @ingroup Special_function_W6300 + @brief Delay function + @details Delay function using internal 100us timer of the W6300 + @param (uint32_t)ms Time to delay in milliseconds. +*/ +void wiz_delay_ms(uint32_t ms); +#endif + +/// @cond DOXY_APPLY_CODE +#if (_PHY_IO_MODE_ == _PHY_IO_MODE_MII_) +/// @endcond +/** + @ingroup Special_function_W6300 + @brief Write data to the PHY via MDC/MDIO interface. + @details Write command data to the PHY via MDC/MDIO interface. + @param phyregaddr Address of the PHY register. It should be @ref PHYRAR_BMCR, @ref PHYRAR_BMSR, and etc. + @param var Data to write to the PHY register. Please refer to the bit definitions of the BMCR and BMSR register. + @note In order to use it, You should define @ref _PHY_IO_MODE_ to @ref _PHY_IO_MODE_MII_. +*/ +void wiz_mdio_write(uint8_t phyregaddr, uint16_t var); + +/** + @ingroup Special_function_W6300 + @brief Read data from the PHY via MDC/MDIO interface. + @details Read command or status data from the PHY via MDC/MDIO interface. + @param phyregaddr Address of the PHY register. It should be @ref PHYRAR_BMCR, @ref PHYRAR_BMSR, and etc. + @return The value of the PHY register + @note In order to use it, You should define @ref _PHY_IO_MODE_ to @ref _PHY_IO_MODE_MII_. +*/ +uint16_t wiz_mdio_read(uint8_t phyregaddr); +/// @cond DOXY_APPLY_CODE +#endif +/// @endcond + +/// @cond DOXY_APPLY_CODE +#endif // _WIZCHIP_ == 6100 +/// @endcond + + +#ifdef __cplusplus +} +#endif + + +#endif //_W6300_H_ \ No newline at end of file diff --git a/lib/w6300/ioLibrary/socket.c b/lib/w6300/ioLibrary/socket.c new file mode 100644 index 0000000..4f6ee50 --- /dev/null +++ b/lib/w6300/ioLibrary/socket.c @@ -0,0 +1,1473 @@ +//***************************************************************************** +// +//! \file socket.c +//! \brief SOCKET APIs Implements file. +//! \details SOCKET APIs like as Berkeley Socket APIs. +//! \version 1.0.3 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.3. Refer to M20140501 +//! 1. Implicit type casting -> Explicit type casting. +//! 2. replace 0x01 with PACK_REMAINED in recvfrom() +//! 3. Validation a destination ip in connect() & sendto(): +//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address. +//! Copy 4 byte addr value into temporary uint32 variable and then compares it. +//! <2013/12/20> V1.0.2 Refer to M20131220 +//! Remove Warning. +//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". +//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT) +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * 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. +//! * Neither the name of the 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 OWNER 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. +// +//***************************************************************************** +#include "socket.h" + +//M20150401 : Typing Error +//#define SOCK_ANY_PORT_NUM 0xC000; +#define SOCK_ANY_PORT_NUM 0xC000 + +static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; +static uint16_t sock_io_mode = 0; +static uint16_t sock_is_sending = 0; + +static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0, 0,}; + +//M20150601 : For extern decleation +//static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; +uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; +// + +#if _WIZCHIP_ == 5200 +static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] = {0,}; +#endif + +//A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 +uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = {0,}; // set by wiz_recv_data() +#endif + + +#define CHECK_SOCKNUM() \ + do{ \ + if(sn >= _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ + }while(0); \ + +#define CHECK_SOCKMODE(mode) \ + do{ \ + if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ + }while(0); \ + +#define CHECK_TCPMODE() \ + do{ \ + if((getSn_MR(sn) & 0x03) != 0x01) return SOCKERR_SOCKMODE; \ + }while(0); + +#define CHECK_SOCKINIT() \ + do{ \ + if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ + }while(0); \ + +#define CHECK_SOCKDATA() \ + do{ \ + if(len == 0) return SOCKERR_DATALEN; \ + }while(0); \ +//teddy 240122 +#if _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 +#define CHECK_TCPMODE() \ + do{ \ + if((getSn_MR(sn) & 0x03) != 0x01) return SOCKERR_SOCKMODE; \ + }while(0); + +#define CHECK_UDPMODE() \ + do{ \ + if((getSn_MR(sn) & 0x03) != 0x02) return SOCKERR_SOCKMODE; \ + }while(0); + +#define CHECK_IPMODE() \ + do{ \ + if((getSn_MR(sn) & 0x07) != 0x03) return SOCKERR_SOCKMODE; \ + }while(0); + +#define CHECK_DGRAMMODE() \ + do{ \ + if(getSn_MR(sn) == Sn_MR_CLOSED) return SOCKERR_SOCKMODE; \ + if((getSn_MR(sn) & 0x03) == 0x01) return SOCKERR_SOCKMODE; \ + }while(0); + +#define CHECK_IPZERO(addr, addrlen) \ + do{ \ + uint16_t ipzero= 0; \ + for(uint8_t i=0; i W5500) +#define IPV6_AVAILABLE +#endif + +#if 1 + + +#define Sn_MR_TCP4 (Sn_MR_TCP) ///< Refer to @ref Sn_MR_TCP. +#define Sn_MR_UDP4 (Sn_MR_UDP) ///< Refer to @ref Sn_MR_UDP +#define Sn_MR_IPRAW4 (Sn_MR_IPRAW) ///< Refer to @ref Sn_MR_IPRAW. +#define Sn_MR_TCP6 (0x09) +#define Sn_MR_UDP6 (0x0A) //0x1010 +#define Sn_MR_IPRAW6 (0x0B) //0x1011 +#define Sn_MR_TCPD (0x0D) +#define Sn_MR_UDPD (0x0E) + + + +#endif + + +#if 0 // By lihan +static uint8_t addrlenTEST = -1 ; + +void setAddrlen_W6x00(uint8_t num) { + addrlenTEST = num; +} + +uint8_t checkAddrlen_W6x00() { + //if (addrlenTEST < 0 ) + if ((addrlenTEST != 4) && (addrlenTEST != 16)) { + perror("Error: addrlen is not initialized"); + } else { + printf("addrlenTEST %d \r\n", addrlenTEST) ; + } + return addrlenTEST; +} + +inline void inline_setAddrlen_W6x00(uint8_t num) { +#if (_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300) + setAddrlen_W6x00(num); +#endif +} + +inline uint8_t inline_CheckAddrlen_W6x00(void) { +#if (_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300) + return checkAddrlen_W6x00(); +#else + return 4; +#endif +} +#endif + + + + +int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) { + + uint8_t taddr[16]; + uint16_t local_port = 0; + CHECK_SOCKNUM(); + switch (protocol & 0x0F) { +#ifdef IPV6_AVAILABLE + case Sn_MR_TCP4 : + getSIPR(taddr); + CHECK_IPZERO(taddr, 4); + break; + case Sn_MR_TCP6 : + getLLAR(taddr); + CHECK_IPZERO(taddr, 16); + //getGUAR(taddr); + //CHECK_IPZERO(taddr, 16); + break; + case Sn_MR_TCPD : + getSIPR(taddr); + CHECK_IPZERO(taddr, 4); + getLLAR(taddr); + CHECK_IPZERO(taddr, 16); + //getGUAR(taddr); + //CHECK_IPZERO(taddr, 16); + break; +#else + case Sn_MR_TCP : { + //M20150601 : Fixed the warning - taddr will never be NULL + /* + uint8_t taddr[4]; + getSIPR(taddr); + */ + uint32_t taddr; + getSIPR((uint8_t*)&taddr); + if (taddr == 0) { + return SOCKERR_SOCKINIT; + } + break; + } +#endif + case Sn_MR_UDP : + case Sn_MR_UDP6 : + case Sn_MR_UDPD : + case Sn_MR_MACRAW : + case Sn_MR_IPRAW4 : + case Sn_MR_IPRAW6 : + break; +#if ( _WIZCHIP_ < 5200 ) + case Sn_MR_PPPoE : + break; +#endif + default : + return SOCKERR_SOCKMODE; + } + //M20150601 : For SF_TCP_ALIGN & W5300 + //if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; + if ((flag & 0x04) != 0) { + return SOCKERR_SOCKFLAG; + } +#if _WIZCHIP_ == 5200 + if (flag & 0x10) { + return SOCKERR_SOCKFLAG; + } +#endif + + if (flag != 0) { + switch (protocol) { + +#ifdef IPV6_AVAILABLE + case Sn_MR_MACRAW: + if ((flag & (SF_DHA_MANUAL | SF_FORCE_ARP)) != 0) { + return SOCKERR_SOCKFLAG; + } + break; + case Sn_MR_TCP4: + case Sn_MR_TCP6: + case Sn_MR_TCPD: + if ((flag & (SF_MULTI_ENABLE | SF_UNI_BLOCK)) != 0) { + return SOCKERR_SOCKFLAG; + } + break; + case Sn_MR_IPRAW4: + case Sn_MR_IPRAW6: + if (flag != 0) { + return SOCKERR_SOCKFLAG; + } + break; +#else + case Sn_MR_TCP: + //M20150601 : For SF_TCP_ALIGN & W5300 +#if _WIZCHIP_ == 5300 + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK | SF_TCP_ALIGN)) == 0) { + return SOCKERR_SOCKFLAG; + } +#else + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK)) == 0) { + return SOCKERR_SOCKFLAG; + } +#endif + + break; + case Sn_MR_UDP: + if (flag & SF_IGMP_VER2) { + if ((flag & SF_MULTI_ENABLE) == 0) { + return SOCKERR_SOCKFLAG; + } + } +#if _WIZCHIP_ == 5500 + if (flag & SF_UNI_BLOCK) { + if ((flag & SF_MULTI_ENABLE) == 0) { + return SOCKERR_SOCKFLAG; + } + } +#endif + break; + +#endif + + default: + break; + } + } + close(sn); + //M20150601 +#if _WIZCHIP_ == 5300 + setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | (((uint16_t)(flag & 0x02)) << 7)); +#else + setSn_MR(sn, (protocol | (flag & 0xF0))); +#endif +#ifdef IPV6_AVAILABLE + setSn_MR2(sn, flag & 0x03); +#endif + if (!port) { + port = sock_any_port++; + if (sock_any_port == 0xFFF0) { + sock_any_port = SOCK_ANY_PORT_NUM; + } + } + setSn_PORTR(sn, port); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn)); + //A20150401 : For release the previous sock_io_mode + sock_io_mode &= ~(1 << sn); + // +#ifndef IPV6_AVAILABLE + sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); +#else + sock_io_mode |= ((flag & (SF_IO_NONBLOCK >> 3)) << sn); +#endif + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + //M20150601 : repalce 0 with PACK_COMPLETED + //sock_pack_info[sn] = 0; + sock_pack_info[sn] = PACK_COMPLETED;//PACK_COMPLETED //TODO::need verify:LINAN 20250421 + // + while (getSn_SR(sn) == SOCK_CLOSED); + return (int8_t)sn; +} + +int8_t close(uint8_t sn) { + CHECK_SOCKNUM(); + //A20160426 : Applied the erratum 1 of W5300 +#if (_WIZCHIP_ == 5300) + //M20160503 : Wrong socket parameter. s -> sn + //if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getSn_TxMAX(s)) ) + if (((getSn_MR(sn) & 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(sn) != getSn_TxMAX(sn))) { + uint8_t destip[4] = {0, 0, 0, 1}; + // TODO + // You can wait for completing to sending data; + // wait about 1 second; + // if you have completed to send data, skip the code of erratum 1 + // ex> wait_1s(); + // if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue; + // + //M20160503 : The socket() of close() calls close() itself again. It occures a infinite loop - close()->socket()->close()->socket()-> ~ + //socket(s,Sn_MR_UDP,0x3000,0); + //sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1). + setSn_MR(sn, Sn_MR_UDP); + setSn_PORTR(sn, 0x3000); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn) != 0); + while (getSn_SR(sn) != SOCK_UDP); + sendto(sn, destip, 1, destip, 0x3000); // send the dummy data to an unknown destination(0.0.0.1). + }; +#endif + setSn_CR(sn, Sn_CR_CLOSE); + /* wait to process the command... */ + while (getSn_CR(sn)); + /* clear all interrupt of SOCKETn. */ + setSn_IR(sn, 0xFF); + //A20150401 : Release the sock_io_mode of socket n. + sock_io_mode &= ~(1 << sn); + // + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + sock_pack_info[sn] = PACK_NONE; + while (getSn_SR(sn) != SOCK_CLOSED); + return SOCK_OK; +} + +int8_t listen(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_TCPMODE(); + CHECK_SOCKINIT(); + setSn_CR(sn, Sn_CR_LISTEN); + while (getSn_CR(sn)); + while (getSn_SR(sn) != SOCK_LISTEN) { + close(sn); + return SOCKERR_SOCKCLOSED; + } + return SOCK_OK; +} +//int8_t connect (uint8_t sn, uint8_t * addr, uint16_t port ) +int8_t connect_W5x00(uint8_t sn, uint8_t * addr, uint16_t port) { + // printf(" W5x00 - connect - addrlen = %d \r\n" , 4 ); + // #ifdef IPV6_AVAILABLE + // TODO :define how to work, when IPV6_AVAILABLE is defined + // #endif + return connect_IO_6(sn, addr, port, 4); +} + +int8_t connect_W6x00(uint8_t sn, uint8_t * addr, uint16_t port, uint8_t addrlen) { + // printf(" W6x00 - connect - addrlen = %d \r\n" , addrlen ); + // #ifdef IPV6_AVAILABLE + // TODO :define how to work, when IPV6_AVAILABLE is defined + // #endif + return connect_IO_6(sn, addr, port, addrlen); +} + +static int8_t connect_IO_6(uint8_t sn, uint8_t * addr, uint16_t port, uint8_t addrlen) { + + // printf(" connect - addrlen = %d \r\n" , addrlen ); + + CHECK_SOCKNUM(); + CHECK_TCPMODE(); // same macro " CHECK_SOCKMODE(Sn_MR_TCP);" + CHECK_SOCKINIT(); + +#ifdef IPV6_AVAILABLE + CHECK_IPZERO(addr, addrlen); +#else + //M20140501 : For avoiding fatal error on memory align mismatched + //if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + { + uint32_t taddr; + taddr = ((uint32_t)addr[0] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + if (taddr == 0xFFFFFFFF || taddr == 0) { + return SOCKERR_IPINVALID; + } + } +#endif + + if (port == 0) { + return SOCKERR_PORTZERO; + } + + setSn_DPORTR(sn, port); + + if (addrlen == 16) { // addrlen=16, Sn_MR_TCP6(1001), Sn_MR_TCPD(1101)) +#ifdef IPV6_AVAILABLE + if (getSn_MR(sn) & 0x08) { + setSn_DIP6R(sn, addr); + setSn_CR(sn, Sn_CR_CONNECT6); + } else +#endif + return SOCKERR_SOCKMODE; + } else { // addrlen=4, Sn_MR_TCP4(0001), Sn_MR_TCPD(1101) + if (getSn_MR(sn) == Sn_MR_TCP6) { + return SOCKERR_SOCKMODE; + } + setSn_DIPR(sn, addr); + //setSn_DPORT(sn,port); //TODO::need verify:LINAN 20250421 + setSn_CR(sn, Sn_CR_CONNECT); + } + while (getSn_CR(sn)); + if (sock_io_mode & (1 << sn)) { + return SOCK_BUSY; + } + while (getSn_SR(sn) != SOCK_ESTABLISHED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + + if (getSn_SR(sn) == SOCK_CLOSED) { + return SOCKERR_SOCKCLOSED; + } + } + + return SOCK_OK; +} + +int8_t disconnect(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_TCPMODE(); + if (getSn_SR(sn) != SOCK_CLOSED) { + setSn_CR(sn, Sn_CR_DISCON); + /* wait to process the command... */ + while (getSn_CR(sn)); + sock_is_sending &= ~(1 << sn); + if (sock_io_mode & (1 << sn)) { + return SOCK_BUSY; + } + while (getSn_SR(sn) != SOCK_CLOSED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + close(sn); + return SOCKERR_TIMEOUT; + } + } + } + return SOCK_OK; +} + + +#if 1 +int32_t send(uint8_t sn, uint8_t * buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t freesize = 0; + /* + The below codes can be omitted for optmization of speed + */ + //CHECK_SOCKNUM(); + //CHECK_TCPMODE(Sn_MR_TCP4); + /************/ +#ifndef IPV6_AVAILABLE + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) { + return SOCKERR_SOCKSTATUS; + } + if (sock_is_sending & (1 << sn)) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); + //M20150401 : Typing Error + //#if _WZICHIP_ == 5200 +#if _WIZCHIP_ == 5200 + if (getSn_TX_RD(sn) != sock_next_rd[sn]) { + setSn_CR(sn, Sn_CR_SEND); + while (getSn_CR(sn)); + return SOCK_BUSY; + } +#endif + sock_is_sending &= ~(1 << sn); + } else if (tmp & Sn_IR_TIMEOUT) { + close(sn); + return SOCKERR_TIMEOUT; + } else { + return SOCK_BUSY; + } + } +#endif + freesize = getSn_TxMAX(sn); + if (len > freesize) { + len = freesize; // check size not to exceed MAX size. + } + while (1) { + freesize = (uint16_t)getSn_TX_FSR(sn); + tmp = getSn_SR(sn); + if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) { + if (tmp == SOCK_CLOSED) { + close(sn); + } + return SOCKERR_SOCKSTATUS; + } + if ((sock_io_mode & (1 << sn)) && (len > freesize)) { + return SOCK_BUSY; //TODO::need verify:LINAN 20250421 + } + // if( sock_io_mode & (1< 4096) len = 4096; // check size not to exceed MAX size.// + //if (len > 8192) len = 8192; // check size not to exceed MAX siz + //if (len > 16384) len = 16384; // check size not to exceed MAX size. + //if (len > 32768) len = 32768; // check size not to exceed MAX size. +#define __FREESIZE__(i) 1024 * i +#define __FREESIZE__Value 8 + if (len > __FREESIZE__(__FREESIZE__Value)) { + len = __FREESIZE__(__FREESIZE__Value); // check size not to exceed MAX size.//tse + } + + while (1) { + freesize = (uint16_t)getSn_TX_FSR(sn); + if (len <= freesize) { + break; + } + } + wiz_send_data(sn, buf, len); + setSn_CR(sn, Sn_CR_SEND); + + while (getSn_CR(sn)); // wait to process the command... + sock_is_sending |= (1 << sn); + + return len; +} +#endif +int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len) { //lihan + uint8_t tmp = 0; + uint16_t recvsize = 0; + /* + The below codes can be omitted for optmization of speed + */ + //A20150601 : For integarating with W5300 +#if _WIZCHIP_ == 5300 + uint8_t head[2]; + uint16_t mr; +#endif + // + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + + recvsize = getSn_RxMAX(sn); + if (recvsize < len) { + len = recvsize; + } + + //A20150601 : For Integrating with W5300 +#if _WIZCHIP_ == 5300 + //sock_pack_info[sn] = PACK_COMPLETED; // for clear + if (sock_remained_size[sn] == 0) { +#endif + // + while (1) { + recvsize = (uint16_t)getSn_RX_RSR(sn); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED) { + if (tmp == SOCK_CLOSE_WAIT) { + if (recvsize != 0) { + break; + } else if (getSn_TX_FSR(sn) == getSn_TxMAX(sn)) { + close(sn); + return SOCKERR_SOCKSTATUS; + } + } else { + close(sn); + return SOCKERR_SOCKSTATUS; + } + } +#ifdef IPV6_AVAILABLE + if (recvsize != 0) { + break; + } + if (sock_io_mode & (1 << sn)) { + return SOCK_BUSY; + } +#else + if (sock_io_mode & (1 << sn)) { + return SOCK_BUSY; + } + if (recvsize != 0) { + break; + } +#endif + }; +#if _WIZCHIP_ == 5300 + } +#endif + + //A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 + if ((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN)) { + mr = getMR(); + if ((getSn_MR(sn) & Sn_MR_ALIGN) == 0) { + wiz_recv_data(sn, head, 2); + if (mr & MR_FS) { + recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]); + } else { + recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]); + } + sock_pack_info[sn] = PACK_FIRST; + } + sock_remained_size[sn] = recvsize; + } + if (len > sock_remained_size[sn]) { + len = sock_remained_size[sn]; + } + recvsize = len; + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf = sock_remained_byte[sn]; + buf++; + sock_pack_info[sn] &= ~(PACK_FIFOBYTE); + recvsize -= 1; + sock_remained_size[sn] -= 1; + } + if (recvsize != 0) { + wiz_recv_data(sn, buf, recvsize); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)); + } + sock_remained_size[sn] -= recvsize; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; + if (recvsize & 0x1) { + sock_pack_info[sn] |= PACK_FIFOBYTE; + } + } else { + sock_pack_info[sn] = PACK_COMPLETED; + } + if (getSn_MR(sn) & Sn_MR_ALIGN) { + sock_remained_size[sn] = 0; + } + //len = recvsize; +#else + if (recvsize < len) { + len = recvsize; + } + wiz_recv_data(sn, buf, len); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)); +#endif + + //M20150409 : Explicit Type Casting + //return len; + return (int32_t)len; +} + + +int32_t sendto_W5x00(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port) { + //static int32_t sendto_IO_6(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port) + // printf("sendto_W5x00\r\n" ) ; + return sendto_IO_6(sn, buf, len, addr, port, 4); +} + +int32_t sendto_W6x00(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port, uint8_t addrlen) { + // printf("sendto_W6x00\r\n" ) ; + //static int32_t sendto_IO_6(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port) + return sendto_IO_6(sn, buf, len, addr, port, addrlen); +} + +static int32_t sendto_IO_6(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port, uint8_t addrlen) { + uint8_t tmp = 0; + uint8_t tcmd = Sn_CR_SEND; + uint16_t freesize = 0; + uint32_t taddr; + + /* + The below codes can be omitted for optmization of speed + */ + CHECK_SOCKNUM(); + //CHECK_DGRAMMODE(); + /************/ + switch (getSn_MR(sn) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + // break; + // #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + case Sn_MR_IPRAW6: + break; + // #endif + default: + return SOCKERR_SOCKMODE; + } + tmp = getSn_MR(sn); + if (tmp != Sn_MR_MACRAW) { + if (addrlen == 16) { // addrlen=16, Sn_MR_UDP6(1010), Sn_MR_UDPD(1110)), IPRAW6(1011) +#ifdef IPV6_AVAILABLE + if (tmp & 0x08) { + setSn_DIP6R(sn, addr); + tcmd = Sn_CR_SEND6; + } else +#endif + return SOCKERR_SOCKMODE; + } else if (addrlen == 4) { // addrlen=4, Sn_MR_UDP4(0010), Sn_MR_UDPD(1110), IPRAW4(0011) + if (tmp == Sn_MR_UDP6 || tmp == Sn_MR_IPRAW6) { + return SOCKERR_SOCKMODE; + } + setSn_DIPR(sn, addr); + tcmd = Sn_CR_SEND; + } else { + return SOCKERR_IPINVALID; + } + } + if ((tmp & 0x03) == 0x02) { // Sn_MR_UPD4(0010), Sn_MR_UDP6(1010), Sn_MR_UDPD(1110) + if (port) { + setSn_DPORTR(sn, port); + } else { + return SOCKERR_PORTZERO; + } + } +#ifndef IPV6_AVAILABLE + CHECK_SOCKDATA(); + //M20140501 : For avoiding fatal error on memory align mismatched + //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + //{ + //uint32_t taddr; + taddr = ((uint32_t)addr[0]) & 0x000000FF; + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + //} + // + //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + if ((taddr == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) { + return SOCKERR_IPINVALID; + } + if ((port == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) { + return SOCKERR_PORTZERO; + } + tmp = getSn_SR(sn); + //#if ( _WIZCHIP_ < 5200 ) + if ((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) { + return SOCKERR_SOCKSTATUS; + } + //#else + // if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; + //#endif + + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); +#endif + + freesize = getSn_TxMAX(sn); + if (len > freesize) { + len = freesize; // check size not to exceed MAX size. + } + + while (1) { + freesize = getSn_TX_FSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) { + return SOCKERR_SOCKCLOSED; + } + if ((sock_io_mode & (1 << sn)) && (len > freesize)) { + return SOCK_BUSY; + } + if (len <= freesize) { + break; + } + }; + wiz_send_data(sn, buf, len); + +#if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + getSIPR((uint8_t *)&taddr); + if (taddr == 0) { + getSUBR((uint8_t*)&taddr); + setSUBR((uint8_t*)"\x00\x00\x00\x00"); + } else { + taddr = 0; + } +#endif + +#ifdef IPV6_AVAILABLE + setSn_CR(sn, tcmd); +#else + //A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + // + setSn_CR(sn, Sn_CR_SEND); +#endif + /* wait to process the command... */ + while (getSn_CR(sn)); + while (1) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); + break; + } + //M:20131104 + //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; + else if (tmp & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + //M20150409 : Fixed the lost of sign bits by type casting. + //len = (uint16_t)SOCKERR_TIMEOUT; + //break; +#if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) { + setSUBR((uint8_t*)&taddr); + } +#endif + return SOCKERR_TIMEOUT; + } + //////////// + } +#if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) { + setSUBR((uint8_t*)&taddr); + } +#endif + //M20150409 : Explicit Type Casting + //return len; + return (int32_t)len; +} + + + +int32_t recvfrom_W5x00(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) { + //int32_t recvfrom_IO_6(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) + // printf("recvfrom_W5x00\r\n" ) ; + uint8_t addrlen = 4; //M20150601 : For W5300 + uint8_t *dummy = &addrlen; + return recvfrom_IO_6(sn, buf, len, addr, port, dummy); +} + +int32_t recvfrom_W6x00(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port, uint8_t *addrlen) { + // printf("recvfrom_W6x00\r\n" ) ; + //int32_t recvfrom_IO_6(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) + return recvfrom_IO_6(sn, buf, len, addr, port, addrlen); +} +static int32_t recvfrom_IO_6(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port, uint8_t *addrlen) { //TODO : WILL BE IMPROVED + //M20150601 : For W5300 +#if _WIZCHIP_ == 5300 + uint16_t mr; + uint16_t mr1; +#else + uint8_t mr; +#endif + // + uint8_t head[8]; + uint16_t pack_len = 0; + + /* + The below codes can be omitted for optmization of speed + */ + CHECK_SOCKNUM(); + //CHECK_DGRAMMODE(); + //CHECK_SOCKDATA(); + /************/ + //CHECK_SOCKMODE(Sn_MR_UDP); + //A20150601 +#if _WIZCHIP_ == 5300 + mr1 = getMR(); +#endif + + switch ((mr = getSn_MR(sn)) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_IPRAW: + case Sn_MR_IPRAW6: + case Sn_MR_MACRAW: + break; +#if ( _WIZCHIP_ < 5200 ) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + if (sock_remained_size[sn] == 0) { + while (1) { + pack_len = getSn_RX_RSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) { + return SOCKERR_SOCKCLOSED; + } +#ifndef IPV6_AVAILABLE + if ((sock_io_mode & (1 << sn)) && (pack_len == 0)) { + return SOCK_BUSY; + } + if (pack_len != 0) { + break; + } +#else + if (pack_len != 0) { + sock_pack_info[sn] = PACK_NONE; + break; + } + if (sock_io_mode & (1 << sn)) { + return SOCK_BUSY; + } +#endif + }; + } +#ifdef IPV6_AVAILABLE + /* First read 2 bytes of PACKET INFO in SOCKETn RX buffer*/ + wiz_recv_data(sn, head, 2); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)); + pack_len = head[0] & 0x07; + pack_len = (pack_len << 8) + head[1]; +#endif + //D20150601 : Move it to bottom + // sock_pack_info[sn] = PACK_COMPLETED; + switch (mr & 0x07) { + case Sn_MR_UDP4 : + case Sn_MR_UDP6: + case Sn_MR_UDPD: +#ifdef IPV6_AVAILABLE + if (addr == 0) { + return SOCKERR_ARG; + } + + sock_pack_info[sn] = head[0] & 0xF8; + + if (sock_pack_info[sn] & PACK_IPv6) { + *addrlen = 16 ; + } else { + *addrlen = 4 ; + } + wiz_recv_data(sn, addr, *addrlen); + setSn_CR(sn, Sn_CR_RECV); + + while (getSn_CR(sn)); + +#else + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 8); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)); + // read peer's IP address, port number & packet length + //A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + if (mr1 & MR_FS) { + addr[0] = head[1]; + addr[1] = head[0]; + addr[2] = head[3]; + addr[3] = head[2]; + *port = head[5]; + *port = (*port << 8) + head[4]; + sock_remained_size[sn] = head[7]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6]; + } else { +#endif + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + *port = head[4]; + *port = (*port << 8) + head[5]; + sock_remained_size[sn] = head[6]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; +#if _WIZCHIP_ == 5300 + } +#endif + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) { + pack_len = len; + } else { + pack_len = sock_remained_size[sn]; + } + //A20150601 : For W5300 + len = pack_len; +#if _WIZCHIP_ == 5300 + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf++ = sock_remained_byte[sn]; + pack_len -= 1; + sock_remained_size[sn] -= 1; + sock_pack_info[sn] &= ~PACK_FIFOBYTE; + } +#endif + // + // Need to packet length check (default 1472) + // + wiz_recv_data(sn, buf, pack_len); // data copy. +#endif + break; + case Sn_MR_MACRAW : + if (sock_remained_size[sn] == 0) { +#ifndef IPV6_AVAILABLE + wiz_recv_data(sn, head, 2); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)); +#endif + // read peer's IP address, port number & packet length + sock_remained_size[sn] = head[0]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[1] - 2; +#if _WIZCHIP_ == W5300 + if (sock_remained_size[sn] & 0x01) { + sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4; + } else { + sock_remained_size[sn] -= 4; + } +#endif + if (sock_remained_size[sn] > 1514) { + close(sn); + return SOCKFATAL_PACKLEN; + } + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) { + pack_len = len; + } else { + pack_len = sock_remained_size[sn]; + } + wiz_recv_data(sn, buf, pack_len); + break; + //#if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW6: + case Sn_MR_IPRAW4 : + if (sock_remained_size[sn] == 0) { +#ifndef IPV6_AVAILABLE + wiz_recv_data(sn, head, 6); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)); + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + sock_remained_size[sn] = head[4]; + //M20150401 : For Typing Error + //sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_pack_info[sn] = PACK_FIRST; + // + // Need to packet length check + // + if (len < sock_remained_size[sn]) { + pack_len = len; + } else { + pack_len = sock_remained_size[sn]; + } + wiz_recv_data(sn, buf, pack_len); // data copy. +#else + if (*addr == 0) { + return SOCKERR_ARG; + } + sock_pack_info[sn] = head[0] & 0xF8; + if (sock_pack_info[sn] & PACK_IPv6) { + *addrlen = 16; + } else { + *addrlen = 4; + } + wiz_recv_data(sn, addr, *addrlen); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)); + +#endif + } + break; + default: + wiz_recv_ignore(sn, pack_len); // data copy. + sock_remained_size[sn] = pack_len; + break; + } +#ifdef IPV6_AVAILABLE + sock_remained_size[sn] = pack_len; + sock_pack_info[sn] |= PACK_FIRST; + if ((getSn_MR(sn) & 0x03) == 0x02) { // Sn_MR_UDP4(0010), Sn_MR_UDP6(1010), Sn_MR_UDPD(1110) + /* Read port number of PACKET INFO in SOCKETn RX buffer */ + if (port == 0) { + return SOCKERR_ARG; + } + wiz_recv_data(sn, head, 2); + *port = (((((uint16_t)head[0])) << 8) + head[1]); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)); + } + + if (len < sock_remained_size[sn]) { + pack_len = len; + } else { + pack_len = sock_remained_size[sn]; + } + wiz_recv_data(sn, buf, pack_len); + setSn_CR(sn, Sn_CR_RECV); + /* wait to process the command... */ + while (getSn_CR(sn)) ; + + sock_remained_size[sn] -= pack_len; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; + } else { + sock_pack_info[sn] |= PACK_COMPLETED; + } + +#else + setSn_CR(sn, Sn_CR_RECV); + /* wait to process the command... */ + while (getSn_CR(sn)) ; + sock_remained_size[sn] -= pack_len; + //M20150601 : + //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; +#if _WIZCHIP_ == 5300 + if (pack_len & 0x01) { + sock_pack_info[sn] |= PACK_FIFOBYTE; + } +#endif + } else { + sock_pack_info[sn] = PACK_COMPLETED; + } +#if _WIZCHIP_ == 5300 + pack_len = len; +#endif + // + //M20150409 : Explicit Type Casting + //return pack_len; +#endif + return (int32_t)pack_len; +} + + +int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg) { + uint8_t tmp = 0; + CHECK_SOCKNUM(); + tmp = *((uint8_t*)arg); + switch (cstype) { + case CS_SET_IOMODE: + if (tmp == SOCK_IO_NONBLOCK) { + sock_io_mode |= (1 << sn); + } else if (tmp == SOCK_IO_BLOCK) { + sock_io_mode &= ~(1 << sn); + } else { + return SOCKERR_ARG; + } + break; + case CS_GET_IOMODE: + //M20140501 : implict type casting -> explict type casting + //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; + *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + // + break; + case CS_GET_MAXTXBUF: + *((uint16_t*)arg) = getSn_TxMAX(sn); + break; + case CS_GET_MAXRXBUF: + *((uint16_t*)arg) = getSn_RxMAX(sn); + break; + case CS_CLR_INTERRUPT: + if (tmp > SIK_ALL) { + return SOCKERR_ARG; + } + setSn_IR(sn, tmp); + break; + case CS_GET_INTERRUPT: + *((uint8_t*)arg) = getSn_IR(sn); + break; +#if _WIZCHIP_ != 5100 + case CS_SET_INTMASK: + if (tmp > SIK_ALL) { + return SOCKERR_ARG; + } + setSn_IMR(sn, tmp); + break; + case CS_GET_INTMASK: + *((uint8_t*)arg) = getSn_IMR(sn); + break; +#endif +#ifdef IPV6_AVAILABLE + case CS_SET_PREFER: + if ((tmp & 0x03) == 0x01) { + return SOCKERR_ARG; + } + setSn_PSR(sn, tmp); + break; + case CS_GET_PREFER: + *(uint8_t*) arg = getSn_PSR(sn); + break; +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg) { + // M20131220 : Remove warning + //uint8_t tmp; + CHECK_SOCKNUM(); + switch (sotype) { + case SO_TTL: + setSn_TTL(sn, *(uint8_t*)arg); + break; + case SO_TOS: + setSn_TOS(sn, *(uint8_t*)arg); + break; + case SO_MSS: + setSn_MSSR(sn, *(uint16_t*)arg); + break; + case SO_DESTIP: +#ifdef IPV6_AVAILABLE + if (((wiz_IPAddress *)arg)->len == 16) { + setSn_DIP6R(sn, ((wiz_IPAddress*)arg)->ip); + } else +#endif + setSn_DIPR(sn, (uint8_t*)arg); + break; + case SO_DESTPORT: + setSn_DPORTR(sn, *(uint16_t*)arg); + break; +#if _WIZCHIP_ != 5100 + case SO_KEEPALIVESEND: + CHECK_TCPMODE(); +#if _WIZCHIP_ > 5200 + if (getSn_KPALVTR(sn) != 0) { + return SOCKERR_SOCKOPT; + } +#endif + setSn_CR(sn, Sn_CR_SEND_KEEP); + while (getSn_CR(sn) != 0) { + // M20131220 + //if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + } + break; +#if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_TCPMODE(); + setSn_KPALVTR(sn, *(uint8_t*)arg); + break; +#endif +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg) { + CHECK_SOCKNUM(); + switch (sotype) { + case SO_FLAG: +#ifdef IPV6_AVAILABLE + *(uint8_t*)arg = (getSn_MR(sn) & 0xF0) | (getSn_MR2(sn)) | ((uint8_t)(((sock_io_mode >> sn) & 0x0001) << 3)); +#endif + *(uint8_t*)arg = getSn_MR(sn) & 0xF0; + break; + case SO_TTL: + *(uint8_t*) arg = getSn_TTL(sn); + break; + case SO_TOS: + *(uint8_t*) arg = getSn_TOS(sn); + break; + case SO_MSS: + *(uint16_t*) arg = getSn_MSSR(sn); + break; + case SO_DESTIP: +#ifdef IPV6_AVAILABLE + CHECK_TCPMODE(); + if (getSn_ESR(sn) & TCPSOCK_MODE) { //IPv6 ? + getSn_DIP6R(sn, ((wiz_IPAddress*)arg)->ip); + ((wiz_IPAddress*)arg)->len = 16; + } else { + getSn_DIPR(sn, ((wiz_IPAddress*)arg)->ip); + ((wiz_IPAddress*)arg)->len = 4; + } + break; +#else + getSn_DIPR(sn, (uint8_t*)arg); + break; +#endif + case SO_DESTPORT: + *(uint16_t*) arg = getSn_DPORTR(sn); + break; +#if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_TCPMODE(); + *(uint16_t*) arg = getSn_KPALVTR(sn); + break; +#endif + case SO_SENDBUF: + *(uint16_t*) arg = getSn_TX_FSR(sn); + break; + case SO_RECVBUF: + *(uint16_t*) arg = getSn_RX_RSR(sn); + break; + case SO_STATUS: + *(uint8_t*) arg = getSn_SR(sn); + break; +#ifdef IPV6_AVAILABLE + case SO_EXTSTATUS: + CHECK_TCPMODE(); + *(uint8_t*) arg = getSn_ESR(sn) & 0x07; + break; + case SO_REMAINSIZE: + if (getSn_MR(sn) == SOCK_CLOSED) { + return SOCKERR_SOCKSTATUS; + } + if (getSn_MR(sn) & 0x01) { + *(uint16_t*)arg = getSn_RX_RSR(sn); + } else { + *(uint16_t*)arg = sock_remained_size[sn]; + } + break; + case SO_PACKINFO: + if (getSn_MR(sn) == SOCK_CLOSED) { + return SOCKERR_SOCKSTATUS; + } + if (getSn_MR(sn) & 0x01) { + return SOCKERR_SOCKMODE; + } else { + *(uint8_t*)arg = sock_pack_info[sn]; + } + break; + case SO_MODE: + *(uint8_t*) arg = 0x0F & getSn_MR(sn); + break; +#else + case SO_REMAINSIZE: + if (getSn_MR(sn) & Sn_MR_TCP) { + *(uint16_t*)arg = getSn_RX_RSR(sn); + } else { + *(uint16_t*)arg = sock_remained_size[sn]; + } + break; + case SO_PACKINFO : + //CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ != 5300 + if ((getSn_MR(sn) == Sn_MR_TCP)) { + return SOCKERR_SOCKMODE; + } +#endif + *(uint8_t*)arg = sock_pack_info[sn]; + break; + +#endif + default: + return SOCKERR_SOCKOPT; + } + return SOCK_OK; +} + +#ifdef IPV6_AVAILABLE +int16_t peeksockmsg(uint8_t sn, uint8_t* submsg, uint16_t subsize) { + uint32_t rx_ptr = 0; + uint16_t i = 0, sub_idx = 0; + + if ((getSn_RX_RSR(sn) > 0) && (subsize > 0)) { + rx_ptr = ((uint32_t)getSn_RX_RD(sn) << 8) + WIZCHIP_RXBUF_BLOCK(sn); + sub_idx = 0; + for (i = 0; i < getSn_RX_RSR(sn) ; i++) { + if (WIZCHIP_READ(rx_ptr) == submsg[sub_idx]) { + sub_idx++; + if (sub_idx == subsize) { + return (i + 1 - sub_idx); + } + } else { + sub_idx = 0; + } + rx_ptr = WIZCHIP_OFFSET_INC(rx_ptr, 1); + } + } + return -1; +} + + +#endif + diff --git a/lib/w6300/ioLibrary/socket.h b/lib/w6300/ioLibrary/socket.h new file mode 100644 index 0000000..292844c --- /dev/null +++ b/lib/w6300/ioLibrary/socket.h @@ -0,0 +1,736 @@ +//***************************************************************************** +// +//! \file socket.h +//! \brief SOCKET APIs Header file. +//! \details SOCKET APIs like as berkeley socket api. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2. Refer to M20140501 +//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED +//! 2. Add the comment as zero byte udp data reception in getsockopt(). +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * 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. +//! * Neither the name of the 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 OWNER 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. +// +//***************************************************************************** +/** + @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs + @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has much similar name and interface. + But there is a little bit of difference. + @details + Comparison between WIZnet and Berkeley SOCKET APIs + + + + + + + + + + + + +
API WIZnet Berkeley
socket() O O
bind() X O
listen() O O
connect() O O
accept() X O
recv() O O
send() O O
recvfrom() O O
sendto() O O
closesocket() O
close() & disconnect()
O
+ There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, + not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number, + and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n + When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port. + When the listen SOCKET accepts a connection request from a client, it keeps listening. + After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n + Following figure shows network flow diagram by Berkeley SOCKET API. + @image html Berkeley_SOCKET.jpg "" + But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n + Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client, + it is changed in order to communicate with the client. + And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n + If there're many listen SOCKET with same listen port number and a client requests a connection, + the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n + Following figure shows network flow diagram by WIZnet SOCKET API. + @image html WIZnet_SOCKET.jpg "" +*/ +#ifndef _SOCKET_H_ +#define _SOCKET_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" + +#define SOCKET uint8_t ///< SOCKET type define for legacy driver + +#define SOCK_OK 1 ///< Result is OK about socket process. +#define SOCK_BUSY 0 ///< Socket is busy on processing the operation. Valid only Non-block IO Mode. +#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. + +#define SOCK_ERROR 0 +#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number +#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option +#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized or SIPR is Zero IP address when Sn_MR_TCP +#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. +#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. +#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag +#define SOCKERR_SOCKSTATUS (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. +#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument. +#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero +#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address +#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred +#define SOCKERR_DATALEN (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. +#define SOCKERR_BUFFER (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. + +#define SOCKFATAL_PACKLEN (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. + +#if (_WIZCHIP_ == W5100 || _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5300 || _WIZCHIP_ == W5500) +/* + SOCKET FLAG +*/ +#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet +#define SF_IGMP_VER2 (Sn_MR_MC) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2. +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In @ref Sn_MR_TCP, Use to nodelayed ack. +#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In @ref Sn_MR_UDP, Enable multicast mode. + +#define Sn_MR2_DHAM (1<<1) +#define SF_DHA_MANUAL (Sn_MR2_DHAM) +#define Sn_MR2_FARP (1<<0) +#define SF_FORCE_ARP (Sn_MR2_FARP) + + +#if _WIZCHIP_ == 5500 +#define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500 +#define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500 +#define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500 +#define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500 +#endif + +//A201505 : For W5300 +#if _WIZCHIP_ == 5300 +#define SF_TCP_ALIGN 0x02 ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN +#endif + +#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). + +/* + UDP & MACRAW Packet Infomation +*/ +#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. (When W5300, This flag can be applied) +#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. (When W5300, This flag can be applied) +#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. (When W5300, This flag can be applied) +//A20150601 : For Integrating with W5300 +#define PACK_FIFOBYTE 0x02 ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR. +// +//teddy 240122 + +#define PACK_IPv6 (1<<7) ///< It indicates the destination IP address of the received packet is IPv6 or IPv4. +#define PACK_IPV6_ALLNODE (PACK_IPv6 | (1<<6)) ///< It indicates the destination IP address of the received packet is allnode multicast(broadcast) address or not. +#define PACK_IPV6_MULTI (PACK_IPv6 | (1<<5)) ///< It indicates the destination IP address of the received packet is multicast address or not. +#define PACK_IPV6_LLA (PACK_IPv6 | (1<<4)) ///< It indicates the destination IP address of the received packet is lla or gua. +#define PACK_NONE (0x00) ///< It indicates no information of a packet + +#elif ((_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300)) + +/* + - @ref Sn_MR_MULTI : Support UDP Multicasting + - @ref Sn_MR_MF : Support MAC Filter Enable + - @ref Sn_MR_BRDB : Broadcast Block + - @ref Sn_MR_FPSH : Force PSH flag + - @ref Sn_MR_ND : No Delay ACK flag + - @ref Sn_MR_MC : IGMP ver2, ver1 + - @ref Sn_MR_SMB : Solicited Multicast Block + - @ref Sn_MR_MMB : IPv4 Multicast block + - @ref Sn_MR_UNIB : Unicast Block + - @ref Sn_MR_MMB6 : IPv6 UDP Multicast Block + + - @ref Sn_MR2_DHAM : @ref Sn_MR2_DHAM_AUTO, @ref Sn_MR2_DHAM_MANUAL + - @ref Sn_MR_FARP +*/ + +/* + SOCKET FLAG +*/ +/** + @brief In UDP mode such as @ref Sn_MR_UDP4 and @ref Sn_MR_UDP6, @ref Sn_MR_UDP6, Enable multicast mode. When @ref Sn_MR_UDP6, Enable only IPv6 Multicating. +*/ +#define SF_MULTI_ENABLE (Sn_MR_MULTI) +#define SF_ETHER_OWN (Sn_MR_MF) ///< In MACRAW mode such as @ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet + +/** + @brief In UDP mode such as @ref Sn_MR_UDP4, @ref Sn_MR_UDP6 and @ref Sn_MR_UDPD, or In MACRAW mode sucha as @ref Sn_MR_MACRAW, Block a broadcast packet. +*/ +#define SF_BROAD_BLOCK (Sn_MR_BRDB) +#define SF_TCP_FPSH (Sn_MR_FPSH) ///< In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6 and @ref Sn_MR_TCPD, Use to forced push flag. + +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6 and @ref Sn_MR_TCPD, Use to nodelayed ack. +#define SF_IGMP_VER2 (Sn_MR_MC) ///< In UDP mode such as @ref Sn_MR_UDP4 with @ref SF_MULTI_ENABLE, Select IGMP version 2. +#define SF_SOLICIT_BLOCK (Sn_MR_SMB) ///< In UDP mode such as @ref Sn_MR_UDP6 and @ref Sn_MR_UDPD, Block a solicited mutlicast packet. +#define SF_ETHER_MULTI4B (Sn_MR_MMB4) ///< In MACRAW mode such as @ref Sn_MR_MACRAW with @ref SF_MULTI_ENABLE, Block a IPv4 multicast packet. + +#define SF_UNI_BLOCK (Sn_MR_UNIB) ///< In UDP mdoe such as @ref Sn_MR_UDP4, @ref Sn_MR_UDP6 and @ref Sn_MR_UDPD with @ref SF_MULTI_ENABLE, Block a unicast packet. +#define SF_ETHER_MULIT6B (Sn_MR_MMB6) ///< In MACRAW mode such as @ref Sn_MR_MACRAW with @ref SF_MULTI_ENABLE, Block a IPv6 multicast packet. + +/** + @brief Force to APR. + @details In datagram mode such as @ref Sn_MR_IPRAW4, @ref Sn_MR_IPRAW6, @ref Sn_MR_UDP4, @ref Sn_MR_UDP6, and @ref Sn_MR_UDPD, + Force to request ARP before a packet is sent to a destination.\n + In TCP mode such as @ref Sn_MR_TCP4, @ref Sn_MR_TCP6, and @ref Sn_MR_TCPD and TCP SERVER operation mode, + Force to request ARP before SYN/ACK packet is sent to a TCP CLIENT. \n + When @ref SF_DHA_MANUAL is set, the ARP is process but the destination hardware address is fixed by user. +*/ +#define SF_FORCE_ARP (Sn_MR2_FARP) + +/** + @brief The destination hardware address of packet to be transmitted is set by user through @ref _Sn_DHAR_. It is invalid in MACRAW mode such as @ref Sn_MR_MACRAW. +*/ +#define SF_DHA_MANUAL (Sn_MR2_DHAM) + +#define SF_IO_NONBLOCK (0x01 << 3) ///< Socket nonblock io mode. It used parameter in @ref socket(). + +/* + UDP, IPRAW, MACRAW Packet Infomation +*/ +#define PACK_IPv6 (1<<7) ///< It indicates the destination IP address of the received packet is IPv6 or IPv4. +#define PACK_IPV6_ALLNODE (PACK_IPv6 | (1<<6)) ///< It indicates the destination IP address of the received packet is allnode multicast(broadcast) address or not. +#define PACK_IPV6_MULTI (PACK_IPv6 | (1<<5)) ///< It indicates the destination IP address of the received packet is multicast address or not. +#define PACK_IPV6_LLA (PACK_IPv6 | (1<<4)) ///< It indicates the destination IP address of the received packet is lla or gua. +#define PACK_COMPLETED (1<<3) ///< It indicates the read data is last in the received packet. +#define PACK_REMAINED (1<<2) ///< It indicates to remain data in the received packet +#define PACK_FIRST (1<<1) ///< It indicates the read data is first in the received packet. +#define PACK_NONE (0x00) ///< It indicates no information of a packet + +#define SRCV6_PREFER_AUTO (PSR_AUTO) ///< Soruce IPv6 address is preferred to auto-selection. Refer to @ref _Sn_PSR_ +#define SRCV6_PREFER_LLA (PSR_LLA) ///< Soruce IPv6 address is preferred to link local address. Refer to @ref _Sn_PSR_ +#define SRCV6_PREFER_GUA (PSR_GUA) ///< Soruce IPv6 address is preferred to global unique address. Refer to @ref _Sn_PSR_ + +#define TCPSOCK_MODE (Sn_ESR_TCPM) ///< It indicates the IP version when SOCKETn is opened as TCP6 or TCPD mode.(0 - IPv4 , 1 - IPv6) +#define TCPSOCK_OP (Sn_ESR_TCPOP) ///< It indicates the operation mode when SOCKETn is connected.(0 - TCP CLIENT , 1 - TCP SERVER) +#define TCPSOCK_SIP (Sn_ESR_IP6T) ///< It indicates the source ip address type when SOCKET is connected. (0 - Link Local, 1 - Global Unique) + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). +#endif + +/** + @ingroup WIZnet_socket_APIs + @brief Open a socket. + @details Initializes the socket with 'sn' passed as parameter and open. + + @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + @param protocol Protocol type to operate such as TCP, UDP and MACRAW. + @param port Port number to be bined. + @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n + Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. + @sa Sn_MR + + @return @b Success : The socket number @b 'sn' passed as parameter\n + @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + @ref SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on. \n + @ref SOCKERR_SOCKFLAG - Invaild socket flag. +*/ +int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); + +/** + @ingroup WIZnet_socket_APIs + @brief Close a socket. + @details It closes the socket with @b'sn' passed as parameter. + + @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + + @return @b Success : @ref SOCK_OK \n + @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number +*/ +int8_t close(uint8_t sn); + +/** + @ingroup WIZnet_socket_APIs + @brief Listen to a connection request from a client. + @details It is listening to a connection request from a client. + If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode. + + @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + @return @b Success : @ref SOCK_OK \n + @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n + @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. +*/ +int8_t listen(uint8_t sn); + +//teddy 240122 +/** + @ingroup WIZnet_socket_APIs + @brief Try to connect to a TCP SERVER. + @details It sends a connection-reqeust message to the server with destination IP address and port number passed as parameter.\n + SOCKET sn is used as active(TCP CLIENT) mode. + @param sn SOCKET number. It should be 0 ~ @ref _WIZCHIP_SOCK_NUM_. + @param addr Pointer variable of destination IPv6 or IPv4 address. + @param port Destination port number. + @param addrlen the length of addr. \n <- removed + If addr is IPv6 address it should be 16,else if addr is IPv4 address it should be 4. Otherwize, return @ref SOCKERR_IPINVALID. + @return Success : @ref SOCK_OK \n + Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + @ref SOCKERR_SOCKMODE - Invalid socket mode\n + @ref SOCKERR_SOCKINIT - Socket is not initialized\n + @ref SOCKERR_IPINVALID - Wrong server IP address\n + @ref SOCKERR_PORTZERO - Server port zero\n + @ref SOCKERR_TIMEOUT - Timeout occurred during request connection\n + @ref SOCK_BUSY - In non-block io mode, it returns immediately\n + @note It is valid only in TCP client mode. \n + In block io mode, it does not return until connection is completed. \n + In Non-block io mode(@ref SF_IO_NONBLOCK), it returns @ref SOCK_BUSY immediately. +*/ +static int8_t connect_IO_6(uint8_t sn, uint8_t * addr, uint16_t port, uint8_t addrlen); +//int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port, uint8_t addrlen); + +/** + @ingroup WIZnet_socket_APIs + @brief Try to disconnect a connection socket. + @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client. + @note It is valid only in TCP server or client mode. \n + In block io mode, it does not return until disconnection is completed. \n + In Non-block io mode, it return @ref SOCK_BUSY immediately. \n + + @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + @return @b Success : @ref SOCK_OK \n + @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + @ref SOCKERR_TIMEOUT - Timeout occurred \n + @ref SOCK_BUSY - Socket is busy. +*/ +int8_t disconnect(uint8_t sn); + +/** + @ingroup WIZnet_socket_APIs + @brief Send data to the connected peer in TCP socket. + @details It is used to send outgoing data to the connected socket. + @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n + In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n + In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. \n + @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + @param buf Pointer buffer containing data to be sent. + @param len The byte length of data in buf. + @return @b Success : The sent data size \n + @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + @ref SOCKERR_TIMEOUT - Timeout occurred \n + @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + @ref SOCKERR_SOCKNUM - Invalid socket number \n + @ref SOCKERR_DATALEN - zero data length \n + @ref SOCK_BUSY - Socket is busy. +*/ +int32_t send(uint8_t sn, uint8_t * buf, uint16_t len); + +/** + @ingroup WIZnet_socket_APIs + @brief Receive data from the connected peer. + @details It is used to read incoming data from the connected socket.\n + It waits for data as much as the application wants to receive. + @note It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n + In block io mode, it doesn't return until data reception is completed - data is filled as len in socket buffer. \n + In non-block io mode, it return @ref SOCK_BUSY immediately when len is greater than data size in socket buffer. \n + + @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + @param buf Pointer buffer to read incoming data. + @param len The max data length of data in buf. + @return @b Success : The real received data size \n + @b Fail :\n + @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + @ref SOCKERR_SOCKNUM - Invalid socket number \n + @ref SOCKERR_DATALEN - zero data length \n + @ref SOCK_BUSY - Socket is busy. +*/ +int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len); + +/** + @ingroup WIZnet_socket_APIs + @brief Send datagram to the peer specifed by destination IP address and port number passed as parameter. + @details It sends datagram data by using UDP,IPRAW, or MACRAW mode SOCKET. + @param sn SOCKET number. It should be 0 ~ @ref _WIZCHIP_SOCK_NUM_. + @param buf Pointer of data buffer to be sent. + @param len The byte length of data in buf. + @param addr Pointer variable of destination IPv6 or IPv4 address. + @param port Destination port number. + @param addrlen the length of addr. \n + If addr is IPv6 address it should be 16,else if addr is IPv4 address it should be 4. Otherwize, return @ref SOCKERR_IPINVALID. + @return Success : The real sent data size. It may be equal to len or small.\n + Fail :\n @ref SOCKERR_SOCKNUM - Invalid SOCKET number \n + @ref SOCKERR_SOCKMODE - Invalid operation in the SOCKET \n + @ref SOCKERR_SOCKSTATUS - Invalid SOCKET status for SOCKET operation \n + @ref SOCKERR_IPINVALID - Invalid IP address\n + @ref SOCKERR_PORTZERO - Destination port number is zero\n + @ref SOCKERR_DATALEN - Invalid data length \n + @ref SOCKERR_SOCKCLOSED - SOCKET unexpectedly closed \n + @ref SOCKERR_TIMEOUT - Timeout occurred \n + @ref SOCK_BUSY - SOCKET is busy. + @note It is valid only in @ref Sn_MR_UDP4, @ref Sn_MR_UDP6, @ref Sn_MR_UDPD, @ref Sn_MR_IPRAW4, @ref Sn_MR_IPRAW6, and @ref Sn_MR_MACRAW. \n + In UDP mode, It can send data as many as SOCKET RX buffer size if data is greater than SOCKET TX buffer size. \n + In IPRAW and MACRAW mode, It should send data as many as MTU(maxium transmission unit) if data is greater than MTU. That is, len can't exceed to MTU. + In block io mode, It doesn't return until data send is completed. + In non-block io mode(@ref SF_IO_NONBLOCK), It return @ref SOCK_BUSY immediately when SOCKET transimttable buffer size is not enough. +*/ +//int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port, uint8_t addrlen); +static int32_t sendto_IO_6(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port, uint8_t addrlen); + +/** + @ingroup WIZnet_socket_APIs + @brief Receive datagram from a peer + @details It can read a data received from a peer by using UDP, IPRAW, or MACRAW mode SOCKET. + @param sn SOCKET number. It should be 0 ~ @ref _WIZCHIP_SOCK_NUM_. + @param buf Pointer buffer to be saved the received data. + @param len The max read data length. \n + When the received packet size <= len, it can read data as many as the packet size. \n + When others, it can read data as many as len and remain to the rest data of the packet. + @param addr Pointer variable of destination IP address.\n + It is valid only when @ref recvfrom() is first called for receiving the datagram packet. + You can check it valid or not through @ref PACK_FIRST. You can get it through @ref getsockopt(sn, @ref SO_PACKINFO, &packinfo).\n + In UDP4, IPRAW mode SOCKET, it should be allocated over 4bytes. \n + In UDP6, UDPD mode SOCKET, it should be allocated over 16bytes. + @param port Pointer variable of destination port number. \n + It is valid only when @ref recvfrom() is first called for receiving the datagram packet, same as port case. + @param addrlen The byte length of destination IP address. \n + It is valid only when @ref recvfrom() is first called for receiving the datagram packet, same as port case.\n + When the destination has a IPv4 address, it is set to 4. \n + when the destination has a IPv6 address, it is set to 16. + @return Success : The real received data size. It may be equal to len or small.\n + Fail : @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + @ref SOCKERR_SOCKNUM - Invalid socket number \n + @ref SOCKERR_ARG - Invalid parameter such as addr, port + @ref SOCK_BUSY - SOCKET is busy. + @note It is valid only in @ref Sn_MR_UDP4, @ref Sn_MR_UDP6, @ref Sn_MR_UDPD, @ref Sn_MR_IPRAW4, @ref Sn_MR_IPRAW6, and @ref Sn_MR_MACRAW. \n + When SOCKET is opened with @ref Sn_MR_MACRAW or When it reads the the remained data of the previous datagram packet, + the parameters such as addr, port, addrlen is ignored. \n + Also, It can read data as many as the received datagram packet size if len is greater than the datagram packet size. \n + In block io mode, it doesn't return until data reception is completed. that is, it waits until any datagram packet is received in SOCKET RX buffer. \n + In non-block io mode(@ref SF_IO_NONBLOCK), it return @ref SOCK_BUSY immediately when SOCKET RX buffer is empty. \n +*/ +//int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port, uint8_t *addrlen); +static int32_t recvfrom_IO_6(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port, uint8_t *addrlen); + + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). + +/** + @defgroup DATA_TYPE DATA TYPE +*/ + +/** + @ingroup DATA_TYPE + @brief The kind of Socket Interrupt. + @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() +*/ +typedef enum { + SIK_CONNECTED = (1 << 0), ///< connected + SIK_DISCONNECTED = (1 << 1), ///< disconnected + SIK_RECEIVED = (1 << 2), ///< data received + SIK_TIMEOUT = (1 << 3), ///< timeout occurred + SIK_SENT = (1 << 4), ///< send ok + //M20150410 : Remove the comma of last member + //SIK_ALL = 0x1F, ///< all interrupt + SIK_ALL = 0x1F ///< all interrupt +} sockint_kind; + +/** + @ingroup DATA_TYPE + @brief The type of @ref ctlsocket(). +*/ +typedef enum { + CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK + CS_GET_IOMODE, ///< get socket IO mode + CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory + CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory + CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind + CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind + + //teddy 240122 + //#if _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + CS_SET_PREFER, ///< set the preferred source IPv6 address of transmission packet.\n Refer to @ref SRCV6_PREFER_AUTO, @ref SRCV6_PREFER_LLA and @ref SRCV6_PREFER_GUA. + CS_GET_PREFER, ///< get the preferred source IPv6 address of transmission packet.\n Refer to @ref SRCV6_PREFER_AUTO, @ref SRCV6_PREFER_LLA and @ref SRCV6_PREFER_GUA. + //#endif +#if _WIZCHIP_ >= 5100 + CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind, Not supported in W5100 + CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind, Not supported in W5100 +#endif +} ctlsock_type; + + +/** + @ingroup DATA_TYPE + @brief The type of socket option in @ref setsockopt() or @ref getsockopt() +*/ +typedef enum { + SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to flag in @ref socket(). + SO_TTL, ///< Set TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) + SO_TOS, ///< Set TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) + SO_MSS, ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) + SO_DESTIP, ///< Set the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() ) + SO_DESTPORT, ///< Set the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() ) +#if _WIZCHIP_ != 5100 + SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode, Not supported in W5100 +#if !( (_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200) ) + SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode, Not supported in W5100, W5200 +#endif +#endif + SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() + SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() + SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR() + + //teddy 240122 + //#if _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + SO_EXTSTATUS, ///< Valid only in @ref getsockopt(). Get the extended TCP SOCKETn status. @ref getSn_ESR() + SO_MODE, + //#endif + SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode. + SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode. +} sockopt_type; + +/** + @ingroup WIZnet_socket_APIs + @brief Control socket. + @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information. + Refer to @ref ctlsock_type. + @param sn socket number + @param cstype type of control socket. refer to @ref ctlsock_type. + @param arg Data type and value is determined according to @ref ctlsock_type. \n + + + + + +
@b cstype @b data type@b value
@ref CS_SET_IOMODE \n @ref CS_GET_IOMODE uint8_t @ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK
@ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF uint16_t 0 ~ 16K
@ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK @ref sockint_kind @ref SIK_CONNECTED, etc.
+ @return @b Success @ref SOCK_OK \n + @b fail @ref SOCKERR_ARG - Invalid argument\n +*/ +int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg); + +/** + @ingroup WIZnet_socket_APIs + @brief set socket options + @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type. + + @param sn socket number + @param sotype socket option type. refer to @ref sockopt_type + @param arg Data type and value is determined according to sotype. \n + + + + + + + + + +
@b sotype @b data type@b value
@ref SO_TTL uint8_t 0 ~ 255
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t 0 ~ 65535
@ref SO_KEEPALIVESEND null null
@ref SO_KEEPALIVEAUTO uint8_t 0 ~ 255
+ @return + - @b Success : @ref SOCK_OK \n + - @b Fail + - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet \n +*/ +int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg); + +/** + @ingroup WIZnet_socket_APIs + @brief get socket options + @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type + @param sn socket number + @param sotype socket option type. refer to @ref sockopt_type + @param arg Data type and value is determined according to sotype. \n + + + + + + + + + + + + + +
@b sotype @b data type@b value
@ref SO_FLAG uint8_t @ref SF_ETHER_OWN, etc...
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t
@ref SO_KEEPALIVEAUTO uint8_t 0 ~ 255
@ref SO_SENDBUF uint16_t 0 ~ 65535
@ref SO_RECVBUF uint16_t 0 ~ 65535
@ref SO_STATUS uint8_t @ref SOCK_ESTABLISHED, etc..
@ref SO_REMAINSIZE uint16_t 0~ 65535
@ref SO_PACKINFO uint8_t @ref PACK_FIRST, etc...
+ @return + - @b Success : @ref SOCK_OK \n + - @b Fail + - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + @note + The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n + When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero, + This means the zero byte UDP data(UDP Header only) received. +*/ +int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg); + +//teddy 240122 +#if _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 +/** + @ingroup WIZnet_socket_APIs + @brief Peeks a sub-message in SOCKETn RX buffer + @details It peeks the incoming message of SOCKETn RX buffer. \n + It can find the specified sub-message in the incoming message and + return the length of incoming message before the sub-message. \n + It is useful when you need to read each messages from multiple message in SOCKET RX buffer. + @param sn SOCKET number + @param submsg sub-message pointer to find + @param subsize the length of submsg + @return + - Success : the length of incoming message length before the submsg \n + - Fail : -1 + @note + It is just return the length of incoming message before the found sub-message. It does not receive the message.\n + So, after calling peeksockmsg, @ref _Sn_RX_RD_ is not changed. +*/ +int16_t peeksockmsg(uint8_t sn, uint8_t* submsg, uint16_t subsize); + +#endif + +// void setAddrlen_W6x00( uint8_t num) ; +// uint8_t checkAddrlen_W6x00() ; + +// void inline_setAddrlen_W6x00( uint8_t num); +// uint8_t inline_CheckAddrlen_W6x00( void ); + + +#if 1 // by_Lihan + +/** + @ingroup WIZnet_socket_APIs + @brief by_Lihan_W5x00 +*/ +int8_t connect_W5x00(uint8_t sn, uint8_t * addr, uint16_t port); +/** + @ingroup WIZnet_socket_APIs + @brief by_Lihan_Wx00 +*/ +int8_t connect_W6x00(uint8_t sn, uint8_t * addr, uint16_t port, uint8_t addrlen); + + + + + +#define GET_MACRO_connect(_1, _2, _3, _4, NAME, ...) NAME +#define CHOOSE_TESTCODE_MACRO(...) GET_MACRO_connect(__VA_ARGS__, connect_4, connect_3) + +/** + // by_LIhan for overroading + // NOTE_LIHAN: Some sections of this code are not yet fully defined. + @note + In case of get 3 arguments - int8_t connect_W5x00(uint8_t sn, uint8_t * addr, uint16_t port );\n + In case of get 4 arguments - int8_t connect_W6x00(uint8_t sn, uint8_t * addr, uint16_t port, uint8_t addrlen ); +*/ + +#define connect(...) CHOOSE_TESTCODE_MACRO(__VA_ARGS__)(__VA_ARGS__) + +// In case of get 3 arguments +#define connect_3(sn , addr , port ) connect_W5x00(sn , addr , port) + +// In case of get 4 arguments +#define connect_4(sn , addr , port, addrlen ) connect_W6x00(sn , addr , port,addrlen) + + + + +/** + @ingroup WIZnet_socket_APIs + @brief by_Lihan +*/ +int32_t sendto_W5x00(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); +/** + @ingroup WIZnet_socket_APIs + @brief by_Lihan +*/ +int32_t sendto_W6x00(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port, uint8_t addrlen); + + +#define GET_MACRO_sendto(_1, _2, _3, _4, _5 , _6, NAME, ...) NAME +#define CHOOSE_sendto_MACRO(...) GET_MACRO_sendto(__VA_ARGS__, sendto_6, sendto_5) + +// by_LIhan for overroading +// NOTE_LIHAN: Some sections of this code are not yet fully defined. +// In case of get 3 arguments - int8_t sendto_W5x00(uint8_t sn, uint8_t * addr, uint16_t port ); +// In case of get 4 arguments - int8_t sendto_W6x00(uint8_t sn, uint8_t * addr, uint16_t port,uint8_t addrlen ); +#define sendto(...) CHOOSE_sendto_MACRO(__VA_ARGS__)(__VA_ARGS__) + +// In case of get 3 arguments +#define sendto_5( sn, buf, len, addr, port ) sendto_W5x00( sn, buf, len, addr, port) + +// In case of get 4 arguments +#define sendto_6( sn, buf, len, addr, port, addrlen ) sendto_W6x00( sn, buf, len, addr, port, addrlen) + +/** + @ingroup WIZnet_socket_APIs + @brief byLihan_W5x00 +*/ +int32_t recvfrom_W5x00(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); +/** + @ingroup WIZnet_socket_APIs + @brief byLihan_Wx00 +*/ +int32_t recvfrom_W6x00(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port, uint8_t *addrlen); + + +#define GET_MACRO_recvfrom(_1, _2, _3, _4, _5, _6 ,NAME, ...) NAME +#define CHOOSE_recvfrom_MACRO(...) GET_MACRO_recvfrom(__VA_ARGS__, recvfrom_6, recvfrom_5) + +// by_LIhanfor overroading +// In case of get 3 arguments - int8_t recvfrom_W5x00(uint8_t sn, uint8_t * addr, uint16_t port ); +// In case of get 4 arguments - int8_t recvfrom_W6x00(uint8_t sn, uint8_t * addr, uint16_t port,uint8_t addrlen ); +#define recvfrom(...) CHOOSE_recvfrom_MACRO(__VA_ARGS__)(__VA_ARGS__) + +// In case of get 3 arguments +#define recvfrom_5(sn, buf, len, addr, port ) recvfrom_W5x00(sn, buf, len, addr, port) + +// In case of get 4 arguments +#define recvfrom_6(sn, buf, len, addr, port, addrlen ) recvfrom_W6x00(sn, buf, len, addr, port, addrlen ) + + +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif // _SOCKET_H_ + + diff --git a/lib/w6300/ioLibrary/wizchip_conf.c b/lib/w6300/ioLibrary/wizchip_conf.c new file mode 100644 index 0000000..9409b60 --- /dev/null +++ b/lib/w6300/ioLibrary/wizchip_conf.c @@ -0,0 +1,1515 @@ +//****************************************************************************/ +//! +//! \file wizchip_conf.c +//! \brief WIZCHIP Config Header File. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.1 Refer to M20140501 +//! 1. Explicit type casting in wizchip_bus_readdata() & wizchip_bus_writedata() +// Issued by Mathias ClauBen. +//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t* +//! For remove the warning when pointer type size is not 32bit. +//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type. +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * 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. +//! * Neither the name of the 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 OWNER 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. +// +//*****************************************************************************/ +//A20140501 : for use the type - ptrdiff_t +#include +// + +#include "wizchip_conf.h" + +///////////// +//M20150401 : Remove ; in the default callback function such as wizchip_cris_enter(), wizchip_cs_select() and etc. +///////////// + +/** + @brief Default function to enable interrupt. + @note This function help not to access wrong address. If you do not describe this function or register any functions, + null function is called. +*/ +//void wizchip_cris_enter(void) {}; +void wizchip_cris_enter(void) {} + +/** + @brief Default function to disable interrupt. + @note This function help not to access wrong address. If you do not describe this function or register any functions, + null function is called. +*/ +//void wizchip_cris_exit(void) {}; +void wizchip_cris_exit(void) {} + +/** + @brief 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. +*/ +//void wizchip_cs_select(void) {}; +void wizchip_cs_select(void) {} + +/** + @brief 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. +*/ +//void wizchip_cs_deselect(void) {}; +void wizchip_cs_deselect(void) {} + +/** + @brief Default function to read in direct or indirect 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. +*/ +//M20150601 : Rename the function for integrating with W5300 +//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); } +iodata_t wizchip_bus_readdata(uint32_t AddrSel) { + return * ((volatile iodata_t *)((ptrdiff_t) AddrSel)); +} + +/** + @brief Default function to write in direct or indirect 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. +*/ +//M20150601 : Rename the function for integrating with W5300 +//void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; } +void wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb) { + *((volatile iodata_t*)((ptrdiff_t)AddrSel)) = wb; +} +#if 1 +// 20231103 taylor +/** + @brief Default function to read @ref iodata_t buffer by using BUS interface + @details @ref wizchip_bus_read_buf() provides the default read @ref iodata_t data as many as len from BUS of @ref _WIZCHIP_. + @param AddrSel It specifies the address of register to be read. + @param buf It specifies your buffer pointer to be saved the read data from @ref _WIZCHIP_. + @param len It specifies the data length to be read from @ref _WIZCHIP_. + @param addrinc It specifies whether the address is increased by every read operation or not.\n + 0 : Not Increased \n + 1 : Increased + @return void + @note It can be overwritten with your function or register your functions by calling @ref reg_wizchip_bus_cbfunc(). + @sa wizchip_bus_write_buf() +*/ +void wizchip_bus_read_buf(uint32_t AddrSel, iodata_t* buf, int16_t len, uint8_t addrinc) { + uint16_t i; + if (addrinc) { + addrinc = sizeof(iodata_t); + } + for (i = 0; i < len; i++) { + *buf++ = WIZCHIP.IF.BUS._read_data(AddrSel); + AddrSel += (uint32_t) addrinc; + } +} + +/** + @brief Default function to write @ref iodata_t buffer by using BUS interface. + @details @ref wizchip_bus_write_buf() provides the default write @ref iodata_t data as many as len to BUS of @ref _WIZCHIP_. + @param AddrSel It specifies the address of register to be written. + @param buf It specifies your buffer pointer to be written to @ref _WIZCHIP_. + @param len It specifies the data length to be written to @ref _WIZCHIP_. + @param addrinc It specifies whether the address is increased by every write operation or not.\n + 0 : Not Increased \n + 1 : Increased + @return void + @note It can be overwritten with your function or register your functions by calling @ref reg_wizchip_bus_cbfunc(). + @sa wizchip_bus_read_buf() +*/ +void wizchip_bus_write_buf(uint32_t AddrSel, iodata_t* buf, int16_t len, uint8_t addrinc) { + uint16_t i; + if (addrinc) { + addrinc = sizeof(iodata_t); + } + for (i = 0; i < len ; i++) { + WIZCHIP.IF.BUS._write_data(AddrSel, *buf++); + AddrSel += (uint32_t)addrinc; + } + +} +#endif + +/** + @brief 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. +*/ +//uint8_t wizchip_spi_readbyte(void) {return 0;}; +uint8_t wizchip_spi_readbyte(void) { + return 0; +} + +/** + @brief 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. +*/ +//void wizchip_spi_writebyte(uint8_t wb) {}; +void wizchip_spi_writebyte(uint8_t wb) {} + +/** + @brief Default function to burst 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. +*/ +//void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {}; +#if 1 +// 20231018 taylor +void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) { + for (uint16_t i = 0; i < len; i++) { + *pBuf++ = WIZCHIP.IF.SPI._read_byte(); + } +} +#else +void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {} +#endif + +/** + @brief Default function to burst 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. +*/ +//void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {}; +#if 1 +// 20231018 taylor +void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) { + for (uint16_t i = 0; i < len; i++) { + WIZCHIP.IF.SPI._write_byte(*pBuf++); + } +} +#else +void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {} +#endif +#if 1 //teddy 240122 + +/** + @brief Default function to read in QSPI 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. +*/ +void wizchip_qspi_read(uint8_t opcode, uint16_t addr, uint8_t* pBuf, uint16_t len) {} + +/** + @brief Default function to write in QSPI 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. +*/ +void wizchip_qspi_write(uint8_t opcode, uint16_t addr, uint8_t* pBuf, uint16_t len) {} + +#endif +/** + @\ref _WIZCHIP instance +*/ +// +//M20150401 : For a compiler didnot support a member of structure +// Replace the assignment of struct members with the assingment of array +// +/* + _WIZCHIP WIZCHIP = + { + .id = _WIZCHIP_ID_, + .if_mode = _WIZCHIP_IO_MODE_, + .CRIS._enter = wizchip_cris_enter, + .CRIS._exit = wizchip_cris_exit, + .CS._select = wizchip_cs_select, + .CS._deselect = wizchip_cs_deselect, + .IF.BUS._read_byte = wizchip_bus_readbyte, + .IF.BUS._write_byte = wizchip_bus_writebyte + // .IF.SPI._read_byte = wizchip_spi_readbyte, + // .IF.SPI._write_byte = wizchip_spi_writebyte + }; +*/ +_WIZCHIP WIZCHIP = { + _WIZCHIP_IO_MODE_, + _WIZCHIP_ID_, + { + wizchip_cris_enter, + wizchip_cris_exit + }, + { + wizchip_cs_select, + wizchip_cs_deselect + }, + { + { + //M20150601 : Rename the function + //wizchip_bus_readbyte, + //wizchip_bus_writebyte + wizchip_bus_readdata, + wizchip_bus_writedata + }, + + } +}; + + +static uint8_t _DNS_[4]; // DNS server ip address +#if (_WIZCHIP_ == W5100 || _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5300 || _WIZCHIP_ == W5500) +static dhcp_mode _DHCP_; // DHCP mode +//teddy 240122 +#elif ((_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300)) +static uint8_t _DNS6_[16]; ///< DSN server IPv6 address +static ipconf_mode _IPMODE_; ///< IP configuration mode +#endif + +void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)) { + if (!cris_en || !cris_ex) { + WIZCHIP.CRIS._enter = wizchip_cris_enter; + WIZCHIP.CRIS._exit = wizchip_cris_exit; + } else { + WIZCHIP.CRIS._enter = cris_en; + WIZCHIP.CRIS._exit = cris_ex; + } +} + +void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)) { + if (!cs_sel || !cs_desel) { + WIZCHIP.CS._select = wizchip_cs_select; + WIZCHIP.CS._deselect = wizchip_cs_deselect; + } else { + WIZCHIP.CS._select = cs_sel; + WIZCHIP.CS._deselect = cs_desel; + } +} + +//M20150515 : For integrating with W5300 +//void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)) +void reg_wizchip_bus_cbfunc(iodata_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)); + //M20150601 : Rename call back function for integrating with W5300 + /* + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } + */ + if (!bus_rb || !bus_wb) { + WIZCHIP.IF.BUS._read_data = wizchip_bus_readdata; + WIZCHIP.IF.BUS._write_data = wizchip_bus_writedata; + } else { + WIZCHIP.IF.BUS._read_data = bus_rb; + WIZCHIP.IF.BUS._write_data = bus_wb; + } +} +#if 1 +// 20231103 taylor +void reg_wizchip_busbuf_cbfunc(void(*busbuf_rb)(uint32_t AddrSel, iodata_t* pBuf, int16_t len, uint8_t addrinc), void (*busbuf_wb)(uint32_t AddrSel, iodata_t* pBuf, int16_t len, uint8_t addrinc)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)); + //M20150601 : Rename call back function for integrating with W5300 + /* + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } + */ + if (!busbuf_rb || !busbuf_wb) { + WIZCHIP.IF.BUS._read_data_buf = wizchip_bus_read_buf; + WIZCHIP.IF.BUS._write_data_buf = wizchip_bus_write_buf; + } else { + WIZCHIP.IF.BUS._read_data_buf = busbuf_rb; + WIZCHIP.IF.BUS._write_data_buf = busbuf_wb; + } +} +#endif + +#if _WIZCHIP_ == W6100 + +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb), + void (*spi_rbuf)(uint8_t* buf, datasize_t len), + void (*spi_wbuf)(uint8_t* buf, datasize_t len)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)); + + if (!spi_rb) { + WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte; + } else { + WIZCHIP.IF.SPI._read_byte = spi_rb; + } + if (!spi_wb) { + WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte; + } else { + WIZCHIP.IF.SPI._write_byte = spi_wb; + } + + if (!spi_rbuf) { + WIZCHIP.IF.SPI._read_burst = wizchip_spi_readburst; + } else { + WIZCHIP.IF.SPI._read_burst = spi_rbuf; + } + if (!spi_wbuf) { + WIZCHIP.IF.SPI._write_burst = wizchip_spi_writeburst; + } else { + WIZCHIP.IF.SPI._write_burst = spi_wbuf; + } +} +#else + +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)); + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte; + WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte; + } else { + WIZCHIP.IF.SPI._read_byte = spi_rb; + WIZCHIP.IF.SPI._write_byte = spi_wb; + } +} +#endif + +// 20140626 Eric Added for SPI burst operations +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t* pBuf, uint16_t len), void (*spi_wb)(uint8_t* pBuf, uint16_t len)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)); + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_burst = wizchip_spi_readburst; + WIZCHIP.IF.SPI._write_burst = wizchip_spi_writeburst; + } else { + WIZCHIP.IF.SPI._read_burst = spi_rb; + WIZCHIP.IF.SPI._write_burst = spi_wb; + } +} +#if 1 //teddy 240122 +void reg_wizchip_qspi_cbfunc(void (*qspi_rb)(uint8_t opcode, uint16_t addr, uint8_t* pBuf, uint16_t len), + void (*qspi_wb)(uint8_t opcode, uint16_t addr, uint8_t* pBuf, uint16_t len)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_QSPI_)); + + if (!qspi_rb || !qspi_wb) { + WIZCHIP.IF.QSPI._read_qspi = wizchip_qspi_read; + WIZCHIP.IF.QSPI._write_qspi = wizchip_qspi_write; + } else { + WIZCHIP.IF.QSPI._read_qspi = qspi_rb; + WIZCHIP.IF.QSPI._write_qspi = qspi_wb; + } +} +#endif + +int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg) { + //teddy 240122 +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 || _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + uint8_t tmp = *(uint8_t*) arg; +#endif + uint8_t* ptmp[2] = {0, 0}; + switch (cwtype) { + //teddy 240122 +#if _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + case CW_SYS_LOCK: + if (tmp & SYS_CHIP_LOCK) { + CHIPLOCK(); + } + if (tmp & SYS_NET_LOCK) { + NETLOCK(); + } + if (tmp & SYS_PHY_LOCK) { + PHYLOCK(); + } + break; + case CW_SYS_UNLOCK: + if (tmp & SYS_CHIP_LOCK) { + CHIPUNLOCK(); + } + if (tmp & SYS_NET_LOCK) { + NETUNLOCK(); + } + if (tmp & SYS_PHY_LOCK) { + PHYUNLOCK(); + } + break; + case CW_GET_SYSLOCK: + *(uint8_t*)arg = getSYSR() >> 5; + break; +#endif + case CW_RESET_WIZCHIP: + wizchip_sw_reset(); + break; + case CW_INIT_WIZCHIP: + if (arg != 0) { + ptmp[0] = (uint8_t*)arg; + ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; + } + return wizchip_init(ptmp[0], ptmp[1]); + case CW_CLR_INTERRUPT: + wizchip_clrinterrupt(*((intr_kind*)arg)); + break; + case CW_GET_INTERRUPT: + *((intr_kind*)arg) = wizchip_getinterrupt(); + break; + case CW_SET_INTRMASK: + wizchip_setinterruptmask(*((intr_kind*)arg)); + break; + case CW_GET_INTRMASK: + *((intr_kind*)arg) = wizchip_getinterruptmask(); + break; + //M20150601 : This can be supported by W5200, W5500 + //#if _WIZCHIP_ > W5100 +#if (_WIZCHIP_ == W5200 || _WIZCHIP_ == W5500) + case CW_SET_INTRTIME: + setINTLEVEL(*(uint16_t*)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t*)arg = getINTLEVEL(); + break; + //teddy 240122 +#elif ((_WIZCHIP_ == W6100) || (_WIZCHIP_ == W6300)) + case CW_SET_INTRTIME: + setINTPTMR(*(uint16_t*)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t*)arg = getINTPTMR(); + break; +#endif + case CW_GET_ID: + ((uint8_t*)arg)[0] = WIZCHIP.id[0]; + ((uint8_t*)arg)[1] = WIZCHIP.id[1]; + ((uint8_t*)arg)[2] = WIZCHIP.id[2]; + ((uint8_t*)arg)[3] = WIZCHIP.id[3]; + ((uint8_t*)arg)[4] = WIZCHIP.id[4]; + ((uint8_t*)arg)[5] = WIZCHIP.id[5]; + ((uint8_t*)arg)[6] = 0; + break; +#if 1 + // 20231017 taylor//teddy 240122 +#if _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + case CW_GET_VER: + *(uint16_t*)arg = getVER(); + break; +#endif +#endif + //teddy 240122 +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 || _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + case CW_RESET_PHY: + wizphy_reset(); + break; + case CW_SET_PHYCONF: + wizphy_setphyconf((wiz_PhyConf*)arg); + break; + case CW_GET_PHYCONF: + wizphy_getphyconf((wiz_PhyConf*)arg); + break; + case CW_GET_PHYSTATUS: +#if 1 + // 20231012 taylor +#if _WIZCHIP_ == W5500 + wizphy_getphystat((wiz_PhyConf*)arg); +#endif +#else + wizphy_getphystat((wiz_PhyConf*)arg); +#endif + break; + case CW_SET_PHYPOWMODE: + //teddy 240122 +#if _WIZCHIP_ == W6100 ||_WIZCHIP_ == W6300 + wizphy_setphypmode(*(uint8_t*)arg); + break; +#else + return wizphy_setphypmode(*(uint8_t*)arg); +#endif +#endif + //teddy 240122 +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 || _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + case CW_GET_PHYPOWMODE: + tmp = wizphy_getphypmode(); + if ((int8_t)tmp == -1) { + return -1; + } + *(uint8_t*)arg = tmp; + break; + case CW_GET_PHYLINK: + tmp = wizphy_getphylink(); + if ((int8_t)tmp == -1) { + return -1; + } + *(uint8_t*)arg = tmp; + break; +#endif + default: + return -1; + } + return 0; +} + + +int8_t ctlnetwork(ctlnetwork_type cntype, void* arg) { + + switch (cntype) { + case CN_SET_NETINFO: + wizchip_setnetinfo((wiz_NetInfo*)arg); + break; + case CN_GET_NETINFO: + wizchip_getnetinfo((wiz_NetInfo*)arg); + break; + case CN_SET_NETMODE: +#if (_WIZCHIP_ == W5100 || _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5300 || _WIZCHIP_ == W5500) + return wizchip_setnetmode(*(netmode_type*)arg); + //teddy 240122 +#elif ((_WIZCHIP_ == 6100)||(_WIZCHIP_ == W6300)) + wizchip_setnetmode(*(netmode_type*)arg); +#endif + case CN_GET_NETMODE: + *(netmode_type*)arg = wizchip_getnetmode(); + break; + case CN_SET_TIMEOUT: + wizchip_settimeout((wiz_NetTimeout*)arg); + break; + case CN_GET_TIMEOUT: + wizchip_gettimeout((wiz_NetTimeout*)arg); + break; + //teddy 240122 +#if ((_WIZCHIP_ == 6100)||(_WIZCHIP_ == 6300)) + case CN_SET_PREFER: + setSLPSR(*(uint8_t*)arg); + break; + case CN_GET_PREFER: + *(uint8_t*)arg = getSLPSR(); + break; +#endif + default: + return -1; + } + return 0; +} + +void wizchip_sw_reset(void) { + uint8_t gw[4], sn[4], sip[4]; + uint8_t mac[6]; + //teddy 240122 +#if ((_WIZCHIP_ == 6100) ||(_WIZCHIP_ == 6300)) + uint8_t gw6[16], sn6[16], lla[16], gua[16]; + uint8_t islock = getSYSR(); +#endif + +#if (_WIZCHIP_ == W5100 || _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5300 || _WIZCHIP_ == W5500) + //A20150601 +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + uint16_t mr = (uint16_t)getMR(); + setMR(mr | MR_IND); +#endif + // + getSHAR(mac); + getGAR(gw); getSUBR(sn); getSIPR(sip); + setMR(MR_RST); + getMR(); // for delay + //A2015051 : For indirect bus mode +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + setMR(mr | MR_IND); +#endif + // + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); + //teddy 240122 +#elif ((_WIZCHIP_ == W6100)||(_WIZCHIP_ == W6300)) + CHIPUNLOCK(); + + getSHAR(mac); + getGAR(gw); getSUBR(sn); getSIPR(sip); getGA6R(gw6); getSUB6R(sn6); getLLAR(lla); getGUAR(gua); + setSYCR0(SYCR0_RST); + getSYCR0(); // for delay + + NETUNLOCK(); + + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); + setGA6R(gw6); + setSUB6R(sn6); + setLLAR(lla); + setGUAR(gua); + if (islock & SYSR_CHPL) { + CHIPLOCK(); + } + if (islock & SYSR_NETL) { + NETLOCK(); + } +#endif +} + +int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize) { + int8_t i; +#if _WIZCHIP_ < W5200 + int8_t j; +#endif + int8_t tmp = 0; + wizchip_sw_reset(); + if (txsize) { + tmp = 0; + //M20150601 : For integrating with W5300 +#if _WIZCHIP_ == W5300 + for (i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) { + if (txsize[i] > 64) { + return -1; //No use 64KB even if W5300 support max 64KB memory allocation + } + tmp += txsize[i]; + if (tmp > 128) { + return -1; + } + } + if (tmp % 8) { + return -1; + } +#else + for (i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += txsize[i]; + +#if _WIZCHIP_ < W5200 //2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) { + return -1; + } +#elif _WIZCHIP_ == W6300 + if (tmp > 32) { + return -1; + } +#else + if (tmp > 16) { + return -1; + } +#endif + } +#endif + for (i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 //2016.10.28 peter add condition for w5100 + j = 0; + while ((txsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_TXBUF_SIZE(i, j); +#else + setSn_TXBUF_SIZE(i, txsize[i]); +#endif + } + } + + if (rxsize) { + tmp = 0; +#if _WIZCHIP_ == W5300 + for (i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) { + if (rxsize[i] > 64) { + return -1; //No use 64KB even if W5300 support max 64KB memory allocation + } + tmp += rxsize[i]; + if (tmp > 128) { + return -1; + } + } + if (tmp % 8) { + return -1; + } +#else + for (i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += rxsize[i]; +#if _WIZCHIP_ < W5200 //2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) { + return -1; + } +#elif _WIZCHIP_ == W6300 + if (tmp > 32) { + return -1; + } +#else + if (tmp > 16) { + return -1; + } +#endif + } +#endif + for (i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // add condition for w5100 + j = 0; + while ((rxsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_RXBUF_SIZE(i, j); +#else + setSn_RXBUF_SIZE(i, rxsize[i]); +#endif + } + } + return 0; +} + +void wizchip_clrinterrupt(intr_kind intr) { + uint8_t ir = (uint8_t)intr; + uint8_t sir = (uint8_t)((uint16_t)intr >> 8); + + //teddy 240122 +#if _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + int i; + uint8_t slir = (uint8_t)((uint32_t)intr >> 16); + setIRCLR(ir); + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (sir & (1 << i)) { + setSn_IRCLR(i, 0xFF); + } + } + setSLIRCLR(slir); + return; +#endif + +#if _WIZCHIP_ < W5500 + ir |= (1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir |= (1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + sir &= 0x0F; +#endif + +#if _WIZCHIP_ <= W5100S + ir |= sir; + setIR(ir); + //A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIR(((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF))); +#else + setIR(ir); + //M20200227 : For clear + //setSIR(sir); + for (ir = 0; ir < 8; ir++) { + if (sir & (0x01 << ir)) { + setSn_IR(ir, 0xff); + } + } + +#endif +} + +intr_kind wizchip_getinterrupt(void) { + uint8_t ir = 0; + uint8_t sir = 0; + uint32_t ret = 0; + +#if _WIZCHIP_ <= W5100S + ir = getIR(); + sir = ir & 0x0F; + //A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIR(); + ir = (uint8_t)(ret >> 8); + sir = (uint8_t)ret; +#else + ir = getIR(); + sir = getSIR(); +#endif + + //M20150601 : For Integrating with W5300 + //#if _WIZCHIP_ < W5500 +#if _WIZCHIP_ < W5200 + ir &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir &= ~(1 << 6); +#endif + ret = sir; + ret = (ret << 8) + ir; + //teddy 240122 +#if _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + ret = (((uint32_t)getSLIR()) << 16) | ret; +#endif + + return (intr_kind)ret; +} + +void wizchip_setinterruptmask(intr_kind intr) { + uint8_t imr = (uint8_t)intr; + uint8_t simr = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + simr &= 0x0F; + imr |= simr; + setIMR(imr); + //A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIMR(((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF))); +#else + setIMR(imr); + setSIMR(simr); + //teddy 240122 +#if _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + uint8_t slimr = (uint8_t)((uint32_t)intr >> 16); + setSLIMR(slimr); +#endif +#endif +} + +intr_kind wizchip_getinterruptmask(void) { + uint8_t imr = 0; + uint8_t simr = 0; + uint32_t ret = 0; +#if _WIZCHIP_ < W5200 + imr = getIMR(); + simr = imr & 0x0F; + //A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIMR(); + imr = (uint8_t)(ret >> 8); + simr = (uint8_t)ret; +#else + imr = getIMR(); + simr = getSIMR(); +#endif + +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); // IK_DEST_UNREACH +#endif + ret = simr; + ret = (ret << 8) + imr; + + //teddy 240122 +#if _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 + ret = (((uint32_t)getSLIMR()) << 16) | ret; +#endif + + return (intr_kind)ret; +} + +int8_t wizphy_getphylink(void) { + int8_t tmp = PHY_LINK_OFF; +#if _WIZCHIP_ == W5100S + if (getPHYSR() & PHYSR_LNK) { + tmp = PHY_LINK_ON; + } +#elif _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_LINK) { + tmp = PHY_LINK_ON; + } +#elif _WIZCHIP_ == W5500 + if (getPHYCFGR() & PHYCFGR_LNK_ON) { + tmp = PHY_LINK_ON; + } + +#elif ((_WIZCHIP_ == W6100)||(_WIZCHIP_ == W6300)) + +#if (_PHY_IO_MODE_ == _PHY_IO_MODE_PHYCR_) + return (getPHYSR() & PHYSR_LNK); +#elif (_PHY_IO_MODE_ == _PHY_IO_MODE_MII_) + if (wiz_mdio_read(PHYRAR_BMSR) & BMSR_LINK_STATUS) { + return PHY_LINK_ON; + } + return PHY_LINK_OFF; +#endif + +#else + tmp = -1; +#endif + return tmp; +} + +#if _WIZCHIP_ > W5100 + +int8_t wizphy_getphypmode(void) { + int8_t tmp = 0; +#if _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_POWERDOWN) { + tmp = PHY_POWER_DOWN; + } else { + tmp = PHY_POWER_NORM; + } +#elif _WIZCHIP_ == 5500 + if ((getPHYCFGR() & PHYCFGR_OPMDC_ALLA) == PHYCFGR_OPMDC_PDOWN) { + tmp = PHY_POWER_DOWN; + } else { + tmp = PHY_POWER_NORM; + } + //teddy 240122 +#elif _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 +#if (_PHY_IO_MODE_ == _PHY_IO_MODE_PHYCR_) + if (getPHYCR1() & PHYCR1_PWDN) { + return PHY_POWER_DOWN; + } +#elif (_PHY_IO_MODE_ == _PHY_IO_MODE_MII_) + if (wiz_mdio_read(PHYRAR_BMCR) & BMCR_PWDN) { + return PHY_POWER_DOWN; + } +#endif + return PHY_POWER_NORM; +#else + tmp = -1; +#endif + return tmp; +} +#endif + +#if _WIZCHIP_ == W5100S +void wizphy_reset(void) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + tmp |= BMCR_RESET; + wiz_mdio_write(PHYMDIO_BMCR, tmp); + while (wiz_mdio_read(PHYMDIO_BMCR)&BMCR_RESET) {} +} + +void wizphy_setphyconf(wiz_PhyConf* phyconf) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (phyconf->mode == PHY_MODE_AUTONEGO) { + tmp |= BMCR_AUTONEGO; + } else { + tmp &= ~BMCR_AUTONEGO; + if (phyconf->duplex == PHY_DUPLEX_FULL) { + tmp |= BMCR_DUP; + } else { + tmp &= ~BMCR_DUP; + } + if (phyconf->speed == PHY_SPEED_100) { + tmp |= BMCR_SPEED; + } else { + tmp &= ~BMCR_SPEED; + } + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); +} + +void wizphy_getphyconf(wiz_PhyConf* phyconf) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + phyconf->by = PHY_CONFBY_SW; + if (tmp & BMCR_AUTONEGO) { + phyconf->mode = PHY_MODE_AUTONEGO; + } else { + phyconf->mode = PHY_MODE_MANUAL; + if (tmp & BMCR_DUP) { + phyconf->duplex = PHY_DUPLEX_FULL; + } else { + phyconf->duplex = PHY_DUPLEX_HALF; + } + if (tmp & BMCR_SPEED) { + phyconf->speed = PHY_SPEED_100; + } else { + phyconf->speed = PHY_SPEED_10; + } + } +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + tmp |= BMCR_PWDN; + } else { + tmp &= ~BMCR_PWDN; + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + if (tmp & BMCR_PWDN) { + return 0; + } + } else { + if ((tmp & BMCR_PWDN) != BMCR_PWDN) { + return 0; + } + } + return -1; +} + +#elif _WIZCHIP_ == W5500 +void wizphy_reset(void) { + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +void wizphy_setphyconf(wiz_PhyConf* phyconf) { + uint8_t tmp = 0; + if (phyconf->by == PHY_CONFBY_SW) { + tmp |= PHYCFGR_OPMD; + } else { + tmp &= ~PHYCFGR_OPMD; + } + if (phyconf->mode == PHY_MODE_AUTONEGO) { + tmp |= PHYCFGR_OPMDC_ALLA; + } else { + if (phyconf->duplex == PHY_DUPLEX_FULL) { + if (phyconf->speed == PHY_SPEED_100) { + tmp |= PHYCFGR_OPMDC_100F; + } else { + tmp |= PHYCFGR_OPMDC_10F; + } + } else { + if (phyconf->speed == PHY_SPEED_100) { + tmp |= PHYCFGR_OPMDC_100H; + } else { + tmp |= PHYCFGR_OPMDC_10H; + } + } + } + setPHYCFGR(tmp); + wizphy_reset(); +} + +void wizphy_getphyconf(wiz_PhyConf* phyconf) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_ALLA: + case PHYCFGR_OPMDC_100FA: + phyconf->mode = PHY_MODE_AUTONEGO; + break; + default: + phyconf->mode = PHY_MODE_MANUAL; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_100H: + phyconf->speed = PHY_SPEED_100; + break; + default: + phyconf->speed = PHY_SPEED_10; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_10F: + phyconf->duplex = PHY_DUPLEX_FULL; + break; + default: + phyconf->duplex = PHY_DUPLEX_HALF; + break; + } +} + +void wizphy_getphystat(wiz_PhyConf* phyconf) { + uint8_t tmp = getPHYCFGR(); + phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; +} + +int8_t 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; +} + +//teddy 240122 +#elif _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 +void wizphy_reset(void) { +#if (_PHY_IO_MODE_ == _PHY_IO_MODE_PHYCR_) + uint8_t tmp = getPHYCR1() | PHYCR1_RST; + PHYUNLOCK(); + setPHYCR1(tmp); + PHYLOCK(); +#elif (_PHY_IO_MODE_ == _PHY_IO_MODE_MII_) + wiz_mdio_write(PHYRAR_BMCR, wiz_mdio_read(PHYRAR_BMCR) | BMCR_RST); + while (wiz_mdio_read(PHYRAR_BMCR) & BMCR_RST); +#endif +} + +void wizphy_setphyconf(wiz_PhyConf* phyconf) { +#if (_PHY_IO_MODE_ == _PHY_IO_MODE_PHYCR_) + uint8_t tmp = 0; + if (phyconf->mode == PHY_MODE_TE) { + setPHYCR1(getPHYCR1() | PHYCR1_TE); + tmp = PHYCR0_AUTO; + } else { + setPHYCR1(getPHYCR1() & ~PHYCR1_TE); + if (phyconf->mode == PHY_MODE_AUTONEGO) { + tmp = PHYCR0_AUTO; + } else { + tmp |= 0x04; + if (phyconf->speed == PHY_SPEED_10) { + tmp |= 0x02; + } + if (phyconf->duplex == PHY_DUPLEX_HALF) { + tmp |= 0x01; + } + } + } + setPHYCR0(tmp); +#elif (_PHY_IO_MODE_ == _PHY_IO_MODE_MII_) + uint16_t tmp = wiz_mdio_read(PHYRAR_BMCR); + if (phyconf->mode == PHY_MODE_TE) { + setPHYCR1(getPHYCR1() | PHYCR1_TE); + setPHYCR0(PHYCR0_AUTO); + } else { + setPHYCR1(getPHYCR1() & ~PHYCR1_TE); + if (phyconf->mode == PHY_MODE_AUTONEGO) { + tmp |= BMCR_ANE; + } else { + tmp &= ~(BMCR_ANE | BMCR_DPX | BMCR_SPD); + if (phyconf->duplex == PHY_DUPLEX_FULL) { + tmp |= BMCR_DPX; + } + if (phyconf->speed == PHY_SPEED_100) { + tmp |= BMCR_SPD; + } + } + wiz_mdio_write(PHYRAR_BMCR, tmp); + } +#endif +} + +void wizphy_getphyconf(wiz_PhyConf* phyconf) { +#if (_PHY_IO_MODE_ == _PHY_IO_MODE_PHYCR_) + uint8_t tmp = 0; + tmp = getPHYSR(); + if (getPHYCR1() & PHYCR1_TE) { + phyconf->mode = PHY_MODE_TE; + } else { + phyconf->mode = (tmp & (1 << 5)) ? PHY_MODE_MANUAL : PHY_MODE_AUTONEGO ; + } + phyconf->speed = (tmp & (1 << 4)) ? PHY_SPEED_10 : PHY_SPEED_100; + phyconf->duplex = (tmp & (1 << 3)) ? PHY_DUPLEX_HALF : PHY_DUPLEX_FULL; +#elif (_PHY_IO_MODE_ == _PHY_IO_MODE_MII_) + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYRAR_BMCR); + if (getPHYCR1() & PHYCR1_TE) { + phyconf->mode = PHY_MODE_TE; + } else { + phyconf->mode = (tmp & BMCR_ANE) ? PHY_MODE_AUTONEGO : PHY_MODE_MANUAL; + } + phyconf->duplex = (tmp & BMCR_DPX) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & BMCR_SPD) ? PHY_SPEED_100 : PHY_SPEED_10; +#endif +} + +void wizphy_getphystat(wiz_PhyConf* phyconf) { + uint8_t tmp = 0; + tmp = getPHYSR(); + if (getPHYCR1() & PHYCR1_TE) { + phyconf->mode = PHY_MODE_TE; + } else { + phyconf->mode = (tmp & (1 << 5)) ? PHY_MODE_MANUAL : PHY_MODE_AUTONEGO ; + } + phyconf->speed = (tmp & PHYSR_SPD) ? PHY_SPEED_10 : PHY_SPEED_100; + phyconf->duplex = (tmp & PHYSR_DPX) ? PHY_DUPLEX_HALF : PHY_DUPLEX_FULL; +} + +void wizphy_setphypmode(uint8_t pmode) { +#if (_PHY_IO_MODE_ == _PHY_IO_MODE_PHYCR_) + uint8_t tmp = getPHYCR1(); + if (pmode == PHY_POWER_DOWN) { + tmp |= PHYCR1_PWDN; + } else { + tmp &= ~PHYCR1_PWDN; + } + setPHYCR1(tmp); +#elif (_PHY_IO_MODE_ == _PHY_IO_MODE_MII_) + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYRAR_BMCR); + if (pmode == PHY_POWER_DOWN) { + tmp |= BMCR_PWDN; + } else { + tmp &= ~BMCR_PWDN; + } + wiz_mdio_write(PHYRAR_BMCR, tmp); +#endif +} + +int8_t wizchip_arp(wiz_ARP* arp) { + uint8_t tmp; + if (arp->destinfo.len == 16) { + setSLDIP6R(arp->destinfo.ip); + setSLCR(SLCR_ARP6); + } else { + setSLDIP4R(arp->destinfo.ip); + setSLCR(SLCR_ARP4); + } + while (getSLCR()); + while ((tmp = getSLIR()) == 0x00); + setSLIRCLR(~SLIR_RA); + if (tmp & (SLIR_ARP4 | SLIR_ARP6)) { + getSLDHAR(arp->dha); + return 0; + } + return -1; +} + +int8_t wizchip_ping(wiz_PING* ping) { + uint8_t tmp; + setPINGIDR(ping->id); + setPINGSEQR(ping->seq); + if (ping->destinfo.len == 16) { + setSLDIP6R(ping->destinfo.ip); + setSLCR(SLCR_PING6); + } else { + setSLDIP4R(ping->destinfo.ip); + setSLCR(SLCR_PING4); + } + while (getSLCR()); + while ((tmp = getSLIR()) == 0x00); + setSLIRCLR(~SLIR_RA); + if (tmp & (SLIR_PING4 | SLIR_PING6)) { + return 0; + } + return -1; +} + +int8_t wizchip_dad(uint8_t* ipv6) { + uint8_t tmp; + setSLDIP6R(ipv6); + setSLCR(SLCR_NS); + while (getSLCR()); + while ((tmp = getSLIR()) == 0x00); + setSLIRCLR(~SLIR_RA); + if (tmp & SLIR_TOUT) { + return 0; + } + return -1; +} + +int8_t wizchip_slaac(wiz_Prefix* prefix) { + uint8_t tmp; + setSLCR(SLCR_RS); + while (getSLCR()); + while ((tmp = getSLIR()) == 0x00); + setSLIRCLR(~SLIR_RA); + if (tmp & SLIR_RS) { + prefix->len = getPLR(); + prefix->flag = getPFR(); + prefix->valid_lifetime = getVLTR(); + prefix->preferred_lifetime = getPLTR(); + getPAR(prefix->prefix); + return 0; + } + return -1; +} + +int8_t wizchip_unsolicited(void) { + uint8_t tmp; + setSLCR(SLCR_UNA); + while (getSLCR()); + while ((tmp = getSLIR()) == 0x00); + setSLIRCLR(~SLIR_RA); + if (tmp & SLIR_TOUT) { + return 0; + } + return -1; +} + +int8_t wizchip_getprefix(wiz_Prefix * prefix) { + if (getSLIR() & SLIR_RA) { + prefix->len = getPLR(); + prefix->flag = getPFR(); + prefix->valid_lifetime = getVLTR(); + prefix->preferred_lifetime = getPLTR(); + getPAR(prefix->prefix); + setSLIRCLR(SLIR_RA); + } + return -1; +} + + +#endif + +#if (_WIZCHIP_ == W5100 || _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5300 || _WIZCHIP_ == W5500) +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo) { + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); + _DNS_[0] = pnetinfo->dns[0]; + _DNS_[1] = pnetinfo->dns[1]; + _DNS_[2] = pnetinfo->dns[2]; + _DNS_[3] = pnetinfo->dns[3]; + _DHCP_ = pnetinfo->dhcp; +} + +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo) { + getSHAR(pnetinfo->mac); + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); + pnetinfo->dns[0] = _DNS_[0]; + pnetinfo->dns[1] = _DNS_[1]; + pnetinfo->dns[2] = _DNS_[2]; + pnetinfo->dns[3] = _DNS_[3]; + pnetinfo->dhcp = _DHCP_; +} + +int8_t wizchip_setnetmode(netmode_type netmode) { + uint8_t tmp = 0; +#if _WIZCHIP_ != W5500 + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) { + return -1; + } +#else + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) { + return -1; + } +#endif + tmp = getMR(); + tmp |= (uint8_t)netmode; + setMR(tmp); + return 0; +} + +netmode_type wizchip_getnetmode(void) { + return (netmode_type) getMR(); +} + +void wizchip_settimeout(wiz_NetTimeout* nettime) { + setRCR(nettime->retry_cnt); + setRTR(nettime->time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout* nettime) { + nettime->retry_cnt = getRCR(); + nettime->time_100us = getRTR(); +} +//teddy 240122 +#elif ((_WIZCHIP_ == 6100) ||(_WIZCHIP_ == 6300)) +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo) { + uint8_t i = 0; + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); + setGA6R(pnetinfo->gw6); + setSUB6R(pnetinfo->sn6); + setLLAR(pnetinfo->lla); + setGUAR(pnetinfo->gua); + + for (i = 0; i < 4; i++) { + _DNS_[i] = pnetinfo->dns[i]; + } + for (i = 0; i < 16; i++) { + _DNS6_[i] = pnetinfo->dns6[i]; + } + + _IPMODE_ = pnetinfo->ipmode; +} + +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo) { + uint8_t i = 0; + getSHAR(pnetinfo->mac); + + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); + + getGA6R(pnetinfo->gw6); + getSUB6R(pnetinfo->sn6); + getLLAR(pnetinfo->lla); + getGUAR(pnetinfo->gua); + for (i = 0; i < 4; i++) { + pnetinfo->dns[i] = _DNS_[i]; + } + for (i = 0; i < 16; i++) { + pnetinfo->dns6[i] = _DNS6_[i]; + } + + pnetinfo->ipmode = _IPMODE_; +} + +void wizchip_setnetmode(netmode_type netmode) { + uint32_t tmp = (uint32_t) netmode; + setNETMR((uint8_t)tmp); + setNETMR2((uint8_t)(tmp >> 8)); + setNET4MR((uint8_t)(tmp >> 16)); + setNET6MR((uint8_t)(tmp >> 24)); +} + +netmode_type wizchip_getnetmode(void) { + uint32_t ret = 0; + ret = getNETMR(); + ret = (ret << 8) + getNETMR2(); + ret = (ret << 16) + getNET4MR(); + ret = (ret << 24) + getNET6MR(); + return (netmode_type)ret; +} + +// netmode_type wizchip_getnetmode(void) +// { +// return (netmode_type) getMR(); +// } + +void wizchip_settimeout(wiz_NetTimeout* nettime) { + setRCR(nettime->s_retry_cnt); + setRTR(nettime->s_time_100us); + setSLRCR(nettime->sl_retry_cnt); + setSLRTR(nettime->sl_time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout* nettime) { + nettime->s_retry_cnt = getRCR(); + nettime->s_time_100us = getRTR(); + nettime->sl_retry_cnt = getSLRCR(); + nettime->sl_time_100us = getSLRTR(); +} +#endif + diff --git a/lib/w6300/ioLibrary/wizchip_conf.h b/lib/w6300/ioLibrary/wizchip_conf.h new file mode 100644 index 0000000..f861b50 --- /dev/null +++ b/lib/w6300/ioLibrary/wizchip_conf.h @@ -0,0 +1,1346 @@ +//***************************************************************************** +// +//! \file wizchip_conf.h +//! \brief WIZCHIP Config Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * 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. +//! * Neither the name of the 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 OWNER 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. +// +//***************************************************************************** + +/** + @defgroup extra_functions 2. WIZnet Extra Functions + + @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions. + @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n + +*/ + +#ifndef _WIZCHIP_CONF_H_ +#define _WIZCHIP_CONF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/** + @brief Select WIZCHIP. + @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b W5500 or etc. \n\n + ex> #define \_WIZCHIP_ W5500 +*/ + +#define W5100 5100 +#define W5100S 5100+5 +#define W5200 5200 +#define W5300 5300 +#define W5500 5500 +#define W6100 6100 +#define W6300 6300 + + +#ifndef _WIZCHIP_ +// NOTE_LIHAN: Some sections of this code are not yet fully defined. +#define _WIZCHIP_ W6300 // W5100, W5100S, W5200, W5300, W5500, 6300 +#endif + +// +//#ifndef _WIZCHIP_ +// #error please Define your WIZnet chip numer +//#endif + + +#define _WIZCHIP_IO_MODE_NONE_ 0x0000 +#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ +#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ +//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 +//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 +// Add to +// + +#define _WIZCHIP_IO_MODE_BUS_DIR_ (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ +#define _WIZCHIP_IO_MODE_BUS_INDIR_ (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ + +#define _WIZCHIP_IO_MODE_SPI_VDM_ (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/ +#define _WIZCHIP_IO_MODE_SPI_FDM_ (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/ +#define _WIZCHIP_IO_MODE_SPI_5500_ (_WIZCHIP_IO_MODE_SPI_ + 3) /**< SPI interface mode for fixed length data mode*/ +//teddy 240122 +#define _WIZCHIP_IO_MODE_SPI_QSPI_ (_WIZCHIP_IO_MODE_SPI_ + 4) /**< SPI interface mode for QSPI mode*/ + + + +/** + @brief PHY can be accessed by @ref _PHYCR0_, _PHYCR1_. + @details It provides hardware access method. + @note It is smaller s/w footprint than @ref _PHY_IO_MODE_MII_. + @sa _PHY_IO_MODE_MII_, _PHY_IO_MODE_ + @sa ctlwizchip(), getPHYCR0(), getPHYCR1(), setPHYCR1(), getPHYSR() +*/ +#define _PHY_IO_MODE_PHYCR_ 0x0000 + +/** + @brief PHY can be accessed by MDC/MDIO signals of MII interface. + @details It provide software access method. + @note It is bigger s/w footprint than @ref _PHY_IO_MODE_PHYCR_. + @sa _PHY_IO_MODE_PHYCR_, _PHY_IO_MODE_ + @sa ctlwizchip(), wiz_read_mdio(), wiz_write_mdio() +*/ +#define _PHY_IO_MODE_MII_ 0x0010 + +/** + @brief Select PHY Access Mode + @details @ref _PHY_IO_MODE_ selects PHY access method. + @todo You should select one of @ref _PHY_IO_MODE_PHYCR_ or @ref _PHY_IO_MODE_MII_. + @sa ctlwizchip() +*/ +#define _PHY_IO_MODE_ _PHY_IO_MODE_MII_ //_PHY_IO_MODE_MII_ + + + +#if (_WIZCHIP_ == W5100) +#define _WIZCHIP_ID_ "W5100\0" +/** + @brief Define interface mode. + @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ +*/ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +//A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +//A20150401 : Indclude W5100.h file +#include "W5100/w5100.h" + +#elif (_WIZCHIP_ == W5100S) +#define _WIZCHIP_ID_ "W5100S\0" +/** + @brief Define interface mode. + @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ +*/ +#if 0 +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#elif 0 +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_5500_ +#else +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ +#endif + +//A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +//A20150401 : Indclude W5100.h file +#include "W5100S/w5100s.h" +#elif (_WIZCHIP_ == W5200) +#define _WIZCHIP_ID_ "W5200\0" +/** + @brief Define interface mode. + @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \ _WIZCHIP_IO_MODE_BUS_INDIR_ +*/ +#ifndef _WIZCHIP_IO_MODE_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ +#endif +//A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "W5200/w5200.h" +#elif (_WIZCHIP_ == W5500) +#define _WIZCHIP_ID_ "W5500\0" + +/** + @brief Define interface mode. \n + @todo Should select interface mode as chip. + - @ref \_WIZCHIP_IO_MODE_SPI_ \n + -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == W5500 \n + -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == W5500 \n + - @ref \_WIZCHIP_IO_MODE_BUS_ \n + - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n + - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n + - Others will be defined in future. \n\n + ex> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ + +*/ +#ifndef _WIZCHIP_IO_MODE_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ +#endif +//A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "W5500/w5500.h" +#elif ( _WIZCHIP_ == W5300) +#define _WIZCHIP_ID_ "W5300\0" +/** + @brief Define interface mode. + @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ +*/ +#ifndef _WIZCHIP_IO_MODE_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#endif + +//A20150601 : Define the unit and bus width of IO DATA. +/** + @brief Select the data width 8 or 16 bits. + @todo you should select the bus width. Select one of 8 or 16. +*/ +#ifndef _WIZCHIP_IO_BUS_WIDTH_ +#define _WIZCHIP_IO_BUS_WIDTH_ 16 // 8 +#endif +#if _WIZCHIP_IO_BUS_WIDTH_ == 8 +typedef uint8_t iodata_t; +#elif _WIZCHIP_IO_BUS_WIDTH_ == 16 +typedef uint16_t iodata_t; +#else +#error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16." +#endif +// +#include "W5300/w5300.h" + + +#elif ( _WIZCHIP_ == W6100) + +#define _WIZCHIP_ID_ "W6100\0" + +/** + @brief Define @ref _WIZCHIP_ interface mode. + @todo You should select interface mode of @ref _WIZCHIP_.\n\n + Select one of @ref _WIZCHIP_IO_MODE_SPI_VDM_, @ref _WIZCHIP_IO_MODE_SPI_FDM_, and @ref _WIZCHIP_IO_MODE_BUS_INDIR_ + @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() +*/ +#if 1 +// 20231103 taylor +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ +#elif 0 +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ +#else +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPV_FDM_ +#endif + +typedef uint8_t iodata_t; ///< IO access unit. bus width +typedef int16_t datasize_t; ///< sent or received data size +#include "./W6100/w6100.h" + +//teddy 240122 +#elif ( _WIZCHIP_ == W6300) + +#define _WIZCHIP_ID_ "W6300\0" + + + + +/** + @brief Define @ref _WIZCHIP_ interface mode. + @todo You should select interface mode of @ref _WIZCHIP_.\n\n + Select one of @ref _WIZCHIP_IO_MODE_SPI_QSPI_, @ref _WIZCHIP_IO_MODE_SPI_VDM_,@ref _WIZCHIP_IO_MODE_BUS_INDIR_ + @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() +*/ + +#define QSPI_SINGLE_MODE (0x00 << 6) // 0b0000 0000 // 0x00 +#define QSPI_DUAL_MODE (0x01 << 6) // 0b0100 0000 // 0x40 +#define QSPI_QUAD_MODE (0x02 << 6) // 0b1000 0000 // 0x80 + +#ifndef _WIZCHIP_QSPI_MODE_ +#define _WIZCHIP_QSPI_MODE_ QSPI_SINGLE_MODE +#endif + +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ ((_WIZCHIP_IO_MODE_SPI_ & 0xff00) | (_WIZCHIP_QSPI_MODE_ & 0x00ff)) + + + +typedef uint8_t iodata_t; ///< IO access unit. bus width +typedef int16_t datasize_t; ///< sent or received data size +#include "./W6300/w6300.h" + +#else +#error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, 5300, 5500, 6100 and 6300!!!" +#endif + +#ifndef _WIZCHIP_IO_MODE_ +#error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" +#endif + +/** + @brief Define I/O base address when BUS IF mode. + @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_, + @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n + ex> #define \_WIZCHIP_IO_BASE_ 0x00008000 +*/ +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +#if 1 +// 20231108 taylor +#if (_WIZCHIP_ == W6300) +#define _WIZCHIP_IO_BASE_ 0x60000000 // for W6100-EVB +#elif (_WIZCHIP_ == W6100) +#define _WIZCHIP_IO_BASE_ 0x60000000 // for W5100S-EV +#elif (_WIZCHIP_ == W5100S) +#define _WIZCHIP_IO_BASE_ 0x60000000 // for W5100S-EVB +#elif (_WIZCHIP_ == W5300) +#define _WIZCHIP_IO_BASE_ 0x68000000 // for W5300 by javakys 20210408 @66c27e960a813f7ea6e8b1ce083d12b3e7e86fc0 +#else +#define _WIZCHIP_IO_BASE_ 0x00000000 +#endif + +#else +#if (_WIZCHIP_ == W6100) +#define _WIZCHIP_IO_BASE_ 0x60000000 // for W6100 BUS +#else +// #define _WIZCHIP_IO_BASE_ 0x60000000 // for 5100S IND +#define _WIZCHIP_IO_BASE_ 0x68000000 // for W5300 +#endif +#endif +#elif _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_ +//#define _WIZCHIP_IO_BASE_ 0x00000000 // for 5100S SPI +#endif + +#ifndef _WIZCHIP_IO_BASE_ +#if 1 +// 20231108 taylor +#define _WIZCHIP_IO_BASE_ 0x00000000 +#else +#define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000 +#endif +#endif + +//M20150401 : Typing Error +//#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +#ifndef _WIZCHIP_IO_BASE_ +#error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." +#endif +#endif + +#if _WIZCHIP_ >= W5200 +#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP +#else +#define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP +#endif + + +/******************************************************** + WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. +*********************************************************/ +/** + @ingroup DATA_TYPE + @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200 +*/ +typedef struct __WIZCHIP { + uint16_t if_mode; ///< host interface mode + uint8_t id[8]; ///< @b WIZCHIP ID such as @b 5100, @b 5100S, @b 5200, @b 5500, and so on. + /** + The set of critical section callback func. + */ + struct _CRIS { + void (*_enter) (void); ///< crtical section enter + void (*_exit) (void); ///< critial section exit + } CRIS; + /** + The set of @ref \_WIZCHIP_ select control callback func. + */ + struct _CS { + void (*_select) (void); ///< @ref \_WIZCHIP_ selected + void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected + } CS; + /** + The set of interface IO callback func. + */ + union _IF { + /** + For BUS interface IO + */ + //M20156501 : Modify the function name for integrating with W5300 + //struct + //{ + // uint8_t (*_read_byte) (uint32_t AddrSel); + // void (*_write_byte) (uint32_t AddrSel, uint8_t wb); + //}BUS; + struct { + iodata_t (*_read_data) (uint32_t AddrSel); + void (*_write_data) (uint32_t AddrSel, iodata_t wb); +#if 1 + // 20231103 taylor + void (*_read_data_buf) (uint32_t AddrSel, iodata_t* pBuf, int16_t len, uint8_t addrinc); ///< Read @ref iodata_t as many as len from @ref _WIZCHIP_ through BUS + void (*_write_data_buf) (uint32_t AddrSel, iodata_t* pBuf, int16_t len, uint8_t addrinc); ///< Write @ref iodata_t data as many as len to @ref _WIZCHIP_ through BUS +#endif + } BUS; + + /** + For SPI interface IO + */ + struct { + uint8_t (*_read_byte) (void); + void (*_write_byte) (uint8_t wb); + void (*_read_burst) (uint8_t* pBuf, uint16_t len); + void (*_write_burst) (uint8_t* pBuf, uint16_t len); + } SPI; + + /** + For QSPI interface IO + */ + //teddy 240122 + struct { + void (*_read_qspi) (uint8_t opcode, uint16_t addr, uint8_t* pBuf, uint16_t len); + void (*_write_qspi) (uint8_t opcode, uint16_t addr, uint8_t* pBuf, uint16_t len); + } QSPI; + // To be added + // + } IF; +} _WIZCHIP; + +extern _WIZCHIP WIZCHIP; + +/** + @ingroup DATA_TYPE + WIZCHIP control type enumration used in @ref ctlwizchip(). +*/ +typedef enum { + CW_SYS_LOCK, ///< Lock or Unlock @ref _WIZCHIP_ with @ref SYS_CHIP_LOCK, @ref SYS_PHY_LOCK, and @ref SYS_NET_LOCK + CW_SYS_UNLOCK, ///< Lock or Unlock @ref _WIZCHIP_ with @ref SYS_CHIP_LOCK, @ref SYS_PHY_LOCK, and @ref SYS_NET_LOCK + CW_GET_SYSLOCK, ///< Get the lock status of @ref _WIZCHIP_ with @ref SYS_CHIP_LOCK, @ref SYS_PHY_LOCK, and @ref SYS_NET_LOCK + + CW_RESET_WIZCHIP, ///< Reset @ref _WIZCHIP_ by software + CW_INIT_WIZCHIP, ///< Initialize to SOCKETn buffer size with n byte array typed uint8_t + CW_GET_INTERRUPT, ///< Get the interrupt status with @ref intr_kind + CW_CLR_INTERRUPT, ///< Clear the interrupt with @ref intr_kind + CW_SET_INTRMASK, ///< Set the interrupt mask with @ref intr_kind + CW_GET_INTRMASK, ///< Get the interrupt mask with @ref intr_kind + CW_SET_INTRTIME, ///< Set the interrupt pending time + CW_GET_INTRTIME, ///< Get the interrupt pending time + CW_SET_IEN, ///< Set the global interrupt enable only when @ref SYS_CHIP_LOCK is not set + CW_GET_IEN, ///< Get the global interrupt enable + + CW_GET_ID, ///< Get @ref _WIZCHIP_ name. + CW_GET_VER, ///< Get the version of TCP/IP TOE engine + + CW_SET_SYSCLK, ///< Set the system clock with @ref SYSCLK_100MHZ or SYSCLK_10MHZ only when @ref SYS_CHIP_LOCK is unlock + CW_GET_SYSCLK, ///< Get the system clock with @ref SYSCLK_100MHZ or SYSCLK_10MHZ + + CW_RESET_PHY, ///< Reset PHY + CW_SET_PHYCONF, ///< Set PHY operation mode (Manual/Auto, 10/100, Half/Full) with @ref wiz_PhyConf + CW_GET_PHYCONF, ///< Get PHY operation mode (Manual/Auto, 10/100, Half/Full) with @ref wiz_PhyConf + CW_GET_PHYSTATUS, ///< Get real operation mode with @ref wiz_PhyConf when PHY is linked up. + CW_SET_PHYPOWMODE, ///< Set PHY power mode with @ref PHY_POWER_NORM or PHY_POWER_DOWN + CW_GET_PHYPOWMODE, ///< Get PHY Power mode with @ref PHY_POWER_NORM or PHY_POWER_DOWN + CW_GET_PHYLINK ///< Get PHY Link status with @ref PHY_LINK_ON or @ref PHY_LINK_OFF +} ctlwizchip_type; + +/** + @ingroup DATA_TYPE + Network control type enumration used in @ref ctlnetwork(). +*/ +typedef enum { + CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo + CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo + CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode + CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode + CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. + CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. + //teddy 240122 +#if ((_WIZCHIP_ == W6100)||(_WIZCHIP_ == W6300)) + CN_SET_PREFER, ///< Set the preferred source IPv6 address of @ref _SLCR_.\n Refer to @ref IPV6_ADDR_AUTO, @ref IPV6_ADDR_LLA, @ref IPV6_ADDR_GUA + CN_GET_PREFER, ///< Get the preferred source IPv6 address of @ref _SLCR_.\n Refer to @ref IPV6_ADDR_AUTO, @ref IPV6_ADDR_LLA, @ref IPV6_ADDR_GUA +#endif +} ctlnetwork_type; + +//teddy 240122 +#if ((_WIZCHIP_ == W6100)||(_WIZCHIP_ == W6300)) +/** + @ingroup DATA_TYPE + @brief Network Service Control Type enumeration + @details @ref ctlnetservice_type includes network management or monitor functions for @ref _WIZCHIP_. + @sa ctlnetservice(), wiz_IPAddress, wiz_Prefix +*/ +typedef enum { + CNS_ARP, ///< ARP process with @ref wiz_IPAddress + CNS_PING, ///< PING process with @ref wiz_IPAddress + CNS_DAD, ///< Duplicated IPv6 Address Detection + /** + @brief Stateless Address Auto-configuration(SLAAC) with @ref wiz_Prefix. + @details @ref CNS_SLAAC sends first RS message to all-router and then receives RA message from a router. + @note It is valid only when the first received RA option is the source link-layer address(0x01) and the second is prefix information(0x03).\n + Refer to @ref SLIR_RS. + @sa ctlnetservice() + @sa CNS_GET_PREFIX + */ + CNS_SLAAC, + CNS_UNSOL_NA, ///< Unsolicited Neighbor Advertisement for update @ref _WIZCHIP_ network information to neighbors + /** + @brief Get prefix information with @ref wiz_Prefix. + @details @ref CNS_GET_PREFIX can get prefix information of RA message to be sent by a router without RS message. + @note It is valid only when @ref IK_SOCKL_RA is set and the prefix information(0x03) of RA option is first received. + @sa ctlnetservice() + @sa CNS_SLAAC + */ + CNS_GET_PREFIX +} ctlnetservice_type; +#endif + +#if (_WIZCHIP_ == W5100 || _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5300 || _WIZCHIP_ == W5500) +/** + @ingroup DATA_TYPE + Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK + and CW_GET_INTRMASK is used in @ref ctlnetwork(). + It can be used with OR operation. +*/ +typedef enum { +#if _WIZCHIP_ == W5500 + IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. +#elif _WIZCHIP_ == W5300 + IK_FMTU = (1 << 4), ///< Received a ICMP message (Fragment MTU) +#endif + + IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected + +#if _WIZCHIP_ != W5200 + IK_DEST_UNREACH = (1 << 6), ///< Destination IP & Port Unreachable, No use in W5200 +#endif + + IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred + + IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt +#if _WIZCHIP_ > W5100S + IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 + IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 + IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 + IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 +#endif + +#if _WIZCHIP_ > W5100S + IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrupt +#else + IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrupt +#endif +} intr_kind; +//teddy 240122 +#elif ((_WIZCHIP_ == W6100)||(_WIZCHIP_ == W6300)) +/** + @ingroup DATA_TYPE + @brief Interrupt Kind + @details @ref intr_kind can be used as the interrupt bits of @ref _IR_, @ref _SIR_, and @ref _SLIR_,\n + It can be used as the interrupt mask bits of @ref _IMR_, @ref _SIMR_, and @ref _SLIMR_,\n + and also, It can be used as the interrupt clear bits of @ref _IRCLR_, @ref _Sn_IRCLR_, and @ref _SLIRCLR_. + @note It can be used with @b OR operation. + @sa ctlwizchip(), CW_GET_INTERRUPT, CW_CLR_INTERRUPT, CW_GET_INTRMASK, CW_SET_INTRMASK + @sa ctlnetservice(), ctlnetservice_type + @sa wizchip_getinterrupt(), wizchip_clrinterrupt(), wizchip_getinterruptmask(), wizchip_setinterruptmask() +*/ +typedef enum { + IK_PPPOE_TERMINATED = (1 << 0), ///< PPPoE Termination Interrupt + IK_DEST_UNREACH = (1 << 1), ///< ICMPv4 Destination Unreachable Interrupt + IK_IP_CONFLICT = (1 << 2), ///< IPv4 Address Conflict Interrupt + IK_DEST_UNREACH6 = (1 << 4), ///< ICMPv6 Destination Unreachable Interrupt + IK_WOL = (1 << 7), ///< WOL magic packet Interrupt + IK_NET_ALL = (0x97), ///< All Network Interrupt + + IK_SOCK_0 = (1 << 8), ///< Socket 0 Interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 Interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 Interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 Interrupt + IK_SOCK_4 = (1 << 12), ///< Socket 4 Interrupt + IK_SOCK_5 = (1 << 13), ///< Socket 5 Interrupt + IK_SOCK_6 = (1 << 14), ///< Socket 6 Interrupt + IK_SOCK_7 = (1 << 15), ///< Socket 7 Interrupt + IK_SOCK_ALL = (0xFF << 8), ///< All Socket Interrupt + + IK_SOCKL_TOUT = (1 << 16), ///< @ref _SLCR_ Timeout Interrupt.\n Refer to @ref ctlnetservice_type. + IK_SOCKL_ARP4 = (1 << 17), ///< @ref _SLCR_ APR4 Interrupt.\n Refer to @ref CNS_ARP. + IK_SOCKL_PING4 = (1 << 18), ///< @ref _SLCR_ PING4 Interrupt.\n Refer to @ref CNS_PING. + IK_SOCKL_ARP6 = (1 << 19), ///< @ref _SLCR_ ARP6 Interrupt.\n Refer to @ref CNS_ARP. + IK_SOCKL_PING6 = (1 << 20), ///< @ref _SLCR_ PING6 Interrupt.\n Refer to @ref CNS_PING. + IK_SOCKL_NS = (1 << 21), ///< @ref _SLCR_ NS Interrupt.\n Refer to @ref CNS_DAD. + IK_SOCKL_RS = (1 << 22), ///< @ref _SLCR_ RS Interrupt.\n Refer to @ref CNS_SLAAC. + IK_SOCKL_RA = (1 << 23), ///< @ref _SLCR_ RA Interrupt.\n Refer to @ref CNS_GET_PREFIX. + IK_SOCKL_ALL = (0xFF << 16), ///< @ref _SLCR_ All Interrupt + + IK_INT_ALL = (0x00FFFF97) ///< All Interrupt +} intr_kind; +#endif + +//teddy 240122 +#if ((_WIZCHIP_ == W6100)||(_WIZCHIP_ == W6300)) +#define SYS_CHIP_LOCK (1<<2) ///< CHIP LOCK. \n Refer to @ref CW_SYS_LOCK, @ref CW_SYS_UNLOCK, and @ref CW_GET_SYSLOCK. +#define SYS_NET_LOCK (1<<1) ///< NETWORK Information LOCK. \n Refer to @ref CW_SYS_LOCK, @ref CW_SYS_UNLOCK, and @ref CW_GET_SYSLOCK. +#define SYS_PHY_LOCK (1<<0) ///< PHY LOCK.\n Refer to @ref CW_SYS_LOCK, @ref CW_SYS_UNLOCK, and @ref CW_GET_SYSLOCK. + +#define SYSCLK_100MHZ 0 ///< System Clock 100MHz.\n Refer to Refer to @ref CW_SET_SYSCLK and @ref CW_GET_SYSCLK. +#define SYSCLK_25MHZ 1 ///< System Clock 25MHz.\n Refer to Refer to @ref CW_SET_SYSCLK and @ref CW_GET_SYSCLK. + +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting.\n Refer to @ref CW_SET_PHYCONF and @ref CW_GET_PHYCONF. +#define PHY_MODE_AUTONEGO 1 ///< Configured PHY operation mode with auto-negotiation.\n Refer to @ref CW_SET_PHYCONF and @ref CW_GET_PHYCONF. +#define PHY_MODE_TE 2 + +#define IPV6_ADDR_AUTO 0x00 ///< IPv6 Address Type : Auto.\n Refer to @ref CN_SET_PREFER, @ref CN_GET_PREFER. +#define IPV6_ADDR_LLA 0x02 ///< IPv6 Address Type : LLA. \n Refer to @ref CN_SET_PREFER, @ref CN_GET_PREFER, @ref CNS_DAD. +#define IPV6_ADDR_GUA 0x03 ///< IPv6 Address Type : GUA. \n Refer to @ref CN_SET_PREFER, @ref CN_GET_PREFER, @ref CNS_DAD. +#endif + +#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin +#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. +#define PHY_MODE_AUTONEGO 1 ///< Configured PHY operation mode with auto-negotiation +#define PHY_SPEED_10 0 ///< Link Speed 10 +#define PHY_SPEED_100 1 ///< Link Speed 100 +#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex +#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex +#define PHY_LINK_OFF 0 ///< Link Off +#define PHY_LINK_ON 1 ///< Link On +#define PHY_POWER_NORM 0 ///< PHY power normal mode +#define PHY_POWER_DOWN 1 ///< PHY power down mode + + +//teddy 240122 +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 || _WIZCHIP_ == W6100 || _WIZCHIP_ == W6300 +/** + @ingroup DATA_TYPE + It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500, + and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n + Valid only in W5500. +*/ +typedef struct wiz_PhyConf_t { + uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW + uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO + uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 + uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL + //uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + //uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF +} wiz_PhyConf; +#endif + +#if (_WIZCHIP_ == W5100 || _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5300 || _WIZCHIP_ == W5500) +/** + @ingroup DATA_TYPE + It used in setting dhcp_mode of @ref wiz_NetInfo. +*/ +typedef enum { + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +} dhcp_mode; + +/** + @ingroup DATA_TYPE + Network Information for WIZCHIP +*/ +typedef struct wiz_NetInfo_t { + uint8_t mac[6]; ///< Source Mac Address + uint8_t ip[4]; ///< Source IP Address + uint8_t sn[4]; ///< Subnet Mask + uint8_t gw[4]; ///< Gateway IP Address + uint8_t dns[4]; ///< DNS server IP Address + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +} wiz_NetInfo; + +/** + @ingroup DATA_TYPE + Network mode +*/ +typedef enum { +#if _WIZCHIP_ == W5500 + NM_FORCEARP = (1 << 1), ///< Force to APP send whenever udp data is sent. Valid only in W5500 +#endif + NM_WAKEONLAN = (1 << 5), ///< Wake On Lan + NM_PINGBLOCK = (1 << 4), ///< Block ping-request + NM_PPPOE = (1 << 3), ///< PPPoE mode +} netmode_type; + +/** + @ingroup DATA_TYPE + Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation. +*/ +typedef struct wiz_NetTimeout_t { + uint8_t retry_cnt; ///< retry count + uint16_t time_100us; ///< time unit 100us +} wiz_NetTimeout; +//teddy 240122 +#elif ((_WIZCHIP_ == W6100)||(_WIZCHIP_ == W6300)) +/** + @ingroup DATA_TYPE + @brief IP Address Configuration Mode + @details @ref ipconf_mode can be used to save the DHCP mode running on your system. + @sa ctlnetwork(), CN_SET_NETINFO, CN_GET_NETINFO + @sa wizchip_setnetinfo(), wizchip_getnetinfo(), wiz_NetInfo +*/ +typedef enum { + NETINFO_NONE = 0x00, ///< No use DHCP + NETINFO_STATIC_V4 = 0x01, ///< Static IPv4 configuration by manually. + NETINFO_STATIC_V6 = 0x02, ///< Static IPv6 configuration by manually. + NETINFO_STATIC_ALL = 0x03, ///< Static IPv4 and IPv6 configuration by manually. + NETINFO_SLAAC_V6 = 0x04, ///< Stateless Adders Auto Configuration for IPv6 + NETINFO_DHCP_V4 = 0x10, ///< Dynamic IPv4 configuration from a DHCP sever + NETINFO_DHCP_V6 = 0x20, ///< Dynamic IPv6 configuration from a DHCP sever + NETINFO_DHCP_ALL = 0x30 ///< Dynamic IPv4 and IPv6 configuration from a DHCP sever +} ipconf_mode; + +/** + @ingroup DATA_TYPE + @brief Network Information for @ref _WIZCHIP_ + @details @ref wiz_NetInfo is a structure type to configure or indicate the network information of @ref _WIZCHIP_. + @sa ctlnetwork(), CN_SET_NETINFO, CN_GET_NETINFO + @sa wizchip_setnetinfo(), wizchip_getnetinfo() +*/ + +typedef enum { + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +} dhcp_mode; + +typedef struct wiz_NetInfo_t { + uint8_t mac[6]; ///< Source Hardware Address + uint8_t ip[4]; ///< Source IPv4 Address + uint8_t sn[4]; ///< Subnet Mask value + uint8_t gw[4]; ///< Gateway IPv4 Address + uint8_t lla[16]; ///< Source Link Local Address + uint8_t gua[16]; ///< Source Global Unicast Address + uint8_t sn6[16]; ///< IPv6 Prefix + uint8_t gw6[16]; ///< Gateway IPv6 Address + uint8_t dns[4]; ///< DNS server IPv4 Address + uint8_t dns6[16]; ///< DNS server IPv6 Address + ipconf_mode ipmode; ///< IP Configuration Mode + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +} wiz_NetInfo; + +/** + @ingroup DATA_TYPE + @brief Network mode Configuration + @details @ref netmode_type includes the network mode control function such as ping, TCP/RST block and etc. + @sa ctlnetwork(), CN_SET_NETMODE, CN_GET_NETMODE +*/ +typedef enum { + // NETMR Bit Values + NM_IPB_V4 = (1 << 0), ///< IPv4 Packet Block + NM_IPB_V6 = (1 << 1), ///< IPv6 Packet Block + NM_WOL = (1 << 2), ///< Wake On Lan(WOL) Mode + NM_PB6_MULTI = (1 << 4), ///< PING6 request from multicasting group address Block + NM_PB6_ALLNODE = (1 << 5), ///< PING6 request from all-node multicasting address Block + NM_MR_MASK = (0x37), ///< @ref _NETMR_ Mask value + + // NETMR2 Bit Values + NM_PPPoE = (1 << 8), ///< PPPoE Mode + NM_DHA_SELECT = (1 << 15), ///< Destination Hardware Address Select + NM_MR2_MASK = (0x09 << 8), ///< @ref _NETMR2_ Mask value + + //NET4MR Bit Values + NM_PB4_ALL = (1 << 16), ///< All PING4 request Block + NM_TRSTB_V4 = (1 << 17), ///< TCP RST packet for IPv4 Send Block + NM_PARP_V4 = (1 << 18), ///< ARP request for IPv4 before PINGv4 Replay + NM_UNRB_V4 = (1 << 19), ///< Unreachable Destination for IPv4 Block + NM_NET4_MASK = (0x0F << 16), ///< @ref _NET4MR_ Mask value + + //NET4MR Bit Values + NM_PB6_ALL = (1 << 24), ///< All PING6 request Block + NM_TRSTB_V6 = (1 << 25), ///< TCP RST packet for IPv6 Send Block + NM_PARP_V6 = (1 << 26), ///< ARP request for IPv6 before PINGv4 Replay + NM_UNRB_V6 = (1 << 27), ///< Unreachable Destination for IPv6 Block + NM_NET6_MASK = (0x0F << 24), ///< @ref _NET6MR_ Mask value + + NM_MASK_ALL = (0x0F0F0937) ///< @ref netmode_type all mask value +} netmode_type; + +/** + @ingroup DATA_TYPE + @brief Network Timeout for @ref _WIZCHIP_ + @details @ref wiz_NetInfo is a structure type to configure or indicate the network timeout of @ref _WIZCHIP_. + @sa ctlnetwork(), CN_SET_TIMEOUT, CN_GET_TIMEOUT + @sa wizchip_settimeout(), wizchip_gettimeout() +*/ +typedef struct wiz_NetTimeout_t { + uint8_t s_retry_cnt; ///< The default retry count of SOCKETn + uint16_t s_time_100us; ///< The retransmission time of SOCKETn (unit 100us) + uint8_t sl_retry_cnt; ///< The retry count of SOCKET-less + uint16_t sl_time_100us; ///< The retransmission time of SOCKET-less (unit 100us) +} wiz_NetTimeout; + +/** + @ingroup DATA_TYPE + @brief Destination Information for Network Service of @ref _WIZCHIP_ + @details @ref wiz_NetInfo is a structure type to configure or indicate a destination information of network service. + @sa ctlnetservice(), CNS_ARP, CNS_PING + @sa IK_SOCKL_TOUT, IK_SOCKL_ARP4, IK_SOCKL_ARP6, IK_SOCKL_PING4, IK_SOCKL_PING6 +*/ +typedef struct wiz_IPAddress_t { + uint8_t ip[16]; ///< Destination IP Address. \n IPv4 index : 0 to 3, IPv6 index : 0 to 15 + uint8_t len; ///< Destination IP Address Length.\n IPv4 : 4, IPv6 : 16. +} wiz_IPAddress; + +/** + @ingroup DATA_TYPE + @brief Prefix Information + @details @ref wiz_Prefix is a structure type to indicate a prefix information(0x03) of received RA message from a router. + @sa ctlnetservice(), CNS_SLAAC, IK_SOCKL_RS + @sa IK_SOCKL_TOUT, IK_SOCKL_RA, CNS_GET_PREFIX +*/ +typedef struct wiz_Prefix_t { + uint8_t len; ///< Prefix Length. \n It is used to set @ref _SUB6R_ to 1 as many as len from LSB bit. + uint8_t flag; ///< Prefix Flag + uint32_t valid_lifetime; ///< Valid Lifetime + uint32_t preferred_lifetime; ///< Preferred Lifetime + uint8_t prefix[16]; ///< Prefix +} wiz_Prefix; + +/** + @ingroup DATA_TYPE + @brief Destination Information & Destination Hardware Address for @ref CNS_ARP + @details @ref wiz_ARP is a structure type to set a destination IP address for ARP-request or \n + indicate a destination hardware address in APR-reply. + @sa ctlnetservice(), CNS_ARP + @sa IK_SOCKL_TOUT, IK_SOCKL_ARP4, IK_SOCKL_ARP6 +*/ +typedef struct wiz_ARP_t { + wiz_IPAddress destinfo; ///< Destination IP address for ARP-request + uint8_t dha[6]; ///< Destination Hardware Address when ARP-reply is received from the destination. +} wiz_ARP; + +/** + @ingroup DATA_TYPE + @brief Destination Information & Destination Hardware Address for @ref CNS_ARP + @details @ref wiz_PING is a structure type to set a ID, sequence number, destination IP address for PING-request. + @sa ctlnetservice(), CNS_PING + @sa IK_SOCKL_TOUT, IK_SOCKL_PING4, IK_SOCKL_PING6 +*/ +typedef struct wiz_PING_t { + uint16_t id; + uint16_t seq; + wiz_IPAddress destinfo; +} wiz_PING; +#endif + +/** + @brief Registers call back function for critical section of I/O functions such as + \ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF. + @param cris_en : callback function for critical section enter. + @param cris_ex : callback function for critical section exit. + @todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions. + @note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called. +*/ +void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)); + + +/** + @brief Registers call back function for WIZCHIP select & deselect. + @param cs_sel : callback function for WIZCHIP select + @param cs_desel : callback fucntion for WIZCHIP deselect + @todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions. + @note If you do not describe or register, null function is called. +*/ +void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)); + +/** + @brief Registers call back function for bus interface. + @param bus_rb : callback function to read byte data using system bus + @param bus_wb : callback function to write byte data using system bus + @todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function + or register your functions. + @note If you do not describe or register, null function is called. +*/ +//M20150601 : For integrating with W5300 +//void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)); +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb)); + +/** + @brief Registers call back function for SPI interface. + @param spi_rb : callback function to read byte using SPI + @param spi_wb : callback function to write byte using SPI + @todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function + or register your functions. + @note If you do not describe or register, null function is called. +*/ +#if _WIZCHIP_ == W6100 +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb), + void (*spi_rbuf)(uint8_t* buf, datasize_t len), + void (*spi_wbuf)(uint8_t* buf, datasize_t len)); +#else +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)); +#endif + +/** + @brief Registers call back function for SPI interface. + @param spi_rb : callback function to burst read using SPI + @param spi_wb : callback function to burst write using SPI + @todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function + or register your functions. + @note If you do not describe or register, null function is called. +*/ +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t* pBuf, uint16_t len), void (*spi_wb)(uint8_t* pBuf, uint16_t len)); + +//teddy 240122 +/** + @brief Registers call back function for QSPI interface. + @param spi_rb : callback function to read using QSPI + @param spi_wb : callback function to write using QSPI + @todo Describe \ref wizchip_qspi_read and \ref wizchip_qspi_write function + or register your functions. + @note If you do not describe or register, null function is called. +*/ +void reg_wizchip_qspi_cbfunc(void (*qspi_rb)(uint8_t opcode, uint16_t addr, uint8_t* pBuf, uint16_t len), void (*qspi_wb)(uint8_t opcode, uint16_t addr, uint8_t* pBuf, uint16_t len)); + +/** + @ingroup extra_functions + @brief Controls to the WIZCHIP. + @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto), + controls interrupt & mask and so on. + @param cwtype : Decides to the control type + @param arg : arg type is dependent on cwtype. + @return 0 : Success \n + -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP +*/ +int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg); + +/** + @ingroup extra_functions + @brief Controls to network. + @details Controls to network environment, mode, timeout and so on. + @param cntype : Input. Decides to the control type + @param arg : Inout. arg type is dependent on cntype. + @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n + 0 : Success +*/ +int8_t ctlnetwork(ctlnetwork_type cntype, void* arg); + +//teddy 240122 +#if ((_WIZCHIP_ == W6100)||(_WIZCHIP_ == W6300)) +/** + @ingroup extra_functions + @brief Controls to network service. + @details Controls to network environment, mode, timeout and so on. + @param cnstype : Decides to the control type + @param arg : arg type is dependent on cnstype. + @return -1 : Fail because of invalid @ref ctlnetwork_type or unsupported @ref ctlnetwork_type \n + 0 : Success +*/ +int8_t ctlnetservice(ctlnetservice_type cnstype, void* arg); +#endif + +/* + The following functions are implemented for internal use. + but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork(). +*/ + +/** + @ingroup extra_functions + @brief Reset WIZCHIP by softly. +*/ +void wizchip_sw_reset(void); + +/** + @ingroup extra_functions + @brief Initializes WIZCHIP with socket buffer size + @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB. + @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB. + @return 0 : succcess \n + -1 : fail. Invalid buffer size +*/ +int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize); + +/** + @ingroup extra_functions + @brief Clear Interrupt of WIZCHIP. + @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. +*/ +void wizchip_clrinterrupt(intr_kind intr); + +/** + @ingroup extra_functions + @brief Get Interrupt of WIZCHIP. + @return @ref intr_kind value operated OR. It can type-cast to uint16_t. +*/ +intr_kind wizchip_getinterrupt(void); + +/** + @ingroup extra_functions + @brief Mask or Unmask Interrupt of WIZCHIP. + @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. +*/ +void wizchip_setinterruptmask(intr_kind intr); + +/** + @ingroup extra_functions + @brief Get Interrupt mask of WIZCHIP. + @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t. +*/ +intr_kind wizchip_getinterruptmask(void); + +//todo +#if _WIZCHIP_ > W5100 +int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100 +int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 +#endif + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 +/** + @ingroup extra_functions + @brief Set the phy information for WIZCHIP without power mode + @param phyconf : @ref wiz_PhyConf +*/ +void wizphy_setphyconf(wiz_PhyConf* phyconf); +/** + @ingroup extra_functions + @brief Get phy configuration information. + @param phyconf : @ref wiz_PhyConf +*/ +void wizphy_getphyconf(wiz_PhyConf* phyconf); +/** + @ingroup extra_functions + @brief Get phy status. + @param phyconf : @ref wiz_PhyConf +*/ +void wizphy_getphystat(wiz_PhyConf* phyconf); +/** + @ingroup extra_functions + @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200 + @param pmode Settig value of power down mode. +*/ +int8_t wizphy_setphypmode(uint8_t pmode); +//teddy 240122 +#elif ((_WIZCHIP_ == W6100)||(_WIZCHIP_ == W6300)) +/** + @ingroup extra_functions + @brief Reset the integrated PHY. + @details @ref wizphy_reset() resets the integrated Ethernet PHY \n + through @ref _PHY_IO_MODE_PHYCR_ or @ref _PHY_IO_MODE_MII_. \n + @note In @ref _PHY_IO_MODE_PHYCR_, It needs a stable reset time. \n + So you need to wait for the stable reset time.\n + The stable reset time for each @ref _WIZCHIP_ maybe different. + @sa ctlwizchip(), CW_RESET_PHY + @sa _PHY_IO_MODE_ +*/ +void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 + +/** + @ingroup extra_functions + @details @ref wizphy_setphyconf() set a operation mode of the integrated Ethernet PHY \n + through @ref _PHY_IO_MODE_PHYCR_ or @ref _PHY_IO_MODE_MII_.\n + @param phyconf : @ref wiz_PhyConf + @note The operation mode can be applied to Ethernet PHY after the Ethernet PHY is reset by @ref wizphy_reset(). + @sa ctlwizchip(), CW_SET_PHYCONF, CW_GET_PHYCONF, CW_GET_PHYSTATUS, CW_RESET_PHY + @sa _PHY_IO_MODE_, wizphy_getphyconf(), wizphy_getphystatus(), wizphy_reset() +*/ +void wizphy_setphyconf(wiz_PhyConf* phyconf); + +/** + @ingroup extra_functions + @brief Get the integrated Ethernet PHY operation mode. + @details @ref wizphy_getphyconf() gets a operation mode of the integrated Ethernet PHY \n + through @ref _PHY_IO_MODE_PHYCR_ or @ref _PHY_IO_MODE_MII_.\n + @param phyconf : @ref wiz_PhyConf + @note It gets just the configured value for PHY operation, not real PHY operation.\n + To get real PHY operation, you can call @ref wizphy_getphystatus() + @sa ctlwizchip(), CW_GET_PHYCONF, CW_SET_PHYCONF, CW_GET_PHYSTATUS + @sa _PHY_IO_MODE_, wizphy_setphyconf(), wizphy_getphystatus() +*/ +void wizphy_getphyconf(wiz_PhyConf* phyconf); + +/** + @ingroup extra_functions + @brief Get the real PHY operation status when link is established. + @details @ref wizphy_getphystatus() gets a operation mode of the integrated Ethernet PHY. \n + @param phyconf : @ref wiz_PhyConf + @sa ctlwizchip(), CW_GET_PHYSTATUS, CW_GET_PHYCONF, CW_SET_PHYCONF + @sa wizphy_setphyconf(), wizphy_getphyconf() +*/ +void wizphy_getphystat(wiz_PhyConf* phyconf); + +/** + @ingroup extra_functions + @brief Set the power mode of integrated Ethernet PHY. + @details @ref wizphy_setphypmode() sets a power mode of the integrated Ethernet PHY \n + through @ref _PHY_IO_MODE_PHYCR_ or @ref _PHY_IO_MODE_MII_.\n + @param pmode @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + @note When the integrated Ethernet PHY enters in power down mode, \n + the system clock of @ref _WIZCHIP_ is changed to the lowest speed. \n + So, you should adjust the access time of @ref _WIZCHIP_ to the changed system clock. + @sa ctlwizchip(), CW_SET_PHYPOWMODE, CW_GET_PHYPOWMODE + @sa _PHY_IO_MODE_, wizphy_setphypmode(), wizphy_getphypmode() +*/ +void wizphy_setphypmode(uint8_t pmode); + +/** + @ingroup extra_functions + @brief get the power mode of integrated Ethernet PHY. + @details @ref wizphy_getphypmode() gets a power mode of the integrated Ethernet PHY \n + through @ref _PHY_IO_MODE_PHYCR_ or @ref _PHY_IO_MODE_MII_.\n + @return @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + @note When the integrated Ethernet PHY enters in power down mode,\n + the system clock of @ref _WIZCHIP_ is changed to the lowest speed. \n + So, you should adjust the access time of @ref _WIZCHIP_ to the changed system clock. + @sa ctlwizchip(), CW_SET_PHYPOWMODE, CW_GET_PHYPOWMODE + @sa _PHY_IO_MODE_, wizphy_setphypmode(), wizphy_getphypmode() +*/ +int8_t wizphy_getphypmode(void); + +/** + @ingroup extra_functions + @brief Set the network information for @ref _WIZCHIP_ + @param pnetinfo : @ref wiz_NetInfo + @sa ctlnetwork(), CN_SET_NETINFO, CN_GET_NETINFO + @sa wizchip_getnetinfo() +*/ +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo); + +/** + @ingroup extra_functions + @brief Get the network information of @ref _WIZCHIP_ + @param pnetinfo : @ref wiz_NetInfo + @sa ctlnetwork(), CN_GET_NETINFO, CN_SET_NETINFO + @sa wizchip_setnetinfo() +*/ +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo); + +/** + @ingroup extra_functions + @brief Set the network mode such as WOL, PPPoE, PING Block, and etc. + @param netmode : @ref netmode_type. + @sa ctlnetwork(), CN_SET_NETMODE, CN_GET_NETMODE + @sa wizchip_getnetmode() +*/ +void wizchip_setnetmode(netmode_type netmode); + +/** + @ingroup extra_functions + @brief Get the network mode such as WOL, PPPoE, PING Block, and etc. + @return @ref netmode_type. + @sa ctlnetwork(), CN_GET_NETMODE, CN_SET_NETMODE + @sa wizchip_setnetmode() +*/ +netmode_type wizchip_getnetmode(void); + +/** + @ingroup extra_functions + @brief Set retransmission time values and retry counts. + @param nettime : @ref wiz_NetTimeout. + @sa ctlnetwork(), CN_SET_TIMEOUT, CN_GET_TIMEOUT + @sa wizchip_gettimeout() +*/ +void wizchip_settimeout(wiz_NetTimeout* nettime); + +/** + @ingroup extra_functions + @brief Get retransmission time values and retry counts. + @param nettime : @ref wiz_NetTimeout. + @sa ctlnetwork(), CN_GET_TIMEOUT, CN_SET_TIMEOUT + @sa wizchip_settimeout() +*/ +void wizchip_gettimeout(wiz_NetTimeout* nettime); + +/** + @ingroup extra_functions + @brief ARP process. + @details @ref wizchip_arp() processes ARP. \n + It sends the APR-request to destination and waits to receive the ARP-reply. + @param arp @ref wiz_ARP.\n + It sets a destination IP address and indicates the destination hardware address. + @return 0 : success, destination hardware address is valid.\n + -1 : fail. destination hardware address is invalid because timeout is occurred.\n + @sa ctlnetservice(), CNS_ARP +*/ +int8_t wizchip_arp(wiz_ARP* arp); + +/** + @ingroup extra_functions + @brief PING process. + @details @ref wizchip_ping() processes PING. \n + It sends the PING-request to destination and waits to receive the PING-reply. + @param ping @ref wiz_PING, It sets a destination IP address, ID, SEQ of PING-request message + @return 0 : success, PING-reply is successfully received.\n + -1 : fail. Timeout is occurred.\n + @sa ctlnetservice(), CNS_PING +*/ +int8_t wizchip_ping(wiz_PING* ping); + +/** + @ingroup extra_functions + @brief DAD(Duplcated Address Detection) process. + @details @ref wizchip_dad() detects the duplication of source IPv6 address.\n + It sends a NA message for DAD to all-node multicasting address(FF02::01). + @param ipv6 : IPv6 address to be detected the duplication. + @return 0 : success, There is no duplicated address. \n + -1 : fail. @ref _WIZCHIP_ source IP address to use is duplicated with a neighbor's one. + @sa ctlnetservice(), CNS_DAD +*/ +int8_t wizchip_dad(uint8_t* ipv6); + +/** + @ingroup extra_functions + @brief Stateless Address Auto Configuration(SLAAC) process. + @details @ref wizchip_slaac() get a prefix information from a router for SLAAC.\n + It sends first a RS message to all-router and waits to receive a RS message with prefix information option from a router. + @param prefix @ref wiz_Prefix + @return 0 : success, RA message is successfully received, and prefix is valid. \n + -1 : fail. Timeout is occurred. + @note It is valid only when the prefix information type(0x03) of RA option received first.\n + The prefix option should be in the order of prefix length, prefix flag, valid lifetime, default lifetime and prefix address. \n + For more detail, Refer to @ref SLIR_RS. + @sa ctlnetservice(), CNS_SLAAC +*/ +int8_t wizchip_slaac(wiz_Prefix* prefix); + +/** + @ingroup extra_functions + @brief Unsolicited NA process. + @details @ref wizchip_unsolicited() updates the network information of @ref _WIZCHIP_ to neighbors.\n + It sends a unsolicited NA message with @ref _LLAR_ or @ref _GUAR_ to neighbors \n + in order to update the network information of @ref _WIZCHIP_.\n + Because the unsolicited NA message have no reply, timeout is always occurred. + @return always 0. Timeout is occurred. + @sa ctlnetservice(), CNS_UNSOL +*/ +int8_t wizchip_unsolicited(void); + +/** + @ingroup extra_functions + @brief Get a prefix information of RA message from a router. + @details @ref wizchip_getprefix() get a prefix information of RA is periodically sent by a router. \n + @return 0 : success, a RS message is successfully received from a router. + -1 : fail, a RS message is not received from a router yet. + @note It is valid only when the prefix information type(0x03) of RA option received first.\n + The prefix option should be in the order of prefix length, prefix flag, valid lifetime, default lifetime and prefix address. \n + For more detail, Refer to @ref SLIR_RS. + @sa ctlnetservice(), CNS_GET_PREFIX +*/ +int8_t wizchip_getprefix(wiz_Prefix * prefix); +#endif + +#if (_WIZCHIP_ == W5100 || _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5300 || _WIZCHIP_ == W5500) +/** + @ingroup extra_functions + @brief Set the network information for WIZCHIP + @param pnetinfo : @ref wizNetInfo +*/ +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo); + +/** + @ingroup extra_functions + @brief Get the network information for WIZCHIP + @param pnetinfo : @ref wizNetInfo +*/ +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo); + +/** + @ingroup extra_functions + @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. + @param pnetinfo Value of network mode. Refer to @ref netmode_type. +*/ +int8_t wizchip_setnetmode(netmode_type netmode); + +/** + @ingroup extra_functions + @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. + @return Value of network mode. Refer to @ref netmode_type. +*/ +netmode_type wizchip_getnetmode(void); + +/** + @ingroup extra_functions + @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_). + @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission. + @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout. +*/ +void wizchip_settimeout(wiz_NetTimeout* nettime); + +/** + @ingroup extra_functions + @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_). + @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission. + @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout. +*/ +void wizchip_gettimeout(wiz_NetTimeout* nettime); +//teddy 240122 +#elif ((_WIZCHIP_ == W6100)||(_WIZCHIP_ == W6300)) +/** + @ingroup extra_functions + @brief Set the network information for @ref _WIZCHIP_ + @param pnetinfo : @ref wiz_NetInfo + @sa ctlnetwork(), CN_SET_NETINFO, CN_GET_NETINFO + @sa wizchip_getnetinfo() +*/ +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo); + +/** + @ingroup extra_functions + @brief Get the network information of @ref _WIZCHIP_ + @param pnetinfo : @ref wiz_NetInfo + @sa ctlnetwork(), CN_GET_NETINFO, CN_SET_NETINFO + @sa wizchip_setnetinfo() +*/ +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo); + +/** + @ingroup extra_functions + @brief Set the network mode such as WOL, PPPoE, PING Block, and etc. + @param netmode : @ref netmode_type. + @sa ctlnetwork(), CN_SET_NETMODE, CN_GET_NETMODE + @sa wizchip_getnetmode() +*/ +void wizchip_setnetmode(netmode_type netmode); + +/** + @ingroup extra_functions + @brief Get the network mode such as WOL, PPPoE, PING Block, and etc. + @return @ref netmode_type. + @sa ctlnetwork(), CN_GET_NETMODE, CN_SET_NETMODE + @sa wizchip_setnetmode() +*/ +netmode_type wizchip_getnetmode(void); + +/** + @ingroup extra_functions + @brief Set retransmission time values and retry counts. + @param nettime : @ref wiz_NetTimeout. + @sa ctlnetwork(), CN_SET_TIMEOUT, CN_GET_TIMEOUT + @sa wizchip_gettimeout() +*/ +void wizchip_settimeout(wiz_NetTimeout* nettime); + +/** + @ingroup extra_functions + @brief Get retransmission time values and retry counts. + @param nettime : @ref wiz_NetTimeout. + @sa ctlnetwork(), CN_GET_TIMEOUT, CN_SET_TIMEOUT + @sa wizchip_settimeout() +*/ +void wizchip_gettimeout(wiz_NetTimeout* nettime); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif // _WIZCHIP_CONF_H_ diff --git a/lib/w6300/port_common.h b/lib/w6300/port_common.h new file mode 100644 index 0000000..f0bb32f --- /dev/null +++ b/lib/w6300/port_common.h @@ -0,0 +1,23 @@ +/** + Copyright (c) 2021 WIZnet Co.,Ltd + + SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef _PORT_COMMON_H_ +#define _PORT_COMMON_H_ + +/** + ---------------------------------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------------------------------- +*/ +/* Common */ +#include "pico/stdlib.h" +#include "pico/binary_info.h" +#include "pico/critical_section.h" +#include "hardware/spi.h" +#include "hardware/dma.h" +#include "hardware/clocks.h" + +#endif /* _PORT_COMMON_H_ */ diff --git a/lib/w6300/wizchip_qspi_pio.c b/lib/w6300/wizchip_qspi_pio.c new file mode 100644 index 0000000..e74220e --- /dev/null +++ b/lib/w6300/wizchip_qspi_pio.c @@ -0,0 +1,753 @@ +/* + 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 "wizchip_conf.h" +#include "wizchip_qspi_pio.h" + +#include "wizchip_qspi_pio.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 + +#if (_WIZCHIP_QSPI_MODE_ == QSPI_SINGLE_MODE) +#define PIO_PROGRAM_NAME wizchip_pio_spi_single_write_read +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_DUAL_MODE) +#define PIO_PROGRAM_NAME wizchip_pio_spi_dual_write_read +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_QUAD_MODE) +#define PIO_PROGRAM_NAME wizchip_pio_spi_quad_write_read +#endif + +#if (_WIZCHIP_ == W6300) +#define PIO_PROGRAM_FUNC __CONCAT(PIO_PROGRAM_NAME, _program) +#define PIO_PROGRAM_GET_DEFAULT_CONFIG_FUNC __CONCAT(PIO_PROGRAM_NAME, _program_get_default_config) +#define PIO_OFFSET_WRITE_BITS __CONCAT(PIO_PROGRAM_NAME, _offset_write_bits) +#define PIO_OFFSET_WRITE_BITS_END __CONCAT(PIO_PROGRAM_NAME, _offset_write_bits_end) +#define PIO_OFFSET_READ_BITS_END __CONCAT(PIO_PROGRAM_NAME, _offset_read_bits_end) + +#else +#define PIO_PROGRAM_NAME wiznet_spi_write_read +#define PIO_PROGRAM_FUNC __CONCAT(PIO_PROGRAM_NAME, _program) +#define PIO_PROGRAM_GET_DEFAULT_CONFIG_FUNC __CONCAT(PIO_PROGRAM_NAME, _program_get_default_config) +#define PIO_OFFSET_WRITE_BITS __CONCAT(PIO_PROGRAM_NAME, _offset_write_bits) +#define PIO_OFFSET_WRITE_BITS_END __CONCAT(PIO_PROGRAM_NAME, _offset_write_end) +#define PIO_OFFSET_READ_BITS_END __CONCAT(PIO_PROGRAM_NAME, _offset_read_end) +// All wiznet spi operations must start with writing a 3 byte header + +#endif + +#ifndef PICO_WIZNET_SPI_PIO_INSTANCE_COUNT +#define PICO_WIZNET_SPI_PIO_INSTANCE_COUNT 1 +#endif + +#define SPI_HEADER_LEN 3 + +typedef struct spi_pio_state { + wiznet_spi_funcs_t *funcs; + const wiznet_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[SPI_HEADER_LEN]; + uint8_t spi_header_count; +} spi_pio_state_t; + + + +static spi_pio_state_t spi_pio_state[PICO_WIZNET_SPI_PIO_INSTANCE_COUNT]; +static spi_pio_state_t *active_state; + +static void wiznet_spi_pio_close(wiznet_spi_handle_t funcs); +static wiznet_spi_funcs_t *get_wiznet_spi_pio_impl(void); + + +static uint16_t mk_cmd_buf(uint8_t *pdst, uint8_t opcode, uint16_t addr) { +#if (_WIZCHIP_QSPI_MODE_ == QSPI_SINGLE_MODE) + + pdst[0] = opcode; + pdst[1] = (uint8_t)((addr >> 8) & 0xFF); + pdst[2] = (uint8_t)((addr >> 0) & 0xFF); + pdst[3] = 0; + + return 3 + 1; +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_DUAL_MODE) + pdst[0] = ((opcode >> 7 & 0x01) << 6) | ((opcode >> 6 & 0x01) << 4) | ((opcode >> 5 & 0x01) << 2) | ((opcode >> 4 & 0x01) << 0); + pdst[1] = ((opcode >> 3 & 0x01) << 6) | ((opcode >> 2 & 0x01) << 4) | ((opcode >> 1 & 0x01) << 2) | ((opcode >> 0 & 0x01) << 0); + pdst[2] = (uint8_t)((addr >> 8) & 0xFF); + pdst[3] = (uint8_t)((addr >> 0) & 0xFF); + + pdst[4] = 0; + + return 4 + 1; +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_QUAD_MODE) + pdst[0] = ((opcode >> 7 & 0x01) << 4) | ((opcode >> 6 & 0x01) << 0); + pdst[1] = ((opcode >> 5 & 0x01) << 4) | ((opcode >> 4 & 0x01) << 0); + pdst[2] = ((opcode >> 3 & 0x01) << 4) | ((opcode >> 2 & 0x01) << 0); + pdst[3] = ((opcode >> 1 & 0x01) << 4) | ((opcode >> 0 & 0x01) << 0); + + pdst[4] = ((uint8_t)(addr >> 8) & 0xFF); + pdst[5] = ((uint8_t)(addr >> 0) & 0xFF); + + pdst[6] = 0; + + return 6 + 1; +#endif + return 0; +} + +// Initialise our gpios +static void pio_spi_gpio_setup(spi_pio_state_t *state) { + +#if (_WIZCHIP_ == W6300) +#if (_WIZCHIP_QSPI_MODE_ == QSPI_SINGLE_MODE) + // Setup DO and DI + gpio_init(state->spi_config->data_io0_pin); + gpio_init(state->spi_config->data_io1_pin); + gpio_set_dir(state->spi_config->data_io0_pin, GPIO_OUT); + gpio_set_dir(state->spi_config->data_io1_pin, GPIO_OUT); + gpio_put(state->spi_config->data_io0_pin, false); + gpio_put(state->spi_config->data_io1_pin, false); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_DUAL_MODE) + // Setup DO and DI + gpio_init(state->spi_config->data_io0_pin); + gpio_init(state->spi_config->data_io1_pin); + gpio_set_dir(state->spi_config->data_io0_pin, GPIO_OUT); + gpio_set_dir(state->spi_config->data_io1_pin, GPIO_OUT); + gpio_put(state->spi_config->data_io0_pin, false); + gpio_put(state->spi_config->data_io1_pin, false); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_QUAD_MODE) + // Setup DO and DI + gpio_init(state->spi_config->data_io0_pin); + gpio_init(state->spi_config->data_io1_pin); + gpio_init(state->spi_config->data_io2_pin); + gpio_init(state->spi_config->data_io3_pin); + gpio_set_dir(state->spi_config->data_io0_pin, GPIO_OUT); + gpio_set_dir(state->spi_config->data_io1_pin, GPIO_OUT); + gpio_set_dir(state->spi_config->data_io2_pin, GPIO_OUT); + gpio_set_dir(state->spi_config->data_io3_pin, GPIO_OUT); + gpio_put(state->spi_config->data_io0_pin, false); + gpio_put(state->spi_config->data_io1_pin, false); + gpio_put(state->spi_config->data_io2_pin, false); + gpio_put(state->spi_config->data_io3_pin, false); +#endif + + // 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 reset + 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); +#else //W55RP20 + // 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); +#endif + +} + +wiznet_spi_handle_t wiznet_spi_pio_open(const wiznet_spi_config_t *spi_config) { + + spi_pio_state_t *state; + for (int i = 0; i < count_of(spi_pio_state); i++) { + if (!spi_pio_state[i].funcs) { + state = &spi_pio_state[i]; + break; + } + } + assert(state); + if (!state) { + return NULL; + } + state->spi_config = spi_config; + state->funcs = get_wiznet_spi_pio_impl(); + + 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], &PIO_PROGRAM_FUNC)) { + pio_index ^= 1; + if (!pio_can_add_program(pios[pio_index], &PIO_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_spi_pio_close(&state->funcs); + return NULL; + } + + state->pio_offset = pio_add_program(state->pio, &PIO_PROGRAM_FUNC); + + uint64_t f_sys = clock_get_hz(clk_sys); // Hz +#if (_WIZCHIP_ == W6300) + const char *wizchip_pio_clock_str = "PIO QSPI CLOCK SPEED"; +#else + const char *wizchip_pio_clock_str = "PIO SPI CLOCK SPEED"; +#endif + + printf("[%s : %.2f MHz] (sys=%.2f MHz)\r\n\r\n", + wizchip_pio_clock_str, + (double)f_sys / (2.0 * (state->spi_config->clock_div_major + + state->spi_config->clock_div_minor / 256.0)) / 1e6, + f_sys / 1e6); + + pio_sm_config sm_config = PIO_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 + ); + +#if (_WIZCHIP_ == W6300) +#if (_WIZCHIP_QSPI_MODE_ == QSPI_SINGLE_MODE) + printf("\r\n[QSPI SINGLE MODE]\r\n"); + sm_config_set_out_pins(&sm_config, state->spi_config->data_io0_pin, 1); + sm_config_set_in_pins(&sm_config, state->spi_config->data_io1_pin); + sm_config_set_set_pins(&sm_config, state->spi_config->data_io0_pin, 2); + 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_io0_pin) | (1u << state->spi_config->data_io1_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_io0_pin, state->pio_func_sel); + + // Set data pin to pull down and schmitt + gpio_set_pulls(state->spi_config->data_io0_pin, false, true); + gpio_set_pulls(state->spi_config->data_io1_pin, false, true); + gpio_set_input_hysteresis_enabled(state->spi_config->data_io0_pin, true); + gpio_set_input_hysteresis_enabled(state->spi_config->data_io1_pin, true); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_DUAL_MODE) + printf("[QSPI DUAL MODE]\r\n\r\n"); + sm_config_set_out_pins(&sm_config, state->spi_config->data_io0_pin, 2); + sm_config_set_in_pins(&sm_config, state->spi_config->data_io0_pin); + sm_config_set_set_pins(&sm_config, state->spi_config->data_io0_pin, 2); + 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_io0_pin) | (1u << state->spi_config->data_io1_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_io0_pin, state->pio_func_sel); + gpio_set_function(state->spi_config->data_io1_pin, state->pio_func_sel); + + // Set data pin to pull down and schmitt + gpio_set_pulls(state->spi_config->data_io0_pin, false, true); + gpio_set_pulls(state->spi_config->data_io1_pin, false, true); + gpio_set_input_hysteresis_enabled(state->spi_config->data_io0_pin, true); + gpio_set_input_hysteresis_enabled(state->spi_config->data_io1_pin, true); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_QUAD_MODE) + printf("\r\n[QSPI QUAD MODE]\r\n"); + sm_config_set_out_pins(&sm_config, state->spi_config->data_io0_pin, 4); + sm_config_set_in_pins(&sm_config, state->spi_config->data_io0_pin); + sm_config_set_set_pins(&sm_config, state->spi_config->data_io0_pin, 4); + 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_io0_pin) | (1u << state->spi_config->data_io1_pin) | (1u << state->spi_config->data_io2_pin) | (1u << state->spi_config->data_io3_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_io0_pin, state->pio_func_sel); + gpio_set_function(state->spi_config->data_io1_pin, state->pio_func_sel); + gpio_set_function(state->spi_config->data_io2_pin, state->pio_func_sel); + gpio_set_function(state->spi_config->data_io3_pin, state->pio_func_sel); + + // Set data pin to pull down and schmitt + gpio_set_pulls(state->spi_config->data_io0_pin, false, true); + gpio_set_pulls(state->spi_config->data_io1_pin, false, true); + gpio_set_pulls(state->spi_config->data_io2_pin, false, true); + gpio_set_pulls(state->spi_config->data_io3_pin, false, true); + gpio_set_input_hysteresis_enabled(state->spi_config->data_io0_pin, true); + gpio_set_input_hysteresis_enabled(state->spi_config->data_io1_pin, true); + gpio_set_input_hysteresis_enabled(state->spi_config->data_io2_pin, true); + gpio_set_input_hysteresis_enabled(state->spi_config->data_io3_pin, true); + /* @todo: Implement to use. */ +#endif +#else //W55RP20 + 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); +#endif + + 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_spi_pio_close(&state->funcs); + return NULL; + } + + return &state->funcs; + +} + +static void wiznet_spi_pio_close(wiznet_spi_handle_t handle) { + + spi_pio_state_t *state = (spi_pio_state_t *)handle; + if (state) { + if (state->pio_sm >= 0) { + if (state->pio_offset != -1) { + pio_remove_program(state->pio, &PIO_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(spi_pio_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_spi_pio_frame_start(void) { + assert(active_state); +#if (_WIZCHIP_ == W6300) +#if (_WIZCHIP_QSPI_MODE_ == QSPI_SINGLE_MODE) + gpio_set_function(active_state->spi_config->data_io0_pin, active_state->pio_func_sel); + gpio_set_function(active_state->spi_config->data_io1_pin, active_state->pio_func_sel); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_DUAL_MODE) + gpio_set_function(active_state->spi_config->data_io0_pin, active_state->pio_func_sel); + gpio_set_function(active_state->spi_config->data_io1_pin, active_state->pio_func_sel); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_QUAD_MODE) + gpio_set_function(active_state->spi_config->data_io0_pin, active_state->pio_func_sel); + gpio_set_function(active_state->spi_config->data_io1_pin, active_state->pio_func_sel); + gpio_set_function(active_state->spi_config->data_io2_pin, active_state->pio_func_sel); + gpio_set_function(active_state->spi_config->data_io3_pin, active_state->pio_func_sel); + /* @todo: Implement to use. */ +#endif + gpio_set_function(active_state->spi_config->clock_pin, active_state->pio_func_sel); + gpio_pull_down(active_state->spi_config->clock_pin); +#else + 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); +#endif + // Pull CS low + cs_set(active_state, false); +} + +static void wiznet_spi_pio_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 +} + +#if (_WIZCHIP_ == W6300) +// To read a byte we must first have been asked to write a 3 byte spi header +void wiznet_spi_pio_read_byte(uint8_t op_code, uint16_t AddrSel, uint8_t *rx, uint16_t rx_length) { + uint8_t command_buf[8] = {0,}; + uint16_t command_len = mk_cmd_buf(command_buf, op_code, AddrSel); + uint32_t loop_cnt = 0; + + pio_sm_set_enabled(active_state->pio, active_state->pio_sm, false); + pio_sm_set_wrap(active_state->pio, active_state->pio_sm, active_state->pio_offset, active_state->pio_offset + PIO_OFFSET_READ_BITS_END - 1); + //pio_sm_set_wrap(active_state->pio, active_state->pio_sm, active_state->pio_offset + PIO_SPI_OFFSET_WRITE_BITS, active_state->pio_offset + PIO_SPI_OFFSET_READ_BITS_END - 1); + pio_sm_clear_fifos(active_state->pio, active_state->pio_sm); + +#if (_WIZCHIP_QSPI_MODE_ == QSPI_SINGLE_MODE) + loop_cnt = 8; + pio_sm_set_pindirs_with_mask(active_state->pio, + active_state->pio_sm, + (1u << active_state->spi_config->data_io0_pin), (1u << active_state->spi_config->data_io0_pin));// | (1u << active_state->spi_config->data_io1_pin)); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_DUAL_MODE) + loop_cnt = 4; + pio_sm_set_pindirs_with_mask(active_state->pio, + active_state->pio_sm, + (1u << active_state->spi_config->data_io0_pin) | (1u << active_state->spi_config->data_io1_pin), + (1u << active_state->spi_config->data_io0_pin) | (1u << active_state->spi_config->data_io1_pin)); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_QUAD_MODE) + loop_cnt = 2; + pio_sm_set_pindirs_with_mask(active_state->pio, + active_state->pio_sm, + (1u << active_state->spi_config->data_io0_pin) | (1u << active_state->spi_config->data_io1_pin) | (1u << active_state->spi_config->data_io2_pin) | (1u << active_state->spi_config->data_io3_pin), + (1u << active_state->spi_config->data_io0_pin) | (1u << active_state->spi_config->data_io1_pin) | (1u << active_state->spi_config->data_io2_pin) | (1u << active_state->spi_config->data_io3_pin)); + + /* @todo: Implement to use. */ +#endif + + pio_sm_restart(active_state->pio, active_state->pio_sm); + pio_sm_clkdiv_restart(active_state->pio, active_state->pio_sm); + + pio_sm_put(active_state->pio, active_state->pio_sm, command_len * loop_cnt - 1); + pio_sm_exec(active_state->pio, active_state->pio_sm, pio_encode_out(pio_x, 32)); + + pio_sm_put(active_state->pio, active_state->pio_sm, rx_length - 1); + pio_sm_exec(active_state->pio, active_state->pio_sm, pio_encode_out(pio_y, 32)); + + pio_sm_exec(active_state->pio, active_state->pio_sm, pio_encode_jmp(active_state->pio_offset)); + + dma_channel_abort(active_state->dma_out); + dma_channel_abort(active_state->dma_in); + + dma_channel_config out_config = dma_channel_get_default_config(active_state->dma_out); + channel_config_set_transfer_data_size(&out_config, DMA_SIZE_8); + channel_config_set_bswap(&out_config, true); + channel_config_set_dreq(&out_config, pio_get_dreq(active_state->pio, active_state->pio_sm, true)); + dma_channel_configure(active_state->dma_out, &out_config, &active_state->pio->txf[active_state->pio_sm], command_buf, command_len, true); + + dma_channel_config in_config = dma_channel_get_default_config(active_state->dma_in); + channel_config_set_transfer_data_size(&in_config, DMA_SIZE_8); + channel_config_set_bswap(&in_config, true); + channel_config_set_dreq(&in_config, pio_get_dreq(active_state->pio, active_state->pio_sm, false)); + channel_config_set_write_increment(&in_config, true); + channel_config_set_read_increment(&in_config, false); + dma_channel_configure(active_state->dma_in, &in_config, rx, &active_state->pio->rxf[active_state->pio_sm], rx_length, true); + +#if 1 + pio_sm_set_enabled(active_state->pio, active_state->pio_sm, true); + + __compiler_memory_barrier(); + + dma_channel_wait_for_finish_blocking(active_state->dma_out); + dma_channel_wait_for_finish_blocking(active_state->dma_in); + + __compiler_memory_barrier(); + + pio_sm_set_enabled(active_state->pio, active_state->pio_sm, false); + pio_sm_exec(active_state->pio, active_state->pio_sm, pio_encode_mov(pio_pins, pio_null)); + +#endif +} + +void wiznet_spi_pio_write_byte(uint8_t op_code, uint16_t AddrSel, uint8_t *tx, uint16_t tx_length) { + uint8_t command_buf[8] = {0,}; + uint16_t command_len = mk_cmd_buf(command_buf, op_code, AddrSel); + uint32_t loop_cnt = 0; + tx_length = tx_length + command_len; + + pio_sm_set_enabled(active_state->pio, active_state->pio_sm, false); + pio_sm_set_wrap(active_state->pio, active_state->pio_sm, active_state->pio_offset, active_state->pio_offset + PIO_OFFSET_WRITE_BITS_END - 1); + pio_sm_clear_fifos(active_state->pio, active_state->pio_sm); + +#if (_WIZCHIP_QSPI_MODE_ == QSPI_SINGLE_MODE) + loop_cnt = 8; + pio_sm_set_pindirs_with_mask(active_state->pio, + active_state->pio_sm, + (1u << active_state->spi_config->data_io0_pin), (1u << active_state->spi_config->data_io0_pin)); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_DUAL_MODE) + loop_cnt = 4; + pio_sm_set_pindirs_with_mask(active_state->pio, + active_state->pio_sm, + (1u << active_state->spi_config->data_io0_pin) | (1u << active_state->spi_config->data_io1_pin), + (1u << active_state->spi_config->data_io0_pin) | (1u << active_state->spi_config->data_io1_pin)); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_QUAD_MODE) + loop_cnt = 2; + pio_sm_set_pindirs_with_mask(active_state->pio, + active_state->pio_sm, + (1u << active_state->spi_config->data_io0_pin) | (1u << active_state->spi_config->data_io1_pin) | (1u << active_state->spi_config->data_io2_pin) | (1u << active_state->spi_config->data_io3_pin), + (1u << active_state->spi_config->data_io0_pin) | (1u << active_state->spi_config->data_io1_pin) | (1u << active_state->spi_config->data_io2_pin) | (1u << active_state->spi_config->data_io3_pin)); + +#endif + + pio_sm_restart(active_state->pio, active_state->pio_sm); + pio_sm_clkdiv_restart(active_state->pio, active_state->pio_sm); + pio_sm_put(active_state->pio, active_state->pio_sm, tx_length * loop_cnt - 1); + pio_sm_exec(active_state->pio, active_state->pio_sm, pio_encode_out(pio_x, 32)); + pio_sm_put(active_state->pio, active_state->pio_sm, 0); + pio_sm_exec(active_state->pio, active_state->pio_sm, pio_encode_out(pio_y, 32)); + pio_sm_exec(active_state->pio, active_state->pio_sm, pio_encode_jmp(active_state->pio_offset)); + dma_channel_abort(active_state->dma_out); + + + dma_channel_config out_config = dma_channel_get_default_config(active_state->dma_out); + channel_config_set_transfer_data_size(&out_config, DMA_SIZE_8); + channel_config_set_bswap(&out_config, true); + channel_config_set_dreq(&out_config, pio_get_dreq(active_state->pio, active_state->pio_sm, true)); + + pio_sm_set_enabled(active_state->pio, active_state->pio_sm, true); + + dma_channel_configure(active_state->dma_out, &out_config, &active_state->pio->txf[active_state->pio_sm], command_buf, command_len, true); + dma_channel_wait_for_finish_blocking(active_state->dma_out); + dma_channel_configure(active_state->dma_out, &out_config, &active_state->pio->txf[active_state->pio_sm], tx, tx_length - command_len, true); + dma_channel_wait_for_finish_blocking(active_state->dma_out); + + const uint32_t fdebug_tx_stall = 1u << (PIO_FDEBUG_TXSTALL_LSB + active_state->pio_sm); + active_state->pio->fdebug = fdebug_tx_stall; + // pio_sm_set_enabled(active_state->pio, active_state->pio_sm, true); + while (!(active_state->pio->fdebug & fdebug_tx_stall)) { + tight_loop_contents(); // todo timeout + } +#if 1 + + __compiler_memory_barrier(); + //pio_sm_set_enabled(active_state->pio, active_state->pio_sm, false); +#if (_WIZCHIP_QSPI_MODE_ == QSPI_SINGLE_MODE) + pio_sm_set_consecutive_pindirs(active_state->pio, active_state->pio_sm, active_state->spi_config->data_io0_pin, 1, false); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_DUAL_MODE) + pio_sm_set_consecutive_pindirs(active_state->pio, active_state->pio_sm, active_state->spi_config->data_io0_pin, 2, false); +#elif (_WIZCHIP_QSPI_MODE_ == QSPI_QUAD_MODE) + pio_sm_set_consecutive_pindirs(active_state->pio, active_state->pio_sm, active_state->spi_config->data_io0_pin, 4, false); +#endif + + pio_sm_exec(active_state->pio, active_state->pio_sm, pio_encode_mov(pio_pins, pio_null)); + pio_sm_set_enabled(active_state->pio, active_state->pio_sm, false); +#endif +} +#else +// send tx then receive rx +// rx can be null if you just want to send, but tx and tx_length must be valid +static bool pio_spi_transfer(spi_pio_state_t *state, const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length) { + assert(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 + PIO_OFFSET_WRITE_BITS, state->pio_offset + PIO_OFFSET_READ_BITS_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 + PIO_OFFSET_WRITE_BITS, state->pio_offset + PIO_OFFSET_WRITE_BITS_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 + PIO_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; +} + + +static uint8_t wiznet_spi_pio_read_byte(void) { + assert(active_state); + assert(active_state->spi_header_count == SPI_HEADER_LEN); + uint8_t ret; + if (!pio_spi_transfer(active_state, 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_spi_pio_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 +static void wiznet_spi_pio_read_buffer(uint8_t* pBuf, uint16_t len) { + + assert(active_state); + assert(active_state->spi_header_count == SPI_HEADER_LEN); + if (!pio_spi_transfer(active_state, 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 +static void wiznet_spi_pio_write_buffer(uint8_t* pBuf, uint16_t len) { + assert(active_state); + if (len == SPI_HEADER_LEN && active_state->spi_header_count == 0) { + memcpy(active_state->spi_header, pBuf, SPI_HEADER_LEN); // expect another call + active_state->spi_header_count = SPI_HEADER_LEN; + } else { + if (active_state->spi_header_count == SPI_HEADER_LEN) { + if (!pio_spi_transfer(active_state, active_state->spi_header, SPI_HEADER_LEN, NULL, 0)) { + panic("spi failed writing header"); + } + active_state->spi_header_count = 0; + } + assert(active_state->spi_header_count == 0); + if (!pio_spi_transfer(active_state, pBuf, len, NULL, 0)) { + panic("spi failed writing buffer"); + } + } +} +#endif + + +static void wiznet_spi_pio_set_active(wiznet_spi_handle_t handle) { + active_state = (spi_pio_state_t *)handle; +} + +static void wiznet_spi_pio_set_inactive(void) { + active_state = NULL; +} + +static void wizchip_spi_pio_reset(wiznet_spi_handle_t handle) { + + spi_pio_state_t *state = (spi_pio_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_spi_funcs_t *get_wiznet_spi_pio_impl(void) { + static wiznet_spi_funcs_t funcs = { + .close = wiznet_spi_pio_close, + .set_active = wiznet_spi_pio_set_active, + .set_inactive = wiznet_spi_pio_set_inactive, + .frame_start = wiznet_spi_pio_frame_start, + .frame_end = wiznet_spi_pio_frame_end, + .read_byte = wiznet_spi_pio_read_byte, + .write_byte = wiznet_spi_pio_write_byte, +#if (_WIZCHIP_ == W5500) + .read_buffer = wiznet_spi_pio_read_buffer, + .write_buffer = wiznet_spi_pio_write_buffer, +#endif + .reset = wizchip_spi_pio_reset, + }; + return &funcs; +} \ No newline at end of file diff --git a/lib/w6300/wizchip_qspi_pio.h b/lib/w6300/wizchip_qspi_pio.h new file mode 100644 index 0000000..6a0c6c7 --- /dev/null +++ b/lib/w6300/wizchip_qspi_pio.h @@ -0,0 +1,77 @@ +/* + Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + + SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef _WIZNET_SPI_FUNCS_H_ +#define _WIZNET_SPI_FUNCS_H_ + +#include + +typedef struct wiznet_spi_funcs** wiznet_spi_handle_t; +#if (_WIZCHIP_ == W6300) +typedef struct wiznet_spi_config { + uint16_t clock_div_major; + uint8_t clock_div_minor; + uint8_t clock_pin; + uint8_t data_io0_pin; + uint8_t data_io1_pin; + uint8_t data_io2_pin; + uint8_t data_io3_pin; + uint8_t cs_pin; + uint8_t reset_pin; + uint8_t irq_pin; +} wiznet_spi_config_t; + +typedef struct wiznet_spi_funcs { + void (*close)(wiznet_spi_handle_t funcs); + void (*set_active)(wiznet_spi_handle_t funcs); + void (*set_inactive)(void); + void (*frame_start)(void); + void (*frame_end)(void); + void (*read_byte)(uint8_t opcode, uint16_t addr, uint8_t* pBuf, uint16_t len); + void (*write_byte)(uint8_t opcode, uint16_t addr, uint8_t* pBuf, uint16_t len); + void (*read_buffer)(uint8_t *pBuf, uint16_t len); + void (*write_buffer)(uint8_t *pBuf, uint16_t len); + void (*reset)(wiznet_spi_handle_t funcs); +} wiznet_spi_funcs_t; +#else +typedef struct wiznet_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_spi_config_t; + +typedef struct wiznet_spi_funcs { + void (*close)(wiznet_spi_handle_t funcs); + void (*set_active)(wiznet_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)(uint8_t *pBuf, uint16_t len); + void (*reset)(wiznet_spi_handle_t funcs); +} wiznet_spi_funcs_t; +#endif + + +#endif + +#ifndef _WIZNET_SPI_PIO_H_ +#define _WIZNET_SPI_PIO_H_ + +#include "wizchip_spi.h" + + +wiznet_spi_handle_t wiznet_spi_pio_open(const wiznet_spi_config_t *spi_config); +#endif + diff --git a/lib/w6300/wizchip_qspi_pio.pio b/lib/w6300/wizchip_qspi_pio.pio new file mode 100644 index 0000000..938e510 --- /dev/null +++ b/lib/w6300/wizchip_qspi_pio.pio @@ -0,0 +1,95 @@ +; +; Copyright (c) 2023 Raspberry Pi (Trading) Ltd. +; +; SPDX-License-Identifier: BSD-3-Clause +; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Normal SPI for W55RP20 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.program wiznet_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: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; QSPI Single for W6300 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.program wizchip_pio_spi_single_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_bits_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_bits_end: + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; QSPI Dual for W6300 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.program wizchip_pio_spi_dual_write_read +.side_set 1 + +public write_bits: + out pins, 2 side 0 + jmp x-- write_bits side 1 + set pins 0 side 0 +public write_bits_end: +read_byte_delay: + set pindirs 0 side 0 +read_byte: + set x 2 side 1 +read_bits: + in pins, 2 side 0 + jmp x-- read_bits side 1 + in pins, 2 side 0 + jmp y-- read_byte side 0 +public read_bits_end: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; QSPI Quad for W6300 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.program wizchip_pio_spi_quad_write_read +.side_set 1 + +write_bits: + out pins, 4 side 0 + jmp x-- write_bits side 1 + set pins 0 side 0 +public write_bits_end: +read_byte_delay: + set pindirs 0 side 0 +read_byte: + set x 0 side 1 +read_bits: + in pins, 4 side 0 + jmp x-- read_bits side 1 + in pins, 4 side 0 + jmp y-- read_byte side 0 +public read_bits_end: diff --git a/lib/w6300/wizchip_spi.c b/lib/w6300/wizchip_spi.c new file mode 100644 index 0000000..db3549d --- /dev/null +++ b/lib/w6300/wizchip_spi.c @@ -0,0 +1,388 @@ +/** + Copyright (c) 2022 WIZnet Co.,Ltd + + SPDX-License-Identifier: BSD-3-Clause +*/ + +/** + ---------------------------------------------------------------------------------------------------- + Includes + ---------------------------------------------------------------------------------------------------- +*/ +#include + +#include "port_common.h" + +#include "wizchip_conf.h" +#include "wizchip_spi.h" +#include "board_list.h" + + +#include "wizchip_qspi_pio.h" +#include "pico/stdlib.h" +#include "pico/binary_info.h" +#include "pico/critical_section.h" +#include "hardware/dma.h" + +/** + ---------------------------------------------------------------------------------------------------- + Macros + ---------------------------------------------------------------------------------------------------- +*/ + +/** + ---------------------------------------------------------------------------------------------------- + Variables + ---------------------------------------------------------------------------------------------------- +*/ +static critical_section_t g_wizchip_cri_sec; + +#ifdef USE_SPI_DMA +static uint dma_tx; +static uint dma_rx; +static dma_channel_config dma_channel_config_tx; +static dma_channel_config dma_channel_config_rx; +#endif + +#ifdef USE_PIO +#if (_WIZCHIP_ == W6300) +wiznet_spi_config_t g_spi_config = { + .clock_div_major = WIZNET_SPI_CLKDIV_MAJOR_DEFAULT, + .clock_div_minor = WIZNET_SPI_CLKDIV_MINOR_DEFAULT, + .clock_pin = PIO_SPI_SCK_PIN, + .data_io0_pin = PIO_SPI_DATA_IO0_PIN, + .data_io1_pin = PIO_SPI_DATA_IO1_PIN, + .data_io2_pin = PIO_SPI_DATA_IO2_PIN, + .data_io3_pin = PIO_SPI_DATA_IO3_PIN, + .cs_pin = PIN_CS, + .reset_pin = PIN_RST, + .irq_pin = PIN_INT, +}; +#else +wiznet_spi_config_t g_spi_config = { + .data_in_pin = PIN_MISO, + .data_out_pin = PIN_MOSI, + .cs_pin = PIN_CS, + .clock_pin = PIN_SCK, + .irq_pin = PIN_INT, + .reset_pin = PIN_RST, + .clock_div_major = WIZNET_SPI_CLKDIV_MAJOR_DEFAULT, + .clock_div_minor = WIZNET_SPI_CLKDIV_MINOR_DEFAULT, +}; +#endif +#endif +wiznet_spi_handle_t spi_handle; + +/** + ---------------------------------------------------------------------------------------------------- + Functions + ---------------------------------------------------------------------------------------------------- +*/ +static inline void wizchip_select(void) { + gpio_put(PIN_CS, 0); +} + +static inline void wizchip_deselect(void) { + gpio_put(PIN_CS, 1); + +} + +void wizchip_reset() { + gpio_init(PIN_RST); + +#if defined(USE_PIO) && (_WIZCHIP_ == W5500) + gpio_pull_up(PIN_RST); + gpio_set_dir(PIN_RST, GPIO_OUT); + sleep_ms(5); +#else + gpio_set_dir(PIN_RST, GPIO_OUT); +#endif + gpio_put(PIN_RST, 0); + sleep_ms(100); + + gpio_put(PIN_RST, 1); + sleep_ms(100); + + bi_decl(bi_1pin_with_name(PIN_RST, "WIZCHIP RESET")); +} + +#ifndef USE_PIO +static uint8_t wizchip_read(void) { + uint8_t rx_data = 0; + uint8_t tx_data = 0xFF; + + spi_read_blocking(SPI_PORT, tx_data, &rx_data, 1); + + return rx_data; +} + +static void wizchip_write(uint8_t tx_data) { + spi_write_blocking(SPI_PORT, &tx_data, 1); +} + + +#if (_WIZCHIP_ == W6100) +static void wizchip_read_buf(uint8_t* rx_data, datasize_t len) { + uint8_t tx_data = 0xFF; + + spi_read_blocking(SPI_PORT, tx_data, rx_data, len); +} + +static void wizchip_write_buf(uint8_t* tx_data, datasize_t len) { + spi_write_blocking(SPI_PORT, tx_data, len); +} +#endif + + + + +#ifdef USE_SPI_DMA +static void wizchip_read_burst(uint8_t *pBuf, uint16_t len) { + uint8_t dummy_data = 0xFF; + + channel_config_set_read_increment(&dma_channel_config_tx, false); + channel_config_set_write_increment(&dma_channel_config_tx, false); + dma_channel_configure(dma_tx, &dma_channel_config_tx, + &spi_get_hw(SPI_PORT)->dr, // write address + &dummy_data, // read address + len, // element count (each element is of size transfer_data_size) + false); // don't start yet + + channel_config_set_read_increment(&dma_channel_config_rx, false); + channel_config_set_write_increment(&dma_channel_config_rx, true); + dma_channel_configure(dma_rx, &dma_channel_config_rx, + pBuf, // write address + &spi_get_hw(SPI_PORT)->dr, // read address + len, // element count (each element is of size transfer_data_size) + false); // don't start yet + + dma_start_channel_mask((1u << dma_tx) | (1u << dma_rx)); + dma_channel_wait_for_finish_blocking(dma_rx); +} + +static void wizchip_write_burst(uint8_t *pBuf, uint16_t len) { + uint8_t dummy_data; + + channel_config_set_read_increment(&dma_channel_config_tx, true); + channel_config_set_write_increment(&dma_channel_config_tx, false); + dma_channel_configure(dma_tx, &dma_channel_config_tx, + &spi_get_hw(SPI_PORT)->dr, // write address + pBuf, // read address + len, // element count (each element is of size transfer_data_size) + false); // don't start yet + + channel_config_set_read_increment(&dma_channel_config_rx, false); + channel_config_set_write_increment(&dma_channel_config_rx, false); + dma_channel_configure(dma_rx, &dma_channel_config_rx, + &dummy_data, // write address + &spi_get_hw(SPI_PORT)->dr, // read address + len, // element count (each element is of size transfer_data_size) + false); // don't start yet + + dma_start_channel_mask((1u << dma_tx) | (1u << dma_rx)); + dma_channel_wait_for_finish_blocking(dma_rx); +} +#endif +#endif + +static void wizchip_critical_section_lock(void) { + critical_section_enter_blocking(&g_wizchip_cri_sec); +} + +static void wizchip_critical_section_unlock(void) { + critical_section_exit(&g_wizchip_cri_sec); +} + +void wizchip_spi_initialize(void) { +#ifdef USE_PIO + spi_handle = wiznet_spi_pio_open(&g_spi_config); + (*spi_handle)->set_active(spi_handle); +#else + // this example will use SPI0 at 5MHz + spi_init(SPI_PORT, SPI_CLK * 1000 * 1000); + + gpio_set_function(PIN_SCK, GPIO_FUNC_SPI); + gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI); + gpio_set_function(PIN_MISO, GPIO_FUNC_SPI); + + // make the SPI pins available to picotool + bi_decl(bi_3pins_with_func(PIN_MISO, PIN_MOSI, PIN_SCK, GPIO_FUNC_SPI)); + + // chip select is active-low, so we'll initialise it to a driven-high state + gpio_init(PIN_CS); + gpio_set_dir(PIN_CS, GPIO_OUT); + gpio_put(PIN_CS, 1); + + // make the SPI pins available to picotool + bi_decl(bi_1pin_with_name(PIN_CS, "W5x00 CHIP SELECT")); + +#ifdef USE_SPI_DMA + dma_tx = dma_claim_unused_channel(true); + dma_rx = dma_claim_unused_channel(true); + + dma_channel_config_tx = dma_channel_get_default_config(dma_tx); + channel_config_set_transfer_data_size(&dma_channel_config_tx, DMA_SIZE_8); + channel_config_set_dreq(&dma_channel_config_tx, DREQ_SPI0_TX); + + // We set the inbound DMA to transfer from the SPI receive FIFO to a memory buffer paced by the SPI RX FIFO DREQ + // We coinfigure the read address to remain unchanged for each element, but the write + // address to increment (so data is written throughout the buffer) + dma_channel_config_rx = dma_channel_get_default_config(dma_rx); + channel_config_set_transfer_data_size(&dma_channel_config_rx, DMA_SIZE_8); + channel_config_set_dreq(&dma_channel_config_rx, DREQ_SPI0_RX); + channel_config_set_read_increment(&dma_channel_config_rx, false); + channel_config_set_write_increment(&dma_channel_config_rx, true); +#endif +#endif +} + +void wizchip_cris_initialize(void) { + critical_section_init(&g_wizchip_cri_sec); + reg_wizchip_cris_cbfunc(wizchip_critical_section_lock, wizchip_critical_section_unlock); +} + +void wizchip_initialize(void) { + +#ifdef USE_PIO + (*spi_handle)->frame_end(); +#if (_WIZCHIP_ == W6300) + reg_wizchip_qspi_cbfunc((*spi_handle)->read_byte, (*spi_handle)->write_byte); +#else + reg_wizchip_spi_cbfunc((*spi_handle)->read_byte, (*spi_handle)->write_byte); + reg_wizchip_spiburst_cbfunc((*spi_handle)->read_buffer, (*spi_handle)->write_buffer); +#endif + reg_wizchip_cs_cbfunc((*spi_handle)->frame_start, (*spi_handle)->frame_end); + +#else + /* Deselect the FLASH : chip select high */ + wizchip_deselect(); + /* CS function register */ + reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); + /* SPI function register */ +#if (_WIZCHIP_ == W6100) + reg_wizchip_spi_cbfunc(wizchip_read, wizchip_write, wizchip_read_buf, wizchip_write_buf); +#else + reg_wizchip_spi_cbfunc(wizchip_read, wizchip_write); +#endif +#endif +#ifdef USE_SPI_DMA + reg_wizchip_spiburst_cbfunc(wizchip_read_burst, wizchip_write_burst); +#endif + + /* W5x00, W6x00 initialize */ + uint8_t temp; +#if (_WIZCHIP_ == W5100S) + uint8_t memsize[2][4] = {{2, 2, 2, 2}, {2, 2, 2, 2}}; +#elif (_WIZCHIP_ == W5500) + uint8_t memsize[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}}; +#elif (_WIZCHIP_ == W6100) + uint8_t memsize[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}}; +#elif (_WIZCHIP_ == W6300) + uint8_t memsize[2][8] = {{4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4}}; +#endif + + if (ctlwizchip(CW_INIT_WIZCHIP, (void *)memsize) == -1) { +#if _WIZCHIP_ <= W5500 + printf(" W5x00 initialized fail\n"); +#else + printf(" W6x00 initialized fail\n"); +#endif + + return; + } +} + +void wizchip_check(void) { +#if (_WIZCHIP_ == W5100S) + /* Read version register */ + if (getVER() != 0x51) { + printf(" ACCESS ERR : VERSION != 0x51, read value = 0x%02x\n", getVER()); + + while (1) + ; + } +#elif (_WIZCHIP_ == W5500) + /* Read version register */ + if (getVERSIONR() != 0x04) { + printf(" ACCESS ERR : VERSION != 0x04, read value = 0x%02x\n", getVERSIONR()); + + while (1) + ; + } +#elif (_WIZCHIP_ == W6100) + /* Read version register */ + if (getCIDR() != 0x6100) { + printf(" ACCESS ERR : VERSION != 0x6100, read value = 0x%02x\n", getCIDR()); + + while (1) + ; + } +#elif (_WIZCHIP_ == W6300) + /* Read version register */ + if (getCIDR() != 0x6300) { + printf(" ACCESS ERR : VERSION != 0x6100, read value = 0x%02x\n", getCIDR()); + + while (1) + ; + } +#endif +} + +/* Network */ +void network_initialize(wiz_NetInfo net_info) { +#if _WIZCHIP_ <= W5500 + ctlnetwork(CN_SET_NETINFO, (void *)&net_info); +#else + uint8_t syslock = SYS_NET_LOCK; + ctlwizchip(CW_SYS_UNLOCK, &syslock); + ctlnetwork(CN_SET_NETINFO, (void *)&net_info); +#endif +} + +void print_network_information(wiz_NetInfo net_info) { + uint8_t tmp_str[8] = { + 0, + }; + + ctlnetwork(CN_GET_NETINFO, (void *)&net_info); + ctlwizchip(CW_GET_ID, (void *)tmp_str); +#if _WIZCHIP_ <= W5500 + if (net_info.dhcp == NETINFO_DHCP) { + printf("====================================================================================================\n"); + printf(" %s network configuration : DHCP\n\n", (char *)tmp_str); + } else { + printf("====================================================================================================\n"); + printf(" %s network configuration : static\n\n", (char *)tmp_str); + } + + printf(" MAC : %02X:%02X:%02X:%02X:%02X:%02X\n", net_info.mac[0], net_info.mac[1], net_info.mac[2], net_info.mac[3], net_info.mac[4], net_info.mac[5]); + printf(" IP : %d.%d.%d.%d\n", net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3]); + printf(" Subnet Mask : %d.%d.%d.%d\n", net_info.sn[0], net_info.sn[1], net_info.sn[2], net_info.sn[3]); + printf(" Gateway : %d.%d.%d.%d\n", net_info.gw[0], net_info.gw[1], net_info.gw[2], net_info.gw[3]); + printf(" DNS : %d.%d.%d.%d\n", net_info.dns[0], net_info.dns[1], net_info.dns[2], net_info.dns[3]); + printf("====================================================================================================\n\n"); +#else + printf("==========================================================\n"); + printf(" %s network configuration\n\n", (char *)tmp_str); + + printf(" MAC : %02X:%02X:%02X:%02X:%02X:%02X\n", net_info.mac[0], net_info.mac[1], net_info.mac[2], net_info.mac[3], net_info.mac[4], net_info.mac[5]); + printf(" IP : %d.%d.%d.%d\n", net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3]); + printf(" Subnet Mask : %d.%d.%d.%d\n", net_info.sn[0], net_info.sn[1], net_info.sn[2], net_info.sn[3]); + printf(" Gateway : %d.%d.%d.%d\n", net_info.gw[0], net_info.gw[1], net_info.gw[2], net_info.gw[3]); + printf(" DNS : %d.%d.%d.%d\n", net_info.dns[0], net_info.dns[1], net_info.dns[2], net_info.dns[3]); + print_ipv6_addr(" GW6 ", net_info.gw6); + print_ipv6_addr(" LLA ", net_info.lla); + print_ipv6_addr(" GUA ", net_info.gua); + print_ipv6_addr(" SUB6", net_info.sn6); + print_ipv6_addr(" DNS6", net_info.dns6); + printf("==========================================================\n\n"); +#endif +} + +void print_ipv6_addr(uint8_t* name, uint8_t* ip6addr) { + printf("%s : ", name); + printf("%04X:%04X", ((uint16_t)ip6addr[0] << 8) | ((uint16_t)ip6addr[1]), ((uint16_t)ip6addr[2] << 8) | ((uint16_t)ip6addr[3])); + printf(":%04X:%04X", ((uint16_t)ip6addr[4] << 8) | ((uint16_t)ip6addr[5]), ((uint16_t)ip6addr[6] << 8) | ((uint16_t)ip6addr[7])); + printf(":%04X:%04X", ((uint16_t)ip6addr[8] << 8) | ((uint16_t)ip6addr[9]), ((uint16_t)ip6addr[10] << 8) | ((uint16_t)ip6addr[11])); + printf(":%04X:%04X\r\n", ((uint16_t)ip6addr[12] << 8) | ((uint16_t)ip6addr[13]), ((uint16_t)ip6addr[14] << 8) | ((uint16_t)ip6addr[15])); +} \ No newline at end of file diff --git a/lib/w6300/wizchip_spi.h b/lib/w6300/wizchip_spi.h new file mode 100644 index 0000000..1ec1d46 --- /dev/null +++ b/lib/w6300/wizchip_spi.h @@ -0,0 +1,236 @@ +/** + Copyright (c) 2022 WIZnet Co.,Ltd + + SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef _WIZCHIP_SPI_H_ +#define _WIZCHIP_SPI_H_ + +#include "board_list.h" + +/** + ---------------------------------------------------------------------------------------------------- + Macros + ---------------------------------------------------------------------------------------------------- +*/ +/* SPI */ +#if (DEVICE_BOARD_NAME == W55RP20_EVB_PICO) + +#define USE_PIO +#define WIZNET_SPI_CLKDIV_MAJOR_DEFAULT 2 +#define WIZNET_SPI_CLKDIV_MINOR_DEFAULT 0 + +#define PIN_CS 20 +#define PIN_SCK 21 +#define PIN_MOSI 23 +#define PIN_MISO 22 +#define PIN_INT 24 +#define PIN_RST 25 + +#elif (DEVICE_BOARD_NAME == W6300_EVB_PICO || DEVICE_BOARD_NAME == W6300_EVB_PICO2) + +#define USE_PIO +#define WIZNET_SPI_CLKDIV_MAJOR_DEFAULT 2 +#define WIZNET_SPI_CLKDIV_MINOR_DEFAULT 0 + +#define PIN_INT 15 +#define PIN_CS 16 +#define PIO_SPI_SCK_PIN 17 +#define PIO_SPI_DATA_IO0_PIN 18 +#define PIO_SPI_DATA_IO1_PIN 19 +#define PIO_SPI_DATA_IO2_PIN 20 +#define PIO_SPI_DATA_IO3_PIN 21 +#define PIN_RST 22 + +#else +/* SPI */ +#define SPI_PORT spi0 +#define SPI_CLK 10 + +#define PIN_SCK 18 +#define PIN_MOSI 19 +#define PIN_MISO 16 +#define PIN_CS 17 +#define PIN_RST 20 +#define PIN_INT 21 + +/* Use SPI DMA */ +//#define USE_SPI_DMA // if you want to use SPI DMA, uncomment. +#endif + + +/** + ---------------------------------------------------------------------------------------------------- + Functions + ---------------------------------------------------------------------------------------------------- +*/ +/* wizchip */ +/*! \brief Set CS pin + \ingroup wizchip_spi + + Set chip select pin of spi0 to low(Active low). + + \param none +*/ +static inline void wizchip_select(void); + +/*! \brief Set CS pin + \ingroup wizchip_spi + + Set chip select pin of spi0 to high(Inactive high). + + \param none +*/ +static inline void wizchip_deselect(void); + +/*! \brief Read from an SPI device, blocking + \ingroup wizchip_spi + + Set spi_read_blocking function. + Read byte from SPI to rx_data buffer. + Blocks until all data is transferred. No timeout, as SPI hardware always transfers at a known data rate. + + \param none +*/ +static uint8_t wizchip_read(void); + +/*! \brief Write to an SPI device, blocking + \ingroup wizchip_spi + + Set spi_write_blocking function. + Write byte from tx_data buffer to SPI device. + Blocks until all data is transferred. No timeout, as SPI hardware always transfers at a known data rate. + + \param tx_data Buffer of data to write +*/ +static void wizchip_write(uint8_t tx_data); + + +#if (_WIZCHIP_ == W6100) +static void wizchip_read_buf(uint8_t* rx_data, datasize_t len); +static void wizchip_write_buf(uint8_t* tx_data, datasize_t len); +#endif + +#ifdef USE_SPI_DMA +/*! \brief Configure all DMA parameters and optionally start transfer + \ingroup wizchip_spi + + Configure all DMA parameters and read from DMA + + \param pBuf Buffer of data to read + \param len element count (each element is of size transfer_data_size) +*/ +static void wizchip_read_burst(uint8_t *pBuf, uint16_t len); + +/*! \brief Configure all DMA parameters and optionally start transfer + \ingroup wizchip_spi + + Configure all DMA parameters and write to DMA + + \param pBuf Buffer of data to write + \param len element count (each element is of size transfer_data_size) +*/ +static void wizchip_write_burst(uint8_t *pBuf, uint16_t len); +#endif + +/*! \brief Enter a critical section + \ingroup wizchip_spi + + Set ciritical section enter blocking function. + If the spin lock associated with this critical section is in use, then this + method will block until it is released. + + \param none +*/ +static void wizchip_critical_section_lock(void); + +/*! \brief Release a critical section + \ingroup wizchip_spi + + Set ciritical section exit function. + Release a critical section. + + \param none +*/ +static void wizchip_critical_section_unlock(void); + +/*! \brief Initialize SPI instances and Set DMA channel + \ingroup wizchip_spi + + Set GPIO to spi0. + Puts the SPI into a known state, and enable it. + Set DMA channel completion channel. + + \param none +*/ +void wizchip_spi_initialize(void); + +/*! \brief Initialize a critical section structure + \ingroup wizchip_spi + + The critical section is initialized ready for use. + Registers callback function for critical section for WIZchip. + + \param none +*/ +void wizchip_cris_initialize(void); + +/*! \brief wizchip reset + \ingroup wizchip_spi + + Set a reset pin and reset. + + \param none +*/ +void wizchip_reset(void); + +/*! \brief Initialize WIZchip + \ingroup wizchip_spi + + Set callback function to read/write byte using SPI & QSPI. + Set callback function for WIZchip select/deselect. + Set memory size of wizchip and monitor PHY link status. + + \param none +*/ +void wizchip_initialize(void); + +/*! \brief Check chip version + \ingroup wizchip_spi + + Get version information. + + \param none +*/ +void wizchip_check(void); + +/* Network */ +/*! \brief Initialize network + \ingroup wizchip_spi + + Set network information. + + \param net_info network information. +*/ +void network_initialize(wiz_NetInfo net_info); + +/*! \brief Print network information + \ingroup wizchip_spi + + Print network information about MAC address, IP address, Subnet mask, Gateway, DHCP and DNS address. + + \param net_info network information. +*/ +void print_network_information(wiz_NetInfo net_info); + +/*! \brief Print IPv6 Address + \ingroup wizchip_spi + + Print IPv6 Address. + + \param net_info network information. +*/ +void print_ipv6_addr(uint8_t* name, uint8_t* ip6addr); + +#endif /* _WIZCHIP_SPI_H_ */ diff --git a/picomap.cpp b/picomap.cpp index a11958b..7da9345 100644 --- a/picomap.cpp +++ b/picomap.cpp @@ -3,6 +3,11 @@ #include "pico/bootrom.h" #include "device.h" +extern "C" { +#include "wizchip_conf.h" +#include "wizchip_spi.h" +} + static void send_bytes(const std::vector &data) { for (auto b : data) { putchar(b); @@ -10,9 +15,21 @@ static void send_bytes(const std::vector &data) { stdio_flush(); } +static bool w6300_init() { + wizchip_spi_initialize(); + wizchip_cris_initialize(); + wizchip_reset(); + wizchip_initialize(); + return getCIDR() == 0x6300; +} + int main() { stdio_init_all(); + if (!w6300_init()) { + printf("W6300 init failed\n"); + } + static static_vector rx_buf; while (true) {