mirror of
https://github.com/EranMorkon/AMTS.git
synced 2023-12-28 16:48:38 +00:00
Ethernet Shield code
This commit is contained in:
parent
496209fb46
commit
f3d70e65a8
7 changed files with 1158 additions and 2 deletions
115
Mieke/SW/ETH/main.c
Normal file
115
Mieke/SW/ETH/main.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
Ethernet shield test program
|
||||
Copyright (C) 2018 Andreas Mieke
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "stm32f10x.h"
|
||||
#include "stm32f10x_usart.h" // Keil::Device:StdPeriph Drivers:USART
|
||||
|
||||
#include "w5100.h"
|
||||
#include "socket.h"
|
||||
|
||||
#include "string.h"
|
||||
|
||||
#define BUFFLEN 256
|
||||
|
||||
// Socket (TCP) with ID 1
|
||||
SOCKET tcp = 1;
|
||||
uint8_t buffer[BUFFLEN] = {0};
|
||||
uint8_t len = 0;
|
||||
|
||||
void USART_SendString(USART_TypeDef *USARTx, uint8_t *str)
|
||||
{
|
||||
// Send a string character by character over UART
|
||||
while(*str) {
|
||||
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
|
||||
USART_SendData(USARTx, *str++);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Enable USART 1 and GPIOA clock
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
|
||||
// Create gpio strct and set default values
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// Set PA9 to alternate function push pull (TxD)
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_9;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Set PA10 to input floating (RxD)
|
||||
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
gpio.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Set up USART1
|
||||
USART_InitTypeDef usart;
|
||||
USART_StructInit(&usart);
|
||||
USART_Init(USART1, &usart);
|
||||
|
||||
// Set up USART1 clocks
|
||||
USART_ClockInitTypeDef usartclock;
|
||||
USART_ClockStructInit(&usartclock);
|
||||
USART_ClockInit(USART1, &usartclock);
|
||||
|
||||
// Enable USART1
|
||||
USART_Cmd(USART1, ENABLE);
|
||||
|
||||
// Initzialize Ethernet module
|
||||
ETH_init();
|
||||
|
||||
// Set gateway IP
|
||||
uint8_t gid[4] = {192, 168, 10, 1};
|
||||
|
||||
// Set subnet mask
|
||||
uint8_t sma[4] = {255, 255, 255, 0};
|
||||
|
||||
// Set MAC address (unused testing address space)
|
||||
uint8_t mac[6] = {0x1E, 0x8E, 0xA8, 0x88, 0x1C, 0xAA};
|
||||
|
||||
// Set source IP (IP of the Ethernet module)
|
||||
uint8_t sip[4] = {192, 168, 10, 2};
|
||||
|
||||
// Transmit all these values to the module
|
||||
ETH_set_gateway_IP(gid);
|
||||
ETH_set_subnet_mask(sma);
|
||||
ETH_set_mac(mac);
|
||||
ETH_set_IP(sip);
|
||||
|
||||
// Try to create a TCP socket on port 80 as long as it does not work
|
||||
do {
|
||||
ETH_socket(tcp, ETH_SMR_TCP, 80, 0);
|
||||
} while (ETH_socket_status(tcp) != ETH_SSR_INIT);
|
||||
|
||||
// Wait for the socket to finish creating
|
||||
while(!ETH_listen(tcp));
|
||||
|
||||
// Endless loop
|
||||
do {
|
||||
// Wait for data to be available
|
||||
while(ETH_recv_available(tcp) == 0);
|
||||
// Receive data
|
||||
buffer[ETH_recv(tcp, buffer, BUFFLEN)] = 0;
|
||||
// Send data to USART
|
||||
USART_SendString(USART1, buffer);
|
||||
// Send string over tcp
|
||||
ETH_send(tcp, "Hallo, Welt!", 12);
|
||||
} while (1);
|
||||
}
|
391
Mieke/SW/ETH/socket.c
Normal file
391
Mieke/SW/ETH/socket.c
Normal file
|
@ -0,0 +1,391 @@
|
|||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "socket.h"
|
||||
|
||||
// Check if address is a net addres 0.0.0.0
|
||||
#define is_net_addr(addr) ((addr[0] == 0x00) && \
|
||||
(addr[1] == 0x00) && \
|
||||
(addr[2] == 0x00) && \
|
||||
(addr[3] == 0x00))
|
||||
|
||||
// Check if address is broadcast address 255.255.255.255
|
||||
#define is_broadcast_addr(addr) ((addr[0] == 0xFF) && \
|
||||
(addr[1] == 0xFF) && \
|
||||
(addr[2] == 0xFF) && \
|
||||
(addr[3] == 0xFF))
|
||||
|
||||
// Check if port is valid (not 0)
|
||||
#define is_valid_port(port) (port != 0x00)
|
||||
|
||||
static uint16_t local_port;
|
||||
|
||||
uint8_t ETH_socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
|
||||
{
|
||||
// Check if protocol is supported
|
||||
if ((protocol == ETH_SMR_TCP) || (protocol == ETH_SMR_UDP) || (protocol == ETH_SMR_IPRAW) || (protocol == ETH_SMR_MACRAW) || (protocol == ETH_SMR_PPPoE))
|
||||
{
|
||||
// Close socket, if open
|
||||
ETH_close(s);
|
||||
// Set the mode register to the protocol, plus eventual flags
|
||||
ETH_writeSnMR(s, protocol | flag);
|
||||
if (port != 0) {
|
||||
// If port is not 0 (0 on client mode) write port to the port register
|
||||
ETH_writeSnPORT(s, port);
|
||||
}
|
||||
else {
|
||||
// Write a random port to the port register (for client mode)
|
||||
local_port++;
|
||||
ETH_writeSnPORT(s, local_port);
|
||||
}
|
||||
|
||||
// Execute the open socket command
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_OPEN);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ETH_socket_status(SOCKET s)
|
||||
{
|
||||
// Read the status register and return it
|
||||
uint8_t tmp = ETH_readSnSR(s);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ETH_close(SOCKET s)
|
||||
{
|
||||
// Execute close socket and disable interrupts
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_CLOSE);
|
||||
ETH_writeSnIR(s, 0xFF);
|
||||
}
|
||||
|
||||
uint8_t ETH_connect(SOCKET s, uint8_t * addr, uint16_t port)
|
||||
{
|
||||
// Check if port and address is valid
|
||||
if (is_net_addr(addr) || is_broadcast_addr(addr) || !is_valid_port(port))
|
||||
return 0;
|
||||
|
||||
// Write IP to destination register
|
||||
ETH_writeSnDIPR(s, addr);
|
||||
// Write port to destination register
|
||||
ETH_writeSnDPORT(s, port);
|
||||
// Execute connect
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_CONNECT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ETH_disconnect(SOCKET s)
|
||||
{
|
||||
// Execute disconnect
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_DISCON);
|
||||
}
|
||||
|
||||
uint8_t ETH_listen(SOCKET s)
|
||||
{
|
||||
// If state is not initzialized, return
|
||||
if (ETH_readSnSR(s) != ETH_SSR_INIT) {
|
||||
return 0;
|
||||
}
|
||||
// Execute the listen command
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_LISTEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t ETH_send(SOCKET s, const uint8_t * buf, uint16_t len)
|
||||
{
|
||||
uint8_t status=0;
|
||||
uint16_t ret=0;
|
||||
uint16_t freesize=0;
|
||||
|
||||
// If data is bigger then Tx memory, split it
|
||||
if (len > ETH_SSIZE)
|
||||
ret = ETH_SSIZE;
|
||||
else
|
||||
ret = len;
|
||||
|
||||
do
|
||||
{
|
||||
// Write data to Tx memory
|
||||
freesize = ETH_get_TX_free_size(s);
|
||||
status = ETH_readSnSR(s);
|
||||
if ((status != ETH_SSR_ESTABLISHED) && (status != ETH_SSR_CLOSE_WAIT))
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (freesize < ret);
|
||||
|
||||
// Start data processing and execute send command
|
||||
ETH_send_data_processing(s, (uint8_t *)buf, ret);
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_SEND);
|
||||
|
||||
// Check interrupt if everything is okay
|
||||
while ((ETH_readSnIR(s) & ETH_SIR_SEND_OK) != ETH_SIR_SEND_OK )
|
||||
{
|
||||
// If socket is closed set the state locally right
|
||||
if (ETH_readSnSR(s) == ETH_SSR_CLOSED )
|
||||
{
|
||||
ETH_close(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// Mark interrupt as handled
|
||||
ETH_writeSnIR(s, ETH_SIR_SEND_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int16_t ETH_recv(SOCKET s, uint8_t * buf, int16_t len)
|
||||
{
|
||||
// Check remaining size
|
||||
int16_t ret = ETH_get_RX_received_size(s);
|
||||
if (ret == 0)
|
||||
{
|
||||
// Read status
|
||||
uint8_t status = ETH_readSnSR(s);
|
||||
// If status is wrong, return 0 read bytes
|
||||
if (status == ETH_SSR_LISTEN || status == ETH_SSR_CLOSED || status == ETH_SSR_CLOSE_WAIT)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return -1 if there is nothing to read
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
// If there is more to read then we have space, just read to the supplied limit
|
||||
else if (ret > len)
|
||||
{
|
||||
ret = len;
|
||||
}
|
||||
|
||||
// If there is data to read and we have space, beginn processing and reading
|
||||
if (ret > 0)
|
||||
{
|
||||
ETH_recv_data_processing(s, buf, ret, 0x00);
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_RECV);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int16_t ETH_recv_available(SOCKET s)
|
||||
{
|
||||
// Check if data is available to read
|
||||
return ETH_get_RX_received_size(s);
|
||||
}
|
||||
|
||||
uint16_t ETH_peek(SOCKET s, uint8_t *buf)
|
||||
{
|
||||
// Receive one byte
|
||||
ETH_recv_data_processing(s, buf, 1, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t ETH_sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
|
||||
{
|
||||
uint16_t ret=0;
|
||||
|
||||
// If write size is bigger then memory, limit to memory
|
||||
if (len > ETH_SSIZE) ret = ETH_SSIZE;
|
||||
else ret = len;
|
||||
|
||||
// Check if address and port is right
|
||||
if (is_net_addr(addr) || !is_valid_port(port) || ret == 0) {
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set address and port to send to
|
||||
ETH_writeSnDIPR(s, addr);
|
||||
ETH_writeSnDPORT(s, port);
|
||||
|
||||
// Process data and send it
|
||||
ETH_send_data_processing(s, (uint8_t *)buf, ret);
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_SEND);
|
||||
|
||||
// Wait for the data to be sent
|
||||
while ((ETH_readSnIR(s) & ETH_SIR_SEND_OK) != ETH_SIR_SEND_OK)
|
||||
{
|
||||
// If time out reset send and timout interrupts
|
||||
if (ETH_readSnIR(s) & ETH_SIR_TIMEOUT)
|
||||
{
|
||||
ETH_writeSnIR(s, (ETH_SIR_SEND_OK | ETH_SIR_TIMEOUT));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset send ok interrupt
|
||||
ETH_writeSnIR(s, ETH_SIR_SEND_OK);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t ETH_recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
|
||||
{
|
||||
uint8_t head[8];
|
||||
uint16_t data_len=0;
|
||||
uint16_t ptr=0;
|
||||
|
||||
// Check if there is something to receive
|
||||
if (len > 0)
|
||||
{
|
||||
// Get the receive pointer
|
||||
ptr = ETH_readSnRX_RD(s);
|
||||
// Handle receiving according to socket type
|
||||
switch (ETH_readSnMR(s) & 0x07)
|
||||
{
|
||||
case ETH_SMR_UDP :
|
||||
ETH_read_data(s, ptr, head, 0x08);
|
||||
ptr += 8;
|
||||
addr[0] = head[0];
|
||||
addr[1] = head[1];
|
||||
addr[2] = head[2];
|
||||
addr[3] = head[3];
|
||||
*port = head[4];
|
||||
*port = (*port << 8) + head[5];
|
||||
data_len = head[6];
|
||||
data_len = (data_len << 8) + head[7];
|
||||
|
||||
ETH_read_data(s, ptr, buf, data_len);
|
||||
ptr += data_len;
|
||||
|
||||
ETH_writeSnRX_RD(s, ptr);
|
||||
break;
|
||||
|
||||
case ETH_SMR_IPRAW :
|
||||
ETH_read_data(s, ptr, head, 0x06);
|
||||
ptr += 6;
|
||||
|
||||
addr[0] = head[0];
|
||||
addr[1] = head[1];
|
||||
addr[2] = head[2];
|
||||
addr[3] = head[3];
|
||||
data_len = head[4];
|
||||
data_len = (data_len << 8) + head[5];
|
||||
|
||||
ETH_read_data(s, ptr, buf, data_len);
|
||||
ptr += data_len;
|
||||
|
||||
ETH_writeSnRX_RD(s, ptr);
|
||||
break;
|
||||
|
||||
case ETH_SMR_MACRAW:
|
||||
ETH_read_data(s, ptr, head, 2);
|
||||
ptr+=2;
|
||||
data_len = head[0];
|
||||
data_len = (data_len<<8) + head[1] - 2;
|
||||
|
||||
ETH_read_data(s, ptr, buf, data_len);
|
||||
ptr += data_len;
|
||||
ETH_writeSnRX_RD(s, ptr);
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_RECV);
|
||||
}
|
||||
return data_len;
|
||||
}
|
||||
|
||||
void ETH_flush(SOCKET s)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
uint16_t ETH_igmpsend(SOCKET s, const uint8_t * buf, uint16_t len)
|
||||
{
|
||||
uint16_t ret=0;
|
||||
|
||||
if (len > ETH_SSIZE)
|
||||
ret = ETH_SSIZE;
|
||||
else
|
||||
ret = len;
|
||||
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
// Process and send IGMP data
|
||||
ETH_send_data_processing(s, (uint8_t *)buf, ret);
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_SEND);
|
||||
|
||||
// Wairt for data to be sent or timeout
|
||||
while ((ETH_readSnIR(s) & ETH_SIR_SEND_OK) != ETH_SIR_SEND_OK)
|
||||
{
|
||||
if (ETH_readSnIR(s) & ETH_SIR_TIMEOUT)
|
||||
{
|
||||
ETH_close(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset interrupt
|
||||
ETH_writeSnIR(s, ETH_SIR_SEND_OK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ETH_start_UDP(SOCKET s, uint8_t* addr, uint16_t port)
|
||||
{
|
||||
// Check if address and port are valid
|
||||
if (is_net_addr(addr) || !is_valid_port(port))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write IP and port
|
||||
ETH_writeSnDIPR(s, addr);
|
||||
ETH_writeSnDPORT(s, port);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ETH_buffer_data(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
if (len > ETH_get_TX_free_size(s))
|
||||
{
|
||||
ret = ETH_get_TX_free_size(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = len;
|
||||
}
|
||||
ETH_send_data_processing_offset(s, offset, buf, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ETH_send_UDP(SOCKET s)
|
||||
{
|
||||
ETH_exec_socket_cmd(s, ETH_SCR_SEND);
|
||||
|
||||
while ((ETH_readSnIR(s) & ETH_SIR_SEND_OK) != ETH_SIR_SEND_OK)
|
||||
{
|
||||
if (ETH_readSnIR(s) & ETH_SIR_TIMEOUT)
|
||||
{
|
||||
ETH_writeSnIR(s, (ETH_SIR_SEND_OK | ETH_SIR_TIMEOUT));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ETH_writeSnIR(s, ETH_SIR_SEND_OK);
|
||||
return 1;
|
||||
}
|
45
Mieke/SW/ETH/socket.h
Normal file
45
Mieke/SW/ETH/socket.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SOCKET_H
|
||||
#define __SOCKET_H
|
||||
|
||||
#include "w5100.h"
|
||||
|
||||
uint8_t ETH_socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag);
|
||||
uint8_t ETH_socket_status(SOCKET s);
|
||||
void ETH_close(SOCKET s);
|
||||
uint8_t ETH_connect(SOCKET s, uint8_t * addr, uint16_t port);
|
||||
void ETH_disconnect(SOCKET s);
|
||||
uint8_t ETH_listen(SOCKET s);
|
||||
uint16_t ETH_send(SOCKET s, const uint8_t * buf, uint16_t len);
|
||||
int16_t ETH_recv(SOCKET s, uint8_t * buf, int16_t len);
|
||||
int16_t ETH_recv_available(SOCKET s);
|
||||
uint16_t ETH_peek(SOCKET s, uint8_t *buf);
|
||||
uint16_t ETH_sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port);
|
||||
uint16_t ETH_recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port);
|
||||
void ETH_flush(SOCKET s);
|
||||
|
||||
uint16_t ETH_igmpsend(SOCKET s, const uint8_t * buf, uint16_t len);
|
||||
|
||||
int ETH_start_UDP(SOCKET s, uint8_t* addr, uint16_t port);
|
||||
uint16_t ETH_buffer_data(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len);
|
||||
int ETH_send_UDP(SOCKET s);
|
||||
|
||||
#endif
|
256
Mieke/SW/ETH/w5100.c
Normal file
256
Mieke/SW/ETH/w5100.c
Normal file
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "w5100.h"
|
||||
|
||||
uint16_t ETH_SBASE[ETH_SOCKETS]; // Tx buffer base address
|
||||
uint16_t ETH_RBASE[ETH_SOCKETS]; // Rx buffer base address
|
||||
|
||||
#define TX_RX_MAX_BUF_SIZE 2048
|
||||
#define TX_BUF 0x1100
|
||||
#define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE)
|
||||
|
||||
#define ETH_TXBUF_BASE 0x4000
|
||||
#define ETH_RXBUF_BASE 0x6000
|
||||
|
||||
void SPI_SetSS(void)
|
||||
{
|
||||
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
|
||||
}
|
||||
|
||||
void SPI_ResetSS(void)
|
||||
{
|
||||
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) != RESET);
|
||||
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
|
||||
}
|
||||
|
||||
uint8_t SPI_WriteRead(uint8_t write)
|
||||
{
|
||||
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
|
||||
SPI1->DR = write;
|
||||
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
|
||||
return SPI1->DR;
|
||||
}
|
||||
|
||||
void ETH_init(void)
|
||||
{
|
||||
// Port init stuff
|
||||
// PA5 -> SCK
|
||||
// PA6 -> MISO
|
||||
// PA7 -> MOSI
|
||||
// PC8 -> /SS
|
||||
|
||||
// Set RCC Registers for GPIOA/C
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
|
||||
|
||||
// Init gpio structure to default values
|
||||
GPIO_InitTypeDef gpio;
|
||||
GPIO_StructInit(&gpio);
|
||||
|
||||
// Set PA5 to alternate function PushPull
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_5;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Set PA7 to alternate function push pull
|
||||
gpio.GPIO_Pin = GPIO_Pin_7;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Set PC8 to push pull
|
||||
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
gpio.GPIO_Pin = GPIO_Pin_8;
|
||||
GPIO_Init(GPIOC, &gpio);
|
||||
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
|
||||
|
||||
// Set PA6 to input floating
|
||||
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
gpio.GPIO_Pin = GPIO_Pin_6;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
// Init SPI engine
|
||||
// Init struct to default values
|
||||
SPI_InitTypeDef spi;
|
||||
SPI_StructInit(&spi);
|
||||
|
||||
// We are master
|
||||
spi.SPI_Mode = SPI_Mode_Master;
|
||||
spi.SPI_NSS = SPI_NSS_Soft;
|
||||
//spi.SPI_CPHA = SPI_CPHA_2Edge;
|
||||
spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
|
||||
|
||||
// Write the registers
|
||||
SPI_Init(SPI1, &spi);
|
||||
|
||||
// Enable SPI1
|
||||
SPI_Cmd(SPI1, ENABLE);
|
||||
|
||||
for(uint16_t i = 0; i < 65535; i++);
|
||||
|
||||
ETH_writeMR(ETH_MR_RST);
|
||||
ETH_writeRMSR(0x55);
|
||||
ETH_writeTMSR(0x55);
|
||||
|
||||
for (int i=0; i<MAX_SOCK_NUM; i++) {
|
||||
ETH_SBASE[i] = ETH_TXBUF_BASE + ETH_SSIZE * i;
|
||||
ETH_RBASE[i] = ETH_RXBUF_BASE + ETH_RSIZE * i;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ETH_write_8(uint16_t addr, uint8_t data)
|
||||
{
|
||||
SPI_SetSS();
|
||||
SPI_WriteRead(0xF0);
|
||||
SPI_WriteRead(addr >> 8);
|
||||
SPI_WriteRead(addr & 0xFF);
|
||||
SPI_WriteRead(data);
|
||||
SPI_ResetSS();
|
||||
return 8;
|
||||
}
|
||||
|
||||
uint16_t ETH_write_n(uint16_t addr, const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
SPI_SetSS();
|
||||
SPI_WriteRead(0xF0);
|
||||
SPI_WriteRead(addr >> 8);
|
||||
SPI_WriteRead(addr & 0xFF);
|
||||
addr++;
|
||||
SPI_WriteRead(buf[i]);
|
||||
SPI_ResetSS();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
uint8_t ETH_read_8(uint16_t addr)
|
||||
{
|
||||
uint8_t data;
|
||||
SPI_SetSS();
|
||||
SPI_WriteRead(0x0F);
|
||||
SPI_WriteRead(addr >> 8);
|
||||
SPI_WriteRead(addr & 0xFF);
|
||||
data = SPI_WriteRead(0x00);
|
||||
SPI_ResetSS();
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t ETH_read_n(uint16_t addr, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
SPI_SetSS();
|
||||
SPI_WriteRead(0x0F);
|
||||
SPI_WriteRead(addr >> 8);
|
||||
SPI_WriteRead(addr & 0xFF);
|
||||
addr++;
|
||||
buf[i] = SPI_WriteRead(0x00);
|
||||
SPI_ResetSS();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
uint16_t ETH_get_TX_free_size(SOCKET s)
|
||||
{
|
||||
uint16_t val=0, val1=0;
|
||||
do {
|
||||
val1 = ETH_readSnTX_FSR(s);
|
||||
if (val1 != 0)
|
||||
val = ETH_readSnTX_FSR(s);
|
||||
}
|
||||
while (val != val1);
|
||||
return val;
|
||||
}
|
||||
|
||||
uint16_t ETH_get_RX_received_size(SOCKET s)
|
||||
{
|
||||
uint16_t val=0,val1=0;
|
||||
do {
|
||||
val1 = ETH_readSnRX_RSR(s);
|
||||
if (val1 != 0)
|
||||
val = ETH_readSnRX_RSR(s);
|
||||
}
|
||||
while (val != val1);
|
||||
return val;
|
||||
}
|
||||
|
||||
void ETH_read_data(SOCKET s, volatile uint16_t src, volatile uint8_t * dst, uint16_t len)
|
||||
{
|
||||
uint16_t size;
|
||||
uint16_t src_mask;
|
||||
uint16_t src_ptr;
|
||||
|
||||
src_mask = src & ETH_RMASK;
|
||||
src_ptr = ETH_RBASE[s] + src_mask;
|
||||
|
||||
if( (src_mask + len) > ETH_RSIZE )
|
||||
{
|
||||
size = ETH_RSIZE - src_mask;
|
||||
ETH_read_n(src_ptr, (uint8_t *)dst, size);
|
||||
dst += size;
|
||||
ETH_read_n(ETH_RBASE[s], (uint8_t *) dst, len - size);
|
||||
}
|
||||
else
|
||||
ETH_read_n(src_ptr, (uint8_t *) dst, len);
|
||||
}
|
||||
|
||||
void ETH_send_data_processing(SOCKET s, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
ETH_send_data_processing_offset(s, 0, data, len);
|
||||
}
|
||||
|
||||
void ETH_send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
uint16_t ptr = ETH_readSnTX_WR(s);
|
||||
ptr += data_offset;
|
||||
uint16_t offset = ptr & ETH_SMASK;
|
||||
uint16_t dstAddr = offset + ETH_SBASE[s];
|
||||
|
||||
if (offset + len > ETH_SSIZE)
|
||||
{
|
||||
uint16_t size = ETH_SSIZE - offset;
|
||||
ETH_write_n(dstAddr, data, size);
|
||||
ETH_write_n(ETH_SBASE[s], data + size, len - size);
|
||||
}
|
||||
else {
|
||||
ETH_write_n(dstAddr, data, len);
|
||||
}
|
||||
|
||||
ptr += len;
|
||||
ETH_writeSnTX_WR(s, ptr);
|
||||
}
|
||||
|
||||
void ETH_recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek)
|
||||
{
|
||||
uint16_t ptr;
|
||||
ptr = ETH_readSnRX_RD(s);
|
||||
ETH_read_data(s, ptr, data, len);
|
||||
if (!peek)
|
||||
{
|
||||
ptr += len;
|
||||
ETH_writeSnRX_RD(s, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void ETH_exec_socket_cmd(SOCKET s, uint8_t cmd)
|
||||
{
|
||||
ETH_writeSnCR(s, cmd);
|
||||
while(ETH_readSnCR(s)) {
|
||||
// Wait for command to be executed
|
||||
}
|
||||
}
|
302
Mieke/SW/ETH/w5100.h
Normal file
302
Mieke/SW/ETH/w5100.h
Normal file
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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
|
Loading…
Add table
Add a link
Reference in a new issue