first and working ethernet

This commit is contained in:
2025-07-26 21:48:13 -04:00
commit 473f9013c0
58 changed files with 3405 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
build
!.vscode/*

22
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -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
}

15
.vscode/cmake-kits.json vendored Normal file
View File

@@ -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}"
}
}
]

9
.vscode/extensions.json vendored Normal file
View File

@@ -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"
]
}

50
.vscode/launch.json vendored Normal file
View File

@@ -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}\""
]
},
]
}

40
.vscode/settings.json vendored Normal file
View File

@@ -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"
}

102
.vscode/tasks.json vendored Normal file
View File

@@ -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",
}
}
]
}

98
CMakeLists.txt Normal file
View File

@@ -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)

86
README_ETH.md Normal file
View File

@@ -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`

BIN
Refernce Code/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -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)

View File

@@ -0,0 +1,51 @@
#include <stdio.h>
#include <stdlib.h>
#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);
}
}
}

View File

@@ -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中即可

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,62 @@
# This is a copy of <PICO_SDK_PATH>/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})

View File

@@ -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);
}
%}

View File

@@ -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)

View File

@@ -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文件
然后运行当前脚本(绿色小三角)即可

View File

@@ -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)

View File

@@ -0,0 +1 @@
2021-11-22新创建。

View File

@@ -0,0 +1 @@
2021-11-22: newly built.

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,54 @@
#ifndef _CH9120_H_
#define _CH9120_H_
#include <Arduino.h>
#include <stdlib.h> // malloc() free()
#include <stdio.h>
/// \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

View File

@@ -0,0 +1,10 @@
#include "CH9120.h"
void setup() {
CH9120_init();
RX_TX();
}
void loop() {
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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);
}
}
}
}

View File

@@ -0,0 +1,54 @@
#ifndef _CH9120_H_
#define _CH9120_H_
#include <stdlib.h> // malloc() free()
#include <stdio.h>
#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

View File

@@ -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)

View File

@@ -0,0 +1,6 @@
#include "CH9120_Test.h"
int main()
{
Pico_ETH_CH9120_test();
}

View File

@@ -0,0 +1,62 @@
# This is a copy of <PICO_SDK_PATH>/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})

View File

@@ -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'))

View File

@@ -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)

View File

@@ -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 topictest_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 topictest_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 topictest_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)

View File

@@ -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)

View File

@@ -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

51
barnum-initial.c Normal file
View File

@@ -0,0 +1,51 @@
#include <stdio.h>
#include <stdlib.h>
#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);
}
}
}

163
barnum.c Normal file
View File

@@ -0,0 +1,163 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}
}
}

225
barnumbak.c Normal file
View File

@@ -0,0 +1,225 @@
#include <stdio.h>
#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);
}
}

34
blink.pio Normal file
View File

@@ -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);
}
%}

181
ch9120.c Normal file
View File

@@ -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);
}
}

42
ch9120.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef _CH9120_H_
#define _CH9120_H_
#include <stdlib.h>
#include <stdio.h>
#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

76
network_scan.py Normal file
View File

@@ -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")

121
pico_sdk_import.cmake Normal file
View File

@@ -0,0 +1,121 @@
# This is a copy of <PICO_SDK_PATH>/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})

87
rp-2040.md Normal file
View File

@@ -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)

66
test_client.py Normal file
View File

@@ -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()

137
test_ethernet.py Normal file
View File

@@ -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()

48
ws2812.pio Normal file
View File

@@ -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);
}
%}