Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • avn/swd/skyward-boardcore
  • emilio.corigliano/skyward-boardcore
  • ettore.pane/skyward-boardcore
  • giulia.facchi/skyward-boardcore
  • valerio.flamminii/skyward-boardcore
  • nicolo.caruso/skyward-boardcore
6 results
Select Git revision
Show changes
Showing
with 0 additions and 4806 deletions
/* Copyright (c) 2016-2017 Skyward Experimental Rocketry
* Author: Silvano Seva
*
* 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 "PacketBuffer.h"
#include <utils/Debug.h>
using namespace std;
using namespace miosix;
PacketBuffer::PacketBuffer(size_t storageSize)
: storageSize(storageSize), usedSize(0), writeIndex(0), readIndex(0),
valid(true)
{
#ifndef __NO_EXCEPTIONS
try
{
buffer = new uint8_t[storageSize];
}
catch (std::bad_alloc& exc)
{
TRACE("bad alloc!\n");
valid = false;
}
#else
buffer = new (std::nothrow) uint8_t[storageSize];
if (buffer == nullptr)
{
valid = false;
}
#endif
}
PacketBuffer::~PacketBuffer()
{
if (valid)
delete[] buffer;
}
bool PacketBuffer::push(packet_header_t& header, const uint8_t* payload)
{
if (!valid)
return false;
size_t packetSize = sizeof(packet_header_t) + header.payloadSize;
// Simple technique to avoid ring buffer writeIndex slip ahead readIndex:
// we keep track of the amount of space used and we reject a new incoming
// packet if usedSize + packetSize is greater that the ring buffer size.
if (usedSize + packetSize >= storageSize)
return false;
// to store the packet into the ring buffer first copy the header
// and then copy the payload
{
Lock<FastMutex> l(mutex);
uint8_t* head = reinterpret_cast<uint8_t*>(&header);
for (unsigned int i = 0; i < sizeof(packet_header_t); i++)
{
buffer[(writeIndex + i) % storageSize] = head[i];
}
writeIndex = (writeIndex + sizeof(packet_header_t)) % storageSize;
for (unsigned int i = 0; i < header.payloadSize; i++)
{
buffer[(writeIndex + i) % storageSize] = payload[i];
}
writeIndex = (writeIndex + header.payloadSize) % storageSize;
usedSize += packetSize;
}
return true;
}
packet_header_t PacketBuffer::getHeader()
{
packet_header_t header = {};
uint8_t* dest = reinterpret_cast<uint8_t*>(&header);
memset(dest, 0x00, sizeof(packet_header_t));
if (valid)
{
Lock<FastMutex> l(mutex);
for (unsigned int i = 0; i < sizeof(packet_header_t); i++)
dest[i] = buffer[(readIndex + i) % storageSize];
}
return header;
}
void PacketBuffer::getData(uint8_t* data)
{
if (!valid)
return;
/* Packet size is stored in header, so first get the payloadSize.
* The data is stored sizeof(packet_header_t) bytes next the read pointer,
* since a packet is stored as header followed by payload, so we have to
* add sizeof(packet_header_t) to the read pointer to reach the first data
* byte
*/
packet_header_t frontHead = getHeader();
{
Lock<FastMutex> l(mutex);
int start = readIndex + sizeof(packet_header_t);
for (unsigned int i = 0; i < frontHead.payloadSize; i++)
{
data[i] = buffer[(start + i) % storageSize];
}
}
}
void PacketBuffer::popFront()
{
if ((!valid) || empty()) // this means that list is empty
return;
/* Popping a packet out of list simply means move the readIndex forward
* of the size of the packet at list's head.
* The size of a packet is made of two parts: a fixed one which is
* constituded by the size of IP address, port and packet length fields
* and a variable one that is the size of the payload. The latter is stored
* into the len field of the packet.
* What we do here is gather the fixed and variable sizes and sum them
* together to obtain the readIndex's needed increment
*/
packet_header_t head = getHeader();
size_t packetSize = sizeof(packet_header_t) + head.payloadSize;
{
Lock<FastMutex> l(mutex);
readIndex = (readIndex + packetSize) % storageSize;
usedSize -= packetSize;
}
}
bool PacketBuffer::empty()
{
Lock<FastMutex> l(mutex);
return usedSize == 0;
}
/* Copyright (c) 2016-2017 Skyward Experimental Rocketry
* Author: Silvano Seva
*
* 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 "UdpManager.h"
using namespace std;
using namespace miosix;
void __attribute__((naked)) EXTI1_IRQHandler()
{
saveContext();
asm volatile("bl _Z13EXTIrqHandlerv");
restoreContext();
}
void __attribute__((used)) EXTIrqHandler()
{
EXTI->PR |= EXTI_PR_PR1;
Singleton<UdpManager>::getInstance().phyIrqHandler();
}
void _evt_mgmt_thread(void* args)
{
Singleton<UdpManager>::getInstance().evtQueue.run();
}
UdpManager::UdpManager()
{
eth::int1::mode(Mode::INPUT);
// Configure STM32 to generate an interrupt on
// falling edge of chip's INT line
{
FastInterruptDisableLock dLock;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
RCC_SYNC();
}
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI1_PC;
EXTI->IMR |= EXTI_IMR_MR1;
EXTI->FTSR |= EXTI_FTSR_TR1;
NVIC_SetPriority(EXTI1_IRQn, 10);
NVIC_ClearPendingIRQ(EXTI1_IRQn);
NVIC_EnableIRQ(EXTI1_IRQn);
phy.setModeReg(0x00);
phy.setSocketInterruptMask(0xFF);
txBuffer = new PacketBuffer(TX_BUF_SIZE);
rxBuffer = new PacketBuffer(RX_BUF_SIZE);
wdt->setDuration(TX_TIMEOUT);
wdt->setCallback(bind(&UdpManager::wdtIrqHandler, this));
if (!txBuffer->isValid() || !rxBuffer->isValid())
{
// TODO log!
}
else
{
Thread::create(_evt_mgmt_thread, 1024);
}
}
UdpManager::~UdpManager()
{
delete txBuffer;
delete rxBuffer;
}
void UdpManager::setTxPort(uint16_t port)
{
// Open transmitting socket
phy.setSocketModeReg(PHY_TX_SOCK_NUM, SOCKn_MR_UDP);
phy.setSocketSourcePort(PHY_TX_SOCK_NUM, port);
// Enable timeout & send ok interrupts
phy.setSocketInterruptMaskReg(PHY_TX_SOCK_NUM, 0x18);
phy.setSocketCommandReg(PHY_TX_SOCK_NUM, SOCKn_CR_OPEN);
}
void UdpManager::setRxPort(uint16_t port)
{
// Open receiving socket
phy.setSocketModeReg(PHY_RX_SOCK_NUM, SOCKn_MR_UDP);
phy.setSocketSourcePort(PHY_RX_SOCK_NUM, port);
// Enable recv interrupt only
phy.setSocketInterruptMaskReg(PHY_RX_SOCK_NUM, 0x04);
phy.setSocketCommandReg(PHY_RX_SOCK_NUM, SOCKn_CR_OPEN);
phy.setSocketCommandReg(PHY_RX_SOCK_NUM, SOCKn_CR_RECV);
}
/** Legacy code, uncomment if we want tx @ port and rx @ port+1 **/
// void UdpManager::setPort(uint16_t port) {
//
// //Open transmitting socket
// phy.setSocketModeReg(PHY_TX_SOCK_NUM,SOCKn_MR_UDP);
// phy.setSocketSourcePort(PHY_TX_SOCK_NUM,port);
// // Enable timeout & send ok interrupts
// phy.setSocketInterruptMaskReg(PHY_TX_SOCK_NUM,0x18);
// phy.setSocketCommandReg(PHY_TX_SOCK_NUM,SOCKn_CR_OPEN);
//
// //Open receiving socket
// phy.setSocketModeReg(PHY_RX_SOCK_NUM,SOCKn_MR_UDP);
// phy.setSocketSourcePort(PHY_RX_SOCK_NUM,port+1);
// // Enable recv interrupt only
// phy.setSocketInterruptMaskReg(PHY_RX_SOCK_NUM,0x04);
// phy.setSocketCommandReg(PHY_RX_SOCK_NUM,SOCKn_CR_OPEN);
// phy.setSocketCommandReg(PHY_RX_SOCK_NUM,SOCKn_CR_RECV);
// }
bool UdpManager::newReceivedPackets() { return !rxBuffer->empty(); }
void UdpManager::sendPacketTo(const uint8_t* ip, const uint16_t port,
const void* data, size_t len)
{
packet_header_t header;
header.ipAddress = *(reinterpret_cast<const uint32_t*>(ip));
header.port = port;
header.payloadSize = len;
bool wasEmpty = txBuffer->empty();
bool ok = txBuffer->push(header, reinterpret_cast<const uint8_t*>(data));
if (!ok)
{
// TODO: better failure logging
puts("UDP->sendPacketTo: failed to enqueue the new packet\n");
}
else if (wasEmpty)
{
bool pok =
evtQueue.postNonBlocking(bind(&UdpManager::tx_handler, this));
if (!pok)
{
// TODO: better failure logging
puts(
"UDP->sendPacketTo: job queue full."
"Failed to post tx_handler.\n");
}
}
}
size_t UdpManager::recvPacketSize()
{
if (rxBuffer->empty())
return 0;
packet_header_t hdr = rxBuffer->getHeader();
return hdr.payloadSize;
}
void UdpManager::readPacket(uint8_t* ip, uint16_t& port, void* data)
{
packet_header_t header = rxBuffer->getHeader();
// IP address is 4 bytes long
memcpy(ip, reinterpret_cast<uint8_t*>(&(header.ipAddress)), 4);
port = header.port;
// The copy of the exact number of bytes is guaranteed by getData. We only
// have to be sure that the receiving buffer has the right capacity,
// which is given by UdpManager::recvPacketSize()
rxBuffer->getData(reinterpret_cast<uint8_t*>(data));
rxBuffer->popFront();
}
/** Interrupt and event handlers **/
void UdpManager::phyIrqHandler()
{
bool hppw = false;
uint8_t sockInt = phy.readSocketInterruptReg();
// TX socket interrupts management
if (sockInt & (0x01 << PHY_TX_SOCK_NUM))
{
// Stopping watchdog inside an IRQ is safe to do
wdt->stop();
uint8_t txFlags = phy.getSocketInterruptReg(PHY_TX_SOCK_NUM);
phy.clearSocketInterruptReg(PHY_TX_SOCK_NUM);
// Send OK interrupt flag set
if (txFlags & 0x10)
evtQueue.IRQpost(bind(&UdpManager::tx_end_handler, this), hppw);
// Timeout flag set, problems with ARP
if (txFlags & 0x08)
evtQueue.IRQpost(bind(&UdpManager::timeout_handler, this), hppw);
}
// RX socket interrupts management
if (sockInt & (0x01 << PHY_RX_SOCK_NUM))
{
uint8_t rxFlags = phy.getSocketInterruptReg(PHY_RX_SOCK_NUM);
phy.clearSocketInterruptReg(PHY_RX_SOCK_NUM);
if (rxFlags & 0x04)
evtQueue.IRQpost(bind(&UdpManager::rx_handler, this), hppw);
}
if (hppw)
Scheduler::IRQfindNextThread();
}
void UdpManager::wdtIrqHandler()
{
bool hppw = false;
evtQueue.IRQpost(bind(&UdpManager::timeout_handler, this), hppw);
if (hppw)
Scheduler::IRQfindNextThread();
}
void UdpManager::tx_handler()
{
if (txBuffer->empty())
return;
packet_header_t header = txBuffer->getHeader();
uint8_t* addr = reinterpret_cast<uint8_t*>(&header.ipAddress);
uint8_t payload[header.payloadSize];
txBuffer->getData(payload);
txBuffer->popFront();
phy.setSocketDestIp(PHY_TX_SOCK_NUM, addr);
phy.setSocketDestPort(PHY_TX_SOCK_NUM, header.port);
phy.writeData(PHY_TX_SOCK_NUM, payload, header.payloadSize);
phy.setSocketCommandReg(PHY_TX_SOCK_NUM, SOCKn_CR_SEND);
wdt->clear();
wdt->start();
}
void UdpManager::tx_end_handler()
{
if (txBuffer->empty())
return;
bool ok = evtQueue.postNonBlocking(bind(&UdpManager::tx_handler, this));
if (!ok)
{
// TODO: better failure logging
puts("UDP->tx_end_handler:job queue full, failed to post tx_handler");
}
}
void UdpManager::timeout_handler()
{
if (wdt->expired())
puts("Tx timeout due to watchdog expiration");
else
puts("Tx timeout due to phy error");
bool ok = evtQueue.postNonBlocking(bind(&UdpManager::tx_end_handler, this));
if (!ok)
puts(
"UDP->timeout_handler: job queue full, "
"failed to post tx_end_handler");
}
void UdpManager::rx_handler()
{
// get new packet len, in bytes
uint16_t len = phy.getReceivedSize(PHY_RX_SOCK_NUM);
uint8_t buffer[len];
// read all the packet, that is made of so30urceIp + sourcePort +
// payload len + payload. Since the header length is of 8 bytes,
// the payload length is len - 8 bytes! :-)
phy.readData(PHY_RX_SOCK_NUM, buffer, len);
// Set back to listening mode
phy.setSocketCommandReg(PHY_RX_SOCK_NUM, SOCKn_CR_RECV);
packet_header_t header;
memcpy(reinterpret_cast<uint8_t*>(&(header.ipAddress)), buffer, 4);
header.port = (buffer[4] << 8) | buffer[5];
header.payloadSize = len - 8;
bool pushOk = rxBuffer->push(header, &buffer[8]);
if (!pushOk)
puts(
"rx_handler error: rxBuffer is full,"
"cannot enqueue a new packet!");
}
/* Copyright (c) 2016-2017 Skyward Experimental Rocketry
* Author: Silvano Seva
*
* 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.
*/
#pragma once
#include <Common.h>
#include <Singleton.h>
#include <W5200/w5200.h>
#include <e20/e20.h>
#include "PacketBuffer.h"
#include "WatchdogTimer.h"
class UdpManager : Singleton<UdpManager>
{
friend class Singleton<UdpManager>;
public:
/**
* Open a transmitting UDP socket which source port is @param port
*/
void setTxPort(uint16_t port);
/**
* Open a receiving UDP socket that will listen on @param port, listening
* starts as soon as this function is called
*/
void setRxPort(uint16_t port);
/**
* Send an UDP packet.
* @param ip: destination IP address
* @param port: destination port
* @param data: pointer to payload data
* @param len: payload lenght in bytes
*/
void sendPacketTo(const uint8_t* ip, const uint16_t port, const void* data,
size_t len);
/**
* @return true if there are new packets in the rx buffer
*/
bool newReceivedPackets();
/**
* @return payload size of the packet stored at the head of the internal
* buffer, in other words the packet that will be read if readPacket() is
* called.
*/
size_t recvPacketSize();
/**
* Read the packet placed at rx buffer's head popping it out of the queue.
* @param ip: source ip address
* @param port: source port
* @param data: pointer to a buffer in which store the payload data. It must
* have a size greater than or equal to that returned by recvPacketSize()
*/
void readPacket(uint8_t* ip, uint16_t& port, void* data);
/**
* IRQ handler for interrupts coming from the phy interface chip
* WARNING: DON'T call this!!
*/
void phyIrqHandler();
/**
* IRQ handler for interrupts coming from the tx watchdog timer
* WARNING: DON'T call this!!
*/
void wdtIrqHandler();
private:
// TX timeout time, in ms
static constexpr unsigned int TX_TIMEOUT = 500; // 500ms timeout
// Size of the event queue, used for event handling
static constexpr unsigned int EVT_QUEUE_SIZE = 20;
// Size of buffer used to store packets still to be sent, IN BYTES
static constexpr unsigned int TX_BUF_SIZE = 100000;
// Size of buffer used to store packets received, IN BYTES
static constexpr unsigned int RX_BUF_SIZE = 100000;
// TX and RX socket number, used by the phy interface
static constexpr uint8_t PHY_TX_SOCK_NUM = 0;
static constexpr uint8_t PHY_RX_SOCK_NUM = 1;
miosix::FixedEventQueue<EVT_QUEUE_SIZE> evtQueue;
PacketBuffer* txBuffer;
PacketBuffer* rxBuffer;
W5200& phy = W5200::instance();
WatchdogTimer* wdt = Singleton<WatchdogTimer>::getInstance();
// Function used by the event management thread
friend void _evt_mgmt_thread(void* args);
void tx_handler(); //< Tx event handler function
void tx_end_handler(); //< Tx end event handler function
void rx_handler(); //< New packet Rx handler function
void timeout_handler(); //< Tx timeout handler function
UdpManager();
UdpManager(const UdpManager& other);
UdpManager& operator=(const UdpManager& other);
~UdpManager();
};
This diff is collapsed.
This diff is collapsed.
/* Copyright (c) 2015-2016 Skyward Experimental Rocketry
* Author: Silvano Seva
*
* 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.
*/
#pragma once
#include <Common.h>
/* Maximum number of sockets managed by the device */
constexpr uint8_t MAX_SOCK_NUM = 8;
static constexpr uint32_t COMMON_BASE = 0x0000;
// TX buffer memory base address
constexpr uint32_t TX_BUF_BASE = COMMON_BASE + 0x8000;
// RX buffer memory base address
constexpr uint32_t RX_BUF_BASE = COMMON_BASE + 0xC000;
// clang-format off
/** Common registers **/
enum eW5200Registers
{
MR = COMMON_BASE + 0x0000, //mode register address
GAR_BASE = COMMON_BASE + 0x0001, //Gateway IP Register base address
SUBR_BASE = COMMON_BASE + 0x0005, //Subnet mask Register base address
SHAR_BASE = COMMON_BASE + 0x0009, //Source MAC Register base address
SIPR_BASE = COMMON_BASE + 0x000F, //Source IP Register base address
IR = COMMON_BASE + 0x0015, //Interrupt Register address
IR_MASK = COMMON_BASE + 0x0036, //Interrupt mask register
RTR_BASE = COMMON_BASE + 0x0017, //retransmission Timeout register
RCR = COMMON_BASE + 0x0019, //retransmission count register
SOCK_IR = COMMON_BASE + 0x0034, //Socket Interrupt Register
SOCK_IR_MASK = COMMON_BASE + 0x0016, //Socket Interrupt mask register
PHY = COMMON_BASE + 0x0035, //PHY Status Register
VERSION = COMMON_BASE + 0x001F, //chip version number register
PPP_AUTH_REG = COMMON_BASE + 0x001C, //autentication type in PPPoE mode
PPP_TIME_REG = COMMON_BASE + 0x0028, //LCP Request Timer in PPPoE mode
PPP_MAGIC_REG = COMMON_BASE + 0x0029, //PPP LCP Magic number in PPPoE mode
INTLEVEL0 = COMMON_BASE + 0x0030, //set Interrupt LL timer register
INTLEVEL1 = COMMON_BASE + 0x0031,
};
/* MODE register values */
enum eW5200MODERegisters
{
MR_RST = 0x80, // Reset
MR_PB = 0x10, // Ping block enable
MR_PPPOE = 0x08, // PPPoE enable
};
/* IR register values */
enum eW5200IRRegisters
{
IR_CONFLICT = 0x80, //IP conflict
IR_PPPoE = 0x20, //PPPoE connection close
};
/* Socket registers */
enum eW5200SockRegisters
{
SR_BASE = COMMON_BASE + 0x4000, //Socket registers base address
SR_SIZE = 0x100, //Size of each channel register map
};
enum eW5200SockNRegisters
{
SOCKn_MR = SR_BASE + 0x0000, // Mode register
SOCKn_CR = SR_BASE + 0x0001, // Command register
SOCKn_IR = SR_BASE + 0x0002, // Interrupt register
SOCKn_SR = SR_BASE + 0x0003, // Status register
SOCKn_SPORT0 = SR_BASE + 0x0004, // Source port register
SOCKn_DHAR0 = SR_BASE + 0x0006, // Destination MAC address register
SOCKn_DIPR0 = SR_BASE + 0x000C, // Destination IP address register
SOCKn_DPORT0 = SR_BASE + 0x0010, // Destination port register
SOCKn_IMR = SR_BASE + 0x002C, // Interrupt mask register
SOCKn_MSSR0 = SR_BASE + 0x0012, // MSS in TCP mode
SOCKn_PROTO = SR_BASE + 0x0014, // Protocol number in IPRAW mode
SOCKn_TOS = SR_BASE + 0x0015, // IP header ToS field value
SOCKn_TTL = SR_BASE + 0x0016, // IP header TTL field value
SOCKn_FRAG0 = SR_BASE + 0x002D, // IP header Fragment field value
SOCKn_RXMEM_SIZE = SR_BASE + 0x001E, // RX buffer size register
SOCKn_TXMEM_SIZE = SR_BASE + 0x001F, // TX buffer size register
SOCKn_TX_FSR0 = SR_BASE + 0x0020, // TX buffer free size register
SOCKn_TX_RD0 = SR_BASE + 0x0022, // TX buffer read pointer address
SOCKn_TX_WR0 = SR_BASE + 0x0024, // TX buffer write pointer address
SOCKn_RX_RSR0 = SR_BASE + 0x0026, // Received data size register
SOCKn_RX_RD0 = SR_BASE + 0x0028, // RX buffer read pointer address
SOCKn_RX_WR0 = SR_BASE + 0x002A, // RX buffer write pointer address
};
/* SOCKn_MR values */
enum eW5200SockNMRValues
{
SOCKn_MR_CLOSE = 0x00, // Socket closed
SOCKn_MR_TCP = 0x01, // TCP mode
SOCKn_MR_UDP = 0x02, // UDP mode
SOCKn_MR_IPRAW = 0x03, // IP layer raw socket
SOCKn_MR_MACRAW = 0x04, // MAC layer raw socket
SOCKn_MR_PPPOE = 0x05, // PPPoE mode
SOCKn_MR_ND = 0x20, // No delayed ACK enable
SOCKn_MR_MULTI = 0x80, // Enable multicasting (only in UDP mode)
};
/* SOCKn_CR values */
enum eW5200SockNCRValues
{
SOCKn_CR_OPEN = 0x01, // Initialize and open socket
SOCKn_CR_LISTEN = 0x02, // Wait conn request in TCP mode (Server mode)
SOCKn_CR_CONNECT = 0x04, // Send conn request in TCP mode (Client mode)
SOCKn_CR_DISCON = 0x08, // Disconnect request in TCP mode
SOCKn_CR_CLOSE = 0x10, // Close socket
SOCKn_CR_SEND = 0x20, // Send all data stored in TX buffer
SOCKn_CR_SEND_MAC = 0x21, // Send data + MAC without ARP (only in UDP mode)
SOCKn_CR_SEND_KEEP = 0x22, // Check if TCP connection is still alive
SOCKn_CR_RECV = 0x40, // Receive data
};
/* SOCKn_IR values */
enum eW5200SockNIRValues
{
SOCKn_IR_CON = 0x01, // Connection established
SOCKn_IR_DISCON = 0x02, // Disconnected (TCP mode)
SOCKn_IR_RECV = 0x04, // Some data received
SOCKn_IR_TIMEOUT = 0x08, // Timeout occurred in ARP or TCP
SOCKn_IR_SEND_OK = 0x10, // SEND command completed
};
/* SOCKn_SR values */
enum eW5200SockStatus
{
SOCK_CLOSED = 0x00, // Socket closed
SOCK_INIT = 0x13, // TCP init state
SOCK_LISTEN = 0x14, // TCP server listen for connection state
SOCK_SYNSENT = 0x15, // TCP connection request sent to server
SOCK_SYNRECV = 0x16, // TCP connection request received from client
SOCK_ESTABLISHED = 0x17, // TCP connection established
SOCK_FIN_WAIT = 0x18, // TCP closing state
SOCK_CLOSING = 0x1A, // TCP closing state
SOCK_TIME_WAIT = 0x1B, // TCP closing state
SOCK_CLOSE_WAIT = 0x1C, // TCP closing state
SOCK_LAST_ACK = 0x1D, // TCP closing state
SOCK_UDP = 0x22, // Socket opened in UDP mode
SOCK_IPRAW = 0x32, // Socket opened in IP raw mode
SOCK_MACRAW = 0x42, // Socket opened in MAC raw mode
SOCK_PPPOE = 0x5F, // Socket opened in PPPoE mode
};
/* IPProto values */
enum eW5200IPProtoValues
{
IPPROTO_IP = 0, // Dummy for IP
IPPROTO_ICMP = 1, // ICMP protocol
IPPROTO_IGMP = 2, // IGMP protocol
IPPROTO_GGP = 3, // GGP protocol
IPPROTO_TCP = 6, // TCP
IPPROTO_PUP = 12, // PUP
IPPROTO_UDP = 17, // UDP
IPPROTO_IDP = 22, // XNS idp
IPPROTO_RAW = 255, // Raw IP packet */
};
// clang-format on
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* Copyright (c) 2017 Skyward Experimental Rocketry
* Author: Silvano Seva
*
* 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.
*/
#pragma once
#include <slave/SlaveEngine.h>
#include <slave/SlaveInterface.h>
#include "ExceptionCodes.h"
#include "PDU.h"
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.