diff --git a/firmware/ChibiOS b/firmware/ChibiOS index c62811da8c..45965706d0 160000 --- a/firmware/ChibiOS +++ b/firmware/ChibiOS @@ -1 +1 @@ -Subproject commit c62811da8c73aef9960d59560c56ca663986d8f4 +Subproject commit 45965706d04b640c2dd7d267afc63e82aac56a32 diff --git a/firmware/Makefile b/firmware/Makefile index c5b89aced8..17024d4847 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -166,6 +166,11 @@ include $(CHIBIOS)/os/ex/devices/ST/lis302dl.mk endif include $(CHIBIOS)/os/hal/lib/streams/streams.mk include $(CHIBIOS)/os/various/cpp_wrappers/chcpp.mk + +ifeq ($(LWIP),yes) + include $(CHIBIOS)/os/various/lwip_bindings/lwip.mk +endif + include $(CHIBIOS)/os/hal/lib/complex/mfs/hal_mfs.mk ifeq ($(USE_FATFS),yes) @@ -209,6 +214,7 @@ $(info LDSCRIPT: $(LDSCRIPT)) CSRC = $(ALLCSRC) \ $(CHIBIOS)/os/various/syscalls.c \ $(CHIBIOS_CONTRIB)/os/various/ramdisk.c \ + $(CHIBIOS)/os/various/evtimer.c \ $(TRIGGER_SRC) \ $(TRIGGER_DECODERS_SRC) \ $(DEV_SRC) \ diff --git a/firmware/console/console.mk b/firmware/console/console.mk index de9f9450f7..7a8cc21c25 100644 --- a/firmware/console/console.mk +++ b/firmware/console/console.mk @@ -9,6 +9,7 @@ CONSOLE_SRC_CPP = $(PROJECT_DIR)/console/status_loop.cpp \ $(PROJECT_DIR)/console/binary_log/log_field.cpp \ $(PROJECT_DIR)/console/binary_log/binary_logging.cpp \ $(PROJECT_DIR)/console/binary_log/usb_console.cpp \ + $(PROJECT_DIR)/console/binary_log/ethernet_console.cpp \ CONSOLE_INC=\ diff --git a/firmware/console/eficonsole.h b/firmware/console/eficonsole.h index 9de61c6a31..77a049f2d6 100644 --- a/firmware/console/eficonsole.h +++ b/firmware/console/eficonsole.h @@ -10,3 +10,4 @@ void initializeConsole(); void startUsbConsole(); +void startEthernetConsole(); diff --git a/firmware/console/ethernet_console.cpp b/firmware/console/ethernet_console.cpp new file mode 100644 index 0000000000..5963b5d572 --- /dev/null +++ b/firmware/console/ethernet_console.cpp @@ -0,0 +1,98 @@ +#include "pch.h" + +#if EFI_ETHERNET + +#include "lwipthread.h" + +#include "lwip/sockets.h" + +#include "thread_controller.h" +#include "tunerstudio.h" + +static int listenerSocket = -1; +static int connectionSocket = -1; + +static void do_connection() { + if (connectionSocket != -1) { + auto localCopy = connectionSocket; + connectionSocket = -1; + + lwip_close(localCopy); + } + + sockaddr_in remote; + socklen_t size = sizeof(remote); + connectionSocket = lwip_accept(listenerSocket, (sockaddr*)&remote, &size); +} + +class EthernetChannel : public TsChannelBase { +public: + EthernetChannel() + : TsChannelBase("Ethernet") + { + } + + bool isReady() const override { + return connectionSocket != -1; + } + + void write(const uint8_t* buffer, size_t size) override { + lwip_send(connectionSocket, buffer, size, 0); + } + + size_t readTimeout(uint8_t* buffer, size_t size, int timeout) override { + auto result = lwip_recv(connectionSocket, buffer, size, 0); + + if (result == -1) { + do_connection(); + return 0; + } + + return result; + } +}; + +static EthernetChannel ethChannel; + +struct EthernetThread : public TunerstudioThread { + EthernetThread() : TunerstudioThread("Ethernet Console") { } + + TsChannelBase* setupChannel() override { + lwipInit(nullptr); + + sockaddr_in address; + address.sin_family = AF_INET; + address.sin_port = htons(29000); + address.sin_addr.s_addr = INADDR_ANY; + + listenerSocket = lwip_socket(AF_INET, SOCK_STREAM, 0); + lwip_bind(listenerSocket, (sockaddr*)&address, sizeof(address)); + lwip_listen(listenerSocket, 1); + + do_connection(); + + return ðChannel; + } +}; + +static EthernetThread ethernetConsole; + +void startEthernetConsole() { + efiSetPadMode("ethernet", GPIOA_1, PAL_MODE_ALTERNATE(0xb)); + efiSetPadMode("ethernet", GPIOA_2, PAL_MODE_ALTERNATE(0xb)); + efiSetPadMode("ethernet", GPIOA_7, PAL_MODE_ALTERNATE(0xb)); + + efiSetPadMode("ethernet", GPIOC_1, PAL_MODE_ALTERNATE(0xb)); + efiSetPadMode("ethernet", GPIOC_4, PAL_MODE_ALTERNATE(0xb)); + efiSetPadMode("ethernet", GPIOC_5, PAL_MODE_ALTERNATE(0xb)); + + efiSetPadMode("ethernet", GPIOD_5, PAL_MODE_ALTERNATE(0xb)); + + efiSetPadMode("ethernet", GPIOG_11, PAL_MODE_ALTERNATE(0xb)); + efiSetPadMode("ethernet", GPIOG_13, PAL_MODE_ALTERNATE(0xb)); + efiSetPadMode("ethernet", GPIOG_14, PAL_MODE_ALTERNATE(0xb)); + + ethernetConsole.Start(); +} + +#endif // EFI_ETHERNET diff --git a/firmware/console/lwipopts.h b/firmware/console/lwipopts.h new file mode 100644 index 0000000000..b293e94288 --- /dev/null +++ b/firmware/console/lwipopts.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef LWIP_HDR_LWIPOPTS_H__ +#define LWIP_HDR_LWIPOPTS_H__ + +/* Fixed settings mandated by the ChibiOS integration.*/ +#include "static_lwipopts.h" + +#define DEFAULT_TCP_RECVMBOX_SIZE 40 +#define DEFAULT_ACCEPTMBOX_SIZE 4 + +/* Optional, application-specific settings.*/ +#if !defined(TCPIP_MBOX_SIZE) +#define TCPIP_MBOX_SIZE MEMP_NUM_PBUF +#endif +#if !defined(TCPIP_THREAD_STACKSIZE) +#define TCPIP_THREAD_STACKSIZE 1024 +#endif + +/* Use ChibiOS specific priorities. */ +#if !defined(TCPIP_THREAD_PRIO) +#define TCPIP_THREAD_PRIO (NORMALPRIO + 5) +#endif +#if !defined(LWIP_THREAD_PRIORITY) +#define LWIP_THREAD_PRIORITY (NORMALPRIO + 4) +#endif + +#define LWIP_LINK_POLL_INTERVAL TIME_S2I(1) +#define LWIP_IPADDR(p) IP4_ADDR(p, 192, 168, 10, 14) +#define LWIP_GATEWAY(p) IP4_ADDR(p, 192, 168, 10, 1) + +#define LWIP_COMPAT_SOCKETS 0 + +#endif /* LWIP_HDR_LWIPOPTS_H__ */ diff --git a/firmware/hw_layer/ports/rusefi_halconf.h b/firmware/hw_layer/ports/rusefi_halconf.h index 89edbee0e7..9e157a8e8a 100644 --- a/firmware/hw_layer/ports/rusefi_halconf.h +++ b/firmware/hw_layer/ports/rusefi_halconf.h @@ -37,6 +37,9 @@ // only the MSD driver requires USB_USE_WAIT #define USB_USE_WAIT (EFI_FILE_LOGGING && EFI_USB_SERIAL) +// Ethernet +#define HAL_USE_MAC EFI_ETHERNET + /*===========================================================================*/ /* Required rusEFI settings */ /*===========================================================================*/ @@ -86,3 +89,7 @@ // Extra field in the UART driver's struct to store a reference to the DMA receive buffer object #define UART_DRIVER_EXT_FIELDS void* dmaAdapterInstance; + +// Ethernet MAC +#define MAC_USE_ZERO_COPY FALSE +#define MAC_USE_EVENTS TRUE diff --git a/firmware/hw_layer/ports/stm32/mcuconf_common_f4_f7.h b/firmware/hw_layer/ports/stm32/mcuconf_common_f4_f7.h index c7039a90ae..4292a829c4 100644 --- a/firmware/hw_layer/ports/stm32/mcuconf_common_f4_f7.h +++ b/firmware/hw_layer/ports/stm32/mcuconf_common_f4_f7.h @@ -175,7 +175,7 @@ #define STM32_MAC_PHY_TIMEOUT 100 #define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE #define STM32_MAC_ETH1_IRQ_PRIORITY 13 -#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0 +#define STM32_MAC_IP_CHECKSUM_OFFLOAD 3 /* * PWM driver system settings. diff --git a/firmware/hw_layer/ports/stm32/stm32f4/board.h b/firmware/hw_layer/ports/stm32/stm32f4/board.h index 65b06cbc6b..741f3e6bbb 100644 --- a/firmware/hw_layer/ports/stm32/stm32f4/board.h +++ b/firmware/hw_layer/ports/stm32/stm32f4/board.h @@ -33,6 +33,12 @@ // Ignore USB VBUS pin (we're never a host, only a device) #define BOARD_OTG_NOVBUSSENS TRUE +/* + * Ethernet PHY type. + */ +#define BOARD_PHY_ID MII_LAN8742A_ID +#define BOARD_PHY_RMII + /* * Default to input mode, with internal pulldown resistor enabled. */ diff --git a/firmware/hw_layer/ports/stm32/stm32f4/cfg/chconf.h b/firmware/hw_layer/ports/stm32/stm32f4/cfg/chconf.h index cb59bb2e30..d0c5c2fd58 100644 --- a/firmware/hw_layer/ports/stm32/stm32f4/cfg/chconf.h +++ b/firmware/hw_layer/ports/stm32/stm32f4/cfg/chconf.h @@ -324,7 +324,7 @@ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. */ #if !defined(CH_CFG_USE_DYNAMIC) -#define CH_CFG_USE_DYNAMIC FALSE +#define CH_CFG_USE_DYNAMIC TRUE #endif /** @} */ diff --git a/firmware/hw_layer/ports/stm32/stm32f7/cfg/chconf.h b/firmware/hw_layer/ports/stm32/stm32f7/cfg/chconf.h index cb59bb2e30..d0c5c2fd58 100644 --- a/firmware/hw_layer/ports/stm32/stm32f7/cfg/chconf.h +++ b/firmware/hw_layer/ports/stm32/stm32f7/cfg/chconf.h @@ -324,7 +324,7 @@ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. */ #if !defined(CH_CFG_USE_DYNAMIC) -#define CH_CFG_USE_DYNAMIC FALSE +#define CH_CFG_USE_DYNAMIC TRUE #endif /** @} */ diff --git a/firmware/rusefi.cpp b/firmware/rusefi.cpp index db68d0521a..3a6039436a 100644 --- a/firmware/rusefi.cpp +++ b/firmware/rusefi.cpp @@ -188,6 +188,10 @@ void runRusEfi(void) { // Perform hardware initialization that doesn't need configuration initHardwareNoConfig(); +#if EFI_ETHERNET + startEthernetConsole(); +#endif + #if EFI_USB_SERIAL startUsbConsole(); #endif