Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b956c4b

Browse filesBrowse files
stracciofpistm
authored andcommitted
Added multicast udp, added callback for interrupt data arrival
Implemented begin multicast for receiving multicast udp. Added ability to add a callback from the interrupt when udp receive data (Usefull with FreeRTOS). ``` void EthernetUDP::onDataArrival( std::function<void()> onDataArrival_fn){ _udp.onDataArrival = onDataArrival_fn; } ```
1 parent 07b3797 commit b956c4b
Copy full SHA for b956c4b

File tree

Expand file treeCollapse file tree

6 files changed

+130
-31
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+130
-31
lines changed

‎src/EthernetUdp.cpp

Copy file name to clipboard
100644100755
Expand all lines: src/EthernetUdp.cpp
+28-7Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,23 @@
2525
*
2626
* bjoern@cs.stanford.edu 12/30/2008
2727
*/
28-
2928
#include "STM32Ethernet.h"
3029
#include "Udp.h"
3130
#include "Dns.h"
3231

32+
#include "lwip/igmp.h"
33+
#include "lwip/ip_addr.h"
34+
3335
/* Constructor */
3436
EthernetUDP::EthernetUDP() {}
3537

3638
/* Start EthernetUDP socket, listening at local port PORT */
3739
uint8_t EthernetUDP::begin(uint16_t port) {
40+
return begin(Ethernet.localIP(), port);
41+
}
42+
43+
/* Start EthernetUDP socket, listening at local IP ip and port PORT */
44+
uint8_t EthernetUDP::begin(IPAddress ip, uint16_t port, bool multicast) {
3845
// Can create a single udp connection per socket
3946
if(_udp.pcb != NULL) {
4047
return 0;
@@ -46,14 +53,25 @@ uint8_t EthernetUDP::begin(uint16_t port) {
4653
return 0;
4754
}
4855

49-
IPAddress ip = Ethernet.localIP();
5056
ip_addr_t ipaddr;
57+
err_t err;
58+
u8_to_ip_addr(rawIPAddress(ip), &ipaddr);
59+
if (multicast) {
60+
err = udp_bind(_udp.pcb, IP_ADDR_ANY, port);
61+
} else {
62+
err = udp_bind(_udp.pcb, &ipaddr, port);
63+
}
5164

52-
if(ERR_OK != udp_bind(_udp.pcb, u8_to_ip_addr(rawIPAddress(ip), &ipaddr), port)) {
65+
if(ERR_OK != err) {
5366
stop();
5467
return 0;
5568
}
5669

70+
#if LWIP_IGMP
71+
if ((multicast) && (ERR_OK != igmp_joingroup(IP_ADDR_ANY, &ipaddr))) {
72+
return 0;
73+
}
74+
#endif
5775
udp_recv(_udp.pcb, &udp_receive_callback, &_udp);
5876

5977
_port = port;
@@ -104,8 +122,6 @@ int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
104122
return 0;
105123
}
106124

107-
ip_addr_t ipaddr;
108-
109125
_sendtoIP = ip;
110126
_sendtoPort = port;
111127

@@ -245,6 +261,11 @@ void EthernetUDP::flush()
245261
/* Start EthernetUDP socket, listening at local port PORT */
246262
uint8_t EthernetUDP::beginMulticast(IPAddress ip, uint16_t port)
247263
{
248-
UNUSED(ip);
249-
return begin(port);
264+
return begin(ip, port, true);
265+
}
266+
267+
#if LWIP_UDP
268+
void EthernetUDP::onDataArrival( std::function<void()> onDataArrival_fn){
269+
_udp.onDataArrival = onDataArrival_fn;
250270
}
271+
#endif

‎src/EthernetUdp.h

Copy file name to clipboardExpand all lines: src/EthernetUdp.h
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,9 @@
3838
#define ethernetudp_h
3939

4040
#include <Udp.h>
41+
#include <functional>
4142

42-
extern "C" {
4343
#include "utility/stm32_eth.h"
44-
}
4544

4645
#define UDP_TX_PACKET_MAX_SIZE 24
4746

@@ -62,6 +61,7 @@ class EthernetUDP : public UDP {
6261
public:
6362
EthernetUDP(); // Constructor
6463
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
64+
virtual uint8_t begin(IPAddress, uint16_t, bool multicast = false); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
6565
virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
6666
virtual void stop(); // Finish with the UDP socket
6767

@@ -104,6 +104,7 @@ class EthernetUDP : public UDP {
104104
virtual IPAddress remoteIP() { return _remoteIP; };
105105
// Return the port of the host who sent the current incoming packet
106106
virtual uint16_t remotePort() { return _remotePort; };
107+
virtual void onDataArrival( std::function<void()> onDataArrival_fn);
107108
};
108109

109110
#endif

‎src/utility/ethernetif.c renamed to ‎src/utility/ethernetif.cpp

Copy file name to clipboardExpand all lines: src/utility/ethernetif.cpp
+86-1Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "ethernetif.h"
5252
#include <string.h>
5353
#include "PeripheralPins.h"
54+
#include "lwip/igmp.h"
5455
#include "stm32_eth.h"
5556
#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01050000)
5657
#include "variant.h"
@@ -92,6 +93,11 @@ static ETH_HandleTypeDef EthHandle;
9293

9394
static uint8_t macaddress[6]= { MAC_ADDR0, MAC_ADDR1, MAC_ADDR2, MAC_ADDR3, MAC_ADDR4, MAC_ADDR5 };
9495

96+
#if LWIP_IGMP
97+
uint32_t ETH_HashTableHigh=0x0;
98+
uint32_t ETH_HashTableLow=0x0;
99+
#endif
100+
95101
/* Private function prototypes -----------------------------------------------*/
96102
/* Private functions ---------------------------------------------------------*/
97103
/*******************************************************************************
@@ -205,7 +211,9 @@ static void low_level_init(struct netif *netif)
205211

206212
/* Enable MAC and DMA transmission and reception */
207213
HAL_ETH_Start(&EthHandle);
208-
214+
#if LWIP_IGMP
215+
netif_set_igmp_mac_filter(netif, igmp_mac_filter);
216+
#endif
209217
/**** Configure PHY to generate an interrupt when Eth Link state changes ****/
210218
/* Read Register Configuration */
211219
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_IMR, &regvalue);
@@ -214,6 +222,10 @@ static void low_level_init(struct netif *netif)
214222

215223
/* Enable Interrupt on change of link status */
216224
HAL_ETH_WritePHYRegister(&EthHandle, PHY_IMR, regvalue );
225+
#if LWIP_IGMP
226+
ETH_HashTableHigh=EthHandle.Instance->MACHTHR;
227+
ETH_HashTableLow=EthHandle.Instance->MACHTLR;
228+
#endif
217229
}
218230

219231
/**
@@ -510,6 +522,13 @@ void ethernetif_set_link(struct netif *netif)
510522
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_BSR, &regvalue);
511523

512524
if((regvalue & PHY_LINKED_STATUS) != (uint16_t)RESET) {
525+
#if LWIP_IGMP
526+
if (!(netif->flags & NETIF_FLAG_IGMP)) {
527+
netif->flags |= NETIF_FLAG_IGMP;
528+
igmp_init();
529+
igmp_start(netif);
530+
}
531+
#endif
513532
netif_set_link_up(netif);
514533
}
515534
}
@@ -628,6 +647,72 @@ void ethernetif_set_mac_addr(const uint8_t *mac) {
628647
}
629648
}
630649

650+
#if LWIP_IGMP
651+
err_t igmp_mac_filter( struct netif *netif, const ip4_addr_t *ip4_addr, netif_mac_filter_action action )
652+
{
653+
uint8_t mac[6];
654+
const uint8_t *p = (const uint8_t *)ip4_addr;
655+
656+
mac[0] = 0x01;
657+
mac[1] = 0x00;
658+
mac[2] = 0x5E;
659+
mac[3] = *(p+1) & 0x7F;
660+
mac[4] = *(p+2);
661+
mac[5] = *(p+3);
662+
663+
register_multicast_address(mac);
664+
665+
return 0;
666+
}
667+
668+
#ifndef HASH_BITS
669+
#define HASH_BITS 6 /* #bits in hash */
670+
#endif
671+
672+
uint32_t ethcrc(const uint8_t *data, size_t length)
673+
{
674+
uint32_t crc = 0xffffffff;
675+
size_t i;
676+
int j;
677+
678+
for (i = 0; i < length; i++) {
679+
for (j = 0; j < 8; j++) {
680+
if (((crc >> 31) ^ (data[i] >> j)) & 0x01) {
681+
/* x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 */
682+
crc = (crc << 1) ^ 0x04C11DB7;
683+
} else {
684+
crc = crc << 1;
685+
}
686+
}
687+
}
688+
return ~crc;
689+
}
690+
691+
void register_multicast_address(const uint8_t *mac)
692+
{
693+
uint32_t crc;
694+
uint8_t hash;
695+
696+
/* Calculate crc32 value of mac address */
697+
crc = ethcrc(mac, HASH_BITS);
698+
699+
/*
700+
* Only upper HASH_BITS are used
701+
* which point to specific bit in the hash registers
702+
*/
703+
hash = (crc >> 26) & 0x3F;
704+
705+
if (hash > 31) {
706+
ETH_HashTableHigh |= 1 << (hash - 32);
707+
EthHandle.Instance->MACHTHR = ETH_HashTableHigh;
708+
} else {
709+
ETH_HashTableLow |= 1 << hash;
710+
EthHandle.Instance->MACHTLR =ETH_HashTableLow;
711+
}
712+
}
713+
#endif /* LWIP_IGMP */
714+
715+
631716
#ifdef ETH_INPUT_USE_IT
632717
/**
633718
* @brief Ethernet Rx Transfer completed callback

‎src/utility/ethernetif.h

Copy file name to clipboard
100644100755
Expand all lines: src/utility/ethernetif.h
+7-5Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,11 @@
4747

4848
#ifndef __ETHERNETIF_H__
4949
#define __ETHERNETIF_H__
50-
51-
#include "lwip/err.h"
52-
#include "lwip/netif.h"
53-
5450
#ifdef __cplusplus
5551
extern "C" {
5652
#endif
57-
53+
#include "lwip/err.h"
54+
#include "lwip/netif.h"
5855
/* Exported types ------------------------------------------------------------*/
5956
uint8_t ethernetif_is_init(void);
6057
err_t ethernetif_init(struct netif *netif);
@@ -65,6 +62,11 @@ void ethernetif_notify_conn_changed(struct netif *netif);
6562

6663
void ethernetif_set_mac_addr(const uint8_t *mac);
6764

65+
#if LWIP_IGMP
66+
err_t igmp_mac_filter( struct netif *netif, const ip4_addr_t *ip4_addr, netif_mac_filter_action action );
67+
void register_multicast_address(const uint8_t *mac);
68+
#endif
69+
6870
#ifdef __cplusplus
6971
}
7072
#endif

