Teensy 4.1 Ethernet support (#19801)
parent
92767f5513
commit
9baa944460
@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../inc/MarlinConfigPre.h"
|
||||
|
||||
#if HAS_ETHERNET
|
||||
|
||||
#include "ethernet.h"
|
||||
#include "../core/serial.h"
|
||||
|
||||
#define DEBUG_OUT ENABLED(DEBUG_ETHERNET)
|
||||
#include "../core/debug_out.h"
|
||||
|
||||
bool MarlinEthernet::hardware_enabled, // = false
|
||||
MarlinEthernet::have_telnet_client; // = false
|
||||
|
||||
IPAddress MarlinEthernet::ip,
|
||||
MarlinEthernet::myDns,
|
||||
MarlinEthernet::gateway,
|
||||
MarlinEthernet::subnet;
|
||||
|
||||
EthernetClient MarlinEthernet::telnetClient; // connected client
|
||||
|
||||
MarlinEthernet ethernet;
|
||||
|
||||
EthernetServer server(23); // telnet server
|
||||
|
||||
enum linkStates { UNLINKED, LINKING, LINKED, CONNECTING, CONNECTED, NO_HARDWARE } linkState;
|
||||
|
||||
#ifdef __IMXRT1062__
|
||||
|
||||
static void teensyMAC(uint8_t * const mac) {
|
||||
const uint32_t m1 = HW_OCOTP_MAC1, m2 = HW_OCOTP_MAC0;
|
||||
mac[0] = m1 >> 8;
|
||||
mac[1] = m1 >> 0;
|
||||
mac[2] = m2 >> 24;
|
||||
mac[3] = m2 >> 16;
|
||||
mac[4] = m2 >> 8;
|
||||
mac[5] = m2 >> 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
byte mac[] = MAC_ADDRESS;
|
||||
|
||||
#endif
|
||||
|
||||
void ethernet_cable_error() { SERIAL_ERROR_MSG("Ethernet cable is not connected."); }
|
||||
|
||||
void MarlinEthernet::init() {
|
||||
if (!hardware_enabled) return;
|
||||
|
||||
SERIAL_ECHO_MSG("Starting network...");
|
||||
|
||||
// Init the Ethernet device
|
||||
#ifdef __IMXRT1062__
|
||||
uint8_t mac[6];
|
||||
teensyMAC(mac);
|
||||
#endif
|
||||
|
||||
if (!ip) {
|
||||
Ethernet.begin(mac); // use DHCP
|
||||
}
|
||||
else {
|
||||
if (!gateway) {
|
||||
gateway = ip;
|
||||
gateway[3] = 1;
|
||||
myDns = gateway;
|
||||
subnet = IPAddress(255,255,255,0);
|
||||
}
|
||||
if (!myDns) myDns = gateway;
|
||||
if (!subnet) subnet = IPAddress(255,255,255,0);
|
||||
Ethernet.begin(mac, ip, myDns, gateway, subnet);
|
||||
}
|
||||
|
||||
// Check for Ethernet hardware present
|
||||
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
|
||||
SERIAL_ERROR_MSG("No Ethernet hardware found.");
|
||||
linkState = NO_HARDWARE;
|
||||
return;
|
||||
}
|
||||
|
||||
linkState = UNLINKED;
|
||||
|
||||
if (Ethernet.linkStatus() == LinkOFF)
|
||||
ethernet_cable_error();
|
||||
}
|
||||
|
||||
void MarlinEthernet::check() {
|
||||
if (!hardware_enabled) return;
|
||||
|
||||
switch (linkState) {
|
||||
case NO_HARDWARE:
|
||||
break;
|
||||
|
||||
case UNLINKED:
|
||||
if (Ethernet.linkStatus() == LinkOFF) break;
|
||||
|
||||
SERIAL_ECHOLNPGM("Ethernet cable connected");
|
||||
server.begin();
|
||||
linkState = LINKING;
|
||||
break;
|
||||
|
||||
case LINKING:
|
||||
if (!Ethernet.localIP()) break;
|
||||
|
||||
SERIAL_ECHOPGM("Successfully started telnet server with IP ");
|
||||
MYSERIAL0.println(Ethernet.localIP());
|
||||
|
||||
linkState = LINKED;
|
||||
break;
|
||||
|
||||
case LINKED:
|
||||
if (Ethernet.linkStatus() == LinkOFF) {
|
||||
ethernet_cable_error();
|
||||
linkState = UNLINKED;
|
||||
break;
|
||||
}
|
||||
telnetClient = server.accept();
|
||||
if (telnetClient) linkState = CONNECTING;
|
||||
break;
|
||||
|
||||
case CONNECTING:
|
||||
telnetClient.println("Marlin " SHORT_BUILD_VERSION);
|
||||
#if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR)
|
||||
telnetClient.println(
|
||||
" Last Updated: " STRING_DISTRIBUTION_DATE
|
||||
" | Author: " STRING_CONFIG_H_AUTHOR
|
||||
);
|
||||
#endif
|
||||
telnetClient.println("Compiled: " __DATE__);
|
||||
|
||||
SERIAL_ECHOLNPGM("Client connected");
|
||||
have_telnet_client = true;
|
||||
linkState = CONNECTED;
|
||||
break;
|
||||
|
||||
case CONNECTED:
|
||||
if (telnetClient && !telnetClient.connected()) {
|
||||
SERIAL_ECHOLNPGM("Client disconnected");
|
||||
telnetClient.stop();
|
||||
have_telnet_client = false;
|
||||
linkState = LINKED;
|
||||
}
|
||||
if (Ethernet.linkStatus() == LinkOFF) {
|
||||
ethernet_cable_error();
|
||||
if (telnetClient) telnetClient.stop();
|
||||
linkState = UNLINKED;
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAS_ETHERNET
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifdef __IMXRT1062__
|
||||
#include <NativeEthernet.h>
|
||||
#endif
|
||||
|
||||
// Teensy 4.1 uses internal MAC Address
|
||||
|
||||
class MarlinEthernet {
|
||||
public:
|
||||
static bool hardware_enabled, have_telnet_client;
|
||||
static IPAddress ip, myDns, gateway, subnet;
|
||||
static EthernetClient telnetClient;
|
||||
static void init();
|
||||
static void check();
|
||||
};
|
||||
|
||||
extern MarlinEthernet ethernet;
|
@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if HAS_ETHERNET
|
||||
|
||||
#include "../../../feature/ethernet.h"
|
||||
#include "../../../core/serial.h"
|
||||
#include "../../gcode.h"
|
||||
|
||||
void say_ethernet() { SERIAL_ECHOPGM(" Ethernet "); }
|
||||
|
||||
void ETH0_report() {
|
||||
say_ethernet();
|
||||
SERIAL_ECHO_TERNARY(ethernet.hardware_enabled, "port ", "en", "dis", "abled.\n");
|
||||
if (ethernet.hardware_enabled) {
|
||||
say_ethernet();
|
||||
SERIAL_ECHO_TERNARY(ethernet.have_telnet_client, "client ", "en", "dis", "abled.\n");
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM("Send 'M552 S1' to enable.");
|
||||
}
|
||||
|
||||
void MAC_report() {
|
||||
uint8_t mac[6];
|
||||
if (ethernet.hardware_enabled) {
|
||||
Ethernet.MACAddress(mac);
|
||||
SERIAL_ECHOPGM(" MAC: ");
|
||||
LOOP_L_N(i, 6) {
|
||||
SERIAL_PRINTF("%02X", mac[i]);
|
||||
if (i < 5) SERIAL_CHAR(':');
|
||||
}
|
||||
}
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
// Display current values when the link is active,
|
||||
// otherwise show the stored values
|
||||
void ip_report(const uint16_t cmd, PGM_P const post, const IPAddress &ipo) {
|
||||
SERIAL_CHAR('M'); SERIAL_ECHO(cmd); SERIAL_CHAR(' ');
|
||||
LOOP_L_N(i, 4) {
|
||||
SERIAL_ECHO(ipo[i]);
|
||||
if (i < 3) SERIAL_CHAR('.');
|
||||
}
|
||||
SERIAL_ECHOPGM(" ; ");
|
||||
SERIAL_ECHOPGM_P(post);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
void M552_report() {
|
||||
ip_report(552, PSTR("ip address"), Ethernet.linkStatus() == LinkON ? Ethernet.localIP() : ethernet.ip);
|
||||
}
|
||||
void M553_report() {
|
||||
ip_report(553, PSTR("subnet mask"), Ethernet.linkStatus() == LinkON ? Ethernet.subnetMask() : ethernet.subnet);
|
||||
}
|
||||
void M554_report() {
|
||||
ip_report(554, PSTR("gateway"), Ethernet.linkStatus() == LinkON ? Ethernet.gatewayIP() : ethernet.gateway);
|
||||
}
|
||||
|
||||
/**
|
||||
* M552: Set IP address, enable/disable network interface
|
||||
*
|
||||
* S0 : disable networking
|
||||
* S1 : enable networking
|
||||
* S-1 : reset network interface
|
||||
*
|
||||
* Pnnn : Set IP address, 0.0.0.0 means acquire an IP address using DHCP
|
||||
*/
|
||||
void GcodeSuite::M552() {
|
||||
const bool seenP = parser.seenval('P');
|
||||
if (seenP) ethernet.ip.fromString(parser.value_string());
|
||||
|
||||
const bool seenS = parser.seenval('S');
|
||||
if (seenS) {
|
||||
switch (parser.value_int()) {
|
||||
case -1:
|
||||
if (ethernet.telnetClient) ethernet.telnetClient.stop();
|
||||
ethernet.init();
|
||||
break;
|
||||
case 0: ethernet.hardware_enabled = false; break;
|
||||
case 1: ethernet.hardware_enabled = true; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
const bool nopar = !seenS && !seenP;
|
||||
if (nopar || seenS) ETH0_report();
|
||||
if (nopar || seenP) M552_report();
|
||||
}
|
||||
|
||||
/**
|
||||
* M553 Pnnn - Set netmask
|
||||
*/
|
||||
void GcodeSuite::M553() {
|
||||
if (parser.seenval('P')) ethernet.subnet.fromString(parser.value_string());
|
||||
M553_report();
|
||||
}
|
||||
|
||||
/**
|
||||
* M554 Pnnn - Set Gateway
|
||||
*/
|
||||
void GcodeSuite::M554() {
|
||||
if (parser.seenval('P')) ethernet.gateway.fromString(parser.value_string());
|
||||
M554_report();
|
||||
}
|
||||
|
||||
#endif // HAS_ETHERNET
|
Loading…
Reference in New Issue