Skyward boardcore
Loading...
Searching...
No Matches
WIZ5500.h
Go to the documentation of this file.
1/* Copyright (c) 2023 Skyward Experimental Rocketry
2 * Author: Davide Mor
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#pragma once
24
25#include <ActiveObject.h>
27#include <miosix.h>
28
29#include <functional>
30
31namespace Boardcore
32{
33
37struct WizIp
38{
39 uint8_t a, b, c, d;
40};
41
45struct WizMac
46{
47 uint8_t a, b, c, d, e, f;
48};
49
54{
55public:
56 struct PhyState
57 {
58 bool full_duplex; //< True if full duplex is enabled, false if link is
59 // only half duplex.
60 bool based_100mbps; //< True if 100Mbps, false if only 10Mpbs.
61 bool link_up; //< True if link is up, false if it is down.
62 };
63
64 using OnIpConflictCb = std::function<void()>;
65 using OnDestUnreachableCb = std::function<void(WizIp, uint16_t)>;
66
75 Wiz5500(SPIBus& bus, miosix::GpioPin cs, miosix::GpioPin intn,
76 SPI::ClockDivider clock_divider);
77 ~Wiz5500();
78
95
112
120 bool checkVersion();
121
129
135 void reset();
136
140 void handleINTn();
141
145 void setGatewayIp(WizIp ip);
146
150 void setSubnetMask(WizIp mask);
151
155 void setSourceMac(WizMac mac);
156
160 void setSourceIp(WizIp ip);
161
173 bool connectTcp(int sock_n, uint16_t src_port, WizIp dst_ip,
174 uint16_t dst_port, int timeout = -1);
175
187 bool listenTcp(int sock_n, uint16_t src_port, WizIp& dst_ip,
188 uint16_t& dst_port, int timeout = -1);
189
201 bool openUdp(int sock_n, uint16_t src_port, WizIp dst_ip, uint16_t dst_port,
202 int timeout = -1);
203
214 bool send(int sock_n, const uint8_t* data, size_t len, int timeout = -1);
215
226 ssize_t recv(int sock_n, uint8_t* data, size_t len, int timeout = -1);
227
240 ssize_t recvfrom(int sock_n, uint8_t* data, size_t len, WizIp& dst_ip,
241 uint16_t& dst_port, int timeout = -1);
242
249 void close(int sock_n, int timeout = -1);
250
251private:
252 static constexpr int NUM_THREAD_WAIT_INFOS = 16;
253 static constexpr int NUM_SOCKETS = 8;
254
255 miosix::TimedWaitResult waitForINTn(miosix::Lock<miosix::FastMutex>& l,
256 long long until);
257 int waitForSocketIrq(miosix::Lock<miosix::FastMutex>& l, int sock_n,
258 uint8_t irq_mask, long long until);
259
260 miosix::TimedWaitResult runInterruptServiceRoutine(
261 miosix::Lock<miosix::FastMutex>& l, long long until);
262
263 void spiRead(uint8_t block, uint16_t address, uint8_t* data, size_t len);
264 void spiWrite(uint8_t block, uint16_t address, const uint8_t* data,
265 size_t len);
266
267 uint8_t spiRead8(uint8_t block, uint16_t address);
268 uint16_t spiRead16(uint8_t block, uint16_t address);
269 WizIp spiReadIp(uint8_t block, uint16_t address);
270 // Avoid stupid linter error
271 // WizMac spiReadMac(uint8_t block, uint16_t address);
272
273 void spiWrite8(uint8_t block, uint16_t address, uint8_t data);
274 void spiWrite16(uint8_t block, uint16_t address, uint16_t data);
275 void spiWriteIp(uint8_t block, uint16_t address, WizIp data);
276 void spiWriteMac(uint8_t block, uint16_t address, WizMac data);
277
278 // Thread currently servicing interrupts
279 miosix::Thread* interrupt_service_thread = nullptr;
280 // Thread currently waiting for an INTn
281 miosix::Thread* intn_thread = nullptr;
282
283 struct ThreadWaitInfo
284 {
285 int sock_n;
286 uint8_t irq_mask;
287 uint8_t irq;
288 miosix::Thread* thread;
289 };
290
291 enum class SocketMode
292 {
293 TCP,
294 UDP,
295 CLOSED
296 };
297
298 struct SocketInfo
299 {
300 SocketMode mode;
301 int irq_mask;
302 };
303
304 SocketInfo socket_infos[NUM_SOCKETS];
305 ThreadWaitInfo wait_infos[NUM_THREAD_WAIT_INFOS];
306
307 OnIpConflictCb on_ip_conflict;
308 OnDestUnreachableCb on_dest_unreachable;
309
310 miosix::GpioPin intn;
311 miosix::FastMutex mutex;
312 SPISlave slave;
313};
314
315} // namespace Boardcore
316
317namespace std
318{
319inline ostream& operator<<(ostream& os, const Boardcore::WizIp& ip)
320{
321 auto old_flags = os.flags(os.dec);
322 os << (int)ip.a << "." << (int)ip.b << "." << (int)ip.c << "." << (int)ip.d;
323 os.flags(old_flags);
324 return os;
325}
326
327inline ostream& operator<<(ostream& os, const Boardcore::WizMac& mac)
328{
329 auto old_flags = os.flags(os.hex);
330 os << (int)mac.a << ":" << (int)mac.b << ":" << (int)mac.c << ":"
331 << (int)mac.d << ":" << (int)mac.e << ":" << (int)mac.f;
332 os.flags(old_flags);
333 return os;
334}
335} // namespace std
Driver for STM32 low level SPI peripheral.
Definition SPIBus.h:61
Driver for the WizNet W5500 ethernet.
Definition WIZ5500.h:54
ssize_t recvfrom(int sock_n, uint8_t *data, size_t len, WizIp &dst_ip, uint16_t &dst_port, int timeout=-1)
Receive data from the socket (works only in UDP).
Definition WIZ5500.cpp:365
std::function< void()> OnIpConflictCb
Definition WIZ5500.h:64
void setSourceIp(WizIp ip)
Set the device IP address.
Definition WIZ5500.cpp:159
bool openUdp(int sock_n, uint16_t src_port, WizIp dst_ip, uint16_t dst_port, int timeout=-1)
Open a simple UDP socket.
Definition WIZ5500.cpp:260
void setSourceMac(WizMac mac)
Set the device MAC address.
Definition WIZ5500.cpp:153
void setOnIpConflict(OnIpConflictCb cb)
Sets the callback to be invoked when the device detects an IP. conflict.
Definition WIZ5500.cpp:82
std::function< void(WizIp, uint16_t)> OnDestUnreachableCb
Definition WIZ5500.h:65
bool checkVersion()
Checks the VERSION register. Can be used to detect device presence.
Definition WIZ5500.cpp:94
void setGatewayIp(WizIp ip)
Set global gateway ip.
Definition WIZ5500.cpp:141
void reset()
Resets the device. Performs a software resets, resetting all registers and closing all sockets.
Definition WIZ5500.cpp:113
bool listenTcp(int sock_n, uint16_t src_port, WizIp &dst_ip, uint16_t &dst_port, int timeout=-1)
Listen for a single remote TCP connection.
Definition WIZ5500.cpp:210
void handleINTn()
Handle an interrupt from INTn.
Definition WIZ5500.cpp:128
Wiz5500(SPIBus &bus, miosix::GpioPin cs, miosix::GpioPin intn, SPI::ClockDivider clock_divider)
Build an instance of the driver.
Definition WIZ5500.cpp:57
ssize_t recv(int sock_n, uint8_t *data, size_t len, int timeout=-1)
Receive data from the socket (works only in TCP).
Definition WIZ5500.cpp:327
void setSubnetMask(WizIp mask)
Set global subnet mask.
Definition WIZ5500.cpp:147
void setOnDestUnreachable(OnDestUnreachableCb cb)
Sets the callback to be invoked when the device detects an unreachable host.
Definition WIZ5500.cpp:88
bool send(int sock_n, const uint8_t *data, size_t len, int timeout=-1)
Send data through the socket (works both in TCP and UDP).
Definition WIZ5500.cpp:293
PhyState getPhyState()
Get current PHY state, can be used to poll link status, and wait for link up.
Definition WIZ5500.cpp:101
void close(int sock_n, int timeout=-1)
Close a socket.
Definition WIZ5500.cpp:422
bool connectTcp(int sock_n, uint16_t src_port, WizIp dst_ip, uint16_t dst_port, int timeout=-1)
Connect to a remote socket via TCP.
Definition WIZ5500.cpp:165
ClockDivider
SPI Clock divider.
Definition SPIDefs.h:70
This file includes all the types the logdecoder script will decode.
Definition WIZ5500.h:318
ostream & operator<<(ostream &os, const Boardcore::WizIp &ip)
Definition WIZ5500.h:319
Class representing an IPv4 ip.
Definition WIZ5500.h:38
Class representing an ethernet MAC address.
Definition WIZ5500.h:46