49 #define BAD_NETWORK_RX_FAIL 3
50 #define BAD_NETWORK_TX_FAIL 3
51 #define BAD_NETWORK_TX_STUTTER 50
56 #define _IP32_C(IP32, IDX) ( ( IP32 >> (IDX * 8)) & 0xFF )
57 #define IP32_TO_LIST(IP32) _IP32_C(IP32, 3),_IP32_C(IP32, 2),_IP32_C(IP32, 1),_IP32_C(IP32, 0)
63 static uint32_t _pktLogPos = 0;
67 if (_pktLogPos == LOG_RX_PACKETS)
return NULL;
68 return &_pktLog[_pktLogPos++];
73 if (pos >= _pktLogPos)
return NULL;
106 #define MODULE_IP NET_IP_U32( 0, 0, 0, 0 )
107 #define SERVER_IP NET_IP_U32(255, 255, 255, 255)
108 static bool _hasIp =
false;
110 #define MODULE_IP NET_IP_U32( 192, 168, 1, 10 )
111 #define SERVER_IP NET_IP_U32( 192, 168, 1, 1 )
112 static bool _hasIp =
true;
114 #define SC_PORT 0xDACE
131 uint32_t lastProcTime;
137 static uint8_t _rxbuf[NET_RX_BUFFER] __attribute__((aligned(4)));
138 static uint32_t _rxbuf_len;
144 void ms_bootp_periodic(
bool force);
147 static bool _using_temp_ip =
true;
148 static ms_ipa_t _temp_ip;
153 #define LED_FLASH_TIME 200
163 .
mac = { 0xFFFF, 0xFFFF, 0xFFFF },
166 SC_PORT + 1, SC_PORT + 2, SC_PORT + 3, SC_PORT + 4
172 .
mac = { 0xFFFF, 0xFFFF, 0xFFFF },
175 SC_PORT + 1, SC_PORT + 2, SC_PORT + 3, SC_PORT + 4
181 static uint32_t _ledsTo[LED_COUNT];
182 static uint32_t _ledsOn = 0;
184 static void netSetLed(
int idx)
190 _ledsOn |= (1 << idx);
193 static void netHandleLeds()
195 if (_ledsOn == 0)
return;
198 for (i = 0; i < LED_COUNT; ++i)
200 if ((_ledsOn & (1 << i)) &&
timeOut(_ledsTo[i]))
203 _ledsOn &= ~(1 << i);
209 static inline void netSetLed(
int idx) {};
210 static void netHandleLeds() {};
214 static bool linkUp() {
215 if (!
wrxUp())
return false;
217 volatile WrxInfo * info =
wrxInfo();
218 if (info->status & WRX_STATUS_LINK_UP)
225 static bool _prevLinkUp =
false;
240 }
else if (_prevLinkUp)
255 ms_get_config(NULL, &cur_ip);
257 if (ms_ipa_eq(&_temp_ip, &cur_ip))
259 ms_bootp_periodic(
true);
264 _using_temp_ip =
false;
276 ms_get_config(NULL, &ip);
277 ms_ipa_get_u32(&ip, &_ipMuxModCfg.
ip);
280 logInfo(
"IP Obtained: %d.%d.%d.%d", IP32_TO_LIST(_ipMuxModCfg.
ip));
290 uint32_t t =
ticks();
294 if (
ipMuxRx(_rxbuf,
sizeof(_rxbuf), &_rxbuf_len))
298 showHex8(
"Receving from IPMUX: ", _rxbuf, _rxbuf_len);
300 #ifdef LOG_RX_PACKETS
305 pkt->ticks =
ticks();
306 pkt->length = _rxbuf_len;
307 if (_rxbuf_len >= 14)
309 pkt->eth_type = ( _rxbuf[12] << 8 ) | ( _rxbuf[13] );
310 pkt->d_mac5 = _rxbuf[10];
311 pkt->d_mac6 = _rxbuf[11];
316 pkt->eth_type = 0xFFFF;
322 ms_rx(_rxbuf, _rxbuf_len);
328 pkt->proc_time =
ticks() - pkt->ticks;
331 ms_rx(_rxbuf, _rxbuf_len);
342 _stats._procTot += t;
344 if (_stats._procCnt == 1024)
346 _stats.lastProcTime = (uint32_t) (( _stats._procTot * 1000) / 1024);
365 ms_ipa_set_u32(destIp, &ipa);
368 if (destIp == 0xFFFFFFFF) {
371 if (destMac == NULL ||
372 (destMac[0] == 0xFFFF && destMac[1] == 0xFFFF && destMac[2] == 0xFFFF) ) {
374 mac = ms_arp_lookup(&ipa);
378 destMac = (uint16_t *)mac;
381 memcpy(&_ipMuxSvrCfg.
mac, destMac, 6);
382 _ipMuxSvrCfg.
ip = destIp;
397 ms_ipa_set_u32(txAddr->
ip, &ipa);
398 ms_udp_tx(&ipa, txAddr->
port, SC_PORT, udpPayload, len);
402 void _ms_tx(
void * hptr,
unsigned int hlen,
void * plptr,
unsigned int pllen)
408 showHex8(
"Sending to IPMUX (header): ", hptr, hlen);
409 if (pllen > 0) showHex8(
"Sending to IPMUX (payload): ", plptr, pllen);
412 #ifdef BAD_NETWORK_TEST
413 int x = rand() % BAD_NETWORK_TX_FAIL;
415 int delay = rand() % BAD_NETWORK_TX_STUTTER;
422 uint32_t l =
ticks();
424 r =
ipMuxTx(hptr, hlen, pllen > 0 ?
false :
true);
425 if (r && (pllen > 0)) r =
ipMuxTx(plptr, pllen,
true);
433 if (_stats.txHisto[l] == 0xFFFF) {
434 for (
int i = 0; i < 7; ++i) {
435 _stats.txHisto[l] >>= 1;
440 void _ms_udp_rx(ms_ipa_t * src_ip,
441 uint16_t src_port, uint16_t dst_port,
442 uint8_t * data,
unsigned int len)
448 ms_udp_tx(src_ip, src_port, dst_port, data, len);
451 #ifdef BAD_NETWORK_TEST
452 int x = rand() % BAD_NETWORK_RX_FAIL;
462 ms_ipa_get_u32(src_ip, &ip32);
464 sAddr.
port = src_port;
469 logWarn(
"UDP Rx on port: %d", dst_port);
478 ms_ipa_set(&ipa, ip);
480 ms_ipa_get_u32(&ipa, &_ipMuxModCfg.
ip);
492 volatile WrxInfo * info =
wrxInfo();
493 logInfo(
"WRX UP: %d, Status: %x",
wrxUp(), info != NULL ? info->status : 0xDEAD);
495 if (!
wrxUp() || !(
wrxInfo()->status & WRX_STATUS_MAC_ADDRESS_VALID))
496 return errSet(ERROR_CTX(E_NET_WRXMAC));
497 uint8_t * mac_bytes = (uint8_t *)
wrxInfo()->macAddr;
499 uint8_t mac_bytes[] = { 0x08, 0x00, 0x30, 0x6C, 0x27, 0x75 };
503 ms_mac_set(&mac, mac_bytes);
515 const uint32_t su_ip = NET_SU_IP_FIX | (lower_mac & NET_SU_IP_DYN_MASK);
518 logInfo(
"Using temporary IP: %d.%d.%d.%d", IP32_TO_LIST(su_ip));
521 ms_ipa_set_u32(su_ip, &_temp_ip);
523 const uint32_t su_ip = 0;
526 ms_ipa_set_u32(su_ip, &ip);
532 memcpy(_ipMuxModCfg.
mac, &mac, MS_MAC_LEN);
533 _ipMuxModCfg.
ip = su_ip;
543 logInfo(
"MAC: %04X:%04X:%04X", _ipMuxModCfg.
mac[0], _ipMuxModCfg.
mac[1],
544 _ipMuxModCfg.
mac[2]);
545 logInfo(
"IP : %d.%d.%d.%d", IP32_TO_LIST(_ipMuxModCfg.
ip));
548 logInfo(
"IP obtain automatic");
551 volatile WrxInfo * wrx =
wrxInfo();
553 logInfo(
"WR Exchange Status: %08lx (MAC mode: %s)", wrx->status, wrx->status & WRX_STATUS_BROADCAST_MODE ?
"Broadcast" :
"P2P");
554 logInfo(
"WR Core Status: WR=%d SERVO=%d PTP=%d", wrx->wState, wrx->sState, wrx->pState);
556 logInfo(
"WhiteRabbit communication link failure");
558 logInfo(
"Proto RX TX RX ERR TX ERR LOST");
559 logInfo(
"SRP %6lu %6lu - %6lu %6lu", _stats.srpRx, _stats.srpTx, _stats.srpTxErr, _stats.srpTxLost);
560 logInfo(
"UDP %6lu %6lu %6lu - -", _stats.udpRx, _stats.udpTx, _stats.udpRxFail);
561 logInfo(
"ETH %6lu %6lu %6lu - -", _stats.ethRx, _stats.ethTx, _stats.ethRxFail);
562 logInfo(
"Average processing time (last 1024 packets)=%u us", _stats.lastProcTime);
575 #include "net/uartbridge.h"
590 ubTx(addr, data, len);
593 void _ubRx(
SockAddr * addr, uint8_t * data,
int len) {
609 #ifndef SRP_ECHO_MODE
610 msgRx(addr, message, len);
613 printf(
"PING PONG! %s\n", message);
614 srpTx(addr, message, len);
625 if (!
srpTx(addr, message, len))
636 void _ms_icmp_du(
int code, ms_ipa_t * cause_ip)
655 static int _eventFailedCount = 0;
669 int t = _eventFailedCount;
670 _eventFailedCount = 0;
680 return !_using_temp_ip && ms_ip_has();
689 #ifdef BAD_NETWORK_TEST
690 logwarn(
"WARNING: Network test 'bad network' active");
694 return netStackInit();
void msgGetEvtTarget(SockAddr *sockAddr)
Returns the event target address.
void _msgTx(SockAddr *addr, uint8_t *data, int len)
Stub function, invoked by RMT when sending a MCF packet.
void ipMuxCfgRemote(IpMuxCfg *svrCfg)
Configure IPmux with remote settings.
int timerMark(int section)
Starts the timing of a new section, the previous section is returned, or -1 if it is the first...
bool srpTx(SockAddr *txAddr, uint8_t *message, int len)
Invoked by application for sending an SRP packet.
bool ipMuxTx(void *buf, uint32_t txlen, bool done)
Sends data to the IPMux's CPU interface.
uint32_t _mcfTimeStamp()
Dependency function.
void _srpUdpTx(SockAddr *txAddr, uint8_t *udpPayload, int len)
Transmit UDP packet.
bool netIpValid()
Returns whether or not the Ip is valid.
Message Container Format formatter / parser.
void _srpLost(SockAddr *addr, uint8_t msgId)
Stub, invoked when an SRP message is lost.
#define NET_IP_U32(A, B, C, D)
Creates a U32 IP address from components.
IPMux configuration structure.
uint16_t port
Port number.
#define TIMER_SECT_IDLE
time spend being idle
PacketLog_t * getPacketLog(uint32_t pos)
Get packet log at position pos.
SRP or Simple Retransmission Protocol is a protocol which retransmits packets if they have not been c...
Simple task scheduler for tasks.
bool ipMuxRx(void *buf, uint32_t buflen, uint32_t *rxlen)
Received data from the IPMux's CPU interface.
static void ipMuxFlushCPU()
Flushes the.
void timeDelay(uint32_t msec)
Simple busy-wait delay.
bool ipMuxRxAvail()
Returns whether or not there is data available for reception.
static uint32_t ticks()
Nr of ticks since device start up.
bool netMuxDest(uint32_t destIp, uint16_t *destMac)
Sets the IPMux destination.
#define logWarn(MSG,...)
Format a log message with warning level.
void gpioPinSet(int pin, bool high)
Sets the pin state.
void srpUdpRx(SockAddr *rxAddr, uint8_t *udpPayload, int len)
Invoked by UDP stack for receiving a SRP packet.
#define E_INVARGUMENT
Generic error: invalid argument.
static bool sockAddrEq(SockAddr *addr1, SockAddr *addr2)
Checks if two socket addresses are equal.
static uint32_t timeOutInit(uint32_t msec)
Initializes a timeout with the specified no of msecs.
uint16_t mac[3]
MAC address.
Handles MCF packed messages from the higher protocol layer.
bool netInit()
Initializes the network.
static bool timeOut(uint32_t to)
Checks whether or not the timeout has expired.
Combination of IP address and port.
Manages the global system error.
void errPrint(bool clear)
Prints the last error.
bool schdAddIdleTask(SchdTaskF idleTask)
Adds an idle task, the task which is executed when there is nothing else to do.
void resetPacketLog()
Reset the packet log.
void msgRx(SockAddr *addr, uint8_t *data, int len)
Receive a packet with data as a command.
void ipMuxInit(IpMuxCfg *modCfg, bool flush)
Initializes the IPMux local (module) only.
bool wrxUp()
Returns whether or not the WhiteRabbit interface is up and running.
volatile WrxInfo * wrxInfo()
Returns the whiteRabbit information structure if available, else NULL.
This module is responsible for distributing error codes.
uint32_t netEventFailedCount()
Returns the number of events failed to be transmitted since the the function was previously invoked...
#define LOG_DEF(NAME,...)
Define a logger for a module.
void netSetIp(uint8_t *ip)
Sets the Ip address to the network.
void netShowInfo(bool extended)
Shows network configuration information.
bool errSet(uint32_t code, const char *error, const char *name)
Sets an error.
#define TIMER_SECT_TASK
time spend executing a task
Implements a generic logger facility.
void _srpRx(SockAddr *rxAddr, uint8_t *message, int len)
Process a received SRP packet.
WhiteRabbit exchange exchanges information between the 2nd LM32 and WhiteRabbit though a small client...
void srpInit()
Initializes the SRP protocol engine.
#define logInfo(MSG,...)
Write a log message with formatting on info level.