‎src/utility/stm32_eth.cpp

Copy file name to clipboardExpand all lines: src/utility/stm32_eth.cpp
+4-8Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,6 @@
4747
#include "lwip/prot/dhcp.h"
4848
#include "lwip/dns.h"
4949

50-
#ifdef __cplusplus
51-
extern "C" {
52-
#endif
53-
5450
/* Check ethernet link status every seconds */
5551
#define TIME_CHECK_ETH_LINK_STATE 500U
5652

@@ -798,6 +794,10 @@ void udp_receive_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p,
798794

799795
ip_addr_copy(udp_arg->ip, *addr);
800796
udp_arg->port = port;
797+
798+
if(udp_arg->onDataArrival != NULL){
799+
udp_arg->onDataArrival();
800+
}
801801
} else {
802802
pbuf_free(p);
803803
}
@@ -1049,7 +1049,3 @@ void tcp_connection_close(struct tcp_pcb *tpcb, struct tcp_struct *tcp)
10491049
}
10501050

10511051
#endif /* LWIP_TCP */
1052-
1053-
#ifdef __cplusplus
1054-
}
1055-
#endif

‎src/utility/stm32_eth.h

Copy file name to clipboardExpand all lines: src/utility/stm32_eth.h
+2-8Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,14 @@
3838
#ifndef __STM32_ETH_H__
3939
#define __STM32_ETH_H__
4040

41-
#ifdef __cplusplus
42-
extern "C" {
43-
#endif
44-
4541
/* Includes ------------------------------------------------------------------*/
4642
#include "stm32_def.h"
4743
#include "lwip/ip_addr.h"
4844
#include "lwip/dhcp.h"
4945
#include "lwip/udp.h"
5046
#include "lwip/tcp.h"
5147
#include "lwip/opt.h"
48+
#include <functional>
5249

5350
/* Exported types ------------------------------------------------------------*/
5451
/* TCP connection state */
@@ -74,6 +71,7 @@ struct udp_struct {
7471
struct pbuf_data data;
7572
ip_addr_t ip; // the remote IP address from which the packet was received
7673
u16_t port; // the remote port from which the packet was received
74+
std::function<void()> onDataArrival;
7775
};
7876

7977
/* TCP structure */
@@ -174,8 +172,4 @@ void tcp_connection_close(struct tcp_pcb *tpcb, struct tcp_struct *tcp);
174172
#error "LWIP_TCP must be enabled in lwipopts.h"
175173
#endif
176174

177-
#ifdef __cplusplus
178-
}
179-
#endif
180-
181175
#endif /* __STM32_ETH_H__ */

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.