/* Ethernet shield test program Copyright (C) 2018 Andreas Mieke Copyright (C) 2010 Arduino LLC This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __W5100_H #define __W5100_H #include "stm32f10x.h" // Device header #include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC #include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO #include "stm32f10x_spi.h" // Keil::Device:StdPeriph Drivers:SPI #define MAX_SOCK_NUM 4 typedef uint8_t SOCKET; enum { ETH_MR_RST = 0x80, ETH_MR_PB = 0x10, ETH_MR_PPPoE = 0x08, ETH_MR_AI = 0x02, ETH_MR_IND = 0x01 }; enum { ETH_IR_CONFLICT = 0x80, ETH_IR_UNREACH = 0x40, ETH_IR_PPPoE = 0x20, ETH_IR_S3_INT = 0x08, ETH_IR_S2_INT = 0x04, ETH_IR_S1_INT = 0x02, ETH_IR_S0_INT = 0x01 }; enum { ETH_IMR_IR7 = 0x80, ETH_IMR_IR6 = 0x40, ETH_IMR_IR5 = 0x20, ETH_IMR_IR3 = 0x08, ETH_IMR_IR2 = 0x04, ETH_IMR_IR1 = 0x02, ETH_IMR_IR0 = 0x01 }; enum { ETH_SMR_MULTI = 0x80, ETH_SMR_ND = 0x20, ETH_SMR_CLOSED = 0x00, ETH_SMR_TCP = 0x01, ETH_SMR_UDP = 0x02, ETH_SMR_IPRAW = 0x03, ETH_SMR_MACRAW = 0x04, ETH_SMR_PPPoE = 0x05 }; enum { ETH_SCR_OPEN = 0x01, ETH_SCR_LISTEN = 0x02, ETH_SCR_CONNECT = 0x04, ETH_SCR_DISCON = 0x08, ETH_SCR_CLOSE = 0x10, ETH_SCR_SEND = 0x20, ETH_SCR_SEND_MAC = 0x21, ETH_SCR_SEND_KEEP = 0x22, ETH_SCR_RECV = 0x40 }; enum { ETH_SIR_SEND_OK = 0x10, ETH_SIR_TIMEOUT = 0x08, ETH_SIR_RECV = 0x04, ETH_SIR_DISCON = 0x02, ETH_SIR_CON = 0x01 }; enum { ETH_SSR_CLOSED = 0x00, ETH_SSR_INIT = 0x12, // Actually 13, Cortex doesn't seem to register the LSB ETH_SSR_LISTEN = 0x14, ETH_SSR_SYNSENT = 0x15, ETH_SSR_SYNRECV = 0x16, ETH_SSR_ESTABLISHED = 0x17, ETH_SSR_FIN_WAIT = 0x18, ETH_SSR_CLOSING = 0x1A, ETH_SSR_TIME_WAIT = 0x1B, ETH_SSR_CLOSE_WAIT = 0x1C, ETH_SSR_LAST_ACK = 0x1D, ETH_SSR_UDP = 0x22, ETH_SSR_IPRAW = 0x32, ETH_SSR_MACRAW = 0x42, ETH_SSR_PPPoE = 0x5F }; enum { ETH_SPROTO_IP = 0, ETH_SPROTO_ICMP = 1, ETH_SPROTO_IGMP = 2, ETH_SPROTO_GGP = 3, ETH_SPROTO_TCP = 6, ETH_SPROTO_PUP = 12, ETH_SPROTO_UDP = 17, ETH_SPROTO_IDP = 22, ETH_SPROTO_ND = 77, ETH_SPROTO_RAW = 255 }; void ETH_init(void); void ETH_read_data(SOCKET s, volatile uint16_t src, volatile uint8_t * dst, uint16_t len); void ETH_send_data_processing(SOCKET s, const uint8_t *data, uint16_t len); void ETH_send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len); void ETH_recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek); inline void ETH_set_gateway_IP(uint8_t *addr); inline void ETH_get_gateway_IP(uint8_t *addr); inline void ETH_set_subnet_mask(uint8_t *addr); inline void ETH_get_subnet_mask(uint8_t *addr); inline void ETH_set_mac(uint8_t * addr); inline void ETH_get_mac(uint8_t * addr); inline void ETH_set_IP(uint8_t * addr); inline void ETH_get_IP(uint8_t * addr); inline void ETH_set_retransmission_time(uint16_t timeout); inline void ETH_set_retransmission_count(uint8_t retry); inline void ETH_exec_socket_cmd(SOCKET s, uint8_t cmd); uint16_t ETH_get_TX_free_size(SOCKET s); uint16_t ETH_get_RX_received_size(SOCKET s); uint8_t ETH_write_8(uint16_t addr, uint8_t data); uint16_t ETH_write_n(uint16_t addr, const uint8_t *buf, uint16_t len); uint8_t ETH_read_8(uint16_t addr); uint16_t ETH_read_n(uint16_t addr, uint8_t *buf, uint16_t len); #define __GP_REGISTER8(name, address) \ static inline void ETH_write##name(uint8_t _data) { \ ETH_write_8(address, _data); \ } \ static inline uint8_t ETH_read##name() { \ return ETH_read_8(address); \ } #define __GP_REGISTER16(name, address) \ static void ETH_write##name(uint16_t _data) { \ ETH_write_8(address, _data >> 8); \ ETH_write_8(address+1, _data & 0xFF); \ } \ static uint16_t ETH_read##name() { \ uint16_t res = ETH_read_8(address); \ res = (res << 8) + ETH_read_8(address + 1); \ return res; \ } #define __GP_REGISTER_N(name, address, size) \ static uint16_t ETH_write##name(uint8_t *_buff) { \ return ETH_write_n(address, _buff, size); \ } \ static uint16_t ETH_read##name(uint8_t *_buff) { \ return ETH_read_n(address, _buff, size); \ } __GP_REGISTER8 (MR, 0x0000); // Mode __GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address __GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address __GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address __GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address __GP_REGISTER8 (IR, 0x0015); // Interrupt __GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask __GP_REGISTER16(RTR, 0x0017); // Timeout address __GP_REGISTER8 (RCR, 0x0019); // Retry count __GP_REGISTER8 (RMSR, 0x001A); // Receive memory size __GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size __GP_REGISTER8 (PATR, 0x001C); // Authentication type address in PPPoE mode __GP_REGISTER8 (PTIMER, 0x0028); // PPP LCP Request Timer __GP_REGISTER8 (PMAGIC, 0x0029); // PPP LCP Magic Number __GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode __GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode #undef __GP_REGISTER8 #undef __GP_REGISTER16 #undef __GP_REGISTER_N static inline uint8_t ETH_sock_read_8(SOCKET _s, uint16_t _addr); static inline uint8_t ETH_sock_write_8(SOCKET _s, uint16_t _addr, uint8_t _data); static inline uint16_t ETH_sock_read_n(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len); static inline uint16_t ETH_sock_write_n(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len); static const uint16_t ETH_CH_BASE = 0x0400; static const uint16_t ETH_CH_SIZE = 0x0100; #define __SOCKET_REGISTER8(name, address) \ static inline void ETH_write##name(SOCKET _s, uint8_t _data) { \ ETH_sock_write_8(_s, address, _data); \ } \ static inline uint8_t ETH_read##name(SOCKET _s) { \ return ETH_sock_read_8(_s, address); \ } #define __SOCKET_REGISTER16(name, address) \ static void ETH_write##name(SOCKET _s, uint16_t _data) { \ ETH_sock_write_8(_s, address, _data >> 8); \ ETH_sock_write_8(_s, address+1, _data & 0xFF); \ } \ static uint16_t ETH_read##name(SOCKET _s) { \ uint16_t res = ETH_sock_read_8(_s, address); \ uint16_t res2 = ETH_sock_read_8(_s,address + 1); \ res = res << 8; \ res2 = res2 & 0xFF; \ res = res | res2; \ return res; \ } #define __SOCKET_REGISTER_N(name, address, size) \ static uint16_t ETH_write##name(SOCKET _s, uint8_t *_buff) { \ return ETH_sock_write_n(_s, address, _buff, size); \ } \ static uint16_t ETH_read##name(SOCKET _s, uint8_t *_buff) { \ return ETH_sock_read_n(_s, address, _buff, size); \ } __SOCKET_REGISTER8(SnMR, 0x0000) // Mode __SOCKET_REGISTER8(SnCR, 0x0001) // Command __SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt __SOCKET_REGISTER8(SnSR, 0x0003) // Status __SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port __SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr __SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr __SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port __SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size __SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode __SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS __SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL __SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size __SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer __SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer __SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size __SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer __SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?) #undef __SOCKET_REGISTER8 #undef __SOCKET_REGISTER16 #undef __SOCKET_REGISTER_N static const int ETH_SOCKETS = 4; static const uint16_t ETH_SMASK = 0x07FF; // Tx buffer MASK static const uint16_t ETH_RMASK = 0x07FF; // Rx buffer MASK static const uint16_t ETH_SSIZE = 2048; // Max Tx buffer size static const uint16_t ETH_RSIZE = 2048; // Max Rx buffer size extern uint16_t ETH_SBASE[ETH_SOCKETS]; // Tx buffer base address extern uint16_t ETH_RBASE[ETH_SOCKETS]; // Rx buffer base address uint8_t ETH_sock_read_8(SOCKET s, uint16_t addr) { return ETH_read_8(ETH_CH_BASE + s * ETH_CH_SIZE + addr); } uint8_t ETH_sock_write_8(SOCKET s, uint16_t addr, uint8_t data) { return ETH_write_8(ETH_CH_BASE + s * ETH_CH_SIZE + addr, data); } uint16_t ETH_sock_read_n(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) { return ETH_read_n(ETH_CH_BASE + s * ETH_CH_SIZE + addr, buf, len); } uint16_t ETH_sock_write_n(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) { return ETH_write_n(ETH_CH_BASE + s * ETH_CH_SIZE + addr, buf, len); } void ETH_set_gateway_IP(uint8_t *addr) { ETH_writeGAR(addr); } void ETH_get_gateway_IP(uint8_t *addr) { ETH_readGAR(addr); } void ETH_set_subnet_mask(uint8_t *addr) { ETH_writeSUBR(addr); } void ETH_get_subnet_mask(uint8_t *addr) { ETH_readSUBR(addr); } void ETH_set_mac(uint8_t * addr) { ETH_writeSHAR(addr); } void ETH_get_mac(uint8_t * addr) { ETH_readSHAR(addr); } void ETH_set_IP(uint8_t * addr) { ETH_writeSIPR(addr); } void ETH_get_IP(uint8_t * addr) { ETH_readSIPR(addr); } void ETH_set_retransmission_time(uint16_t timeout) { ETH_writeRTR(timeout); } void ETH_set_retransmission_count(uint8_t retry) { ETH_writeRCR(retry); } #endif