diff --git a/Kernel/platform/platform-rpipico/CMakeLists.txt b/Kernel/platform/platform-rpipico/CMakeLists.txt index 7e958ccbc..765a1bd07 100644 --- a/Kernel/platform/platform-rpipico/CMakeLists.txt +++ b/Kernel/platform/platform-rpipico/CMakeLists.txt @@ -37,6 +37,7 @@ add_executable(fuzix swapper.c tricks.S core1.c + devgpio.c usbdescriptors.c ../../dev/blkdev.c ../../dev/mbr.c diff --git a/Kernel/platform/platform-rpipico/Makefile b/Kernel/platform/platform-rpipico/Makefile index 626db3f7c..a6d6a39ff 100644 --- a/Kernel/platform/platform-rpipico/Makefile +++ b/Kernel/platform/platform-rpipico/Makefile @@ -1,6 +1,6 @@ # Set one of these depending. -export PICO_SDK_FETCH_FROM_GIT = yes -#export PICO_SDK_PATH = /home/dg/src/pico/pico-sdk +#export PICO_SDK_FETCH_FROM_GIT = yes +export PICO_SDK_PATH = ${HOME}/.pico-sdk/sdk/1.5.1 include ../../../version.mk diff --git a/Kernel/platform/platform-rpipico/config.h b/Kernel/platform/platform-rpipico/config.h index 150d87821..5bd7d82d9 100644 --- a/Kernel/platform/platform-rpipico/config.h +++ b/Kernel/platform/platform-rpipico/config.h @@ -15,8 +15,10 @@ * CS GPIO 5 */ -#define CONFIG_RC2040 +#define CONFIG_MAKER_PI +/* We have a GPIO interface */ +#define CONFIG_DEV_GPIO /* Enable to make ^Z dump the inode table for debug */ #undef CONFIG_IDUMP /* Enable to make ^A drop back into the monitor */ diff --git a/Kernel/platform/platform-rpipico/devgpio.c b/Kernel/platform/platform-rpipico/devgpio.c new file mode 100644 index 000000000..8b4207c6c --- /dev/null +++ b/Kernel/platform/platform-rpipico/devgpio.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include "picosdk.h" + +// Access raspberry pi pico GPIO +int gpio_ioctl(uarg_t request, char *data) { + const uint8_t num_pins = 28; + static struct gpioreq gr; + + if (request == GPIOC_COUNT) { + return num_pins; + } + + if (uget(data, &gr, sizeof(struct gpioreq)) == -1) { + return -1; + } + + if (gr.pin >= num_pins) { + udata.u_error = ENODEV; + return -1; + } + + switch (request) { + case GPIOC_SETBYTE: + break; + case GPIOC_SET: + gpio_init(gr.pin); + gpio_set_dir(gr.pin, GPIO_OUT); + gpio_put(gr.pin, gr.val != 0); + return 0; + break; + default: + udata.u_error = ENODEV; + return -1; + } + + return -1; +} \ No newline at end of file diff --git a/Kernel/platform/platform-rpipico/devsdspi.c b/Kernel/platform/platform-rpipico/devsdspi.c index 9c339125b..e4f392e2a 100644 --- a/Kernel/platform/platform-rpipico/devsdspi.c +++ b/Kernel/platform/platform-rpipico/devsdspi.c @@ -23,6 +23,16 @@ //Pico spi0 or spi1 must match GPIO pins used above. #define Pico_SD_SPI_MOD spi1 +#elif defined(CONFIG_MAKER_PI) +// Maker pico board +// https://www.adafruit.com/product/5160 +#define Pico_SD_SCK 10 +#define Pico_SD_TX 11 +#define Pico_SD_RX 12 +#define Pico_SD_CS 15 + +#define Pico_SD_SPI_MOD spi1 + #else /* Pico SPI GPIO connected to SD SPIO - David Given's Arrangement */ diff --git a/Kernel/platform/platform-rpipico/picosdk.h b/Kernel/platform/platform-rpipico/picosdk.h index 55249266e..ec44a54ff 100644 --- a/Kernel/platform/platform-rpipico/picosdk.h +++ b/Kernel/platform/platform-rpipico/picosdk.h @@ -4,6 +4,7 @@ #include #include #include +#include "pico/stdlib.h" #define MANGLED 1 #include "mangle.h" diff --git a/Kernel/platform/platform-rpipico/utils/picoctl.c b/Kernel/platform/platform-rpipico/utils/picoctl.c index 98ddfe3f1..bd10d210c 100644 --- a/Kernel/platform/platform-rpipico/utils/picoctl.c +++ b/Kernel/platform/platform-rpipico/utils/picoctl.c @@ -1,31 +1,66 @@ +#include #include #include #include -#include +#include +#include + +#include #include #include "../pico_ioctl.h" -int main(int argc, char **argv) -{ - if (argc == 1 || strcmp(argv[1], "--help") == 0) - { - puts("usage: picoioctl [ --help ] "); - puts("Command list:"); - puts("\tflash\tReset into flash mode."); - return 0; +int is_valid_uint8(const char *str) { + char *endptr; + long val = strtol(str, &endptr, 10); + + // check string was a number and within the range of uint8_t + if (*endptr == '\0' && val >= 0 && val <= UINT8_MAX) { + return 1; } - int fd = open("/dev/sys", O_RDWR, 0); - if (!fd) - { - puts("Failed to open /dev/sys."); - exit(1); - } - if (ioctl(fd, PICOIOC_FLASH) != 0) - { - puts("Failed to perform operation."); - close(fd); - exit(1); - } - close(fd); return 0; } + +int main(int argc, char **argv) { + if (argc == 1 || strcmp(argv[1], "--help") == 0) + { + puts("Turn on/off GPIO pins on the pico"); + puts("Usage: picoctl "); + return 0; + } + + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + if (!is_valid_uint8(argv[1])) { + fprintf(stderr, "Error: must be a valid uint8_t value\n"); + return 1; + } + uint8_t pin = (uint8_t)strtoul(argv[1], NULL, 10); + + if (!is_valid_uint8(argv[2])) { + fprintf(stderr, "Error: must be a valid uint8_t value\n"); + return 1; + } + uint8_t value = (uint8_t)strtoul(argv[2], NULL, 10); + + int fd = open("/dev/gpio", O_RDWR, 0); + if (!fd) { + puts("Failed to open /dev/gpio."); + exit(1); + } + + struct gpioreq gr; + gr.pin = pin; + gr.val = value; + + if (ioctl(fd, GPIOC_SET, &gr) != 0) { + puts("Failed to perform operation."); + close(fd); + exit(1); + } + + close(fd); + return 0; +}