/* * e131.cpp * * Project: E131 - E.131 (sACN) library for Arduino * Copyright (c) 2015 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, * subject to the laws and regulations where you are using it. Due diligence * is strongly suggested before using this code. Please give credit where due. * * The Author makes no warranty of any kind, express or implied, with regard * to this program or the documentation contained in this document. The * Author shall not be liable in any event for incidental or consequential * damages in connection with, or arising out of, the furnishing, performance * or use of these programs. * * Modified to work on RP2040 by Amelia Deck * This version will not run anymore on ESP32 due to changes to the includes. * */ #include "e131.h" #include /* E1.17 ACN Packet Identifier */ #ifdef ARDUINO_ARCH_AVR const PROGMEM byte E131::ACN_ID[12] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 }; #else const byte E131::ACN_ID[12] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 }; #endif Wiznet5500lwIP eth(17, SPI, 21); // 17 : cs, 21 : INTn /* Constructor */ E131::E131() { #ifdef NO_DOUBLE_BUFFER memset(pbuff1.raw, 0, sizeof(pbuff1.raw)); packet = &pbuff1; pwbuff = packet; #else memset(pbuff1.raw, 0, sizeof(pbuff1.raw)); memset(pbuff2.raw, 0, sizeof(pbuff2.raw)); packet = &pbuff1; pwbuff = &pbuff2; #endif stats.num_packets = 0; stats.packet_errors = 0; } void E131::initUnicast() { delay(100); udp.begin(E131_DEFAULT_PORT); if (Serial) { Serial.print(F("- Unicast port: ")); Serial.println(E131_DEFAULT_PORT); } } void E131::initMulticast(uint16_t universe, uint8_t n) { delay(100); IPAddress address = IPAddress(239, 255, ((universe >> 8) & 0xff), ((universe >> 0) & 0xff)); #ifdef INT_ESP8266 ip_addr_t ifaddr; ip_addr_t multicast_addr; ifaddr.addr = static_cast(WiFi.localIP()); for (uint8_t i = 1; i < n; i++) { multicast_addr.addr = static_cast(IPAddress(239, 255, (((universe + i) >> 8) & 0xff), (((universe + i) >> 0) & 0xff))); igmp_joingroup(&ifaddr, &multicast_addr); } udp.beginMulticast(WiFi.localIP(), address, E131_DEFAULT_PORT); #endif if (Serial) { Serial.println(F("- Multicast Enabled")); } } /****** START - Wireless ifdef block ******/ #if defined (INT_ESP8266) || defined (INT_WIFI) /* WiFi Initialization */ int E131::initWiFi(const char *ssid, const char *passphrase) { /* Switch to station mode and disconnect just in case */ WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); if (Serial) { Serial.println(""); Serial.print(F("Connecting to ")); Serial.print(ssid); } if (passphrase != NULL) WiFi.begin(ssid, passphrase); else WiFi.begin(ssid); uint32_t timeout = millis(); uint8_t retval = 1; while (WiFi.status() != WL_CONNECTED) { delay(250); if (Serial) Serial.print("."); if (millis() - timeout > WIFI_CONNECT_TIMEOUT) { retval = 0; if (Serial) { Serial.println(""); Serial.println(F("*** Failed to connect ***")); } break; } } return retval; } void E131::begin(e131_listen_t type, uint16_t universe, uint8_t n) { if (type == E131_UNICAST) initUnicast(); if (type == E131_MULTICAST) initMulticast(universe, n); } int E131::begin(const char *ssid, const char *passphrase) { if (initWiFi(ssid, passphrase)) { if (Serial) { Serial.println(""); Serial.print(F("Connected DHCP with IP: ")); Serial.println(WiFi.localIP()); } initUnicast(); } return WiFi.status(); } int E131::begin(const char *ssid, const char *passphrase, IPAddress ip, IPAddress netmask, IPAddress gateway, IPAddress dns) { if (initWiFi(ssid, passphrase)) { WiFi.config(ip, gateway, netmask, dns); if (Serial) { Serial.println(""); Serial.print(F("Connected with Static IP: ")); Serial.println(WiFi.localIP()); } initUnicast(); } return WiFi.status(); } #endif /****** END - Wireless ifdef block ******/ /****** START - ESP8266 ifdef block ******/ #if defined (INT_ESP8266) int E131::beginMulticast(const char *ssid, const char *passphrase, uint16_t universe, uint8_t n) { if (initWiFi(ssid, passphrase)) { if (Serial) { Serial.println(""); Serial.print(F("Connected DHCP with IP: ")); Serial.println(WiFi.localIP()); } initMulticast(universe, n); } return WiFi.status(); } int E131::beginMulticast(const char *ssid, const char *passphrase, uint16_t universe, IPAddress ip, IPAddress netmask, IPAddress gateway, IPAddress dns, uint8_t n) { if (initWiFi(ssid, passphrase)) { WiFi.config(ip, dns, gateway, netmask); if (Serial) { Serial.println(""); Serial.print(F("Connected with Static IP: ")); Serial.println(WiFi.localIP()); } initMulticast(universe, n); } return WiFi.status(); } #endif /****** END - ESP8266 ifdef block ******/ /****** START - Ethernet ifdef block ******/ #if defined (INT_ETHERNET) /* Unicast Ethernet Initializers */ int E131::begin() { int retval = 0; if (Serial) { Serial.println(""); Serial.println(F("Requesting Address via DHCP")); Serial.println(""); } SPI.setRX(16); SPI.setCS(17); SPI.setSCK(18); SPI.setTX(19); //eth.setSPISpeed(30000000); //lwipPollingPeriod(3); if (!eth.begin()) { Serial.println("No wired Ethernet hardware detected. Check pinouts, wiring."); return false; } while (!eth.connected()) { Serial.print("."); delay(500); } retval = eth.connected(); if (Serial) { if (retval) { Serial.print(F("\n- IP Address: ")); Serial.println(eth.localIP()); } else { Serial.println(F("** DHCP FAILED")); } } if (retval) initUnicast(); return retval; } /* Multicast Ethernet Initializers */ int E131::beginMulticast(uint8_t *mac, uint16_t universe, uint8_t n) { //TODO: Add ethernet multicast support return -1; } void E131::beginMulticast(uint8_t *mac, uint16_t universe, IPAddress ip, IPAddress netmask, IPAddress gateway, IPAddress dns, uint8_t n) { //TODO: Add ethernet multicast support //return -1; } #endif /****** END - Ethernet ifdef block ******/ void E131::dumpError(e131_error_t error) { switch (error) { case ERROR_ACN_ID: Serial.print(F("INVALID PACKET ID: ")); for (int i = 0; i < sizeof(ACN_ID); i++) Serial.print(pwbuff->acn_id[i], HEX); Serial.println(""); break; case ERROR_PACKET_SIZE: Serial.println(F("INVALID PACKET SIZE: ")); break; case ERROR_VECTOR_ROOT: Serial.print(F("INVALID ROOT VECTOR: 0x")); Serial.println(htonl(pwbuff->root_vector), HEX); break; case ERROR_VECTOR_FRAME: Serial.print(F("INVALID FRAME VECTOR: 0x")); Serial.println(htonl(pwbuff->frame_vector), HEX); break; case ERROR_VECTOR_DMP: Serial.print(F("INVALID DMP VECTOR: 0x")); Serial.println(pwbuff->dmp_vector, HEX); } }