#include #include "pico/stdlib.h" #include "hardware/spi.h" #include "hardware/i2c.h" #include "hardware/dma.h" #include "hardware/pio.h" #include "hardware/interp.h" #include "hardware/timer.h" #include "hardware/watchdog.h" #include "hardware/uart.h" // RP2040-ETH board CH9120 ethernet chip defines #define CH9120_UART_ID uart0 #define CH9120_RXD_PIN 21 // Serial data input to CH9120 #define CH9120_TXD_PIN 20 // Serial data output from CH9120 #define CH9120_TCPCS_PIN 17 // TCP client connection status #define CH9120_CFG0_PIN 18 // Network configuration pin #define CH9120_RSTI_PIN 19 // Reset pin (active LOW) // SPI Defines for RP2040-ETH // Using available pins that don't conflict with CH9120 ethernet chip // CH9120 uses pins 17-21, so we avoid those #define SPI_PORT spi0 #define PIN_MISO 0 #define PIN_CS 1 #define PIN_SCK 2 #define PIN_MOSI 3 // I2C defines for RP2040-ETH // Using I2C0 on available pins that don't conflict with CH9120 #define I2C_PORT i2c0 #define I2C_SDA 4 #define I2C_SCL 5 // Data will be copied from src to dst const char src[] = "Hello, world! (from DMA)"; char dst[count_of(src)]; #include "blink.pio.h" #include "ws2812.pio.h" void blink_pin_forever(PIO pio, uint sm, uint offset, uint pin, uint freq) { blink_program_init(pio, sm, offset, pin); pio_sm_set_enabled(pio, sm, true); printf("Blinking pin %d at %d Hz\n", pin, freq); // PIO counter program takes 3 more cycles in total than we pass as // input (wait for n + 1; mov; jmp) pio->txf[sm] = (125000000 / (2 * freq)) - 3; } void put_pixel(uint32_t pixel_grb) { pio_sm_put_blocking(pio0, 0, pixel_grb << 8u); // Use state machine 0 } void put_rgb(uint8_t red, uint8_t green, uint8_t blue) { uint32_t mask = (green << 16) | (red << 8) | (blue << 0); put_pixel(mask); } int64_t alarm_callback(alarm_id_t id, void *user_data) { // Put your timeout handler code in here return 0; } // UART defines for RP2040-ETH // By default the stdout UART is `uart0`, so we will use the second one // Note: CH9120 ethernet chip uses UART0 on pins 20-21 #define UART_ID uart1 #define BAUD_RATE 115200 // Use pins 8 and 9 for UART1 (avoiding CH9120 pins) #define UART_TX_PIN 8 #define UART_RX_PIN 9 int main() { stdio_init_all(); // SPI initialisation. This example will use SPI at 1MHz. spi_init(SPI_PORT, 1000*1000); gpio_set_function(PIN_MISO, GPIO_FUNC_SPI); gpio_set_function(PIN_CS, GPIO_FUNC_SIO); gpio_set_function(PIN_SCK, GPIO_FUNC_SPI); gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI); // Chip select is active-low, so we'll initialise it to a driven-high state gpio_set_dir(PIN_CS, GPIO_OUT); gpio_put(PIN_CS, 1); // For more examples of SPI use see https://github.com/raspberrypi/pico-examples/tree/master/spi // I2C Initialisation. Using it at 400Khz. i2c_init(I2C_PORT, 400*1000); gpio_set_function(I2C_SDA, GPIO_FUNC_I2C); gpio_set_function(I2C_SCL, GPIO_FUNC_I2C); gpio_pull_up(I2C_SDA); gpio_pull_up(I2C_SCL); // For more examples of I2C use see https://github.com/raspberrypi/pico-examples/tree/master/i2c // Get a free channel, panic() if there are none int chan = dma_claim_unused_channel(true); // 8 bit transfers. Both read and write address increment after each // transfer (each pointing to a location in src or dst respectively). // No DREQ is selected, so the DMA transfers as fast as it can. dma_channel_config c = dma_channel_get_default_config(chan); channel_config_set_transfer_data_size(&c, DMA_SIZE_8); channel_config_set_read_increment(&c, true); channel_config_set_write_increment(&c, true); dma_channel_configure( chan, // Channel to be configured &c, // The configuration we just created dst, // The initial write address src, // The initial read address count_of(src), // Number of transfers; in this case each is 1 byte. true // Start immediately. ); // We could choose to go and do something else whilst the DMA is doing its // thing. In this case the processor has nothing else to do, so we just // wait for the DMA to finish. dma_channel_wait_for_finish_blocking(chan); // The DMA has now copied our text from the transmit buffer (src) to the // receive buffer (dst), so we can print it out from there. puts(dst); // PIO Blinking example PIO pio = pio0; uint offset = pio_add_program(pio, &blink_program); printf("Loaded blink program at %d\n", offset); // WS2812B RGB LED on pin 25 (RP2040-ETH board) uint ws2812_offset = pio_add_program(pio, &ws2812_program); printf("Loaded WS2812B program at %d\n", ws2812_offset); ws2812_program_init(pio, 0, ws2812_offset, 25, 800000, false); // Use state machine 0 printf("WS2812B RGB LED initialized on pin 25\n"); // For more pio examples see https://github.com/raspberrypi/pico-examples/tree/master/pio // Interpolator example code interp_config cfg = interp_default_config(); // Now use the various interpolator library functions for your use case // e.g. interp_config_clamp(&cfg, true); // interp_config_shift(&cfg, 2); // Then set the config interp_set_config(interp0, 0, &cfg); // For examples of interpolator use see https://github.com/raspberrypi/pico-examples/tree/master/interp // Timer example code - This example fires off the callback after 2000ms add_alarm_in_ms(2000, alarm_callback, NULL, false); // For more examples of timer use see https://github.com/raspberrypi/pico-examples/tree/master/timer // Watchdog example code if (watchdog_caused_reboot()) { printf("Rebooted by Watchdog!\n"); // Whatever action you may take if a watchdog caused a reboot } // Enable the watchdog, requiring the watchdog to be updated every 100ms or the chip will reboot // second arg is pause on debug which means the watchdog will pause when stepping through code watchdog_enable(100, 1); // You need to call this function at least more often than the 100ms in the enable call to prevent a reboot watchdog_update(); // Set up our UART uart_init(UART_ID, BAUD_RATE); // Set the TX and RX pins by using the function select on the GPIO // Set datasheet for more information on function select gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART); gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART); // Use some the various UART functions to send out data // In a default system, printf will also output via the default UART // Send out a string, with CR/LF conversions uart_puts(UART_ID, " Hello, UART!\n"); // For more examples of UART use see https://github.com/raspberrypi/pico-examples/tree/master/uart // Initialize CH9120 ethernet chip uart_init(CH9120_UART_ID, 115200); gpio_set_function(CH9120_TXD_PIN, GPIO_FUNC_UART); gpio_set_function(CH9120_RXD_PIN, GPIO_FUNC_UART); // Configure CH9120 control pins gpio_init(CH9120_TCPCS_PIN); gpio_set_dir(CH9120_TCPCS_PIN, GPIO_IN); gpio_init(CH9120_CFG0_PIN); gpio_set_dir(CH9120_CFG0_PIN, GPIO_OUT); gpio_put(CH9120_CFG0_PIN, 0); // Normal operation mode gpio_init(CH9120_RSTI_PIN); gpio_set_dir(CH9120_RSTI_PIN, GPIO_OUT); gpio_put(CH9120_RSTI_PIN, 1); // Release reset (active LOW) printf("CH9120 ethernet chip initialized\\n"); uint8_t state = 0; while (true) { printf("Hello, world!\n"); // Simple color cycling - solid colors switch(state % 6) { case 0: put_rgb(255, 0, 0); break; // Red case 1: put_rgb(255, 128, 0); break; // Orange case 2: put_rgb(255, 255, 0); break; // Yellow case 3: put_rgb(0, 255, 0); break; // Green case 4: put_rgb(0, 0, 255); break; // Blue case 5: put_rgb(128, 0, 255); break; // Purple } state++; sleep_ms(1000); } }