From 85a3315a998ce7c625796177a665e6f4cd373e73 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 9 Mar 2020 15:51:29 +0700 Subject: Adding lwip_webserver to ci - buil_al.py skip specific MCU if .skip.MCU_ exists - reduce stm32f070 heap & stack size to compile webserver --- examples/device/lwip_webserver/.skip.MCU_LPC11UXX | 0 examples/device/lwip_webserver/.skip.MCU_LPC13XX | 0 examples/device/lwip_webserver/.skip.MCU_NUC121 | 0 examples/device/lwip_webserver/.skip.MCU_STM32L0 | 0 hw/bsp/samg55xplained/samg55xplained.c | 3 +- hw/bsp/spresense/board.mk | 4 +- hw/bsp/stm32f070rbnucleo/stm32F070rbtx_flash.ld | 4 +- src/class/net/net_device.h | 2 + tools/build_all.py | 56 ++++++++++++++++------- tools/build_success.sh | 10 ---- 10 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 examples/device/lwip_webserver/.skip.MCU_LPC11UXX create mode 100644 examples/device/lwip_webserver/.skip.MCU_LPC13XX create mode 100644 examples/device/lwip_webserver/.skip.MCU_NUC121 create mode 100644 examples/device/lwip_webserver/.skip.MCU_STM32L0 delete mode 100644 tools/build_success.sh diff --git a/examples/device/lwip_webserver/.skip.MCU_LPC11UXX b/examples/device/lwip_webserver/.skip.MCU_LPC11UXX new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/lwip_webserver/.skip.MCU_LPC13XX b/examples/device/lwip_webserver/.skip.MCU_LPC13XX new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/lwip_webserver/.skip.MCU_NUC121 b/examples/device/lwip_webserver/.skip.MCU_NUC121 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/lwip_webserver/.skip.MCU_STM32L0 b/examples/device/lwip_webserver/.skip.MCU_STM32L0 new file mode 100644 index 000000000..e69de29bb diff --git a/hw/bsp/samg55xplained/samg55xplained.c b/hw/bsp/samg55xplained/samg55xplained.c index a5e145734..66a3d137f 100644 --- a/hw/bsp/samg55xplained/samg55xplained.c +++ b/hw/bsp/samg55xplained/samg55xplained.c @@ -24,13 +24,14 @@ */ #include "sam.h" +#include "bsp/board.h" + #include "peripheral_clk_config.h" #include "hal/include/hal_init.h" #include "hal/include/hpl_usart_sync.h" #include "hpl/pmc/hpl_pmc.h" #include "hal/include/hal_gpio.h" -#include "bsp/board.h" //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION diff --git a/hw/bsp/spresense/board.mk b/hw/bsp/spresense/board.mk index 2e88cf994..c6b5ce12a 100644 --- a/hw/bsp/spresense/board.mk +++ b/hw/bsp/spresense/board.mk @@ -1,5 +1,4 @@ CFLAGS += \ - -DCONFIG_WCHAR_BUILTIN \ -DCONFIG_HAVE_DOUBLE \ -Dmain=spresense_main \ -pipe \ @@ -14,6 +13,9 @@ CFLAGS += \ -fomit-frame-pointer \ -DCFG_TUSB_MCU=OPT_MCU_CXD56 \ +# lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration +CFLAGS += -Wno-error=shadow + SPRESENSE_SDK = $(TOP)/hw/mcu/sony/cxd56/spresense-exported-sdk INC += \ diff --git a/hw/bsp/stm32f070rbnucleo/stm32F070rbtx_flash.ld b/hw/bsp/stm32f070rbnucleo/stm32F070rbtx_flash.ld index 7ae8e5960..59e18f375 100644 --- a/hw/bsp/stm32f070rbnucleo/stm32F070rbtx_flash.ld +++ b/hw/bsp/stm32f070rbnucleo/stm32F070rbtx_flash.ld @@ -55,8 +55,8 @@ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x20004000; /* end of "RAM" Ram type memory */ -_Min_Heap_Size = 0x400; /* required amount of heap */ -_Min_Stack_Size = 0x600; /* required amount of stack */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ /* Memories definition */ MEMORY diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index fee54163f..71483364d 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -31,6 +31,8 @@ #include "common/tusb_common.h" #include "device/usbd.h" #include "class/cdc/cdc.h" + +// TODO should not include external files #include "lwip/pbuf.h" #include "netif/ethernet.h" diff --git a/tools/build_all.py b/tools/build_all.py index 97294a9a3..45ae8d4d5 100644 --- a/tools/build_all.py +++ b/tools/build_all.py @@ -1,5 +1,5 @@ import os -import shutil +import glob import sys import subprocess import time @@ -10,9 +10,8 @@ exit_status = 0 total_time = time.monotonic() +# 1st Argument is Example, build all examples if not existed all_examples = [] - -# build all example if input not existed if len(sys.argv) > 1: all_examples.append(sys.argv[1]) else: @@ -22,11 +21,17 @@ else: # TODO update freeRTOS example to work with all boards (only nrf52840 now) all_examples.remove("cdc_msc_hid_freertos") +all_examples.sort() +# 2nd Argument is Board, build all boards if not existed all_boards = [] -for entry in os.scandir("hw/bsp"): - if entry.is_dir(): - all_boards.append(entry.name) +if len(sys.argv) > 2: + all_boards.append(sys.argv[2]) +else: + for entry in os.scandir("hw/bsp"): + if entry.is_dir(): + all_boards.append(entry.name) +all_boards.sort() def build_example(example, board): @@ -35,6 +40,16 @@ def build_example(example, board): return subprocess.run("make -j 4 -C examples/device/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) +def skip_example(example, board): + ex_dir = 'examples/device/' + example + board_mk = 'hw/bsp/{}/board.mk'.format(board) + for skip_file in glob.iglob(ex_dir + '/.skip.MCU_*'): + mcu_cflag = '-DCFG_TUSB_MCU=OPT_' + os.path.basename(skip_file).split('.')[2] + with open(board_mk) as mk: + if mcu_cflag in mk.read(): + return 1 + + return 0 build_format = '| {:30} | {:30} | {:9} ' build_separator = '-' * 87 @@ -44,20 +59,27 @@ for example in all_examples: print(build_separator) for board in all_boards: start_time = time.monotonic() - build_result = build_example(example, board) - build_duration = time.monotonic() - start_time - if build_result.returncode == 0: - success = "\033[32msucceeded\033[0m" - success_count += 1 + # Check if board is skipped + if skip_example(example, board): + success = "\033[33mskipped\033[0m " + print((build_format + '| {:.2f}s |').format(example, board, success, 0)) else: - exit_status = build_result.returncode - success = "\033[31mfailed\033[0m " - fail_count += 1 + build_result = build_example(example, board) + + if build_result.returncode == 0: + success = "\033[32msucceeded\033[0m" + success_count += 1 + else: + exit_status = build_result.returncode + success = "\033[31mfailed\033[0m " + fail_count += 1 + + build_duration = time.monotonic() - start_time + print((build_format + '| {:.2f}s |').format(example, board, success, build_duration)) - print((build_format + '| {:.2f}s |').format(example, board, success, build_duration)) - if build_result.returncode != 0: - print(build_result.stdout.decode("utf-8")) + if build_result.returncode != 0: + print(build_result.stdout.decode("utf-8")) # FreeRTOS example # example = 'cdc_msc_hid_freertos' diff --git a/tools/build_success.sh b/tools/build_success.sh deleted file mode 100644 index df725bdce..000000000 --- a/tools/build_success.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -# Trigger mynewt-tinyusb-example repo each push -curl -s -X POST \ - -H "Content-Type: application/json" \ - -H "Accept: application/json" \ - -H "Travis-API-Version: 3" \ - -H "Authorization: token $TRAVIS_TOKEN" \ - -d '{ "request": { "branch":"master" }}' \ - https://api.travis-ci.com/repo/hathach%2Fmynewt-tinyusb-example/requests \ No newline at end of file -- cgit v1.3.1 From 1617b9d22e760647e1539cbf0fbb3a142f3960c2 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 9 Mar 2020 15:53:20 +0700 Subject: rename lwip_webserver to net_webserver for example naming convention (with class driver) --- examples/device/lwip_webserver/.skip.MCU_LPC11UXX | 0 examples/device/lwip_webserver/.skip.MCU_LPC13XX | 0 examples/device/lwip_webserver/.skip.MCU_NUC121 | 0 examples/device/lwip_webserver/.skip.MCU_STM32L0 | 0 examples/device/lwip_webserver/Makefile | 57 ------ examples/device/lwip_webserver/src/arch/cc.h | 75 -------- examples/device/lwip_webserver/src/lwipopts.h | 57 ------ examples/device/lwip_webserver/src/main.c | 214 --------------------- examples/device/lwip_webserver/src/tusb_config.h | 90 --------- .../device/lwip_webserver/src/usb_descriptors.c | 199 ------------------- .../device/lwip_webserver/src/usb_descriptors.h | 28 --- examples/device/net_webserver/.skip.MCU_LPC11UXX | 0 examples/device/net_webserver/.skip.MCU_LPC13XX | 0 examples/device/net_webserver/.skip.MCU_NUC121 | 0 examples/device/net_webserver/.skip.MCU_STM32L0 | 0 examples/device/net_webserver/Makefile | 57 ++++++ examples/device/net_webserver/src/arch/cc.h | 75 ++++++++ examples/device/net_webserver/src/lwipopts.h | 57 ++++++ examples/device/net_webserver/src/main.c | 214 +++++++++++++++++++++ examples/device/net_webserver/src/tusb_config.h | 90 +++++++++ .../device/net_webserver/src/usb_descriptors.c | 199 +++++++++++++++++++ .../device/net_webserver/src/usb_descriptors.h | 28 +++ 22 files changed, 720 insertions(+), 720 deletions(-) delete mode 100644 examples/device/lwip_webserver/.skip.MCU_LPC11UXX delete mode 100644 examples/device/lwip_webserver/.skip.MCU_LPC13XX delete mode 100644 examples/device/lwip_webserver/.skip.MCU_NUC121 delete mode 100644 examples/device/lwip_webserver/.skip.MCU_STM32L0 delete mode 100644 examples/device/lwip_webserver/Makefile delete mode 100644 examples/device/lwip_webserver/src/arch/cc.h delete mode 100644 examples/device/lwip_webserver/src/lwipopts.h delete mode 100644 examples/device/lwip_webserver/src/main.c delete mode 100644 examples/device/lwip_webserver/src/tusb_config.h delete mode 100644 examples/device/lwip_webserver/src/usb_descriptors.c delete mode 100644 examples/device/lwip_webserver/src/usb_descriptors.h create mode 100644 examples/device/net_webserver/.skip.MCU_LPC11UXX create mode 100644 examples/device/net_webserver/.skip.MCU_LPC13XX create mode 100644 examples/device/net_webserver/.skip.MCU_NUC121 create mode 100644 examples/device/net_webserver/.skip.MCU_STM32L0 create mode 100644 examples/device/net_webserver/Makefile create mode 100644 examples/device/net_webserver/src/arch/cc.h create mode 100644 examples/device/net_webserver/src/lwipopts.h create mode 100644 examples/device/net_webserver/src/main.c create mode 100644 examples/device/net_webserver/src/tusb_config.h create mode 100644 examples/device/net_webserver/src/usb_descriptors.c create mode 100644 examples/device/net_webserver/src/usb_descriptors.h diff --git a/examples/device/lwip_webserver/.skip.MCU_LPC11UXX b/examples/device/lwip_webserver/.skip.MCU_LPC11UXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/lwip_webserver/.skip.MCU_LPC13XX b/examples/device/lwip_webserver/.skip.MCU_LPC13XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/lwip_webserver/.skip.MCU_NUC121 b/examples/device/lwip_webserver/.skip.MCU_NUC121 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/lwip_webserver/.skip.MCU_STM32L0 b/examples/device/lwip_webserver/.skip.MCU_STM32L0 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/lwip_webserver/Makefile b/examples/device/lwip_webserver/Makefile deleted file mode 100644 index a153c30be..000000000 --- a/examples/device/lwip_webserver/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -include ../../../tools/top.mk -include ../../make.mk - -CFLAGS += \ - -DPBUF_POOL_SIZE=2 \ - -DTCP_WND=2*TCP_MSS \ - -DHTTPD_USE_CUSTOM_FSDATA=0 - -INC += \ - src \ - $(TOP)/hw \ - $(TOP)/lib/lwip/src/include \ - $(TOP)/lib/lwip/src/include/ipv4 \ - $(TOP)/lib/lwip/src/include/lwip/apps \ - $(TOP)/lib/networking - -# Example source -EXAMPLE_SOURCE += $(wildcard src/*.c) -SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -SRC_C += \ - lib/lwip/src/core/altcp.c \ - lib/lwip/src/core/altcp_alloc.c \ - lib/lwip/src/core/altcp_tcp.c \ - lib/lwip/src/core/def.c \ - lib/lwip/src/core/dns.c \ - lib/lwip/src/core/inet_chksum.c \ - lib/lwip/src/core/init.c \ - lib/lwip/src/core/ip.c \ - lib/lwip/src/core/mem.c \ - lib/lwip/src/core/memp.c \ - lib/lwip/src/core/netif.c \ - lib/lwip/src/core/pbuf.c \ - lib/lwip/src/core/raw.c \ - lib/lwip/src/core/stats.c \ - lib/lwip/src/core/sys.c \ - lib/lwip/src/core/tcp.c \ - lib/lwip/src/core/tcp_in.c \ - lib/lwip/src/core/tcp_out.c \ - lib/lwip/src/core/timeouts.c \ - lib/lwip/src/core/udp.c \ - lib/lwip/src/core/ipv4/autoip.c \ - lib/lwip/src/core/ipv4/dhcp.c \ - lib/lwip/src/core/ipv4/etharp.c \ - lib/lwip/src/core/ipv4/icmp.c \ - lib/lwip/src/core/ipv4/igmp.c \ - lib/lwip/src/core/ipv4/ip4.c \ - lib/lwip/src/core/ipv4/ip4_addr.c \ - lib/lwip/src/core/ipv4/ip4_frag.c \ - lib/lwip/src/netif/ethernet.c \ - lib/lwip/src/netif/slipif.c \ - lib/lwip/src/apps/http/httpd.c \ - lib/lwip/src/apps/http/fs.c \ - lib/networking/dhserver.c \ - lib/networking/dnserver.c \ - lib/networking/rndis_reports.c - -include ../../rules.mk diff --git a/examples/device/lwip_webserver/src/arch/cc.h b/examples/device/lwip_webserver/src/arch/cc.h deleted file mode 100644 index 56a0cacf7..000000000 --- a/examples/device/lwip_webserver/src/arch/cc.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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: Adam Dunkels - * - */ -#ifndef __CC_H__ -#define __CC_H__ - -//#include "cpu.h" - -typedef int sys_prot_t; - - - -/* define compiler specific symbols */ -#if defined (__ICCARM__) - -#define PACK_STRUCT_BEGIN -#define PACK_STRUCT_STRUCT -#define PACK_STRUCT_END -#define PACK_STRUCT_FIELD(x) x -#define PACK_STRUCT_USE_INCLUDES - -#elif defined (__CC_ARM) - -#define PACK_STRUCT_BEGIN __packed -#define PACK_STRUCT_STRUCT -#define PACK_STRUCT_END -#define PACK_STRUCT_FIELD(x) x - -#elif defined (__GNUC__) - -#define PACK_STRUCT_BEGIN -#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) -#define PACK_STRUCT_END -#define PACK_STRUCT_FIELD(x) x - -#elif defined (__TASKING__) - -#define PACK_STRUCT_BEGIN -#define PACK_STRUCT_STRUCT -#define PACK_STRUCT_END -#define PACK_STRUCT_FIELD(x) x - -#endif - -#define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0) - -#endif /* __CC_H__ */ diff --git a/examples/device/lwip_webserver/src/lwipopts.h b/examples/device/lwip_webserver/src/lwipopts.h deleted file mode 100644 index 23319592d..000000000 --- a/examples/device/lwip_webserver/src/lwipopts.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 __LWIPOPTS_H__ -#define __LWIPOPTS_H__ - -/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ -#define NO_SYS 1 -#define MEM_ALIGNMENT 4 -#define LWIP_RAW 1 -#define LWIP_NETCONN 0 -#define LWIP_SOCKET 0 -#define LWIP_DHCP 0 -#define LWIP_ICMP 1 -#define LWIP_UDP 1 -#define LWIP_TCP 1 -#define ETH_PAD_SIZE 0 -#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67)) - -#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) -#define TCP_SND_BUF (2 * TCP_MSS) - -#define ETHARP_SUPPORT_STATIC_ENTRIES 1 - -#define LWIP_HTTPD_CGI 0 -#define LWIP_HTTPD_SSI 0 -#define LWIP_HTTPD_SSI_INCLUDE_TAG 0 - -#endif /* __LWIPOPTS_H__ */ diff --git a/examples/device/lwip_webserver/src/main.c b/examples/device/lwip_webserver/src/main.c deleted file mode 100644 index c193aeb0f..000000000 --- a/examples/device/lwip_webserver/src/main.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Peter Lawrence - * - * influenced by lrndis https://github.com/fetisov/lrndis - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -/* -depending on the value of CFG_TUD_NET (tusb_config.h), this can be a CDC-ECM, RNDIS, or CDC-EEM USB virtual network adapter - -CDC-ECM should be valid on Linux and MacOS hosts -RNDIS should be valid on Linux and Windows hosts -CDC-EEM should be valid on Linux hosts - -You *must* customize tusb_config.h to set the CFG_TUD_NET definition to the type of these network adapters to emulate. - -The MCU appears to the host as IP address 192.168.7.1, and provides a DHCP server, DNS server, and web server. -*/ - -#include "bsp/board.h" -#include "tusb.h" - -#include "dhserver.h" -#include "dnserver.h" -#include "lwip/init.h" -#include "httpd.h" - -/* lwip context */ -static struct netif netif_data; - -/* shared between tud_network_recv_cb() and service_traffic() */ -static struct pbuf *received_frame; - -/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */ -/* ideally speaking, this should be generated from the hardware's unique ID (if available) */ -const uint8_t tud_network_mac_address[6] = {0x20,0x89,0x84,0x6A,0x96,0x00}; - -/* network parameters of this MCU */ -static const ip_addr_t ipaddr = IPADDR4_INIT_BYTES(192, 168, 7, 1); -static const ip_addr_t netmask = IPADDR4_INIT_BYTES(255, 255, 255, 0); -static const ip_addr_t gateway = IPADDR4_INIT_BYTES(0, 0, 0, 0); - -/* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */ -static dhcp_entry_t entries[] = -{ - /* mac ip address subnet mask lease time */ - { {0}, {192, 168, 7, 2}, {255, 255, 255, 0}, 24 * 60 * 60 }, - { {0}, {192, 168, 7, 3}, {255, 255, 255, 0}, 24 * 60 * 60 }, - { {0}, {192, 168, 7, 4}, {255, 255, 255, 0}, 24 * 60 * 60 } -}; - -/* DHCP configuration parameters, leveraging "entries" above */ -static const dhcp_config_t dhcp_config = -{ - {192, 168, 7, 1}, 67, /* server address (self), port */ - {192, 168, 7, 1}, /* dns server (self) */ - "usb", /* dns suffix */ - TU_ARRAY_SIZE(entries), /* number of entries */ - entries /* pointer to entries */ -}; - -static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) -{ - (void)netif; - - for (;;) - { - /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ - if (!tud_ready()) - return ERR_USE; - - /* if the network driver can accept another packet, we make it happen */ - if (tud_network_can_xmit()) - { - tud_network_xmit(p); - return ERR_OK; - } - - /* transfer execution to TinyUSB in the hopes that it will finish transmitting the prior packet */ - tud_task(); - } -} - -static err_t output_fn(struct netif *netif, struct pbuf *p, const ip_addr_t *addr) -{ - return etharp_output(netif, p, addr); -} - -static err_t netif_init_cb(struct netif *netif) -{ - LWIP_ASSERT("netif != NULL", (netif != NULL)); - netif->mtu = CFG_TUD_NET_MTU; - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; - netif->state = NULL; - netif->name[0] = 'E'; - netif->name[1] = 'X'; - netif->linkoutput = linkoutput_fn; - netif->output = output_fn; - return ERR_OK; -} - -static void init_lwip(void) -{ - struct netif *netif = &netif_data; - - lwip_init(); - netif->hwaddr_len = sizeof(tud_network_mac_address); - memcpy(netif->hwaddr, tud_network_mac_address, sizeof(tud_network_mac_address)); - - netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ip_input); - netif_set_default(netif); -} - -/* handle any DNS requests from dns-server */ -bool dns_query_proc(const char *name, ip_addr_t *addr) -{ - if (0 == strcmp(name, "tiny.usb")) - { - *addr = ipaddr; - return true; - } - return false; -} - -bool tud_network_recv_cb(struct pbuf *p) -{ - /* this shouldn't happen, but if we get another packet before - parsing the previous, we must signal our inability to accept it */ - if (received_frame) return false; - - /* store away the pointer for service_traffic() to later handle */ - received_frame = p; - return true; -} - -static void service_traffic(void) -{ - /* handle any packet received by tud_network_recv_cb() */ - if (received_frame) - { - ethernet_input(received_frame, &netif_data); - pbuf_free(received_frame); - received_frame = NULL; - tud_network_recv_renew(); - } -} - -void tud_network_init_cb(void) -{ - /* if the network is re-initializing and we have a leftover packet, we must do a cleanup */ - if (received_frame) - { - pbuf_free(received_frame); - received_frame = NULL; - } -} - -int main(void) -{ - /* initialize TinyUSB */ - board_init(); - tusb_init(); - - /* initialize lwip, dhcp-server, dns-server, and http */ - init_lwip(); - while (!netif_is_up(&netif_data)); - while (dhserv_init(&dhcp_config) != ERR_OK); - while (dnserv_init(&ipaddr, 53, dns_query_proc) != ERR_OK); - httpd_init(); - - while (1) - { - tud_task(); - service_traffic(); - } - - return 0; -} - -/* lwip has provision for using a mutex, when applicable */ -sys_prot_t sys_arch_protect(void) -{ - return 0; -} -void sys_arch_unprotect(sys_prot_t pval) -{ - (void)pval; -} - -/* lwip needs a millisecond time source, and the TinyUSB board support code has one available */ -uint32_t sys_now(void) -{ - return board_millis(); -} diff --git a/examples/device/lwip_webserver/src/tusb_config.h b/examples/device/lwip_webserver/src/tusb_config.h deleted file mode 100644 index 329fc80b9..000000000 --- a/examples/device/lwip_webserver/src/tusb_config.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -//-------------------------------------------------------------------- -// COMMON CONFIGURATION -//-------------------------------------------------------------------- - -// defined by compiler flags for flexibility -#ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) -#else -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE -#endif - -#define CFG_TUSB_OS OPT_OS_NONE - -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 - -/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. - * Tinyusb use follows macros to declare transferring memory so that they can be put - * into those specific section. - * e.g - * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) - * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) - */ -#ifndef CFG_TUSB_MEM_SECTION -#define CFG_TUSB_MEM_SECTION -#endif - -#ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) -#endif - -//-------------------------------------------------------------------- -// DEVICE CONFIGURATION -//-------------------------------------------------------------------- - -#ifndef CFG_TUD_ENDPOINT0_SIZE -#define CFG_TUD_ENDPOINT0_SIZE 64 -#endif - -//------------- CLASS -------------// -#define CFG_TUD_CDC 0 -#define CFG_TUD_MSC 0 -#define CFG_TUD_HID 0 -#define CFG_TUD_MIDI 0 -#define CFG_TUD_VENDOR 0 -//#define CFG_TUD_NET OPT_NET_ECM -#define CFG_TUD_NET OPT_NET_RNDIS -//#define CFG_TUD_NET OPT_NET_EEM - -#ifdef __cplusplus - } -#endif - -#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/lwip_webserver/src/usb_descriptors.c b/examples/device/lwip_webserver/src/usb_descriptors.c deleted file mode 100644 index 26f8aeba6..000000000 --- a/examples/device/lwip_webserver/src/usb_descriptors.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#include "tusb.h" -#include "usb_descriptors.h" - -/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. - * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. - * - * Auto ProductID layout's Bitmap: - * [MSB] NET1:NET0 | VENDOR | MIDI | HID | MSC | CDC [LSB] - */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) | _PID_MAP(NET, 5) ) - -//--------------------------------------------------------------------+ -// Device Descriptors -//--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = -{ - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0x0200, - - .bDeviceClass = TUSB_CLASS_UNSPECIFIED, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - - .idVendor = 0xCafe, - .idProduct = USB_PID, - .bcdDevice = 0x0100, - - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, - - .bNumConfigurations = 0x01 -}; - -// Invoked when received GET DEVICE DESCRIPTOR -// Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) -{ - return (uint8_t const *) &desc_device; -} - -//--------------------------------------------------------------------+ -// Configuration Descriptor -//--------------------------------------------------------------------+ -enum -{ - ITF_NUM_CDC = 0, - ITF_NUM_CDC_DATA, - ITF_NUM_TOTAL -}; - -enum -{ - STR_LANGID = 0, - STR_MANUFACTURER, - STR_PRODUCT, - STR_ITFNAME, - STR_MAC, -}; - -#if CFG_TUD_NET == OPT_NET_ECM -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN) -#elif CFG_TUD_NET == OPT_NET_RNDIS -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN) -#elif CFG_TUD_NET == OPT_NET_EEM -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_EEM_DESC_LEN) -#endif - -#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX - // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number - // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... - #define EPNUM_CDC 2 -#else - #define EPNUM_CDC 2 -#endif - -uint8_t const desc_configuration[] = -{ - // Interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 100), - -#if CFG_TUD_NET == OPT_NET_ECM - // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. - TUD_CDC_ECM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, STR_MAC, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), -#elif CFG_TUD_NET == OPT_NET_RNDIS - // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_RNDIS_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE), -#elif CFG_TUD_NET == OPT_NET_EEM - // Interface number, description string index, EP data address (out, in) and size. - TUD_CDC_EEM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE), -#endif -}; - -// Invoked when received GET CONFIGURATION DESCRIPTOR -// Application return pointer to descriptor -// Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) -{ - (void) index; // for multiple configurations - return desc_configuration; -} - -//--------------------------------------------------------------------+ -// String Descriptors -//--------------------------------------------------------------------+ - -// array of pointer to string descriptors -char const* string_desc_arr [] = -{ - [STR_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409) - [STR_MANUFACTURER] = "TinyUSB", // Manufacturer - [STR_PRODUCT] = "TinyUSB Device", // Product - [STR_ITFNAME] = // CDC-ECM Interface -#if CFG_TUD_NET == OPT_NET_ECM - "TinyUSB CDC-ECM", -#elif CFG_TUD_NET == OPT_NET_RNDIS - "TinyUSB RNDIS", -#elif CFG_TUD_NET == OPT_NET_EEM - "TinyUSB CDC-EEM", -#endif -}; - -static uint16_t _desc_str[32]; - -// Invoked when received GET STRING DESCRIPTOR request -// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) -{ - (void)langid; - - unsigned chr_count = 0; - - if (STR_LANGID == index) - { - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - } - else if (STR_MAC == index) - { - // Convert MAC address into UTF-16 - - for (unsigned i=0; i> 4) & 0xf]; - _desc_str[1+chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf]; - } - } - else - { - // Convert ASCII string into UTF-16 - - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; - - const char* str = string_desc_arr[index]; - - // Cap at max char - chr_count = strlen(str); - if ( chr_count > (TU_ARRAY_SIZE(_desc_str) - 1)) chr_count = TU_ARRAY_SIZE(_desc_str) - 1; - - for (unsigned i=0; i + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +//#include "cpu.h" + +typedef int sys_prot_t; + + + +/* define compiler specific symbols */ +#if defined (__ICCARM__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define PACK_STRUCT_BEGIN __packed +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__GNUC__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__TASKING__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#endif + +#define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0) + +#endif /* __CC_H__ */ diff --git a/examples/device/net_webserver/src/lwipopts.h b/examples/device/net_webserver/src/lwipopts.h new file mode 100644 index 000000000..23319592d --- /dev/null +++ b/examples/device/net_webserver/src/lwipopts.h @@ -0,0 +1,57 @@ +/* + * 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 __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ +#define NO_SYS 1 +#define MEM_ALIGNMENT 4 +#define LWIP_RAW 1 +#define LWIP_NETCONN 0 +#define LWIP_SOCKET 0 +#define LWIP_DHCP 0 +#define LWIP_ICMP 1 +#define LWIP_UDP 1 +#define LWIP_TCP 1 +#define ETH_PAD_SIZE 0 +#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67)) + +#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) +#define TCP_SND_BUF (2 * TCP_MSS) + +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 + +#define LWIP_HTTPD_CGI 0 +#define LWIP_HTTPD_SSI 0 +#define LWIP_HTTPD_SSI_INCLUDE_TAG 0 + +#endif /* __LWIPOPTS_H__ */ diff --git a/examples/device/net_webserver/src/main.c b/examples/device/net_webserver/src/main.c new file mode 100644 index 000000000..c193aeb0f --- /dev/null +++ b/examples/device/net_webserver/src/main.c @@ -0,0 +1,214 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Peter Lawrence + * + * influenced by lrndis https://github.com/fetisov/lrndis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +/* +depending on the value of CFG_TUD_NET (tusb_config.h), this can be a CDC-ECM, RNDIS, or CDC-EEM USB virtual network adapter + +CDC-ECM should be valid on Linux and MacOS hosts +RNDIS should be valid on Linux and Windows hosts +CDC-EEM should be valid on Linux hosts + +You *must* customize tusb_config.h to set the CFG_TUD_NET definition to the type of these network adapters to emulate. + +The MCU appears to the host as IP address 192.168.7.1, and provides a DHCP server, DNS server, and web server. +*/ + +#include "bsp/board.h" +#include "tusb.h" + +#include "dhserver.h" +#include "dnserver.h" +#include "lwip/init.h" +#include "httpd.h" + +/* lwip context */ +static struct netif netif_data; + +/* shared between tud_network_recv_cb() and service_traffic() */ +static struct pbuf *received_frame; + +/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */ +/* ideally speaking, this should be generated from the hardware's unique ID (if available) */ +const uint8_t tud_network_mac_address[6] = {0x20,0x89,0x84,0x6A,0x96,0x00}; + +/* network parameters of this MCU */ +static const ip_addr_t ipaddr = IPADDR4_INIT_BYTES(192, 168, 7, 1); +static const ip_addr_t netmask = IPADDR4_INIT_BYTES(255, 255, 255, 0); +static const ip_addr_t gateway = IPADDR4_INIT_BYTES(0, 0, 0, 0); + +/* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */ +static dhcp_entry_t entries[] = +{ + /* mac ip address subnet mask lease time */ + { {0}, {192, 168, 7, 2}, {255, 255, 255, 0}, 24 * 60 * 60 }, + { {0}, {192, 168, 7, 3}, {255, 255, 255, 0}, 24 * 60 * 60 }, + { {0}, {192, 168, 7, 4}, {255, 255, 255, 0}, 24 * 60 * 60 } +}; + +/* DHCP configuration parameters, leveraging "entries" above */ +static const dhcp_config_t dhcp_config = +{ + {192, 168, 7, 1}, 67, /* server address (self), port */ + {192, 168, 7, 1}, /* dns server (self) */ + "usb", /* dns suffix */ + TU_ARRAY_SIZE(entries), /* number of entries */ + entries /* pointer to entries */ +}; + +static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) +{ + (void)netif; + + for (;;) + { + /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ + if (!tud_ready()) + return ERR_USE; + + /* if the network driver can accept another packet, we make it happen */ + if (tud_network_can_xmit()) + { + tud_network_xmit(p); + return ERR_OK; + } + + /* transfer execution to TinyUSB in the hopes that it will finish transmitting the prior packet */ + tud_task(); + } +} + +static err_t output_fn(struct netif *netif, struct pbuf *p, const ip_addr_t *addr) +{ + return etharp_output(netif, p, addr); +} + +static err_t netif_init_cb(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + netif->mtu = CFG_TUD_NET_MTU; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + netif->state = NULL; + netif->name[0] = 'E'; + netif->name[1] = 'X'; + netif->linkoutput = linkoutput_fn; + netif->output = output_fn; + return ERR_OK; +} + +static void init_lwip(void) +{ + struct netif *netif = &netif_data; + + lwip_init(); + netif->hwaddr_len = sizeof(tud_network_mac_address); + memcpy(netif->hwaddr, tud_network_mac_address, sizeof(tud_network_mac_address)); + + netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ip_input); + netif_set_default(netif); +} + +/* handle any DNS requests from dns-server */ +bool dns_query_proc(const char *name, ip_addr_t *addr) +{ + if (0 == strcmp(name, "tiny.usb")) + { + *addr = ipaddr; + return true; + } + return false; +} + +bool tud_network_recv_cb(struct pbuf *p) +{ + /* this shouldn't happen, but if we get another packet before + parsing the previous, we must signal our inability to accept it */ + if (received_frame) return false; + + /* store away the pointer for service_traffic() to later handle */ + received_frame = p; + return true; +} + +static void service_traffic(void) +{ + /* handle any packet received by tud_network_recv_cb() */ + if (received_frame) + { + ethernet_input(received_frame, &netif_data); + pbuf_free(received_frame); + received_frame = NULL; + tud_network_recv_renew(); + } +} + +void tud_network_init_cb(void) +{ + /* if the network is re-initializing and we have a leftover packet, we must do a cleanup */ + if (received_frame) + { + pbuf_free(received_frame); + received_frame = NULL; + } +} + +int main(void) +{ + /* initialize TinyUSB */ + board_init(); + tusb_init(); + + /* initialize lwip, dhcp-server, dns-server, and http */ + init_lwip(); + while (!netif_is_up(&netif_data)); + while (dhserv_init(&dhcp_config) != ERR_OK); + while (dnserv_init(&ipaddr, 53, dns_query_proc) != ERR_OK); + httpd_init(); + + while (1) + { + tud_task(); + service_traffic(); + } + + return 0; +} + +/* lwip has provision for using a mutex, when applicable */ +sys_prot_t sys_arch_protect(void) +{ + return 0; +} +void sys_arch_unprotect(sys_prot_t pval) +{ + (void)pval; +} + +/* lwip needs a millisecond time source, and the TinyUSB board support code has one available */ +uint32_t sys_now(void) +{ + return board_millis(); +} diff --git a/examples/device/net_webserver/src/tusb_config.h b/examples/device/net_webserver/src/tusb_config.h new file mode 100644 index 000000000..329fc80b9 --- /dev/null +++ b/examples/device/net_webserver/src/tusb_config.h @@ -0,0 +1,90 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) +#else +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE +#endif + +#define CFG_TUSB_OS OPT_OS_NONE + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 +//#define CFG_TUD_NET OPT_NET_ECM +#define CFG_TUD_NET OPT_NET_RNDIS +//#define CFG_TUD_NET OPT_NET_EEM + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/net_webserver/src/usb_descriptors.c b/examples/device/net_webserver/src/usb_descriptors.c new file mode 100644 index 000000000..26f8aeba6 --- /dev/null +++ b/examples/device/net_webserver/src/usb_descriptors.c @@ -0,0 +1,199 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "tusb.h" +#include "usb_descriptors.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] NET1:NET0 | VENDOR | MIDI | HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) | _PID_MAP(NET, 5) ) + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + .bDeviceClass = TUSB_CLASS_UNSPECIFIED, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ +enum +{ + ITF_NUM_CDC = 0, + ITF_NUM_CDC_DATA, + ITF_NUM_TOTAL +}; + +enum +{ + STR_LANGID = 0, + STR_MANUFACTURER, + STR_PRODUCT, + STR_ITFNAME, + STR_MAC, +}; + +#if CFG_TUD_NET == OPT_NET_ECM +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN) +#elif CFG_TUD_NET == OPT_NET_RNDIS +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN) +#elif CFG_TUD_NET == OPT_NET_EEM +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_EEM_DESC_LEN) +#endif + +#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX + // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number + // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... + #define EPNUM_CDC 2 +#else + #define EPNUM_CDC 2 +#endif + +uint8_t const desc_configuration[] = +{ + // Interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 100), + +#if CFG_TUD_NET == OPT_NET_ECM + // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. + TUD_CDC_ECM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, STR_MAC, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), +#elif CFG_TUD_NET == OPT_NET_RNDIS + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. + TUD_RNDIS_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE), +#elif CFG_TUD_NET == OPT_NET_EEM + // Interface number, description string index, EP data address (out, in) and size. + TUD_CDC_EEM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE), +#endif +}; + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + return desc_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// array of pointer to string descriptors +char const* string_desc_arr [] = +{ + [STR_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409) + [STR_MANUFACTURER] = "TinyUSB", // Manufacturer + [STR_PRODUCT] = "TinyUSB Device", // Product + [STR_ITFNAME] = // CDC-ECM Interface +#if CFG_TUD_NET == OPT_NET_ECM + "TinyUSB CDC-ECM", +#elif CFG_TUD_NET == OPT_NET_RNDIS + "TinyUSB RNDIS", +#elif CFG_TUD_NET == OPT_NET_EEM + "TinyUSB CDC-EEM", +#endif +}; + +static uint16_t _desc_str[32]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + (void)langid; + + unsigned chr_count = 0; + + if (STR_LANGID == index) + { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + } + else if (STR_MAC == index) + { + // Convert MAC address into UTF-16 + + for (unsigned i=0; i> 4) & 0xf]; + _desc_str[1+chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf]; + } + } + else + { + // Convert ASCII string into UTF-16 + + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + + const char* str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + if ( chr_count > (TU_ARRAY_SIZE(_desc_str) - 1)) chr_count = TU_ARRAY_SIZE(_desc_str) - 1; + + for (unsigned i=0; i Date: Mon, 9 Mar 2020 15:54:16 +0700 Subject: add net_webserver into ci build --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 729222512..d1e3b8993 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,8 +24,8 @@ jobs: strategy: fail-fast: false matrix: - example: ['board_test', 'cdc_dual_ports', 'cdc_msc', 'dfu_rt', 'hid_composite', - 'hid_generic_inout', 'midi_test', 'msc_dual_lun', 'usbtmc', 'webusb_serial'] + example: ['board_test', 'cdc_dual_ports', 'cdc_msc', 'dfu_rt', 'hid_composite', 'hid_generic_inout', + 'midi_test', 'msc_dual_lun', 'net_webserver', 'usbtmc', 'webusb_serial'] steps: - name: Setup Python uses: actions/setup-python@v1 -- cgit v1.3.1 From 6f5466f017eb03aca64e397093af65b1bf80a8dd Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 9 Mar 2020 17:42:57 +0700 Subject: add Flash & Ram to ci build result --- tools/build_all.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tools/build_all.py b/tools/build_all.py index 45ae8d4d5..039b77022 100644 --- a/tools/build_all.py +++ b/tools/build_all.py @@ -6,6 +6,7 @@ import time success_count = 0 fail_count = 0 +skip_count = 0 exit_status = 0 total_time = time.monotonic() @@ -40,6 +41,14 @@ def build_example(example, board): return subprocess.run("make -j 4 -C examples/device/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) +def build_size(example, board): + elf_file = 'examples/device/{}/_build/build-{}/{}-firmware.elf'.format(example, board, board) + size_output = subprocess.run('size {}'.format(elf_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8") + size_list = size_output.split('\n')[1].split('\t') + flash_size = int(size_list[0]) + sram_size = int(size_list[1]) + int(size_list[2]) + return (flash_size, sram_size) + def skip_example(example, board): ex_dir = 'examples/device/' + example board_mk = 'hw/bsp/{}/board.mk'.format(board) @@ -51,32 +60,38 @@ def skip_example(example, board): return 0 -build_format = '| {:30} | {:30} | {:9} ' -build_separator = '-' * 87 +build_format = '| {:20} | {:30} | {:9} | {:5} | {:6} | {:6} |' +build_separator = '-' * 95 print(build_separator) -print((build_format + '| {:5} |').format('Example', 'Board', 'Result', 'Time')) +print(build_format.format('Example', 'Board', 'Result', 'Time', 'Flash', 'SRAM')) + for example in all_examples: print(build_separator) for board in all_boards: start_time = time.monotonic() + flash_size = "-" + sram_size = "-" + # Check if board is skipped if skip_example(example, board): success = "\033[33mskipped\033[0m " - print((build_format + '| {:.2f}s |').format(example, board, success, 0)) + skip_count += 1 + print((build_format + '| {:.2f}s |').format(example, board, success, 0, flash_size, sram_size)) else: build_result = build_example(example, board) if build_result.returncode == 0: success = "\033[32msucceeded\033[0m" success_count += 1 + (flash_size, sram_size) = build_size(example, board) else: exit_status = build_result.returncode success = "\033[31mfailed\033[0m " fail_count += 1 build_duration = time.monotonic() - start_time - print((build_format + '| {:.2f}s |').format(example, board, success, build_duration)) + print(build_format.format(example, board, success, "{:.2f}".format(build_duration), flash_size, sram_size)) if build_result.returncode != 0: print(build_result.stdout.decode("utf-8")) @@ -88,7 +103,7 @@ for example in all_examples: total_time = time.monotonic() - total_time print(build_separator) -print("Build Sumamary: {} \033[32msucceeded\033[0m, {} \033[31mfailed\033[0m and took {:.2f}s".format(success_count, fail_count, total_time)) +print("Build Sumamary: {} \033[32msucceeded\033[0m, {} \033[31mfailed\033[0m, {} \033[33mskipped\033[0m and took {:.2f}s".format(success_count, fail_count, skip_count, total_time)) print(build_separator) sys.exit(exit_status) -- cgit v1.3.1 From ec4323277d78c4a4fc4f1f2f58147eb108d5a0f1 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 9 Mar 2020 17:55:31 +0700 Subject: fix ci --- tools/build_all.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_all.py b/tools/build_all.py index 039b77022..4f3e28747 100644 --- a/tools/build_all.py +++ b/tools/build_all.py @@ -77,7 +77,7 @@ for example in all_examples: if skip_example(example, board): success = "\033[33mskipped\033[0m " skip_count += 1 - print((build_format + '| {:.2f}s |').format(example, board, success, 0, flash_size, sram_size)) + print(build_format.format(example, board, success, '-', flash_size, sram_size)) else: build_result = build_example(example, board) -- cgit v1.3.1 From 8a8f84cd3708781a4b2031a76b1f12dbde5d006c Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 9 Mar 2020 23:05:22 +0700 Subject: more rename --- .github/workflows/build.yml | 2 +- .../device/net_lwip_webserver/.skip.MCU_LPC11UXX | 0 .../device/net_lwip_webserver/.skip.MCU_LPC13XX | 0 .../device/net_lwip_webserver/.skip.MCU_NUC121 | 0 .../device/net_lwip_webserver/.skip.MCU_STM32L0 | 0 examples/device/net_lwip_webserver/Makefile | 57 ++++++ examples/device/net_lwip_webserver/src/arch/cc.h | 75 ++++++++ examples/device/net_lwip_webserver/src/lwipopts.h | 57 ++++++ examples/device/net_lwip_webserver/src/main.c | 214 +++++++++++++++++++++ .../device/net_lwip_webserver/src/tusb_config.h | 90 +++++++++ .../net_lwip_webserver/src/usb_descriptors.c | 199 +++++++++++++++++++ .../net_lwip_webserver/src/usb_descriptors.h | 28 +++ examples/device/net_webserver/.skip.MCU_LPC11UXX | 0 examples/device/net_webserver/.skip.MCU_LPC13XX | 0 examples/device/net_webserver/.skip.MCU_NUC121 | 0 examples/device/net_webserver/.skip.MCU_STM32L0 | 0 examples/device/net_webserver/Makefile | 57 ------ examples/device/net_webserver/src/arch/cc.h | 75 -------- examples/device/net_webserver/src/lwipopts.h | 57 ------ examples/device/net_webserver/src/main.c | 214 --------------------- examples/device/net_webserver/src/tusb_config.h | 90 --------- .../device/net_webserver/src/usb_descriptors.c | 199 ------------------- .../device/net_webserver/src/usb_descriptors.h | 28 --- 23 files changed, 721 insertions(+), 721 deletions(-) create mode 100644 examples/device/net_lwip_webserver/.skip.MCU_LPC11UXX create mode 100644 examples/device/net_lwip_webserver/.skip.MCU_LPC13XX create mode 100644 examples/device/net_lwip_webserver/.skip.MCU_NUC121 create mode 100644 examples/device/net_lwip_webserver/.skip.MCU_STM32L0 create mode 100644 examples/device/net_lwip_webserver/Makefile create mode 100644 examples/device/net_lwip_webserver/src/arch/cc.h create mode 100644 examples/device/net_lwip_webserver/src/lwipopts.h create mode 100644 examples/device/net_lwip_webserver/src/main.c create mode 100644 examples/device/net_lwip_webserver/src/tusb_config.h create mode 100644 examples/device/net_lwip_webserver/src/usb_descriptors.c create mode 100644 examples/device/net_lwip_webserver/src/usb_descriptors.h delete mode 100644 examples/device/net_webserver/.skip.MCU_LPC11UXX delete mode 100644 examples/device/net_webserver/.skip.MCU_LPC13XX delete mode 100644 examples/device/net_webserver/.skip.MCU_NUC121 delete mode 100644 examples/device/net_webserver/.skip.MCU_STM32L0 delete mode 100644 examples/device/net_webserver/Makefile delete mode 100644 examples/device/net_webserver/src/arch/cc.h delete mode 100644 examples/device/net_webserver/src/lwipopts.h delete mode 100644 examples/device/net_webserver/src/main.c delete mode 100644 examples/device/net_webserver/src/tusb_config.h delete mode 100644 examples/device/net_webserver/src/usb_descriptors.c delete mode 100644 examples/device/net_webserver/src/usb_descriptors.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d1e3b8993..54d4babac 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: fail-fast: false matrix: example: ['board_test', 'cdc_dual_ports', 'cdc_msc', 'dfu_rt', 'hid_composite', 'hid_generic_inout', - 'midi_test', 'msc_dual_lun', 'net_webserver', 'usbtmc', 'webusb_serial'] + 'midi_test', 'msc_dual_lun', 'net_lwip_webserver', 'usbtmc', 'webusb_serial'] steps: - name: Setup Python uses: actions/setup-python@v1 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_LPC11UXX b/examples/device/net_lwip_webserver/.skip.MCU_LPC11UXX new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/net_lwip_webserver/.skip.MCU_LPC13XX b/examples/device/net_lwip_webserver/.skip.MCU_LPC13XX new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/net_lwip_webserver/.skip.MCU_NUC121 b/examples/device/net_lwip_webserver/.skip.MCU_NUC121 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/net_lwip_webserver/.skip.MCU_STM32L0 b/examples/device/net_lwip_webserver/.skip.MCU_STM32L0 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/device/net_lwip_webserver/Makefile b/examples/device/net_lwip_webserver/Makefile new file mode 100644 index 000000000..a153c30be --- /dev/null +++ b/examples/device/net_lwip_webserver/Makefile @@ -0,0 +1,57 @@ +include ../../../tools/top.mk +include ../../make.mk + +CFLAGS += \ + -DPBUF_POOL_SIZE=2 \ + -DTCP_WND=2*TCP_MSS \ + -DHTTPD_USE_CUSTOM_FSDATA=0 + +INC += \ + src \ + $(TOP)/hw \ + $(TOP)/lib/lwip/src/include \ + $(TOP)/lib/lwip/src/include/ipv4 \ + $(TOP)/lib/lwip/src/include/lwip/apps \ + $(TOP)/lib/networking + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) +SRC_C += \ + lib/lwip/src/core/altcp.c \ + lib/lwip/src/core/altcp_alloc.c \ + lib/lwip/src/core/altcp_tcp.c \ + lib/lwip/src/core/def.c \ + lib/lwip/src/core/dns.c \ + lib/lwip/src/core/inet_chksum.c \ + lib/lwip/src/core/init.c \ + lib/lwip/src/core/ip.c \ + lib/lwip/src/core/mem.c \ + lib/lwip/src/core/memp.c \ + lib/lwip/src/core/netif.c \ + lib/lwip/src/core/pbuf.c \ + lib/lwip/src/core/raw.c \ + lib/lwip/src/core/stats.c \ + lib/lwip/src/core/sys.c \ + lib/lwip/src/core/tcp.c \ + lib/lwip/src/core/tcp_in.c \ + lib/lwip/src/core/tcp_out.c \ + lib/lwip/src/core/timeouts.c \ + lib/lwip/src/core/udp.c \ + lib/lwip/src/core/ipv4/autoip.c \ + lib/lwip/src/core/ipv4/dhcp.c \ + lib/lwip/src/core/ipv4/etharp.c \ + lib/lwip/src/core/ipv4/icmp.c \ + lib/lwip/src/core/ipv4/igmp.c \ + lib/lwip/src/core/ipv4/ip4.c \ + lib/lwip/src/core/ipv4/ip4_addr.c \ + lib/lwip/src/core/ipv4/ip4_frag.c \ + lib/lwip/src/netif/ethernet.c \ + lib/lwip/src/netif/slipif.c \ + lib/lwip/src/apps/http/httpd.c \ + lib/lwip/src/apps/http/fs.c \ + lib/networking/dhserver.c \ + lib/networking/dnserver.c \ + lib/networking/rndis_reports.c + +include ../../rules.mk diff --git a/examples/device/net_lwip_webserver/src/arch/cc.h b/examples/device/net_lwip_webserver/src/arch/cc.h new file mode 100644 index 000000000..56a0cacf7 --- /dev/null +++ b/examples/device/net_lwip_webserver/src/arch/cc.h @@ -0,0 +1,75 @@ +/* + * 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: Adam Dunkels + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +//#include "cpu.h" + +typedef int sys_prot_t; + + + +/* define compiler specific symbols */ +#if defined (__ICCARM__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define PACK_STRUCT_BEGIN __packed +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__GNUC__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__TASKING__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#endif + +#define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0) + +#endif /* __CC_H__ */ diff --git a/examples/device/net_lwip_webserver/src/lwipopts.h b/examples/device/net_lwip_webserver/src/lwipopts.h new file mode 100644 index 000000000..23319592d --- /dev/null +++ b/examples/device/net_lwip_webserver/src/lwipopts.h @@ -0,0 +1,57 @@ +/* + * 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 __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ +#define NO_SYS 1 +#define MEM_ALIGNMENT 4 +#define LWIP_RAW 1 +#define LWIP_NETCONN 0 +#define LWIP_SOCKET 0 +#define LWIP_DHCP 0 +#define LWIP_ICMP 1 +#define LWIP_UDP 1 +#define LWIP_TCP 1 +#define ETH_PAD_SIZE 0 +#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67)) + +#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) +#define TCP_SND_BUF (2 * TCP_MSS) + +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 + +#define LWIP_HTTPD_CGI 0 +#define LWIP_HTTPD_SSI 0 +#define LWIP_HTTPD_SSI_INCLUDE_TAG 0 + +#endif /* __LWIPOPTS_H__ */ diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c new file mode 100644 index 000000000..c193aeb0f --- /dev/null +++ b/examples/device/net_lwip_webserver/src/main.c @@ -0,0 +1,214 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Peter Lawrence + * + * influenced by lrndis https://github.com/fetisov/lrndis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +/* +depending on the value of CFG_TUD_NET (tusb_config.h), this can be a CDC-ECM, RNDIS, or CDC-EEM USB virtual network adapter + +CDC-ECM should be valid on Linux and MacOS hosts +RNDIS should be valid on Linux and Windows hosts +CDC-EEM should be valid on Linux hosts + +You *must* customize tusb_config.h to set the CFG_TUD_NET definition to the type of these network adapters to emulate. + +The MCU appears to the host as IP address 192.168.7.1, and provides a DHCP server, DNS server, and web server. +*/ + +#include "bsp/board.h" +#include "tusb.h" + +#include "dhserver.h" +#include "dnserver.h" +#include "lwip/init.h" +#include "httpd.h" + +/* lwip context */ +static struct netif netif_data; + +/* shared between tud_network_recv_cb() and service_traffic() */ +static struct pbuf *received_frame; + +/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */ +/* ideally speaking, this should be generated from the hardware's unique ID (if available) */ +const uint8_t tud_network_mac_address[6] = {0x20,0x89,0x84,0x6A,0x96,0x00}; + +/* network parameters of this MCU */ +static const ip_addr_t ipaddr = IPADDR4_INIT_BYTES(192, 168, 7, 1); +static const ip_addr_t netmask = IPADDR4_INIT_BYTES(255, 255, 255, 0); +static const ip_addr_t gateway = IPADDR4_INIT_BYTES(0, 0, 0, 0); + +/* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */ +static dhcp_entry_t entries[] = +{ + /* mac ip address subnet mask lease time */ + { {0}, {192, 168, 7, 2}, {255, 255, 255, 0}, 24 * 60 * 60 }, + { {0}, {192, 168, 7, 3}, {255, 255, 255, 0}, 24 * 60 * 60 }, + { {0}, {192, 168, 7, 4}, {255, 255, 255, 0}, 24 * 60 * 60 } +}; + +/* DHCP configuration parameters, leveraging "entries" above */ +static const dhcp_config_t dhcp_config = +{ + {192, 168, 7, 1}, 67, /* server address (self), port */ + {192, 168, 7, 1}, /* dns server (self) */ + "usb", /* dns suffix */ + TU_ARRAY_SIZE(entries), /* number of entries */ + entries /* pointer to entries */ +}; + +static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) +{ + (void)netif; + + for (;;) + { + /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ + if (!tud_ready()) + return ERR_USE; + + /* if the network driver can accept another packet, we make it happen */ + if (tud_network_can_xmit()) + { + tud_network_xmit(p); + return ERR_OK; + } + + /* transfer execution to TinyUSB in the hopes that it will finish transmitting the prior packet */ + tud_task(); + } +} + +static err_t output_fn(struct netif *netif, struct pbuf *p, const ip_addr_t *addr) +{ + return etharp_output(netif, p, addr); +} + +static err_t netif_init_cb(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + netif->mtu = CFG_TUD_NET_MTU; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + netif->state = NULL; + netif->name[0] = 'E'; + netif->name[1] = 'X'; + netif->linkoutput = linkoutput_fn; + netif->output = output_fn; + return ERR_OK; +} + +static void init_lwip(void) +{ + struct netif *netif = &netif_data; + + lwip_init(); + netif->hwaddr_len = sizeof(tud_network_mac_address); + memcpy(netif->hwaddr, tud_network_mac_address, sizeof(tud_network_mac_address)); + + netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ip_input); + netif_set_default(netif); +} + +/* handle any DNS requests from dns-server */ +bool dns_query_proc(const char *name, ip_addr_t *addr) +{ + if (0 == strcmp(name, "tiny.usb")) + { + *addr = ipaddr; + return true; + } + return false; +} + +bool tud_network_recv_cb(struct pbuf *p) +{ + /* this shouldn't happen, but if we get another packet before + parsing the previous, we must signal our inability to accept it */ + if (received_frame) return false; + + /* store away the pointer for service_traffic() to later handle */ + received_frame = p; + return true; +} + +static void service_traffic(void) +{ + /* handle any packet received by tud_network_recv_cb() */ + if (received_frame) + { + ethernet_input(received_frame, &netif_data); + pbuf_free(received_frame); + received_frame = NULL; + tud_network_recv_renew(); + } +} + +void tud_network_init_cb(void) +{ + /* if the network is re-initializing and we have a leftover packet, we must do a cleanup */ + if (received_frame) + { + pbuf_free(received_frame); + received_frame = NULL; + } +} + +int main(void) +{ + /* initialize TinyUSB */ + board_init(); + tusb_init(); + + /* initialize lwip, dhcp-server, dns-server, and http */ + init_lwip(); + while (!netif_is_up(&netif_data)); + while (dhserv_init(&dhcp_config) != ERR_OK); + while (dnserv_init(&ipaddr, 53, dns_query_proc) != ERR_OK); + httpd_init(); + + while (1) + { + tud_task(); + service_traffic(); + } + + return 0; +} + +/* lwip has provision for using a mutex, when applicable */ +sys_prot_t sys_arch_protect(void) +{ + return 0; +} +void sys_arch_unprotect(sys_prot_t pval) +{ + (void)pval; +} + +/* lwip needs a millisecond time source, and the TinyUSB board support code has one available */ +uint32_t sys_now(void) +{ + return board_millis(); +} diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h new file mode 100644 index 000000000..329fc80b9 --- /dev/null +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -0,0 +1,90 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) +#else +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE +#endif + +#define CFG_TUSB_OS OPT_OS_NONE + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 +//#define CFG_TUD_NET OPT_NET_ECM +#define CFG_TUD_NET OPT_NET_RNDIS +//#define CFG_TUD_NET OPT_NET_EEM + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c new file mode 100644 index 000000000..26f8aeba6 --- /dev/null +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -0,0 +1,199 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "tusb.h" +#include "usb_descriptors.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] NET1:NET0 | VENDOR | MIDI | HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) | _PID_MAP(NET, 5) ) + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + .bDeviceClass = TUSB_CLASS_UNSPECIFIED, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ +enum +{ + ITF_NUM_CDC = 0, + ITF_NUM_CDC_DATA, + ITF_NUM_TOTAL +}; + +enum +{ + STR_LANGID = 0, + STR_MANUFACTURER, + STR_PRODUCT, + STR_ITFNAME, + STR_MAC, +}; + +#if CFG_TUD_NET == OPT_NET_ECM +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN) +#elif CFG_TUD_NET == OPT_NET_RNDIS +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN) +#elif CFG_TUD_NET == OPT_NET_EEM +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_EEM_DESC_LEN) +#endif + +#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX + // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number + // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... + #define EPNUM_CDC 2 +#else + #define EPNUM_CDC 2 +#endif + +uint8_t const desc_configuration[] = +{ + // Interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 100), + +#if CFG_TUD_NET == OPT_NET_ECM + // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. + TUD_CDC_ECM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, STR_MAC, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), +#elif CFG_TUD_NET == OPT_NET_RNDIS + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. + TUD_RNDIS_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE), +#elif CFG_TUD_NET == OPT_NET_EEM + // Interface number, description string index, EP data address (out, in) and size. + TUD_CDC_EEM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE), +#endif +}; + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + return desc_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// array of pointer to string descriptors +char const* string_desc_arr [] = +{ + [STR_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409) + [STR_MANUFACTURER] = "TinyUSB", // Manufacturer + [STR_PRODUCT] = "TinyUSB Device", // Product + [STR_ITFNAME] = // CDC-ECM Interface +#if CFG_TUD_NET == OPT_NET_ECM + "TinyUSB CDC-ECM", +#elif CFG_TUD_NET == OPT_NET_RNDIS + "TinyUSB RNDIS", +#elif CFG_TUD_NET == OPT_NET_EEM + "TinyUSB CDC-EEM", +#endif +}; + +static uint16_t _desc_str[32]; + +// Invoked when received GET STRING DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + (void)langid; + + unsigned chr_count = 0; + + if (STR_LANGID == index) + { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + } + else if (STR_MAC == index) + { + // Convert MAC address into UTF-16 + + for (unsigned i=0; i> 4) & 0xf]; + _desc_str[1+chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf]; + } + } + else + { + // Convert ASCII string into UTF-16 + + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + + const char* str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + if ( chr_count > (TU_ARRAY_SIZE(_desc_str) - 1)) chr_count = TU_ARRAY_SIZE(_desc_str) - 1; + + for (unsigned i=0; i - * - */ -#ifndef __CC_H__ -#define __CC_H__ - -//#include "cpu.h" - -typedef int sys_prot_t; - - - -/* define compiler specific symbols */ -#if defined (__ICCARM__) - -#define PACK_STRUCT_BEGIN -#define PACK_STRUCT_STRUCT -#define PACK_STRUCT_END -#define PACK_STRUCT_FIELD(x) x -#define PACK_STRUCT_USE_INCLUDES - -#elif defined (__CC_ARM) - -#define PACK_STRUCT_BEGIN __packed -#define PACK_STRUCT_STRUCT -#define PACK_STRUCT_END -#define PACK_STRUCT_FIELD(x) x - -#elif defined (__GNUC__) - -#define PACK_STRUCT_BEGIN -#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) -#define PACK_STRUCT_END -#define PACK_STRUCT_FIELD(x) x - -#elif defined (__TASKING__) - -#define PACK_STRUCT_BEGIN -#define PACK_STRUCT_STRUCT -#define PACK_STRUCT_END -#define PACK_STRUCT_FIELD(x) x - -#endif - -#define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0) - -#endif /* __CC_H__ */ diff --git a/examples/device/net_webserver/src/lwipopts.h b/examples/device/net_webserver/src/lwipopts.h deleted file mode 100644 index 23319592d..000000000 --- a/examples/device/net_webserver/src/lwipopts.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 __LWIPOPTS_H__ -#define __LWIPOPTS_H__ - -/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ -#define NO_SYS 1 -#define MEM_ALIGNMENT 4 -#define LWIP_RAW 1 -#define LWIP_NETCONN 0 -#define LWIP_SOCKET 0 -#define LWIP_DHCP 0 -#define LWIP_ICMP 1 -#define LWIP_UDP 1 -#define LWIP_TCP 1 -#define ETH_PAD_SIZE 0 -#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67)) - -#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) -#define TCP_SND_BUF (2 * TCP_MSS) - -#define ETHARP_SUPPORT_STATIC_ENTRIES 1 - -#define LWIP_HTTPD_CGI 0 -#define LWIP_HTTPD_SSI 0 -#define LWIP_HTTPD_SSI_INCLUDE_TAG 0 - -#endif /* __LWIPOPTS_H__ */ diff --git a/examples/device/net_webserver/src/main.c b/examples/device/net_webserver/src/main.c deleted file mode 100644 index c193aeb0f..000000000 --- a/examples/device/net_webserver/src/main.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Peter Lawrence - * - * influenced by lrndis https://github.com/fetisov/lrndis - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -/* -depending on the value of CFG_TUD_NET (tusb_config.h), this can be a CDC-ECM, RNDIS, or CDC-EEM USB virtual network adapter - -CDC-ECM should be valid on Linux and MacOS hosts -RNDIS should be valid on Linux and Windows hosts -CDC-EEM should be valid on Linux hosts - -You *must* customize tusb_config.h to set the CFG_TUD_NET definition to the type of these network adapters to emulate. - -The MCU appears to the host as IP address 192.168.7.1, and provides a DHCP server, DNS server, and web server. -*/ - -#include "bsp/board.h" -#include "tusb.h" - -#include "dhserver.h" -#include "dnserver.h" -#include "lwip/init.h" -#include "httpd.h" - -/* lwip context */ -static struct netif netif_data; - -/* shared between tud_network_recv_cb() and service_traffic() */ -static struct pbuf *received_frame; - -/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */ -/* ideally speaking, this should be generated from the hardware's unique ID (if available) */ -const uint8_t tud_network_mac_address[6] = {0x20,0x89,0x84,0x6A,0x96,0x00}; - -/* network parameters of this MCU */ -static const ip_addr_t ipaddr = IPADDR4_INIT_BYTES(192, 168, 7, 1); -static const ip_addr_t netmask = IPADDR4_INIT_BYTES(255, 255, 255, 0); -static const ip_addr_t gateway = IPADDR4_INIT_BYTES(0, 0, 0, 0); - -/* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */ -static dhcp_entry_t entries[] = -{ - /* mac ip address subnet mask lease time */ - { {0}, {192, 168, 7, 2}, {255, 255, 255, 0}, 24 * 60 * 60 }, - { {0}, {192, 168, 7, 3}, {255, 255, 255, 0}, 24 * 60 * 60 }, - { {0}, {192, 168, 7, 4}, {255, 255, 255, 0}, 24 * 60 * 60 } -}; - -/* DHCP configuration parameters, leveraging "entries" above */ -static const dhcp_config_t dhcp_config = -{ - {192, 168, 7, 1}, 67, /* server address (self), port */ - {192, 168, 7, 1}, /* dns server (self) */ - "usb", /* dns suffix */ - TU_ARRAY_SIZE(entries), /* number of entries */ - entries /* pointer to entries */ -}; - -static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) -{ - (void)netif; - - for (;;) - { - /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ - if (!tud_ready()) - return ERR_USE; - - /* if the network driver can accept another packet, we make it happen */ - if (tud_network_can_xmit()) - { - tud_network_xmit(p); - return ERR_OK; - } - - /* transfer execution to TinyUSB in the hopes that it will finish transmitting the prior packet */ - tud_task(); - } -} - -static err_t output_fn(struct netif *netif, struct pbuf *p, const ip_addr_t *addr) -{ - return etharp_output(netif, p, addr); -} - -static err_t netif_init_cb(struct netif *netif) -{ - LWIP_ASSERT("netif != NULL", (netif != NULL)); - netif->mtu = CFG_TUD_NET_MTU; - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; - netif->state = NULL; - netif->name[0] = 'E'; - netif->name[1] = 'X'; - netif->linkoutput = linkoutput_fn; - netif->output = output_fn; - return ERR_OK; -} - -static void init_lwip(void) -{ - struct netif *netif = &netif_data; - - lwip_init(); - netif->hwaddr_len = sizeof(tud_network_mac_address); - memcpy(netif->hwaddr, tud_network_mac_address, sizeof(tud_network_mac_address)); - - netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ip_input); - netif_set_default(netif); -} - -/* handle any DNS requests from dns-server */ -bool dns_query_proc(const char *name, ip_addr_t *addr) -{ - if (0 == strcmp(name, "tiny.usb")) - { - *addr = ipaddr; - return true; - } - return false; -} - -bool tud_network_recv_cb(struct pbuf *p) -{ - /* this shouldn't happen, but if we get another packet before - parsing the previous, we must signal our inability to accept it */ - if (received_frame) return false; - - /* store away the pointer for service_traffic() to later handle */ - received_frame = p; - return true; -} - -static void service_traffic(void) -{ - /* handle any packet received by tud_network_recv_cb() */ - if (received_frame) - { - ethernet_input(received_frame, &netif_data); - pbuf_free(received_frame); - received_frame = NULL; - tud_network_recv_renew(); - } -} - -void tud_network_init_cb(void) -{ - /* if the network is re-initializing and we have a leftover packet, we must do a cleanup */ - if (received_frame) - { - pbuf_free(received_frame); - received_frame = NULL; - } -} - -int main(void) -{ - /* initialize TinyUSB */ - board_init(); - tusb_init(); - - /* initialize lwip, dhcp-server, dns-server, and http */ - init_lwip(); - while (!netif_is_up(&netif_data)); - while (dhserv_init(&dhcp_config) != ERR_OK); - while (dnserv_init(&ipaddr, 53, dns_query_proc) != ERR_OK); - httpd_init(); - - while (1) - { - tud_task(); - service_traffic(); - } - - return 0; -} - -/* lwip has provision for using a mutex, when applicable */ -sys_prot_t sys_arch_protect(void) -{ - return 0; -} -void sys_arch_unprotect(sys_prot_t pval) -{ - (void)pval; -} - -/* lwip needs a millisecond time source, and the TinyUSB board support code has one available */ -uint32_t sys_now(void) -{ - return board_millis(); -} diff --git a/examples/device/net_webserver/src/tusb_config.h b/examples/device/net_webserver/src/tusb_config.h deleted file mode 100644 index 329fc80b9..000000000 --- a/examples/device/net_webserver/src/tusb_config.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -//-------------------------------------------------------------------- -// COMMON CONFIGURATION -//-------------------------------------------------------------------- - -// defined by compiler flags for flexibility -#ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined -#endif - -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) -#else -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE -#endif - -#define CFG_TUSB_OS OPT_OS_NONE - -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 - -/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. - * Tinyusb use follows macros to declare transferring memory so that they can be put - * into those specific section. - * e.g - * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) - * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) - */ -#ifndef CFG_TUSB_MEM_SECTION -#define CFG_TUSB_MEM_SECTION -#endif - -#ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) -#endif - -//-------------------------------------------------------------------- -// DEVICE CONFIGURATION -//-------------------------------------------------------------------- - -#ifndef CFG_TUD_ENDPOINT0_SIZE -#define CFG_TUD_ENDPOINT0_SIZE 64 -#endif - -//------------- CLASS -------------// -#define CFG_TUD_CDC 0 -#define CFG_TUD_MSC 0 -#define CFG_TUD_HID 0 -#define CFG_TUD_MIDI 0 -#define CFG_TUD_VENDOR 0 -//#define CFG_TUD_NET OPT_NET_ECM -#define CFG_TUD_NET OPT_NET_RNDIS -//#define CFG_TUD_NET OPT_NET_EEM - -#ifdef __cplusplus - } -#endif - -#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/net_webserver/src/usb_descriptors.c b/examples/device/net_webserver/src/usb_descriptors.c deleted file mode 100644 index 26f8aeba6..000000000 --- a/examples/device/net_webserver/src/usb_descriptors.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#include "tusb.h" -#include "usb_descriptors.h" - -/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. - * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. - * - * Auto ProductID layout's Bitmap: - * [MSB] NET1:NET0 | VENDOR | MIDI | HID | MSC | CDC [LSB] - */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) | _PID_MAP(NET, 5) ) - -//--------------------------------------------------------------------+ -// Device Descriptors -//--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = -{ - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0x0200, - - .bDeviceClass = TUSB_CLASS_UNSPECIFIED, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - - .idVendor = 0xCafe, - .idProduct = USB_PID, - .bcdDevice = 0x0100, - - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, - - .bNumConfigurations = 0x01 -}; - -// Invoked when received GET DEVICE DESCRIPTOR -// Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) -{ - return (uint8_t const *) &desc_device; -} - -//--------------------------------------------------------------------+ -// Configuration Descriptor -//--------------------------------------------------------------------+ -enum -{ - ITF_NUM_CDC = 0, - ITF_NUM_CDC_DATA, - ITF_NUM_TOTAL -}; - -enum -{ - STR_LANGID = 0, - STR_MANUFACTURER, - STR_PRODUCT, - STR_ITFNAME, - STR_MAC, -}; - -#if CFG_TUD_NET == OPT_NET_ECM -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN) -#elif CFG_TUD_NET == OPT_NET_RNDIS -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN) -#elif CFG_TUD_NET == OPT_NET_EEM -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_EEM_DESC_LEN) -#endif - -#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX - // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number - // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... - #define EPNUM_CDC 2 -#else - #define EPNUM_CDC 2 -#endif - -uint8_t const desc_configuration[] = -{ - // Interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 100), - -#if CFG_TUD_NET == OPT_NET_ECM - // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. - TUD_CDC_ECM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, STR_MAC, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), -#elif CFG_TUD_NET == OPT_NET_RNDIS - // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_RNDIS_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE), -#elif CFG_TUD_NET == OPT_NET_EEM - // Interface number, description string index, EP data address (out, in) and size. - TUD_CDC_EEM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE), -#endif -}; - -// Invoked when received GET CONFIGURATION DESCRIPTOR -// Application return pointer to descriptor -// Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) -{ - (void) index; // for multiple configurations - return desc_configuration; -} - -//--------------------------------------------------------------------+ -// String Descriptors -//--------------------------------------------------------------------+ - -// array of pointer to string descriptors -char const* string_desc_arr [] = -{ - [STR_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409) - [STR_MANUFACTURER] = "TinyUSB", // Manufacturer - [STR_PRODUCT] = "TinyUSB Device", // Product - [STR_ITFNAME] = // CDC-ECM Interface -#if CFG_TUD_NET == OPT_NET_ECM - "TinyUSB CDC-ECM", -#elif CFG_TUD_NET == OPT_NET_RNDIS - "TinyUSB RNDIS", -#elif CFG_TUD_NET == OPT_NET_EEM - "TinyUSB CDC-EEM", -#endif -}; - -static uint16_t _desc_str[32]; - -// Invoked when received GET STRING DESCRIPTOR request -// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) -{ - (void)langid; - - unsigned chr_count = 0; - - if (STR_LANGID == index) - { - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - } - else if (STR_MAC == index) - { - // Convert MAC address into UTF-16 - - for (unsigned i=0; i> 4) & 0xf]; - _desc_str[1+chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf]; - } - } - else - { - // Convert ASCII string into UTF-16 - - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; - - const char* str = string_desc_arr[index]; - - // Cap at max char - chr_count = strlen(str); - if ( chr_count > (TU_ARRAY_SIZE(_desc_str) - 1)) chr_count = TU_ARRAY_SIZE(_desc_str) - 1; - - for (unsigned i=0; i Date: Tue, 10 Mar 2020 13:28:55 +0700 Subject: doc update --- CONTRIBUTORS.md | 8 +++++--- README.md | 3 ++- docs/boards.md | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index e1d5db693..6c83ef9c0 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -25,9 +25,11 @@ * Board support for STM32F070RB Nucleo, STM32F303 Discovery * **[Peter Lawrence](https://github.com/majbthrd)** - * Nuvoton NUC 121, 125, 126 device driver port - * Board support for NuTiny NUC121s, NUC125s, NUC126V - * Complete multiple class interfaces & add cdc_dual_ports example + * Nuvoton NUC 120, 121, 125, 126, 505 device driver port + * USBNET RNDIS, CDC-ECM, CDC-EEM class driver + * Added `net_lwip_webserver` example for demonstration of usbnet with lwip + * Board support for NuTiny NUC120, NUC121s, NUC125s, NUC126V, NUC505 + * Complete multiple class interfaces & add cdc_dual_ports example * **[Scott Shawcroft](https://github.com/tannewt)** * SAMD21 and SAMD51 device driver port diff --git a/README.md b/README.md index 7ab55f781..211dcc50a 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ The stack supports the following MCUs: - **Sony:** CXD56 - **ST:** STM32 series: L0, F0, F1, F2, F3, F4, F7, H7 (device only) - **[ValentyUSB](https://github.com/im-tomu/valentyusb)** eptri -- **Nuvoton:** NUC121/NUC125, NUC126, NUC505 +- **Nuvoton:** NUC120, NUC121/NUC125, NUC126, NUC505 [Here is the list of supported Boards](docs/boards.md) that can be used with provided examples. @@ -50,6 +50,7 @@ Supports multiple device configurations by dynamically changing usb descriptors. - Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ... - Mass Storage Class (MSC): with multiple LUNs - Musical Instrument Digital Interface (MIDI) +- Network with RNDIS, CDC-ECM, CDC-EEM (work in progress) - Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file. - [WebUSB](https://github.com/WICG/webusb) with vendor-specific class diff --git a/docs/boards.md b/docs/boards.md index d56e39bd0..9667f6944 100644 --- a/docs/boards.md +++ b/docs/boards.md @@ -33,6 +33,7 @@ This code base already had supported for a handful of following boards (sorted a ### Nuvoton +- NuTiny SDK NUC120 - [NuTiny NUC121S](https://direct.nuvoton.com/en/nutiny-nuc121s) - [NuTiny NUC125S](https://direct.nuvoton.com/en/nutiny-nuc125s) - [NuTiny NUC126V](https://direct.nuvoton.com/en/nutiny-nuc126v) -- cgit v1.3.1