#include #include #include #include "pico/stdlib.h" #include "hardware/pio.h" #include "hardware/clocks.h" #include "ws2812.pio.h" #include "ch9120.h" #define WS2812_PIN 25 #define LED_FREQ 800000 void put_pixel(uint32_t pixel_grb) { pio_sm_put_blocking(pio0, 0, pixel_grb << 8u); } void put_rgb(uint8_t red, uint8_t green, uint8_t blue) { uint32_t mask = (green << 16) | (red << 8) | (blue << 0); put_pixel(mask); } void parse_color_command(const char *cmd, uint8_t *r, uint8_t *g, uint8_t *b) { if (strncmp(cmd, "RGB:", 4) == 0) { sscanf(cmd + 4, "%hhu,%hhu,%hhu", r, g, b); } else if (strcmp(cmd, "RED") == 0) { *r = 255; *g = 0; *b = 0; } else if (strcmp(cmd, "GREEN") == 0) { *r = 0; *g = 255; *b = 0; } else if (strcmp(cmd, "BLUE") == 0) { *r = 0; *g = 0; *b = 255; } else if (strcmp(cmd, "WHITE") == 0) { *r = 255; *g = 255; *b = 255; } else if (strcmp(cmd, "OFF") == 0) { *r = 0; *g = 0; *b = 0; } } int main() { stdio_init_all(); printf("RP2040-ETH WS2812 Network Control\n"); // Initialize WS2812 LED PIO pio = pio0; int sm = 0; uint offset = pio_add_program(pio, &ws2812_program); ws2812_program_init(pio, sm, offset, WS2812_PIN, LED_FREQ, true); // Initialize CH9120 Ethernet CH9120_init(); printf("Ethernet initialized\n"); printf("IP: 192.168.1.201\n"); printf("Port: 1000\n"); printf("Mode: TCP Server\n"); printf("Send color commands: RED, GREEN, BLUE, WHITE, OFF, or RGB:r,g,b\n"); // Flash LED to indicate startup for (int i = 0; i < 3; i++) { put_rgb(0, 0, 255); // Blue flash sleep_ms(200); put_rgb(0, 0, 0); // Off sleep_ms(200); } // Current LED state uint8_t current_r = 0, current_g = 0, current_b = 0; uint8_t target_r = 0, target_g = 0, target_b = 0; bool color_changing = false; char rx_buffer[256]; uint32_t last_heartbeat = 0; uint32_t last_blink = 0; bool show_blink = false; while (1) { // Check for network data int received = CH9120_receive_data(rx_buffer, sizeof(rx_buffer) - 1); if (received > 0) { rx_buffer[received] = '\0'; // Flash amber to indicate traffic put_rgb(255, 191, 0); // Amber sleep_ms(50); // Parse color command uint8_t new_r, new_g, new_b; parse_color_command(rx_buffer, &new_r, &new_g, &new_b); // Set new target color target_r = new_r; target_g = new_g; target_b = new_b; color_changing = true; // Send acknowledgment char ack[64]; snprintf(ack, sizeof(ack), "Setting color to R:%d G:%d B:%d\n", new_r, new_g, new_b); CH9120_send_data(ack, strlen(ack)); // Flash amber again for outgoing traffic put_rgb(255, 191, 0); // Amber sleep_ms(50); printf("Received command: %s\n", rx_buffer); } // Smooth color transition if (color_changing) { bool done = true; if (current_r != target_r) { current_r += (current_r < target_r) ? 1 : -1; done = false; } if (current_g != target_g) { current_g += (current_g < target_g) ? 1 : -1; done = false; } if (current_b != target_b) { current_b += (current_b < target_b) ? 1 : -1; done = false; } put_rgb(current_r, current_g, current_b); if (done) { color_changing = false; } sleep_ms(3); } else { // Keep current color put_rgb(current_r, current_g, current_b); sleep_ms(10); } // Periodic green flash to show firmware is running (regardless of state) uint32_t now = to_ms_since_boot(get_absolute_time()); // Check if it's time to blink (every 1 second) if (now - last_blink >= 1000) { show_blink = true; last_blink = now; } // Show green flash for 100ms if (show_blink && (now - last_blink < 100)) { put_rgb(0, 128, 0); // 50% green } // Clear blink flag after 100ms if (now - last_blink >= 100) { show_blink = false; } // Heartbeat log every 5 seconds if (now - last_heartbeat > 5000) { printf("Ethernet heartbeat - waiting for commands...\n"); last_heartbeat = now; } } }