//----------------------------------------------------------------------------- #include "w5100_spi_interface.h" #include "spi_master.h" volatile BOOL sock0_connection_established = false; volatile U08 eth_read_buffer[ETH_READ_BUFFER_SIZE]; volatile U08 eth_write_buffer[ETH_WRITE_BUFFER_SIZE]; //----------------------------------------------------------------------------- void w5100_write( U16 addr, U08 data) { spi_write_buffer[0]=0xF0; spi_write_buffer[1]=(U08)(addr>>8); spi_write_buffer[2]=(U08)(addr); spi_write_buffer[3]=data; spi_transfer(4, 0); // spi_read_buffer should contain 0x00 0x01 0x02 and 0x03 ... nice check! } U08 w5100_read( U16 addr) { spi_write_buffer[0]=0x0F; spi_write_buffer[1]=(U08)(addr>>8); spi_write_buffer[2]=(U08)(addr); spi_write_buffer[3]=0x00; spi_transfer(4, 0); return spi_read_buffer[3]; // spi_read_buffer should contain 0x00 0x01 0x02 and data ... nice check! } U08 w5100_init (void) { U08 sock0_status; // set FSCs MAC Address to value defined in w5100_spi_interface.h w5100_write( CM_SHAR0, FSC_MAC_ADDRESS0 ); w5100_write( CM_SHAR1, FSC_MAC_ADDRESS1 ); w5100_write( CM_SHAR2, FSC_MAC_ADDRESS2 ); w5100_write( CM_SHAR3, FSC_MAC_ADDRESS3 ); w5100_write( CM_SHAR4, FSC_MAC_ADDRESS4 ); w5100_write( CM_SHAR5, FSC_MAC_ADDRESS5 ); //set IP w5100_write( CM_SIPR0, FSC_IP_ADDRESS0 ); w5100_write( CM_SIPR1, FSC_IP_ADDRESS1 ); w5100_write( CM_SIPR2, FSC_IP_ADDRESS2 ); w5100_write( CM_SIPR3, FSC_IP_ADDRESS3 ); // set subnet mask w5100_write( CM_SUBR0, FSC_SUBNET_MASK0 ); w5100_write( CM_SUBR1, FSC_SUBNET_MASK1 ); w5100_write( CM_SUBR2, FSC_SUBNET_MASK2 ); w5100_write( CM_SUBR3, FSC_SUBNET_MASK3 ); // set IP of Gateway used by FSC w5100_write( CM_GAR0, FSC_GATEWAY_ADDRESS0 ); w5100_write( CM_GAR1, FSC_GATEWAY_ADDRESS1 ); w5100_write( CM_GAR2, FSC_GATEWAY_ADDRESS2 ); w5100_write( CM_GAR3, FSC_GATEWAY_ADDRESS3 ); //set socket read and write fifo sizes w5100_write( CM_RMSR, 0x0A); // --> 4k for socket 0 and 1 w5100_write( CM_TMSR, 0x0A); // --> 4k for socket 0 and 1 w5100_write ( S0_MR, 0x01); // set Socket 0 as TCP w5100_write ( S0_PORT0, 0x13 ); // Port 5000 -> 0x1388 w5100_write ( S0_PORT1, 0x88 ); w5100_write ( S0_CR, CR_OPEN ); // issue Socket open command sock0_status = w5100_read(S0_SR); // request socket 0 status if ( sock0_status != SR_SOCK_INIT) { return sock0_status; } w5100_write ( S0_CR, CR_LISTEN ); // issue Socket listen command sock0_status = w5100_read(S0_SR); // request socket 0 status if ( sock0_status != SR_SOCK_LISTEN) { return sock0_status; } return sock0_status; } BOOL w5100_is_established() { if ( w5100_read(S0_SR) == SR_SOCK_ESTABLISHED ) { sock0_connection_established = true; } else { sock0_connection_established = false; } return sock0_connection_established; } U08 w5100_sock_status() { return w5100_read(S0_SR); } // getters of TX and RX registers // S0_TX_FSR U16 get_S0_TX_FSR() { U16 freesize; freesize=w5100_read(S0_TX_FSR1); freesize = freesize << 8; freesize += w5100_read(S0_TX_FSR0); return freesize; } // S0_TX_RD U16 get_S0_TX_RD() { U16 readpointer; readpointer=w5100_read(S0_TX_RD1); readpointer = readpointer << 8; readpointer += w5100_read(S0_TX_RD0); return readpointer; } // S0_TX_WR U16 get_S0_TX_WR() { U16 writepointer; writepointer=w5100_read(S0_TX_WR1); writepointer = writepointer << 8; writepointer += w5100_read(S0_TX_WR0); return writepointer; } // S0_RX_RSR U16 get_S0_RX_RSR() { U16 received_size; received_size=w5100_read(S0_RX_RSR1); received_size = received_size << 8; received_size += w5100_read(S0_RX_RSR0); return received_size; } // S0_RX_RD U16 get_S0_RX_RD() { U16 readpointer; readpointer=w5100_read(S0_RX_RD1); readpointer = readpointer << 8; readpointer += w5100_read(S0_RX_RD0); return readpointer; } // setters for some RX and TX registers // S0_TX_WR void set_S0_TX_WR(U16 value) { U08 high_byte = (value>>8); U08 low_byte = (value<<8)>>8; w5100_write(S0_TX_WR1, high_byte); w5100_write(S0_TX_WR0, low_byte); } // S0_TX_RD void set_S0_RX_RD(U16 value) { U08 high_byte = (value>>8); U08 low_byte = (value<<8)>>8; w5100_write(S0_TX_RD1, high_byte); w5100_write(S0_TX_RD0, low_byte); } U08 w5100_get_RX(U08 NumBytes, BOOL send_ACK) { U16 size = get_S0_RX_RSR(); U16 upper_size, lower_size; if (NumBytes > ETH_READ_BUFFER_SIZE) { NumBytes = ETH_READ_BUFFER_SIZE; } if (size == 0) { return 0; } else if ( size < NumBytes ) { NumBytes = size; } // now calculate the offset address // calculated according to W5100 datasheet page: 43 U16 last_RX_read_pointer = get_S0_RX_RD(); U16 offset = last_RX_read_pointer & S0_RX_MASK; U16 start_address = S0_RX_BASE + offset; if ((offset + NumBytes) > (S0_RX_MASK + 1) ) // if data is turned over in RX-mem { upper_size = (S0_RX_MASK + 1) - offset; lower_size = NumBytes - upper_size; for (U08 i = 0; i < upper_size; ++i) { eth_read_buffer[i] = w5100_read(start_address + i); } for (U08 i = 0; i < lower_size; ++i) { eth_read_buffer[upper_size + i] = w5100_read(S0_RX_BASE + i); } } else // if not data turn over in RX-mem { for (U08 i = 0; i < NumBytes; ++i) { eth_read_buffer[i] = w5100_read(start_address + i); } } // inform W5100 about how much data was read out. set_S0_RX_RD(last_RX_read_pointer + NumBytes); // if user wishes, W5100 may inform peer about receiption. // this should be done quickly, otherwise timeout may occur on // peer side, and peer retransmitts or so ... // // maybe it is necessary to acknowledge receiption very early. // I think there is an option in Socket mode register for this. if (send_ACK) { w5100_write ( S0_CR, CR_RECV ); } return NumBytes; } // returns number of words, transmitted into TX - buffer. U08 w5100_set_TX(U08 NumBytes) { U16 freesize = get_S0_TX_FSR(); if (freesize == 0) { return 0; } if (freesize < NumBytes) { NumBytes = freesize; } U16 last_TX_write_pointer = get_S0_TX_WR(); U16 offset = last_TX_write_pointer & S0_TX_MASK; U16 start_address = S0_TX_BASE + offset; U16 upper_size, lower_size; if (NumBytes > ETH_READ_BUFFER_SIZE) { NumBytes = ETH_READ_BUFFER_SIZE; } if (freesize == 0) { return 0; } else if ( freesize < NumBytes ) { NumBytes = freesize; } // now calculate the offset address // calculated according to W5100 datasheet page: 43 if ((offset + NumBytes) > (S0_RX_MASK + 1) ) // if data is turned over in RX-mem { upper_size = (S0_RX_MASK + 1) - offset; lower_size = NumBytes - upper_size; for (U08 i = 0; i < upper_size; ++i) { eth_read_buffer[i] = w5100_read(start_address + i); } for (U08 i = 0; i < lower_size; ++i) { eth_read_buffer[upper_size + i] = w5100_read(S0_RX_BASE + i); } } else // if not data turn over in RX-mem { for (U08 i = 0; i < NumBytes; ++i) { eth_read_buffer[i] = w5100_read(start_address + i); } } // inform W5100 about how much data was read out. set_S0_RX_RD(last_TX_write_pointer + NumBytes); return NumBytes; }