first and working ethernet
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
build
|
||||
!.vscode/*
|
||||
22
.vscode/c_cpp_properties.json
vendored
Normal file
22
.vscode/c_cpp_properties.json
vendored
Normal 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
15
.vscode/cmake-kits.json
vendored
Normal 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
9
.vscode/extensions.json
vendored
Normal 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
50
.vscode/launch.json
vendored
Normal 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
40
.vscode/settings.json
vendored
Normal 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
102
.vscode/tasks.json
vendored
Normal 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
98
CMakeLists.txt
Normal 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
86
README_ETH.md
Normal 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
BIN
Refernce Code/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
Refernce Code/RP2040-ETH-WS2812B/.DS_Store
vendored
Normal file
BIN
Refernce Code/RP2040-ETH-WS2812B/.DS_Store
vendored
Normal file
Binary file not shown.
41
Refernce Code/RP2040-ETH-WS2812B/C/CMakeLists.txt
Normal file
41
Refernce Code/RP2040-ETH-WS2812B/C/CMakeLists.txt
Normal 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)
|
||||
|
||||
51
Refernce Code/RP2040-ETH-WS2812B/C/RP2040_WS2812B_Test.c
Normal file
51
Refernce Code/RP2040-ETH-WS2812B/C/RP2040_WS2812B_Test.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Refernce Code/RP2040-ETH-WS2812B/C/ReadmeCN.txt
Normal file
34
Refernce Code/RP2040-ETH-WS2812B/C/ReadmeCN.txt
Normal 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中即可
|
||||
|
||||
35
Refernce Code/RP2040-ETH-WS2812B/C/ReadmeEN.txt
Normal file
35
Refernce Code/RP2040-ETH-WS2812B/C/ReadmeEN.txt
Normal 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
|
||||
|
||||
61
Refernce Code/RP2040-ETH-WS2812B/C/generated/ws2812.pio.h
Normal file
61
Refernce Code/RP2040-ETH-WS2812B/C/generated/ws2812.pio.h
Normal 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
|
||||
|
||||
62
Refernce Code/RP2040-ETH-WS2812B/C/pico_sdk_import.cmake
Normal file
62
Refernce Code/RP2040-ETH-WS2812B/C/pico_sdk_import.cmake
Normal 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})
|
||||
BIN
Refernce Code/RP2040-ETH-WS2812B/C/uf2/RP2040_WS2812B_Test.uf2
Normal file
BIN
Refernce Code/RP2040-ETH-WS2812B/C/uf2/RP2040_WS2812B_Test.uf2
Normal file
Binary file not shown.
48
Refernce Code/RP2040-ETH-WS2812B/C/ws2812.pio
Normal file
48
Refernce Code/RP2040-ETH-WS2812B/C/ws2812.pio
Normal 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);
|
||||
}
|
||||
%}
|
||||
@@ -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)
|
||||
36
Refernce Code/RP2040-ETH-WS2812B/Python/ReadmeCN.txt
Normal file
36
Refernce Code/RP2040-ETH-WS2812B/Python/ReadmeCN.txt
Normal 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文件
|
||||
然后运行当前脚本(绿色小三角)即可
|
||||
|
||||
38
Refernce Code/RP2040-ETH-WS2812B/Python/ReadmeEN.txt
Normal file
38
Refernce Code/RP2040-ETH-WS2812B/Python/ReadmeEN.txt
Normal 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)
|
||||
|
||||
Binary file not shown.
1
Refernce Code/RP2040-ETH-WS2812B/Version_CN.txt
Normal file
1
Refernce Code/RP2040-ETH-WS2812B/Version_CN.txt
Normal file
@@ -0,0 +1 @@
|
||||
2021-11-22:新创建。
|
||||
1
Refernce Code/RP2040-ETH-WS2812B/Version_EN.txt
Normal file
1
Refernce Code/RP2040-ETH-WS2812B/Version_EN.txt
Normal file
@@ -0,0 +1 @@
|
||||
2021-11-22: newly built.
|
||||
315
Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/CH9120.cpp
Normal file
315
Refernce Code/RP2040_ETH_CODE/Arduino/RP2040-ETH-Demo/CH9120.cpp
Normal 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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "CH9120.h"
|
||||
|
||||
void setup() {
|
||||
CH9120_init();
|
||||
RX_TX();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
6
Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/main.c
Normal file
6
Refernce Code/RP2040_ETH_CODE/C/RP2040-ETH-Demo/main.c
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "CH9120_Test.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
Pico_ETH_CH9120_test();
|
||||
}
|
||||
@@ -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})
|
||||
Binary file not shown.
@@ -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'))
|
||||
@@ -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)
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,86 @@
|
||||
from machine import UART, Pin
|
||||
from mqtt_client import MQTTClient
|
||||
from ch9120 import CH9120
|
||||
import time
|
||||
|
||||
# MQTT
|
||||
CLIENT_ID = "Waveshare_RP2040_ETH"
|
||||
SUBSCRIBE_TOPIC = "test_topic1"
|
||||
PUBLISH_TOPIC = "test_topic2"
|
||||
|
||||
# CH9120
|
||||
MODE = 1 #0:TCP Server 1:TCP Client 2:UDP Server 3:UDP Client
|
||||
GATEWAY = (192, 168, 1, 1) # GATEWAY
|
||||
TARGET_IP = (47, 92, 129, 18) # TARGET_IP
|
||||
LOCAL_IP = (192, 168, 1, 200) # LOCAL_IP
|
||||
SUBNET_MASK = (255,255,255,0) # SUBNET_MASK
|
||||
LOCAL_PORT1 = 1000 # LOCAL_PORT1
|
||||
TARGET_PORT = 1883 # TARGET_PORT
|
||||
BAUD_RATE = 115200 # BAUD_RATE
|
||||
|
||||
uart1 = UART(1, baudrate=9600, tx=Pin(20), rx=Pin(21))
|
||||
|
||||
def ch9120_configure():
|
||||
global uart1
|
||||
ch9120 = CH9120(uart1)
|
||||
ch9120.enter_config() # enter configuration mode
|
||||
ch9120.set_mode(MODE)
|
||||
ch9120.set_localIP(LOCAL_IP)
|
||||
ch9120.set_subnetMask(SUBNET_MASK)
|
||||
ch9120.set_gateway(GATEWAY)
|
||||
ch9120.set_localPort(LOCAL_PORT1)
|
||||
ch9120.set_targetIP(TARGET_IP)
|
||||
ch9120.set_targetPort(TARGET_PORT)
|
||||
ch9120.set_baudRate(BAUD_RATE)
|
||||
ch9120.exit_config() # exit configuration mode
|
||||
|
||||
# Clear cache and reconfigure uart1
|
||||
uart1.read(uart1.any())
|
||||
time.sleep(0.5)
|
||||
uart1 = UART(1, baudrate=115200, tx=Pin(20), rx=Pin(21))
|
||||
|
||||
if __name__ == "__main__":
|
||||
ch9120_configure()
|
||||
mqtt_client = MQTTClient(uart1)
|
||||
mqtt_client.ClientID = CLIENT_ID # Set ClientID
|
||||
mqtt_client.connect() # Connect to MQTT server
|
||||
mqtt_client.subscribe(SUBSCRIBE_TOPIC) # Subscribe to topic:test_topic1
|
||||
|
||||
mqtt_client.send_heartbeat()
|
||||
last_heartbeat_time = time.time()
|
||||
time.sleep_ms(60) # Sending the first heartbeat
|
||||
uart1.read() # Clear unnecessary data
|
||||
|
||||
while True:
|
||||
rxData = uart1.read()
|
||||
if rxData is not None:
|
||||
topic, message = mqtt_client.extract_data(rxData) # Parse the received data
|
||||
if topic == SUBSCRIBE_TOPIC:
|
||||
print("Topic:", topic)
|
||||
print("Message:", message)
|
||||
mqtt_client.publish(PUBLISH_TOPIC, message) # Send received data to topic:test_topic2
|
||||
|
||||
current_time = time.time()
|
||||
if current_time - last_heartbeat_time >= 30:
|
||||
mqtt_client.send_heartbeat() # Send a heartbeat every 30 seconds
|
||||
last_heartbeat_time = current_time
|
||||
time.sleep_ms(60) # Waiting for the server to respond
|
||||
if not mqtt_client.check_heartbeat_response():
|
||||
while True:
|
||||
print("Reconnecting...")
|
||||
mqtt_client = MQTTClient(uart1)
|
||||
mqtt_client.ClientID = CLIENT_ID # Set ClientID
|
||||
mqtt_client.connect() # Connect to MQTT server
|
||||
mqtt_client.subscribe(SUBSCRIBE_TOPIC) # Subscribe to topic:test_topic1
|
||||
time.sleep_ms(200) # Waiting for the server to respond
|
||||
uart1.read() # Clear unnecessary data
|
||||
mqtt_client.send_heartbeat() # Sending the first heartbeat
|
||||
last_heartbeat_time = current_time # Clear unnecessary data
|
||||
time.sleep_ms(60) # Waiting for the server to respond
|
||||
if mqtt_client.check_heartbeat_response():
|
||||
print("Reconnection successful!")
|
||||
break
|
||||
|
||||
time.sleep_ms(20)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
51
barnum-initial.c
Normal file
51
barnum-initial.c
Normal 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
163
barnum.c
Normal 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
225
barnumbak.c
Normal 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
34
blink.pio
Normal 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
181
ch9120.c
Normal 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
42
ch9120.h
Normal 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
76
network_scan.py
Normal 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
121
pico_sdk_import.cmake
Normal 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
87
rp-2040.md
Normal 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
66
test_client.py
Normal 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
137
test_ethernet.py
Normal 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
48
ws2812.pio
Normal 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);
|
||||
}
|
||||
%}
|
||||
Reference in New Issue
Block a user