commit 473f9013c0099e7aae266201392f7e4ec8099422 Author: noisedestroyers Date: Sat Jul 26 21:48:13 2025 -0400 first and working ethernet diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..8077a71 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2435c20 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +!.vscode/* diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..f691ef3 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,22 @@ +{ + "configurations": [ + { + "name": "Pico", + "includePath": [ + "${workspaceFolder}/**", + "${userHome}/.pico-sdk/sdk/2.1.1/**" + ], + "forcedInclude": [ + "${userHome}/.pico-sdk/sdk/2.1.1/src/common/pico_base_headers/include/pico.h", + "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h" + ], + "defines": [], + "compilerPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gcc", + "compileCommands": "${workspaceFolder}/build/compile_commands.json", + "cStandard": "c17", + "cppStandard": "c++14", + "intelliSenseMode": "linux-gcc-arm" + } + ], + "version": 4 +} diff --git a/.vscode/cmake-kits.json b/.vscode/cmake-kits.json new file mode 100644 index 0000000..b0f3815 --- /dev/null +++ b/.vscode/cmake-kits.json @@ -0,0 +1,15 @@ +[ + { + "name": "Pico", + "compilers": { + "C": "${command:raspberry-pi-pico.getCompilerPath}", + "CXX": "${command:raspberry-pi-pico.getCxxCompilerPath}" + }, + "environmentVariables": { + "PATH": "${command:raspberry-pi-pico.getEnvPath};${env:PATH}" + }, + "cmakeSettings": { + "Python3_EXECUTABLE": "${command:raspberry-pi-pico.getPythonPath}" + } + } +] \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..a940d7c --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "marus25.cortex-debug", + "ms-vscode.cpptools", + "ms-vscode.cpptools-extension-pack", + "ms-vscode.vscode-serial-monitor", + "raspberry-pi.raspberry-pi-pico" + ] +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..34abc12 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,50 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Pico Debug (Cortex-Debug)", + "cwd": "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", + "executable": "${command:raspberry-pi-pico.launchTargetPath}", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "serverpath": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", + "gdbPath": "${command:raspberry-pi-pico.getGDBPath}", + "device": "${command:raspberry-pi-pico.getChipUppercase}", + "configFiles": [ + "interface/cmsis-dap.cfg", + "target/${command:raspberry-pi-pico.getTarget}.cfg" + ], + "svdFile": "${userHome}/.pico-sdk/sdk/2.1.1/src/${command:raspberry-pi-pico.getChip}/hardware_regs/${command:raspberry-pi-pico.getChipUppercase}.svd", + "runToEntryPoint": "main", + // Fix for no_flash binaries, where monitor reset halt doesn't do what is expected + // Also works fine for flash binaries + "overrideLaunchCommands": [ + "monitor reset init", + "load \"${command:raspberry-pi-pico.launchTargetPath}\"" + ], + "openOCDLaunchCommands": [ + "adapter speed 5000" + ] + }, + { + "name": "Pico Debug (Cortex-Debug with external OpenOCD)", + "cwd": "${workspaceRoot}", + "executable": "${command:raspberry-pi-pico.launchTargetPath}", + "request": "launch", + "type": "cortex-debug", + "servertype": "external", + "gdbTarget": "localhost:3333", + "gdbPath": "${command:raspberry-pi-pico.getGDBPath}", + "device": "${command:raspberry-pi-pico.getChipUppercase}", + "svdFile": "${userHome}/.pico-sdk/sdk/2.1.1/src/${command:raspberry-pi-pico.getChip}/hardware_regs/${command:raspberry-pi-pico.getChipUppercase}.svd", + "runToEntryPoint": "main", + // Fix for no_flash binaries, where monitor reset halt doesn't do what is expected + // Also works fine for flash binaries + "overrideLaunchCommands": [ + "monitor reset init", + "load \"${command:raspberry-pi-pico.launchTargetPath}\"" + ] + }, + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..53ad160 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,40 @@ +{ + "cmake.showSystemKits": false, + "cmake.options.statusBarVisibility": "hidden", + "cmake.options.advanced": { + "build": { + "statusBarVisibility": "hidden" + }, + "launch": { + "statusBarVisibility": "hidden" + }, + "debug": { + "statusBarVisibility": "hidden" + } + }, + "cmake.configureOnEdit": false, + "cmake.automaticReconfigure": false, + "cmake.configureOnOpen": false, + "cmake.generator": "Ninja", + "cmake.cmakePath": "${userHome}/.pico-sdk/cmake/v3.31.5/bin/cmake", + "C_Cpp.debugShortcut": false, + "terminal.integrated.env.windows": { + "PICO_SDK_PATH": "${env:USERPROFILE}/.pico-sdk/sdk/2.1.1", + "PICO_TOOLCHAIN_PATH": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1", + "Path": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1/bin;${env:USERPROFILE}/.pico-sdk/picotool/2.1.1/picotool;${env:USERPROFILE}/.pico-sdk/cmake/v3.31.5/bin;${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1;${env:PATH}" + }, + "terminal.integrated.env.osx": { + "PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/2.1.1", + "PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/14_2_Rel1", + "PATH": "${env:HOME}/.pico-sdk/toolchain/14_2_Rel1/bin:${env:HOME}/.pico-sdk/picotool/2.1.1/picotool:${env:HOME}/.pico-sdk/cmake/v3.31.5/bin:${env:HOME}/.pico-sdk/ninja/v1.12.1:${env:PATH}" + }, + "terminal.integrated.env.linux": { + "PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/2.1.1", + "PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/14_2_Rel1", + "PATH": "${env:HOME}/.pico-sdk/toolchain/14_2_Rel1/bin:${env:HOME}/.pico-sdk/picotool/2.1.1/picotool:${env:HOME}/.pico-sdk/cmake/v3.31.5/bin:${env:HOME}/.pico-sdk/ninja/v1.12.1:${env:PATH}" + }, + "raspberry-pi-pico.cmakeAutoConfigure": true, + "raspberry-pi-pico.useCmakeTools": false, + "raspberry-pi-pico.cmakePath": "${HOME}/.pico-sdk/cmake/v3.31.5/bin/cmake", + "raspberry-pi-pico.ninjaPath": "${HOME}/.pico-sdk/ninja/v1.12.1/ninja" +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..ee4df5f --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,102 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Compile Project", + "type": "process", + "isBuildCommand": true, + "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", + "args": ["-C", "${workspaceFolder}/build"], + "group": "build", + "presentation": { + "reveal": "always", + "panel": "dedicated" + }, + "problemMatcher": "$gcc", + "windows": { + "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" + } + }, + { + "label": "Run Project", + "type": "process", + "command": "${env:HOME}/.pico-sdk/picotool/2.1.1/picotool/picotool", + "args": [ + "load", + "${command:raspberry-pi-pico.launchTargetPath}", + "-fx" + ], + "presentation": { + "reveal": "always", + "panel": "dedicated" + }, + "problemMatcher": [], + "windows": { + "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.1.1/picotool/picotool.exe" + } + }, + { + "label": "Flash", + "type": "process", + "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", + "args": [ + "-s", + "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", + "-f", + "interface/cmsis-dap.cfg", + "-f", + "target/${command:raspberry-pi-pico.getTarget}.cfg", + "-c", + "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" + ], + "problemMatcher": [], + "windows": { + "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", + } + }, + { + "label": "Rescue Reset", + "type": "process", + "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", + "args": [ + "-s", + "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", + "-f", + "interface/cmsis-dap.cfg", + "-f", + "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", + "-c", + "adapter speed 5000; reset halt; exit" + ], + "problemMatcher": [], + "windows": { + "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", + } + }, + { + "label": "Risc-V Reset (RP2350)", + "type": "process", + "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", + "args": [ + "-s", + "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", + "-c", + "set USE_CORE { rv0 rv1 cm0 cm1 }", + "-f", + "interface/cmsis-dap.cfg", + "-f", + "target/rp2350.cfg", + "-c", + "adapter speed 5000; init;", + "-c", + "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", + "-c", + "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" + ], + "problemMatcher": [], + "windows": { + "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", + } + } + ] +} diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..60aa855 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,98 @@ +# Generated Cmake Pico project file + +cmake_minimum_required(VERSION 3.13) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Initialise pico_sdk from installed location +# (note this can come from environment, CMake cache etc) + +# == DO NOT EDIT THE FOLLOWING LINES for the Raspberry Pi Pico VS Code Extension to work == +if(WIN32) + set(USERHOME $ENV{USERPROFILE}) +else() + set(USERHOME $ENV{HOME}) +endif() +set(sdkVersion 2.1.1) +set(toolchainVersion 14_2_Rel1) +set(picotoolVersion 2.1.1) +set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake) +if (EXISTS ${picoVscode}) + include(${picoVscode}) +endif() +# ==================================================================================== +set(PICO_BOARD waveshare_rp2040_eth CACHE STRING "Board type") + +# Pull in Raspberry Pi Pico SDK (must be before project) +include(pico_sdk_import.cmake) + +project(barnum C CXX ASM) + +# Initialise the Raspberry Pi Pico SDK +pico_sdk_init() + +# Add executable. Default name is the project name, version 0.1 + +add_executable(barnum barnum.c ch9120.c) + +# Add initial version without ethernet +add_executable(barnum-initial barnum-initial.c) + +pico_set_program_name(barnum "barnum") +pico_set_program_version(barnum "0.1") + +pico_set_program_name(barnum-initial "barnum-initial") +pico_set_program_version(barnum-initial "0.1") + +# Generate PIO header +pico_generate_pio_header(barnum ${CMAKE_CURRENT_LIST_DIR}/blink.pio) +pico_generate_pio_header(barnum ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio) +pico_generate_pio_header(barnum-initial ${CMAKE_CURRENT_LIST_DIR}/blink.pio) +pico_generate_pio_header(barnum-initial ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio) + +# Modify the below lines to enable/disable output over UART/USB +pico_enable_stdio_uart(barnum 1) +pico_enable_stdio_usb(barnum 1) + +# Enable stdio for initial version +pico_enable_stdio_uart(barnum-initial 0) +pico_enable_stdio_usb(barnum-initial 1) + +# Add the standard library to the build +target_link_libraries(barnum + pico_stdlib) + +target_link_libraries(barnum-initial + pico_stdlib) + +# Add the standard include files to the build +target_include_directories(barnum PRIVATE + ${CMAKE_CURRENT_LIST_DIR} +) + +target_include_directories(barnum-initial PRIVATE + ${CMAKE_CURRENT_LIST_DIR} +) + +# Add any user requested libraries +target_link_libraries(barnum + hardware_uart + hardware_pio + hardware_timer + ) + +target_link_libraries(barnum-initial + hardware_spi + hardware_i2c + hardware_dma + hardware_pio + hardware_interp + hardware_timer + hardware_watchdog + ) + +pico_add_extra_outputs(barnum) +pico_add_extra_outputs(barnum-initial) + diff --git a/README_ETH.md b/README_ETH.md new file mode 100644 index 0000000..7420ab2 --- /dev/null +++ b/README_ETH.md @@ -0,0 +1,86 @@ +# RP2040-ETH WS2812 Network Control + +This implementation adds ethernet connectivity to the WS2812 LED control, allowing you to control the LED color over the network. + +## Hardware Setup + +- **Board**: Waveshare RP2040-ETH +- **LED**: WS2812 connected to GPIO 25 +- **Ethernet**: CH9120 chip handles TCP/IP communication + +## Network Configuration + +Default settings (can be modified in `ch9120.c`): +- **IP Address**: 192.168.1.200 +- **Port**: 1000 +- **Mode**: TCP Client +- **Target IP**: 192.168.1.10 +- **Target Port**: 2000 + +## Building + +```bash +cd build +cmake .. +make barnum_eth +``` + +## Flashing + +1. Hold BOOTSEL button and connect USB +2. Copy `barnum_eth.uf2` to the RPI-RP2 drive +3. The board will reboot automatically + +## Usage + +### Supported Commands + +Send these commands as TCP messages to control the LED: +- `RED` - Set LED to red +- `GREEN` - Set LED to green +- `BLUE` - Set LED to blue +- `WHITE` - Set LED to white +- `OFF` - Turn LED off +- `RGB:r,g,b` - Set custom color (e.g., `RGB:255,128,0` for orange) + +### Python Test Client + +Use the included `test_client.py` to test: + +```bash +# Run demo sequence +python3 test_client.py + +# Send single command +python3 test_client.py "RGB:255,0,255" +``` + +### Features + +- Smooth color transitions between commands +- Network status feedback via USB serial +- Acknowledgment messages for each command + +## Pin Assignments + +- **WS2812 Data**: GPIO 25 +- **UART TX (CH9120)**: GPIO 20 +- **UART RX (CH9120)**: GPIO 21 +- **CFG (CH9120)**: GPIO 18 +- **RES (CH9120)**: GPIO 19 + +## Troubleshooting + +1. **No network connection**: + - Check ethernet cable is connected + - Verify IP settings match your network + - Use serial monitor to see debug output + +2. **LED not responding**: + - Verify WS2812 is connected to GPIO 25 + - Check power supply to LED + - Monitor serial output for errors + +3. **Can't flash the board**: + - Make sure to use the correct board setting in CMakeLists.txt + - The board type is already set to `waveshare_rp2040_eth` \ No newline at end of file diff --git a/Refernce Code/.DS_Store b/Refernce Code/.DS_Store new file mode 100644 index 0000000..cc314cd Binary files /dev/null and b/Refernce Code/.DS_Store differ diff --git a/Refernce Code/RP2040-ETH-WS2812B/.DS_Store b/Refernce Code/RP2040-ETH-WS2812B/.DS_Store new file mode 100644 index 0000000..d60146f Binary files /dev/null and b/Refernce Code/RP2040-ETH-WS2812B/.DS_Store differ diff --git a/Refernce Code/RP2040-ETH-WS2812B/C/CMakeLists.txt b/Refernce Code/RP2040-ETH-WS2812B/C/CMakeLists.txt new file mode 100644 index 0000000..daa2a43 --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/C/CMakeLists.txt @@ -0,0 +1,41 @@ +# Generated Cmake Pico project file + +cmake_minimum_required(VERSION 3.13) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +# initalize pico_sdk from installed location +# (note this can come from environment, CMake cache etc) +#set(PICO_SDK_PATH "D:/Raspberry/Pico-Code/pico-sdk") + +# Pull in Raspberry Pi Pico SDK (must be before project) +include(pico_sdk_import.cmake) + +project(RP2040_WS2812B_Test C CXX ASM) + +# Initialise the Raspberry Pi Pico SDK +pico_sdk_init() + +# Add executable. Default name is the project name, version 0.1 + +add_executable(RP2040_WS2812B_Test RP2040_WS2812B_Test.c ) + +pico_generate_pio_header(RP2040_WS2812B_Test ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio OUTPUT_DIR ${CMAKE_CURRENT_LIST_DIR}/generated) + +pico_set_program_name(RP2040_WS2812B_Test "RP2040_WS2812B_Test") +pico_set_program_version(RP2040_WS2812B_Test "0.1") + +pico_enable_stdio_uart(RP2040_WS2812B_Test 0) +pico_enable_stdio_usb(RP2040_WS2812B_Test 0) + +# Add the standard library to the build +target_link_libraries(RP2040_WS2812B_Test pico_stdlib) + +# Add any user requested libraries +target_link_libraries(RP2040_WS2812B_Test + hardware_pio + ) + +pico_add_extra_outputs(RP2040_WS2812B_Test) + diff --git a/Refernce Code/RP2040-ETH-WS2812B/C/RP2040_WS2812B_Test.c b/Refernce Code/RP2040-ETH-WS2812B/C/RP2040_WS2812B_Test.c new file mode 100644 index 0000000..90d129e --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/C/RP2040_WS2812B_Test.c @@ -0,0 +1,51 @@ +#include +#include + +#include "pico/stdlib.h" +#include "hardware/pio.h" +#include "hardware/clocks.h" +#include "ws2812.pio.h" + +void put_pixel(uint32_t pixel_grb) +{ + pio_sm_put_blocking(pio0, 0, pixel_grb << 8u); +} +void put_rgb(uint8_t red, uint8_t green, uint8_t blue) +{ + uint32_t mask = (green << 16) | (red << 8) | (blue << 0); + put_pixel(mask); +} + +int main() +{ + //set_sys_clock_48(); + stdio_init_all(); + + PIO pio = pio0; + int sm = 0; + uint offset = pio_add_program(pio, &ws2812_program); + uint8_t cnt = 0; + + puts("RP2040-Zero WS2812 Test"); + + ws2812_program_init(pio, sm, offset, 25, 800000, true); + + while (1) + { + for (cnt = 0; cnt < 0xff; cnt++) + { + put_rgb(cnt, 0xff - cnt, 0); + sleep_ms(3); + } + for (cnt = 0; cnt < 0xff; cnt++) + { + put_rgb(0xff - cnt, 0, cnt); + sleep_ms(3); + } + for (cnt = 0; cnt < 0xff; cnt++) + { + put_rgb(0, cnt, 0xff - cnt); + sleep_ms(3); + } + } +} \ No newline at end of file diff --git a/Refernce Code/RP2040-ETH-WS2812B/C/ReadmeCN.txt b/Refernce Code/RP2040-ETH-WS2812B/C/ReadmeCN.txt new file mode 100644 index 0000000..ad1ffdc --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/C/ReadmeCN.txt @@ -0,0 +1,34 @@ +/***************************************************************************** +* | File : Readme_CN.txt +* | Author : +* | Function : Help with use +* | Info : +*---------------- +* | This version: V1.0 +* | Date : 2023-04-23 +* | Info : 在这里提供一个中文版本的使用文档,以便你的快速使用 +******************************************************************************/ +这个文件是帮助您使用本例程。 +由于我们的LCD越来越多,不便于我们的维护,因此把所有的LCD程序做成一个工程。 +在这里简略的描述本工程的使用: + +1.基本信息: +本例程用于测试或者演示RP2040-ETH上WS2812B; + +2.管脚连接: +DIN -> 25 + +3.基本使用: +你需要执行: + 如果目录已经存在,则可以直接进入。 如果没有目录,执行: + mkdir build + 进入目录,并添加SDK: + cd build + export PICO_SDK_PATH=../../pico-sdk + 其中 ../../pico-sdk 是你的SDK的目录。 + 执行cmake,自动生成Makefile文件: + cmake .. + 执行make生成可执行文件,然后在终端中输入: + make + 编译好的uf2文件复制到pico中即可 + diff --git a/Refernce Code/RP2040-ETH-WS2812B/C/ReadmeEN.txt b/Refernce Code/RP2040-ETH-WS2812B/C/ReadmeEN.txt new file mode 100644 index 0000000..c5ca11f --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/C/ReadmeEN.txt @@ -0,0 +1,35 @@ +/***************************************************************************** +* | File : Readme_EN.txt +* | Author : +* | Function : Help with use +* | Info : +*---------------- +* | This version: V1.0 +* | Date : 2021-02-04 +* | Info : Here is an English version of the documentation for your quick use. +******************************************************************************/ +This file is to help you use this routine. +Since our ink screens are getting more and more, it is not convenient for our maintenance, so all the ink screen programs are made into one project. +A brief description of the use of this project is here: + +1. Basic information: +This routine is used to test or demonstrate WS2812B on RP2040-ETH. + +2. Pin connection: +Pin connection You can look at dev_config.c/h in \lib\Config. Again, here: +DIN -> 25 + +3. Basic use: +You need to execute: + If the directory already exists, you can go directly. If there is no build directory, execute + mkdir build + Enter the build directory and type in the terminal: + cd build + export PICO_SDK_PATH=../../pico-sdk + Where ../../pico-sdk is your installed SDK directory + Execute cmake, automatically generate Makefile file, enter in the terminal: + cmake .. + Execute make to generate an executable file, and enter in the terminal: + make + Copy the compiled uf2 file to pico + diff --git a/Refernce Code/RP2040-ETH-WS2812B/C/generated/ws2812.pio.h b/Refernce Code/RP2040-ETH-WS2812B/C/generated/ws2812.pio.h new file mode 100644 index 0000000..a7739ad --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/C/generated/ws2812.pio.h @@ -0,0 +1,61 @@ +// -------------------------------------------------- // +// This file is autogenerated by pioasm; do not edit! // +// -------------------------------------------------- // + +#pragma once + +#if !PICO_NO_HARDWARE +#include "hardware/pio.h" +#endif + +// ------ // +// ws2812 // +// ------ // + +#define ws2812_wrap_target 0 +#define ws2812_wrap 3 + +#define ws2812_T1 2 +#define ws2812_T2 5 +#define ws2812_T3 3 + +static const uint16_t ws2812_program_instructions[] = { + // .wrap_target + 0x6221, // 0: out x, 1 side 0 [2] + 0x1123, // 1: jmp !x, 3 side 1 [1] + 0x1400, // 2: jmp 0 side 1 [4] + 0xa442, // 3: nop side 0 [4] + // .wrap +}; + +#if !PICO_NO_HARDWARE +static const struct pio_program ws2812_program = { + .instructions = ws2812_program_instructions, + .length = 4, + .origin = -1, +}; + +static inline pio_sm_config ws2812_program_get_default_config(uint offset) { + pio_sm_config c = pio_get_default_sm_config(); + sm_config_set_wrap(&c, offset + ws2812_wrap_target, offset + ws2812_wrap); + sm_config_set_sideset(&c, 1, false, false); + return c; +} + +#include "hardware/clocks.h" +static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) { + pio_gpio_init(pio, pin); + pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); + pio_sm_config c = ws2812_program_get_default_config(offset); + sm_config_set_sideset_pins(&c, pin); + sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24); + sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); + int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3; + float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit); + sm_config_set_clkdiv(&c, div); + pio_sm_init(pio, sm, offset, &c); + pio_sm_set_enabled(pio, sm, true); +} + +#endif + diff --git a/Refernce Code/RP2040-ETH-WS2812B/C/pico_sdk_import.cmake b/Refernce Code/RP2040-ETH-WS2812B/C/pico_sdk_import.cmake new file mode 100644 index 0000000..28efe9e --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/C/pico_sdk_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + ) + if (NOT pico_sdk) + message("Downloading Raspberry Pi Pico SDK") + FetchContent_Populate(pico_sdk) + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE}) diff --git a/Refernce Code/RP2040-ETH-WS2812B/C/uf2/RP2040_WS2812B_Test.uf2 b/Refernce Code/RP2040-ETH-WS2812B/C/uf2/RP2040_WS2812B_Test.uf2 new file mode 100644 index 0000000..5fe71cc Binary files /dev/null and b/Refernce Code/RP2040-ETH-WS2812B/C/uf2/RP2040_WS2812B_Test.uf2 differ diff --git a/Refernce Code/RP2040-ETH-WS2812B/C/ws2812.pio b/Refernce Code/RP2040-ETH-WS2812B/C/ws2812.pio new file mode 100644 index 0000000..ae19a6b --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/C/ws2812.pio @@ -0,0 +1,48 @@ +; +; Copyright (c) 2020 Raspberry Pi (Trading) Ltd. +; +; SPDX-License-Identifier: BSD-3-Clause +; + +.program ws2812 +.side_set 1 + +.define public T1 2 +.define public T2 5 +.define public T3 3 + +.lang_opt python sideset_init = pico.PIO.OUT_HIGH +.lang_opt python out_init = pico.PIO.OUT_HIGH +.lang_opt python out_shiftdir = 1 + +.wrap_target +bitloop: + out x, 1 side 0 [T3 - 1] ; Side-set still takes place when instruction stalls + jmp !x do_zero side 1 [T1 - 1] ; Branch on the bit we shifted out. Positive pulse +do_one: + jmp bitloop side 1 [T2 - 1] ; Continue driving high, for a long pulse +do_zero: + nop side 0 [T2 - 1] ; Or drive low, for a short pulse +.wrap + +% c-sdk { +#include "hardware/clocks.h" + +static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) { + + pio_gpio_init(pio, pin); + pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); + + pio_sm_config c = ws2812_program_get_default_config(offset); + sm_config_set_sideset_pins(&c, pin); + sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24); + sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); + + int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3; + float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit); + sm_config_set_clkdiv(&c, div); + + pio_sm_init(pio, sm, offset, &c); + pio_sm_set_enabled(pio, sm, true); +} +%} diff --git a/Refernce Code/RP2040-ETH-WS2812B/Python/RP2040-ETH-WS2812B.py b/Refernce Code/RP2040-ETH-WS2812B/Python/RP2040-ETH-WS2812B.py new file mode 100644 index 0000000..4ef2b48 --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/Python/RP2040-ETH-WS2812B.py @@ -0,0 +1,53 @@ +import time +from machine import Pin +import rp2 + +max_lum =100 +r=0 +g=0 +b=0 + +@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24) +def ws2812(): + T1 = 2 + T2 = 5 + T3 = 3 + wrap_target() + label("bitloop") + out(x, 1) .side(0) [T3 - 1] + jmp(not_x, "do_zero") .side(1) [T1 - 1] + jmp("bitloop") .side(1) [T2 - 1] + label("do_zero") + nop() .side(0) [T2 - 1] + wrap() + + +# Create the StateMachine with the ws2812 program, outputting on Pin(4). +sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(25)) + +# Start the StateMachine, it will wait for data on its FIFO. +sm.active(1) + +# Color change +while True: + for i in range(0,max_lum): + r=i + b=max_lum-i + rgb =(g<<24) | (r<<16) | (b<<8) + sm.put(rgb) + time.sleep_ms(10) + time.sleep_ms(300) + for i in range(0,max_lum): + g=i + r=max_lum-i + rgb =(g<<24) | (r<<16) | (b<<8) + sm.put(rgb) + time.sleep_ms(10) + time.sleep_ms(300) + for i in range(0,max_lum): + b=i + g=max_lum-i + rgb =(g<<24) | (r<<16) | (b<<8) + sm.put(rgb) + time.sleep_ms(10) + time.sleep_ms(300) \ No newline at end of file diff --git a/Refernce Code/RP2040-ETH-WS2812B/Python/ReadmeCN.txt b/Refernce Code/RP2040-ETH-WS2812B/Python/ReadmeCN.txt new file mode 100644 index 0000000..5ddca62 --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/Python/ReadmeCN.txt @@ -0,0 +1,36 @@ +/***************************************************************************** +* | File : Readme_CN.txt +* | Author : +* | Function : Help with use +* | Info : +*---------------- +* | This version: V1.0 +* | Date : 2021-11-22 +* | Info : 在这里提供一个中文版本的使用文档,以便你的快速使用 +******************************************************************************/ +这个文件是帮助您使用本例程。 +在这里简略的描述本工程的使用: + +1.基本信息: +本例程用于测试或者演示RP2040-Zero上WS2812B; + +2.管脚连接: +管脚连接你可以在RP2040-Zero.py查看,这里也再重述一次: +DIN -> 16 + +3.基本使用: + 1): 按住RP2040-Zero板上的Boot按键,将RP2040-Zero通过Type-C USB线接到电脑的USB接口,然后松开按键。 + 接入之后,电脑会自动识别到一个可移动盘(RPI-RP2) + + 2): 将Python目录下的uf2文件夹中rp2-pico-20210902-v1.17.uf2 文件复制到识别的可移动盘(RPI-RP2)中 + + 3): 更新Thonny IDE + sudo apt upgrade thonny + + 4): 打开Thonny IDE (点击树莓logo -> Programming -> Thonny Python IDE ) + 选择Tools -> Options... -> Interpreter + 选择MicroPython(Raspberry Pi Pico 和ttyACM0端口 + + 5): 在Thonny IDE中打开Python/RP2040-Zero.py文件 + 然后运行当前脚本(绿色小三角)即可 + \ No newline at end of file diff --git a/Refernce Code/RP2040-ETH-WS2812B/Python/ReadmeEN.txt b/Refernce Code/RP2040-ETH-WS2812B/Python/ReadmeEN.txt new file mode 100644 index 0000000..6644f71 --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/Python/ReadmeEN.txt @@ -0,0 +1,38 @@ +/***************************************************************************** +* | File : Readme_EN.txt +* | Author : +* | Function : Help with use +* | Info : +*---------------- +* | This version: V1.0 +* | Date : 2021-11-22 +* | Info : Here is an English version of the documentation for your quick use. +******************************************************************************/ +This file is to help you use this routine. +Here is a brief description of the use of this project: + +1. Basic information: +This routine is used to test or demonstrate WS2812B on RP2040-Zero. + +2. Pin connection: +You can check the pin connection at RP2040-Zero.py, and repeat it here: +DIN -> 16 + +3. Basic use: + 1): Press and hold the Bootsel button on the RP2040-Zero board, connect RP2040-Zero to the USB port of the + computer through the Type-C USB cable, and then release the button. + After connecting, the computer will automatically recognize a removable disk (RPI-RP2) + + 2): Copy the rp2-Pico-20210902-v1.17.uf2 file from the Uf2 folder in the Python directory to an identified + removable disk (rpi-rp2) + + 3): Update Thonny IDE + sudo apt upgrade thonny + + 4): Open Thonny IDE (Click raspberry logo -> Programming -> Thonny Python IDE ) + select Tools -> Options... -> Interpreter + select MicroPython(Raspberry Pi Pico and ttyACM0 port + + 5): Open the Python/ rp2040-zero.py file in Thonny IDE + Then run the current script (little green triangle) + \ No newline at end of file diff --git a/Refernce Code/RP2040-ETH-WS2812B/Python/uf2/rp2-pico-20230209-unstable-v1.19.1.uf2 b/Refernce Code/RP2040-ETH-WS2812B/Python/uf2/rp2-pico-20230209-unstable-v1.19.1.uf2 new file mode 100644 index 0000000..fe9d0b6 Binary files /dev/null and b/Refernce Code/RP2040-ETH-WS2812B/Python/uf2/rp2-pico-20230209-unstable-v1.19.1.uf2 differ diff --git a/Refernce Code/RP2040-ETH-WS2812B/Version_CN.txt b/Refernce Code/RP2040-ETH-WS2812B/Version_CN.txt new file mode 100644 index 0000000..7d65e3a --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/Version_CN.txt @@ -0,0 +1 @@ +2021-11-22:新创建。 diff --git a/Refernce Code/RP2040-ETH-WS2812B/Version_EN.txt b/Refernce Code/RP2040-ETH-WS2812B/Version_EN.txt new file mode 100644 index 0000000..c4aa51f --- /dev/null +++ b/Refernce Code/RP2040-ETH-WS2812B/Version_EN.txt @@ -0,0 +1 @@ +2021-11-22: newly built. \ No newline at end of file diff --git a/Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/CH9120.cpp b/Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/CH9120.cpp new file mode 100644 index 0000000..578000f --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/CH9120.cpp @@ -0,0 +1,315 @@ +#include "CH9120.h" + +UCHAR CH9120_Mode = TCP_CLIENT; //Optional:TCP_SERVER、TCP_CLIENT、UDP_SERVER、UDP_CLIENT +UCHAR CH9120_LOCAL_IP[4] = {192, 168, 10, 205}; // LOCAL IP +UCHAR CH9120_GATEWAY[4] = {192, 168, 11, 1}; // GATEWAY +UCHAR CH9120_SUBNET_MASK[4] = {255, 255, 252, 0}; // SUBNET MASK +UCHAR CH9120_TARGET_IP[4] = {192, 168, 10, 137}; // TARGET_IP +UWORD CH9120_PORT1 = 1000; // LOCAL PORT1 +UWORD CH9120_TARGET_PORT = 2000; // TARGET PORT +UDOUBLE CH9120_BAUD_RATE = 115200; // BAUD RATE + +UCHAR tx[8] = {0x57, 0xAB}; + +/****************************************************************************** +function: Send four bytes +parameter: + data: parameter + command: command code +Info: Set mode, enable port, clear serial port, switch DHCP, switch port 2 +******************************************************************************/ +void CH9120_TX_4_bytes(UCHAR data, int command) +{ + for (int i = 2; i < 4; i++) + { + if (i == 2) + tx[i] = command; + else + tx[i] = data; + } + DEV_Delay_ms(10); + for (int o = 0; o < 4; o++) + UART_ID1.write(tx[o]); + DEV_Delay_ms(10); + for (int i = 2; i < 4; i++) + tx[i] = 0; +} + +/****************************************************************************** +function: Send five bytes +parameter: + data: parameter + command: command code +Info: Set the local port and target port +******************************************************************************/ +void CH9120_TX_5_bytes(UWORD data, int command) +{ + UCHAR Port[2]; + Port[0] = data & 0xff; + Port[1] = data >> 8; + for (int i = 2; i < 5; i++) + { + if (i == 2) + tx[i] = command; + else + tx[i] = Port[i - 3]; + } + DEV_Delay_ms(10); + for (int o = 0; o < 5; o++) + UART_ID1.write(tx[o]); + DEV_Delay_ms(10); + for (int i = 2; i < 5; i++) + tx[i] = 0; +} +/****************************************************************************** +function: Send seven bytes +parameter: + data: parameter + command: command code +Info: Set the IP address, subnet mask, gateway, +******************************************************************************/ +void CH9120_TX_7_bytes(UCHAR data[], int command) +{ + for (int i = 2; i < 7; i++) + { + if (i == 2) + tx[i] = command; + else + tx[i] = data[i - 3]; + } + DEV_Delay_ms(10); + for (int o = 0; o < 7; o++) + UART_ID1.write(tx[o]); + DEV_Delay_ms(10); + for (int i = 2; i < 7; i++) + tx[i] = 0; +} + +/****************************************************************************** +function: CH9120_TX_BAUD +parameter: + data: parameter + command: command code +Info: Set baud rate +******************************************************************************/ +void CH9120_TX_BAUD(UDOUBLE data, int command) +{ + UCHAR Port[4]; + Port[0] = (data & 0xff); + Port[1] = (data >> 8) & 0xff; + Port[2] = (data >> 16) & 0xff; + Port[3] = data >> 24; + + for (int i = 2; i < 7; i++) + { + if (i == 2) + tx[i] = command; + else + tx[i] = Port[i - 3]; + } + DEV_Delay_ms(10); + for (int o = 0; o < 7; o++) + UART_ID1.write(tx[o]); + DEV_Delay_ms(10); + for (int i = 2; i < 7; i++) + tx[i] = 0; +} + +/****************************************************************************** +function: CH9120_Start +parameter: +Info: Start configuration Parameters +******************************************************************************/ +void CH9120_Start(void) +{ + digitalWrite(CFG_PIN, 0); + digitalWrite(RES_PIN, 1); + DEV_Delay_ms(500); +} + +/****************************************************************************** +function: CH9120_End +parameter: +Info: Updating configuration Parameters +******************************************************************************/ +void CH9120_End(void) +{ + tx[2] = 0x0d; + for (int o = 0; o < 3; o++) + UART_ID1.write(tx[o]); + DEV_Delay_ms(200); + tx[2] = 0x0e; + for (int o = 0; o < 3; o++) + UART_ID1.write(tx[o]); + DEV_Delay_ms(200); + tx[2] = 0x5e; + for (int o = 0; o < 3; o++) + UART_ID1.write(tx[o]); + DEV_Delay_ms(500); + gpio_put(CFG_PIN, 1); +} + +/****************************************************************************** +Function: CH9120_SetMode +Parameters: + Mode: Mode parameter +Info: Configure communication mode +******************************************************************************/ +void CH9120_SetMode(UCHAR Mode) +{ + CH9120_TX_4_bytes(Mode, Mode1); //Mode + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetLocalIP +Parameters: + CH9120_LOCAL_IP: Local IP parameter +Info: Configure local IP +******************************************************************************/ +void CH9120_SetLocalIP(UCHAR CH9120_LOCAL_IP[]) +{ + CH9120_TX_7_bytes(CH9120_LOCAL_IP, LOCAL_IP); //LOCALIP + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetSubnetMask +Parameters: + CH9120_SUBNET_MASK: SUBNET MASK parameter +Info: Configure subnet mask +******************************************************************************/ +void CH9120_SetSubnetMask(UCHAR CH9120_SUBNET_MASK[]) +{ + CH9120_TX_7_bytes(CH9120_SUBNET_MASK, SUBNET_MASK); //SUBNET MASK + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetGateway +Parameters: + CH9120_GATEWAY: Gateway parameter +Info: Configure gateway +******************************************************************************/ +void CH9120_SetGateway(UCHAR CH9120_GATEWAY[]) +{ + CH9120_TX_7_bytes(CH9120_GATEWAY, GATEWAY); //GATEWAY + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetTargetIP +Parameters: + CH9120_TARGET_IP: Target IP parameter +Info: Configure target IP +******************************************************************************/ +void CH9120_SetTargetIP(UCHAR CH9120_TARGET_IP[]) +{ + CH9120_TX_7_bytes(CH9120_TARGET_IP, TARGET_IP1); //TARGET IP + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetLocalPort +Parameters: + CH9120_PORT: Local Port parameter +Info: Configure local port number +******************************************************************************/ +void CH9120_SetLocalPort(UWORD CH9120_PORT) +{ + CH9120_TX_5_bytes(CH9120_PORT, LOCAL_PORT1); //Local port + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetTargetPort +Parameters: + CH9120_TARGET_PORT: Target Port parameter +Info: Configure target port number +******************************************************************************/ +void CH9120_SetTargetPort(UWORD CH9120_TARGET_PORT) +{ + CH9120_TX_5_bytes(CH9120_TARGET_PORT, TARGET_PORT1); //Target port + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetBaudRate +Parameters: + CH9120_BAUD_RATE: Baud Rate parameter +Info: Configure communication baud rate +******************************************************************************/ +void CH9120_SetBaudRate(UDOUBLE CH9120_BAUD_RATE) +{ + CH9120_TX_BAUD(CH9120_BAUD_RATE, UART1_BAUD1); //Port 1 baud rate + DEV_Delay_ms(100); +} + +/** + * delay x ms +**/ +void DEV_Delay_ms(UDOUBLE xms) +{ + delay(xms); +} + +void DEV_Delay_us(UDOUBLE xus) +{ + delayMicroseconds(xus); +} + +/****************************************************************************** +function: CH9120_init +parameter: +Info: Initialize CH9120 +******************************************************************************/ +void CH9120_init(void) +{ + Serial.begin(115200); + delay(1000); + + UART_ID1.setTX(UART_TX_PIN1); + UART_ID1.setRX(UART_RX_PIN1); + UART_ID1.begin(Inti_BAUD_RATE); + + pinMode(CFG_PIN,OUTPUT); + pinMode(RES_PIN,OUTPUT); + + CH9120_Start(); + CH9120_SetMode(CH9120_Mode); //Mode + CH9120_SetLocalIP(CH9120_LOCAL_IP); //LOCALIP + CH9120_SetSubnetMask(CH9120_SUBNET_MASK); //SUBNET MASK + CH9120_SetGateway(CH9120_GATEWAY); //GATEWAY + CH9120_SetTargetIP(CH9120_TARGET_IP); //TARGET IP + CH9120_SetLocalPort(CH9120_PORT1); //Local port + CH9120_SetTargetPort(CH9120_TARGET_PORT); //Target port + CH9120_SetBaudRate(CH9120_BAUD_RATE); //Port 1 baud rate + CH9120_End(); + + UART_ID1.begin(Transport_BAUD_RATE); + while (UART_ID1.available()) + { + UBYTE ch1 = UART_ID1.read(); + } +} + + +/****************************************************************************** +function: RX_TX +parameter: +Info: Serial port 1 and serial port 2 receive and dispatch +******************************************************************************/ +void RX_TX() +{ + + while (1) + { + while (UART_ID1.available()) + { + UCHAR ch1 = UART_ID1.read(); + UART_ID1.write(ch1); +// Serial.print((char)ch1); + + } + } +} diff --git a/Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/CH9120.h b/Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/CH9120.h new file mode 100644 index 0000000..ec21f82 --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/CH9120.h @@ -0,0 +1,54 @@ +#ifndef _CH9120_H_ +#define _CH9120_H_ + +#include + +#include // malloc() free() +#include + + +/// \tag::uart_advanced[] +#define UART_ID1 Serial2 +#define Inti_BAUD_RATE 9600 +#define Transport_BAUD_RATE 115200 +#define DATA_BITS 8 +#define STOP_BITS 1 +#define PARITY UART_PARITY_NONE + +// We are using pins 0 and 1, but see the GPIO function select table in the +// datasheet for information on which other pins can be used. + +#define UART_TX_PIN1 20 +#define UART_RX_PIN1 21 + +#define CFG_PIN 18 +#define RES_PIN 19 +#define GPIO_OUT 1 +#define GPIO_IN 0 + +#define UCHAR unsigned char +#define UBYTE uint8_t +#define UWORD uint16_t +#define UDOUBLE uint32_t + +#define TCP_SERVER 0 +#define TCP_CLIENT 1 +#define UDP_SERVER 2 +#define UDP_CLIENT 3 + +#define Mode1 0x10 //Port 1: Setup Mode 0x00:TCP Server 0x01:TCP Client 0x02:UDP Server 0x03:UDP Client +#define LOCAL_IP 0x11 //Local IP +#define SUBNET_MASK 0x12 //Subnet Mask +#define GATEWAY 0x13 //Gateway +#define LOCAL_PORT1 0X14 //Port 1:Local Port +#define TARGET_IP1 0x15 //Port 1:Target IP +#define TARGET_PORT1 0x16 //Port 1:Target Port +#define PORT_RANDOM_ENABLE1 0x17 //Port 1:Port Random Enable +#define UART1_BAUD1 0x21 //Port 1:Baud rate of serial port 1 + +void CH9120_init(void); +void RX_TX(); +void DEV_Delay_ms(UDOUBLE xms); +void DEV_Delay_us(UDOUBLE xus); + +#endif diff --git a/Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/RP2040-ETH-Demo.ino b/Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/RP2040-ETH-Demo.ino new file mode 100644 index 0000000..959c4e1 --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/RP2040-ETH-Demo.ino @@ -0,0 +1,10 @@ +#include "CH9120.h" + +void setup() { + CH9120_init(); + RX_TX(); +} + +void loop() { + +} diff --git a/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/CMakeLists.txt b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/CMakeLists.txt new file mode 100644 index 0000000..8d5a85c --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.12) +include(pico_sdk_import.cmake) +project(Pico_ePaper_Code) +pico_sdk_init() + +#添加编译子目录 +add_subdirectory(lib/CH9120) +add_subdirectory(examples) + + + +#添加头文件目录 +include_directories(examples) +include_directories(./lib/CH9120) + + +# 生成可执行文件 +add_executable(main +main.c +) + +# enable usb output, disable uart output +pico_enable_stdio_usb(main 1) +pico_enable_stdio_uart(main 1) + +# create map/bin/hex/uf2 file etc. +pico_add_extra_outputs(main) + +target_link_libraries(main examples CH9120 pico_stdlib hardware_spi) \ No newline at end of file diff --git a/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/examples/CH9120_Test.h b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/examples/CH9120_Test.h new file mode 100644 index 0000000..c053707 --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/examples/CH9120_Test.h @@ -0,0 +1,45 @@ +/***************************************************************************** +* | File : CH9120_Test.h +* | Author : Waveshare team +* | Function : RP2040 ETH test Demo +* | Info : +*---------------- +* | This version: V1.0 +* | Date : 2023-04-01 +* | Info : +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documnetation 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 +# furished 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 OR 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 _CH9120_TEST_H_ +#define _CH9120_TEST_H_ + +#include "CH9120.h" + +extern UCHAR CH9120_LOCAL_IP[4]; +extern UCHAR CH9120_GATEWAY[4]; +extern UCHAR CH9120_SUBNET_MASK[4]; +extern UCHAR CH9120_TARGET_IP[4]; +extern UWORD CH9120_PORT1; +extern UWORD CH9120_TARGET_PORT; +extern UDOUBLE CH9120_BAUD_RATE; + +int Pico_ETH_CH9120_test(void); + +#endif diff --git a/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/examples/CMakeLists.txt b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/examples/CMakeLists.txt new file mode 100644 index 0000000..257ef2d --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/examples/CMakeLists.txt @@ -0,0 +1,9 @@ +# 查找当前目录下的所有源文件 +# 并将名称保存到 DIR_examples_SRCS 变量 +aux_source_directory(. DIR_examples_SRCS) + +include_directories(../lib/CH9120) + +# 生成链接库 +add_library(examples ${DIR_examples_SRCS}) +target_link_libraries(examples PUBLIC CH9120) \ No newline at end of file diff --git a/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/examples/RP2040_ETH_CH9120_test.c b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/examples/RP2040_ETH_CH9120_test.c new file mode 100644 index 0000000..de7f418 --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/examples/RP2040_ETH_CH9120_test.c @@ -0,0 +1,36 @@ +/***************************************************************************** +* | File : RP2040_ETH_CH9120_test.c +* | Author : Waveshare team +* | Function : Pico_ETH_CH9120 test demo +* | Info : +*---------------- +* | This version: V1.0 +* | Date : 2023-04-01 +* | Info : +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documnetation 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 +# furished 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 OR 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 "CH9120_Test.h" + +int Pico_ETH_CH9120_test(void) +{ + CH9120_init(); //Initialize Configuration CH9120 + RX_TX(); //receive and dispatch +} diff --git a/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/lib/CH9120/CH9120.c b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/lib/CH9120/CH9120.c new file mode 100644 index 0000000..5731bbc --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/lib/CH9120/CH9120.c @@ -0,0 +1,313 @@ +#include "CH9120.h" + +UCHAR CH9120_Mode = TCP_CLIENT; //Optional:TCP_SERVER、TCP_CLIENT、UDP_SERVER、UDP_CLIENT +UCHAR CH9120_LOCAL_IP[4] = {192, 168, 1, 200}; // LOCAL IP +UCHAR CH9120_GATEWAY[4] = {192, 168, 1, 1}; // GATEWAY +UCHAR CH9120_SUBNET_MASK[4] = {255, 255, 255, 0}; // SUBNET MASK +UCHAR CH9120_TARGET_IP[4] = {192, 168, 1, 10}; // TARGET_IP +UWORD CH9120_PORT1 = 1000; // LOCAL PORT1 +UWORD CH9120_TARGET_PORT = 2000; // TARGET PORT +UDOUBLE CH9120_BAUD_RATE = 115200; // BAUD RATE + +UCHAR tx[8] = {0x57, 0xAB}; + +/****************************************************************************** +function: Send four bytes +parameter: + data: parameter + command: command code +Info: Set mode, enable port, clear serial port, switch DHCP, switch port 2 +******************************************************************************/ +void CH9120_TX_4_bytes(UCHAR data, int command) +{ + for (int i = 2; i < 4; i++) + { + if (i == 2) + tx[i] = command; + else + tx[i] = data; + } + DEV_Delay_ms(10); + for (int o = 0; o < 4; o++) + uart_putc(UART_ID1, tx[o]); + DEV_Delay_ms(10); + for (int i = 2; i < 4; i++) + tx[i] = 0; +} + +/****************************************************************************** +function: Send five bytes +parameter: + data: parameter + command: command code +Info: Set the local port and target port +******************************************************************************/ +void CH9120_TX_5_bytes(UWORD data, int command) +{ + UCHAR Port[2]; + Port[0] = data & 0xff; + Port[1] = data >> 8; + for (int i = 2; i < 5; i++) + { + if (i == 2) + tx[i] = command; + else + tx[i] = Port[i - 3]; + } + DEV_Delay_ms(10); + for (int o = 0; o < 5; o++) + uart_putc(UART_ID1, tx[o]); + DEV_Delay_ms(10); + for (int i = 2; i < 5; i++) + tx[i] = 0; +} +/****************************************************************************** +function: Send seven bytes +parameter: + data: parameter + command: command code +Info: Set the IP address, subnet mask, gateway, +******************************************************************************/ +void CH9120_TX_7_bytes(UCHAR data[], int command) +{ + for (int i = 2; i < 7; i++) + { + if (i == 2) + tx[i] = command; + else + tx[i] = data[i - 3]; + } + DEV_Delay_ms(10); + for (int o = 0; o < 7; o++) + uart_putc(UART_ID1, tx[o]); + DEV_Delay_ms(10); + for (int i = 2; i < 7; i++) + tx[i] = 0; +} + +/****************************************************************************** +function: CH9120_TX_BAUD +parameter: + data: parameter + command: command code +Info: Set baud rate +******************************************************************************/ +void CH9120_TX_BAUD(UDOUBLE data, int command) +{ + UCHAR Port[4]; + Port[0] = (data & 0xff); + Port[1] = (data >> 8) & 0xff; + Port[2] = (data >> 16) & 0xff; + Port[3] = data >> 24; + + for (int i = 2; i < 7; i++) + { + if (i == 2) + tx[i] = command; + else + tx[i] = Port[i - 3]; + } + DEV_Delay_ms(10); + for (int o = 0; o < 7; o++) + uart_putc(UART_ID1, tx[o]); + DEV_Delay_ms(10); + for (int i = 2; i < 7; i++) + tx[i] = 0; +} + +/****************************************************************************** +function: CH9120_Start +parameter: +Info: Start configuration Parameters +******************************************************************************/ +void CH9120_Start() +{ + gpio_put(RES_PIN, 1); + gpio_put(CFG_PIN, 0); + DEV_Delay_ms(500); +} + +/****************************************************************************** +function: CH9120_End +parameter: +Info: Updating configuration Parameters +******************************************************************************/ +void CH9120_End() +{ + tx[2] = 0x0d; + uart_puts(UART_ID1, tx); + DEV_Delay_ms(200); + tx[2] = 0x0e; + uart_puts(UART_ID1, tx); + DEV_Delay_ms(200); + tx[2] = 0x5e; + uart_puts(UART_ID1, tx); + DEV_Delay_ms(200); + gpio_put(CFG_PIN, 1); +} + +/****************************************************************************** +Function: CH9120_SetMode +Parameters: + Mode: Mode parameter +Info: Configure communication mode +******************************************************************************/ +void CH9120_SetMode(UCHAR Mode) +{ + CH9120_TX_4_bytes(Mode, Mode1); //Mode + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetLocalIP +Parameters: + CH9120_LOCAL_IP: Local IP parameter +Info: Configure local IP +******************************************************************************/ +void CH9120_SetLocalIP(UCHAR CH9120_LOCAL_IP[]) +{ + CH9120_TX_7_bytes(CH9120_LOCAL_IP, LOCAL_IP); //LOCALIP + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetSubnetMask +Parameters: + CH9120_SUBNET_MASK: SUBNET MASK parameter +Info: Configure subnet mask +******************************************************************************/ +void CH9120_SetSubnetMask(UCHAR CH9120_SUBNET_MASK[]) +{ + CH9120_TX_7_bytes(CH9120_SUBNET_MASK, SUBNET_MASK); //SUBNET MASK + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetGateway +Parameters: + CH9120_GATEWAY: Gateway parameter +Info: Configure gateway +******************************************************************************/ +void CH9120_SetGateway(UCHAR CH9120_GATEWAY[]) +{ + CH9120_TX_7_bytes(CH9120_GATEWAY, GATEWAY); //GATEWAY + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetTargetIP +Parameters: + CH9120_TARGET_IP: Target IP parameter +Info: Configure target IP +******************************************************************************/ +void CH9120_SetTargetIP(UCHAR CH9120_TARGET_IP[]) +{ + CH9120_TX_7_bytes(CH9120_TARGET_IP, TARGET_IP1); //TARGET IP + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetLocalPort +Parameters: + CH9120_PORT: Local Port parameter +Info: Configure local port number +******************************************************************************/ +void CH9120_SetLocalPort(UWORD CH9120_PORT) +{ + CH9120_TX_5_bytes(CH9120_PORT, LOCAL_PORT1); //Local port + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetTargetPort +Parameters: + CH9120_TARGET_PORT: Target Port parameter +Info: Configure target port number +******************************************************************************/ +void CH9120_SetTargetPort(UWORD CH9120_TARGET_PORT) +{ + CH9120_TX_5_bytes(CH9120_TARGET_PORT, TARGET_PORT1); //Target port + DEV_Delay_ms(100); +} + +/****************************************************************************** +Function: CH9120_SetBaudRate +Parameters: + CH9120_BAUD_RATE: Baud Rate parameter +Info: Configure communication baud rate +******************************************************************************/ +void CH9120_SetBaudRate(UDOUBLE CH9120_BAUD_RATE) +{ + CH9120_TX_BAUD(CH9120_BAUD_RATE, UART1_BAUD1); //Port 1 baud rate + DEV_Delay_ms(100); +} + +/** + * delay x ms +**/ +void DEV_Delay_ms(UDOUBLE xms) +{ + sleep_ms(xms); +} + +void DEV_Delay_us(UDOUBLE xus) +{ + sleep_us(xus); +} + +/****************************************************************************** +function: CH9120_init +parameter: +Info: Initialize CH9120 +******************************************************************************/ +void CH9120_init(void) +{ + stdio_init_all(); + + uart_init(UART_ID1, Inti_BAUD_RATE); + gpio_set_function(UART_TX_PIN1, GPIO_FUNC_UART); + gpio_set_function(UART_RX_PIN1, GPIO_FUNC_UART); + + gpio_init(CFG_PIN); + gpio_init(RES_PIN); + gpio_set_dir(CFG_PIN, GPIO_OUT); + gpio_set_dir(RES_PIN, GPIO_OUT); + + CH9120_Start(); + CH9120_SetMode(CH9120_Mode); //Mode + CH9120_SetLocalIP(CH9120_LOCAL_IP); //LOCALIP + CH9120_SetSubnetMask(CH9120_SUBNET_MASK); //SUBNET MASK + CH9120_SetGateway(CH9120_GATEWAY); //GATEWAY + CH9120_SetTargetIP(CH9120_TARGET_IP); //TARGET IP + CH9120_SetLocalPort(CH9120_PORT1); //Local port + CH9120_SetTargetPort(CH9120_TARGET_PORT); //Target port + CH9120_SetBaudRate(CH9120_BAUD_RATE); //Port 1 baud rate + CH9120_End(); + + uart_set_baudrate(UART_ID1, Transport_BAUD_RATE); + while (uart_is_readable(UART_ID1)) + { + UBYTE ch1 = uart_getc(UART_ID1); + } +} + + +/****************************************************************************** +function: RX_TX +parameter: +Info: Serial port 1 and serial port 2 receive and dispatch +******************************************************************************/ +void RX_TX() +{ + while (1) + { + while (uart_is_readable(UART_ID1)) + { + UBYTE ch1 = uart_getc(UART_ID1); + if (uart_is_writable(UART_ID1)) + { + uart_putc(UART_ID1, ch1); + } + } + } +} \ No newline at end of file diff --git a/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/lib/CH9120/CH9120.h b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/lib/CH9120/CH9120.h new file mode 100644 index 0000000..8d91141 --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/lib/CH9120/CH9120.h @@ -0,0 +1,54 @@ +#ifndef _CH9120_H_ +#define _CH9120_H_ + +#include // malloc() free() +#include +#include "pico/stdlib.h" +#include "hardware/uart.h" +#include "hardware/irq.h" + +/// \tag::uart_advanced[] +#define UART_ID1 uart1 +#define Inti_BAUD_RATE 9600 +#define Transport_BAUD_RATE 115200 +#define DATA_BITS 8 +#define STOP_BITS 1 +#define PARITY UART_PARITY_NONE + +// We are using pins 0 and 1, but see the GPIO function select table in the +// datasheet for information on which other pins can be used. + +#define UART_TX_PIN1 20 +#define UART_RX_PIN1 21 + +#define CFG_PIN 18 +#define RES_PIN 19 +#define GPIO_OUT 1 +#define GPIO_IN 0 + +#define UCHAR unsigned char +#define UBYTE uint8_t +#define UWORD uint16_t +#define UDOUBLE uint32_t + +#define TCP_SERVER 0 +#define TCP_CLIENT 1 +#define UDP_SERVER 2 +#define UDP_CLIENT 3 + +#define Mode1 0x10 //Port 1: Setup Mode 0x00:TCP Server 0x01:TCP Client 0x02:UDP Server 0x03:UDP Client +#define LOCAL_IP 0x11 //Local IP +#define SUBNET_MASK 0x12 //Subnet Mask +#define GATEWAY 0x13 //Gateway +#define LOCAL_PORT1 0X14 //Port 1:Local Port +#define TARGET_IP1 0x15 //Port 1:Target IP +#define TARGET_PORT1 0x16 //Port 1:Target Port +#define PORT_RANDOM_ENABLE1 0x17 //Port 1:Port Random Enable +#define UART1_BAUD1 0x21 //Port 1:Baud rate of serial port 1 + +void CH9120_init(void); +void RX_TX(); +void DEV_Delay_ms(UDOUBLE xms); +void DEV_Delay_us(UDOUBLE xus); + +#endif diff --git a/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/lib/CH9120/CMakeLists.txt b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/lib/CH9120/CMakeLists.txt new file mode 100644 index 0000000..c74cae9 --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/lib/CH9120/CMakeLists.txt @@ -0,0 +1,9 @@ +# 查找当前目录下的所有源文件 +# 并将名称保存到 DIR_CH9120_SRCS 变量 +aux_source_directory(. DIR_CH9120_SRCS) + +include_directories(../Config) + +# 生成链接库 +add_library(CH9120 ${DIR_CH9120_SRCS}) +target_link_libraries( CH9120 PUBLIC pico_stdlib hardware_spi) \ No newline at end of file diff --git a/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/main.c b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/main.c new file mode 100644 index 0000000..58e9d64 --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/main.c @@ -0,0 +1,6 @@ +#include "CH9120_Test.h" + +int main() +{ + Pico_ETH_CH9120_test(); +} diff --git a/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/pico_sdk_import.cmake b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/pico_sdk_import.cmake new file mode 100644 index 0000000..dacfc00 --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/pico_sdk_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the PICO SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + ) + if (NOT pico_sdk) + message("Downloading PICO SDK") + FetchContent_Populate(pico_sdk) + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "PICO SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git. \r\nexport PICO_SDK_PATH=../../pico-sdk" + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the PICO SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the PICO SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE}) diff --git a/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/uf2/RP2040-ETH-Test.uf2 b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/uf2/RP2040-ETH-Test.uf2 new file mode 100644 index 0000000..63d533c Binary files /dev/null and b/Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/uf2/RP2040-ETH-Test.uf2 differ diff --git a/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-Demo/RP2040-ETH-Demo.py b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-Demo/RP2040-ETH-Demo.py new file mode 100644 index 0000000..3b27c7b --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-Demo/RP2040-ETH-Demo.py @@ -0,0 +1,45 @@ +from machine import UART, Pin +from mqtt_client import MQTTClient +from ch9120 import CH9120 +import time + +# CH9120 +MODE = 1 #0:TCP Server 1:TCP Client 2:UDP Server 3:UDP Client +GATEWAY = (192, 168, 1, 1) # GATEWAY +TARGET_IP = (192, 168, 1, 10) # TARGET_IP +LOCAL_IP = (192, 168, 1, 200) # LOCAL_IP +SUBNET_MASK = (255,255,255,0) # SUBNET_MASK +LOCAL_PORT1 = 1000 # LOCAL_PORT1 +TARGET_PORT = 2000 # TARGET_PORT +BAUD_RATE = 115200 # BAUD_RATE + +uart1 = UART(1, baudrate=9600, tx=Pin(20), rx=Pin(21)) + +def ch9120_configure(): + # Configure + global uart1 + ch9120 = CH9120(uart1) + ch9120.enter_config() # enter configuration mode + ch9120.set_mode(MODE) # 0:TCP Server 1:TCP Client 2:UDP Server 3:UDP Client + ch9120.set_localIP(LOCAL_IP) + ch9120.set_subnetMask(SUBNET_MASK) + ch9120.set_gateway(GATEWAY) + ch9120.set_localPort(LOCAL_PORT1) + ch9120.set_targetIP(TARGET_IP) + ch9120.set_targetPort(TARGET_PORT) + ch9120.set_baudRate(BAUD_RATE) + ch9120.exit_config() # exit configuration mode + + # Clear cache and reconfigure uart1 + uart1.read(uart1.any()) + time.sleep(0.5) + uart1 = UART(1, baudrate=115200, tx=Pin(20), rx=Pin(21)) + +if __name__ == "__main__": + ch9120_configure() + while True: + time.sleep(0.1) + while uart1.any() > 0: + rxData1 = uart1.read(uart1.any()) + uart1.write(rxData1) + print(rxData1.decode('utf8')) diff --git a/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-Demo/ch9120.py b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-Demo/ch9120.py new file mode 100644 index 0000000..c1046ab --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-Demo/ch9120.py @@ -0,0 +1,74 @@ +from machine import UART, Pin +import time + +class CH9120: + def __init__(self, uart): + self.uart = uart + self.MODE = 1 #0:TCP Server 1:TCP Client 2:UDP Server 3:UDP Client + self.GATEWAY = (192, 168, 11, 1) # GATEWAY + self.TARGET_IP = (47, 92, 129, 18) # TARGET_IP + self.LOCAL_IP = (192, 168, 10, 200) # LOCAL_IP + self.SUBNET_MASK = (255,255,252,0) # SUBNET_MASK + self.LOCAL_PORT = 1000 # LOCAL_PORT1 + self.TARGET_PORT = 1883 # TARGET_PORT + self.BAUD_RATE = 115200 # BAUD_RATE + self.CFG = Pin(18, Pin.OUT,Pin.PULL_UP) + self.RST = Pin(19, Pin.OUT,Pin.PULL_UP) + + def enter_config(self): + print("begin") + self.RST.value(1) + self.CFG.value(0) + time.sleep(0.5) + + def exit_config(self): + self.uart.write(b'\x57\xab\x0D') + time.sleep(0.1) + self.uart.write(b'\x57\xab\x0E') + time.sleep(0.1) + self.uart.write(b'\x57\xab\x5E') + time.sleep(0.1) + self.CFG.value(1) + time.sleep(0.1) + print("end") + + def set_mode(self,MODE): + self.MODE = MODE + self.uart.write(b'\x57\xab\x10' + self.MODE.to_bytes(1, 'little'))#Convert int to bytes + time.sleep(0.1) + + def set_localIP(self,LOCAL_IP): + self.LOCAL_IP = LOCAL_IP + self.uart.write(b'\x57\xab\x11' + bytes(self.LOCAL_IP))#Converts the int tuple to bytes + time.sleep(0.1) + + def set_subnetMask(self,SUBNET_MASK): + self.SUBNET_MASK = SUBNET_MASK + self.uart.write(b'\x57\xab\x12' + bytes(self.SUBNET_MASK)) + time.sleep(0.1) + + def set_gateway(self,GATEWAY): + self.GATEWAY = GATEWAY + self.uart.write(b'\x57\xab\x13' + bytes(self.GATEWAY)) + time.sleep(0.1) + + def set_localPort(self,LOCAL_PORT): + self.LOCAL_PORT = LOCAL_PORT + self.uart.write(b'\x57\xab\x14' + self.LOCAL_PORT.to_bytes(2, 'little')) + time.sleep(0.1) + + def set_targetIP(self,TARGET_IP): + self.TARGET_IP = TARGET_IP + self.uart.write(b'\x57\xab\x15' + bytes(self.TARGET_IP)) + time.sleep(0.1) + + def set_targetPort(self,TARGET_PORT): + self.TARGET_PORT = TARGET_PORT + self.uart.write(b'\x57\xab\x16' + self.TARGET_PORT.to_bytes(2, 'little')) + time.sleep(0.1) + + def set_baudRate(self,BAUD_RATE): + self.BAUD_RATE = BAUD_RATE + self.uart.write(b'\x57\xab\x21' + self.BAUD_RATE.to_bytes(4, 'little')) + time.sleep(0.1) + diff --git a/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-Demo/rp2-pico-20230209-unstable-v1.19.1.uf2 b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-Demo/rp2-pico-20230209-unstable-v1.19.1.uf2 new file mode 100644 index 0000000..fe9d0b6 Binary files /dev/null and b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-Demo/rp2-pico-20230209-unstable-v1.19.1.uf2 differ diff --git a/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/RP2040-ETH-MQTT.py b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/RP2040-ETH-MQTT.py new file mode 100644 index 0000000..ffba3ea --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/RP2040-ETH-MQTT.py @@ -0,0 +1,86 @@ +from machine import UART, Pin +from mqtt_client import MQTTClient +from ch9120 import CH9120 +import time + +# MQTT +CLIENT_ID = "Waveshare_RP2040_ETH" +SUBSCRIBE_TOPIC = "test_topic1" +PUBLISH_TOPIC = "test_topic2" + +# CH9120 +MODE = 1 #0:TCP Server 1:TCP Client 2:UDP Server 3:UDP Client +GATEWAY = (192, 168, 1, 1) # GATEWAY +TARGET_IP = (47, 92, 129, 18) # TARGET_IP +LOCAL_IP = (192, 168, 1, 200) # LOCAL_IP +SUBNET_MASK = (255,255,255,0) # SUBNET_MASK +LOCAL_PORT1 = 1000 # LOCAL_PORT1 +TARGET_PORT = 1883 # TARGET_PORT +BAUD_RATE = 115200 # BAUD_RATE + +uart1 = UART(1, baudrate=9600, tx=Pin(20), rx=Pin(21)) + +def ch9120_configure(): + global uart1 + ch9120 = CH9120(uart1) + ch9120.enter_config() # enter configuration mode + ch9120.set_mode(MODE) + ch9120.set_localIP(LOCAL_IP) + ch9120.set_subnetMask(SUBNET_MASK) + ch9120.set_gateway(GATEWAY) + ch9120.set_localPort(LOCAL_PORT1) + ch9120.set_targetIP(TARGET_IP) + ch9120.set_targetPort(TARGET_PORT) + ch9120.set_baudRate(BAUD_RATE) + ch9120.exit_config() # exit configuration mode + + # Clear cache and reconfigure uart1 + uart1.read(uart1.any()) + time.sleep(0.5) + uart1 = UART(1, baudrate=115200, tx=Pin(20), rx=Pin(21)) + +if __name__ == "__main__": + ch9120_configure() + mqtt_client = MQTTClient(uart1) + mqtt_client.ClientID = CLIENT_ID # Set ClientID + mqtt_client.connect() # Connect to MQTT server + mqtt_client.subscribe(SUBSCRIBE_TOPIC) # Subscribe to topic:test_topic1 + + mqtt_client.send_heartbeat() + last_heartbeat_time = time.time() + time.sleep_ms(60) # Sending the first heartbeat + uart1.read() # Clear unnecessary data + + while True: + rxData = uart1.read() + if rxData is not None: + topic, message = mqtt_client.extract_data(rxData) # Parse the received data + if topic == SUBSCRIBE_TOPIC: + print("Topic:", topic) + print("Message:", message) + mqtt_client.publish(PUBLISH_TOPIC, message) # Send received data to topic:test_topic2 + + current_time = time.time() + if current_time - last_heartbeat_time >= 30: + mqtt_client.send_heartbeat() # Send a heartbeat every 30 seconds + last_heartbeat_time = current_time + time.sleep_ms(60) # Waiting for the server to respond + if not mqtt_client.check_heartbeat_response(): + while True: + print("Reconnecting...") + mqtt_client = MQTTClient(uart1) + mqtt_client.ClientID = CLIENT_ID # Set ClientID + mqtt_client.connect() # Connect to MQTT server + mqtt_client.subscribe(SUBSCRIBE_TOPIC) # Subscribe to topic:test_topic1 + time.sleep_ms(200) # Waiting for the server to respond + uart1.read() # Clear unnecessary data + mqtt_client.send_heartbeat() # Sending the first heartbeat + last_heartbeat_time = current_time # Clear unnecessary data + time.sleep_ms(60) # Waiting for the server to respond + if mqtt_client.check_heartbeat_response(): + print("Reconnection successful!") + break + + time.sleep_ms(20) + + \ No newline at end of file diff --git a/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/ch9120.py b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/ch9120.py new file mode 100644 index 0000000..c1046ab --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/ch9120.py @@ -0,0 +1,74 @@ +from machine import UART, Pin +import time + +class CH9120: + def __init__(self, uart): + self.uart = uart + self.MODE = 1 #0:TCP Server 1:TCP Client 2:UDP Server 3:UDP Client + self.GATEWAY = (192, 168, 11, 1) # GATEWAY + self.TARGET_IP = (47, 92, 129, 18) # TARGET_IP + self.LOCAL_IP = (192, 168, 10, 200) # LOCAL_IP + self.SUBNET_MASK = (255,255,252,0) # SUBNET_MASK + self.LOCAL_PORT = 1000 # LOCAL_PORT1 + self.TARGET_PORT = 1883 # TARGET_PORT + self.BAUD_RATE = 115200 # BAUD_RATE + self.CFG = Pin(18, Pin.OUT,Pin.PULL_UP) + self.RST = Pin(19, Pin.OUT,Pin.PULL_UP) + + def enter_config(self): + print("begin") + self.RST.value(1) + self.CFG.value(0) + time.sleep(0.5) + + def exit_config(self): + self.uart.write(b'\x57\xab\x0D') + time.sleep(0.1) + self.uart.write(b'\x57\xab\x0E') + time.sleep(0.1) + self.uart.write(b'\x57\xab\x5E') + time.sleep(0.1) + self.CFG.value(1) + time.sleep(0.1) + print("end") + + def set_mode(self,MODE): + self.MODE = MODE + self.uart.write(b'\x57\xab\x10' + self.MODE.to_bytes(1, 'little'))#Convert int to bytes + time.sleep(0.1) + + def set_localIP(self,LOCAL_IP): + self.LOCAL_IP = LOCAL_IP + self.uart.write(b'\x57\xab\x11' + bytes(self.LOCAL_IP))#Converts the int tuple to bytes + time.sleep(0.1) + + def set_subnetMask(self,SUBNET_MASK): + self.SUBNET_MASK = SUBNET_MASK + self.uart.write(b'\x57\xab\x12' + bytes(self.SUBNET_MASK)) + time.sleep(0.1) + + def set_gateway(self,GATEWAY): + self.GATEWAY = GATEWAY + self.uart.write(b'\x57\xab\x13' + bytes(self.GATEWAY)) + time.sleep(0.1) + + def set_localPort(self,LOCAL_PORT): + self.LOCAL_PORT = LOCAL_PORT + self.uart.write(b'\x57\xab\x14' + self.LOCAL_PORT.to_bytes(2, 'little')) + time.sleep(0.1) + + def set_targetIP(self,TARGET_IP): + self.TARGET_IP = TARGET_IP + self.uart.write(b'\x57\xab\x15' + bytes(self.TARGET_IP)) + time.sleep(0.1) + + def set_targetPort(self,TARGET_PORT): + self.TARGET_PORT = TARGET_PORT + self.uart.write(b'\x57\xab\x16' + self.TARGET_PORT.to_bytes(2, 'little')) + time.sleep(0.1) + + def set_baudRate(self,BAUD_RATE): + self.BAUD_RATE = BAUD_RATE + self.uart.write(b'\x57\xab\x21' + self.BAUD_RATE.to_bytes(4, 'little')) + time.sleep(0.1) + diff --git a/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/mqtt_client.py b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/mqtt_client.py new file mode 100644 index 0000000..dd3ba0f --- /dev/null +++ b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/mqtt_client.py @@ -0,0 +1,68 @@ +from machine import UART +import time +import ubinascii + +class MQTTClient: + def __init__(self, uart): + self.uart = uart + self.ClientID = "Waveshare_RP2040_ETH" + self.connect_message = bytearray([ + 0x10, # MQTT control packet type (CONNECT) + 0x11, # Remaining Length in the fixed header + 0x00, 0x04, # Length of the UTF-8 encoded protocol name + 0x4D, 0x51, 0x54, 0x54, # MQTT string "MQTT" + 0x04, # Protocol Level (MQTT 3.1.1) + 0x02, # Connect Flags: Clean Session, No Will, No Will Retain, QoS = 0, No Will Flag, Keep Alive = 60 seconds + 0x00, 0x3C # Keep Alive Time in seconds + ]) + + def connect(self): + byte_array = bytes(self.ClientID, "utf-8") + length = len(byte_array) + self.connect_message.extend(length.to_bytes(2, 'big')) # Length of the Client ID + self.connect_message.extend(byte_array) # Client ID + self.connect_message[1] = len(self.connect_message) - 2 # Change Length + self.uart.write(bytes(self.connect_message)) + + def publish(self, topic, message): + publish_message = bytearray([ + 0x30, 0x11, # MQTT control packet type (PUBLISH) + 0x00, 0x0A # Length of the topic name + ]) + publish_message.extend(bytes(topic, "utf-8")) # Topic + publish_message.extend(bytes(message, "utf-8")) # Message content + publish_message[1] = len(publish_message) - 2 # Change Length + publish_message[3] = len(bytes(topic, "utf-8")) # Change Length + self.uart.write(bytes(publish_message)) + + def subscribe(self, topic): + subscribe_message = bytearray([ + 0x82, 0x0A, # MQTT control packet type (SUBSCRIBE) + 0x00, 0x01 # Remaining length + ]) + byte_array = bytes(topic, "utf-8") + length = len(byte_array) + subscribe_message.extend(length.to_bytes(2, 'big')) # Length of the topic name + subscribe_message.extend(byte_array) # Topic + subscribe_message.extend(bytes([0x00])) # qos + subscribe_message[1] = len(subscribe_message) - 2 # Change Length + self.uart.write(bytes(subscribe_message)) + + def send_heartbeat(self): + heartbeat_message = bytearray([0xC0, 0x00])# Heartbeat message to keep the connection alive + self.uart.write(heartbeat_message) + + def check_heartbeat_response(self): + response = self.uart.read()# Check for PINGRESP message + if response == bytes([0xD0, 0x00]): + return True + else: + return False + + def extract_data(self, rxData): + rxArray = bytearray() + rxArray.extend(rxData) + topic = rxArray[4:4 + rxArray[3]].decode('utf-8') + message = rxArray[4 + rxArray[3]:rxArray[1] + 2].decode('utf-8') + return topic, message + diff --git a/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/rp2-pico-20230209-unstable-v1.19.1.uf2 b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/rp2-pico-20230209-unstable-v1.19.1.uf2 new file mode 100644 index 0000000..fe9d0b6 Binary files /dev/null and b/Refernce Code/RP2040_ETH_CODE/Python/RP2040-ETH-MQTT/rp2-pico-20230209-unstable-v1.19.1.uf2 differ diff --git a/barnum-initial.c b/barnum-initial.c new file mode 100644 index 0000000..90d129e --- /dev/null +++ b/barnum-initial.c @@ -0,0 +1,51 @@ +#include +#include + +#include "pico/stdlib.h" +#include "hardware/pio.h" +#include "hardware/clocks.h" +#include "ws2812.pio.h" + +void put_pixel(uint32_t pixel_grb) +{ + pio_sm_put_blocking(pio0, 0, pixel_grb << 8u); +} +void put_rgb(uint8_t red, uint8_t green, uint8_t blue) +{ + uint32_t mask = (green << 16) | (red << 8) | (blue << 0); + put_pixel(mask); +} + +int main() +{ + //set_sys_clock_48(); + stdio_init_all(); + + PIO pio = pio0; + int sm = 0; + uint offset = pio_add_program(pio, &ws2812_program); + uint8_t cnt = 0; + + puts("RP2040-Zero WS2812 Test"); + + ws2812_program_init(pio, sm, offset, 25, 800000, true); + + while (1) + { + for (cnt = 0; cnt < 0xff; cnt++) + { + put_rgb(cnt, 0xff - cnt, 0); + sleep_ms(3); + } + for (cnt = 0; cnt < 0xff; cnt++) + { + put_rgb(0xff - cnt, 0, cnt); + sleep_ms(3); + } + for (cnt = 0; cnt < 0xff; cnt++) + { + put_rgb(0, cnt, 0xff - cnt); + sleep_ms(3); + } + } +} \ No newline at end of file diff --git a/barnum.c b/barnum.c new file mode 100644 index 0000000..9c7d527 --- /dev/null +++ b/barnum.c @@ -0,0 +1,163 @@ +#include +#include +#include + +#include "pico/stdlib.h" +#include "hardware/pio.h" +#include "hardware/clocks.h" +#include "ws2812.pio.h" +#include "ch9120.h" + +#define WS2812_PIN 25 +#define LED_FREQ 800000 + +void put_pixel(uint32_t pixel_grb) { + pio_sm_put_blocking(pio0, 0, pixel_grb << 8u); +} + +void put_rgb(uint8_t red, uint8_t green, uint8_t blue) { + uint32_t mask = (green << 16) | (red << 8) | (blue << 0); + put_pixel(mask); +} + +void parse_color_command(const char *cmd, uint8_t *r, uint8_t *g, uint8_t *b) { + if (strncmp(cmd, "RGB:", 4) == 0) { + sscanf(cmd + 4, "%hhu,%hhu,%hhu", r, g, b); + } else if (strcmp(cmd, "RED") == 0) { + *r = 255; *g = 0; *b = 0; + } else if (strcmp(cmd, "GREEN") == 0) { + *r = 0; *g = 255; *b = 0; + } else if (strcmp(cmd, "BLUE") == 0) { + *r = 0; *g = 0; *b = 255; + } else if (strcmp(cmd, "WHITE") == 0) { + *r = 255; *g = 255; *b = 255; + } else if (strcmp(cmd, "OFF") == 0) { + *r = 0; *g = 0; *b = 0; + } +} + +int main() { + stdio_init_all(); + + printf("RP2040-ETH WS2812 Network Control\n"); + + // Initialize WS2812 LED + PIO pio = pio0; + int sm = 0; + uint offset = pio_add_program(pio, &ws2812_program); + ws2812_program_init(pio, sm, offset, WS2812_PIN, LED_FREQ, true); + + // Initialize CH9120 Ethernet + CH9120_init(); + printf("Ethernet initialized\n"); + printf("IP: 192.168.1.201\n"); + printf("Port: 1000\n"); + printf("Mode: TCP Server\n"); + printf("Send color commands: RED, GREEN, BLUE, WHITE, OFF, or RGB:r,g,b\n"); + + // Flash LED to indicate startup + for (int i = 0; i < 3; i++) { + put_rgb(0, 0, 255); // Blue flash + sleep_ms(200); + put_rgb(0, 0, 0); // Off + sleep_ms(200); + } + + // Current LED state + uint8_t current_r = 0, current_g = 0, current_b = 0; + uint8_t target_r = 0, target_g = 0, target_b = 0; + bool color_changing = false; + + char rx_buffer[256]; + uint32_t last_heartbeat = 0; + uint32_t last_blink = 0; + bool show_blink = false; + + while (1) { + // Check for network data + int received = CH9120_receive_data(rx_buffer, sizeof(rx_buffer) - 1); + if (received > 0) { + rx_buffer[received] = '\0'; + + // Flash amber to indicate traffic + put_rgb(255, 191, 0); // Amber + sleep_ms(50); + + // Parse color command + uint8_t new_r, new_g, new_b; + parse_color_command(rx_buffer, &new_r, &new_g, &new_b); + + // Set new target color + target_r = new_r; + target_g = new_g; + target_b = new_b; + color_changing = true; + + // Send acknowledgment + char ack[64]; + snprintf(ack, sizeof(ack), "Setting color to R:%d G:%d B:%d\n", new_r, new_g, new_b); + CH9120_send_data(ack, strlen(ack)); + + // Flash amber again for outgoing traffic + put_rgb(255, 191, 0); // Amber + sleep_ms(50); + + printf("Received command: %s\n", rx_buffer); + } + + // Smooth color transition + if (color_changing) { + bool done = true; + + if (current_r != target_r) { + current_r += (current_r < target_r) ? 1 : -1; + done = false; + } + if (current_g != target_g) { + current_g += (current_g < target_g) ? 1 : -1; + done = false; + } + if (current_b != target_b) { + current_b += (current_b < target_b) ? 1 : -1; + done = false; + } + + put_rgb(current_r, current_g, current_b); + + if (done) { + color_changing = false; + } + + sleep_ms(3); + } else { + // Keep current color + put_rgb(current_r, current_g, current_b); + sleep_ms(10); + } + + // Periodic green flash to show firmware is running (regardless of state) + uint32_t now = to_ms_since_boot(get_absolute_time()); + + // Check if it's time to blink (every 1 second) + if (now - last_blink >= 1000) { + show_blink = true; + last_blink = now; + } + + // Show green flash for 100ms + if (show_blink && (now - last_blink < 100)) { + put_rgb(0, 128, 0); // 50% green + } + + // Clear blink flag after 100ms + if (now - last_blink >= 100) { + show_blink = false; + } + + // Heartbeat log every 5 seconds + if (now - last_heartbeat > 5000) { + printf("Ethernet heartbeat - waiting for commands...\n"); + last_heartbeat = now; + } + } +} \ No newline at end of file diff --git a/barnumbak.c b/barnumbak.c new file mode 100644 index 0000000..89db08b --- /dev/null +++ b/barnumbak.c @@ -0,0 +1,225 @@ +#include +#include "pico/stdlib.h" +#include "hardware/spi.h" +#include "hardware/i2c.h" +#include "hardware/dma.h" +#include "hardware/pio.h" +#include "hardware/interp.h" +#include "hardware/timer.h" +#include "hardware/watchdog.h" +#include "hardware/uart.h" + +// RP2040-ETH board CH9120 ethernet chip defines +#define CH9120_UART_ID uart0 +#define CH9120_RXD_PIN 21 // Serial data input to CH9120 +#define CH9120_TXD_PIN 20 // Serial data output from CH9120 +#define CH9120_TCPCS_PIN 17 // TCP client connection status +#define CH9120_CFG0_PIN 18 // Network configuration pin +#define CH9120_RSTI_PIN 19 // Reset pin (active LOW) + +// SPI Defines for RP2040-ETH +// Using available pins that don't conflict with CH9120 ethernet chip +// CH9120 uses pins 17-21, so we avoid those +#define SPI_PORT spi0 +#define PIN_MISO 0 +#define PIN_CS 1 +#define PIN_SCK 2 +#define PIN_MOSI 3 + +// I2C defines for RP2040-ETH +// Using I2C0 on available pins that don't conflict with CH9120 +#define I2C_PORT i2c0 +#define I2C_SDA 4 +#define I2C_SCL 5 + +// Data will be copied from src to dst +const char src[] = "Hello, world! (from DMA)"; +char dst[count_of(src)]; + +#include "blink.pio.h" +#include "ws2812.pio.h" + +void blink_pin_forever(PIO pio, uint sm, uint offset, uint pin, uint freq) { + blink_program_init(pio, sm, offset, pin); + pio_sm_set_enabled(pio, sm, true); + + printf("Blinking pin %d at %d Hz\n", pin, freq); + + // PIO counter program takes 3 more cycles in total than we pass as + // input (wait for n + 1; mov; jmp) + pio->txf[sm] = (125000000 / (2 * freq)) - 3; +} + +void put_pixel(uint32_t pixel_grb) { + pio_sm_put_blocking(pio0, 0, pixel_grb << 8u); // Use state machine 0 +} + +void put_rgb(uint8_t red, uint8_t green, uint8_t blue) { + uint32_t mask = (green << 16) | (red << 8) | (blue << 0); + put_pixel(mask); +} + + +int64_t alarm_callback(alarm_id_t id, void *user_data) { + // Put your timeout handler code in here + return 0; +} + + +// UART defines for RP2040-ETH +// By default the stdout UART is `uart0`, so we will use the second one +// Note: CH9120 ethernet chip uses UART0 on pins 20-21 +#define UART_ID uart1 +#define BAUD_RATE 115200 + +// Use pins 8 and 9 for UART1 (avoiding CH9120 pins) +#define UART_TX_PIN 8 +#define UART_RX_PIN 9 + + + +int main() +{ + stdio_init_all(); + + // SPI initialisation. This example will use SPI at 1MHz. + spi_init(SPI_PORT, 1000*1000); + gpio_set_function(PIN_MISO, GPIO_FUNC_SPI); + gpio_set_function(PIN_CS, GPIO_FUNC_SIO); + gpio_set_function(PIN_SCK, GPIO_FUNC_SPI); + gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI); + + // Chip select is active-low, so we'll initialise it to a driven-high state + gpio_set_dir(PIN_CS, GPIO_OUT); + gpio_put(PIN_CS, 1); + // For more examples of SPI use see https://github.com/raspberrypi/pico-examples/tree/master/spi + + // I2C Initialisation. Using it at 400Khz. + i2c_init(I2C_PORT, 400*1000); + + gpio_set_function(I2C_SDA, GPIO_FUNC_I2C); + gpio_set_function(I2C_SCL, GPIO_FUNC_I2C); + gpio_pull_up(I2C_SDA); + gpio_pull_up(I2C_SCL); + // For more examples of I2C use see https://github.com/raspberrypi/pico-examples/tree/master/i2c + + // Get a free channel, panic() if there are none + int chan = dma_claim_unused_channel(true); + + // 8 bit transfers. Both read and write address increment after each + // transfer (each pointing to a location in src or dst respectively). + // No DREQ is selected, so the DMA transfers as fast as it can. + + dma_channel_config c = dma_channel_get_default_config(chan); + channel_config_set_transfer_data_size(&c, DMA_SIZE_8); + channel_config_set_read_increment(&c, true); + channel_config_set_write_increment(&c, true); + + dma_channel_configure( + chan, // Channel to be configured + &c, // The configuration we just created + dst, // The initial write address + src, // The initial read address + count_of(src), // Number of transfers; in this case each is 1 byte. + true // Start immediately. + ); + + // We could choose to go and do something else whilst the DMA is doing its + // thing. In this case the processor has nothing else to do, so we just + // wait for the DMA to finish. + dma_channel_wait_for_finish_blocking(chan); + + // The DMA has now copied our text from the transmit buffer (src) to the + // receive buffer (dst), so we can print it out from there. + puts(dst); + + // PIO Blinking example + PIO pio = pio0; + uint offset = pio_add_program(pio, &blink_program); + printf("Loaded blink program at %d\n", offset); + + // WS2812B RGB LED on pin 25 (RP2040-ETH board) + uint ws2812_offset = pio_add_program(pio, &ws2812_program); + printf("Loaded WS2812B program at %d\n", ws2812_offset); + ws2812_program_init(pio, 0, ws2812_offset, 25, 800000, false); // Use state machine 0 + printf("WS2812B RGB LED initialized on pin 25\n"); + // For more pio examples see https://github.com/raspberrypi/pico-examples/tree/master/pio + + // Interpolator example code + interp_config cfg = interp_default_config(); + // Now use the various interpolator library functions for your use case + // e.g. interp_config_clamp(&cfg, true); + // interp_config_shift(&cfg, 2); + // Then set the config + interp_set_config(interp0, 0, &cfg); + // For examples of interpolator use see https://github.com/raspberrypi/pico-examples/tree/master/interp + + // Timer example code - This example fires off the callback after 2000ms + add_alarm_in_ms(2000, alarm_callback, NULL, false); + // For more examples of timer use see https://github.com/raspberrypi/pico-examples/tree/master/timer + + // Watchdog example code + if (watchdog_caused_reboot()) { + printf("Rebooted by Watchdog!\n"); + // Whatever action you may take if a watchdog caused a reboot + } + + // Enable the watchdog, requiring the watchdog to be updated every 100ms or the chip will reboot + // second arg is pause on debug which means the watchdog will pause when stepping through code + watchdog_enable(100, 1); + + // You need to call this function at least more often than the 100ms in the enable call to prevent a reboot + watchdog_update(); + + // Set up our UART + uart_init(UART_ID, BAUD_RATE); + // Set the TX and RX pins by using the function select on the GPIO + // Set datasheet for more information on function select + gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART); + gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART); + + // Use some the various UART functions to send out data + // In a default system, printf will also output via the default UART + + // Send out a string, with CR/LF conversions + uart_puts(UART_ID, " Hello, UART!\n"); + + // For more examples of UART use see https://github.com/raspberrypi/pico-examples/tree/master/uart + + // Initialize CH9120 ethernet chip + uart_init(CH9120_UART_ID, 115200); + gpio_set_function(CH9120_TXD_PIN, GPIO_FUNC_UART); + gpio_set_function(CH9120_RXD_PIN, GPIO_FUNC_UART); + + // Configure CH9120 control pins + gpio_init(CH9120_TCPCS_PIN); + gpio_set_dir(CH9120_TCPCS_PIN, GPIO_IN); + + gpio_init(CH9120_CFG0_PIN); + gpio_set_dir(CH9120_CFG0_PIN, GPIO_OUT); + gpio_put(CH9120_CFG0_PIN, 0); // Normal operation mode + + gpio_init(CH9120_RSTI_PIN); + gpio_set_dir(CH9120_RSTI_PIN, GPIO_OUT); + gpio_put(CH9120_RSTI_PIN, 1); // Release reset (active LOW) + + printf("CH9120 ethernet chip initialized\\n"); + + uint8_t state = 0; + while (true) { + printf("Hello, world!\n"); + + // Simple color cycling - solid colors + switch(state % 6) { + case 0: put_rgb(255, 0, 0); break; // Red + case 1: put_rgb(255, 128, 0); break; // Orange + case 2: put_rgb(255, 255, 0); break; // Yellow + case 3: put_rgb(0, 255, 0); break; // Green + case 4: put_rgb(0, 0, 255); break; // Blue + case 5: put_rgb(128, 0, 255); break; // Purple + } + + state++; + sleep_ms(1000); + } +} diff --git a/blink.pio b/blink.pio new file mode 100644 index 0000000..b174819 --- /dev/null +++ b/blink.pio @@ -0,0 +1,34 @@ +; +; Copyright (c) 2020 Raspberry Pi (Trading) Ltd. +; +; SPDX-License-Identifier: BSD-3-Clause +; + +; SET pin 0 should be mapped to your LED GPIO + +.program blink + pull block + out y, 32 +.wrap_target + mov x, y + set pins, 1 ; Turn LED on +lp1: + jmp x-- lp1 ; Delay for (x + 1) cycles, x is a 32 bit number + mov x, y + set pins, 0 ; Turn LED off +lp2: + jmp x-- lp2 ; Delay for the same number of cycles again +.wrap ; Blink forever! + + +% c-sdk { +// this is a raw helper function for use by the user which sets up the GPIO output, and configures the SM to output on a particular pin + +void blink_program_init(PIO pio, uint sm, uint offset, uint pin) { + pio_gpio_init(pio, pin); + pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); + pio_sm_config c = blink_program_get_default_config(offset); + sm_config_set_set_pins(&c, pin, 1); + pio_sm_init(pio, sm, offset, &c); +} +%} \ No newline at end of file diff --git a/ch9120.c b/ch9120.c new file mode 100644 index 0000000..5946104 --- /dev/null +++ b/ch9120.c @@ -0,0 +1,181 @@ +#include "ch9120.h" + +static uint8_t CH9120_Mode = TCP_SERVER; +static uint8_t CH9120_LOCAL_IP[4] = {192, 168, 1, 201}; +static uint8_t CH9120_GATEWAY[4] = {192, 168, 1, 1}; +static uint8_t CH9120_SUBNET_MASK[4] = {255, 255, 0, 0}; +static uint8_t CH9120_TARGET_IP[4] = {192, 168, 1, 10}; +static uint16_t CH9120_PORT1 = 1000; +static uint16_t CH9120_TARGET_PORT = 2000; +static uint32_t CH9120_BAUD_RATE = 115200; + +static uint8_t tx[8] = {0x57, 0xAB}; + +static void CH9120_TX_4_bytes(uint8_t data, int command) { + for (int i = 2; i < 4; i++) { + if (i == 2) + tx[i] = command; + else + tx[i] = data; + } + sleep_ms(10); + for (int o = 0; o < 4; o++) + uart_putc(UART_ID1, tx[o]); + sleep_ms(10); + for (int i = 2; i < 4; i++) + tx[i] = 0; +} + +static void CH9120_TX_5_bytes(uint16_t data, int command) { + uint8_t Port[2]; + Port[0] = data & 0xff; + Port[1] = data >> 8; + for (int i = 2; i < 5; i++) { + if (i == 2) + tx[i] = command; + else + tx[i] = Port[i - 3]; + } + sleep_ms(10); + for (int o = 0; o < 5; o++) + uart_putc(UART_ID1, tx[o]); + sleep_ms(10); + for (int i = 2; i < 5; i++) + tx[i] = 0; +} + +static void CH9120_TX_7_bytes(uint8_t data[], int command) { + for (int i = 2; i < 7; i++) { + if (i == 2) + tx[i] = command; + else + tx[i] = data[i - 3]; + } + sleep_ms(10); + for (int o = 0; o < 7; o++) + uart_putc(UART_ID1, tx[o]); + sleep_ms(10); + for (int i = 2; i < 7; i++) + tx[i] = 0; +} + +static void CH9120_TX_BAUD(uint32_t data, int command) { + uint8_t Port[4]; + Port[0] = (data & 0xff); + Port[1] = (data >> 8) & 0xff; + Port[2] = (data >> 16) & 0xff; + Port[3] = data >> 24; + + for (int i = 2; i < 7; i++) { + if (i == 2) + tx[i] = command; + else + tx[i] = Port[i - 3]; + } + sleep_ms(10); + for (int o = 0; o < 7; o++) + uart_putc(UART_ID1, tx[o]); + sleep_ms(10); + for (int i = 2; i < 7; i++) + tx[i] = 0; +} + +static void CH9120_Start() { + // Hard reset the CH9120 + gpio_put(RES_PIN, 0); + sleep_ms(100); + gpio_put(RES_PIN, 1); + sleep_ms(100); + + // Enter configuration mode + gpio_put(CFG_PIN, 0); + sleep_ms(500); +} + +static void CH9120_End() { + tx[2] = 0x0d; + uart_write_blocking(UART_ID1, tx, 3); + sleep_ms(200); + tx[2] = 0x0e; + uart_write_blocking(UART_ID1, tx, 3); + sleep_ms(200); + tx[2] = 0x5e; + uart_write_blocking(UART_ID1, tx, 3); + sleep_ms(200); + gpio_put(CFG_PIN, 1); +} + +void CH9120_init(void) { + uart_init(UART_ID1, INIT_BAUD_RATE); + gpio_set_function(UART_TX_PIN1, GPIO_FUNC_UART); + gpio_set_function(UART_RX_PIN1, GPIO_FUNC_UART); + + gpio_init(CFG_PIN); + gpio_init(RES_PIN); + gpio_set_dir(CFG_PIN, GPIO_OUT); + gpio_set_dir(RES_PIN, GPIO_OUT); + + printf("CH9120 Configuration:\n"); + printf("Mode: %s\n", (CH9120_Mode == TCP_SERVER) ? "TCP_SERVER" : "TCP_CLIENT"); + printf("Local IP: %d.%d.%d.%d\n", CH9120_LOCAL_IP[0], CH9120_LOCAL_IP[1], CH9120_LOCAL_IP[2], CH9120_LOCAL_IP[3]); + printf("Gateway: %d.%d.%d.%d\n", CH9120_GATEWAY[0], CH9120_GATEWAY[1], CH9120_GATEWAY[2], CH9120_GATEWAY[3]); + printf("Subnet: %d.%d.%d.%d\n", CH9120_SUBNET_MASK[0], CH9120_SUBNET_MASK[1], CH9120_SUBNET_MASK[2], CH9120_SUBNET_MASK[3]); + printf("Local Port: %d\n", CH9120_PORT1); + + printf("Starting CH9120 configuration...\n"); + CH9120_Start(); + printf("Setting mode...\n"); + CH9120_TX_4_bytes(CH9120_Mode, Mode1); + printf("Setting local IP...\n"); + CH9120_TX_7_bytes(CH9120_LOCAL_IP, LOCAL_IP); + printf("Setting subnet mask...\n"); + CH9120_TX_7_bytes(CH9120_SUBNET_MASK, SUBNET_MASK); + printf("Setting gateway...\n"); + CH9120_TX_7_bytes(CH9120_GATEWAY, GATEWAY); + printf("Setting target IP...\n"); + CH9120_TX_7_bytes(CH9120_TARGET_IP, TARGET_IP1); + printf("Setting local port...\n"); + CH9120_TX_5_bytes(CH9120_PORT1, LOCAL_PORT1); + printf("Setting target port...\n"); + CH9120_TX_5_bytes(CH9120_TARGET_PORT, TARGET_PORT1); + printf("Setting baud rate...\n"); + CH9120_TX_BAUD(CH9120_BAUD_RATE, UART1_BAUD1); + printf("Finalizing configuration...\n"); + CH9120_End(); + + uart_set_baudrate(UART_ID1, TRANSPORT_BAUD_RATE); + + while (uart_is_readable(UART_ID1)) { + uart_getc(UART_ID1); + } + + printf("CH9120 initialization complete\n"); +} + +void CH9120_send_data(const char *data, size_t len) { + for (size_t i = 0; i < len; i++) { + if (uart_is_writable(UART_ID1)) { + uart_putc(UART_ID1, data[i]); + } + } +} + +int CH9120_receive_data(char *buffer, size_t max_len) { + size_t count = 0; + while (uart_is_readable(UART_ID1) && count < max_len) { + buffer[count++] = uart_getc(UART_ID1); + } + return count; +} + +void CH9120_process(void) { + char buffer[256]; + int received = CH9120_receive_data(buffer, sizeof(buffer) - 1); + if (received > 0) { + buffer[received] = '\0'; + printf("Received: %s\n", buffer); + + CH9120_send_data("ACK: ", 5); + CH9120_send_data(buffer, received); + } +} \ No newline at end of file diff --git a/ch9120.h b/ch9120.h new file mode 100644 index 0000000..f44336d --- /dev/null +++ b/ch9120.h @@ -0,0 +1,42 @@ +#ifndef _CH9120_H_ +#define _CH9120_H_ + +#include +#include +#include "pico/stdlib.h" +#include "hardware/uart.h" +#include "hardware/irq.h" + +#define UART_ID1 uart1 +#define INIT_BAUD_RATE 9600 +#define TRANSPORT_BAUD_RATE 115200 +#define DATA_BITS 8 +#define STOP_BITS 1 +#define PARITY UART_PARITY_NONE + +#define UART_TX_PIN1 20 +#define UART_RX_PIN1 21 + +#define CFG_PIN 18 +#define RES_PIN 19 + +#define TCP_SERVER 0 +#define TCP_CLIENT 1 +#define UDP_SERVER 2 +#define UDP_CLIENT 3 + +#define Mode1 0x10 +#define LOCAL_IP 0x11 +#define SUBNET_MASK 0x12 +#define GATEWAY 0x13 +#define LOCAL_PORT1 0X14 +#define TARGET_IP1 0x15 +#define TARGET_PORT1 0x16 +#define UART1_BAUD1 0x21 + +void CH9120_init(void); +void CH9120_send_data(const char *data, size_t len); +int CH9120_receive_data(char *buffer, size_t max_len); +void CH9120_process(void); + +#endif \ No newline at end of file diff --git a/network_scan.py b/network_scan.py new file mode 100644 index 0000000..b895793 --- /dev/null +++ b/network_scan.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +""" +Scan the local network to see what devices are active +""" + +import subprocess +import sys +import ipaddress + +def scan_network(): + """Scan the 192.168.1.x network""" + print("Scanning 192.168.1.0/24 network...") + + # Use nmap if available, otherwise use ping + try: + result = subprocess.run(['nmap', '-sn', '192.168.1.0/24'], + capture_output=True, text=True, timeout=30) + if result.returncode == 0: + print("Active hosts (nmap):") + print(result.stdout) + else: + print("nmap failed, trying ping scan...") + ping_scan() + except FileNotFoundError: + print("nmap not found, using ping scan...") + ping_scan() + +def ping_scan(): + """Ping scan 192.168.1.1-254""" + active_hosts = [] + + for i in range(1, 255): + ip = f"192.168.1.{i}" + try: + result = subprocess.run(['ping', '-c', '1', '-W', '1000', ip], + capture_output=True, timeout=2) + if result.returncode == 0: + active_hosts.append(ip) + print(f"✓ {ip} is active") + except subprocess.TimeoutExpired: + pass + except Exception: + pass + + print(f"\nFound {len(active_hosts)} active hosts:") + for host in active_hosts: + print(f" {host}") + +def check_arp(): + """Check ARP table for RP2040-ETH""" + print("\nChecking ARP table for RP2040-ETH...") + try: + result = subprocess.run(['arp', '-a'], capture_output=True, text=True) + lines = result.stdout.split('\n') + rp2040_found = False + + for line in lines: + if '192.168.1.20' in line or '192.168.1.201' in line: + print(f"Found: {line}") + rp2040_found = True + + if not rp2040_found: + print("RP2040-ETH not found in ARP table") + + except Exception as e: + print(f"ARP check failed: {e}") + +if __name__ == "__main__": + scan_network() + check_arp() + + print("\nNext steps:") + print("1. Check if 192.168.1.201 appears in the scan") + print("2. Try: ping 192.168.1.201") + print("3. Monitor serial output from RP2040-ETH for debug info") + print("4. Check ethernet cable connection") \ No newline at end of file diff --git a/pico_sdk_import.cmake b/pico_sdk_import.cmake new file mode 100644 index 0000000..d493cc2 --- /dev/null +++ b/pico_sdk_import.cmake @@ -0,0 +1,121 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +# Copyright 2020 (c) 2020 Raspberry Pi (Trading) Ltd. +# +# 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. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_TAG} AND (NOT PICO_SDK_FETCH_FROM_GIT_TAG)) + set(PICO_SDK_FETCH_FROM_GIT_TAG $ENV{PICO_SDK_FETCH_FROM_GIT_TAG}) + message("Using PICO_SDK_FETCH_FROM_GIT_TAG from environment ('${PICO_SDK_FETCH_FROM_GIT_TAG}')") +endif () + +if (PICO_SDK_FETCH_FROM_GIT AND NOT PICO_SDK_FETCH_FROM_GIT_TAG) + set(PICO_SDK_FETCH_FROM_GIT_TAG "master") + message("Using master as default value for PICO_SDK_FETCH_FROM_GIT_TAG") +endif() + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") +set(PICO_SDK_FETCH_FROM_GIT_TAG "${PICO_SDK_FETCH_FROM_GIT_TAG}" CACHE FILEPATH "release tag for SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} + ) + + if (NOT pico_sdk) + message("Downloading Raspberry Pi Pico SDK") + # GIT_SUBMODULES_RECURSE was added in 3.17 + if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") + FetchContent_Populate( + pico_sdk + QUIET + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} + GIT_SUBMODULES_RECURSE FALSE + + SOURCE_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-src + BINARY_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-build + SUBBUILD_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-subbuild + ) + else () + FetchContent_Populate( + pico_sdk + QUIET + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} + + SOURCE_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-src + BINARY_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-build + SUBBUILD_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-subbuild + ) + endif () + + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE}) diff --git a/rp-2040.md b/rp-2040.md new file mode 100644 index 0000000..4bf9207 --- /dev/null +++ b/rp-2040.md @@ -0,0 +1,87 @@ +# RP2040-ETH Documentation + +## Overview + +The Waveshare RP2040-ETH is a compact microcontroller board that combines the Raspberry Pi RP2040 chip with built-in Ethernet connectivity. It provides a powerful dual-core processor with integrated networking capabilities in a small form factor. + +## Hardware Specifications + +### Processor +- **Chip**: Dual-core Arm Cortex M0+ processor +- **Clock Speed**: Flexible clock up to 133 MHz +- **Memory**: 264KB SRAM +- **Storage**: 4MB onboard Flash memory (W25Q32JVSSIQ NOR-Flash) + +### Ethernet +- **Ethernet Chip**: CH9120 with integrated TCP/IP protocol stack +- **Capabilities**: + - TCP Server/Client modes + - UDP Server/Client modes +- **Connector**: RJ45 Ethernet port + +### I/O and Interfaces +- **GPIO**: 14 multi-function GPIO pins +- **USB**: Type-C connector (USB 1.1 host/device support) +- **Special Features**: + - 8 Programmable I/O (PIO) state machines + - Temperature sensor + - Castellated module design for board integration + - Compatible with some Pico HATs + +### Power +- **Regulator**: RT9013-33GB 500mA Low Dropout LDO +- **Programming**: Drag-and-drop via USB mass storage + +## Programming the RP2040-ETH + +### Development Options +- C/C++ SDK +- MicroPython +- Arduino IDE + +### What We've Learned + +From our WS2812 LED control implementation: + +1. **PIO Usage**: The RP2040's PIO (Programmable I/O) is excellent for timing-critical operations like WS2812 LED control. We used PIO0 with state machine 0 to generate precise timing signals. + +2. **Clock Configuration**: The default system clock works well for most applications. We commented out `set_sys_clock_48()` as it wasn't necessary for our WS2812 implementation. + +3. **Pin Mapping**: GPIO 25 was used for WS2812 data output in our example, demonstrating the flexibility of pin assignment on the RP2040. + +4. **Timing Precision**: The PIO handles the 800kHz timing requirement of WS2812 LEDs perfectly, showing the RP2040's capability for real-time signal generation. + +5. **Memory Efficiency**: With 264KB of SRAM, there's plenty of room for complex applications beyond simple LED control. + +### Code Structure Example + +Our WS2812 implementation demonstrates key RP2040 programming patterns: + +```c +// PIO initialization +PIO pio = pio0; +int sm = 0; +uint offset = pio_add_program(pio, &ws2812_program); +ws2812_program_init(pio, sm, offset, 25, 800000, true); + +// Color data formatting (GRB format for WS2812) +uint32_t mask = (green << 16) | (red << 8) | (blue << 0); +put_pixel(mask); +``` + +### Key Takeaways + +1. **Hardware Abstraction**: The Pico SDK provides excellent hardware abstraction layers, making it easy to work with complex peripherals. + +2. **PIO Power**: The programmable I/O blocks are one of the RP2040's strongest features, enabling precise timing without CPU intervention. + +3. **Development Workflow**: The USB mass storage programming mode makes development iteration very fast - just drag and drop the UF2 file. + +4. **Ethernet Integration**: While our example doesn't use Ethernet, the CH9120 chip provides a straightforward path to network connectivity without complex TCP/IP stack implementation. + +## Future Considerations + +- The Ethernet functionality via CH9120 opens possibilities for IoT applications +- The dual-core processor allows for concurrent tasks (e.g., LED animation on one core, network communication on the other) +- The castellated edges make this board ideal for integration into custom PCBs +- PIO state machines can be used for various protocols beyond WS2812 (SPI, I2C variants, custom protocols) \ No newline at end of file diff --git a/test_client.py b/test_client.py new file mode 100644 index 0000000..50c36a7 --- /dev/null +++ b/test_client.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +""" +Test client for RP2040-ETH WS2812 Network Control +Sends color commands to the RP2040-ETH board +""" + +import socket +import sys +import time + +# RP2040-ETH configuration +HOST = '192.168.1.200' # The RP2040-ETH IP address +PORT = 1000 # The port used by the RP2040-ETH + +def send_command(sock, command): + """Send a command and receive response""" + print(f"Sending: {command}") + sock.send(command.encode()) + + # Wait for response + sock.settimeout(1.0) + try: + response = sock.recv(1024) + print(f"Received: {response.decode()}") + except socket.timeout: + print("No response received") + +def main(): + # Create a TCP socket + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + try: + # Connect to server + print(f"Connecting to {HOST}:{PORT}") + sock.connect((HOST, PORT)) + print("Connected!") + + # Demo sequence + commands = [ + "RED", + "GREEN", + "BLUE", + "WHITE", + "RGB:255,128,0", # Orange + "RGB:128,0,255", # Purple + "RGB:0,255,128", # Cyan-green + "OFF" + ] + + for cmd in commands: + send_command(sock, cmd) + time.sleep(2) # Wait 2 seconds between commands + + except ConnectionRefusedError: + print(f"Connection refused. Make sure the RP2040-ETH is running and accessible at {HOST}:{PORT}") + except Exception as e: + print(f"Error: {e}") + +if __name__ == "__main__": + if len(sys.argv) > 1: + # Allow custom command from command line + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.connect((HOST, PORT)) + send_command(sock, sys.argv[1]) + else: + # Run demo sequence + main() \ No newline at end of file diff --git a/test_ethernet.py b/test_ethernet.py new file mode 100644 index 0000000..462cb1c --- /dev/null +++ b/test_ethernet.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python3 +""" +Test ethernet connectivity for RP2040-ETH +""" + +import socket +import subprocess +import sys +import time + +# RP2040-ETH configuration +HOST = '192.168.1.200' +PORT = 1000 + +def ping_test(): + """Test basic connectivity with ping""" + print(f"1. Testing ping to {HOST}...") + try: + result = subprocess.run(['ping', '-c', '3', HOST], + capture_output=True, text=True, timeout=10) + if result.returncode == 0: + print("✓ Ping successful!") + print(result.stdout) + return True + else: + print("✗ Ping failed") + return False + except subprocess.TimeoutExpired: + print("✗ Ping timeout") + return False + except Exception as e: + print(f"✗ Ping error: {e}") + return False + +def tcp_test(): + """Test TCP connection""" + print(f"\n2. Testing TCP connection to {HOST}:{PORT}...") + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(5) + result = sock.connect_ex((HOST, PORT)) + if result == 0: + print("✓ TCP connection successful!") + + # Send a test command + print(" Sending test command 'GREEN'...") + sock.send(b"GREEN") + + # Try to receive response + try: + response = sock.recv(1024) + print(f" ✓ Received response: {response.decode()}") + except socket.timeout: + print(" - No response received (timeout)") + + sock.close() + return True + else: + print(f"✗ TCP connection failed (error code: {result})") + sock.close() + return False + except Exception as e: + print(f"✗ TCP error: {e}") + return False + +def arp_test(): + """Check ARP table for the device""" + print(f"\n3. Checking ARP table for {HOST}...") + try: + # For macOS/Linux + result = subprocess.run(['arp', '-n'], capture_output=True, text=True) + if HOST in result.stdout: + print(f"✓ Device found in ARP table") + # Extract the relevant line + for line in result.stdout.split('\n'): + if HOST in line: + print(f" {line}") + return True + else: + print("✗ Device not found in ARP table") + return False + except Exception as e: + print(f"✗ ARP check error: {e}") + return False + +def port_scan(): + """Quick port scan to see what's open""" + print(f"\n4. Scanning common ports on {HOST}...") + common_ports = [80, 443, 22, 23, 1000, 2000, 8080] + open_ports = [] + + for port in common_ports: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(0.5) + result = sock.connect_ex((HOST, port)) + if result == 0: + open_ports.append(port) + print(f" ✓ Port {port} is open") + sock.close() + + if not open_ports: + print(" ✗ No common ports are open") + + return len(open_ports) > 0 + +def main(): + print("RP2040-ETH Ethernet Test Suite") + print("==============================\n") + + results = { + 'ping': ping_test(), + 'tcp': tcp_test(), + 'arp': arp_test(), + 'ports': port_scan() + } + + print("\n\nSummary:") + print("--------") + passed = sum(results.values()) + total = len(results) + + for test, result in results.items(): + status = "✓ PASS" if result else "✗ FAIL" + print(f"{test.upper():8} {status}") + + print(f"\nTotal: {passed}/{total} tests passed") + + if passed == 0: + print("\nTroubleshooting:") + print("1. Check ethernet cable is connected") + print("2. Verify IP address matches your network (192.168.1.x)") + print("3. Check if RP2040-ETH is powered on") + print("4. Use serial monitor to see debug output from the device") + print("5. Ensure your computer is on the same network subnet") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ws2812.pio b/ws2812.pio new file mode 100644 index 0000000..ae19a6b --- /dev/null +++ b/ws2812.pio @@ -0,0 +1,48 @@ +; +; Copyright (c) 2020 Raspberry Pi (Trading) Ltd. +; +; SPDX-License-Identifier: BSD-3-Clause +; + +.program ws2812 +.side_set 1 + +.define public T1 2 +.define public T2 5 +.define public T3 3 + +.lang_opt python sideset_init = pico.PIO.OUT_HIGH +.lang_opt python out_init = pico.PIO.OUT_HIGH +.lang_opt python out_shiftdir = 1 + +.wrap_target +bitloop: + out x, 1 side 0 [T3 - 1] ; Side-set still takes place when instruction stalls + jmp !x do_zero side 1 [T1 - 1] ; Branch on the bit we shifted out. Positive pulse +do_one: + jmp bitloop side 1 [T2 - 1] ; Continue driving high, for a long pulse +do_zero: + nop side 0 [T2 - 1] ; Or drive low, for a short pulse +.wrap + +% c-sdk { +#include "hardware/clocks.h" + +static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) { + + pio_gpio_init(pio, pin); + pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); + + pio_sm_config c = ws2812_program_get_default_config(offset); + sm_config_set_sideset_pins(&c, pin); + sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24); + sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); + + int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3; + float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit); + sm_config_set_clkdiv(&c, div); + + pio_sm_init(pio, sm, offset, &c); + pio_sm_set_enabled(pio, sm, true); +} +%}