kopia lustrzana https://github.com/maxnet/pico-webserver
Initial version
rodzic
721bd82383
commit
f64f407460
|
@ -0,0 +1,2 @@
|
||||||
|
build
|
||||||
|
makefsdata
|
|
@ -0,0 +1,10 @@
|
||||||
|
[submodule "tinyusb"]
|
||||||
|
path = tinyusb
|
||||||
|
url = https://github.com/raspberrypi/tinyusb.git
|
||||||
|
branch = pico
|
||||||
|
[submodule "pico-sdk"]
|
||||||
|
path = pico-sdk
|
||||||
|
url = https://github.com/raspberrypi/pico-sdk.git
|
||||||
|
[submodule "lwip"]
|
||||||
|
path = lwip
|
||||||
|
url = https://git.savannah.nongnu.org/git/lwip.git
|
|
@ -0,0 +1,31 @@
|
||||||
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
|
# We prefer to have all linked submodules at toplevel
|
||||||
|
set(PICO_TINYUSB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/tinyusb)
|
||||||
|
|
||||||
|
include(pico-sdk/pico_sdk_init.cmake)
|
||||||
|
project(pico_webserver)
|
||||||
|
pico_sdk_init()
|
||||||
|
|
||||||
|
# LWIP
|
||||||
|
set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lwip)
|
||||||
|
set (LWIP_INCLUDE_DIRS
|
||||||
|
"${LWIP_DIR}/src/include"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
)
|
||||||
|
include(${LWIP_DIR}/src/Filelists.cmake)
|
||||||
|
|
||||||
|
# Extra stuff from TinyUSB, that is not part of tinyusb_device library
|
||||||
|
set(TINYUSB_LIBNETWORKING_SOURCES
|
||||||
|
${PICO_TINYUSB_PATH}/lib/networking/dhserver.c
|
||||||
|
${PICO_TINYUSB_PATH}/lib/networking/rndis_reports.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} webserver.c tusb_lwip_glue.c usb_descriptors.c ${TINYUSB_LIBNETWORKING_SOURCES})
|
||||||
|
|
||||||
|
pico_enable_stdio_usb(${PROJECT_NAME} 0)
|
||||||
|
pico_enable_stdio_uart(${PROJECT_NAME} 0)
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE ${LWIP_INCLUDE_DIRS} ${PICO_TINYUSB_PATH}/src ${PICO_TINYUSB_PATH}/lib/networking)
|
||||||
|
target_link_libraries(${PROJECT_NAME} pico_stdlib pico_unique_id tinyusb_device lwipallapps lwipcore)
|
||||||
|
pico_add_extra_outputs(${PROJECT_NAME})
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE PICO_ENTER_USB_BOOT_ON_EXIT=1)
|
60
LICENSE
60
LICENSE
|
@ -1,3 +1,62 @@
|
||||||
|
Based on TinyUSB example code:
|
||||||
|
|
||||||
|
==
|
||||||
|
* 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.
|
||||||
|
==
|
||||||
|
|
||||||
|
Uses some files from lwip licensed BSD:
|
||||||
|
|
||||||
|
==
|
||||||
|
Copyright (c) 2001, 2002 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.
|
||||||
|
==
|
||||||
|
|
||||||
|
|
||||||
|
Other files, build scripts and packaging, public domain:
|
||||||
|
|
||||||
|
==
|
||||||
This is free and unencumbered software released into the public domain.
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
@ -22,3 +81,4 @@ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
For more information, please refer to <https://unlicense.org>
|
For more information, please refer to <https://unlicense.org>
|
||||||
|
==
|
||||||
|
|
36
README.md
36
README.md
|
@ -1 +1,35 @@
|
||||||
# pico-webserver
|
# pico-webserver
|
||||||
|
|
||||||
|
Webserver example that came with TinyUSB slightly modified to run on a Raspberry Pi Pico.
|
||||||
|
Lets the Pico pretend to be a USB Ethernet device. Runs a webinterface at http://192.168.7.1/
|
||||||
|
|
||||||
|
## Build dependencies
|
||||||
|
|
||||||
|
On Debian:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt install git build-essential cmake gcc-arm-none-eabi
|
||||||
|
```
|
||||||
|
|
||||||
|
Your Linux distribution does need to provide a recent CMake (3.13+).
|
||||||
|
If not, compile [CMake from source](https://cmake.org/download/#latest) first.
|
||||||
|
|
||||||
|
## Build instructions
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone --depth 1 https://github.com/maxnet/pico-webserver
|
||||||
|
cd pico-webserver
|
||||||
|
git submodule update --init --depth 1
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy the resulting pico_webserver.uf2 file to the Pico mass storage device manually.
|
||||||
|
Webserver will be available at http://192.168.7.1/
|
||||||
|
|
||||||
|
Content it is serving is in /fs
|
||||||
|
If you change any files there, run ./regen-fsdata.sh
|
||||||
|
|
||||||
|
By default it shows a webpage that led you toggle the Pico's led, and allows you to switch to BOOTSEL mode.
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* 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 <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#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
|
||||||
|
|
||||||
|
#ifndef LWIP_PLATFORM_ASSERT
|
||||||
|
#define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CC_H__ */
|
|
@ -0,0 +1,27 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||||
|
"http://www.w3.org/TR/html4/strict.dtd"
|
||||||
|
>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Welcome to your Pico</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<h1>Welcome to your Pico!</h1>
|
||||||
|
|
||||||
|
<!-- Image Map Generated by http://www.image-map.net/ -->
|
||||||
|
<img src="pico.png" usemap="#image-map">
|
||||||
|
|
||||||
|
<map name="image-map">
|
||||||
|
<area target="" alt="BOOTSEL" title="BOOTSEL" href="/reset_usb_boot" coords="319,97,11" shape="circle">
|
||||||
|
<area target="" alt="LED" title="LED" href="/toggle_led" coords="341,58,359,79" shape="rect">
|
||||||
|
</map>
|
||||||
|
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
You can click the LED and BOOTSEL button on the picture above.
|
||||||
|
|
||||||
|
</center>
|
||||||
|
</body>
|
||||||
|
</html>
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 142 KiB |
Plik diff jest za duży
Load Diff
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 0056522cc974d2be2005c324f37187b5b3695765
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Simon Goldschmidt
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __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 0
|
||||||
|
#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 1
|
||||||
|
#ifndef LWIP_HTTPD_SSI
|
||||||
|
#define LWIP_HTTPD_SSI 0
|
||||||
|
#define LWIP_HTTPD_SSI_INCLUDE_TAG 0
|
||||||
|
#endif
|
||||||
|
#define HTTPD_USE_CUSTOM_FSDATA 1
|
||||||
|
#define HTTPD_FSDATA_FILE "../../../../fsdata.c"
|
||||||
|
|
||||||
|
#define LWIP_SINGLE_NETIF 1
|
||||||
|
|
||||||
|
#endif /* __LWIPOPTS_H__ */
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit fc10a97c386f65c1a44c68684fe52a56aaf50df0
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ ! -f makefsdata ]; then
|
||||||
|
# Doing this outside cmake as we don't want it cross-compiled but for host
|
||||||
|
echo Compiling makefsdata
|
||||||
|
gcc -o makefsdata -Ilwip/src/include -I. lwip/src/apps/http/makefsdata/makefsdata.c
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo Regenerating fsdata.c
|
||||||
|
./makefsdata
|
||||||
|
echo Done
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 11c23f88bf42f64ce14b8a7b0b2a4e207dc4dd12
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* 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 board.mk
|
||||||
|
#ifndef CFG_TUSB_MCU
|
||||||
|
#error CFG_TUSB_MCU must be defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// RHPort number used for device can be defined by board.mk, default to port 0
|
||||||
|
#ifndef BOARD_DEVICE_RHPORT_NUM
|
||||||
|
#define BOARD_DEVICE_RHPORT_NUM 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// RHPort max operational speed can defined by board.mk
|
||||||
|
// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed
|
||||||
|
#ifndef BOARD_DEVICE_RHPORT_SPEED
|
||||||
|
#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \
|
||||||
|
CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56)
|
||||||
|
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED
|
||||||
|
#else
|
||||||
|
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Device mode with rhport and speed defined by board.mk
|
||||||
|
#if BOARD_DEVICE_RHPORT_NUM == 0
|
||||||
|
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
|
||||||
|
#elif BOARD_DEVICE_RHPORT_NUM == 1
|
||||||
|
#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
|
||||||
|
#else
|
||||||
|
#error "Incorrect RHPort configuration"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUSB_OS
|
||||||
|
#define CFG_TUSB_OS OPT_OS_NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 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 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _TUSB_CONFIG_H_ */
|
|
@ -0,0 +1,248 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Based on tinyUSB example that is: Copyright (c) 2020 Peter Lawrence
|
||||||
|
* Modified for Pico by Floris Bos
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tusb_lwip_glue.h"
|
||||||
|
#include "pico/unique_id.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) */
|
||||||
|
/* it is suggested that the first byte is 0x02 to indicate a link-local address */
|
||||||
|
const uint8_t tud_network_mac_address[6] = {0x02,0x02,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 lease time */
|
||||||
|
{ {0}, IPADDR4_INIT_BYTES(192, 168, 7, 2), 24 * 60 * 60 },
|
||||||
|
{ {0}, IPADDR4_INIT_BYTES(192, 168, 7, 3), 24 * 60 * 60 },
|
||||||
|
{ {0}, IPADDR4_INIT_BYTES(192, 168, 7, 4), 24 * 60 * 60 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const dhcp_config_t dhcp_config =
|
||||||
|
{
|
||||||
|
.router = IPADDR4_INIT_BYTES(0, 0, 0, 0), /* router address (if any) */
|
||||||
|
.port = 67, /* listen port */
|
||||||
|
.dns = IPADDR4_INIT_BYTES(0, 0, 0, 0), /* dns server (if any) */
|
||||||
|
"", /* dns suffix */
|
||||||
|
TU_ARRAY_SIZE(entries), /* num entry */
|
||||||
|
entries /* 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, 0 /* unused for this example */);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_lwip(void)
|
||||||
|
{
|
||||||
|
struct netif *netif = &netif_data;
|
||||||
|
|
||||||
|
/* Fixup MAC address based on flash serial */
|
||||||
|
//pico_unique_board_id_t id;
|
||||||
|
//pico_get_unique_board_id(&id);
|
||||||
|
//memcpy( (tud_network_mac_address)+1, id.id, 5);
|
||||||
|
// Fixing up does not work because tud_network_mac_address is const
|
||||||
|
|
||||||
|
/* Initialize tinyUSB */
|
||||||
|
tusb_init();
|
||||||
|
|
||||||
|
/* Initialize lwip */
|
||||||
|
lwip_init();
|
||||||
|
|
||||||
|
/* the lwip virtual MAC address must be different from the host's; to ensure this, we toggle the LSbit */
|
||||||
|
netif->hwaddr_len = sizeof(tud_network_mac_address);
|
||||||
|
memcpy(netif->hwaddr, tud_network_mac_address, sizeof(tud_network_mac_address));
|
||||||
|
netif->hwaddr[5] ^= 0x01;
|
||||||
|
|
||||||
|
netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ip_input);
|
||||||
|
netif_set_default(netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tud_network_recv_cb(const uint8_t *src, uint16_t size)
|
||||||
|
{
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
{
|
||||||
|
struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL);
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
/* pbuf_alloc() has already initialized struct; all we need to do is copy the data */
|
||||||
|
memcpy(p->payload, src, size);
|
||||||
|
|
||||||
|
/* store away the pointer for service_traffic() to later handle */
|
||||||
|
received_frame = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg)
|
||||||
|
{
|
||||||
|
struct pbuf *p = (struct pbuf *)ref;
|
||||||
|
struct pbuf *q;
|
||||||
|
uint16_t len = 0;
|
||||||
|
|
||||||
|
(void)arg; /* unused for this example */
|
||||||
|
|
||||||
|
/* traverse the "pbuf chain"; see ./lwip/src/core/pbuf.c for more info */
|
||||||
|
for(q = p; q != NULL; q = q->next)
|
||||||
|
{
|
||||||
|
memcpy(dst, (char *)q->payload, q->len);
|
||||||
|
dst += q->len;
|
||||||
|
len += q->len;
|
||||||
|
if (q->len == q->tot_len) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_check_timeouts();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dhcpd_init()
|
||||||
|
{
|
||||||
|
while (dhserv_init(&dhcp_config) != ERR_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_for_netif_is_up()
|
||||||
|
{
|
||||||
|
while (!netif_is_up(&netif_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* lwip platform specific routines for Pico */
|
||||||
|
static mutex_t lwip_mutex;
|
||||||
|
static int lwip_mutex_count = 0;
|
||||||
|
|
||||||
|
sys_prot_t sys_arch_protect(void)
|
||||||
|
{
|
||||||
|
uint32_t owner;
|
||||||
|
if (!mutex_try_enter(&lwip_mutex, &owner))
|
||||||
|
{
|
||||||
|
if (owner != get_core_num())
|
||||||
|
{
|
||||||
|
// Wait until other core releases mutex
|
||||||
|
mutex_enter_blocking(&lwip_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lwip_mutex_count++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sys_arch_unprotect(sys_prot_t pval)
|
||||||
|
{
|
||||||
|
(void)pval;
|
||||||
|
|
||||||
|
if (lwip_mutex_count)
|
||||||
|
{
|
||||||
|
lwip_mutex_count--;
|
||||||
|
if (!lwip_mutex_count)
|
||||||
|
{
|
||||||
|
mutex_exit(&lwip_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t sys_now(void)
|
||||||
|
{
|
||||||
|
return to_ms_since_boot( get_absolute_time() );
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef _TUSB_LWIP_GLUE_H_
|
||||||
|
#define _TUSB_LWIP_GLUE_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
#include "dhserver.h"
|
||||||
|
#include "dnserver.h"
|
||||||
|
#include "lwip/init.h"
|
||||||
|
#include "lwip/timeouts.h"
|
||||||
|
#include "lwip/apps/httpd.h"
|
||||||
|
|
||||||
|
void init_lwip();
|
||||||
|
void wait_for_netif_is_up();
|
||||||
|
void dhcpd_init();
|
||||||
|
void service_traffic();
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,238 @@
|
||||||
|
/*
|
||||||
|
* 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 "pico/unique_id.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] NET | 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) )
|
||||||
|
|
||||||
|
// String Descriptor Index
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STRID_LANGID = 0,
|
||||||
|
STRID_MANUFACTURER,
|
||||||
|
STRID_PRODUCT,
|
||||||
|
STRID_SERIAL,
|
||||||
|
STRID_INTERFACE,
|
||||||
|
STRID_MAC
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ITF_NUM_CDC = 0,
|
||||||
|
ITF_NUM_CDC_DATA,
|
||||||
|
ITF_NUM_TOTAL
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CONFIG_ID_RNDIS = 0,
|
||||||
|
CONFIG_ID_ECM = 1,
|
||||||
|
CONFIG_ID_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Device Descriptors
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
tusb_desc_device_t const desc_device =
|
||||||
|
{
|
||||||
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
|
.bcdUSB = 0x0200,
|
||||||
|
|
||||||
|
// Use Interface Association Descriptor (IAD) device class
|
||||||
|
.bDeviceClass = TUSB_CLASS_MISC,
|
||||||
|
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||||
|
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||||
|
|
||||||
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||||
|
|
||||||
|
.idVendor = 0xCafe,
|
||||||
|
.idProduct = USB_PID,
|
||||||
|
.bcdDevice = 0x0101,
|
||||||
|
|
||||||
|
.iManufacturer = STRID_MANUFACTURER,
|
||||||
|
.iProduct = STRID_PRODUCT,
|
||||||
|
.iSerialNumber = STRID_SERIAL,
|
||||||
|
|
||||||
|
.bNumConfigurations = CONFIG_ID_COUNT // multiple configurations
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
#define MAIN_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN)
|
||||||
|
#define ALT_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN)
|
||||||
|
|
||||||
|
#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_NET_NOTIF 0x81
|
||||||
|
#define EPNUM_NET_OUT 0x02
|
||||||
|
#define EPNUM_NET_IN 0x82
|
||||||
|
|
||||||
|
#elif CFG_TUSB_MCU == OPT_MCU_SAMG
|
||||||
|
// SAMG doesn't support a same endpoint number with different direction IN and OUT
|
||||||
|
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||||
|
#define EPNUM_NET_NOTIF 0x81
|
||||||
|
#define EPNUM_NET_OUT 0x02
|
||||||
|
#define EPNUM_NET_IN 0x83
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define EPNUM_NET_NOTIF 0x81
|
||||||
|
#define EPNUM_NET_OUT 0x02
|
||||||
|
#define EPNUM_NET_IN 0x82
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static uint8_t const rndis_configuration[] =
|
||||||
|
{
|
||||||
|
// Config number (index+1), interface count, string index, total length, attribute, power in mA
|
||||||
|
TUD_CONFIG_DESCRIPTOR(CONFIG_ID_RNDIS+1, ITF_NUM_TOTAL, 0, MAIN_CONFIG_TOTAL_LEN, 0, 100),
|
||||||
|
|
||||||
|
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||||
|
TUD_RNDIS_DESCRIPTOR(ITF_NUM_CDC, STRID_INTERFACE, EPNUM_NET_NOTIF, 8, EPNUM_NET_OUT, EPNUM_NET_IN, CFG_TUD_NET_ENDPOINT_SIZE),
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t const ecm_configuration[] =
|
||||||
|
{
|
||||||
|
// Config number (index+1), interface count, string index, total length, attribute, power in mA
|
||||||
|
TUD_CONFIG_DESCRIPTOR(CONFIG_ID_ECM+1, ITF_NUM_TOTAL, 0, ALT_CONFIG_TOTAL_LEN, 0, 100),
|
||||||
|
|
||||||
|
// 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, STRID_INTERFACE, STRID_MAC, EPNUM_NET_NOTIF, 64, EPNUM_NET_OUT, EPNUM_NET_IN, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Configuration array: RNDIS and CDC-ECM
|
||||||
|
// - Windows only works with RNDIS
|
||||||
|
// - MacOS only works with CDC-ECM
|
||||||
|
// - Linux will work on both
|
||||||
|
// Note index is Num-1x
|
||||||
|
static uint8_t const * const configuration_arr[2] =
|
||||||
|
{
|
||||||
|
[CONFIG_ID_RNDIS] = rndis_configuration,
|
||||||
|
[CONFIG_ID_ECM ] = ecm_configuration
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
return (index < CONFIG_ID_COUNT) ? configuration_arr[index] : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// String Descriptors
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// array of pointer to string descriptors
|
||||||
|
static char const* string_desc_arr [] =
|
||||||
|
{
|
||||||
|
[STRID_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409)
|
||||||
|
[STRID_MANUFACTURER] = "TinyUSB", // Manufacturer
|
||||||
|
[STRID_PRODUCT] = "Go to http://192.168.7.1/", // Product
|
||||||
|
//[STRID_SERIAL] = "123456", // Serial
|
||||||
|
[STRID_INTERFACE] = "TinyUSB Network Interface" // Interface Description
|
||||||
|
|
||||||
|
// STRID_MAC index is handled separately
|
||||||
|
// STRID_SERIAL index is handled seperately
|
||||||
|
};
|
||||||
|
|
||||||
|
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 int chr_count = 0;
|
||||||
|
|
||||||
|
if (STRID_LANGID == index)
|
||||||
|
{
|
||||||
|
memcpy(&_desc_str[1], string_desc_arr[STRID_LANGID], 2);
|
||||||
|
chr_count = 1;
|
||||||
|
}
|
||||||
|
else if (STRID_SERIAL == index)
|
||||||
|
{
|
||||||
|
pico_unique_board_id_t id;
|
||||||
|
pico_get_unique_board_id(&id);
|
||||||
|
|
||||||
|
for (unsigned i=0; i<sizeof(id.id); i++)
|
||||||
|
{
|
||||||
|
_desc_str[1+chr_count++] = "0123456789ABCDEF"[(id.id[i] >> 4) & 0xf];
|
||||||
|
_desc_str[1+chr_count++] = "0123456789ABCDEF"[(id.id[i] >> 0) & 0xf];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (STRID_MAC == index)
|
||||||
|
{
|
||||||
|
// Convert MAC address into UTF-16
|
||||||
|
|
||||||
|
for (unsigned i=0; i<sizeof(tud_network_mac_address); i++)
|
||||||
|
{
|
||||||
|
_desc_str[1+chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 4) & 0xf];
|
||||||
|
_desc_str[1+chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
|
||||||
|
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Convert ASCII string into UTF-16
|
||||||
|
for (unsigned int i=0; i<chr_count; i++)
|
||||||
|
{
|
||||||
|
_desc_str[1+i] = str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// first byte is length (including header), second byte is string type
|
||||||
|
_desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
|
||||||
|
|
||||||
|
return _desc_str;
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/bootrom.h"
|
||||||
|
#include "hardware/watchdog.h"
|
||||||
|
#include "hardware/structs/watchdog.h"
|
||||||
|
|
||||||
|
#include "tusb_lwip_glue.h"
|
||||||
|
|
||||||
|
#define LED_PIN 25
|
||||||
|
|
||||||
|
// let our webserver do some dynamic handling
|
||||||
|
static const char *cgi_toggle_led(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
|
||||||
|
{
|
||||||
|
gpio_put(LED_PIN, !gpio_get(LED_PIN));
|
||||||
|
return "/index.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *cgi_reset_usb_boot(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
|
||||||
|
{
|
||||||
|
reset_usb_boot(0, 0);
|
||||||
|
return "/index.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const tCGI cgi_handlers[] = {
|
||||||
|
{
|
||||||
|
"/toggle_led",
|
||||||
|
cgi_toggle_led
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"/reset_usb_boot",
|
||||||
|
cgi_reset_usb_boot
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Initialize tinyusb, lwip, dhcpd and httpd
|
||||||
|
init_lwip();
|
||||||
|
wait_for_netif_is_up();
|
||||||
|
dhcpd_init();
|
||||||
|
httpd_init();
|
||||||
|
http_set_cgi_handlers(cgi_handlers, LWIP_ARRAYSIZE(cgi_handlers));
|
||||||
|
|
||||||
|
// For toggle_led
|
||||||
|
gpio_init(LED_PIN);
|
||||||
|
gpio_set_dir(LED_PIN, GPIO_OUT);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
tud_task();
|
||||||
|
service_traffic();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Ładowanie…
Reference in New Issue